irmode.c 15.7 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
 */
Matthias Braun's avatar
Matthias Braun committed
11
#include "config.h"
Boris Boesler's avatar
added    
Boris Boesler committed
12

Moritz Kroll's avatar
Moritz Kroll committed
13
14
15
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
16
#include <stdbool.h>
17

Moritz Kroll's avatar
Moritz Kroll committed
18
19
20
21
22
23
24
25
26
#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"
27
#include "pattern_dmp.h"
Christian Schäfer's avatar
Christian Schäfer committed
28

Michael Beck's avatar
Michael Beck committed
29
/** Obstack to hold all modes. */
30
static struct obstack modes;
Christian Schäfer's avatar
Christian Schäfer committed
31

Michael Beck's avatar
Michael Beck committed
32
/** The list of all currently existing modes. */
Matthias Braun's avatar
Matthias Braun committed
33
34
static ir_mode **mode_list;

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

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

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

	case irms_control_flow:
91
92
93
94
95
	case irms_block:
	case irms_tuple:
	case irms_any:
	case irms_bad:
	case irms_memory:
96
97
98
99
100
101
102
		mode->min  = tarval_bad;
		mode->max  = tarval_bad;
		mode->null = tarval_bad;
		mode->one  = tarval_bad;
		mode->minus_one = tarval_bad;
		break;
	}
103
}
104

105
106
107
108
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
109
110
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
111

112
113
114
ir_mode *mode_F;
ir_mode *mode_D;
ir_mode *mode_Q;
Christian Schäfer's avatar
Christian Schäfer committed
115

116
117
118
ir_mode *mode_Bs;
ir_mode *mode_Bu;
ir_mode *mode_Hs;
119
ir_mode *mode_Hu;
120
ir_mode *mode_Is;
121
ir_mode *mode_Iu;
122
ir_mode *mode_Ls;
123
ir_mode *mode_Lu;
124
ir_mode *mode_LLs;
125
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
126

127
128
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
129

130
131
ir_mode *mode_P_code;
ir_mode *mode_P_data;
132

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

155

156
157
ir_mode *(get_modeP_code)(void)
{
158
	return get_modeP_code_();
Michael Beck's avatar
Michael Beck committed
159
160
}

161
162
ir_mode *(get_modeP_data)(void)
{
163
	return get_modeP_data_();
164
165
}

166
167
void set_modeP_code(ir_mode *p)
{
168
169
	assert(mode_is_reference(p));
	mode_P_code = p;
170
171
}

172
173
void set_modeP_data(ir_mode *p)
{
174
175
	assert(mode_is_reference(p));
	mode_P_data = p;
176
	mode_P = p;
Michael Beck's avatar
Michael Beck committed
177
}
178

179
180
/*
 * Creates a new mode.
181
 */
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
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;
	}
208

209
	mode->kind = k_ir_mode;
210
	mode->type = new_type_primitive(mode);
211
	ARR_APP1(ir_mode*, mode_list, mode);
212
	set_mode_values(mode);
213
	hook_new_mode(mode);
214
	return mode;
215
216
}

217
218
219
220
221
222
223
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);
}
224

225
226
227
228
229
230
231
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);
}
232

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

251
	result = alloc_mode(name, irms_float_number, irma_x86_extended_float, bit_size, 1, 0);
252
253
254
255
	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);
256
257
}

258
259
ident *(get_mode_ident)(const ir_mode *mode)
{
260
	return get_mode_ident_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
261
262
}

263
264
const char *get_mode_name(const ir_mode *mode)
{
265
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
266
267
}

268
269
unsigned (get_mode_size_bits)(const ir_mode *mode)
{
270
	return get_mode_size_bits_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
271
272
}

273
274
unsigned (get_mode_size_bytes)(const ir_mode *mode)
{
275
	return get_mode_size_bytes_(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
276
277
}

278
279
int (get_mode_sign)(const ir_mode *mode)
{
280
	return get_mode_sign_(mode);
281
282
}

283
284
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode)
{
285
	return get_mode_arithmetic_(mode);
286
287
}

288

289
290
unsigned int (get_mode_modulo_shift)(const ir_mode *mode)
{
291
	return get_mode_modulo_shift_(mode);
292
293
}

294
295
void *(get_mode_link)(const ir_mode *mode)
{
296
	return get_mode_link_(mode);
297
298
}

299
300
void (set_mode_link)(ir_mode *mode, void *l)
{
301
	set_mode_link_(mode, l);
302
303
}

Matthias Braun's avatar
Matthias Braun committed
304
ir_tarval *get_mode_min(ir_mode *mode)
305
{
306
307
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
308

309
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
310
311
}

Matthias Braun's avatar
Matthias Braun committed
312
ir_tarval *get_mode_max(ir_mode *mode)
313
{
314
315
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
316

317
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
318
319
}

Matthias Braun's avatar
Matthias Braun committed
320
ir_tarval *get_mode_null(ir_mode *mode)
321
{
322
	assert(mode);
323
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
324

325
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
326
327
}

Matthias Braun's avatar
Matthias Braun committed
328
ir_tarval *get_mode_one(ir_mode *mode)
329
{
330
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
331
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
332

333
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
334
335
}

Matthias Braun's avatar
Matthias Braun committed
336
ir_tarval *get_mode_minus_one(ir_mode *mode)
337
{
338
339
	assert(mode);
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
340

341
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
342
343
}

Matthias Braun's avatar
Matthias Braun committed
344
ir_tarval *get_mode_all_one(ir_mode *mode)
345
{
346
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
347
	assert(mode_is_datab(mode));
348
349
350
	return mode->all_one;
}

Matthias Braun's avatar
Matthias Braun committed
351
ir_tarval *get_mode_infinite(ir_mode *mode)
352
{
353
354
	assert(mode);
	assert(mode_is_float(mode));
355

356
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
357
358
}

Matthias Braun's avatar
Matthias Braun committed
359
ir_tarval *get_mode_NAN(ir_mode *mode)
360
{
361
362
	assert(mode);
	assert(mode_is_float(mode));
363

364
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
365
366
}

367
368
int is_mode(const void *thing)
{
Michael Beck's avatar
Michael Beck committed
369
	return get_kind(thing) == k_ir_mode;
370
371
}

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

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

382
383
int (mode_is_int)(const ir_mode *mode)
{
384
	return mode_is_int_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
385
386
}

387
388
int (mode_is_reference)(const ir_mode *mode)
{
389
	return mode_is_reference_(mode);
390
391
}

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

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

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

407
408
int (mode_is_dataM)(const ir_mode *mode)
{
409
	return mode_is_dataM_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
410
}
411

412
413
414
415
416
417
418
419
420
421
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);
}

422
423
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
424
	int sm_bits, lm_bits;
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
475
476
477
478

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

	case irms_internal_boolean:
		return mode_is_int(lm);

	default:
		break;
	}

	/* else */
	return 0;
}

493
494
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
{
495
496
	if (sm == lm)
		return true;
497

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

525
526
ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
{
527
528
529
530
	assert(mode_is_reference(mode));
	return mode->eq_signed;
}

531
532
void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
533
534
535
536
537
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_signed = int_mode;
}

538
539
ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
{
540
541
542
543
	assert(mode_is_reference(mode));
	return mode->eq_unsigned;
}

544
545
void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
546
547
548
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_unsigned = int_mode;
549
550
}

551
552
553
554
555
556
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);
}

557
558
void init_mode(void)
{
559
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
560
	mode_list = NEW_ARR_F(ir_mode*, 0);
561

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

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

595
596
ir_mode *find_unsigned_mode(const ir_mode *mode)
{
597
	ir_mode n = *mode;
598

599
600
601
602
603
	/* allowed for reference mode */
	if (mode->sort == irms_reference)
		n.sort = irms_int_number;

	assert(n.sort == irms_int_number);
604
605
	n.sign = 0;
	return find_mode(&n);
606
607
}

608
609
ir_mode *find_signed_mode(const ir_mode *mode)
{
610
	ir_mode n = *mode;
611

612
613
614
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
615
616
}

617
618
ir_mode *find_double_bits_int_mode(const ir_mode *mode)
{
619
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
620

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

623
624
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
625
}
626

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

637
638
int mode_overflow_on_unary_Minus(const ir_mode *mode)
{
639
640
641
	if (mode->sort == irms_float_number)
		return mode->arithmetic == irma_ieee754 ? 0 : 1;
	return 1;
642
643
}

644
645
int mode_wrap_around(const ir_mode *mode)
{
646
647
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
648
649
}

650
651
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
{
652
653
654
655
656
657
658
659
660
661
	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;

662
	return ma == irma_twos_complement;
663
664
}

665
666
667
668
669
ir_type *(get_type_for_mode) (const ir_mode *mode)
{
	return get_type_for_mode_(mode);
}

Matthias Braun's avatar
Matthias Braun committed
670
671
672
673
674
675
676
677
678
679
680
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];
}

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

	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;

707
	mode_P      = NULL;
708
709
	mode_P_code = NULL;
	mode_P_data = NULL;
710
}