irmode.c 21.6 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
 *
 * 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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
static void set_mode_values(ir_mode* mode) {
	switch (get_mode_sort(mode))    {
	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);
		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;
		break;

	case irms_reference:
		mode->min  = tarval_bad;
		mode->max  = tarval_bad;
		mode->null = get_tarval_null(mode);
		mode->one  = tarval_bad;
		mode->minus_one = tarval_bad;
		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;
	}
170
}
171

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

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

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

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

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

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

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

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

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

236

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

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

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

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

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

263
	assert(new_mode);
264

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

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

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

277
	set_mode_values(mode);
278

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

/*
 * Creates a new mode.
 */
Michael Beck's avatar
Michael Beck committed
286
ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int sign,
287
                     mode_arithmetic arithmetic, unsigned int modulo_shift)
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
322
	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;
323
324
}

325
326
327
/*
 * Creates a new vector mode.
 */
Michael Beck's avatar
Michael Beck committed
328
ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsigned num_of_elem, int sign,
329
                            mode_arithmetic arithmetic, unsigned int modulo_shift)
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
375
	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;
376
377
}

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

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

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

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

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

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

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

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

419
420
421
422
423

/* 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
424
425
unsigned int
(get_mode_modulo_shift)(const ir_mode *mode) {
426
	return _get_mode_modulo_shift(mode);
427
428
}

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

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

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

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

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

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

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

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

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

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

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

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

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

489
tarval *
490
491
get_mode_infinite(ir_mode *mode) {
	assert(mode);
492
	assert(get_mode_modecode(mode) < (modecode) num_modes);
493
	assert(mode_is_float(mode));
494

495
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
496
497
}

498
tarval *
499
500
get_mode_NAN(ir_mode *mode) {
	assert(mode);
501
	assert(get_mode_modecode(mode) < (modecode) num_modes);
502
	assert(mode_is_float(mode));
503

504
	return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
505
506
}

507
int
508
509
510
511
512
is_mode(void *thing) {
	if (get_kind(thing) == k_ir_mode)
		return 1;
	else
		return 0;
513
514
}

Christian Schäfer's avatar
Christian Schäfer committed
515
int
Michael Beck's avatar
Michael Beck committed
516
(mode_is_signed)(const ir_mode *mode) {
517
	return _mode_is_signed(mode);
Christian Schäfer's avatar
Christian Schäfer committed
518
519
}

520
int
Michael Beck's avatar
Michael Beck committed
521
(mode_is_float)(const ir_mode *mode) {
522
	return _mode_is_float(mode);
Christian Schäfer's avatar
Christian Schäfer committed
523
524
}

525
int
Michael Beck's avatar
Michael Beck committed
526
(mode_is_int)(const ir_mode *mode) {
527
	return _mode_is_int(mode);
Christian Schäfer's avatar
Christian Schäfer committed
528
529
}

Michael Beck's avatar
Michael Beck committed
530
531
int
(mode_is_reference)(const ir_mode *mode) {
532
	return _mode_is_reference(mode);
533
534
}

535
int
Michael Beck's avatar
Michael Beck committed
536
(mode_is_num)(const ir_mode *mode) {
537
	return _mode_is_num(mode);
Christian Schäfer's avatar
Christian Schäfer committed
538
539
}

540
int
Michael Beck's avatar
Michael Beck committed
541
(mode_is_data)(const ir_mode *mode) {
542
	return _mode_is_data(mode);
Christian Schäfer's avatar
Christian Schäfer committed
543
544
545
}

int
Michael Beck's avatar
Michael Beck committed
546
(mode_is_datab)(const ir_mode *mode) {
547
	return _mode_is_datab(mode);
Christian Schäfer's avatar
Christian Schäfer committed
548
549
550
}

int
Michael Beck's avatar
Michael Beck committed
551
(mode_is_dataM)(const ir_mode *mode) {
552
	return _mode_is_dataM(mode);
Christian Schäfer's avatar
Christian Schäfer committed
553
}
554
555

int
Michael Beck's avatar
Michael Beck committed
556
(mode_is_float_vector)(const ir_mode *mode) {
557
	return _mode_is_float_vector(mode);
558
559
560
}

int
Michael Beck's avatar
Michael Beck committed
561
(mode_is_int_vector)(const ir_mode *mode) {
562
	return _mode_is_int_vector(mode);
Michael Beck's avatar
Michael Beck committed
563
564
}

565
/* Returns true if sm can be converted to lm without loss. */
566
int
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
609
610
611
612
613
614
615
616
617
618
619
620
621
622
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:
			/* 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 (   get_mode_arithmetic(sm) == get_mode_arithmetic(lm)
				&& get_mode_arithmetic(sm) == irma_twos_complement) {
				return lm_bits >= sm_bits;
			} else if (mode_is_signed(sm)) {
				if ( mode_is_signed(lm) && (lm_bits >= sm_bits) )
					return 1;
			} else if (mode_is_signed(lm)) {
				if (lm_bits > sm_bits + 1)
					return 1;
			} else if (lm_bits >= sm_bits) {
				return 1;
			}
			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;

623
624
625
	case irms_internal_boolean:
		return mode_is_int(lm);

626
627
628
629
630
631
632
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
	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;
658
659
}

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

665
	obstack_init(&modes);
666

667
668
	num_modes  =  0;
	/* initialize predefined modes */
669

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

681
682
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
683

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

688
	mode_BB = register_mode(&newmode);
689

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

694
	mode_X = register_mode(&newmode);
695

696
697
	/* Memory Modes */
	newmode.sort    = irms_memory;
698

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

703
	mode_M = register_mode(&newmode);
704

705
706
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
707

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

712
	mode_T = register_mode(&newmode);
713

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

718
	mode_ANY = register_mode(&newmode);
719

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

724
	mode_BAD = register_mode(&newmode);
725

726
727
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
728

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

733
	mode_b = register_mode(&newmode);
734

735
736
	/* Data Modes */
	newmode.vector_elem = 1;
737

738
739
740
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
741

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

748
	mode_F = register_mode(&newmode);
749

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

756
	mode_D = register_mode(&newmode);
757

758
759
760
761
762
	/* extended */
	newmode.name    = new_id_from_chars("E", 1);
	newmode.code    = irm_E;
	newmode.sign    = 1;
	newmode.size    = 80;
763

764
	mode_E = register_mode(&newmode);
765

766
767
768
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
769

770
771
772
773
774
775
	/* signed byte */
	newmode.name         = new_id_from_chars("Bs", 2);
	newmode.code         = irm_Bs;
	newmode.sign         = 1;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
776

777
	mode_Bs = register_mode(&newmode);
778

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

787
	mode_Bu = register_mode(&newmode);
788

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

796
	mode_Hs = register_mode(&newmode);
797

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

805
	mode_Hu = register_mode(&newmode);
806

807
808
809
810
811
812
	/* signed integer */
	newmode.name         = new_id_from_chars("Is", 2);
	newmode.code         = irm_Is;
	newmode.sign         = 1;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
813

814
	mode_Is = register_mode(&newmode);
815

816
817
818
819
820
821
	/* unsigned integer */
	newmode.name         = new_id_from_chars("Iu", 2);
	newmode.code         = irm_Iu;
	newmode.sign         = 0;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
822

823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
	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);

843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
	/* 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);

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

Michael Beck's avatar
Michael Beck committed
881
882
/* find a signed mode for an unsigned integer mode */
ir_mode *find_unsigned_mode(const ir_mode *mode) {
883
	ir_mode n = *mode;
884

885
886
887
	assert(mode->sort == irms_int_number);
	n.sign = 0;
	return find_mode(&n);
888
889
}

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

894
895
896
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
897
898
}

Michael Beck's avatar
Michael Beck committed
899
900
/* 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) {
901
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
902

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

905
906
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
907
}
908

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

922
923
924
925
926
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
927
928
929
930
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;
931
932
}

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

945
void finish_mode(void) {
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
	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;

970
	mode_P      = NULL;
971
972
	mode_P_code = NULL;
	mode_P_data = NULL;
973
}