irmode.c 21.9 KB
Newer Older
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1
2
3
4
5
6
7
8
9
10
11
/*
 * Project:     libFIRM
 * File name:   ir/ir/irmode.c
 * Purpose:     Data modes of operations.
 * Author:      Martin Trapp, Christian Schaefer
 * Modified by: Goetz Lindenmaier, Mathias Heil
 * Created:
 * CVS-ID:      $Id$
 * Copyright:   (c) 1998-2003 Universitt Karlsruhe
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */
Boris Boesler's avatar
added    
Boris Boesler committed
12
#ifdef HAVE_CONFIG_H
Michael Beck's avatar
Michael Beck committed
13
# include "config.h"
Boris Boesler's avatar
added    
Boris Boesler committed
14
15
#endif

Michael Beck's avatar
Michael Beck committed
16
#ifdef HAVE_STDLIB_H
17
# include <stdlib.h>
Michael Beck's avatar
Michael Beck committed
18
19
#endif
#ifdef HAVE_STRING_H
20
# include <string.h>
Michael Beck's avatar
Michael Beck committed
21
22
23
#endif

# include <stddef.h>
24

25
# include "irprog_t.h"
26
27
# include "irmode_t.h"
# include "ident.h"
Michael Beck's avatar
Michael Beck committed
28
# include "tv_t.h"
29
# include "obst.h"
30
# include "irhooks.h"
31
# include "irtools.h"
Christian Schäfer's avatar
Christian Schäfer committed
32

33
34
35
/* * *
 * local values
 * * */
36

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

Michael Beck's avatar
Michael Beck committed
38
/** dynamic array to hold all modes */
39
static struct obstack modes;
Christian Schäfer's avatar
Christian Schäfer committed
40

Michael Beck's avatar
Michael Beck committed
41
/** number of defined modes */
42
static int num_modes;
Christian Schäfer's avatar
Christian Schäfer committed
43

44
45
46
/* * *
 * local functions
 * * */
Christian Schäfer's avatar
Christian Schäfer committed
47

48
/**
49
 * Compare modes that don't need to have their code field
50
 * correctly set
51
52
53
 *
 * TODO: Add other fields
 **/
54
55
56
57
58
59
60
61
62
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
63

64
	return 0;
65
}
Matthias Heil's avatar
Matthias Heil committed
66

67
68
69
/*
 * calculates the next obstack address
 */
70
71
72
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);
73

74
	adr += s + mask;
75

76
	return INT_TO_PTR(adr & ~mask);
77
78
}

79
/**
80
 * searches the modes obstack for the given mode and returns
81
 * a pointer on an equal mode already in the array, NULL if
82
83
 * none found
 */
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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;
114
}
Christian Schäfer's avatar
Christian Schäfer committed
115

116
117
118
/**
 * sets special values of modes
 */
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
static void set_mode_values(ir_mode* mode) {
	switch (get_mode_sort(mode))    {
	case irms_character:
	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;
	}
157
}
158

159
160
161
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
162

163
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
164

165
166
167
168
169
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
170
171
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
172

173
174
175
176
/* 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
177

178
179
180
181
182
183
184
185
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;
186
187
ir_mode *mode_LLs;  /* 128 bit */
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
188

189
190
191
192
ir_mode *mode_C;
ir_mode *mode_U;
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
193
194

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

198
199
200
201
202
/* * *
 * functions defined in irmode.h
 * * */

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

259
260
261
	mode->kind = k_ir_mode;
	if (num_modes >= irm_max) mode->code = num_modes;
		num_modes++;
262

263
264
	/* add the new mode to the irp list of modes */
	add_irp_mode(mode);
265

266
	set_mode_values(mode);
267

268
269
	hook_new_mode(new_mode, mode);
	return mode;
270
271
272
273
274
}

/*
 * Creates a new mode.
 */
Michael Beck's avatar
Michael Beck committed
275
ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int sign,
276
                     mode_arithmetic arithmetic, unsigned int modulo_shift)
277
{
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
	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:
	case irms_character:
		mode = register_mode(&mode_tmpl);
	}
	return mode;
313
314
}

315
316
317
/*
 * Creates a new vector mode.
 */
Michael Beck's avatar
Michael Beck committed
318
ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsigned num_of_elem, int sign,
319
                            mode_arithmetic arithmetic, unsigned int modulo_shift)
320
{
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
	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:
	case irms_character:
		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;
367
368
}

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

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

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

385
mode_sort
386
387
(get_mode_sort)(const ir_mode* mode) {
	return _get_mode_sort(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
388
389
}

Michael Beck's avatar
Michael Beck committed
390
int
391
392
(get_mode_size_bits)(const ir_mode *mode) {
	return _get_mode_size_bits(mode);
Christian Schäfer's avatar
Christian Schäfer committed
393
394
}

Michael Beck's avatar
Michael Beck committed
395
396
int
(get_mode_size_bytes)(const ir_mode *mode) {
397
	return _get_mode_size_bytes(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
398
399
}

400
int
401
402
(get_mode_sign)(const ir_mode *mode) {
	return _get_mode_sign(mode);
403
404
}

Michael Beck's avatar
Michael Beck committed
405
int
406
407
(get_mode_arithmetic)(const ir_mode *mode) {
	return get_mode_arithmetic(mode);
408
409
}

410
411
412
413
414

/* 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
415
416
unsigned int
(get_mode_modulo_shift)(const ir_mode *mode) {
417
	return _get_mode_modulo_shift(mode);
418
419
}

Michael Beck's avatar
Michael Beck committed
420
unsigned int
421
(get_mode_n_vector_elems)(const ir_mode *mode) {
422
	return _get_mode_vector_elems(mode);
423
424
}

Michael Beck's avatar
Michael Beck committed
425
void *
426
427
(get_mode_link)(const ir_mode *mode) {
	return _get_mode_link(mode);
428
429
}

Michael Beck's avatar
Michael Beck committed
430
void
431
432
(set_mode_link)(ir_mode *mode, void *l) {
	_set_mode_link(mode, l);
433
434
}

Christian Schäfer's avatar
Christian Schäfer committed
435
tarval *
436
437
438
439
get_mode_min(ir_mode *mode) {
	assert(mode);
	assert(get_mode_modecode(mode) < num_modes);
	assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
440

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

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

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
471
tarval *
472
473
474
475
get_mode_minus_one(ir_mode *mode) {
	assert(mode);
	assert(get_mode_modecode(mode) < num_modes);
	assert(mode_is_data(mode));
Michael Beck's avatar
Michael Beck committed
476

477
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
478
479
}

480
tarval *
481
482
483
484
get_mode_infinite(ir_mode *mode) {
	assert(mode);
	assert(get_mode_modecode(mode) < num_modes);
	assert(mode_is_float(mode));
485

486
	return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
487
488
}

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

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

498
int
499
500
501
502
503
is_mode(void *thing) {
	if (get_kind(thing) == k_ir_mode)
		return 1;
	else
		return 0;
504
505
}

Christian Schäfer's avatar
Christian Schäfer committed
506
int
Michael Beck's avatar
Michael Beck committed
507
(mode_is_signed)(const ir_mode *mode) {
508
	return _mode_is_signed(mode);
Christian Schäfer's avatar
Christian Schäfer committed
509
510
}

511
int
Michael Beck's avatar
Michael Beck committed
512
(mode_is_float)(const ir_mode *mode) {
513
	return _mode_is_float(mode);
Christian Schäfer's avatar
Christian Schäfer committed
514
515
}

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

Michael Beck's avatar
Michael Beck committed
521
522
int
(mode_is_character)(const ir_mode *mode) {
523
	return _mode_is_character(mode);
524
525
}

Michael Beck's avatar
Michael Beck committed
526
527
int
(mode_is_reference)(const ir_mode *mode) {
528
	return _mode_is_reference(mode);
529
530
}

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

Michael Beck's avatar
fixed:    
Michael Beck committed
536
int
Michael Beck's avatar
Michael Beck committed
537
(mode_is_numP)(const ir_mode *mode) {
538
	return _mode_is_numP(mode);
Michael Beck's avatar
fixed:    
Michael Beck committed
539
540
}

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

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

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

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

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

566
/* Returns true if sm can be converted to lm without loss. */
567
int
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
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
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;

	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;
656
657
}

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

663
	obstack_init(&modes);
664

665
666
	num_modes  =  0;
	/* initialize predefined modes */
667

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

679
680
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
681

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

686
	mode_BB = register_mode(&newmode);
687

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

692
	mode_X = register_mode(&newmode);
693

694
695
	/* Memory Modes */
	newmode.sort    = irms_memory;
696

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

701
	mode_M = register_mode(&newmode);
702

703
704
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
705

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

710
	mode_T = register_mode(&newmode);
711

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

716
	mode_ANY = register_mode(&newmode);
717

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

722
	mode_BAD = register_mode(&newmode);
723

724
725
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
726

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

731
	mode_b = register_mode(&newmode);
732

733
734
	/* Data Modes */
	newmode.vector_elem = 1;
735

736
737
738
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
739

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

746
	mode_F = register_mode(&newmode);
747

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

754
	mode_D = register_mode(&newmode);
755

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

762
	mode_E = register_mode(&newmode);
763

764
765
766
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
767

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

775
	mode_Bs = register_mode(&newmode);
776

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

785
	mode_Bu = register_mode(&newmode);
786

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

794
	mode_Hs = register_mode(&newmode);
795

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

803
	mode_Hu = register_mode(&newmode);
804

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

812
	mode_Is = register_mode(&newmode);
813

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

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

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

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
	/* Character Modes */
	newmode.sort         = irms_character;
	newmode.arithmetic   = irma_twos_complement;
	newmode.modulo_shift = 0;

	/* Character */
	newmode.name         = new_id_from_chars("C", 1);
	newmode.code         = irm_C;
	newmode.sign         = 0;
	newmode.size         = 8;

	mode_C = register_mode(&newmode);

	/* Unicode character */
	newmode.name         = new_id_from_chars("U", 1);
	newmode.code         = irm_U;
	newmode.sign         = 0;
	newmode.size         = 16;

	mode_U = register_mode(&newmode);

	/* Reference Modes */
	newmode.sort    = irms_reference;
	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;
898
}
899

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

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

Michael Beck's avatar
Michael Beck committed
909
910
/* find an unsigned mode for a signed integer mode */
ir_mode *find_signed_mode(const ir_mode *mode) {
911
	ir_mode n = *mode;
912

913
914
915
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
916
917
}

Michael Beck's avatar
Michael Beck committed
918
919
/* 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) {
920
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
921

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

924
925
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
926
}
927

928
929
930
931
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
932
933
934
935
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
936
937
938
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
939
940
}

941
942
943
944
945
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
946
947
948
949
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;
950
951
}

Michael Beck's avatar
Michael Beck committed
952
/*
953
 * Returns non-zero if the mode has a reversed wrap-around
Michael Beck's avatar
Michael Beck committed
954
955
956
957
958
959
 * 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) {
960
961
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
962
963
}

964
void finish_mode(void) {
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
	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_C   = NULL;
	mode_U   = NULL;
	mode_b   = NULL;
	mode_P   = NULL;

	mode_P_code = NULL;
	mode_P_data = NULL;
994
}