irmode.c 15.6 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
203
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;
	mode_tmpl->tv_priv      = 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;
	}
204

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

213
214
215
216
217
218
219
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);
}
220

221
222
223
224
225
226
227
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);
}
228

229
230
231
232
233
234
235
236
237
238
239
240
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");
241
	}
242
243
244
245
246
	if (exponent_size >= 256)
		panic("Exponents >= 256 bits not supported");
	if (mantissa_size >= 256)
		panic("Mantissa >= 256 bits not supported");

247
	result = alloc_mode(name, irms_float_number, arithmetic, bit_size, 1, 0);
248
249
250
251
	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);
252
253
}

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

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

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

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

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

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

284

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

408
409
410
411
412
413
414
415
416
417
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);
}

418
419
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
420
	int sm_bits, lm_bits;
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
474

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

	case irms_internal_boolean:
		return mode_is_int(lm);

	default:
		break;
	}

	/* else */
	return 0;
}

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

Moritz Kroll's avatar
Moritz Kroll committed
494
	if (sm == mode_b)
495
496
497
498
499
500
501
502
		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
503
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
504
505
506
507
508
509
510
511
512
513
514
515
516
		} 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;
517
	}
518
	return false;
519
520
}

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

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

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

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

547
548
549
550
551
552
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);
}

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

558
	/* initialize predefined modes */
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
	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);
583
584
	set_reference_mode_signed_eq(mode_P, mode_Is);
	set_reference_mode_unsigned_eq(mode_P, mode_Iu);
585
586
587
588

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

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

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

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

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

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

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

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

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

623
624
int mode_honor_signed_zeros(const ir_mode *mode)
{
625
626
627
	/* 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
628
629
630
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
631
632
}

633
634
int mode_overflow_on_unary_Minus(const ir_mode *mode)
{
635
636
637
	if (mode->sort == irms_float_number)
		return mode->arithmetic == irma_ieee754 ? 0 : 1;
	return 1;
638
639
}

640
641
int mode_wrap_around(const ir_mode *mode)
{
642
643
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
644
645
}

646
647
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
{
648
649
650
651
652
653
654
655
656
657
	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;

658
	return ma == irma_twos_complement;
659
660
}

661
662
663
664
665
ir_type *(get_type_for_mode) (const ir_mode *mode)
{
	return get_type_for_mode_(mode);
}

Matthias Braun's avatar
Matthias Braun committed
666
667
668
669
670
671
672
673
674
675
676
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];
}

677
678
void finish_mode(void)
{
679
	obstack_free(&modes, 0);
Matthias Braun's avatar
Matthias Braun committed
680
	DEL_ARR_F(mode_list);
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702

	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;

703
	mode_P      = NULL;
704
705
	mode_P_code = NULL;
	mode_P_data = NULL;
706
}