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
 */
Boris Boesler's avatar
added    
Boris Boesler committed
26
#ifdef HAVE_CONFIG_H
Michael Beck's avatar
Michael Beck committed
27
# include "config.h"
Boris Boesler's avatar
added    
Boris Boesler committed
28
29
#endif

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

# include <stddef.h>
38

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

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

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

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

57
/**
58
 * Compare modes that don't need to have their code field
59
 * correctly set
60
61
62
 *
 * TODO: Add other fields
 **/
Michael Beck's avatar
Michael Beck committed
63
static INLINE int modes_are_equal(const ir_mode *m, const ir_mode *n) {
64
65
66
67
68
69
70
71
	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
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
static ir_mode *find_mode(const ir_mode *m) {
Michael Beck's avatar
Michael Beck committed
82
83
	int i;
	for (i = ARR_LEN(mode_list) - 1; i >= 0; --i) {
Matthias Braun's avatar
Matthias Braun committed
84
		ir_mode *n = mode_list[i];
85
86
87
		if (modes_are_equal(n, m))
			return n;
	}
Michael Beck's avatar
Michael Beck committed
88
89
90
91
92
93
94
95
96
97
98
99
100
101
	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;
}
102

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

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

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

156
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
157

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

166
167
168
169
/* 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
170

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

182
183
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
184
185

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

189
190
191
192
193
/* * *
 * functions defined in irmode.h
 * * */

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

216

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

221
ir_mode *(get_modeP_data)(void) {
222
	return _get_modeP_data();
223
224
225
}

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

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

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

243
	assert(new_mode);
244

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

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

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

258
	set_mode_values(mode);
259

260
261
	hook_new_mode(new_mode, mode);
	return mode;
262
263
264
265
266
}

/*
 * Creates a new mode.
 */
267
268
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)
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
302
303
	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;
304
305
}

306
307
308
/*
 * Creates a new vector mode.
 */
309
310
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)
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
355
356
	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;
357
358
}

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

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

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

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

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

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

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

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

392
393
394
395
396

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

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

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

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

413
tarval *get_mode_min(ir_mode *mode) {
414
	assert(mode);
415
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
416
	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
	assert(mode);
423
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
424
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
425

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

429
tarval *get_mode_null(ir_mode *mode) {
430
	assert(mode);
431
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
432
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
433

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

437
tarval *get_mode_one(ir_mode *mode) {
438
	assert(mode);
439
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
Matthias Braun's avatar
Matthias Braun committed
440
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
441

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

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

450
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
451
452
}

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

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

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

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

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

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

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

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

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

495
int (mode_is_reference)(const ir_mode *mode) {
496
	return _mode_is_reference(mode);
497
498
}

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

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

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

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

515
int (mode_is_float_vector)(const ir_mode *mode) {
516
	return _mode_is_float_vector(mode);
517
518
}

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

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

	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
599
	ir_mode_arithmetic arith;
600
601
602
603
604
605

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

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

609
610
611
	sm_bits = get_mode_size_bits(sm);
	lm_bits = get_mode_size_bits(lm);

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

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

Moritz Kroll's avatar
Moritz Kroll committed
621
622
		default:
			return 0;
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
648
649
	}
}

/* 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;
650
651
}

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

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

659
660
	num_modes  =  0;
	/* initialize predefined modes */
661

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

673
674
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
675

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

680
	mode_BB = register_mode(&newmode);
681

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

686
	mode_X = register_mode(&newmode);
687

688
689
	/* Memory Modes */
	newmode.sort    = irms_memory;
690

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

695
	mode_M = register_mode(&newmode);
696

697
698
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
699

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

704
	mode_T = register_mode(&newmode);
705

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

710
	mode_ANY = register_mode(&newmode);
711

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

716
	mode_BAD = register_mode(&newmode);
717

718
719
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
720

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

725
	mode_b = register_mode(&newmode);
726

727
728
	/* Data Modes */
	newmode.vector_elem = 1;
729

730
731
732
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
733

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

740
	mode_F = register_mode(&newmode);
741

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

748
	mode_D = register_mode(&newmode);
749

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

756
	mode_E = register_mode(&newmode);
757

758
759
760
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
761

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

769
	mode_Bs = register_mode(&newmode);
770

771
772
773
774
775
776
777
	/* 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;
778

779
	mode_Bu = register_mode(&newmode);
780

781
782
783
784
785
786
	/* 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;
787

788
	mode_Hs = register_mode(&newmode);
789

790
791
792
793
794
795
	/* 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;
796

797
	mode_Hu = register_mode(&newmode);
798

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

806
	mode_Is = register_mode(&newmode);
807

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

815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
	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);

835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
	/* 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);

853
854
	/* Reference Mode */
	newmode.sort       = irms_reference;
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
	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;
871
}
872

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
895
896
/* 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) {
897
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
898

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

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

905
906
907
908
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
909
910
911
912
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
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
925
926
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;
927
928
}

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

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

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

	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;

986
	mode_P      = NULL;
987
988
	mode_P_code = NULL;
	mode_P_data = NULL;
989
}