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"
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
57
58
59
60
61
62
63
64
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
}

65
/**
66
 * Compare modes that don't need to have their code field
67
 * correctly set
68
69
70
 *
 * TODO: Add other fields
 **/
71
static inline int modes_are_equal(const ir_mode *m, const ir_mode *n) {
72
73
74
75
76
77
78
79
	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
80

81
	return 0;
82
}
Matthias Heil's avatar
Matthias Heil committed
83

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

#ifdef FIRM_STATISTICS
/* return the mode index, only needed for statistics */
int stat_find_mode_index(const ir_mode *m) {
	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;
}
110

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

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

160
161
162
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
163

164
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
165

166
167
168
169
170
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
171
172
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
173

174
175
176
177
/* 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
178

179
180
181
182
183
184
185
186
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;
187
188
ir_mode *mode_LLs;  /* 128 bit */
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
189

190
191
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
192
193

/* machine specific modes */
194
195
ir_mode *mode_P_code;   /**< machine specific pointer mode for code addresses */
ir_mode *mode_P_data;   /**< machine specific pointer mode for data addresses */
196

197
198
199
200
201
/* * *
 * functions defined in irmode.h
 * * */

/* JNI access functions */
202
203
204
205
206
207
208
209
210
211
212
213
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; }
214
215
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
216
217
218
219
220
221
222
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; }
223

224

225
ir_mode *(get_modeP_code)(void) {
226
	return _get_modeP_code();
Michael Beck's avatar
Michael Beck committed
227
228
}

229
ir_mode *(get_modeP_data)(void) {
230
	return _get_modeP_data();
231
232
233
}

void set_modeP_code(ir_mode *p) {
234
235
	assert(mode_is_reference(p));
	mode_P_code = p;
236
237
238
}

void set_modeP_data(ir_mode *p) {
239
240
	assert(mode_is_reference(p));
	mode_P_data = p;
Michael Beck's avatar
Michael Beck committed
241
}
242

243
/**
244
245
246
 * Registers a new mode.
 *
 * @param new_mode  The new mode template.
247
 */
248
249
static ir_mode *register_mode(const ir_mode *new_mode) {
	ir_mode *mode = NULL;
250

251
	assert(new_mode);
252

253
254
	/* copy mode struct to modes array */
	mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode));
Matthias Braun's avatar
Matthias Braun committed
255
	ARR_APP1(ir_mode*, mode_list, mode);
256

257
	mode->kind = k_ir_mode;
258
	mode->type = new_type_primitive(mode);
259

260
261
	/* add the new mode to the irp list of modes */
	add_irp_mode(mode);
262

263
	set_mode_values(mode);
264

265
266
	hook_new_mode(new_mode, mode);
	return mode;
267
268
269
270
271
}

/*
 * Creates a new mode.
 */
272
273
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)
274
{
275
276
277
278
279
280
281
	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;
282
283
	mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number ||
	                          mode_tmpl.sort == irms_reference) ? modulo_shift : 0;
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
	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:
301
		panic("internal modes cannot be user defined");
302
303
304
305
306

	case irms_float_number:
	case irms_int_number:
	case irms_reference:
		mode = register_mode(&mode_tmpl);
307
		break;
308
	}
309
	assert(mode != NULL);
310
	return mode;
311
312
}

313
314
315
/*
 * Creates a new vector mode.
 */
316
317
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)
318
{
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
	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) {
		assert(0 && "vector modes should have at least 2 elements");
		return NULL;
	}

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

	case irms_reference:
352
		panic("only integer and floating point modes can be vectorized");
353
354

	case irms_float_number:
355
		panic("not yet implemented");
356
357
358
359

	case irms_int_number:
		mode = register_mode(&mode_tmpl);
	}
360
	assert(mode != NULL);
361
	return mode;
362
363
}

364
/* Functions for the direct access to all attributes of an ir_mode */
365
ident *(get_mode_ident)(const ir_mode *mode) {
366
	return _get_mode_ident(mode);
Christian Schäfer's avatar
Christian Schäfer committed
367
368
}

369
const char *get_mode_name(const ir_mode *mode) {
370
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
371
372
}

373
ir_mode_sort (get_mode_sort)(const ir_mode* mode) {
374
	return _get_mode_sort(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
375
376
}

377
unsigned (get_mode_size_bits)(const ir_mode *mode) {
378
	return _get_mode_size_bits(mode);
Christian Schäfer's avatar
Christian Schäfer committed
379
380
}

381
unsigned (get_mode_size_bytes)(const ir_mode *mode) {
382
	return _get_mode_size_bytes(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
383
384
}

385
int (get_mode_sign)(const ir_mode *mode) {
386
	return _get_mode_sign(mode);
387
388
}

389
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode) {
390
	return get_mode_arithmetic(mode);
391
392
}

393
394
395
396
397

/* 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.
 */
398
unsigned int (get_mode_modulo_shift)(const ir_mode *mode) {
399
	return _get_mode_modulo_shift(mode);
400
401
}

402
unsigned int (get_mode_n_vector_elems)(const ir_mode *mode) {
403
	return _get_mode_vector_elems(mode);
404
405
}

406
void *(get_mode_link)(const ir_mode *mode) {
407
	return _get_mode_link(mode);
408
409
}

410
void (set_mode_link)(ir_mode *mode, void *l) {
411
	_set_mode_link(mode, l);
412
413
}

414
tarval *get_mode_min(ir_mode *mode) {
415
416
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
417

418
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
419
420
}

421
tarval *get_mode_max(ir_mode *mode) {
422
423
	assert(mode);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
424

425
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
426
427
}

428
tarval *get_mode_null(ir_mode *mode) {
429
	assert(mode);
430
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
431

432
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
433
434
}

435
tarval *get_mode_one(ir_mode *mode) {
436
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
437
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
438

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

442
tarval *get_mode_minus_one(ir_mode *mode) {
443
444
	assert(mode);
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
445

446
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
447
448
}

449
tarval *get_mode_all_one(ir_mode *mode) {
450
	assert(mode);
Matthias Braun's avatar
Matthias Braun committed
451
	assert(mode_is_datab(mode));
452
453
454
	return mode->all_one;
}

455
tarval *get_mode_infinite(ir_mode *mode) {
456
457
	assert(mode);
	assert(mode_is_float(mode));
458

459
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
460
461
}

462
tarval *get_mode_NAN(ir_mode *mode) {
463
464
	assert(mode);
	assert(mode_is_float(mode));
465

466
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
467
468
}

Michael Beck's avatar
Michael Beck committed
469
int is_mode(const void *thing) {
Michael Beck's avatar
Michael Beck committed
470
	return get_kind(thing) == k_ir_mode;
471
472
}

473
int (mode_is_signed)(const ir_mode *mode) {
474
	return _mode_is_signed(mode);
Christian Schäfer's avatar
Christian Schäfer committed
475
476
}

477
int (mode_is_float)(const ir_mode *mode) {
478
	return _mode_is_float(mode);
Christian Schäfer's avatar
Christian Schäfer committed
479
480
}

481
int (mode_is_int)(const ir_mode *mode) {
482
	return _mode_is_int(mode);
Christian Schäfer's avatar
Christian Schäfer committed
483
484
}

485
int (mode_is_reference)(const ir_mode *mode) {
486
	return _mode_is_reference(mode);
487
488
}

489
int (mode_is_num)(const ir_mode *mode) {
490
	return _mode_is_num(mode);
Christian Schäfer's avatar
Christian Schäfer committed
491
492
}

493
int (mode_is_data)(const ir_mode *mode) {
494
	return _mode_is_data(mode);
Christian Schäfer's avatar
Christian Schäfer committed
495
496
}

497
int (mode_is_datab)(const ir_mode *mode) {
498
	return _mode_is_datab(mode);
Christian Schäfer's avatar
Christian Schäfer committed
499
500
}

501
int (mode_is_dataM)(const ir_mode *mode) {
502
	return _mode_is_dataM(mode);
Christian Schäfer's avatar
Christian Schäfer committed
503
}
504

505
int (mode_is_float_vector)(const ir_mode *mode) {
506
	return _mode_is_float_vector(mode);
507
508
}

509
int (mode_is_int_vector)(const ir_mode *mode) {
510
	return _mode_is_int_vector(mode);
Michael Beck's avatar
Michael Beck committed
511
512
}

513
/* Returns true if sm can be converted to lm without loss. */
514
int smaller_mode(const ir_mode *sm, const ir_mode *lm) {
515
	int sm_bits, lm_bits;
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570

	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
571
		/* do exist machines out there with different pointer lengths ?*/
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
		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. */
int values_in_mode(const ir_mode *sm, const ir_mode *lm) {
	int sm_bits, lm_bits;
Moritz Kroll's avatar
Moritz Kroll committed
589
	ir_mode_arithmetic arith;
590
591
592
593
594
595

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

Moritz Kroll's avatar
Moritz Kroll committed
596
597
598
	if (sm == mode_b)
		return mode_is_int(lm);

599
600
601
	sm_bits = get_mode_size_bits(sm);
	lm_bits = get_mode_size_bits(lm);

Moritz Kroll's avatar
Moritz Kroll committed
602
603
	arith = get_mode_arithmetic(sm);
	if (arith != get_mode_arithmetic(lm))
604
605
		return 0;

Moritz Kroll's avatar
Moritz Kroll committed
606
607
608
609
	switch (arith) {
		case irma_twos_complement:
		case irma_ieee754:
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
610

Moritz Kroll's avatar
Moritz Kroll committed
611
612
		default:
			return 0;
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
	}
}

/* Return the signed integer equivalent mode for an reference mode. */
ir_mode *get_reference_mode_signed_eq(ir_mode *mode) {
	assert(mode_is_reference(mode));
	return mode->eq_signed;
}

/* Sets the signed integer equivalent mode for an reference mode. */
void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode) {
	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. */
ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode) {
	assert(mode_is_reference(mode));
	return mode->eq_unsigned;
}

/* Sets the unsigned integer equivalent mode for an reference mode. */
void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode) {
	assert(mode_is_reference(ref_mode));
	assert(mode_is_int(int_mode));
	ref_mode->eq_unsigned = int_mode;
640
641
}

642
/* initialization, build the default modes */
643
void init_mode(void) {
644
	ir_mode newmode;
645

646
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
647
	mode_list = NEW_ARR_F(ir_mode*, 0);
648

649
	/* initialize predefined modes */
650

651
652
653
654
655
656
657
658
659
660
	/* 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;
661

662
663
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
664

665
666
	/* Basic Block */
	newmode.name    = new_id_from_chars("BB", 2);
667
	mode_BB         = register_mode(&newmode);
668

669
670
	/* eXecution */
	newmode.name    = new_id_from_chars("X", 1);
671
	mode_X          = register_mode(&newmode);
672

673
674
	/* Memory Modes */
	newmode.sort    = irms_memory;
675

676
677
	/* Memory */
	newmode.name    = new_id_from_chars("M", 1);
678
	mode_M          = register_mode(&newmode);
679

680
681
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
682

683
684
	/* Tuple */
	newmode.name    = new_id_from_chars("T", 1);
685
	mode_T          = register_mode(&newmode);
686

687
688
	/* ANY */
	newmode.name    = new_id_from_chars("ANY", 3);
689
	mode_ANY        = register_mode(&newmode);
690

691
692
	/* BAD */
	newmode.name    = new_id_from_chars("BAD", 3);
693
	mode_BAD        = register_mode(&newmode);
694

695
696
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
697

698
699
	/* boolean */
	newmode.name    = new_id_from_chars("b", 1);
700
	mode_b          = register_mode(&newmode);
701

702
703
	/* Data Modes */
	newmode.vector_elem = 1;
704

705
706
707
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
708

709
710
711
712
	/* float */
	newmode.name    = new_id_from_chars("F", 1);
	newmode.sign    = 1;
	newmode.size    = 32;
713
	mode_F          = register_mode(&newmode);
714

715
716
717
718
	/* double */
	newmode.name    = new_id_from_chars("D", 1);
	newmode.sign    = 1;
	newmode.size    = 64;
719
	mode_D          = register_mode(&newmode);
720

721
722
723
	/* extended */
	newmode.name    = new_id_from_chars("E", 1);
	newmode.sign    = 1;
Matthias Braun's avatar
Matthias Braun committed
724
725
726
	/* 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;
727
	mode_E          = register_mode(&newmode);
728

729
730
731
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
732

733
734
735
736
737
	/* signed byte */
	newmode.name         = new_id_from_chars("Bs", 2);
	newmode.sign         = 1;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
738
	mode_Bs              = register_mode(&newmode);
739

740
741
742
743
744
745
	/* 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;
746
	mode_Bu              = register_mode(&newmode);
747

748
749
750
751
752
	/* signed short integer */
	newmode.name         = new_id_from_chars("Hs", 2);
	newmode.sign         = 1;
	newmode.size         = 16;
	newmode.modulo_shift = 32;
753
	mode_Hs              = register_mode(&newmode);
754

755
756
757
758
759
	/* unsigned short integer */
	newmode.name         = new_id_from_chars("Hu", 2);
	newmode.sign         = 0;
	newmode.size         = 16;
	newmode.modulo_shift = 32;
760
	mode_Hu              = register_mode(&newmode);
761

762
763
764
765
766
	/* signed integer */
	newmode.name         = new_id_from_chars("Is", 2);
	newmode.sign         = 1;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
767
	mode_Is              = register_mode(&newmode);
768

769
770
771
772
773
	/* unsigned integer */
	newmode.name         = new_id_from_chars("Iu", 2);
	newmode.sign         = 0;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
774
	mode_Iu              = register_mode(&newmode);
775
776
777
778
779
780

	/* signed long integer */
	newmode.name         = new_id_from_chars("Ls", 2);
	newmode.sign         = 1;
	newmode.size         = 64;
	newmode.modulo_shift = 64;
781
	mode_Ls              = register_mode(&newmode);
782
783
784
785
786
787

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

790
791
792
793
794
	/* signed long long integer */
	newmode.name         = new_id_from_chars("LLs", 3);
	newmode.sign         = 1;
	newmode.size         = 128;
	newmode.modulo_shift = 128;
795
	mode_LLs             = register_mode(&newmode);
796
797
798
799
800
801

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

804
805
	/* Reference Mode */
	newmode.sort       = irms_reference;
806
807
808
809
810
811
	newmode.arithmetic = irma_twos_complement;

	/* pointer */
	newmode.name         = new_id_from_chars("P", 1);
	newmode.sign         = 0;
	newmode.size         = 32;
812
	newmode.modulo_shift = 32;
813
814
	newmode.eq_signed    = mode_Is;
	newmode.eq_unsigned  = mode_Iu;
815
	mode_P               = register_mode(&newmode);
816
817
818
819

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

Michael Beck's avatar
Michael Beck committed
822
823
/* find a signed mode for an unsigned integer mode */
ir_mode *find_unsigned_mode(const ir_mode *mode) {
824
	ir_mode n = *mode;
825

826
827
828
829
830
	/* allowed for reference mode */
	if (mode->sort == irms_reference)
		n.sort = irms_int_number;

	assert(n.sort == irms_int_number);
831
832
	n.sign = 0;
	return find_mode(&n);
833
834
}

Michael Beck's avatar
Michael Beck committed
835
836
/* find an unsigned mode for a signed integer mode */
ir_mode *find_signed_mode(const ir_mode *mode) {
837
	ir_mode n = *mode;
838

839
840
841
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
842
843
}

Michael Beck's avatar
Michael Beck committed
844
845
/* finds a integer mode with 2*n bits for an integer mode with n bits. */
ir_mode *find_double_bits_int_mode(const ir_mode *mode) {
846
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
847

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

850
851
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
852
}
853

854
855
856
857
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
858
859
860
861
int mode_honor_signed_zeros(const ir_mode *mode) {
	/* 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
862
863
864
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
865
866
}

867
868
869
870
871
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
872
873
874
875
int mode_overflow_on_unary_Minus(const ir_mode *mode) {
	if (mode->sort == irms_float_number)
		return mode->arithmetic == irma_ieee754 ? 0 : 1;
	return 1;
876
877
}

Michael Beck's avatar
Michael Beck committed
878
/*
879
 * Returns non-zero if the mode has a reversed wrap-around
Michael Beck's avatar
Michael Beck committed
880
881
882
883
884
885
 * logic, especially (a + x) - x == a.
 *
 * This is normally true for integer modes, not for floating
 * point modes.
 */
int mode_wrap_around(const ir_mode *mode) {
886
887
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
888
889
}

890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
/*
 * 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)
 */
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst) {
	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;
}

909
void finish_mode(void) {
910
	obstack_free(&modes, 0);
Matthias Braun's avatar
Matthias Braun committed
911
	DEL_ARR_F(mode_list);
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934

	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;

935
	mode_P      = NULL;
936
937
	mode_P_code = NULL;
	mode_P_data = NULL;
938
}