irmode.c 22.5 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.
 */

Götz Lindenmaier's avatar
Götz Lindenmaier committed
20
21
22
23
24
25
26
27
28
29
/*
 * 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
 */
Boris Boesler's avatar
added    
Boris Boesler committed
30
#ifdef HAVE_CONFIG_H
Michael Beck's avatar
Michael Beck committed
31
# include "config.h"
Boris Boesler's avatar
added    
Boris Boesler committed
32
33
#endif

Michael Beck's avatar
Michael Beck committed
34
#ifdef HAVE_STDLIB_H
35
# include <stdlib.h>
Michael Beck's avatar
Michael Beck committed
36
37
#endif
#ifdef HAVE_STRING_H
38
# include <string.h>
Michael Beck's avatar
Michael Beck committed
39
40
41
#endif

# include <stddef.h>
42

43
# include "irprog_t.h"
44
45
# include "irmode_t.h"
# include "ident.h"
Michael Beck's avatar
Michael Beck committed
46
# include "tv_t.h"
47
# include "obst.h"
48
# include "irhooks.h"
49
# include "irtools.h"
Christian Schäfer's avatar
Christian Schäfer committed
50

51
52
53
/* * *
 * local values
 * * */
54

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

Michael Beck's avatar
Michael Beck committed
56
/** dynamic array to hold all modes */
57
static struct obstack modes;
Christian Schäfer's avatar
Christian Schäfer committed
58

Michael Beck's avatar
Michael Beck committed
59
/** number of defined modes */
60
static int num_modes;
Christian Schäfer's avatar
Christian Schäfer committed
61

62
63
64
/* * *
 * local functions
 * * */
Christian Schäfer's avatar
Christian Schäfer committed
65

66
/**
67
 * Compare modes that don't need to have their code field
68
 * correctly set
69
70
71
 *
 * TODO: Add other fields
 **/
72
73
74
75
76
77
78
79
80
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
81

82
	return 0;
83
}
Matthias Heil's avatar
Matthias Heil committed
84

85
86
87
/*
 * calculates the next obstack address
 */
88
89
90
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);
91

92
	adr += s + mask;
93

94
	return INT_TO_PTR(adr & ~mask);
95
96
}

97
/**
98
 * searches the modes obstack for the given mode and returns
99
 * a pointer on an equal mode already in the array, NULL if
100
101
 * none found
 */
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
128
129
130
131
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;
132
}
Christian Schäfer's avatar
Christian Schäfer committed
133

134
135
136
/**
 * sets special values of modes
 */
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
170
171
172
173
174
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;
	}
175
}
176

177
178
179
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
180

181
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
182

183
184
185
186
187
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
188
189
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
190

191
192
193
194
/* 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
195

196
197
198
199
200
201
202
203
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;
204
205
ir_mode *mode_LLs;  /* 128 bit */
ir_mode *mode_LLu;
Christian Schäfer's avatar
Christian Schäfer committed
206

207
208
209
210
ir_mode *mode_C;
ir_mode *mode_U;
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
211
212

/* machine specific modes */
213
214
ir_mode *mode_P_code;   /**< machine specific pointer mode for code addresses */
ir_mode *mode_P_data;   /**< machine specific pointer mode for data addresses */
215

216
217
218
219
220
/* * *
 * functions defined in irmode.h
 * * */

/* JNI access functions */
221
222
223
224
225
226
227
228
229
230
231
232
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; }
233
234
ir_mode *get_modeLLs(void){ return mode_LLs; }
ir_mode *get_modeLLu(void){ return mode_LLu; }
235
236
237
238
239
240
241
242
243
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; }
244

245

246
ir_mode *(get_modeP_code)(void) {
247
	return _get_modeP_code();
Michael Beck's avatar
Michael Beck committed
248
249
}

250
ir_mode *(get_modeP_data)(void) {
251
	return _get_modeP_data();
252
253
254
}

void set_modeP_code(ir_mode *p) {
255
256
	assert(mode_is_reference(p));
	mode_P_code = p;
257
258
259
}

void set_modeP_data(ir_mode *p) {
260
261
	assert(mode_is_reference(p));
	mode_P_data = p;
Michael Beck's avatar
Michael Beck committed
262
}
263

264
/**
265
266
267
 * Registers a new mode.
 *
 * @param new_mode  The new mode template.
268
 */
269
270
static ir_mode *register_mode(const ir_mode *new_mode) {
	ir_mode *mode = NULL;
271

272
	assert(new_mode);
273

274
275
	/* copy mode struct to modes array */
	mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode));
276

277
278
279
	mode->kind = k_ir_mode;
	if (num_modes >= irm_max) mode->code = num_modes;
		num_modes++;
280

281
282
	/* add the new mode to the irp list of modes */
	add_irp_mode(mode);
283

284
	set_mode_values(mode);
285

286
287
	hook_new_mode(new_mode, mode);
	return mode;
288
289
290
291
292
}

/*
 * Creates a new mode.
 */
Michael Beck's avatar
Michael Beck committed
293
ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int sign,
294
                     mode_arithmetic arithmetic, unsigned int modulo_shift)
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
323
324
325
326
327
328
329
330
	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;
331
332
}

333
334
335
/*
 * Creates a new vector mode.
 */
Michael Beck's avatar
Michael Beck committed
336
ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsigned num_of_elem, int sign,
337
                            mode_arithmetic arithmetic, unsigned int modulo_shift)
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
376
377
378
379
380
381
382
383
384
	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;
385
386
}

387
/* Functions for the direct access to all attributes of an ir_mode */
Christian Schäfer's avatar
Christian Schäfer committed
388
modecode
389
390
(get_mode_modecode)(const ir_mode *mode) {
	return _get_mode_modecode(mode);
Christian Schäfer's avatar
Christian Schäfer committed
391
392
393
}

ident *
394
395
(get_mode_ident)(const ir_mode *mode) {
	return _get_mode_ident(mode);
Christian Schäfer's avatar
Christian Schäfer committed
396
397
}

398
const char *
399
400
get_mode_name(const ir_mode *mode) {
	return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
401
402
}

403
mode_sort
404
405
(get_mode_sort)(const ir_mode* mode) {
	return _get_mode_sort(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
406
407
}

Michael Beck's avatar
Michael Beck committed
408
int
409
410
(get_mode_size_bits)(const ir_mode *mode) {
	return _get_mode_size_bits(mode);
Christian Schäfer's avatar
Christian Schäfer committed
411
412
}

Michael Beck's avatar
Michael Beck committed
413
414
int
(get_mode_size_bytes)(const ir_mode *mode) {
415
	return _get_mode_size_bytes(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
416
417
}

418
int
419
420
(get_mode_sign)(const ir_mode *mode) {
	return _get_mode_sign(mode);
421
422
}

Michael Beck's avatar
Michael Beck committed
423
int
424
425
(get_mode_arithmetic)(const ir_mode *mode) {
	return get_mode_arithmetic(mode);
426
427
}

428
429
430
431
432

/* 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
433
434
unsigned int
(get_mode_modulo_shift)(const ir_mode *mode) {
435
	return _get_mode_modulo_shift(mode);
436
437
}

Michael Beck's avatar
Michael Beck committed
438
unsigned int
439
(get_mode_n_vector_elems)(const ir_mode *mode) {
440
	return _get_mode_vector_elems(mode);
441
442
}

Michael Beck's avatar
Michael Beck committed
443
void *
444
445
(get_mode_link)(const ir_mode *mode) {
	return _get_mode_link(mode);
446
447
}

Michael Beck's avatar
Michael Beck committed
448
void
449
450
(set_mode_link)(ir_mode *mode, void *l) {
	_set_mode_link(mode, l);
451
452
}

Christian Schäfer's avatar
Christian Schäfer committed
453
tarval *
454
455
456
457
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
458

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

tarval *
463
464
465
466
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
467

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

tarval *
472
473
474
475
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
476

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

480
tarval *
481
482
483
484
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
485

486
	return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
487
488
}

Michael Beck's avatar
Michael Beck committed
489
tarval *
490
491
492
493
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
494

495
	return mode->minus_one;
Michael Beck's avatar
Michael Beck committed
496
497
}

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

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

507
tarval *
508
509
510
511
get_mode_NAN(ir_mode *mode) {
	assert(mode);
	assert(get_mode_modecode(mode) < num_modes);
	assert(mode_is_float(mode));
512

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
539
540
int
(mode_is_character)(const ir_mode *mode) {
541
	return _mode_is_character(mode);
542
543
}

Michael Beck's avatar
Michael Beck committed
544
545
int
(mode_is_reference)(const ir_mode *mode) {
546
	return _mode_is_reference(mode);
547
548
}

549
int
Michael Beck's avatar
Michael Beck committed
550
(mode_is_num)(const ir_mode *mode) {
551
	return _mode_is_num(mode);
Christian Schäfer's avatar
Christian Schäfer committed
552
553
}

Michael Beck's avatar
fixed:    
Michael Beck committed
554
int
Michael Beck's avatar
Michael Beck committed
555
(mode_is_numP)(const ir_mode *mode) {
556
	return _mode_is_numP(mode);
Michael Beck's avatar
fixed:    
Michael Beck committed
557
558
}

559
int
Michael Beck's avatar
Michael Beck committed
560
(mode_is_data)(const ir_mode *mode) {
561
	return _mode_is_data(mode);
Christian Schäfer's avatar
Christian Schäfer committed
562
563
564
}

int
Michael Beck's avatar
Michael Beck committed
565
(mode_is_datab)(const ir_mode *mode) {
566
	return _mode_is_datab(mode);
Christian Schäfer's avatar
Christian Schäfer committed
567
568
569
}

int
Michael Beck's avatar
Michael Beck committed
570
(mode_is_dataM)(const ir_mode *mode) {
571
	return _mode_is_dataM(mode);
Christian Schäfer's avatar
Christian Schäfer committed
572
}
573
574

int
Michael Beck's avatar
Michael Beck committed
575
(mode_is_float_vector)(const ir_mode *mode) {
576
	return _mode_is_float_vector(mode);
577
578
579
}

int
Michael Beck's avatar
Michael Beck committed
580
(mode_is_int_vector)(const ir_mode *mode) {
581
	return _mode_is_int_vector(mode);
Michael Beck's avatar
Michael Beck committed
582
583
}

584
/* Returns true if sm can be converted to lm without loss. */
585
int
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
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
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;
674
675
}

676
/* initialization, build the default modes */
677
void
678
679
init_mode (void) {
	ir_mode newmode;
680

681
	obstack_init(&modes);
682

683
684
	num_modes  =  0;
	/* initialize predefined modes */
685

686
687
688
689
690
691
692
693
694
695
	/* 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;
696

697
698
	/* Control Flow Modes*/
	newmode.sort    = irms_control_flow;
699

700
701
702
	/* Basic Block */
	newmode.name    = new_id_from_chars("BB", 2);
	newmode.code    = irm_BB;
703

704
	mode_BB = register_mode(&newmode);
705

706
707
708
	/* eXecution */
	newmode.name    = new_id_from_chars("X", 1);
	newmode.code    = irm_X;
709

710
	mode_X = register_mode(&newmode);
711

712
713
	/* Memory Modes */
	newmode.sort    = irms_memory;
714

715
716
717
	/* Memory */
	newmode.name    = new_id_from_chars("M", 1);
	newmode.code    = irm_M;
718

719
	mode_M = register_mode(&newmode);
720

721
722
	/* Auxiliary Modes */
	newmode.sort    = irms_auxiliary,
723

724
725
726
	/* Tuple */
	newmode.name    = new_id_from_chars("T", 1);
	newmode.code    = irm_T;
727

728
	mode_T = register_mode(&newmode);
729

730
731
732
	/* ANY */
	newmode.name    = new_id_from_chars("ANY", 3);
	newmode.code    = irm_ANY;
733

734
	mode_ANY = register_mode(&newmode);
735

736
737
738
	/* BAD */
	newmode.name    = new_id_from_chars("BAD", 3);
	newmode.code    = irm_BAD;
739

740
	mode_BAD = register_mode(&newmode);
741

742
743
	/* Internal Boolean Modes */
	newmode.sort    = irms_internal_boolean;
744

745
746
747
	/* boolean */
	newmode.name    = new_id_from_chars("b", 1);
	newmode.code    = irm_b;
748

749
	mode_b = register_mode(&newmode);
750

751
752
	/* Data Modes */
	newmode.vector_elem = 1;
753

754
755
756
	/* Float Number Modes */
	newmode.sort       = irms_float_number;
	newmode.arithmetic = irma_ieee754;
757

758
759
760
761
762
	/* float */
	newmode.name    = new_id_from_chars("F", 1);
	newmode.code    = irm_F;
	newmode.sign    = 1;
	newmode.size    = 32;
763

764
	mode_F = register_mode(&newmode);
765

766
767
768
769
770
	/* double */
	newmode.name    = new_id_from_chars("D", 1);
	newmode.code    = irm_D;
	newmode.sign    = 1;
	newmode.size    = 64;
771

772
	mode_D = register_mode(&newmode);
773

774
775
776
777
778
	/* extended */
	newmode.name    = new_id_from_chars("E", 1);
	newmode.code    = irm_E;
	newmode.sign    = 1;
	newmode.size    = 80;
779

780
	mode_E = register_mode(&newmode);
781

782
783
784
	/* Integer Number Modes */
	newmode.sort         = irms_int_number;
	newmode.arithmetic   = irma_twos_complement;
785

786
787
788
789
790
791
	/* signed byte */
	newmode.name         = new_id_from_chars("Bs", 2);
	newmode.code         = irm_Bs;
	newmode.sign         = 1;
	newmode.size         = 8;
	newmode.modulo_shift = 32;
792

793
	mode_Bs = register_mode(&newmode);
794

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

803
	mode_Bu = register_mode(&newmode);
804

805
806
807
808
809
810
	/* 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;
811

812
	mode_Hs = register_mode(&newmode);
813

814
815
816
817
818
819
	/* 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;
820

821
	mode_Hu = register_mode(&newmode);
822

823
824
825
826
827
828
	/* signed integer */
	newmode.name         = new_id_from_chars("Is", 2);
	newmode.code         = irm_Is;
	newmode.sign         = 1;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
829

830
	mode_Is = register_mode(&newmode);
831

832
833
834
835
836
837
	/* unsigned integer */
	newmode.name         = new_id_from_chars("Iu", 2);
	newmode.code         = irm_Iu;
	newmode.sign         = 0;
	newmode.size         = 32;
	newmode.modulo_shift = 32;
838

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

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
	/* 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);

877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
	/* 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;
916
}
917

Michael Beck's avatar
Michael Beck committed
918
919
/* find a signed mode for an unsigned integer mode */
ir_mode *find_unsigned_mode(const ir_mode *mode) {
920
	ir_mode n = *mode;
921

922
923
924
	assert(mode->sort == irms_int_number);
	n.sign = 0;
	return find_mode(&n);
925
926
}

Michael Beck's avatar
Michael Beck committed
927
928
/* find an unsigned mode for a signed integer mode */
ir_mode *find_signed_mode(const ir_mode *mode) {
929
	ir_mode n = *mode;
930

931
932
933
	assert(mode->sort == irms_int_number);
	n.sign = 1;
	return find_mode(&n);
934
935
}

Michael Beck's avatar
Michael Beck committed
936
937
/* 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) {
938
	ir_mode n = *mode;
Michael Beck's avatar
Michael Beck committed
939

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

942
943
	n.size = 2*mode->size;
	return find_mode(&n);
Michael Beck's avatar
Michael Beck committed
944
}
945

946
947
948
949
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
950
951
952
953
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
954
955
956
	return
		mode->sort == irms_float_number &&
		mode->arithmetic != irma_ieee754;
957
958
}

959
960
961
962
963
/*
 * Returns non-zero if the given mode might overflow on unary Minus.
 *
 * This does NOT happen on IEEE 754.
 */
964
965
966
967
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;
968
969
}

Michael Beck's avatar
Michael Beck committed
970
/*
971
 * Returns non-zero if the mode has a reversed wrap-around
Michael Beck's avatar
Michael Beck committed
972
973
974
975
976
977
 * 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) {
978
979
	/* FIXME: better would be an extra mode property */
	return mode_is_int(mode);
Michael Beck's avatar
Michael Beck committed
980
981
}

982
void finish_mode(void) {
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
	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;
1012
}