irmode.c 20 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
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
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);
		default: return "<unknown>";
	}
#undef X
}

63
64
static inline int modes_are_equal(const ir_mode *m, const ir_mode *n)
{
65
66
67
68
69
	if (m == n) return 1;
	if (m->sort         == n->sort &&
		m->arithmetic   == n->arithmetic &&
		m->size         == n->size &&
		m->sign         == n->sign  &&
70
		m->modulo_shift == n->modulo_shift)
71
		return 1;
Christian Schäfer's avatar
Christian Schäfer committed
72

73
	return 0;
74
}
Matthias Heil's avatar
Matthias Heil committed
75

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

92
93
94
/**
 * sets special values of modes
 */
95
96
static void set_mode_values(ir_mode* mode)
{
97
	switch (get_mode_sort(mode))    {
98
	case irms_reference:
99
100
101
102
103
104
105
	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);
106
		if (get_mode_sort(mode) != irms_float_number) {
107
108
109
110
			mode->all_one = get_tarval_all_one(mode);
		} else {
			mode->all_one = tarval_bad;
		}
111
112
113
114
115
116
117
118
		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;
119
		mode->all_one = tarval_b_true;
120
121
122
123
124
125
126
127
128
129
130
131
		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;
	}
132
}
133

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

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

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

148
149
150
151
/* 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
152

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

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

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

171
172
173
174
175
/* * *
 * functions defined in irmode.h
 * * */

/* JNI access functions */
176
177
178
179
180
181
182
183
184
185
186
187
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; }
188
189
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
190
191
192
193
194
195
196
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; }
197

198

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

204
205
ir_mode *(get_modeP_data)(void)
{
206
	return get_modeP_data_();
207
208
}

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

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

222
/**
223
224
225
 * Registers a new mode.
 *
 * @param new_mode  The new mode template.
226
 */
227
228
static ir_mode *register_mode(const ir_mode *new_mode)
{
229
	ir_mode *mode = NULL;
230

231
	assert(new_mode);
232

233
234
	/* copy mode struct to modes array */
	mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode));
Matthias Braun's avatar
Matthias Braun committed
235
	ARR_APP1(ir_mode*, mode_list, mode);
236

237
	mode->kind = k_ir_mode;
238
	mode->type = new_type_primitive(mode);
239

240
241
	/* add the new mode to the irp list of modes */
	add_irp_mode(mode);
242

243
	set_mode_values(mode);
244

245
246
	hook_new_mode(new_mode, mode);
	return mode;
247
248
249
250
251
}

/*
 * Creates a new mode.
 */
252
253
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)
254
{
255
256
257
258
259
260
261
	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;
262
263
	mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number ||
	                          mode_tmpl.sort == irms_reference) ? modulo_shift : 0;
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
	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:
280
		panic("internal modes cannot be user defined");
281
282
283
284
285

	case irms_float_number:
	case irms_int_number:
	case irms_reference:
		mode = register_mode(&mode_tmpl);
286
		break;
287
	}
288
	assert(mode != NULL);
289
	return mode;
290
291
}

292
/* Functions for the direct access to all attributes of an ir_mode */
293
294
ident *(get_mode_ident)(const ir_mode *mode)
{
295
	return get_mode_ident_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
296
297
}

298
299
const char *get_mode_name(const ir_mode *mode)
{
300
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
301
302
}

303
304
ir_mode_sort (get_mode_sort)(const ir_mode* mode)
{
305
	return get_mode_sort_(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
306
307
}

308
309
unsigned (get_mode_size_bits)(const ir_mode *mode)
{
310
	return get_mode_size_bits_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
311
312
}

313
314
unsigned (get_mode_size_bytes)(const ir_mode *mode)
{
315
	return get_mode_size_bytes_(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
316
317
}

318
319
int (get_mode_sign)(const ir_mode *mode)
{
320
	return get_mode_sign_(mode);
321
322
}

323
324
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode)
{
325
	return get_mode_arithmetic_(mode);
326
327
}

328
329
330
331
332

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

338
339
void *(get_mode_link)(const ir_mode *mode)
{
340
	return get_mode_link_(mode);
341
342
}

343
344
void (set_mode_link)(ir_mode *mode, void *l)
{
345
	set_mode_link_(mode, l);
346
347
}

Matthias Braun's avatar
Matthias Braun committed
348
ir_tarval *get_mode_min(ir_mode *mode)
349
{
350
351
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
352

353
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
354
355
}

Matthias Braun's avatar
Matthias Braun committed
356
ir_tarval *get_mode_max(ir_mode *mode)
357
{
358
359
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
360

361
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
362
363
}

Matthias Braun's avatar
Matthias Braun committed
364
ir_tarval *get_mode_null(ir_mode *mode)
365
{
366
	assert(mode);
367
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
368

369
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
370
371
}

Matthias Braun's avatar
Matthias Braun committed
372
ir_tarval *get_mode_one(ir_mode *mode)
373
{
374
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
375
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
376

377
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
378
379
}

Matthias Braun's avatar
Matthias Braun committed
380
ir_tarval *get_mode_minus_one(ir_mode *mode)
381
{
382
383
	assert(mode);
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
384

385
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
386
387
}

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

Matthias Braun's avatar
Matthias Braun committed
395
ir_tarval *get_mode_infinite(ir_mode *mode)
396
{
397
398
	assert(mode);
	assert(mode_is_float(mode));
399

400
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
401
402
}

Matthias Braun's avatar
Matthias Braun committed
403
ir_tarval *get_mode_NAN(ir_mode *mode)
404
{
405
406
	assert(mode);
	assert(mode_is_float(mode));
407

408
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
409
410
}

411
412
int is_mode(const void *thing)
{
Michael Beck's avatar
Michael Beck committed
413
	return get_kind(thing) == k_ir_mode;
414
415
}

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

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

426
427
int (mode_is_int)(const ir_mode *mode)
{
428
	return mode_is_int_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
429
430
}

431
432
int (mode_is_reference)(const ir_mode *mode)
{
433
	return mode_is_reference_(mode);
434
435
}

436
437
int (mode_is_num)(const ir_mode *mode)
{
438
	return mode_is_num_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
439
440
}

441
442
int (mode_is_data)(const ir_mode *mode)
{
443
	return mode_is_data_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
444
445
}

446
447
int (mode_is_datab)(const ir_mode *mode)
{
448
	return mode_is_datab_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
449
450
}

451
452
int (mode_is_dataM)(const ir_mode *mode)
{
453
	return mode_is_dataM_(mode);
Christian Schäfer's avatar
Christian Schäfer committed
454
}
455

456
/* Returns true if sm can be converted to lm without loss. */
457
458
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
459
	int sm_bits, lm_bits;
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
513

	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
514
		/* do exist machines out there with different pointer lengths ?*/
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
		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. */
530
531
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
{
Moritz Kroll's avatar
Moritz Kroll committed
532
	ir_mode_arithmetic arith;
533
534
535
536
537
538

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

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

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

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

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

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

/* Sets the signed integer equivalent mode for an reference mode. */
564
565
void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
566
567
568
569
570
571
	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. */
572
573
ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
{
574
575
576
577
578
	assert(mode_is_reference(mode));
	return mode->eq_unsigned;
}

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

586
/* initialization, build the default modes */
587
588
void init_mode(void)
{
589
	ir_mode newmode;
590

591
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
592
	mode_list = NEW_ARR_F(ir_mode*, 0);
593

594
	/* initialize predefined modes */
595

596
597
598
599
600
601
602
603
604
	/* Internal Modes */
	newmode.arithmetic   = irma_none;
	newmode.size         = 0;
	newmode.sign         = 0;
	newmode.modulo_shift = 0;
	newmode.eq_signed    = NULL;
	newmode.eq_unsigned  = NULL;
	newmode.link         = NULL;
	newmode.tv_priv      = NULL;
605

606
607
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
608

609
610
	/* Basic Block */
	newmode.name    = new_id_from_chars("BB", 2);
611
	mode_BB         = register_mode(&newmode);
612

613
614
	/* eXecution */
	newmode.name    = new_id_from_chars("X", 1);
615
	mode_X          = register_mode(&newmode);
616

617
618
	/* Memory Modes */
	newmode.sort    = irms_memory;
619

620
621
	/* Memory */
	newmode.name    = new_id_from_chars("M", 1);
622
	mode_M          = register_mode(&newmode);
623

624
625
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
626

627
628
	/* Tuple */
	newmode.name    = new_id_from_chars("T", 1);
629
	mode_T          = register_mode(&newmode);
630

631
632
	/* ANY */
	newmode.name    = new_id_from_chars("ANY", 3);
633
	mode_ANY        = register_mode(&newmode);
634

635
636
	/* BAD */
	newmode.name    = new_id_from_chars("BAD", 3);
637
	mode_BAD        = register_mode(&newmode);
638

639
640
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
641

642
643
	/* boolean */
	newmode.name    = new_id_from_chars("b", 1);
644
	mode_b          = register_mode(&newmode);
645

646
647
648
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
649

650
651
652
653
	/* float */
	newmode.name    = new_id_from_chars("F", 1);
	newmode.sign    = 1;
	newmode.size    = 32;
654
	mode_F          = register_mode(&newmode);
655

656
657
658
659
	/* double */
	newmode.name    = new_id_from_chars("D", 1);
	newmode.sign    = 1;
	newmode.size    = 64;
660
	mode_D          = register_mode(&newmode);
661

662
663
664
	/* extended */
	newmode.name    = new_id_from_chars("E", 1);
	newmode.sign    = 1;
Matthias Braun's avatar
Matthias Braun committed
665
666
667
	/* 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;
668
	mode_E          = register_mode(&newmode);
669

670
671
672
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
673

674
675
676
677
678
	/* signed byte */
	newmode.name         = new_id_from_chars("Bs", 2);
	newmode.sign         = 1;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
679
	mode_Bs              = register_mode(&newmode);
680

681
682
683
684
685
686
	/* 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;
687
	mode_Bu              = register_mode(&newmode);
688

689
690
691
692
693
	/* signed short integer */
	newmode.name         = new_id_from_chars("Hs", 2);
	newmode.sign         = 1;
	newmode.size         = 16;
	newmode.modulo_shift = 32;
694
	mode_Hs              = register_mode(&newmode);
695

696
697
698
699
700
	/* unsigned short integer */
	newmode.name         = new_id_from_chars("Hu", 2);
	newmode.sign         = 0;
	newmode.size         = 16;
	newmode.modulo_shift = 32;
701
	mode_Hu              = register_mode(&newmode);
702

703
704
705
706
707
	/* signed integer */
	newmode.name         = new_id_from_chars("Is", 2);
	newmode.sign         = 1;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
708
	mode_Is              = register_mode(&newmode);
709

710
711
712
713
714
	/* unsigned integer */
	newmode.name         = new_id_from_chars("Iu", 2);
	newmode.sign         = 0;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
715
	mode_Iu              = register_mode(&newmode);
716
717
718
719
720
721

	/* signed long integer */
	newmode.name         = new_id_from_chars("Ls", 2);
	newmode.sign         = 1;
	newmode.size         = 64;
	newmode.modulo_shift = 64;
722
	mode_Ls              = register_mode(&newmode);
723
724
725
726
727
728

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

731
732
733
734
735
	/* signed long long integer */
	newmode.name         = new_id_from_chars("LLs", 3);
	newmode.sign         = 1;
	newmode.size         = 128;
	newmode.modulo_shift = 128;
736
	mode_LLs             = register_mode(&newmode);
737
738
739
740
741
742

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

745
746
	/* Reference Mode */
	newmode.sort       = irms_reference;
747
748
749
750
751
752
	newmode.arithmetic = irma_twos_complement;

	/* pointer */
	newmode.name         = new_id_from_chars("P", 1);
	newmode.sign         = 0;
	newmode.size         = 32;
753
	newmode.modulo_shift = 32;
754
755
	newmode.eq_signed    = mode_Is;
	newmode.eq_unsigned  = mode_Iu;
756
	mode_P               = register_mode(&newmode);
757
758
759
760

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

Michael Beck's avatar
Michael Beck committed
763
/* find a signed mode for an unsigned integer mode */
764
765
ir_mode *find_unsigned_mode(const ir_mode *mode)
{
766
	ir_mode n = *mode;
767

768
769
770
771
772
	/* allowed for reference mode */
	if (mode->sort == irms_reference)
		n.sort = irms_int_number;

	assert(n.sort == irms_int_number);
773
774
	n.sign = 0;
	return find_mode(&n);
775
776
}

Michael Beck's avatar
Michael Beck committed
777
/* find an unsigned mode for a signed integer mode */
778
779
ir_mode *find_signed_mode(const ir_mode *mode)
{
780
	ir_mode n = *mode;
781

782
783
784
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
785
786
}

Michael Beck's avatar
Michael Beck committed
787
/* finds a integer mode with 2*n bits for an integer mode with n bits. */
788
789
ir_mode *find_double_bits_int_mode(const ir_mode *mode)
{
790
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
791

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

794
795
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
796
}
797

798
799
800
801
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
802
803
int mode_honor_signed_zeros(const ir_mode *mode)
{
804
805
806
	/* 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
807
808
809
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
810
811
}

812
813
814
815
816
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
817
818
int mode_overflow_on_unary_Minus(const ir_mode *mode)
{
819
820
821
	if (mode->sort == irms_float_number)
		return mode->arithmetic == irma_ieee754 ? 0 : 1;
	return 1;
822
823
}

Michael Beck's avatar
Michael Beck committed
824
/*
825
 * Returns non-zero if the mode has a reversed wrap-around
Michael Beck's avatar
Michael Beck committed
826
827
828
829
830
 * logic, especially (a + x) - x == a.
 *
 * This is normally true for integer modes, not for floating
 * point modes.
 */
831
832
int mode_wrap_around(const ir_mode *mode)
{
833
834
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
835
836
}

837
838
839
840
841
/*
 * 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)
 */
842
843
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
{
844
845
846
847
848
849
850
851
852
853
	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;

854
	return ma == irma_twos_complement;
855
856
}

857
858
859
860
861
ir_type *(get_type_for_mode) (const ir_mode *mode)
{
	return get_type_for_mode_(mode);
}

862
863
void finish_mode(void)
{
864
	obstack_free(&modes, 0);
Matthias Braun's avatar
Matthias Braun committed
865
	DEL_ARR_F(mode_list);
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888

	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;

889
	mode_P      = NULL;
890
891
	mode_P_code = NULL;
	mode_P_data = NULL;
892
}