2 * This file is part of libFirm.
3 * Copyright (C) 2012 University of Karlsruhe.
8 * @brief Data modes of operations.
9 * @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Mathias Heil
27 #include "pattern_dmp.h"
29 /** Obstack to hold all modes. */
30 static struct obstack modes;
32 /** The list of all currently existing modes. */
33 static ir_mode **mode_list;
35 static bool modes_are_equal(const ir_mode *m, const ir_mode *n)
37 return m->sort == n->sort &&
38 m->arithmetic == n->arithmetic &&
41 m->modulo_shift == n->modulo_shift;
45 * searches the modes obstack for the given mode and returns
46 * a pointer on an equal mode already in the array, NULL if
49 static ir_mode *find_mode(const ir_mode *m)
52 for (i = 0, n_modes = ARR_LEN(mode_list); i < n_modes; ++i) {
53 ir_mode *n = mode_list[i];
54 if (modes_are_equal(n, m))
61 * sets special values of modes
63 static void set_mode_values(ir_mode* mode)
65 switch (get_mode_sort(mode)) {
68 case irms_float_number:
69 mode->min = get_tarval_min(mode);
70 mode->max = get_tarval_max(mode);
71 mode->null = get_tarval_null(mode);
72 mode->one = get_tarval_one(mode);
73 mode->minus_one = get_tarval_minus_one(mode);
74 if (get_mode_sort(mode) != irms_float_number) {
75 mode->all_one = get_tarval_all_one(mode);
77 mode->all_one = tarval_bad;
81 case irms_internal_boolean:
82 mode->min = tarval_b_false;
83 mode->max = tarval_b_true;
84 mode->null = tarval_b_false;
85 mode->one = tarval_b_true;
86 mode->minus_one = tarval_bad;
87 mode->all_one = tarval_b_true;
90 case irms_control_flow:
96 mode->min = tarval_bad;
97 mode->max = tarval_bad;
98 mode->null = tarval_bad;
99 mode->one = tarval_bad;
100 mode->minus_one = tarval_bad;
130 ir_mode *mode_P_code;
131 ir_mode *mode_P_data;
133 ir_mode *get_modeT(void) { return mode_T; }
134 ir_mode *get_modeF(void) { return mode_F; }
135 ir_mode *get_modeD(void) { return mode_D; }
136 ir_mode *get_modeQ(void) { return mode_Q; }
137 ir_mode *get_modeBs(void) { return mode_Bs; }
138 ir_mode *get_modeBu(void) { return mode_Bu; }
139 ir_mode *get_modeHs(void) { return mode_Hs; }
140 ir_mode *get_modeHu(void) { return mode_Hu; }
141 ir_mode *get_modeIs(void) { return mode_Is; }
142 ir_mode *get_modeIu(void) { return mode_Iu; }
143 ir_mode *get_modeLs(void) { return mode_Ls; }
144 ir_mode *get_modeLu(void) { return mode_Lu; }
145 ir_mode *get_modeLLs(void){ return mode_LLs; }
146 ir_mode *get_modeLLu(void){ return mode_LLu; }
147 ir_mode *get_modeb(void) { return mode_b; }
148 ir_mode *get_modeP(void) { return mode_P; }
149 ir_mode *get_modeX(void) { return mode_X; }
150 ir_mode *get_modeM(void) { return mode_M; }
151 ir_mode *get_modeBB(void) { return mode_BB; }
152 ir_mode *get_modeANY(void) { return mode_ANY; }
153 ir_mode *get_modeBAD(void) { return mode_BAD; }
156 ir_mode *(get_modeP_code)(void)
158 return get_modeP_code_();
161 ir_mode *(get_modeP_data)(void)
163 return get_modeP_data_();
166 void set_modeP_code(ir_mode *p)
168 assert(mode_is_reference(p));
172 void set_modeP_data(ir_mode *p)
174 assert(mode_is_reference(p));
180 * Creates a new mode.
182 static ir_mode *alloc_mode(const char *name, ir_mode_sort sort,
183 ir_mode_arithmetic arithmetic, unsigned bit_size,
184 int sign, unsigned modulo_shift)
186 ir_mode *mode_tmpl = OALLOCZ(&modes, ir_mode);
188 mode_tmpl->name = new_id_from_str(name);
189 mode_tmpl->sort = sort;
190 mode_tmpl->size = bit_size;
191 mode_tmpl->sign = sign ? 1 : 0;
192 mode_tmpl->modulo_shift = modulo_shift;
193 mode_tmpl->arithmetic = arithmetic;
194 mode_tmpl->link = NULL;
195 mode_tmpl->tv_priv = NULL;
199 static ir_mode *register_mode(ir_mode *mode)
201 /* does any of the existing modes have the same properties? */
202 ir_mode *old = find_mode(mode);
204 /* remove new mode from obstack */
205 obstack_free(&modes, mode);
209 mode->kind = k_ir_mode;
210 mode->type = new_type_primitive(mode);
211 ARR_APP1(ir_mode*, mode_list, mode);
212 set_mode_values(mode);
217 ir_mode *new_int_mode(const char *name, ir_mode_arithmetic arithmetic,
218 unsigned bit_size, int sign, unsigned modulo_shift)
220 ir_mode *result = alloc_mode(name, irms_int_number, arithmetic, bit_size,
222 return register_mode(result);
225 ir_mode *new_reference_mode(const char *name, ir_mode_arithmetic arithmetic,
226 unsigned bit_size, unsigned modulo_shift)
228 ir_mode *result = alloc_mode(name, irms_reference, arithmetic, bit_size,
230 return register_mode(result);
233 ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic,
234 unsigned exponent_size, unsigned mantissa_size)
236 bool explicit_one = false;
237 unsigned bit_size = exponent_size + mantissa_size + 1;
240 if (arithmetic == irma_x86_extended_float) {
243 } else if (arithmetic != irma_ieee754) {
244 panic("Arithmetic %s invalid for float");
246 if (exponent_size >= 256)
247 panic("Exponents >= 256 bits not supported");
248 if (mantissa_size >= 256)
249 panic("Mantissa >= 256 bits not supported");
251 result = alloc_mode(name, irms_float_number, irma_x86_extended_float, bit_size, 1, 0);
252 result->float_desc.exponent_size = exponent_size;
253 result->float_desc.mantissa_size = mantissa_size;
254 result->float_desc.explicit_one = explicit_one;
255 return register_mode(result);
258 ident *(get_mode_ident)(const ir_mode *mode)
260 return get_mode_ident_(mode);
263 const char *get_mode_name(const ir_mode *mode)
265 return get_id_str(mode->name);
268 unsigned (get_mode_size_bits)(const ir_mode *mode)
270 return get_mode_size_bits_(mode);
273 unsigned (get_mode_size_bytes)(const ir_mode *mode)
275 return get_mode_size_bytes_(mode);
278 int (get_mode_sign)(const ir_mode *mode)
280 return get_mode_sign_(mode);
283 ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode)
285 return get_mode_arithmetic_(mode);
289 unsigned int (get_mode_modulo_shift)(const ir_mode *mode)
291 return get_mode_modulo_shift_(mode);
294 void *(get_mode_link)(const ir_mode *mode)
296 return get_mode_link_(mode);
299 void (set_mode_link)(ir_mode *mode, void *l)
301 set_mode_link_(mode, l);
304 ir_tarval *get_mode_min(ir_mode *mode)
307 assert(mode_is_data(mode));
312 ir_tarval *get_mode_max(ir_mode *mode)
315 assert(mode_is_data(mode));
320 ir_tarval *get_mode_null(ir_mode *mode)
323 assert(mode_is_datab(mode));
328 ir_tarval *get_mode_one(ir_mode *mode)
331 assert(mode_is_datab(mode));
336 ir_tarval *get_mode_minus_one(ir_mode *mode)
339 assert(mode_is_data(mode));
341 return mode->minus_one;
344 ir_tarval *get_mode_all_one(ir_mode *mode)
347 assert(mode_is_datab(mode));
348 return mode->all_one;
351 ir_tarval *get_mode_infinite(ir_mode *mode)
354 assert(mode_is_float(mode));
356 return get_tarval_plus_inf(mode);
359 ir_tarval *get_mode_NAN(ir_mode *mode)
362 assert(mode_is_float(mode));
364 return get_tarval_nan(mode);
367 int is_mode(const void *thing)
369 return get_kind(thing) == k_ir_mode;
372 int (mode_is_signed)(const ir_mode *mode)
374 return mode_is_signed_(mode);
377 int (mode_is_float)(const ir_mode *mode)
379 return mode_is_float_(mode);
382 int (mode_is_int)(const ir_mode *mode)
384 return mode_is_int_(mode);
387 int (mode_is_reference)(const ir_mode *mode)
389 return mode_is_reference_(mode);
392 int (mode_is_num)(const ir_mode *mode)
394 return mode_is_num_(mode);
397 int (mode_is_data)(const ir_mode *mode)
399 return mode_is_data_(mode);
402 int (mode_is_datab)(const ir_mode *mode)
404 return mode_is_datab_(mode);
407 int (mode_is_dataM)(const ir_mode *mode)
409 return mode_is_dataM_(mode);
412 unsigned (get_mode_mantissa_size)(const ir_mode *mode)
414 return get_mode_mantissa_size_(mode);
417 unsigned (get_mode_exponent_size)(const ir_mode *mode)
419 return get_mode_exponent_size_(mode);
422 int smaller_mode(const ir_mode *sm, const ir_mode *lm)
424 int sm_bits, lm_bits;
429 if (sm == lm) return 1;
431 sm_bits = get_mode_size_bits(sm);
432 lm_bits = get_mode_size_bits(lm);
434 switch (get_mode_sort(sm)) {
435 case irms_int_number:
436 switch (get_mode_sort(lm)) {
437 case irms_int_number:
438 if (get_mode_arithmetic(sm) != get_mode_arithmetic(lm))
441 /* only two complement implemented */
442 assert(get_mode_arithmetic(sm) == irma_twos_complement);
444 /* integers are convertable if
445 * - both have the same sign and lm is the larger one
446 * - lm is the signed one and is at least two bits larger
447 * (one for the sign, one for the highest bit of sm)
448 * - sm & lm are two_complement and lm has greater or equal number of bits
450 if (mode_is_signed(sm)) {
451 if (!mode_is_signed(lm))
453 return sm_bits <= lm_bits;
455 if (mode_is_signed(lm)) {
456 return sm_bits < lm_bits;
458 return sm_bits <= lm_bits;
461 case irms_float_number:
462 /* int to float works if the float is large enough */
470 case irms_float_number:
471 if (get_mode_arithmetic(sm) == get_mode_arithmetic(lm)) {
472 if ( (get_mode_sort(lm) == irms_float_number)
473 && (get_mode_size_bits(lm) >= get_mode_size_bits(sm)) )
479 /* do exist machines out there with different pointer lengths ?*/
482 case irms_internal_boolean:
483 return mode_is_int(lm);
493 int values_in_mode(const ir_mode *sm, const ir_mode *lm)
499 return mode_is_int(lm) || mode_is_float(lm);
501 ir_mode_arithmetic larith = get_mode_arithmetic(lm);
502 ir_mode_arithmetic sarith = get_mode_arithmetic(sm);
504 case irma_x86_extended_float:
506 if (sarith == irma_ieee754 || sarith == irma_x86_extended_float) {
507 return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
508 } else if (sarith == irma_twos_complement) {
509 unsigned int_mantissa = get_mode_size_bits(sm) - (mode_is_signed(sm) ? 1 : 0);
510 unsigned float_mantissa = get_mode_mantissa_size(lm) + 1;
511 return int_mantissa <= float_mantissa;
514 case irma_twos_complement:
515 if (sarith == irma_twos_complement) {
516 return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
525 ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
527 assert(mode_is_reference(mode));
528 return mode->eq_signed;
531 void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
533 assert(mode_is_reference(ref_mode));
534 assert(mode_is_int(int_mode));
535 ref_mode->eq_signed = int_mode;
538 ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
540 assert(mode_is_reference(mode));
541 return mode->eq_unsigned;
544 void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
546 assert(mode_is_reference(ref_mode));
547 assert(mode_is_int(int_mode));
548 ref_mode->eq_unsigned = int_mode;
551 static ir_mode *new_internal_mode(const char *name, ir_mode_sort sort)
553 ir_mode *mode = alloc_mode(name, sort, irma_none, 0, 0, 0);
554 return register_mode(mode);
559 obstack_init(&modes);
560 mode_list = NEW_ARR_F(ir_mode*, 0);
562 /* initialize predefined modes */
563 mode_BB = new_internal_mode("BB", irms_block);
564 mode_X = new_internal_mode("X", irms_control_flow);
565 mode_M = new_internal_mode("M", irms_memory);
566 mode_T = new_internal_mode("T", irms_tuple);
567 mode_ANY = new_internal_mode("ANY", irms_any);
568 mode_BAD = new_internal_mode("BAD", irms_bad);
569 mode_b = new_internal_mode("b", irms_internal_boolean);
571 mode_F = new_float_mode("F", irma_ieee754, 8, 23);
572 mode_D = new_float_mode("D", irma_ieee754, 11, 52);
573 mode_Q = new_float_mode("Q", irma_ieee754, 15, 112);
575 mode_Bs = new_int_mode("Bs", irma_twos_complement, 8, 1, 32);
576 mode_Bu = new_int_mode("Bu", irma_twos_complement, 8, 0, 32);
577 mode_Hs = new_int_mode("Hs", irma_twos_complement, 16, 1, 32);
578 mode_Hu = new_int_mode("Hu", irma_twos_complement, 16, 0, 32);
579 mode_Is = new_int_mode("Is", irma_twos_complement, 32, 1, 32);
580 mode_Iu = new_int_mode("Iu", irma_twos_complement, 32, 0, 32);
581 mode_Ls = new_int_mode("Ls", irma_twos_complement, 64, 1, 64);
582 mode_Lu = new_int_mode("Lu", irma_twos_complement, 64, 0, 64);
583 mode_LLs = new_int_mode("LLs", irma_twos_complement, 128, 1, 128);
584 mode_LLu = new_int_mode("LLu", irma_twos_complement, 128, 0, 128);
586 mode_P = new_reference_mode("P", irma_twos_complement, 32, 32);
587 set_reference_mode_signed_eq(mode_P, mode_Is);
588 set_reference_mode_unsigned_eq(mode_P, mode_Iu);
590 /* set the machine specific modes to the predefined ones */
591 mode_P_code = mode_P;
592 mode_P_data = mode_P;
595 ir_mode *find_unsigned_mode(const ir_mode *mode)
599 /* allowed for reference mode */
600 if (mode->sort == irms_reference)
601 n.sort = irms_int_number;
603 assert(n.sort == irms_int_number);
605 return find_mode(&n);
608 ir_mode *find_signed_mode(const ir_mode *mode)
612 assert(mode->sort == irms_int_number);
614 return find_mode(&n);
617 ir_mode *find_double_bits_int_mode(const ir_mode *mode)
621 assert(mode->sort == irms_int_number && mode->arithmetic == irma_twos_complement);
623 n.size = 2*mode->size;
624 return find_mode(&n);
627 int mode_honor_signed_zeros(const ir_mode *mode)
629 /* for floating point, we know that IEEE 754 has +0 and -0,
630 * but always handles it identical.
633 mode->sort == irms_float_number &&
634 mode->arithmetic != irma_ieee754;
637 int mode_overflow_on_unary_Minus(const ir_mode *mode)
639 if (mode->sort == irms_float_number)
640 return mode->arithmetic == irma_ieee754 ? 0 : 1;
644 int mode_wrap_around(const ir_mode *mode)
646 /* FIXME: better would be an extra mode property */
647 return mode_is_int(mode);
650 int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
652 ir_mode_arithmetic ma;
656 if (get_mode_size_bits(src) != get_mode_size_bits(dst))
658 ma = get_mode_arithmetic(src);
659 if (ma != get_mode_arithmetic(dst))
662 return ma == irma_twos_complement;
665 ir_type *(get_type_for_mode) (const ir_mode *mode)
667 return get_type_for_mode_(mode);
670 size_t ir_get_n_modes(void)
672 return ARR_LEN(mode_list);
675 ir_mode *ir_get_mode(size_t num)
677 assert(num < ARR_LEN(mode_list));
678 return mode_list[num];
681 void finish_mode(void)
683 obstack_free(&modes, 0);
684 DEL_ARR_F(mode_list);