irmode.c 22.9 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

Michael Beck's avatar
Michael Beck committed
28
#ifdef HAVE_STDLIB_H
29
# include <stdlib.h>
Michael Beck's avatar
Michael Beck committed
30
31
#endif
#ifdef HAVE_STRING_H
32
# include <string.h>
Michael Beck's avatar
Michael Beck committed
33
34
35
#endif

# include <stddef.h>
36

37
# include "irprog_t.h"
38
39
# include "irmode_t.h"
# include "ident.h"
Michael Beck's avatar
Michael Beck committed
40
# include "tv_t.h"
41
# include "obst.h"
42
# include "irhooks.h"
43
# include "irtools.h"
Matthias Braun's avatar
Matthias Braun committed
44
# include "array.h"
Christian Schäfer's avatar
Christian Schäfer committed
45

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

Michael Beck's avatar
Michael Beck committed
49
/** Number of defined modes. */
50
static int num_modes = 0;
Christian Schäfer's avatar
Christian Schäfer committed
51

Michael Beck's avatar
Michael Beck committed
52
/** The list of all currently existing modes. */
Matthias Braun's avatar
Matthias Braun committed
53
54
static ir_mode **mode_list;

55
/**
56
 * Compare modes that don't need to have their code field
57
 * correctly set
58
59
60
 *
 * TODO: Add other fields
 **/
Michael Beck's avatar
Michael Beck committed
61
static INLINE int modes_are_equal(const ir_mode *m, const ir_mode *n) {
62
63
64
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  &&
		m->modulo_shift == n->modulo_shift &&
		m->vector_elem  == n->vector_elem)
		return 1;
Christian Schäfer's avatar
Christian Schäfer committed
70

71
	return 0;
72
}
Matthias Heil's avatar
Matthias Heil committed
73

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

Michael Beck's avatar
Michael Beck committed
101
102
103
104
/* 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];
105
	return NULL;
106
}
Michael Beck's avatar
Michael Beck committed
107
#endif
Christian Schäfer's avatar
Christian Schäfer committed
108

109
110
111
/**
 * sets special values of modes
 */
112
113
static void set_mode_values(ir_mode* mode) {
	switch (get_mode_sort(mode))    {
114
	case irms_reference:
115
116
117
118
119
120
121
	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);
122
123
124
125
126
		if(get_mode_sort(mode) != irms_float_number) {
			mode->all_one = get_tarval_all_one(mode);
		} else {
			mode->all_one = tarval_bad;
		}
127
128
129
130
131
132
133
134
		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;
135
		mode->all_one = tarval_b_true;
136
137
138
139
140
141
142
143
144
145
146
147
		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;
	}
148
}
149

150
151
152
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
153

154
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
155

156
157
158
159
160
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
161
162
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
163

164
165
166
167
/* 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
168

169
170
171
172
173
174
175
176
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;
177
178
ir_mode *mode_LLs;  /* 128 bit */
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
179

180
181
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
182
183

/* machine specific modes */
184
185
ir_mode *mode_P_code;   /**< machine specific pointer mode for code addresses */
ir_mode *mode_P_data;   /**< machine specific pointer mode for data addresses */
186

187
188
189
190
191
/* * *
 * functions defined in irmode.h
 * * */

/* JNI access functions */
192
193
194
195
196
197
198
199
200
201
202
203
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; }
204
205
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
206
207
208
209
210
211
212
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; }
213

214

215
ir_mode *(get_modeP_code)(void) {
216
	return _get_modeP_code();
Michael Beck's avatar
Michael Beck committed
217
218
}

219
ir_mode *(get_modeP_data)(void) {
220
	return _get_modeP_data();
221
222
223
}

void set_modeP_code(ir_mode *p) {
224
225
	assert(mode_is_reference(p));
	mode_P_code = p;
226
227
228
}

void set_modeP_data(ir_mode *p) {
229
230
	assert(mode_is_reference(p));
	mode_P_data = p;
Michael Beck's avatar
Michael Beck committed
231
}
232

233
/**
234
235
236
 * Registers a new mode.
 *
 * @param new_mode  The new mode template.
237
 */
238
239
static ir_mode *register_mode(const ir_mode *new_mode) {
	ir_mode *mode = NULL;
240

241
	assert(new_mode);
242

243
244
	/* copy mode struct to modes array */
	mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode));
Matthias Braun's avatar
Matthias Braun committed
245
	ARR_APP1(ir_mode*, mode_list, mode);
246

247
	mode->kind = k_ir_mode;
248
249
250
251
	if (num_modes >= irm_max)  {
		mode->code = num_modes;
	}
	num_modes++;
252

253
254
	/* add the new mode to the irp list of modes */
	add_irp_mode(mode);
255

256
	set_mode_values(mode);
257

258
259
	hook_new_mode(new_mode, mode);
	return mode;
260
261
262
263
264
}

/*
 * Creates a new mode.
 */
265
266
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)
267
{
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
	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;
	mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0;
	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:
		assert(0 && "internal modes cannot be user defined");
		break;

	case irms_float_number:
	case irms_int_number:
	case irms_reference:
		mode = register_mode(&mode_tmpl);
	}
	return mode;
302
303
}

304
305
306
/*
 * Creates a new vector mode.
 */
307
308
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)
309
{
310
311
312
313
314
315
316
317
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
349
350
351
352
353
354
	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:
		assert(0 && "internal modes cannot be user defined");
		break;

	case irms_reference:
		assert(0 && "only integer and floating point modes can be vectorized");
		break;

	case irms_float_number:
		assert(0 && "not yet implemented");
		break;

	case irms_int_number:
		mode = register_mode(&mode_tmpl);
	}
	return mode;
355
356
}

357
/* Functions for the direct access to all attributes of an ir_mode */
358
ir_modecode (get_mode_modecode)(const ir_mode *mode) {
359
	return _get_mode_modecode(mode);
Christian Schäfer's avatar
Christian Schäfer committed
360
361
}

362
ident *(get_mode_ident)(const ir_mode *mode) {
363
	return _get_mode_ident(mode);
Christian Schäfer's avatar
Christian Schäfer committed
364
365
}

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

370
ir_mode_sort (get_mode_sort)(const ir_mode* mode) {
371
	return _get_mode_sort(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
372
373
}

374
unsigned (get_mode_size_bits)(const ir_mode *mode) {
375
	return _get_mode_size_bits(mode);
Christian Schäfer's avatar
Christian Schäfer committed
376
377
}

378
unsigned (get_mode_size_bytes)(const ir_mode *mode) {
379
	return _get_mode_size_bytes(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
380
381
}

382
int (get_mode_sign)(const ir_mode *mode) {
383
	return _get_mode_sign(mode);
384
385
}

386
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode) {
387
	return get_mode_arithmetic(mode);
388
389
}

390
391
392
393
394

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

399
unsigned int (get_mode_n_vector_elems)(const ir_mode *mode) {
400
	return _get_mode_vector_elems(mode);
401
402
}

403
void *(get_mode_link)(const ir_mode *mode) {
404
	return _get_mode_link(mode);
405
406
}

407
void (set_mode_link)(ir_mode *mode, void *l) {
408
	_set_mode_link(mode, l);
409
410
}

411
tarval *get_mode_min(ir_mode *mode) {
412
	assert(mode);
413
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
414
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
415

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

419
tarval *get_mode_max(ir_mode *mode) {
420
	assert(mode);
421
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
422
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
423

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

427
tarval *get_mode_null(ir_mode *mode) {
428
	assert(mode);
429
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
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);
437
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
Matthias Braun's avatar
Matthias Braun committed
438
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
439

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

443
tarval *get_mode_minus_one(ir_mode *mode) {
444
	assert(mode);
445
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
446
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
447

448
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
449
450
}

451
tarval *get_mode_all_one(ir_mode *mode) {
452
	assert(mode);
453
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
Matthias Braun's avatar
Matthias Braun committed
454
	assert(mode_is_datab(mode));
455
456
457
	return mode->all_one;
}

458
tarval *get_mode_infinite(ir_mode *mode) {
459
	assert(mode);
460
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
461
	assert(mode_is_float(mode));
462

463
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
464
465
}

466
tarval *get_mode_NAN(ir_mode *mode) {
467
	assert(mode);
468
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
469
	assert(mode_is_float(mode));
470

471
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
472
473
}

474
int is_mode(void *thing) {
475
476
477
478
	if (get_kind(thing) == k_ir_mode)
		return 1;
	else
		return 0;
479
480
}

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

485
int (mode_is_float)(const ir_mode *mode) {
486
	return _mode_is_float(mode);
Christian Schäfer's avatar
Christian Schäfer committed
487
488
}

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

493
int (mode_is_reference)(const ir_mode *mode) {
494
	return _mode_is_reference(mode);
495
496
}

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

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

505
int (mode_is_datab)(const ir_mode *mode) {
506
	return _mode_is_datab(mode);
Christian Schäfer's avatar
Christian Schäfer committed
507
508
}

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

513
int (mode_is_float_vector)(const ir_mode *mode) {
514
	return _mode_is_float_vector(mode);
515
516
}

517
int (mode_is_int_vector)(const ir_mode *mode) {
518
	return _mode_is_int_vector(mode);
Michael Beck's avatar
Michael Beck committed
519
520
}

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

	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:
		/* do exist machines out there with different pointer lenghts ?*/
		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
597
	ir_mode_arithmetic arith;
598
599
600
601
602
603

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

Moritz Kroll's avatar
Moritz Kroll committed
604
605
606
	if (sm == mode_b)
		return mode_is_int(lm);

607
608
609
	sm_bits = get_mode_size_bits(sm);
	lm_bits = get_mode_size_bits(lm);

Moritz Kroll's avatar
Moritz Kroll committed
610
611
	arith = get_mode_arithmetic(sm);
	if (arith != get_mode_arithmetic(lm))
612
613
		return 0;

Moritz Kroll's avatar
Moritz Kroll committed
614
615
616
617
	switch (arith) {
		case irma_twos_complement:
		case irma_ieee754:
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
618

Moritz Kroll's avatar
Moritz Kroll committed
619
620
		default:
			return 0;
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
	}
}

/* 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;
648
649
}

650
/* initialization, build the default modes */
651
void init_mode(void) {
652
	ir_mode newmode;
653

654
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
655
	mode_list = NEW_ARR_F(ir_mode*, 0);
656

657
658
	num_modes  =  0;
	/* initialize predefined modes */
659

660
661
662
663
664
665
666
667
668
669
	/* 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;
670

671
672
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
673

674
675
676
	/* Basic Block */
	newmode.name    = new_id_from_chars("BB", 2);
	newmode.code    = irm_BB;
677

678
	mode_BB = register_mode(&newmode);
679

680
681
682
	/* eXecution */
	newmode.name    = new_id_from_chars("X", 1);
	newmode.code    = irm_X;
683

684
	mode_X = register_mode(&newmode);
685

686
687
	/* Memory Modes */
	newmode.sort    = irms_memory;
688

689
690
691
	/* Memory */
	newmode.name    = new_id_from_chars("M", 1);
	newmode.code    = irm_M;
692

693
	mode_M = register_mode(&newmode);
694

695
696
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
697

698
699
700
	/* Tuple */
	newmode.name    = new_id_from_chars("T", 1);
	newmode.code    = irm_T;
701

702
	mode_T = register_mode(&newmode);
703

704
705
706
	/* ANY */
	newmode.name    = new_id_from_chars("ANY", 3);
	newmode.code    = irm_ANY;
707

708
	mode_ANY = register_mode(&newmode);
709

710
711
712
	/* BAD */
	newmode.name    = new_id_from_chars("BAD", 3);
	newmode.code    = irm_BAD;
713

714
	mode_BAD = register_mode(&newmode);
715

716
717
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
718

719
720
721
	/* boolean */
	newmode.name    = new_id_from_chars("b", 1);
	newmode.code    = irm_b;
722

723
	mode_b = register_mode(&newmode);
724

725
726
	/* Data Modes */
	newmode.vector_elem = 1;
727

728
729
730
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
731

732
733
734
735
736
	/* float */
	newmode.name    = new_id_from_chars("F", 1);
	newmode.code    = irm_F;
	newmode.sign    = 1;
	newmode.size    = 32;
737

738
	mode_F = register_mode(&newmode);
739

740
741
742
743
744
	/* double */
	newmode.name    = new_id_from_chars("D", 1);
	newmode.code    = irm_D;
	newmode.sign    = 1;
	newmode.size    = 64;
745

746
	mode_D = register_mode(&newmode);
747

748
749
750
751
752
	/* extended */
	newmode.name    = new_id_from_chars("E", 1);
	newmode.code    = irm_E;
	newmode.sign    = 1;
	newmode.size    = 80;
753

754
	mode_E = register_mode(&newmode);
755

756
757
758
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
759

760
761
762
763
764
765
	/* signed byte */
	newmode.name         = new_id_from_chars("Bs", 2);
	newmode.code         = irm_Bs;
	newmode.sign         = 1;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
766

767
	mode_Bs = register_mode(&newmode);
768

769
770
771
772
773
774
775
	/* unsigned byte */
	newmode.name         = new_id_from_chars("Bu", 2);
	newmode.code         = irm_Bu;
	newmode.arithmetic   = irma_twos_complement;
	newmode.sign         = 0;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
776

777
	mode_Bu = register_mode(&newmode);
778

779
780
781
782
783
784
	/* signed short integer */
	newmode.name         = new_id_from_chars("Hs", 2);
	newmode.code         = irm_Hs;
	newmode.sign         = 1;
	newmode.size         = 16;
	newmode.modulo_shift = 32;
785

786
	mode_Hs = register_mode(&newmode);
787

788
789
790
791
792
793
	/* unsigned short integer */
	newmode.name         = new_id_from_chars("Hu", 2);
	newmode.code         = irm_Hu;
	newmode.sign         = 0;
	newmode.size         = 16;
	newmode.modulo_shift = 32;
794

795
	mode_Hu = register_mode(&newmode);
796

797
798
799
800
801
802
	/* signed integer */
	newmode.name         = new_id_from_chars("Is", 2);
	newmode.code         = irm_Is;
	newmode.sign         = 1;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
803

804
	mode_Is = register_mode(&newmode);
805

806
807
808
809
810
811
	/* unsigned integer */
	newmode.name         = new_id_from_chars("Iu", 2);
	newmode.code         = irm_Iu;
	newmode.sign         = 0;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
812

813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
	mode_Iu = register_mode(&newmode);

	/* signed long integer */
	newmode.name         = new_id_from_chars("Ls", 2);
	newmode.code         = irm_Ls;
	newmode.sign         = 1;
	newmode.size         = 64;
	newmode.modulo_shift = 64;

	mode_Ls = register_mode(&newmode);

	/* unsigned long integer */
	newmode.name         = new_id_from_chars("Lu", 2);
	newmode.code         = irm_Lu;
	newmode.sign         = 0;
	newmode.size         = 64;
	newmode.modulo_shift = 64;

	mode_Lu = register_mode(&newmode);

833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
	/* signed long long integer */
	newmode.name         = new_id_from_chars("LLs", 3);
	newmode.code         = irm_LLs;
	newmode.sign         = 1;
	newmode.size         = 128;
	newmode.modulo_shift = 128;

	mode_LLs = register_mode(&newmode);

	/* unsigned long long integer */
	newmode.name         = new_id_from_chars("LLu", 3);
	newmode.code         = irm_LLu;
	newmode.sign         = 0;
	newmode.size         = 128;
	newmode.modulo_shift = 128;

	mode_LLu = register_mode(&newmode);

851
852
	/* Reference Mode */
	newmode.sort       = irms_reference;
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
	newmode.arithmetic = irma_twos_complement;

	/* pointer */
	newmode.name         = new_id_from_chars("P", 1);
	newmode.code         = irm_P;
	newmode.sign         = 0;
	newmode.size         = 32;
	newmode.modulo_shift = 0;
	newmode.eq_signed    = mode_Is;
	newmode.eq_unsigned  = mode_Iu;

	mode_P = register_mode(&newmode);

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

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

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

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

Michael Beck's avatar
Michael Beck committed
884
885
/* find an unsigned mode for a signed integer mode */
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
894
/* 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) {
895
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
896

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

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

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

916
917
918
919
920
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
921
922
923
924
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;
925
926
}

Michael Beck's avatar
Michael Beck committed
927
/*
928
 * Returns non-zero if the mode has a reversed wrap-around
Michael Beck's avatar
Michael Beck committed
929
930
931
932
933
934
 * 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) {
935
936
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
937
938
}

939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
/*
 * 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;
}

958
void finish_mode(void) {
959
	obstack_free(&modes, 0);
Matthias Braun's avatar
Matthias Braun committed
960
	DEL_ARR_F(mode_list);
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983

	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;

984
	mode_P      = NULL;
985
986
	mode_P_code = NULL;
	mode_P_data = NULL;
987
}