irmode.c 17.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
50
51
52
53
54
55
56
const char *get_mode_arithmetic_name(ir_mode_arithmetic ari)
{
#define X(a)    case a: return #a
	switch (ari) {
		X(irma_uninitialized);
		X(irma_none);
		X(irma_twos_complement);
		X(irma_ieee754);
57
		X(irma_x86_extended_float);
58
59
60
61
62
		default: return "<unknown>";
	}
#undef X
}

63
static bool modes_are_equal(const ir_mode *m, const ir_mode *n)
64
{
65
66
67
68
69
	return m->sort         == n->sort &&
	       m->arithmetic   == n->arithmetic &&
	       m->size         == n->size &&
	       m->sign         == n->sign &&
	       m->modulo_shift == n->modulo_shift;
70
}
Matthias Heil's avatar
Matthias Heil committed
71

72
/**
73
 * searches the modes obstack for the given mode and returns
74
 * a pointer on an equal mode already in the array, NULL if
75
76
 * none found
 */
77
78
static ir_mode *find_mode(const ir_mode *m)
{
79
80
	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
81
		ir_mode *n = mode_list[i];
82
83
84
		if (modes_are_equal(n, m))
			return n;
	}
Michael Beck's avatar
Michael Beck committed
85
86
87
	return NULL;
}

88
89
90
/**
 * sets special values of modes
 */
91
92
static void set_mode_values(ir_mode* mode)
{
93
	switch (get_mode_sort(mode))    {
94
	case irms_reference:
95
96
97
98
99
100
101
	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);
102
		if (get_mode_sort(mode) != irms_float_number) {
103
104
105
106
			mode->all_one = get_tarval_all_one(mode);
		} else {
			mode->all_one = tarval_bad;
		}
107
108
109
110
111
112
113
114
		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;
115
		mode->all_one = tarval_b_true;
116
117
118
		break;

	case irms_control_flow:
119
120
121
122
123
	case irms_block:
	case irms_tuple:
	case irms_any:
	case irms_bad:
	case irms_memory:
124
125
126
127
128
129
130
		mode->min  = tarval_bad;
		mode->max  = tarval_bad;
		mode->null = tarval_bad;
		mode->one  = tarval_bad;
		mode->minus_one = tarval_bad;
		break;
	}
131
}
132

133
134
135
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
136

137
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
138

139
140
141
142
143
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
144
145
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
146

147
/* predefined numerical modes: */
148
149
150
ir_mode *mode_F;
ir_mode *mode_D;
ir_mode *mode_Q;
Christian Schäfer's avatar
Christian Schäfer committed
151

152
153
154
155
156
157
158
159
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;
160
161
ir_mode *mode_LLs;  /* 128 bit */
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
162

163
164
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
165
166

/* machine specific modes */
167
168
ir_mode *mode_P_code;   /**< machine specific pointer mode for code addresses */
ir_mode *mode_P_data;   /**< machine specific pointer mode for data addresses */
169

170
171
172
173
/* * *
 * functions defined in irmode.h
 * * */

174
175
176
ir_mode *get_modeT(void) { return mode_T; }
ir_mode *get_modeF(void) { return mode_F; }
ir_mode *get_modeD(void) { return mode_D; }
177
ir_mode *get_modeQ(void) { return mode_Q; }
178
179
180
181
182
183
184
185
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; }
186
187
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
188
189
190
191
192
193
194
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; }
195

196

197
198
ir_mode *(get_modeP_code)(void)
{
199
	return get_modeP_code_();
Michael Beck's avatar
Michael Beck committed
200
201
}

202
203
ir_mode *(get_modeP_data)(void)
{
204
	return get_modeP_data_();
205
206
}

207
208
void set_modeP_code(ir_mode *p)
{
209
210
	assert(mode_is_reference(p));
	mode_P_code = p;
211
212
}

213
214
void set_modeP_data(ir_mode *p)
{
215
216
	assert(mode_is_reference(p));
	mode_P_data = p;
217
	mode_P = p;
Michael Beck's avatar
Michael Beck committed
218
}
219

220
221
/*
 * Creates a new mode.
222
 */
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
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;
	}
249

250
	mode->kind = k_ir_mode;
251
	mode->type = new_type_primitive(mode);
252
	ARR_APP1(ir_mode*, mode_list, mode);
253
254
	add_irp_mode(mode);
	set_mode_values(mode);
255
	hook_new_mode(mode);
256
	return mode;
257
258
}

259
260
261
262
263
264
265
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);
}
266

267
268
269
270
271
272
273
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);
}
274

275
276
277
278
279
280
281
282
283
284
285
286
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");
287
	}
288
289
290
291
292
	if (exponent_size >= 256)
		panic("Exponents >= 256 bits not supported");
	if (mantissa_size >= 256)
		panic("Mantissa >= 256 bits not supported");

293
	result = alloc_mode(name, irms_float_number, irma_x86_extended_float, bit_size, 1, 0);
294
295
296
297
	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);
298
299
}

300
/* Functions for the direct access to all attributes of an ir_mode */
301
302
ident *(get_mode_ident)(const ir_mode *mode)
{
303
	return get_mode_ident_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
304
305
}

306
307
const char *get_mode_name(const ir_mode *mode)
{
308
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
309
310
}

311
312
unsigned (get_mode_size_bits)(const ir_mode *mode)
{
313
	return get_mode_size_bits_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
314
315
}

316
317
unsigned (get_mode_size_bytes)(const ir_mode *mode)
{
318
	return get_mode_size_bytes_(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
319
320
}

321
322
int (get_mode_sign)(const ir_mode *mode)
{
323
	return get_mode_sign_(mode);
324
325
}

326
327
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode)
{
328
	return get_mode_arithmetic_(mode);
329
330
}

331
332
333
334
335

/* 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.
 */
336
337
unsigned int (get_mode_modulo_shift)(const ir_mode *mode)
{
338
	return get_mode_modulo_shift_(mode);
339
340
}

341
342
void *(get_mode_link)(const ir_mode *mode)
{
343
	return get_mode_link_(mode);
344
345
}

346
347
void (set_mode_link)(ir_mode *mode, void *l)
{
348
	set_mode_link_(mode, l);
349
350
}

Matthias Braun's avatar
Matthias Braun committed
351
ir_tarval *get_mode_min(ir_mode *mode)
352
{
353
354
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
355

356
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
357
358
}

Matthias Braun's avatar
Matthias Braun committed
359
ir_tarval *get_mode_max(ir_mode *mode)
360
{
361
362
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
363

364
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
365
366
}

Matthias Braun's avatar
Matthias Braun committed
367
ir_tarval *get_mode_null(ir_mode *mode)
368
{
369
	assert(mode);
370
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
371

372
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
373
374
}

Matthias Braun's avatar
Matthias Braun committed
375
ir_tarval *get_mode_one(ir_mode *mode)
376
{
377
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
378
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
379

380
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
381
382
}

Matthias Braun's avatar
Matthias Braun committed
383
ir_tarval *get_mode_minus_one(ir_mode *mode)
384
{
385
386
	assert(mode);
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
387

388
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
389
390
}

Matthias Braun's avatar
Matthias Braun committed
391
ir_tarval *get_mode_all_one(ir_mode *mode)
392
{
393
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
394
	assert(mode_is_datab(mode));
395
396
397
	return mode->all_one;
}

Matthias Braun's avatar
Matthias Braun committed
398
ir_tarval *get_mode_infinite(ir_mode *mode)
399
{
400
401
	assert(mode);
	assert(mode_is_float(mode));
402

403
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
404
405
}

Matthias Braun's avatar
Matthias Braun committed
406
ir_tarval *get_mode_NAN(ir_mode *mode)
407
{
408
409
	assert(mode);
	assert(mode_is_float(mode));
410

411
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
412
413
}

414
415
int is_mode(const void *thing)
{
Michael Beck's avatar
Michael Beck committed
416
	return get_kind(thing) == k_ir_mode;
417
418
}

419
420
int (mode_is_signed)(const ir_mode *mode)
{
421
	return mode_is_signed_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
422
423
}

424
425
int (mode_is_float)(const ir_mode *mode)
{
426
	return mode_is_float_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
427
428
}

429
430
int (mode_is_int)(const ir_mode *mode)
{
431
	return mode_is_int_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
432
433
}

434
435
int (mode_is_reference)(const ir_mode *mode)
{
436
	return mode_is_reference_(mode);
437
438
}

439
440
int (mode_is_num)(const ir_mode *mode)
{
441
	return mode_is_num_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
442
443
}

444
445
int (mode_is_data)(const ir_mode *mode)
{
446
	return mode_is_data_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
447
448
}

449
450
int (mode_is_datab)(const ir_mode *mode)
{
451
	return mode_is_datab_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
452
453
}

454
455
int (mode_is_dataM)(const ir_mode *mode)
{
456
	return mode_is_dataM_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
457
}
458

459
460
461
462
463
464
465
466
467
468
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);
}

469
/* Returns true if sm can be converted to lm without loss. */
470
471
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
472
	int sm_bits, lm_bits;
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
513
514
515
516
517
518
519
520
521
522
523
524
525
526

	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
527
		/* do exist machines out there with different pointer lengths ?*/
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
		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. */
543
544
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
{
Moritz Kroll's avatar
Moritz Kroll committed
545
	ir_mode_arithmetic arith;
546
547
548
549
550
551

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

Moritz Kroll's avatar
Moritz Kroll committed
552
553
554
555
556
	if (sm == mode_b)
		return mode_is_int(lm);

	arith = get_mode_arithmetic(sm);
	if (arith != get_mode_arithmetic(lm))
557
558
		return 0;

Moritz Kroll's avatar
Moritz Kroll committed
559
560
561
562
	switch (arith) {
		case irma_twos_complement:
		case irma_ieee754:
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
563

Moritz Kroll's avatar
Moritz Kroll committed
564
565
		default:
			return 0;
566
567
568
569
	}
}

/* Return the signed integer equivalent mode for an reference mode. */
570
571
ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
{
572
573
574
575
576
	assert(mode_is_reference(mode));
	return mode->eq_signed;
}

/* Sets the signed integer equivalent mode for an reference mode. */
577
578
void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
579
580
581
582
583
584
	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. */
585
586
ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
{
587
588
589
590
591
	assert(mode_is_reference(mode));
	return mode->eq_unsigned;
}

/* Sets the unsigned integer equivalent mode for an reference mode. */
592
593
void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
594
595
596
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_unsigned = int_mode;
597
598
}

599
600
601
602
603
604
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);
}

605
/* initialization, build the default modes */
606
607
void init_mode(void)
{
608
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
609
	mode_list = NEW_ARR_F(ir_mode*, 0);
610

611
	/* initialize predefined modes */
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
	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);
636
637
	set_reference_mode_signed_eq(mode_P, mode_Is);
	set_reference_mode_unsigned_eq(mode_P, mode_Iu);
638
639
640
641

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

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

649
650
651
652
653
	/* allowed for reference mode */
	if (mode->sort == irms_reference)
		n.sort = irms_int_number;

	assert(n.sort == irms_int_number);
654
655
	n.sign = 0;
	return find_mode(&n);
656
657
}

Michael Beck's avatar
Michael Beck committed
658
/* find an unsigned mode for a signed integer mode */
659
660
ir_mode *find_signed_mode(const ir_mode *mode)
{
661
	ir_mode n = *mode;
662

663
664
665
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
666
667
}

Michael Beck's avatar
Michael Beck committed
668
/* finds a integer mode with 2*n bits for an integer mode with n bits. */
669
670
ir_mode *find_double_bits_int_mode(const ir_mode *mode)
{
671
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
672

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

675
676
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
677
}
678

679
680
681
682
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
683
684
int mode_honor_signed_zeros(const ir_mode *mode)
{
685
686
687
	/* 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
688
689
690
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
691
692
}

693
694
695
696
697
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
698
699
int mode_overflow_on_unary_Minus(const ir_mode *mode)
{
700
701
702
	if (mode->sort == irms_float_number)
		return mode->arithmetic == irma_ieee754 ? 0 : 1;
	return 1;
703
704
}

Michael Beck's avatar
Michael Beck committed
705
/*
706
 * Returns non-zero if the mode has a reversed wrap-around
Michael Beck's avatar
Michael Beck committed
707
708
709
710
711
 * logic, especially (a + x) - x == a.
 *
 * This is normally true for integer modes, not for floating
 * point modes.
 */
712
713
int mode_wrap_around(const ir_mode *mode)
{
714
715
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
716
717
}

718
719
720
721
722
/*
 * 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)
 */
723
724
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
{
725
726
727
728
729
730
731
732
733
734
	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;

735
	return ma == irma_twos_complement;
736
737
}

738
739
740
741
742
ir_type *(get_type_for_mode) (const ir_mode *mode)
{
	return get_type_for_mode_(mode);
}

743
744
void finish_mode(void)
{
745
	obstack_free(&modes, 0);
Matthias Braun's avatar
Matthias Braun committed
746
	DEL_ARR_F(mode_list);
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768

	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;

769
	mode_P      = NULL;
770
771
	mode_P_code = NULL;
	mode_P_data = NULL;
772
}