irmode.c 21.8 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
2
 * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

Matthias Braun's avatar
Matthias Braun committed
20
21
22
23
24
/**
 * @file
 * @brief    Data modes of operations.
 * @author   Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Mathias Heil
 * @version  $Id$
Götz Lindenmaier's avatar
Götz Lindenmaier committed
25
 */
Matthias Braun's avatar
Matthias Braun committed
26
#include "config.h"
Boris Boesler's avatar
added    
Boris Boesler committed
27

Moritz Kroll's avatar
Moritz Kroll committed
28
29
#include <stdlib.h>
#include <string.h>
Michael Beck's avatar
Michael Beck committed
30

Moritz Kroll's avatar
Moritz Kroll committed
31
#include <stddef.h>
32

Moritz Kroll's avatar
Moritz Kroll committed
33
34
35
36
37
38
39
40
41
#include "irprog_t.h"
#include "irmode_t.h"
#include "ident.h"
#include "tv_t.h"
#include "obst.h"
#include "irhooks.h"
#include "irtools.h"
#include "array.h"
#include "error.h"
42
#include "pattern_dmp.h"
Christian Schäfer's avatar
Christian Schäfer committed
43

Michael Beck's avatar
Michael Beck committed
44
/** Obstack to hold all modes. */
45
static struct obstack modes;
Christian Schäfer's avatar
Christian Schäfer committed
46

Michael Beck's avatar
Michael Beck committed
47
/** The list of all currently existing modes. */
Matthias Braun's avatar
Matthias Braun committed
48
49
static ir_mode **mode_list;

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
const char *get_mode_arithmetic_name(ir_mode_arithmetic ari)
{
#define X(a)    case a: return #a
	switch (ari) {
		X(irma_uninitialized);
		X(irma_none);
		X(irma_twos_complement);
		X(irma_ones_complement);
		X(irma_int_BCD);
		X(irma_ieee754);
		X(irma_float_BCD);
		default: return "<unknown>";
	}
#undef X
}

66
/**
67
 * Compare modes that don't need to have their code field
68
 * correctly set
69
70
71
 *
 * TODO: Add other fields
 **/
72
73
static inline int modes_are_equal(const ir_mode *m, const ir_mode *n)
{
74
75
76
77
78
79
80
81
	if (m == n) return 1;
	if (m->sort         == n->sort &&
		m->arithmetic   == n->arithmetic &&
		m->size         == n->size &&
		m->sign         == n->sign  &&
		m->modulo_shift == n->modulo_shift &&
		m->vector_elem  == n->vector_elem)
		return 1;
Christian Schäfer's avatar
Christian Schäfer committed
82

83
	return 0;
84
}
Matthias Heil's avatar
Matthias Heil committed
85

86
/**
87
 * searches the modes obstack for the given mode and returns
88
 * a pointer on an equal mode already in the array, NULL if
89
90
 * none found
 */
91
92
static ir_mode *find_mode(const ir_mode *m)
{
93
94
	size_t i, n_modes;
	for (i = 0, n_modes = ARR_LEN(mode_list); i < n_modes; ++i) {
Matthias Braun's avatar
Matthias Braun committed
95
		ir_mode *n = mode_list[i];
96
97
98
		if (modes_are_equal(n, m))
			return n;
	}
Michael Beck's avatar
Michael Beck committed
99
100
101
	return NULL;
}

102
103
104
/**
 * sets special values of modes
 */
105
106
static void set_mode_values(ir_mode* mode)
{
107
	switch (get_mode_sort(mode))    {
108
	case irms_reference:
109
110
111
112
113
114
115
	case irms_int_number:
	case irms_float_number:
		mode->min  = get_tarval_min(mode);
		mode->max  = get_tarval_max(mode);
		mode->null = get_tarval_null(mode);
		mode->one  = get_tarval_one(mode);
		mode->minus_one = get_tarval_minus_one(mode);
116
		if (get_mode_sort(mode) != irms_float_number) {
117
118
119
120
			mode->all_one = get_tarval_all_one(mode);
		} else {
			mode->all_one = tarval_bad;
		}
121
122
123
124
125
126
127
128
		break;

	case irms_internal_boolean:
		mode->min  = tarval_b_false;
		mode->max  = tarval_b_true;
		mode->null = tarval_b_false;
		mode->one  = tarval_b_true;
		mode->minus_one = tarval_bad;
129
		mode->all_one = tarval_b_true;
130
131
132
133
134
135
136
137
138
139
140
141
		break;

	case irms_auxiliary:
	case irms_memory:
	case irms_control_flow:
		mode->min  = tarval_bad;
		mode->max  = tarval_bad;
		mode->null = tarval_bad;
		mode->one  = tarval_bad;
		mode->minus_one = tarval_bad;
		break;
	}
142
}
143

144
145
146
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
147

148
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
149

150
151
152
153
154
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
155
156
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
157

158
159
160
161
/* predefined numerical modes: */
ir_mode *mode_F;    /* float */
ir_mode *mode_D;    /* double */
ir_mode *mode_E;    /* long double */
Christian Schäfer's avatar
Christian Schäfer committed
162

163
164
165
166
167
168
169
170
ir_mode *mode_Bs;   /* integral values, signed and unsigned */
ir_mode *mode_Bu;   /* 8 bit */
ir_mode *mode_Hs;   /* 16 bit */
ir_mode *mode_Hu;
ir_mode *mode_Is;   /* 32 bit */
ir_mode *mode_Iu;
ir_mode *mode_Ls;   /* 64 bit */
ir_mode *mode_Lu;
171
172
ir_mode *mode_LLs;  /* 128 bit */
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
173

174
175
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
176
177

/* machine specific modes */
178
179
ir_mode *mode_P_code;   /**< machine specific pointer mode for code addresses */
ir_mode *mode_P_data;   /**< machine specific pointer mode for data addresses */
180

181
182
183
184
185
/* * *
 * functions defined in irmode.h
 * * */

/* JNI access functions */
186
187
188
189
190
191
192
193
194
195
196
197
ir_mode *get_modeT(void) { return mode_T; }
ir_mode *get_modeF(void) { return mode_F; }
ir_mode *get_modeD(void) { return mode_D; }
ir_mode *get_modeE(void) { return mode_E; }
ir_mode *get_modeBs(void) { return mode_Bs; }
ir_mode *get_modeBu(void) { return mode_Bu; }
ir_mode *get_modeHs(void) { return mode_Hs; }
ir_mode *get_modeHu(void) { return mode_Hu; }
ir_mode *get_modeIs(void) { return mode_Is; }
ir_mode *get_modeIu(void) { return mode_Iu; }
ir_mode *get_modeLs(void) { return mode_Ls; }
ir_mode *get_modeLu(void) { return mode_Lu; }
198
199
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
200
201
202
203
204
205
206
ir_mode *get_modeb(void) { return mode_b; }
ir_mode *get_modeP(void) { return mode_P; }
ir_mode *get_modeX(void) { return mode_X; }
ir_mode *get_modeM(void) { return mode_M; }
ir_mode *get_modeBB(void) { return mode_BB; }
ir_mode *get_modeANY(void) { return mode_ANY; }
ir_mode *get_modeBAD(void) { return mode_BAD; }
207

208

209
210
ir_mode *(get_modeP_code)(void)
{
211
	return _get_modeP_code();
Michael Beck's avatar
Michael Beck committed
212
213
}

214
215
ir_mode *(get_modeP_data)(void)
{
216
	return _get_modeP_data();
217
218
}

219
220
void set_modeP_code(ir_mode *p)
{
221
222
	assert(mode_is_reference(p));
	mode_P_code = p;
223
224
}

225
226
void set_modeP_data(ir_mode *p)
{
227
228
	assert(mode_is_reference(p));
	mode_P_data = p;
Michael Beck's avatar
Michael Beck committed
229
}
230

231
/**
232
233
234
 * Registers a new mode.
 *
 * @param new_mode  The new mode template.
235
 */
236
237
static ir_mode *register_mode(const ir_mode *new_mode)
{
238
	ir_mode *mode = NULL;
239

240
	assert(new_mode);
241

242
243
	/* copy mode struct to modes array */
	mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode));
Matthias Braun's avatar
Matthias Braun committed
244
	ARR_APP1(ir_mode*, mode_list, mode);
245

246
	mode->kind = k_ir_mode;
247
	mode->type = new_type_primitive(mode);
248

249
250
	/* add the new mode to the irp list of modes */
	add_irp_mode(mode);
251

252
	set_mode_values(mode);
253

254
255
	hook_new_mode(new_mode, mode);
	return mode;
256
257
258
259
260
}

/*
 * Creates a new mode.
 */
261
262
ir_mode *new_ir_mode(const char *name, ir_mode_sort sort, int bit_size, int sign,
                     ir_mode_arithmetic arithmetic, unsigned int modulo_shift)
263
{
264
265
266
267
268
269
270
	ir_mode mode_tmpl;
	ir_mode *mode = NULL;

	mode_tmpl.name         = new_id_from_str(name);
	mode_tmpl.sort         = sort;
	mode_tmpl.size         = bit_size;
	mode_tmpl.sign         = sign ? 1 : 0;
271
272
	mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number ||
	                          mode_tmpl.sort == irms_reference) ? modulo_shift : 0;
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
	mode_tmpl.vector_elem  = 1;
	mode_tmpl.arithmetic   = arithmetic;
	mode_tmpl.link         = NULL;
	mode_tmpl.tv_priv      = NULL;

	mode = find_mode(&mode_tmpl);
	if (mode) {
		hook_new_mode(&mode_tmpl, mode);
		return mode;
	}

	/* sanity checks */
	switch (sort) {
	case irms_auxiliary:
	case irms_control_flow:
	case irms_memory:
	case irms_internal_boolean:
290
		panic("internal modes cannot be user defined");
291
292
293
294
295

	case irms_float_number:
	case irms_int_number:
	case irms_reference:
		mode = register_mode(&mode_tmpl);
296
		break;
297
	}
298
	assert(mode != NULL);
299
	return mode;
300
301
}

302
303
304
/*
 * Creates a new vector mode.
 */
305
306
ir_mode *new_ir_vector_mode(const char *name, ir_mode_sort sort, int bit_size, unsigned num_of_elem, int sign,
                            ir_mode_arithmetic arithmetic, unsigned int modulo_shift)
307
{
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
	ir_mode mode_tmpl;
	ir_mode *mode = NULL;

	mode_tmpl.name         = new_id_from_str(name);
	mode_tmpl.sort         = sort;
	mode_tmpl.size         = bit_size * num_of_elem;
	mode_tmpl.sign         = sign ? 1 : 0;
	mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0;
	mode_tmpl.vector_elem  = num_of_elem;
	mode_tmpl.arithmetic   = arithmetic;
	mode_tmpl.link         = NULL;
	mode_tmpl.tv_priv      = NULL;

	mode = find_mode(&mode_tmpl);
	if (mode) {
		hook_new_mode(&mode_tmpl, mode);
		return mode;
	}

	if (num_of_elem <= 1) {
328
		panic("vector modes should have at least 2 elements");
329
330
331
332
333
334
335
336
	}

	/* sanity checks */
	switch (sort) {
	case irms_auxiliary:
	case irms_control_flow:
	case irms_memory:
	case irms_internal_boolean:
337
		panic("internal modes cannot be user defined");
338
339

	case irms_reference:
340
		panic("only integer and floating point modes can be vectorized");
341
342

	case irms_float_number:
343
		panic("not yet implemented");
344
345
346
347

	case irms_int_number:
		mode = register_mode(&mode_tmpl);
	}
348
	assert(mode != NULL);
349
	return mode;
350
351
}

352
/* Functions for the direct access to all attributes of an ir_mode */
353
354
ident *(get_mode_ident)(const ir_mode *mode)
{
355
	return _get_mode_ident(mode);
Christian Schäfer's avatar
Christian Schäfer committed
356
357
}

358
359
const char *get_mode_name(const ir_mode *mode)
{
360
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
361
362
}

363
364
ir_mode_sort (get_mode_sort)(const ir_mode* mode)
{
365
	return _get_mode_sort(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
366
367
}

368
369
unsigned (get_mode_size_bits)(const ir_mode *mode)
{
370
	return _get_mode_size_bits(mode);
Christian Schäfer's avatar
Christian Schäfer committed
371
372
}

373
374
unsigned (get_mode_size_bytes)(const ir_mode *mode)
{
375
	return _get_mode_size_bytes(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
376
377
}

378
379
int (get_mode_sign)(const ir_mode *mode)
{
380
	return _get_mode_sign(mode);
381
382
}

383
384
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode)
{
385
	return get_mode_arithmetic(mode);
386
387
}

388
389
390
391
392

/* Attribute modulo shift specifies for modes of kind irms_int_number
 *  whether shift applies modulo to value of bits to shift.  Asserts
 *  if mode is not irms_int_number.
 */
393
394
unsigned int (get_mode_modulo_shift)(const ir_mode *mode)
{
395
	return _get_mode_modulo_shift(mode);
396
397
}

398
399
unsigned int (get_mode_n_vector_elems)(const ir_mode *mode)
{
400
	return _get_mode_vector_elems(mode);
401
402
}

403
404
void *(get_mode_link)(const ir_mode *mode)
{
405
	return _get_mode_link(mode);
406
407
}

408
409
void (set_mode_link)(ir_mode *mode, void *l)
{
410
	_set_mode_link(mode, l);
411
412
}

Matthias Braun's avatar
Matthias Braun committed
413
ir_tarval *get_mode_min(ir_mode *mode)
414
{
415
416
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
417

418
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
419
420
}

Matthias Braun's avatar
Matthias Braun committed
421
ir_tarval *get_mode_max(ir_mode *mode)
422
{
423
424
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
425

426
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
427
428
}

Matthias Braun's avatar
Matthias Braun committed
429
ir_tarval *get_mode_null(ir_mode *mode)
430
{
431
	assert(mode);
432
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
433

434
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
435
436
}

Matthias Braun's avatar
Matthias Braun committed
437
ir_tarval *get_mode_one(ir_mode *mode)
438
{
439
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
440
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
441

442
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
443
444
}

Matthias Braun's avatar
Matthias Braun committed
445
ir_tarval *get_mode_minus_one(ir_mode *mode)
446
{
447
448
	assert(mode);
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
449

450
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
451
452
}

Matthias Braun's avatar
Matthias Braun committed
453
ir_tarval *get_mode_all_one(ir_mode *mode)
454
{
455
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
456
	assert(mode_is_datab(mode));
457
458
459
	return mode->all_one;
}

Matthias Braun's avatar
Matthias Braun committed
460
ir_tarval *get_mode_infinite(ir_mode *mode)
461
{
462
463
	assert(mode);
	assert(mode_is_float(mode));
464

465
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
466
467
}

Matthias Braun's avatar
Matthias Braun committed
468
ir_tarval *get_mode_NAN(ir_mode *mode)
469
{
470
471
	assert(mode);
	assert(mode_is_float(mode));
472

473
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
474
475
}

476
477
int is_mode(const void *thing)
{
Michael Beck's avatar
Michael Beck committed
478
	return get_kind(thing) == k_ir_mode;
479
480
}

481
482
int (mode_is_signed)(const ir_mode *mode)
{
483
	return _mode_is_signed(mode);
Christian Schäfer's avatar
Christian Schäfer committed
484
485
}

486
487
int (mode_is_float)(const ir_mode *mode)
{
488
	return _mode_is_float(mode);
Christian Schäfer's avatar
Christian Schäfer committed
489
490
}

491
492
int (mode_is_int)(const ir_mode *mode)
{
493
	return _mode_is_int(mode);
Christian Schäfer's avatar
Christian Schäfer committed
494
495
}

496
497
int (mode_is_reference)(const ir_mode *mode)
{
498
	return _mode_is_reference(mode);
499
500
}

501
502
int (mode_is_num)(const ir_mode *mode)
{
503
	return _mode_is_num(mode);
Christian Schäfer's avatar
Christian Schäfer committed
504
505
}

506
507
int (mode_is_data)(const ir_mode *mode)
{
508
	return _mode_is_data(mode);
Christian Schäfer's avatar
Christian Schäfer committed
509
510
}

511
512
int (mode_is_datab)(const ir_mode *mode)
{
513
	return _mode_is_datab(mode);
Christian Schäfer's avatar
Christian Schäfer committed
514
515
}

516
517
int (mode_is_dataM)(const ir_mode *mode)
{
518
	return _mode_is_dataM(mode);
Christian Schäfer's avatar
Christian Schäfer committed
519
}
520

521
522
int (mode_is_float_vector)(const ir_mode *mode)
{
523
	return _mode_is_float_vector(mode);
524
525
}

526
527
int (mode_is_int_vector)(const ir_mode *mode)
{
528
	return _mode_is_int_vector(mode);
Michael Beck's avatar
Michael Beck committed
529
530
}

531
/* Returns true if sm can be converted to lm without loss. */
532
533
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
534
	int sm_bits, lm_bits;
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

	sm_bits = get_mode_size_bits(sm);
	lm_bits = get_mode_size_bits(lm);

	switch (get_mode_sort(sm)) {
	case irms_int_number:
		switch (get_mode_sort(lm)) {
		case irms_int_number:
			if (get_mode_arithmetic(sm) != get_mode_arithmetic(lm))
				return 0;

			/* only two complement implemented */
			assert(get_mode_arithmetic(sm) == irma_twos_complement);

			/* integers are convertable if
			 *   - both have the same sign and lm is the larger one
			 *   - lm is the signed one and is at least two bits larger
			 *     (one for the sign, one for the highest bit of sm)
			 *   - sm & lm are two_complement and lm has greater or equal number of bits
			 */
			if (mode_is_signed(sm)) {
				if (!mode_is_signed(lm))
					return 0;
				return sm_bits <= lm_bits;
			} else {
				if (mode_is_signed(lm)) {
					return sm_bits < lm_bits;
				}
				return sm_bits <= lm_bits;
			}

		case irms_float_number:
			/* int to float works if the float is large enough */
			return 0;

		default:
			break;
		}
		break;

	case irms_float_number:
		if (get_mode_arithmetic(sm) == get_mode_arithmetic(lm)) {
			if ( (get_mode_sort(lm) == irms_float_number)
				&& (get_mode_size_bits(lm) >= get_mode_size_bits(sm)) )
				return 1;
		}
		break;

	case irms_reference:
Michael Beck's avatar
Michael Beck committed
589
		/* do exist machines out there with different pointer lengths ?*/
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
		return 0;

	case irms_internal_boolean:
		return mode_is_int(lm);

	default:
		break;
	}

	/* else */
	return 0;
}

/* Returns true if a value of mode sm can be converted into mode lm
   and backwards without loss. */
605
606
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
{
Moritz Kroll's avatar
Moritz Kroll committed
607
	ir_mode_arithmetic arith;
608
609
610
611
612
613

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

Moritz Kroll's avatar
Moritz Kroll committed
614
615
616
617
618
	if (sm == mode_b)
		return mode_is_int(lm);

	arith = get_mode_arithmetic(sm);
	if (arith != get_mode_arithmetic(lm))
619
620
		return 0;

Moritz Kroll's avatar
Moritz Kroll committed
621
622
623
624
	switch (arith) {
		case irma_twos_complement:
		case irma_ieee754:
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
625

Moritz Kroll's avatar
Moritz Kroll committed
626
627
		default:
			return 0;
628
629
630
631
	}
}

/* Return the signed integer equivalent mode for an reference mode. */
632
633
ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
{
634
635
636
637
638
	assert(mode_is_reference(mode));
	return mode->eq_signed;
}

/* Sets the signed integer equivalent mode for an reference mode. */
639
640
void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
641
642
643
644
645
646
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_signed = int_mode;
}

/* Return the unsigned integer equivalent mode for an reference mode. */
647
648
ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
{
649
650
651
652
653
	assert(mode_is_reference(mode));
	return mode->eq_unsigned;
}

/* Sets the unsigned integer equivalent mode for an reference mode. */
654
655
void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
656
657
658
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_unsigned = int_mode;
659
660
}

661
/* initialization, build the default modes */
662
663
void init_mode(void)
{
664
	ir_mode newmode;
665

666
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
667
	mode_list = NEW_ARR_F(ir_mode*, 0);
668

669
	/* initialize predefined modes */
670

671
672
673
674
675
676
677
678
679
680
	/* Internal Modes */
	newmode.arithmetic   = irma_none;
	newmode.size         = 0;
	newmode.sign         = 0;
	newmode.modulo_shift = 0;
	newmode.vector_elem  = 0;
	newmode.eq_signed    = NULL;
	newmode.eq_unsigned  = NULL;
	newmode.link         = NULL;
	newmode.tv_priv      = NULL;
681

682
683
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
684

685
686
	/* Basic Block */
	newmode.name    = new_id_from_chars("BB", 2);
687
	mode_BB         = register_mode(&newmode);
688

689
690
	/* eXecution */
	newmode.name    = new_id_from_chars("X", 1);
691
	mode_X          = register_mode(&newmode);
692

693
694
	/* Memory Modes */
	newmode.sort    = irms_memory;
695

696
697
	/* Memory */
	newmode.name    = new_id_from_chars("M", 1);
698
	mode_M          = register_mode(&newmode);
699

700
701
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
702

703
704
	/* Tuple */
	newmode.name    = new_id_from_chars("T", 1);
705
	mode_T          = register_mode(&newmode);
706

707
708
	/* ANY */
	newmode.name    = new_id_from_chars("ANY", 3);
709
	mode_ANY        = register_mode(&newmode);
710

711
712
	/* BAD */
	newmode.name    = new_id_from_chars("BAD", 3);
713
	mode_BAD        = register_mode(&newmode);
714

715
716
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
717

718
719
	/* boolean */
	newmode.name    = new_id_from_chars("b", 1);
720
	mode_b          = register_mode(&newmode);
721

722
723
	/* Data Modes */
	newmode.vector_elem = 1;
724

725
726
727
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
728

729
730
731
732
	/* float */
	newmode.name    = new_id_from_chars("F", 1);
	newmode.sign    = 1;
	newmode.size    = 32;
733
	mode_F          = register_mode(&newmode);
734

735
736
737
738
	/* double */
	newmode.name    = new_id_from_chars("D", 1);
	newmode.sign    = 1;
	newmode.size    = 64;
739
	mode_D          = register_mode(&newmode);
740

741
742
743
	/* extended */
	newmode.name    = new_id_from_chars("E", 1);
	newmode.sign    = 1;
Matthias Braun's avatar
Matthias Braun committed
744
745
746
	/* note that the tarval module is calculating with 80 bits, but we use
	 * 96 bits, as that is what will be stored to memory by most hardware */
	newmode.size    = 96;
747
	mode_E          = register_mode(&newmode);
748

749
750
751
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
752

753
754
755
756
757
	/* signed byte */
	newmode.name         = new_id_from_chars("Bs", 2);
	newmode.sign         = 1;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
758
	mode_Bs              = register_mode(&newmode);
759

760
761
762
763
764
765
	/* unsigned byte */
	newmode.name         = new_id_from_chars("Bu", 2);
	newmode.arithmetic   = irma_twos_complement;
	newmode.sign         = 0;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
766
	mode_Bu              = register_mode(&newmode);
767

768
769
770
771
772
	/* signed short integer */
	newmode.name         = new_id_from_chars("Hs", 2);
	newmode.sign         = 1;
	newmode.size         = 16;
	newmode.modulo_shift = 32;
773
	mode_Hs              = register_mode(&newmode);
774

775
776
777
778
779
	/* unsigned short integer */
	newmode.name         = new_id_from_chars("Hu", 2);
	newmode.sign         = 0;
	newmode.size         = 16;
	newmode.modulo_shift = 32;
780
	mode_Hu              = register_mode(&newmode);
781

782
783
784
785
786
	/* signed integer */
	newmode.name         = new_id_from_chars("Is", 2);
	newmode.sign         = 1;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
787
	mode_Is              = register_mode(&newmode);
788

789
790
791
792
793
	/* unsigned integer */
	newmode.name         = new_id_from_chars("Iu", 2);
	newmode.sign         = 0;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
794
	mode_Iu              = register_mode(&newmode);
795
796
797
798
799
800

	/* signed long integer */
	newmode.name         = new_id_from_chars("Ls", 2);
	newmode.sign         = 1;
	newmode.size         = 64;
	newmode.modulo_shift = 64;
801
	mode_Ls              = register_mode(&newmode);
802
803
804
805
806
807

	/* unsigned long integer */
	newmode.name         = new_id_from_chars("Lu", 2);
	newmode.sign         = 0;
	newmode.size         = 64;
	newmode.modulo_shift = 64;
808
	mode_Lu              = register_mode(&newmode);
809

810
811
812
813
814
	/* signed long long integer */
	newmode.name         = new_id_from_chars("LLs", 3);
	newmode.sign         = 1;
	newmode.size         = 128;
	newmode.modulo_shift = 128;
815
	mode_LLs             = register_mode(&newmode);
816
817
818
819
820
821

	/* unsigned long long integer */
	newmode.name         = new_id_from_chars("LLu", 3);
	newmode.sign         = 0;
	newmode.size         = 128;
	newmode.modulo_shift = 128;
822
	mode_LLu             = register_mode(&newmode);
823

824
825
	/* Reference Mode */
	newmode.sort       = irms_reference;
826
827
828
829
830
831
	newmode.arithmetic = irma_twos_complement;

	/* pointer */
	newmode.name         = new_id_from_chars("P", 1);
	newmode.sign         = 0;
	newmode.size         = 32;
832
	newmode.modulo_shift = 32;
833
834
	newmode.eq_signed    = mode_Is;
	newmode.eq_unsigned  = mode_Iu;
835
	mode_P               = register_mode(&newmode);
836
837
838
839

	/* set the machine specific modes to the predefined ones */
	mode_P_code = mode_P;
	mode_P_data = mode_P;
840
}
841

Michael Beck's avatar
Michael Beck committed
842
/* find a signed mode for an unsigned integer mode */
843
844
ir_mode *find_unsigned_mode(const ir_mode *mode)
{
845
	ir_mode n = *mode;
846

847
848
849
850
851
	/* allowed for reference mode */
	if (mode->sort == irms_reference)
		n.sort = irms_int_number;

	assert(n.sort == irms_int_number);
852
853
	n.sign = 0;
	return find_mode(&n);
854
855
}

Michael Beck's avatar
Michael Beck committed
856
/* find an unsigned mode for a signed integer mode */
857
858
ir_mode *find_signed_mode(const ir_mode *mode)
{
859
	ir_mode n = *mode;
860

861
862
863
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
864
865
}

Michael Beck's avatar
Michael Beck committed
866
/* finds a integer mode with 2*n bits for an integer mode with n bits. */
867
868
ir_mode *find_double_bits_int_mode(const ir_mode *mode)
{
869
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
870

871
	assert(mode->sort == irms_int_number && mode->arithmetic == irma_twos_complement);
Michael Beck's avatar
Michael Beck committed
872

873
874
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
875
}
876

877
878
879
880
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
881
882
int mode_honor_signed_zeros(const ir_mode *mode)
{
883
884
885
	/* for floating point, we know that IEEE 754 has +0 and -0,
	 * but always handles it identical.
	 */
Christian Würdig's avatar
Christian Würdig committed
886
887
888
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
889
890
}

891
892
893
894
895
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
896
897
int mode_overflow_on_unary_Minus(const ir_mode *mode)
{
898
899
900
	if (mode->sort == irms_float_number)
		return mode->arithmetic == irma_ieee754 ? 0 : 1;
	return 1;
901
902
}

Michael Beck's avatar
Michael Beck committed
903
/*
904
 * Returns non-zero if the mode has a reversed wrap-around
Michael Beck's avatar
Michael Beck committed
905
906
907
908
909
 * logic, especially (a + x) - x == a.
 *
 * This is normally true for integer modes, not for floating
 * point modes.
 */
910
911
int mode_wrap_around(const ir_mode *mode)
{
912
913
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
914
915
}

916
917
918
919
920
/*
 * Returns non-zero if the cast from mode src to mode dst is a
 * reinterpret cast (ie. only the bit pattern is reinterpreted,
 * no conversion is done)
 */
921
922
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
{
923
924
925
926
927
928
929
930
931
932
933
934
935
	ir_mode_arithmetic ma;

	if (src == dst)
		return 1;
	if (get_mode_size_bits(src) != get_mode_size_bits(dst))
		return 0;
	ma = get_mode_arithmetic(src);
	if (ma != get_mode_arithmetic(dst))
		return 0;

	return ma == irma_twos_complement || ma == irma_ones_complement;
}

936
937
938
939
940
ir_type *(get_type_for_mode) (const ir_mode *mode)
{
	return get_type_for_mode_(mode);
}

941
942
void finish_mode(void)
{
943
	obstack_free(&modes, 0);
Matthias Braun's avatar
Matthias Braun committed
944
	DEL_ARR_F(mode_list);
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967

	mode_T   = NULL;
	mode_X   = NULL;
	mode_M   = NULL;
	mode_BB  = NULL;
	mode_ANY = NULL;
	mode_BAD = NULL;

	mode_F   = NULL;
	mode_D   = NULL;
	mode_E   = NULL;

	mode_Bs  = NULL;
	mode_Bu  = NULL;
	mode_Hs  = NULL;
	mode_Hu  = NULL;
	mode_Is  = NULL;
	mode_Iu  = NULL;
	mode_Ls  = NULL;
	mode_Lu  = NULL;

	mode_b   = NULL;

968
	mode_P      = NULL;
969
970
	mode_P_code = NULL;
	mode_P_data = NULL;
971
}