irmode.c 15.7 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
227
	add_irp_mode(mode);
	set_mode_values(mode);
228
	hook_new_mode(mode);
229
	return mode;
230
231
}

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

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

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

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

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

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

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

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

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

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

303

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

437
438
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
439
	int sm_bits, lm_bits;
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
493

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

	case irms_internal_boolean:
		return mode_is_int(lm);

	default:
		break;
	}

	/* else */
	return 0;
}

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

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

671
	return ma == irma_twos_complement;
672
673
}

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

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

	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;

705
	mode_P      = NULL;
706
707
	mode_P_code = NULL;
	mode_P_data = NULL;
708
}