irmode.c 22.3 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 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
24
/**
 * @file
 * @brief    Data modes of operations.
 * @author   Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Mathias Heil
 * @version  $Id$
Götz Lindenmaier's avatar
Götz Lindenmaier committed
25
 */
Matthias Braun's avatar
Matthias Braun committed
26
#include "config.h"
Boris Boesler's avatar
added    
Boris Boesler committed
27

Moritz Kroll's avatar
Moritz Kroll committed
28
29
#include <stdlib.h>
#include <string.h>
Michael Beck's avatar
Michael Beck committed
30

Moritz Kroll's avatar
Moritz Kroll committed
31
#include <stddef.h>
32

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

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

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

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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_ones_complement);
		X(irma_int_BCD);
		X(irma_ieee754);
		X(irma_float_BCD);
		default: return "<unknown>";
	}
#undef X
}

66
/**
67
 * Compare modes that don't need to have their code field
68
 * correctly set
69
70
71
 *
 * TODO: Add other fields
 **/
72
73
static inline int modes_are_equal(const ir_mode *m, const ir_mode *n)
{
74
75
76
77
78
79
80
81
	if (m == n) return 1;
	if (m->sort         == n->sort &&
		m->arithmetic   == n->arithmetic &&
		m->size         == n->size &&
		m->sign         == n->sign  &&
		m->modulo_shift == n->modulo_shift &&
		m->vector_elem  == n->vector_elem)
		return 1;
Christian Schäfer's avatar
Christian Schäfer committed
82

83
	return 0;
84
}
Matthias Heil's avatar
Matthias Heil committed
85

86
/**
87
 * searches the modes obstack for the given mode and returns
88
 * a pointer on an equal mode already in the array, NULL if
89
90
 * none found
 */
91
92
static ir_mode *find_mode(const ir_mode *m)
{
Michael Beck's avatar
Michael Beck committed
93
94
	int i;
	for (i = ARR_LEN(mode_list) - 1; i >= 0; --i) {
Matthias Braun's avatar
Matthias Braun committed
95
		ir_mode *n = mode_list[i];
96
97
98
		if (modes_are_equal(n, m))
			return n;
	}
Michael Beck's avatar
Michael Beck committed
99
100
101
102
103
	return NULL;
}

#ifdef FIRM_STATISTICS
/* return the mode index, only needed for statistics */
104
105
int stat_find_mode_index(const ir_mode *m)
{
Michael Beck's avatar
Michael Beck committed
106
107
108
109
110
111
112
113
	int i;
	for (i = ARR_LEN(mode_list) - 1; i >= 0; --i) {
		ir_mode *n = mode_list[i];
		if (modes_are_equal(n, m))
			return i;
	}
	return -1;
}
114

Michael Beck's avatar
Michael Beck committed
115
/* return the mode for a given index, only needed for statistics */
116
117
ir_mode *stat_mode_for_index(int idx)
{
Michael Beck's avatar
Michael Beck committed
118
119
	if (0 <= idx  && idx < ARR_LEN(mode_list))
		return mode_list[idx];
120
	return NULL;
121
}
Michael Beck's avatar
Michael Beck committed
122
#endif
Christian Schäfer's avatar
Christian Schäfer committed
123

124
125
126
/**
 * sets special values of modes
 */
127
128
static void set_mode_values(ir_mode* mode)
{
129
	switch (get_mode_sort(mode))    {
130
	case irms_reference:
131
132
133
134
135
136
137
	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);
138
		if (get_mode_sort(mode) != irms_float_number) {
139
140
141
142
			mode->all_one = get_tarval_all_one(mode);
		} else {
			mode->all_one = tarval_bad;
		}
143
144
145
146
147
148
149
150
		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;
151
		mode->all_one = tarval_b_true;
152
153
154
155
156
157
158
159
160
161
162
163
		break;

	case irms_auxiliary:
	case irms_memory:
	case irms_control_flow:
		mode->min  = tarval_bad;
		mode->max  = tarval_bad;
		mode->null = tarval_bad;
		mode->one  = tarval_bad;
		mode->minus_one = tarval_bad;
		break;
	}
164
}
165

166
167
168
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
169

170
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
171

172
173
174
175
176
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
177
178
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
179

180
181
182
183
/* predefined numerical modes: */
ir_mode *mode_F;    /* float */
ir_mode *mode_D;    /* double */
ir_mode *mode_E;    /* long double */
Christian Schäfer's avatar
Christian Schäfer committed
184

185
186
187
188
189
190
191
192
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;
193
194
ir_mode *mode_LLs;  /* 128 bit */
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
195

196
197
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
198
199

/* machine specific modes */
200
201
ir_mode *mode_P_code;   /**< machine specific pointer mode for code addresses */
ir_mode *mode_P_data;   /**< machine specific pointer mode for data addresses */
202

203
204
205
206
207
/* * *
 * functions defined in irmode.h
 * * */

/* JNI access functions */
208
209
210
211
212
213
214
215
216
217
218
219
ir_mode *get_modeT(void) { return mode_T; }
ir_mode *get_modeF(void) { return mode_F; }
ir_mode *get_modeD(void) { return mode_D; }
ir_mode *get_modeE(void) { return mode_E; }
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; }
220
221
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
222
223
224
225
226
227
228
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; }
229

230

231
232
ir_mode *(get_modeP_code)(void)
{
233
	return _get_modeP_code();
Michael Beck's avatar
Michael Beck committed
234
235
}

236
237
ir_mode *(get_modeP_data)(void)
{
238
	return _get_modeP_data();
239
240
}

241
242
void set_modeP_code(ir_mode *p)
{
243
244
	assert(mode_is_reference(p));
	mode_P_code = p;
245
246
}

247
248
void set_modeP_data(ir_mode *p)
{
249
250
	assert(mode_is_reference(p));
	mode_P_data = p;
Michael Beck's avatar
Michael Beck committed
251
}
252

253
/**
254
255
256
 * Registers a new mode.
 *
 * @param new_mode  The new mode template.
257
 */
258
259
static ir_mode *register_mode(const ir_mode *new_mode)
{
260
	ir_mode *mode = NULL;
261

262
	assert(new_mode);
263

264
265
	/* copy mode struct to modes array */
	mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode));
Matthias Braun's avatar
Matthias Braun committed
266
	ARR_APP1(ir_mode*, mode_list, mode);
267

268
	mode->kind = k_ir_mode;
269
	mode->type = new_type_primitive(mode);
270

271
272
	/* add the new mode to the irp list of modes */
	add_irp_mode(mode);
273

274
	set_mode_values(mode);
275

276
277
	hook_new_mode(new_mode, mode);
	return mode;
278
279
280
281
282
}

/*
 * Creates a new mode.
 */
283
284
ir_mode *new_ir_mode(const char *name, ir_mode_sort sort, int bit_size, int sign,
                     ir_mode_arithmetic arithmetic, unsigned int modulo_shift)
285
{
286
287
288
289
290
291
292
	ir_mode mode_tmpl;
	ir_mode *mode = NULL;

	mode_tmpl.name         = new_id_from_str(name);
	mode_tmpl.sort         = sort;
	mode_tmpl.size         = bit_size;
	mode_tmpl.sign         = sign ? 1 : 0;
293
294
	mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number ||
	                          mode_tmpl.sort == irms_reference) ? modulo_shift : 0;
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
	mode_tmpl.vector_elem  = 1;
	mode_tmpl.arithmetic   = arithmetic;
	mode_tmpl.link         = NULL;
	mode_tmpl.tv_priv      = NULL;

	mode = find_mode(&mode_tmpl);
	if (mode) {
		hook_new_mode(&mode_tmpl, mode);
		return mode;
	}

	/* sanity checks */
	switch (sort) {
	case irms_auxiliary:
	case irms_control_flow:
	case irms_memory:
	case irms_internal_boolean:
312
		panic("internal modes cannot be user defined");
313
314
315
316
317

	case irms_float_number:
	case irms_int_number:
	case irms_reference:
		mode = register_mode(&mode_tmpl);
318
		break;
319
	}
320
	assert(mode != NULL);
321
	return mode;
322
323
}

324
325
326
/*
 * Creates a new vector mode.
 */
327
328
ir_mode *new_ir_vector_mode(const char *name, ir_mode_sort sort, int bit_size, unsigned num_of_elem, int sign,
                            ir_mode_arithmetic arithmetic, unsigned int modulo_shift)
329
{
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
	ir_mode mode_tmpl;
	ir_mode *mode = NULL;

	mode_tmpl.name         = new_id_from_str(name);
	mode_tmpl.sort         = sort;
	mode_tmpl.size         = bit_size * num_of_elem;
	mode_tmpl.sign         = sign ? 1 : 0;
	mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0;
	mode_tmpl.vector_elem  = num_of_elem;
	mode_tmpl.arithmetic   = arithmetic;
	mode_tmpl.link         = NULL;
	mode_tmpl.tv_priv      = NULL;

	mode = find_mode(&mode_tmpl);
	if (mode) {
		hook_new_mode(&mode_tmpl, mode);
		return mode;
	}

	if (num_of_elem <= 1) {
350
		panic("vector modes should have at least 2 elements");
351
352
353
354
355
356
357
358
	}

	/* sanity checks */
	switch (sort) {
	case irms_auxiliary:
	case irms_control_flow:
	case irms_memory:
	case irms_internal_boolean:
359
		panic("internal modes cannot be user defined");
360
361

	case irms_reference:
362
		panic("only integer and floating point modes can be vectorized");
363
364

	case irms_float_number:
365
		panic("not yet implemented");
366
367
368
369

	case irms_int_number:
		mode = register_mode(&mode_tmpl);
	}
370
	assert(mode != NULL);
371
	return mode;
372
373
}

374
/* Functions for the direct access to all attributes of an ir_mode */
375
376
ident *(get_mode_ident)(const ir_mode *mode)
{
377
	return _get_mode_ident(mode);
Christian Schäfer's avatar
Christian Schäfer committed
378
379
}

380
381
const char *get_mode_name(const ir_mode *mode)
{
382
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
383
384
}

385
386
ir_mode_sort (get_mode_sort)(const ir_mode* mode)
{
387
	return _get_mode_sort(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
388
389
}

390
391
unsigned (get_mode_size_bits)(const ir_mode *mode)
{
392
	return _get_mode_size_bits(mode);
Christian Schäfer's avatar
Christian Schäfer committed
393
394
}

395
396
unsigned (get_mode_size_bytes)(const ir_mode *mode)
{
397
	return _get_mode_size_bytes(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
398
399
}

400
401
int (get_mode_sign)(const ir_mode *mode)
{
402
	return _get_mode_sign(mode);
403
404
}

405
406
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode)
{
407
	return get_mode_arithmetic(mode);
408
409
}

410
411
412
413
414

/* 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.
 */
415
416
unsigned int (get_mode_modulo_shift)(const ir_mode *mode)
{
417
	return _get_mode_modulo_shift(mode);
418
419
}

420
421
unsigned int (get_mode_n_vector_elems)(const ir_mode *mode)
{
422
	return _get_mode_vector_elems(mode);
423
424
}

425
426
void *(get_mode_link)(const ir_mode *mode)
{
427
	return _get_mode_link(mode);
428
429
}

430
431
void (set_mode_link)(ir_mode *mode, void *l)
{
432
	_set_mode_link(mode, l);
433
434
}

435
436
tarval *get_mode_min(ir_mode *mode)
{
437
438
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
439

440
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
441
442
}

443
444
tarval *get_mode_max(ir_mode *mode)
{
445
446
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
447

448
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
449
450
}

451
452
tarval *get_mode_null(ir_mode *mode)
{
453
	assert(mode);
454
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
455

456
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
457
458
}

459
460
tarval *get_mode_one(ir_mode *mode)
{
461
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
462
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
463

464
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
465
466
}

467
468
tarval *get_mode_minus_one(ir_mode *mode)
{
469
470
	assert(mode);
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
471

472
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
473
474
}

475
476
tarval *get_mode_all_one(ir_mode *mode)
{
477
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
478
	assert(mode_is_datab(mode));
479
480
481
	return mode->all_one;
}

482
483
tarval *get_mode_infinite(ir_mode *mode)
{
484
485
	assert(mode);
	assert(mode_is_float(mode));
486

487
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
488
489
}

490
491
tarval *get_mode_NAN(ir_mode *mode)
{
492
493
	assert(mode);
	assert(mode_is_float(mode));
494

495
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
496
497
}

498
499
int is_mode(const void *thing)
{
Michael Beck's avatar
Michael Beck committed
500
	return get_kind(thing) == k_ir_mode;
501
502
}

503
504
int (mode_is_signed)(const ir_mode *mode)
{
505
	return _mode_is_signed(mode);
Christian Schäfer's avatar
Christian Schäfer committed
506
507
}

508
509
int (mode_is_float)(const ir_mode *mode)
{
510
	return _mode_is_float(mode);
Christian Schäfer's avatar
Christian Schäfer committed
511
512
}

513
514
int (mode_is_int)(const ir_mode *mode)
{
515
	return _mode_is_int(mode);
Christian Schäfer's avatar
Christian Schäfer committed
516
517
}

518
519
int (mode_is_reference)(const ir_mode *mode)
{
520
	return _mode_is_reference(mode);
521
522
}

523
524
int (mode_is_num)(const ir_mode *mode)
{
525
	return _mode_is_num(mode);
Christian Schäfer's avatar
Christian Schäfer committed
526
527
}

528
529
int (mode_is_data)(const ir_mode *mode)
{
530
	return _mode_is_data(mode);
Christian Schäfer's avatar
Christian Schäfer committed
531
532
}

533
534
int (mode_is_datab)(const ir_mode *mode)
{
535
	return _mode_is_datab(mode);
Christian Schäfer's avatar
Christian Schäfer committed
536
537
}

538
539
int (mode_is_dataM)(const ir_mode *mode)
{
540
	return _mode_is_dataM(mode);
Christian Schäfer's avatar
Christian Schäfer committed
541
}
542

543
544
int (mode_is_float_vector)(const ir_mode *mode)
{
545
	return _mode_is_float_vector(mode);
546
547
}

548
549
int (mode_is_int_vector)(const ir_mode *mode)
{
550
	return _mode_is_int_vector(mode);
Michael Beck's avatar
Michael Beck committed
551
552
}

553
/* Returns true if sm can be converted to lm without loss. */
554
555
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
556
	int sm_bits, lm_bits;
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611

	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;
			}
			break;

		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
612
		/* do exist machines out there with different pointer lengths ?*/
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
		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. */
628
629
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
{
630
	int sm_bits, lm_bits;
Moritz Kroll's avatar
Moritz Kroll committed
631
	ir_mode_arithmetic arith;
632
633
634
635
636
637

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

Moritz Kroll's avatar
Moritz Kroll committed
638
639
640
	if (sm == mode_b)
		return mode_is_int(lm);

641
642
643
	sm_bits = get_mode_size_bits(sm);
	lm_bits = get_mode_size_bits(lm);

Moritz Kroll's avatar
Moritz Kroll committed
644
645
	arith = get_mode_arithmetic(sm);
	if (arith != get_mode_arithmetic(lm))
646
647
		return 0;

Moritz Kroll's avatar
Moritz Kroll committed
648
649
650
651
	switch (arith) {
		case irma_twos_complement:
		case irma_ieee754:
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
652

Moritz Kroll's avatar
Moritz Kroll committed
653
654
		default:
			return 0;
655
656
657
658
	}
}

/* Return the signed integer equivalent mode for an reference mode. */
659
660
ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
{
661
662
663
664
665
	assert(mode_is_reference(mode));
	return mode->eq_signed;
}

/* Sets the signed integer equivalent mode for an reference mode. */
666
667
void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
668
669
670
671
672
673
	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. */
674
675
ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
{
676
677
678
679
680
	assert(mode_is_reference(mode));
	return mode->eq_unsigned;
}

/* Sets the unsigned integer equivalent mode for an reference mode. */
681
682
void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
683
684
685
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_unsigned = int_mode;
686
687
}

688
/* initialization, build the default modes */
689
690
void init_mode(void)
{
691
	ir_mode newmode;
692

693
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
694
	mode_list = NEW_ARR_F(ir_mode*, 0);
695

696
	/* initialize predefined modes */
697

698
699
700
701
702
703
704
705
706
707
	/* Internal Modes */
	newmode.arithmetic   = irma_none;
	newmode.size         = 0;
	newmode.sign         = 0;
	newmode.modulo_shift = 0;
	newmode.vector_elem  = 0;
	newmode.eq_signed    = NULL;
	newmode.eq_unsigned  = NULL;
	newmode.link         = NULL;
	newmode.tv_priv      = NULL;
708

709
710
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
711

712
713
	/* Basic Block */
	newmode.name    = new_id_from_chars("BB", 2);
714
	mode_BB         = register_mode(&newmode);
715

716
717
	/* eXecution */
	newmode.name    = new_id_from_chars("X", 1);
718
	mode_X          = register_mode(&newmode);
719

720
721
	/* Memory Modes */
	newmode.sort    = irms_memory;
722

723
724
	/* Memory */
	newmode.name    = new_id_from_chars("M", 1);
725
	mode_M          = register_mode(&newmode);
726

727
728
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
729

730
731
	/* Tuple */
	newmode.name    = new_id_from_chars("T", 1);
732
	mode_T          = register_mode(&newmode);
733

734
735
	/* ANY */
	newmode.name    = new_id_from_chars("ANY", 3);
736
	mode_ANY        = register_mode(&newmode);
737

738
739
	/* BAD */
	newmode.name    = new_id_from_chars("BAD", 3);
740
	mode_BAD        = register_mode(&newmode);
741

742
743
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
744

745
746
	/* boolean */
	newmode.name    = new_id_from_chars("b", 1);
747
	mode_b          = register_mode(&newmode);
748

749
750
	/* Data Modes */
	newmode.vector_elem = 1;
751

752
753
754
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
755

756
757
758
759
	/* float */
	newmode.name    = new_id_from_chars("F", 1);
	newmode.sign    = 1;
	newmode.size    = 32;
760
	mode_F          = register_mode(&newmode);
761

762
763
764
765
	/* double */
	newmode.name    = new_id_from_chars("D", 1);
	newmode.sign    = 1;
	newmode.size    = 64;
766
	mode_D          = register_mode(&newmode);
767

768
769
770
	/* extended */
	newmode.name    = new_id_from_chars("E", 1);
	newmode.sign    = 1;
Matthias Braun's avatar
Matthias Braun committed
771
772
773
	/* note that the tarval module is calculating with 80 bits, but we use
	 * 96 bits, as that is what will be stored to memory by most hardware */
	newmode.size    = 96;
774
	mode_E          = register_mode(&newmode);
775

776
777
778
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
779

780
781
782
783
784
	/* signed byte */
	newmode.name         = new_id_from_chars("Bs", 2);
	newmode.sign         = 1;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
785
	mode_Bs              = register_mode(&newmode);
786

787
788
789
790
791
792
	/* unsigned byte */
	newmode.name         = new_id_from_chars("Bu", 2);
	newmode.arithmetic   = irma_twos_complement;
	newmode.sign         = 0;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
793
	mode_Bu              = register_mode(&newmode);
794

795
796
797
798
799
	/* signed short integer */
	newmode.name         = new_id_from_chars("Hs", 2);
	newmode.sign         = 1;
	newmode.size         = 16;
	newmode.modulo_shift = 32;
800
	mode_Hs              = register_mode(&newmode);
801

802
803
804
805
806
	/* unsigned short integer */
	newmode.name         = new_id_from_chars("Hu", 2);
	newmode.sign         = 0;
	newmode.size         = 16;
	newmode.modulo_shift = 32;
807
	mode_Hu              = register_mode(&newmode);
808

809
810
811
812
813
	/* signed integer */
	newmode.name         = new_id_from_chars("Is", 2);
	newmode.sign         = 1;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
814
	mode_Is              = register_mode(&newmode);
815

816
817
818
819
820
	/* unsigned integer */
	newmode.name         = new_id_from_chars("Iu", 2);
	newmode.sign         = 0;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
821
	mode_Iu              = register_mode(&newmode);
822
823
824
825
826
827

	/* signed long integer */
	newmode.name         = new_id_from_chars("Ls", 2);
	newmode.sign         = 1;
	newmode.size         = 64;
	newmode.modulo_shift = 64;
828
	mode_Ls              = register_mode(&newmode);
829
830
831
832
833
834

	/* unsigned long integer */
	newmode.name         = new_id_from_chars("Lu", 2);
	newmode.sign         = 0;
	newmode.size         = 64;
	newmode.modulo_shift = 64;
835
	mode_Lu              = register_mode(&newmode);
836

837
838
839
840
841
	/* signed long long integer */
	newmode.name         = new_id_from_chars("LLs", 3);
	newmode.sign         = 1;
	newmode.size         = 128;
	newmode.modulo_shift = 128;
842
	mode_LLs             = register_mode(&newmode);
843
844
845
846
847
848

	/* unsigned long long integer */
	newmode.name         = new_id_from_chars("LLu", 3);
	newmode.sign         = 0;
	newmode.size         = 128;
	newmode.modulo_shift = 128;
849
	mode_LLu             = register_mode(&newmode);
850

851
852
	/* Reference Mode */
	newmode.sort       = irms_reference;
853
854
855
856
857
858
	newmode.arithmetic = irma_twos_complement;

	/* pointer */
	newmode.name         = new_id_from_chars("P", 1);
	newmode.sign         = 0;
	newmode.size         = 32;
859
	newmode.modulo_shift = 32;
860
861
	newmode.eq_signed    = mode_Is;
	newmode.eq_unsigned  = mode_Iu;
862
	mode_P               = register_mode(&newmode);
863
864
865
866

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

Michael Beck's avatar
Michael Beck committed
869
/* find a signed mode for an unsigned integer mode */
870
871
ir_mode *find_unsigned_mode(const ir_mode *mode)
{
872
	ir_mode n = *mode;
873

874
875
876
877
878
	/* allowed for reference mode */
	if (mode->sort == irms_reference)
		n.sort = irms_int_number;

	assert(n.sort == irms_int_number);
879
880
	n.sign = 0;
	return find_mode(&n);
881
882
}

Michael Beck's avatar
Michael Beck committed
883
/* find an unsigned mode for a signed integer mode */
884
885
ir_mode *find_signed_mode(const ir_mode *mode)
{
886
	ir_mode n = *mode;
887

888
889
890
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
891
892
}

Michael Beck's avatar
Michael Beck committed
893
/* finds a integer mode with 2*n bits for an integer mode with n bits. */
894
895
ir_mode *find_double_bits_int_mode(const ir_mode *mode)
{
896
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
897

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

900
901
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
902
}
903

904
905
906
907
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
908
909
int mode_honor_signed_zeros(const ir_mode *mode)
{
910
911
912
	/* 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
913
914
915
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
916
917
}

918
919
920
921
922
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
923
924
int mode_overflow_on_unary_Minus(const ir_mode *mode)
{
925
926
927
	if (mode->sort == irms_float_number)
		return mode->arithmetic == irma_ieee754 ? 0 : 1;
	return 1;
928
929
}

Michael Beck's avatar
Michael Beck committed
930
/*
931
 * Returns non-zero if the mode has a reversed wrap-around
Michael Beck's avatar
Michael Beck committed
932
933
934
935
936
 * logic, especially (a + x) - x == a.
 *
 * This is normally true for integer modes, not for floating
 * point modes.
 */
937
938
int mode_wrap_around(const ir_mode *mode)
{
939
940
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
941
942
}

943
944
945
946
947
/*
 * 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)
 */
948
949
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
{
950
951
952
953
954
955
956
957
958
959
960
961
962
	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;

	return ma == irma_twos_complement || ma == irma_ones_complement;
}

963
964
void finish_mode(void)
{
965
	obstack_free(&modes, 0);
Matthias Braun's avatar
Matthias Braun committed
966
	DEL_ARR_F(mode_list);
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989

	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_E   = 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;

990
	mode_P      = NULL;
991
992
	mode_P_code = NULL;
	mode_P_data = NULL;
993
}