irmode.c 21.8 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"
Christian Schäfer's avatar
Christian Schäfer committed
46

47
48
49
/* * *
 * local values
 * * */
50

Christian Schäfer's avatar
Christian Schäfer committed
51

Michael Beck's avatar
Michael Beck committed
52
/** dynamic array to hold all modes */
53
static struct obstack modes;
Christian Schäfer's avatar
Christian Schäfer committed
54

Michael Beck's avatar
Michael Beck committed
55
/** number of defined modes */
56
static int num_modes = 0;
Christian Schäfer's avatar
Christian Schäfer committed
57

58
59
60
/* * *
 * local functions
 * * */
Christian Schäfer's avatar
Christian Schäfer committed
61

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

78
	return 0;
79
}
Matthias Heil's avatar
Matthias Heil committed
80

81
82
83
/*
 * calculates the next obstack address
 */
84
85
86
static void *next_obstack_adr(struct obstack *o, void *p, size_t s) {
	PTR_INT_TYPE adr = PTR_TO_INT((char *)p);
	int mask = obstack_alignment_mask(o);
87

88
	adr += s + mask;
89

90
	return INT_TO_PTR(adr & ~mask);
91
92
}

93
/**
94
 * searches the modes obstack for the given mode and returns
95
 * a pointer on an equal mode already in the array, NULL if
96
97
 * none found
 */
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
static ir_mode *find_mode(const ir_mode *m) {
	ir_mode *n, *nn;
	struct _obstack_chunk	*p;

	p  = modes.chunk;
	n  = (ir_mode *)p->contents;
	nn = next_obstack_adr(&modes, n, sizeof(*n));
	for (; (char *)nn <= modes.next_free;) {
		assert(is_mode(n));
		if (modes_are_equal(n, m))
			return n;

		n  = nn;
		nn = next_obstack_adr(&modes, n, sizeof(*n));
	}

	for (p = p->prev; p; p = p->prev) {
		n  = (ir_mode *)p->contents;
		nn = next_obstack_adr(&modes, n, sizeof(*n));
		for (; (char *)nn < p->limit;) {
			assert(is_mode(n));
			if (modes_are_equal(n, m))
				return n;

			n  = nn;
			nn = next_obstack_adr(&modes, n, sizeof(*n));
		}
	}

	return NULL;
128
}
Christian Schäfer's avatar
Christian Schäfer committed
129

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

171
172
173
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
174

175
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
176

177
178
179
180
181
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
182
183
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
184

185
186
187
188
/* 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
189

190
191
192
193
194
195
196
197
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;
198
199
ir_mode *mode_LLs;  /* 128 bit */
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
200

201
202
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
203
204

/* machine specific modes */
205
206
ir_mode *mode_P_code;   /**< machine specific pointer mode for code addresses */
ir_mode *mode_P_data;   /**< machine specific pointer mode for data addresses */
207

208
209
210
211
212
/* * *
 * functions defined in irmode.h
 * * */

/* JNI access functions */
213
214
215
216
217
218
219
220
221
222
223
224
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; }
225
226
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
227
228
229
230
231
232
233
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; }
234

235

236
ir_mode *(get_modeP_code)(void) {
237
	return _get_modeP_code();
Michael Beck's avatar
Michael Beck committed
238
239
}

240
ir_mode *(get_modeP_data)(void) {
241
	return _get_modeP_data();
242
243
244
}

void set_modeP_code(ir_mode *p) {
245
246
	assert(mode_is_reference(p));
	mode_P_code = p;
247
248
249
}

void set_modeP_data(ir_mode *p) {
250
251
	assert(mode_is_reference(p));
	mode_P_data = p;
Michael Beck's avatar
Michael Beck committed
252
}
253

254
/**
255
256
257
 * Registers a new mode.
 *
 * @param new_mode  The new mode template.
258
 */
259
260
static ir_mode *register_mode(const ir_mode *new_mode) {
	ir_mode *mode = NULL;
261

262
	assert(new_mode);
263

264
265
	/* copy mode struct to modes array */
	mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode));
266

267
	mode->kind = k_ir_mode;
268
269
270
271
	if (num_modes >= irm_max)  {
		mode->code = num_modes;
	}
	num_modes++;
272

273
274
	/* add the new mode to the irp list of modes */
	add_irp_mode(mode);
275

276
	set_mode_values(mode);
277

278
279
	hook_new_mode(new_mode, mode);
	return mode;
280
281
282
283
284
}

/*
 * Creates a new mode.
 */
Michael Beck's avatar
Michael Beck committed
285
ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int sign,
286
                     mode_arithmetic arithmetic, unsigned int modulo_shift)
287
{
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
	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;
322
323
}

324
325
326
/*
 * Creates a new vector mode.
 */
Michael Beck's avatar
Michael Beck committed
327
ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsigned num_of_elem, int sign,
328
                            mode_arithmetic arithmetic, unsigned int modulo_shift)
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
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
	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;
375
376
}

377
/* Functions for the direct access to all attributes of an ir_mode */
Christian Schäfer's avatar
Christian Schäfer committed
378
modecode
379
380
(get_mode_modecode)(const ir_mode *mode) {
	return _get_mode_modecode(mode);
Christian Schäfer's avatar
Christian Schäfer committed
381
382
383
}

ident *
384
385
(get_mode_ident)(const ir_mode *mode) {
	return _get_mode_ident(mode);
Christian Schäfer's avatar
Christian Schäfer committed
386
387
}

388
const char *
389
390
get_mode_name(const ir_mode *mode) {
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
391
392
}

393
mode_sort
394
395
(get_mode_sort)(const ir_mode* mode) {
	return _get_mode_sort(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
396
397
}

Michael Beck's avatar
Michael Beck committed
398
int
399
400
(get_mode_size_bits)(const ir_mode *mode) {
	return _get_mode_size_bits(mode);
Christian Schäfer's avatar
Christian Schäfer committed
401
402
}

Michael Beck's avatar
Michael Beck committed
403
404
int
(get_mode_size_bytes)(const ir_mode *mode) {
405
	return _get_mode_size_bytes(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
406
407
}

408
int
409
410
(get_mode_sign)(const ir_mode *mode) {
	return _get_mode_sign(mode);
411
412
}

413
mode_arithmetic
414
415
(get_mode_arithmetic)(const ir_mode *mode) {
	return get_mode_arithmetic(mode);
416
417
}

418
419
420
421
422

/* 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.
 */
Michael Beck's avatar
Michael Beck committed
423
424
unsigned int
(get_mode_modulo_shift)(const ir_mode *mode) {
425
	return _get_mode_modulo_shift(mode);
426
427
}

Michael Beck's avatar
Michael Beck committed
428
unsigned int
429
(get_mode_n_vector_elems)(const ir_mode *mode) {
430
	return _get_mode_vector_elems(mode);
431
432
}

Michael Beck's avatar
Michael Beck committed
433
void *
434
435
(get_mode_link)(const ir_mode *mode) {
	return _get_mode_link(mode);
436
437
}

Michael Beck's avatar
Michael Beck committed
438
void
439
440
(set_mode_link)(ir_mode *mode, void *l) {
	_set_mode_link(mode, l);
441
442
}

Christian Schäfer's avatar
Christian Schäfer committed
443
tarval *
444
445
get_mode_min(ir_mode *mode) {
	assert(mode);
446
	assert(get_mode_modecode(mode) < (modecode) num_modes);
447
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
448

449
	return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
450
451
452
}

tarval *
453
454
get_mode_max(ir_mode *mode) {
	assert(mode);
455
	assert(get_mode_modecode(mode) < (modecode) num_modes);
456
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
457

458
	return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
459
460
461
}

tarval *
462
463
get_mode_null(ir_mode *mode) {
	assert(mode);
464
	assert(get_mode_modecode(mode) < (modecode) num_modes);
465
	assert(mode_is_datab(mode));
Christian Schäfer's avatar
Christian Schäfer committed
466

467
	return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
468
469
}

470
tarval *
471
472
get_mode_one(ir_mode *mode) {
	assert(mode);
473
	assert(get_mode_modecode(mode) < (modecode) num_modes);
474
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
475

476
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
477
478
}

Michael Beck's avatar
Michael Beck committed
479
tarval *
480
481
get_mode_minus_one(ir_mode *mode) {
	assert(mode);
482
	assert(get_mode_modecode(mode) < (modecode) num_modes);
483
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
484

485
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
486
487
}

488
489
490
491
tarval *
get_mode_all_one(ir_mode *mode) {
	assert(mode);
	assert(get_mode_modecode(mode) < (modecode) num_modes);
492
	assert(mode_is_data(mode) || mode == mode_b);
493
494
495
	return mode->all_one;
}

496
tarval *
497
498
get_mode_infinite(ir_mode *mode) {
	assert(mode);
499
	assert(get_mode_modecode(mode) < (modecode) num_modes);
500
	assert(mode_is_float(mode));
501

502
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
503
504
}

505
tarval *
506
507
get_mode_NAN(ir_mode *mode) {
	assert(mode);
508
	assert(get_mode_modecode(mode) < (modecode) num_modes);
509
	assert(mode_is_float(mode));
510

511
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
512
513
}

514
int
515
516
517
518
519
is_mode(void *thing) {
	if (get_kind(thing) == k_ir_mode)
		return 1;
	else
		return 0;
520
521
}

Christian Schäfer's avatar
Christian Schäfer committed
522
int
Michael Beck's avatar
Michael Beck committed
523
(mode_is_signed)(const ir_mode *mode) {
524
	return _mode_is_signed(mode);
Christian Schäfer's avatar
Christian Schäfer committed
525
526
}

527
int
Michael Beck's avatar
Michael Beck committed
528
(mode_is_float)(const ir_mode *mode) {
529
	return _mode_is_float(mode);
Christian Schäfer's avatar
Christian Schäfer committed
530
531
}

532
int
Michael Beck's avatar
Michael Beck committed
533
(mode_is_int)(const ir_mode *mode) {
534
	return _mode_is_int(mode);
Christian Schäfer's avatar
Christian Schäfer committed
535
536
}

Michael Beck's avatar
Michael Beck committed
537
538
int
(mode_is_reference)(const ir_mode *mode) {
539
	return _mode_is_reference(mode);
540
541
}

542
int
Michael Beck's avatar
Michael Beck committed
543
(mode_is_num)(const ir_mode *mode) {
544
	return _mode_is_num(mode);
Christian Schäfer's avatar
Christian Schäfer committed
545
546
}

547
int
Michael Beck's avatar
Michael Beck committed
548
(mode_is_data)(const ir_mode *mode) {
549
	return _mode_is_data(mode);
Christian Schäfer's avatar
Christian Schäfer committed
550
551
552
}

int
Michael Beck's avatar
Michael Beck committed
553
(mode_is_datab)(const ir_mode *mode) {
554
	return _mode_is_datab(mode);
Christian Schäfer's avatar
Christian Schäfer committed
555
556
557
}

int
Michael Beck's avatar
Michael Beck committed
558
(mode_is_dataM)(const ir_mode *mode) {
559
	return _mode_is_dataM(mode);
Christian Schäfer's avatar
Christian Schäfer committed
560
}
561
562

int
Michael Beck's avatar
Michael Beck committed
563
(mode_is_float_vector)(const ir_mode *mode) {
564
	return _mode_is_float_vector(mode);
565
566
567
}

int
Michael Beck's avatar
Michael Beck committed
568
(mode_is_int_vector)(const ir_mode *mode) {
569
	return _mode_is_int_vector(mode);
Michael Beck's avatar
Michael Beck committed
570
571
}

572
/* Returns true if sm can be converted to lm without loss. */
573
int
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
smaller_mode(const ir_mode *sm, const ir_mode *lm) {
	int sm_bits, lm_bits;

	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:
Matthias Braun's avatar
Matthias Braun committed
589
590
591
592
593
594
			if(get_mode_arithmetic(sm) != get_mode_arithmetic(lm))
				return 0;

			/* only two complement implemented */
			assert(get_mode_arithmetic(sm)==irma_twos_complement);

595
596
597
598
599
600
			/* 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
			 */
Matthias Braun's avatar
Matthias Braun committed
601
602
603
604
605
606
607
608
609
			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;
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
			}
			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;

634
635
636
	case irms_internal_boolean:
		return mode_is_int(lm);

637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
	default:
		break;
	}

	/* else */
	return 0;
}

/* 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;
669
670
}

671
/* initialization, build the default modes */
672
void
673
init_mode(void) {
674
	ir_mode newmode;
675

676
	obstack_init(&modes);
677

678
679
	num_modes  =  0;
	/* initialize predefined modes */
680

681
682
683
684
685
686
687
688
689
690
	/* 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;
691

692
693
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
694

695
696
697
	/* Basic Block */
	newmode.name    = new_id_from_chars("BB", 2);
	newmode.code    = irm_BB;
698

699
	mode_BB = register_mode(&newmode);
700

701
702
703
	/* eXecution */
	newmode.name    = new_id_from_chars("X", 1);
	newmode.code    = irm_X;
704

705
	mode_X = register_mode(&newmode);
706

707
708
	/* Memory Modes */
	newmode.sort    = irms_memory;
709

710
711
712
	/* Memory */
	newmode.name    = new_id_from_chars("M", 1);
	newmode.code    = irm_M;
713

714
	mode_M = register_mode(&newmode);
715

716
717
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
718

719
720
721
	/* Tuple */
	newmode.name    = new_id_from_chars("T", 1);
	newmode.code    = irm_T;
722

723
	mode_T = register_mode(&newmode);
724

725
726
727
	/* ANY */
	newmode.name    = new_id_from_chars("ANY", 3);
	newmode.code    = irm_ANY;
728

729
	mode_ANY = register_mode(&newmode);
730

731
732
733
	/* BAD */
	newmode.name    = new_id_from_chars("BAD", 3);
	newmode.code    = irm_BAD;
734

735
	mode_BAD = register_mode(&newmode);
736

737
738
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
739

740
741
742
	/* boolean */
	newmode.name    = new_id_from_chars("b", 1);
	newmode.code    = irm_b;
743

744
	mode_b = register_mode(&newmode);
745

746
747
	/* Data Modes */
	newmode.vector_elem = 1;
748

749
750
751
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
752

753
754
755
756
757
	/* float */
	newmode.name    = new_id_from_chars("F", 1);
	newmode.code    = irm_F;
	newmode.sign    = 1;
	newmode.size    = 32;
758

759
	mode_F = register_mode(&newmode);
760

761
762
763
764
765
	/* double */
	newmode.name    = new_id_from_chars("D", 1);
	newmode.code    = irm_D;
	newmode.sign    = 1;
	newmode.size    = 64;
766

767
	mode_D = register_mode(&newmode);
768

769
770
771
772
773
	/* extended */
	newmode.name    = new_id_from_chars("E", 1);
	newmode.code    = irm_E;
	newmode.sign    = 1;
	newmode.size    = 80;
774

775
	mode_E = register_mode(&newmode);
776

777
778
779
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
780

781
782
783
784
785
786
	/* signed byte */
	newmode.name         = new_id_from_chars("Bs", 2);
	newmode.code         = irm_Bs;
	newmode.sign         = 1;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
787

788
	mode_Bs = register_mode(&newmode);
789

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

798
	mode_Bu = register_mode(&newmode);
799

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

807
	mode_Hs = register_mode(&newmode);
808

809
810
811
812
813
814
	/* 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;
815

816
	mode_Hu = register_mode(&newmode);
817

818
819
820
821
822
823
	/* signed integer */
	newmode.name         = new_id_from_chars("Is", 2);
	newmode.code         = irm_Is;
	newmode.sign         = 1;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
824

825
	mode_Is = register_mode(&newmode);
826

827
828
829
830
831
832
	/* unsigned integer */
	newmode.name         = new_id_from_chars("Iu", 2);
	newmode.code         = irm_Iu;
	newmode.sign         = 0;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
833

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

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
	/* 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);

872
873
	/* Reference Mode */
	newmode.sort       = irms_reference;
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
	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;
890
}
891

Michael Beck's avatar
Michael Beck committed
892
893
/* find a signed mode for an unsigned integer mode */
ir_mode *find_unsigned_mode(const ir_mode *mode) {
894
	ir_mode n = *mode;
895

896
897
898
	assert(mode->sort == irms_int_number);
	n.sign = 0;
	return find_mode(&n);
899
900
}

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

905
906
907
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
908
909
}

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

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

916
917
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
918
}
919

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

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

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

956
void finish_mode(void) {
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
	obstack_free(&modes, 0);

	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;

981
	mode_P      = NULL;
982
983
	mode_P_code = NULL;
	mode_P_data = NULL;
984
}