irmode.c 15.9 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
/**
 * @file
 * @brief    Data modes of operations.
 * @author   Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Mathias Heil
Götz Lindenmaier's avatar
Götz Lindenmaier committed
24
 */
Matthias Braun's avatar
Matthias Braun committed
25
#include "config.h"
Boris Boesler's avatar
added    
Boris Boesler committed
26

Moritz Kroll's avatar
Moritz Kroll committed
27
28
29
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
30
#include <stdbool.h>
31

Moritz Kroll's avatar
Moritz Kroll committed
32
33
34
35
36
37
38
39
40
#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"
41
#include "pattern_dmp.h"
Christian Schäfer's avatar
Christian Schäfer committed
42

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

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

49
static bool modes_are_equal(const ir_mode *m, const ir_mode *n)
50
{
51
52
53
54
55
	return m->sort         == n->sort &&
	       m->arithmetic   == n->arithmetic &&
	       m->size         == n->size &&
	       m->sign         == n->sign &&
	       m->modulo_shift == n->modulo_shift;
56
}
Matthias Heil's avatar
Matthias Heil committed
57

58
/**
59
 * searches the modes obstack for the given mode and returns
60
 * a pointer on an equal mode already in the array, NULL if
61
62
 * none found
 */
63
64
static ir_mode *find_mode(const ir_mode *m)
{
65
66
	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
67
		ir_mode *n = mode_list[i];
68
69
70
		if (modes_are_equal(n, m))
			return n;
	}
Michael Beck's avatar
Michael Beck committed
71
72
73
	return NULL;
}

74
75
76
/**
 * sets special values of modes
 */
77
78
static void set_mode_values(ir_mode* mode)
{
79
	switch (get_mode_sort(mode))    {
80
	case irms_reference:
81
82
83
84
85
86
87
	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);
88
		if (get_mode_sort(mode) != irms_float_number) {
89
90
91
92
			mode->all_one = get_tarval_all_one(mode);
		} else {
			mode->all_one = tarval_bad;
		}
93
94
95
96
97
98
99
100
		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;
101
		mode->all_one = tarval_b_true;
102
103
104
		break;

	case irms_control_flow:
105
106
107
108
109
	case irms_block:
	case irms_tuple:
	case irms_any:
	case irms_bad:
	case irms_memory:
110
111
112
113
114
115
116
		mode->min  = tarval_bad;
		mode->max  = tarval_bad;
		mode->null = tarval_bad;
		mode->one  = tarval_bad;
		mode->minus_one = tarval_bad;
		break;
	}
117
}
118

119
120
121
122
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
123
124
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
125

126
127
128
ir_mode *mode_F;
ir_mode *mode_D;
ir_mode *mode_Q;
Christian Schäfer's avatar
Christian Schäfer committed
129

130
131
132
ir_mode *mode_Bs;
ir_mode *mode_Bu;
ir_mode *mode_Hs;
133
ir_mode *mode_Hu;
134
ir_mode *mode_Is;
135
ir_mode *mode_Iu;
136
ir_mode *mode_Ls;
137
ir_mode *mode_Lu;
138
ir_mode *mode_LLs;
139
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
140

141
142
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
143

144
145
ir_mode *mode_P_code;
ir_mode *mode_P_data;
146

147
148
149
ir_mode *get_modeT(void) { return mode_T; }
ir_mode *get_modeF(void) { return mode_F; }
ir_mode *get_modeD(void) { return mode_D; }
150
ir_mode *get_modeQ(void) { return mode_Q; }
151
152
153
154
155
156
157
158
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; }
159
160
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
161
162
163
164
165
166
167
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; }
168

169

170
171
ir_mode *(get_modeP_code)(void)
{
172
	return get_modeP_code_();
Michael Beck's avatar
Michael Beck committed
173
174
}

175
176
ir_mode *(get_modeP_data)(void)
{
177
	return get_modeP_data_();
178
179
}

180
181
void set_modeP_code(ir_mode *p)
{
182
183
	assert(mode_is_reference(p));
	mode_P_code = p;
184
185
}

186
187
void set_modeP_data(ir_mode *p)
{
188
189
	assert(mode_is_reference(p));
	mode_P_data = p;
190
	mode_P = p;
Michael Beck's avatar
Michael Beck committed
191
}
192

193
194
/*
 * Creates a new mode.
195
 */
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
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;
	}
222

223
	mode->kind = k_ir_mode;
224
	mode->type = new_type_primitive(mode);
225
	ARR_APP1(ir_mode*, mode_list, mode);
226
	set_mode_values(mode);
227
	hook_new_mode(mode);
228
	return mode;
229
230
}

231
232
233
234
235
236
237
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);
}
238

239
240
241
242
243
244
245
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);
}
246

247
248
249
250
251
252
253
254
255
256
257
258
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");
259
	}
260
261
262
263
264
	if (exponent_size >= 256)
		panic("Exponents >= 256 bits not supported");
	if (mantissa_size >= 256)
		panic("Mantissa >= 256 bits not supported");

265
	result = alloc_mode(name, irms_float_number, irma_x86_extended_float, bit_size, 1, 0);
266
267
268
269
	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);
270
271
}

272
273
ident *(get_mode_ident)(const ir_mode *mode)
{
274
	return get_mode_ident_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
275
276
}

277
278
const char *get_mode_name(const ir_mode *mode)
{
279
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
280
281
}

282
283
unsigned (get_mode_size_bits)(const ir_mode *mode)
{
284
	return get_mode_size_bits_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
285
286
}

287
288
unsigned (get_mode_size_bytes)(const ir_mode *mode)
{
289
	return get_mode_size_bytes_(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
290
291
}

292
293
int (get_mode_sign)(const ir_mode *mode)
{
294
	return get_mode_sign_(mode);
295
296
}

297
298
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode)
{
299
	return get_mode_arithmetic_(mode);
300
301
}

302

303
304
unsigned int (get_mode_modulo_shift)(const ir_mode *mode)
{
305
	return get_mode_modulo_shift_(mode);
306
307
}

308
309
void *(get_mode_link)(const ir_mode *mode)
{
310
	return get_mode_link_(mode);
311
312
}

313
314
void (set_mode_link)(ir_mode *mode, void *l)
{
315
	set_mode_link_(mode, l);
316
317
}

Matthias Braun's avatar
Matthias Braun committed
318
ir_tarval *get_mode_min(ir_mode *mode)
319
{
320
321
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
322

323
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
324
325
}

Matthias Braun's avatar
Matthias Braun committed
326
ir_tarval *get_mode_max(ir_mode *mode)
327
{
328
329
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
330

331
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
332
333
}

Matthias Braun's avatar
Matthias Braun committed
334
ir_tarval *get_mode_null(ir_mode *mode)
335
{
336
	assert(mode);
337
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
338

339
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
340
341
}

Matthias Braun's avatar
Matthias Braun committed
342
ir_tarval *get_mode_one(ir_mode *mode)
343
{
344
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
345
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
346

347
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
348
349
}

Matthias Braun's avatar
Matthias Braun committed
350
ir_tarval *get_mode_minus_one(ir_mode *mode)
351
{
352
353
	assert(mode);
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
354

355
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
356
357
}

Matthias Braun's avatar
Matthias Braun committed
358
ir_tarval *get_mode_all_one(ir_mode *mode)
359
{
360
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
361
	assert(mode_is_datab(mode));
362
363
364
	return mode->all_one;
}

Matthias Braun's avatar
Matthias Braun committed
365
ir_tarval *get_mode_infinite(ir_mode *mode)
366
{
367
368
	assert(mode);
	assert(mode_is_float(mode));
369

370
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
371
372
}

Matthias Braun's avatar
Matthias Braun committed
373
ir_tarval *get_mode_NAN(ir_mode *mode)
374
{
375
376
	assert(mode);
	assert(mode_is_float(mode));
377

378
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
379
380
}

381
382
int is_mode(const void *thing)
{
Michael Beck's avatar
Michael Beck committed
383
	return get_kind(thing) == k_ir_mode;
384
385
}

386
387
int (mode_is_signed)(const ir_mode *mode)
{
388
	return mode_is_signed_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
389
390
}

391
392
int (mode_is_float)(const ir_mode *mode)
{
393
	return mode_is_float_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
394
395
}

396
397
int (mode_is_int)(const ir_mode *mode)
{
398
	return mode_is_int_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
399
400
}

401
402
int (mode_is_reference)(const ir_mode *mode)
{
403
	return mode_is_reference_(mode);
404
405
}

406
407
int (mode_is_num)(const ir_mode *mode)
{
408
	return mode_is_num_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
409
410
}

411
412
int (mode_is_data)(const ir_mode *mode)
{
413
	return mode_is_data_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
414
415
}

416
417
int (mode_is_datab)(const ir_mode *mode)
{
418
	return mode_is_datab_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
419
420
}

421
422
int (mode_is_dataM)(const ir_mode *mode)
{
423
	return mode_is_dataM_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
424
}
425

426
427
428
429
430
431
432
433
434
435
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);
}

436
437
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
438
	int sm_bits, lm_bits;
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
479
480
481
482
483
484
485
486
487
488
489
490
491
492

	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
493
		/* do exist machines out there with different pointer lengths ?*/
494
495
496
497
498
499
500
501
502
503
504
505
506
		return 0;

	case irms_internal_boolean:
		return mode_is_int(lm);

	default:
		break;
	}

	/* else */
	return 0;
}

507
508
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
{
Moritz Kroll's avatar
Moritz Kroll committed
509
	ir_mode_arithmetic arith;
510
511
512
513
514
515

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

Moritz Kroll's avatar
Moritz Kroll committed
516
517
518
519
520
	if (sm == mode_b)
		return mode_is_int(lm);

	arith = get_mode_arithmetic(sm);
	if (arith != get_mode_arithmetic(lm))
521
522
		return 0;

Moritz Kroll's avatar
Moritz Kroll committed
523
524
525
526
	switch (arith) {
		case irma_twos_complement:
		case irma_ieee754:
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
527

Moritz Kroll's avatar
Moritz Kroll committed
528
529
		default:
			return 0;
530
531
532
	}
}

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

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

546
547
ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
{
548
549
550
551
	assert(mode_is_reference(mode));
	return mode->eq_unsigned;
}

552
553
void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
554
555
556
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_unsigned = int_mode;
557
558
}

559
560
561
562
563
564
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);
}

565
566
void init_mode(void)
{
567
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
568
	mode_list = NEW_ARR_F(ir_mode*, 0);
569

570
	/* initialize predefined modes */
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
	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);
595
596
	set_reference_mode_signed_eq(mode_P, mode_Is);
	set_reference_mode_unsigned_eq(mode_P, mode_Iu);
597
598
599
600

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

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

607
608
609
610
611
	/* allowed for reference mode */
	if (mode->sort == irms_reference)
		n.sort = irms_int_number;

	assert(n.sort == irms_int_number);
612
613
	n.sign = 0;
	return find_mode(&n);
614
615
}

616
617
ir_mode *find_signed_mode(const ir_mode *mode)
{
618
	ir_mode n = *mode;
619

620
621
622
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
623
624
}

625
626
ir_mode *find_double_bits_int_mode(const ir_mode *mode)
{
627
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
628

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

631
632
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
633
}
634

635
636
int mode_honor_signed_zeros(const ir_mode *mode)
{
637
638
639
	/* 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
640
641
642
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
643
644
}

645
646
int mode_overflow_on_unary_Minus(const ir_mode *mode)
{
647
648
649
	if (mode->sort == irms_float_number)
		return mode->arithmetic == irma_ieee754 ? 0 : 1;
	return 1;
650
651
}

652
653
int mode_wrap_around(const ir_mode *mode)
{
654
655
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
656
657
}

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

670
	return ma == irma_twos_complement;
671
672
}

673
674
675
676
677
ir_type *(get_type_for_mode) (const ir_mode *mode)
{
	return get_type_for_mode_(mode);
}

Matthias Braun's avatar
Matthias Braun committed
678
679
680
681
682
683
684
685
686
687
688
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];
}

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

	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;

715
	mode_P      = NULL;
716
717
	mode_P_code = NULL;
	mode_P_data = NULL;
718
}