irmode.c 23.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
/** Number of defined modes. */
47
static int num_modes = 0;
Christian Schäfer's avatar
Christian Schäfer committed
48

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

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
}

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

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

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

Michael Beck's avatar
Michael Beck committed
114
115
116
117
/* 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];
118
	return NULL;
119
}
Michael Beck's avatar
Michael Beck committed
120
#endif
Christian Schäfer's avatar
Christian Schäfer committed
121

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

163
164
165
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
166

167
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
168

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

177
178
179
180
/* 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
181

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

193
194
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
195
196

/* machine specific modes */
197
198
ir_mode *mode_P_code;   /**< machine specific pointer mode for code addresses */
ir_mode *mode_P_data;   /**< machine specific pointer mode for data addresses */
199

200
201
202
203
204
/* * *
 * functions defined in irmode.h
 * * */

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

227

228
ir_mode *(get_modeP_code)(void) {
229
	return _get_modeP_code();
Michael Beck's avatar
Michael Beck committed
230
231
}

232
ir_mode *(get_modeP_data)(void) {
233
	return _get_modeP_data();
234
235
236
}

void set_modeP_code(ir_mode *p) {
237
238
	assert(mode_is_reference(p));
	mode_P_code = p;
239
240
241
}

void set_modeP_data(ir_mode *p) {
242
243
	assert(mode_is_reference(p));
	mode_P_data = p;
Michael Beck's avatar
Michael Beck committed
244
}
245

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

254
	assert(new_mode);
255

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

260
	mode->kind = k_ir_mode;
261
262
263
264
	if (num_modes >= irm_max)  {
		mode->code = num_modes;
	}
	num_modes++;
265

266
267
	/* add the new mode to the irp list of modes */
	add_irp_mode(mode);
268

269
	set_mode_values(mode);
270

271
272
	hook_new_mode(new_mode, mode);
	return mode;
273
274
275
276
277
}

/*
 * Creates a new mode.
 */
278
279
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)
280
{
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
	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:
306
		panic("internal modes cannot be user defined");
307
308
309
310
311

	case irms_float_number:
	case irms_int_number:
	case irms_reference:
		mode = register_mode(&mode_tmpl);
312
		break;
313
	}
314
	assert(mode != NULL);
315
	return mode;
316
317
}

318
319
320
/*
 * Creates a new vector mode.
 */
321
322
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)
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
	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:
354
		panic("internal modes cannot be user defined");
355
356

	case irms_reference:
357
		panic("only integer and floating point modes can be vectorized");
358
359

	case irms_float_number:
360
		panic("not yet implemented");
361
362
363
364

	case irms_int_number:
		mode = register_mode(&mode_tmpl);
	}
365
	assert(mode != NULL);
366
	return mode;
367
368
}

369
/* Functions for the direct access to all attributes of an ir_mode */
370
ir_modecode (get_mode_modecode)(const ir_mode *mode) {
371
	return _get_mode_modecode(mode);
Christian Schäfer's avatar
Christian Schäfer committed
372
373
}

374
ident *(get_mode_ident)(const ir_mode *mode) {
375
	return _get_mode_ident(mode);
Christian Schäfer's avatar
Christian Schäfer committed
376
377
}

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

382
ir_mode_sort (get_mode_sort)(const ir_mode* mode) {
383
	return _get_mode_sort(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
384
385
}

386
unsigned (get_mode_size_bits)(const ir_mode *mode) {
387
	return _get_mode_size_bits(mode);
Christian Schäfer's avatar
Christian Schäfer committed
388
389
}

390
unsigned (get_mode_size_bytes)(const ir_mode *mode) {
391
	return _get_mode_size_bytes(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
392
393
}

394
int (get_mode_sign)(const ir_mode *mode) {
395
	return _get_mode_sign(mode);
396
397
}

398
ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode) {
399
	return get_mode_arithmetic(mode);
400
401
}

402
403
404
405
406

/* 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.
 */
407
unsigned int (get_mode_modulo_shift)(const ir_mode *mode) {
408
	return _get_mode_modulo_shift(mode);
409
410
}

411
unsigned int (get_mode_n_vector_elems)(const ir_mode *mode) {
412
	return _get_mode_vector_elems(mode);
413
414
}

415
void *(get_mode_link)(const ir_mode *mode) {
416
	return _get_mode_link(mode);
417
418
}

419
void (set_mode_link)(ir_mode *mode, void *l) {
420
	_set_mode_link(mode, l);
421
422
}

423
tarval *get_mode_min(ir_mode *mode) {
424
	assert(mode);
425
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
426
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
427

428
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
429
430
}

431
tarval *get_mode_max(ir_mode *mode) {
432
	assert(mode);
433
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
434
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
435

436
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
437
438
}

439
tarval *get_mode_null(ir_mode *mode) {
440
	assert(mode);
441
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
442
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
443

444
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
445
446
}

447
tarval *get_mode_one(ir_mode *mode) {
448
	assert(mode);
449
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
Matthias Braun's avatar
Matthias Braun committed
450
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
451

452
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
453
454
}

455
tarval *get_mode_minus_one(ir_mode *mode) {
456
	assert(mode);
457
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
458
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
459

460
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
461
462
}

463
tarval *get_mode_all_one(ir_mode *mode) {
464
	assert(mode);
465
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
Matthias Braun's avatar
Matthias Braun committed
466
	assert(mode_is_datab(mode));
467
468
469
	return mode->all_one;
}

470
tarval *get_mode_infinite(ir_mode *mode) {
471
	assert(mode);
472
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
473
	assert(mode_is_float(mode));
474

475
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
476
477
}

478
tarval *get_mode_NAN(ir_mode *mode) {
479
	assert(mode);
480
	assert(get_mode_modecode(mode) < (ir_modecode) num_modes);
481
	assert(mode_is_float(mode));
482

483
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
484
485
}

Michael Beck's avatar
Michael Beck committed
486
int is_mode(const void *thing) {
487
488
489
490
	if (get_kind(thing) == k_ir_mode)
		return 1;
	else
		return 0;
491
492
}

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

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

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

505
int (mode_is_reference)(const ir_mode *mode) {
506
	return _mode_is_reference(mode);
507
508
}

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

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

517
int (mode_is_datab)(const ir_mode *mode) {
518
	return _mode_is_datab(mode);
Christian Schäfer's avatar
Christian Schäfer committed
519
520
}

521
int (mode_is_dataM)(const ir_mode *mode) {
522
	return _mode_is_dataM(mode);
Christian Schäfer's avatar
Christian Schäfer committed
523
}
524

525
int (mode_is_float_vector)(const ir_mode *mode) {
526
	return _mode_is_float_vector(mode);
527
528
}

529
int (mode_is_int_vector)(const ir_mode *mode) {
530
	return _mode_is_int_vector(mode);
Michael Beck's avatar
Michael Beck committed
531
532
}

533
/* Returns true if sm can be converted to lm without loss. */
534
int smaller_mode(const ir_mode *sm, const ir_mode *lm) {
535
	int sm_bits, lm_bits;
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
599
600
601
602
603
604
605
606
607
608

	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
609
	ir_mode_arithmetic arith;
610
611
612
613
614
615

	assert(sm);
	assert(lm);

	if (sm == lm) return 1;

Moritz Kroll's avatar
Moritz Kroll committed
616
617
618
	if (sm == mode_b)
		return mode_is_int(lm);

619
620
621
	sm_bits = get_mode_size_bits(sm);
	lm_bits = get_mode_size_bits(lm);

Moritz Kroll's avatar
Moritz Kroll committed
622
623
	arith = get_mode_arithmetic(sm);
	if (arith != get_mode_arithmetic(lm))
624
625
		return 0;

Moritz Kroll's avatar
Moritz Kroll committed
626
627
628
629
	switch (arith) {
		case irma_twos_complement:
		case irma_ieee754:
			return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
630

Moritz Kroll's avatar
Moritz Kroll committed
631
632
		default:
			return 0;
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
	}
}

/* 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;
660
661
}

662
/* initialization, build the default modes */
663
void init_mode(void) {
664
	ir_mode newmode;
665

666
	obstack_init(&modes);
Matthias Braun's avatar
Matthias Braun committed
667
	mode_list = NEW_ARR_F(ir_mode*, 0);
668

669
670
	num_modes  =  0;
	/* initialize predefined modes */
671

672
673
674
675
676
677
678
679
680
681
	/* 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;
682

683
684
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
685

686
687
688
	/* Basic Block */
	newmode.name    = new_id_from_chars("BB", 2);
	newmode.code    = irm_BB;
689

690
	mode_BB = register_mode(&newmode);
691

692
693
694
	/* eXecution */
	newmode.name    = new_id_from_chars("X", 1);
	newmode.code    = irm_X;
695

696
	mode_X = register_mode(&newmode);
697

698
699
	/* Memory Modes */
	newmode.sort    = irms_memory;
700

701
702
703
	/* Memory */
	newmode.name    = new_id_from_chars("M", 1);
	newmode.code    = irm_M;
704

705
	mode_M = register_mode(&newmode);
706

707
708
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
709

710
711
712
	/* Tuple */
	newmode.name    = new_id_from_chars("T", 1);
	newmode.code    = irm_T;
713

714
	mode_T = register_mode(&newmode);
715

716
717
718
	/* ANY */
	newmode.name    = new_id_from_chars("ANY", 3);
	newmode.code    = irm_ANY;
719

720
	mode_ANY = register_mode(&newmode);
721

722
723
724
	/* BAD */
	newmode.name    = new_id_from_chars("BAD", 3);
	newmode.code    = irm_BAD;
725

726
	mode_BAD = register_mode(&newmode);
727

728
729
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
730

731
732
733
	/* boolean */
	newmode.name    = new_id_from_chars("b", 1);
	newmode.code    = irm_b;
734

735
	mode_b = register_mode(&newmode);
736

737
738
	/* Data Modes */
	newmode.vector_elem = 1;
739

740
741
742
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
743

744
745
746
747
748
	/* float */
	newmode.name    = new_id_from_chars("F", 1);
	newmode.code    = irm_F;
	newmode.sign    = 1;
	newmode.size    = 32;
749

750
	mode_F = register_mode(&newmode);
751

752
753
754
755
756
	/* double */
	newmode.name    = new_id_from_chars("D", 1);
	newmode.code    = irm_D;
	newmode.sign    = 1;
	newmode.size    = 64;
757

758
	mode_D = register_mode(&newmode);
759

760
761
762
763
	/* extended */
	newmode.name    = new_id_from_chars("E", 1);
	newmode.code    = irm_E;
	newmode.sign    = 1;
Matthias Braun's avatar
Matthias Braun committed
764
765
766
	/* 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;
767

768
	mode_E = register_mode(&newmode);
769

770
771
772
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
773

774
775
776
777
778
779
	/* signed byte */
	newmode.name         = new_id_from_chars("Bs", 2);
	newmode.code         = irm_Bs;
	newmode.sign         = 1;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
780

781
	mode_Bs = register_mode(&newmode);
782

783
784
785
786
787
788
789
	/* 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;
790

791
	mode_Bu = register_mode(&newmode);
792

793
794
795
796
797
798
	/* 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;
799

800
	mode_Hs = register_mode(&newmode);
801

802
803
804
805
806
807
	/* 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;
808

809
	mode_Hu = register_mode(&newmode);
810

811
812
813
814
815
816
	/* signed integer */
	newmode.name         = new_id_from_chars("Is", 2);
	newmode.code         = irm_Is;
	newmode.sign         = 1;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
817

818
	mode_Is = register_mode(&newmode);
819

820
821
822
823
824
825
	/* unsigned integer */
	newmode.name         = new_id_from_chars("Iu", 2);
	newmode.code         = irm_Iu;
	newmode.sign         = 0;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
826

827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
	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);

847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
	/* 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);

865
866
	/* Reference Mode */
	newmode.sort       = irms_reference;
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
	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;
883
}
884

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

889
890
891
892
893
	/* allowed for reference mode */
	if (mode->sort == irms_reference)
		n.sort = irms_int_number;

	assert(n.sort == irms_int_number);
894
895
	n.sign = 0;
	return find_mode(&n);
896
897
}

Michael Beck's avatar
Michael Beck committed
898
899
/* find an unsigned mode for a signed integer mode */
ir_mode *find_signed_mode(const ir_mode *mode) {
900
	ir_mode n = *mode;
901

902
903
904
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
905
906
}

Michael Beck's avatar
Michael Beck committed
907
908
/* 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) {
909
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
910

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

913
914
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
915
}
916

917
918
919
920
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
921
922
923
924
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
925
926
927
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
928
929
}

930
931
932
933
934
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
935
936
937
938
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;
939
940
}

Michael Beck's avatar
Michael Beck committed
941
/*
942
 * Returns non-zero if the mode has a reversed wrap-around
Michael Beck's avatar
Michael Beck committed
943
944
945
946
947
948
 * 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) {
949
950
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
951
952
}

953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
/*
 * 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;
}

972
void finish_mode(void) {
973
	obstack_free(&modes, 0);
Matthias Braun's avatar
Matthias Braun committed
974
	DEL_ARR_F(mode_list);
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997

	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;

998
	mode_P      = NULL;
999
1000
	mode_P_code = NULL;
	mode_P_data = NULL;