irmode.c 15.8 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

Matthias Braun's avatar
Matthias Braun committed
6
7
8
9
/**
 * @file
 * @brief    Data modes of operations.
 * @author   Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Mathias Heil
Götz Lindenmaier's avatar
Götz Lindenmaier committed
10
 */
Moritz Kroll's avatar
Moritz Kroll committed
11
12
#include <stdlib.h>
#include <stddef.h>
13
#include <stdbool.h>
14

Moritz Kroll's avatar
Moritz Kroll committed
15
16
17
18
19
20
21
22
#include "irprog_t.h"
#include "irmode_t.h"
#include "ident.h"
#include "tv_t.h"
#include "obst.h"
#include "irhooks.h"
#include "array.h"
#include "error.h"
23
#include "pattern_dmp.h"
Christian Schäfer's avatar
Christian Schäfer committed
24

Michael Beck's avatar
Michael Beck committed
25
/** Obstack to hold all modes. */
26
static struct obstack modes;
Christian Schäfer's avatar
Christian Schäfer committed
27

Michael Beck's avatar
Michael Beck committed
28
/** The list of all currently existing modes. */
Matthias Braun's avatar
Matthias Braun committed
29
30
static ir_mode **mode_list;

31
static bool modes_are_equal(const ir_mode *m, const ir_mode *n)
32
{
33
34
35
36
37
	return m->sort         == n->sort &&
	       m->arithmetic   == n->arithmetic &&
	       m->size         == n->size &&
	       m->sign         == n->sign &&
	       m->modulo_shift == n->modulo_shift;
38
}
Matthias Heil's avatar
Matthias Heil committed
39

40
/**
41
 * searches the modes obstack for the given mode and returns
42
 * a pointer on an equal mode already in the array, NULL if
43
44
 * none found
 */
45
46
static ir_mode *find_mode(const ir_mode *m)
{
47
48
	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
49
		ir_mode *n = mode_list[i];
50
51
52
		if (modes_are_equal(n, m))
			return n;
	}
Michael Beck's avatar
Michael Beck committed
53
54
55
	return NULL;
}

56
57
58
/**
 * sets special values of modes
 */
59
60
static void set_mode_values(ir_mode* mode)
{
61
	switch (get_mode_sort(mode))    {
62
	case irms_reference:
63
64
65
66
67
68
69
	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);
70
		if (get_mode_sort(mode) != irms_float_number) {
71
72
73
74
			mode->all_one = get_tarval_all_one(mode);
		} else {
			mode->all_one = tarval_bad;
		}
75
76
77
78
79
80
81
82
		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;
83
		mode->all_one = tarval_b_true;
84
85
86
		break;

	case irms_control_flow:
87
88
89
90
91
	case irms_block:
	case irms_tuple:
	case irms_any:
	case irms_bad:
	case irms_memory:
92
93
94
95
96
97
98
		mode->min  = tarval_bad;
		mode->max  = tarval_bad;
		mode->null = tarval_bad;
		mode->one  = tarval_bad;
		mode->minus_one = tarval_bad;
		break;
	}
99
}
100

101
102
103
104
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
105
106
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
107

108
109
110
ir_mode *mode_F;
ir_mode *mode_D;
ir_mode *mode_Q;
Christian Schäfer's avatar
Christian Schäfer committed
111

112
113
114
ir_mode *mode_Bs;
ir_mode *mode_Bu;
ir_mode *mode_Hs;
115
ir_mode *mode_Hu;
116
ir_mode *mode_Is;
117
ir_mode *mode_Iu;
118
ir_mode *mode_Ls;
119
ir_mode *mode_Lu;
120
ir_mode *mode_LLs;
121
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
122

123
124
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
125

126
127
ir_mode *mode_P_code;
ir_mode *mode_P_data;
128

129
130
131
ir_mode *get_modeT(void) { return mode_T; }
ir_mode *get_modeF(void) { return mode_F; }
ir_mode *get_modeD(void) { return mode_D; }
132
ir_mode *get_modeQ(void) { return mode_Q; }
133
134
135
136
137
138
139
140
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; }
141
142
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
143
144
145
146
147
148
149
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; }
150

151

152
153
ir_mode *(get_modeP_code)(void)
{
154
	return get_modeP_code_();
Michael Beck's avatar
Michael Beck committed
155
156
}

157
158
ir_mode *(get_modeP_data)(void)
{
159
	return get_modeP_data_();
160
161
}

162
163
void set_modeP_code(ir_mode *p)
{
164
165
	assert(mode_is_reference(p));
	mode_P_code = p;
166
167
}

168
169
void set_modeP_data(ir_mode *p)
{
170
171
	assert(mode_is_reference(p));
	mode_P_data = p;
172
	mode_P = p;
Michael Beck's avatar
Michael Beck committed
173
}
174

175
176
/*
 * Creates a new mode.
177
 */
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
static ir_mode *alloc_mode(const char *name, ir_mode_sort sort,
                           ir_mode_arithmetic arithmetic, unsigned bit_size,
                           int sign, unsigned modulo_shift)
{
	ir_mode *mode_tmpl = OALLOCZ(&modes, ir_mode);

	mode_tmpl->name         = new_id_from_str(name);
	mode_tmpl->sort         = sort;
	mode_tmpl->size         = bit_size;
	mode_tmpl->sign         = sign ? 1 : 0;
	mode_tmpl->modulo_shift = modulo_shift;
	mode_tmpl->arithmetic   = arithmetic;
	mode_tmpl->link         = NULL;
	return mode_tmpl;
}

static ir_mode *register_mode(ir_mode *mode)
{
	/* does any of the existing modes have the same properties? */
	ir_mode *old = find_mode(mode);
	if (old != NULL) {
		/* remove new mode from obstack */
		obstack_free(&modes, mode);
		return old;
	}
203

204
	mode->kind = k_ir_mode;
205
	mode->type = new_type_primitive(mode);
206
	ARR_APP1(ir_mode*, mode_list, mode);
207
	set_mode_values(mode);
208
	hook_new_mode(mode);
209
	return mode;
210
211
}

212
213
214
215
216
217
218
ir_mode *new_int_mode(const char *name, ir_mode_arithmetic arithmetic,
                      unsigned bit_size, int sign, unsigned modulo_shift)
{
	ir_mode *result = alloc_mode(name, irms_int_number, arithmetic, bit_size,
	                             sign, modulo_shift);
	return register_mode(result);
}
219

220
221
222
223
224
225
226
ir_mode *new_reference_mode(const char *name, ir_mode_arithmetic arithmetic,
                            unsigned bit_size, unsigned modulo_shift)
{
	ir_mode *result = alloc_mode(name, irms_reference, arithmetic, bit_size,
	                             0, modulo_shift);
	return register_mode(result);
}
227

228
229
230
231
232
233
234
235
236
237
238
239
ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic,
                        unsigned exponent_size, unsigned mantissa_size)
{
	bool     explicit_one = false;
	unsigned bit_size     = exponent_size + mantissa_size + 1;
	ir_mode *result;

	if (arithmetic == irma_x86_extended_float) {
		explicit_one = true;
		bit_size++;
	} else if (arithmetic != irma_ieee754) {
		panic("Arithmetic %s invalid for float");
240
	}
241
242
243
244
245
	if (exponent_size >= 256)
		panic("Exponents >= 256 bits not supported");
	if (mantissa_size >= 256)
		panic("Mantissa >= 256 bits not supported");

246
	result = alloc_mode(name, irms_float_number, arithmetic, bit_size, 1, 0);
247
248
249
250
	result->float_desc.exponent_size = exponent_size;
	result->float_desc.mantissa_size = mantissa_size;
	result->float_desc.explicit_one  = explicit_one;
	return register_mode(result);
251
252
}

253
254
ident *(get_mode_ident)(const ir_mode *mode)
{
255
	return get_mode_ident_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
256
257
}

258
259
const char *get_mode_name(const ir_mode *mode)
{
260
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
261
262
}

263
264
unsigned (get_mode_size_bits)(const ir_mode *mode)
{
265
	return get_mode_size_bits_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
266
267
}

268
269
unsigned (get_mode_size_bytes)(const ir_mode *mode)
{
270
	return get_mode_size_bytes_(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
271
272
}

273
274
int (get_mode_sign)(const ir_mode *mode)
{
275
	return get_mode_sign_(mode);
276
277
}

278
279
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode)
{
280
	return get_mode_arithmetic_(mode);
281
282
}

283

284
285
unsigned int (get_mode_modulo_shift)(const ir_mode *mode)
{
286
	return get_mode_modulo_shift_(mode);
287
288
}

289
290
void *(get_mode_link)(const ir_mode *mode)
{
291
	return get_mode_link_(mode);
292
293
}

294
295
void (set_mode_link)(ir_mode *mode, void *l)
{
296
	set_mode_link_(mode, l);
297
298
}

Matthias Braun's avatar
Matthias Braun committed
299
ir_tarval *get_mode_min(ir_mode *mode)
300
{
301
302
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
303

304
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
305
306
}

Matthias Braun's avatar
Matthias Braun committed
307
ir_tarval *get_mode_max(ir_mode *mode)
308
{
309
310
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
311

312
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
313
314
}

Matthias Braun's avatar
Matthias Braun committed
315
ir_tarval *get_mode_null(ir_mode *mode)
316
{
317
	assert(mode);
318
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
319

320
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
321
322
}

Matthias Braun's avatar
Matthias Braun committed
323
ir_tarval *get_mode_one(ir_mode *mode)
324
{
325
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
326
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
327

328
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
329
330
}

Matthias Braun's avatar
Matthias Braun committed
331
ir_tarval *get_mode_minus_one(ir_mode *mode)
332
{
333
334
	assert(mode);
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
335

336
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
337
338
}

Matthias Braun's avatar
Matthias Braun committed
339
ir_tarval *get_mode_all_one(ir_mode *mode)
340
{
341
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
342
	assert(mode_is_datab(mode));
343
344
345
	return mode->all_one;
}

Matthias Braun's avatar
Matthias Braun committed
346
ir_tarval *get_mode_infinite(ir_mode *mode)
347
{
348
349
	assert(mode);
	assert(mode_is_float(mode));
350

351
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
352
353
}

Matthias Braun's avatar
Matthias Braun committed
354
ir_tarval *get_mode_NAN(ir_mode *mode)
355
{
356
357
	assert(mode);
	assert(mode_is_float(mode));
358

359
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
360
361
}

362
363
int is_mode(const void *thing)
{
Michael Beck's avatar
Michael Beck committed
364
	return get_kind(thing) == k_ir_mode;
365
366
}

367
368
int (mode_is_signed)(const ir_mode *mode)
{
369
	return mode_is_signed_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
370
371
}

372
373
int (mode_is_float)(const ir_mode *mode)
{
374
	return mode_is_float_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
375
376
}

377
378
int (mode_is_int)(const ir_mode *mode)
{
379
	return mode_is_int_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
380
381
}

382
383
int (mode_is_reference)(const ir_mode *mode)
{
384
	return mode_is_reference_(mode);
385
386
}

387
388
int (mode_is_num)(const ir_mode *mode)
{
389
	return mode_is_num_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
390
391
}

392
393
int (mode_is_data)(const ir_mode *mode)
{
394
	return mode_is_data_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
395
396
}

397
398
int (mode_is_datab)(const ir_mode *mode)
{
399
	return mode_is_datab_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
400
401
}

402
403
int (mode_is_dataM)(const ir_mode *mode)
{
404
	return mode_is_dataM_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
405
}
406

407
408
409
410
411
412
413
414
415
416
unsigned (get_mode_mantissa_size)(const ir_mode *mode)
{
	return get_mode_mantissa_size_(mode);
}

unsigned (get_mode_exponent_size)(const ir_mode *mode)
{
	return get_mode_exponent_size_(mode);
}

417
418
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
419
	int sm_bits, lm_bits;
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473

	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
474
		/* do exist machines out there with different pointer lengths ?*/
475
476
477
478
479
480
481
482
483
484
485
486
487
		return 0;

	case irms_internal_boolean:
		return mode_is_int(lm);

	default:
		break;
	}

	/* else */
	return 0;
}

488
489
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
{
490
491
	if (sm == lm)
		return true;
492

Moritz Kroll's avatar
Moritz Kroll committed
493
	if (sm == mode_b)
494
495
496
497
498
499
500
501
		return mode_is_int(lm) || mode_is_float(lm);

	ir_mode_arithmetic larith = get_mode_arithmetic(lm);
	ir_mode_arithmetic sarith = get_mode_arithmetic(sm);
	switch (larith) {
	case irma_x86_extended_float:
	case irma_ieee754:
		if (sarith == irma_ieee754 || sarith == irma_x86_extended_float) {
Moritz Kroll's avatar
Moritz Kroll committed
502
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
503
504
505
506
507
508
509
510
511
512
513
514
515
		} else if (sarith == irma_twos_complement) {
			unsigned int_mantissa   = get_mode_size_bits(sm) - (mode_is_signed(sm) ? 1 : 0);
			unsigned float_mantissa = get_mode_mantissa_size(lm) + 1;
			return int_mantissa <= float_mantissa;
		}
		break;
	case irma_twos_complement:
		if (sarith == irma_twos_complement) {
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
		}
		break;
	case irma_none:
		break;
516
	}
517
	return false;
518
519
}

520
521
ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
{
522
523
524
525
	assert(mode_is_reference(mode));
	return mode->eq_signed;
}

526
527
void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
528
529
530
531
532
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_signed = int_mode;
}

533
534
ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
{
535
536
537
538
	assert(mode_is_reference(mode));
	return mode->eq_unsigned;
}

539
540
void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
541
542
543
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_unsigned = int_mode;
544
545
}

546
547
548
549
550
551
static ir_mode *new_internal_mode(const char *name, ir_mode_sort sort)
{
	ir_mode *mode = alloc_mode(name, sort, irma_none, 0, 0, 0);
	return register_mode(mode);
}

552
553
void init_mode(void)
{
554
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
555
	mode_list = NEW_ARR_F(ir_mode*, 0);
556

557
	/* initialize predefined modes */
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
	mode_BB  = new_internal_mode("BB",  irms_block);
	mode_X   = new_internal_mode("X",   irms_control_flow);
	mode_M   = new_internal_mode("M",   irms_memory);
	mode_T   = new_internal_mode("T",   irms_tuple);
	mode_ANY = new_internal_mode("ANY", irms_any);
	mode_BAD = new_internal_mode("BAD", irms_bad);
	mode_b   = new_internal_mode("b",   irms_internal_boolean);

	mode_F   = new_float_mode("F", irma_ieee754,  8, 23);
	mode_D   = new_float_mode("D", irma_ieee754, 11, 52);
	mode_Q   = new_float_mode("Q", irma_ieee754, 15, 112);

	mode_Bs  = new_int_mode("Bs",  irma_twos_complement, 8,   1, 32);
	mode_Bu  = new_int_mode("Bu",  irma_twos_complement, 8,   0, 32);
	mode_Hs  = new_int_mode("Hs",  irma_twos_complement, 16,  1, 32);
	mode_Hu  = new_int_mode("Hu",  irma_twos_complement, 16,  0, 32);
	mode_Is  = new_int_mode("Is",  irma_twos_complement, 32,  1, 32);
	mode_Iu  = new_int_mode("Iu",  irma_twos_complement, 32,  0, 32);
	mode_Ls  = new_int_mode("Ls",  irma_twos_complement, 64,  1, 64);
	mode_Lu  = new_int_mode("Lu",  irma_twos_complement, 64,  0, 64);
	mode_LLs = new_int_mode("LLs", irma_twos_complement, 128, 1, 128);
	mode_LLu = new_int_mode("LLu", irma_twos_complement, 128, 0, 128);

	mode_P   = new_reference_mode("P", irma_twos_complement, 32, 32);
582
583
	set_reference_mode_signed_eq(mode_P, mode_Is);
	set_reference_mode_unsigned_eq(mode_P, mode_Iu);
584
585
586
587

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

590
591
ir_mode *find_unsigned_mode(const ir_mode *mode)
{
592
	ir_mode n = *mode;
593

594
595
596
597
598
	/* allowed for reference mode */
	if (mode->sort == irms_reference)
		n.sort = irms_int_number;

	assert(n.sort == irms_int_number);
599
600
	n.sign = 0;
	return find_mode(&n);
601
602
}

603
604
ir_mode *find_signed_mode(const ir_mode *mode)
{
605
	ir_mode n = *mode;
606

607
608
609
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
610
611
}

612
613
ir_mode *find_double_bits_int_mode(const ir_mode *mode)
{
614
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
615

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

618
619
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
620
}
621

622
623
624
625
626
627
628
629
630
631
int mode_has_signed_zero(const ir_mode *mode)
{
	switch (mode->arithmetic) {
	case irma_ieee754:
	case irma_x86_extended_float:
		return 1;
	case irma_none:
	case irma_twos_complement:
		return 0;
	}
632
	panic("invalid arithmetic mode");
633
634
}

635
636
int mode_overflow_on_unary_Minus(const ir_mode *mode)
{
637
638
639
640
641
642
643
644
645
	switch (mode->arithmetic) {
	case irma_twos_complement:
		return 1;
	case irma_ieee754:
	case irma_x86_extended_float:
	case irma_none:
		return 0;
	}
	panic("invalid arithmetic mode");
646
647
}

648
649
int mode_wrap_around(const ir_mode *mode)
{
650
651
652
653
654
655
656
657
658
	switch (mode->arithmetic) {
	case irma_twos_complement:
	case irma_none:
		return 1;
	case irma_ieee754:
	case irma_x86_extended_float:
		return 0;
	}
	panic("invalid arithmetic mode");
Michael Beck's avatar
Michael Beck committed
659
660
}

661
662
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
{
663
664
665
666
667
668
669
670
671
672
	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;

673
	return ma == irma_twos_complement;
674
675
}

676
677
678
679
680
ir_type *(get_type_for_mode) (const ir_mode *mode)
{
	return get_type_for_mode_(mode);
}

Matthias Braun's avatar
Matthias Braun committed
681
682
683
684
685
686
687
688
689
690
691
size_t ir_get_n_modes(void)
{
	return ARR_LEN(mode_list);
}

ir_mode *ir_get_mode(size_t num)
{
	assert(num < ARR_LEN(mode_list));
	return mode_list[num];
}

692
693
void finish_mode(void)
{
694
	obstack_free(&modes, 0);
Matthias Braun's avatar
Matthias Braun committed
695
	DEL_ARR_F(mode_list);
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717

	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_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;

718
	mode_P      = NULL;
719
720
	mode_P_code = NULL;
	mode_P_data = NULL;
721
}