irmode.c 17.6 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
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
122

123
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
124

125
126
127
128
129
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
130
131
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
132

133
/* predefined numerical modes: */
134
135
136
ir_mode *mode_F;
ir_mode *mode_D;
ir_mode *mode_Q;
Christian Schäfer's avatar
Christian Schäfer committed
137

138
139
140
141
142
143
144
145
ir_mode *mode_Bs;   /* integral values, signed and unsigned */
ir_mode *mode_Bu;   /* 8 bit */
ir_mode *mode_Hs;   /* 16 bit */
ir_mode *mode_Hu;
ir_mode *mode_Is;   /* 32 bit */
ir_mode *mode_Iu;
ir_mode *mode_Ls;   /* 64 bit */
ir_mode *mode_Lu;
146
147
ir_mode *mode_LLs;  /* 128 bit */
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
148

149
150
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
151
152

/* machine specific modes */
153
154
ir_mode *mode_P_code;   /**< machine specific pointer mode for code addresses */
ir_mode *mode_P_data;   /**< machine specific pointer mode for data addresses */
155

156
157
158
159
/* * *
 * functions defined in irmode.h
 * * */

160
161
162
ir_mode *get_modeT(void) { return mode_T; }
ir_mode *get_modeF(void) { return mode_F; }
ir_mode *get_modeD(void) { return mode_D; }
163
ir_mode *get_modeQ(void) { return mode_Q; }
164
165
166
167
168
169
170
171
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; }
172
173
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
174
175
176
177
178
179
180
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; }
181

182

183
184
ir_mode *(get_modeP_code)(void)
{
185
	return get_modeP_code_();
Michael Beck's avatar
Michael Beck committed
186
187
}

188
189
ir_mode *(get_modeP_data)(void)
{
190
	return get_modeP_data_();
191
192
}

193
194
void set_modeP_code(ir_mode *p)
{
195
196
	assert(mode_is_reference(p));
	mode_P_code = p;
197
198
}

199
200
void set_modeP_data(ir_mode *p)
{
201
202
	assert(mode_is_reference(p));
	mode_P_data = p;
203
	mode_P = p;
Michael Beck's avatar
Michael Beck committed
204
}
205

206
207
/*
 * Creates a new mode.
208
 */
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
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;
	}
235

236
	mode->kind = k_ir_mode;
237
	mode->type = new_type_primitive(mode);
238
	ARR_APP1(ir_mode*, mode_list, mode);
239
240
	add_irp_mode(mode);
	set_mode_values(mode);
241
	hook_new_mode(mode);
242
	return mode;
243
244
}

245
246
247
248
249
250
251
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);
}
252

253
254
255
256
257
258
259
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);
}
260

261
262
263
264
265
266
267
268
269
270
271
272
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");
273
	}
274
275
276
277
278
	if (exponent_size >= 256)
		panic("Exponents >= 256 bits not supported");
	if (mantissa_size >= 256)
		panic("Mantissa >= 256 bits not supported");

279
	result = alloc_mode(name, irms_float_number, irma_x86_extended_float, bit_size, 1, 0);
280
281
282
283
	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);
284
285
}

286
/* Functions for the direct access to all attributes of an ir_mode */
287
288
ident *(get_mode_ident)(const ir_mode *mode)
{
289
	return get_mode_ident_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
290
291
}

292
293
const char *get_mode_name(const ir_mode *mode)
{
294
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
295
296
}

297
298
unsigned (get_mode_size_bits)(const ir_mode *mode)
{
299
	return get_mode_size_bits_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
300
301
}

302
303
unsigned (get_mode_size_bytes)(const ir_mode *mode)
{
304
	return get_mode_size_bytes_(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
305
306
}

307
308
int (get_mode_sign)(const ir_mode *mode)
{
309
	return get_mode_sign_(mode);
310
311
}

312
313
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode)
{
314
	return get_mode_arithmetic_(mode);
315
316
}

317
318
319
320
321

/* Attribute modulo shift specifies for modes of kind irms_int_number
 *  whether shift applies modulo to value of bits to shift.  Asserts
 *  if mode is not irms_int_number.
 */
322
323
unsigned int (get_mode_modulo_shift)(const ir_mode *mode)
{
324
	return get_mode_modulo_shift_(mode);
325
326
}

327
328
void *(get_mode_link)(const ir_mode *mode)
{
329
	return get_mode_link_(mode);
330
331
}

332
333
void (set_mode_link)(ir_mode *mode, void *l)
{
334
	set_mode_link_(mode, l);
335
336
}

Matthias Braun's avatar
Matthias Braun committed
337
ir_tarval *get_mode_min(ir_mode *mode)
338
{
339
340
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
341

342
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
343
344
}

Matthias Braun's avatar
Matthias Braun committed
345
ir_tarval *get_mode_max(ir_mode *mode)
346
{
347
348
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
349

350
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
351
352
}

Matthias Braun's avatar
Matthias Braun committed
353
ir_tarval *get_mode_null(ir_mode *mode)
354
{
355
	assert(mode);
356
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
357

358
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
359
360
}

Matthias Braun's avatar
Matthias Braun committed
361
ir_tarval *get_mode_one(ir_mode *mode)
362
{
363
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
364
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
365

366
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
367
368
}

Matthias Braun's avatar
Matthias Braun committed
369
ir_tarval *get_mode_minus_one(ir_mode *mode)
370
{
371
372
	assert(mode);
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
373

374
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
375
376
}

Matthias Braun's avatar
Matthias Braun committed
377
ir_tarval *get_mode_all_one(ir_mode *mode)
378
{
379
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
380
	assert(mode_is_datab(mode));
381
382
383
	return mode->all_one;
}

Matthias Braun's avatar
Matthias Braun committed
384
ir_tarval *get_mode_infinite(ir_mode *mode)
385
{
386
387
	assert(mode);
	assert(mode_is_float(mode));
388

389
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
390
391
}

Matthias Braun's avatar
Matthias Braun committed
392
ir_tarval *get_mode_NAN(ir_mode *mode)
393
{
394
395
	assert(mode);
	assert(mode_is_float(mode));
396

397
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
398
399
}

400
401
int is_mode(const void *thing)
{
Michael Beck's avatar
Michael Beck committed
402
	return get_kind(thing) == k_ir_mode;
403
404
}

405
406
int (mode_is_signed)(const ir_mode *mode)
{
407
	return mode_is_signed_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
408
409
}

410
411
int (mode_is_float)(const ir_mode *mode)
{
412
	return mode_is_float_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
413
414
}

415
416
int (mode_is_int)(const ir_mode *mode)
{
417
	return mode_is_int_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
418
419
}

420
421
int (mode_is_reference)(const ir_mode *mode)
{
422
	return mode_is_reference_(mode);
423
424
}

425
426
int (mode_is_num)(const ir_mode *mode)
{
427
	return mode_is_num_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
428
429
}

430
431
int (mode_is_data)(const ir_mode *mode)
{
432
	return mode_is_data_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
433
434
}

435
436
int (mode_is_datab)(const ir_mode *mode)
{
437
	return mode_is_datab_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
438
439
}

440
441
int (mode_is_dataM)(const ir_mode *mode)
{
442
	return mode_is_dataM_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
443
}
444

445
446
447
448
449
450
451
452
453
454
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);
}

455
/* Returns true if sm can be converted to lm without loss. */
456
457
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
458
	int sm_bits, lm_bits;
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
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

	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
513
		/* do exist machines out there with different pointer lengths ?*/
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
		return 0;

	case irms_internal_boolean:
		return mode_is_int(lm);

	default:
		break;
	}

	/* else */
	return 0;
}

/* Returns true if a value of mode sm can be converted into mode lm
   and backwards without loss. */
529
530
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
{
Moritz Kroll's avatar
Moritz Kroll committed
531
	ir_mode_arithmetic arith;
532
533
534
535
536
537

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

Moritz Kroll's avatar
Moritz Kroll committed
538
539
540
541
542
	if (sm == mode_b)
		return mode_is_int(lm);

	arith = get_mode_arithmetic(sm);
	if (arith != get_mode_arithmetic(lm))
543
544
		return 0;

Moritz Kroll's avatar
Moritz Kroll committed
545
546
547
548
	switch (arith) {
		case irma_twos_complement:
		case irma_ieee754:
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
549

Moritz Kroll's avatar
Moritz Kroll committed
550
551
		default:
			return 0;
552
553
554
555
	}
}

/* Return the signed integer equivalent mode for an reference mode. */
556
557
ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
{
558
559
560
561
562
	assert(mode_is_reference(mode));
	return mode->eq_signed;
}

/* Sets the signed integer equivalent mode for an reference mode. */
563
564
void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
565
566
567
568
569
570
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_signed = int_mode;
}

/* Return the unsigned integer equivalent mode for an reference mode. */
571
572
ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
{
573
574
575
576
577
	assert(mode_is_reference(mode));
	return mode->eq_unsigned;
}

/* Sets the unsigned integer equivalent mode for an reference mode. */
578
579
void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
580
581
582
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_unsigned = int_mode;
583
584
}

585
586
587
588
589
590
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);
}

591
/* initialization, build the default modes */
592
593
void init_mode(void)
{
594
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
595
	mode_list = NEW_ARR_F(ir_mode*, 0);
596

597
	/* initialize predefined modes */
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
	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);
622
623
	set_reference_mode_signed_eq(mode_P, mode_Is);
	set_reference_mode_unsigned_eq(mode_P, mode_Iu);
624
625
626
627

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

Michael Beck's avatar
Michael Beck committed
630
/* find a signed mode for an unsigned integer mode */
631
632
ir_mode *find_unsigned_mode(const ir_mode *mode)
{
633
	ir_mode n = *mode;
634

635
636
637
638
639
	/* allowed for reference mode */
	if (mode->sort == irms_reference)
		n.sort = irms_int_number;

	assert(n.sort == irms_int_number);
640
641
	n.sign = 0;
	return find_mode(&n);
642
643
}

Michael Beck's avatar
Michael Beck committed
644
/* find an unsigned mode for a signed integer mode */
645
646
ir_mode *find_signed_mode(const ir_mode *mode)
{
647
	ir_mode n = *mode;
648

649
650
651
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
652
653
}

Michael Beck's avatar
Michael Beck committed
654
/* finds a integer mode with 2*n bits for an integer mode with n bits. */
655
656
ir_mode *find_double_bits_int_mode(const ir_mode *mode)
{
657
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
658

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

661
662
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
663
}
664

665
666
667
668
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
669
670
int mode_honor_signed_zeros(const ir_mode *mode)
{
671
672
673
	/* 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
674
675
676
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
677
678
}

679
680
681
682
683
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
684
685
int mode_overflow_on_unary_Minus(const ir_mode *mode)
{
686
687
688
	if (mode->sort == irms_float_number)
		return mode->arithmetic == irma_ieee754 ? 0 : 1;
	return 1;
689
690
}

Michael Beck's avatar
Michael Beck committed
691
/*
692
 * Returns non-zero if the mode has a reversed wrap-around
Michael Beck's avatar
Michael Beck committed
693
694
695
696
697
 * logic, especially (a + x) - x == a.
 *
 * This is normally true for integer modes, not for floating
 * point modes.
 */
698
699
int mode_wrap_around(const ir_mode *mode)
{
700
701
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
702
703
}

704
705
706
707
708
/*
 * Returns non-zero if the cast from mode src to mode dst is a
 * reinterpret cast (ie. only the bit pattern is reinterpreted,
 * no conversion is done)
 */
709
710
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
{
711
712
713
714
715
716
717
718
719
720
	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;

721
	return ma == irma_twos_complement;
722
723
}

724
725
726
727
728
ir_type *(get_type_for_mode) (const ir_mode *mode)
{
	return get_type_for_mode_(mode);
}

729
730
void finish_mode(void)
{
731
	obstack_free(&modes, 0);
Matthias Braun's avatar
Matthias Braun committed
732
	DEL_ARR_F(mode_list);
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754

	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;

755
	mode_P      = NULL;
756
757
	mode_P_code = NULL;
	mode_P_data = NULL;
758
}