2 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * File name: ir/ir/irmode.c
23 * Purpose: Data modes of operations.
24 * Author: Martin Trapp, Christian Schaefer
25 * Modified by: Goetz Lindenmaier, Mathias Heil
28 * Copyright: (c) 1998-2003 Universität Karlsruhe
43 # include "irprog_t.h"
44 # include "irmode_t.h"
56 /** dynamic array to hold all modes */
57 static struct obstack modes;
59 /** number of defined modes */
67 * Compare modes that don't need to have their code field
70 * TODO: Add other fields
72 INLINE static int modes_are_equal(const ir_mode *m, const ir_mode *n) {
74 if (m->sort == n->sort &&
75 m->arithmetic == n->arithmetic &&
78 m->modulo_shift == n->modulo_shift &&
79 m->vector_elem == n->vector_elem)
86 * calculates the next obstack address
88 static void *next_obstack_adr(struct obstack *o, void *p, size_t s) {
89 PTR_INT_TYPE adr = PTR_TO_INT((char *)p);
90 int mask = obstack_alignment_mask(o);
94 return INT_TO_PTR(adr & ~mask);
98 * searches the modes obstack for the given mode and returns
99 * a pointer on an equal mode already in the array, NULL if
102 static ir_mode *find_mode(const ir_mode *m) {
104 struct _obstack_chunk *p;
107 n = (ir_mode *)p->contents;
108 nn = next_obstack_adr(&modes, n, sizeof(*n));
109 for (; (char *)nn <= modes.next_free;) {
111 if (modes_are_equal(n, m))
115 nn = next_obstack_adr(&modes, n, sizeof(*n));
118 for (p = p->prev; p; p = p->prev) {
119 n = (ir_mode *)p->contents;
120 nn = next_obstack_adr(&modes, n, sizeof(*n));
121 for (; (char *)nn < p->limit;) {
123 if (modes_are_equal(n, m))
127 nn = next_obstack_adr(&modes, n, sizeof(*n));
135 * sets special values of modes
137 static void set_mode_values(ir_mode* mode) {
138 switch (get_mode_sort(mode)) {
140 case irms_int_number:
141 case irms_float_number:
142 mode->min = get_tarval_min(mode);
143 mode->max = get_tarval_max(mode);
144 mode->null = get_tarval_null(mode);
145 mode->one = get_tarval_one(mode);
146 mode->minus_one = get_tarval_minus_one(mode);
149 case irms_internal_boolean:
150 mode->min = tarval_b_false;
151 mode->max = tarval_b_true;
152 mode->null = tarval_b_false;
153 mode->one = tarval_b_true;
154 mode->minus_one = tarval_bad;
158 mode->min = tarval_bad;
159 mode->max = tarval_bad;
160 mode->null = get_tarval_null(mode);
161 mode->one = tarval_bad;
162 mode->minus_one = tarval_bad;
167 case irms_control_flow:
168 mode->min = tarval_bad;
169 mode->max = tarval_bad;
170 mode->null = tarval_bad;
171 mode->one = tarval_bad;
172 mode->minus_one = tarval_bad;
178 * globals defined in irmode.h
181 /* --- Predefined modes --- */
183 /* FIRM internal modes: */
191 /* predefined numerical modes: */
192 ir_mode *mode_F; /* float */
193 ir_mode *mode_D; /* double */
194 ir_mode *mode_E; /* long double */
196 ir_mode *mode_Bs; /* integral values, signed and unsigned */
197 ir_mode *mode_Bu; /* 8 bit */
198 ir_mode *mode_Hs; /* 16 bit */
200 ir_mode *mode_Is; /* 32 bit */
202 ir_mode *mode_Ls; /* 64 bit */
204 ir_mode *mode_LLs; /* 128 bit */
212 /* machine specific modes */
213 ir_mode *mode_P_code; /**< machine specific pointer mode for code addresses */
214 ir_mode *mode_P_data; /**< machine specific pointer mode for data addresses */
217 * functions defined in irmode.h
220 /* JNI access functions */
221 ir_mode *get_modeT(void) { return mode_T; }
222 ir_mode *get_modeF(void) { return mode_F; }
223 ir_mode *get_modeD(void) { return mode_D; }
224 ir_mode *get_modeE(void) { return mode_E; }
225 ir_mode *get_modeBs(void) { return mode_Bs; }
226 ir_mode *get_modeBu(void) { return mode_Bu; }
227 ir_mode *get_modeHs(void) { return mode_Hs; }
228 ir_mode *get_modeHu(void) { return mode_Hu; }
229 ir_mode *get_modeIs(void) { return mode_Is; }
230 ir_mode *get_modeIu(void) { return mode_Iu; }
231 ir_mode *get_modeLs(void) { return mode_Ls; }
232 ir_mode *get_modeLu(void) { return mode_Lu; }
233 ir_mode *get_modeLLs(void){ return mode_LLs; }
234 ir_mode *get_modeLLu(void){ return mode_LLu; }
235 ir_mode *get_modeC(void) { return mode_C; }
236 ir_mode *get_modeU(void) { return mode_U; }
237 ir_mode *get_modeb(void) { return mode_b; }
238 ir_mode *get_modeP(void) { return mode_P; }
239 ir_mode *get_modeX(void) { return mode_X; }
240 ir_mode *get_modeM(void) { return mode_M; }
241 ir_mode *get_modeBB(void) { return mode_BB; }
242 ir_mode *get_modeANY(void) { return mode_ANY; }
243 ir_mode *get_modeBAD(void) { return mode_BAD; }
246 ir_mode *(get_modeP_code)(void) {
247 return _get_modeP_code();
250 ir_mode *(get_modeP_data)(void) {
251 return _get_modeP_data();
254 void set_modeP_code(ir_mode *p) {
255 assert(mode_is_reference(p));
259 void set_modeP_data(ir_mode *p) {
260 assert(mode_is_reference(p));
265 * Registers a new mode.
267 * @param new_mode The new mode template.
269 static ir_mode *register_mode(const ir_mode *new_mode) {
270 ir_mode *mode = NULL;
274 /* copy mode struct to modes array */
275 mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode));
277 mode->kind = k_ir_mode;
278 if (num_modes >= irm_max) mode->code = num_modes;
281 /* add the new mode to the irp list of modes */
284 set_mode_values(mode);
286 hook_new_mode(new_mode, mode);
291 * Creates a new mode.
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)
297 ir_mode *mode = NULL;
299 mode_tmpl.name = new_id_from_str(name);
300 mode_tmpl.sort = sort;
301 mode_tmpl.size = bit_size;
302 mode_tmpl.sign = sign ? 1 : 0;
303 mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0;
304 mode_tmpl.vector_elem = 1;
305 mode_tmpl.arithmetic = arithmetic;
306 mode_tmpl.link = NULL;
307 mode_tmpl.tv_priv = NULL;
309 mode = find_mode(&mode_tmpl);
311 hook_new_mode(&mode_tmpl, mode);
318 case irms_control_flow:
320 case irms_internal_boolean:
321 assert(0 && "internal modes cannot be user defined");
324 case irms_float_number:
325 case irms_int_number:
328 mode = register_mode(&mode_tmpl);
334 * Creates a new vector mode.
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)
340 ir_mode *mode = NULL;
342 mode_tmpl.name = new_id_from_str(name);
343 mode_tmpl.sort = sort;
344 mode_tmpl.size = bit_size * num_of_elem;
345 mode_tmpl.sign = sign ? 1 : 0;
346 mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0;
347 mode_tmpl.vector_elem = num_of_elem;
348 mode_tmpl.arithmetic = arithmetic;
349 mode_tmpl.link = NULL;
350 mode_tmpl.tv_priv = NULL;
352 mode = find_mode(&mode_tmpl);
354 hook_new_mode(&mode_tmpl, mode);
358 if (num_of_elem <= 1) {
359 assert(0 && "vector modes should have at least 2 elements");
366 case irms_control_flow:
368 case irms_internal_boolean:
369 assert(0 && "internal modes cannot be user defined");
374 assert(0 && "only integer and floating point modes can be vectorized");
377 case irms_float_number:
378 assert(0 && "not yet implemented");
381 case irms_int_number:
382 mode = register_mode(&mode_tmpl);
387 /* Functions for the direct access to all attributes of an ir_mode */
389 (get_mode_modecode)(const ir_mode *mode) {
390 return _get_mode_modecode(mode);
394 (get_mode_ident)(const ir_mode *mode) {
395 return _get_mode_ident(mode);
399 get_mode_name(const ir_mode *mode) {
400 return get_id_str(mode->name);
404 (get_mode_sort)(const ir_mode* mode) {
405 return _get_mode_sort(mode);
409 (get_mode_size_bits)(const ir_mode *mode) {
410 return _get_mode_size_bits(mode);
414 (get_mode_size_bytes)(const ir_mode *mode) {
415 return _get_mode_size_bytes(mode);
419 (get_mode_sign)(const ir_mode *mode) {
420 return _get_mode_sign(mode);
424 (get_mode_arithmetic)(const ir_mode *mode) {
425 return get_mode_arithmetic(mode);
429 /* Attribute modulo shift specifies for modes of kind irms_int_number
430 * whether shift applies modulo to value of bits to shift. Asserts
431 * if mode is not irms_int_number.
434 (get_mode_modulo_shift)(const ir_mode *mode) {
435 return _get_mode_modulo_shift(mode);
439 (get_mode_n_vector_elems)(const ir_mode *mode) {
440 return _get_mode_vector_elems(mode);
444 (get_mode_link)(const ir_mode *mode) {
445 return _get_mode_link(mode);
449 (set_mode_link)(ir_mode *mode, void *l) {
450 _set_mode_link(mode, l);
454 get_mode_min(ir_mode *mode) {
456 assert(get_mode_modecode(mode) < num_modes);
457 assert(mode_is_data(mode));
463 get_mode_max(ir_mode *mode) {
465 assert(get_mode_modecode(mode) < num_modes);
466 assert(mode_is_data(mode));
472 get_mode_null(ir_mode *mode) {
474 assert(get_mode_modecode(mode) < num_modes);
475 assert(mode_is_data(mode));
481 get_mode_one(ir_mode *mode) {
483 assert(get_mode_modecode(mode) < num_modes);
484 assert(mode_is_data(mode));
490 get_mode_minus_one(ir_mode *mode) {
492 assert(get_mode_modecode(mode) < num_modes);
493 assert(mode_is_data(mode));
495 return mode->minus_one;
499 get_mode_infinite(ir_mode *mode) {
501 assert(get_mode_modecode(mode) < num_modes);
502 assert(mode_is_float(mode));
504 return get_tarval_plus_inf(mode);
508 get_mode_NAN(ir_mode *mode) {
510 assert(get_mode_modecode(mode) < num_modes);
511 assert(mode_is_float(mode));
513 return get_tarval_nan(mode);
517 is_mode(void *thing) {
518 if (get_kind(thing) == k_ir_mode)
525 (mode_is_signed)(const ir_mode *mode) {
526 return _mode_is_signed(mode);
530 (mode_is_float)(const ir_mode *mode) {
531 return _mode_is_float(mode);
535 (mode_is_int)(const ir_mode *mode) {
536 return _mode_is_int(mode);
540 (mode_is_character)(const ir_mode *mode) {
541 return _mode_is_character(mode);
545 (mode_is_reference)(const ir_mode *mode) {
546 return _mode_is_reference(mode);
550 (mode_is_num)(const ir_mode *mode) {
551 return _mode_is_num(mode);
555 (mode_is_numP)(const ir_mode *mode) {
556 return _mode_is_numP(mode);
560 (mode_is_data)(const ir_mode *mode) {
561 return _mode_is_data(mode);
565 (mode_is_datab)(const ir_mode *mode) {
566 return _mode_is_datab(mode);
570 (mode_is_dataM)(const ir_mode *mode) {
571 return _mode_is_dataM(mode);
575 (mode_is_float_vector)(const ir_mode *mode) {
576 return _mode_is_float_vector(mode);
580 (mode_is_int_vector)(const ir_mode *mode) {
581 return _mode_is_int_vector(mode);
584 /* Returns true if sm can be converted to lm without loss. */
586 smaller_mode(const ir_mode *sm, const ir_mode *lm) {
587 int sm_bits, lm_bits;
592 if (sm == lm) return 1;
594 sm_bits = get_mode_size_bits(sm);
595 lm_bits = get_mode_size_bits(lm);
597 switch (get_mode_sort(sm)) {
598 case irms_int_number:
599 switch (get_mode_sort(lm)) {
600 case irms_int_number:
601 /* integers are convertable if
602 * - both have the same sign and lm is the larger one
603 * - lm is the signed one and is at least two bits larger
604 * (one for the sign, one for the highest bit of sm)
605 * - sm & lm are two_complement and lm has greater or equal number of bits
607 if ( get_mode_arithmetic(sm) == get_mode_arithmetic(lm)
608 && get_mode_arithmetic(sm) == irma_twos_complement) {
609 return lm_bits >= sm_bits;
610 } else if (mode_is_signed(sm)) {
611 if ( mode_is_signed(lm) && (lm_bits >= sm_bits) )
613 } else if (mode_is_signed(lm)) {
614 if (lm_bits > sm_bits + 1)
616 } else if (lm_bits >= sm_bits) {
621 case irms_float_number:
622 /* int to float works if the float is large enough */
630 case irms_float_number:
631 if (get_mode_arithmetic(sm) == get_mode_arithmetic(lm)) {
632 if ( (get_mode_sort(lm) == irms_float_number)
633 && (get_mode_size_bits(lm) >= get_mode_size_bits(sm)) )
639 /* do exist machines out there with different pointer lenghts ?*/
650 /* Return the signed integer equivalent mode for an reference mode. */
651 ir_mode *get_reference_mode_signed_eq(ir_mode *mode) {
652 assert(mode_is_reference(mode));
653 return mode->eq_signed;
656 /* Sets the signed integer equivalent mode for an reference mode. */
657 void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode) {
658 assert(mode_is_reference(ref_mode));
659 assert(mode_is_int(int_mode));
660 ref_mode->eq_signed = int_mode;
663 /* Return the unsigned integer equivalent mode for an reference mode. */
664 ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode) {
665 assert(mode_is_reference(mode));
666 return mode->eq_unsigned;
669 /* Sets the unsigned integer equivalent mode for an reference mode. */
670 void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode) {
671 assert(mode_is_reference(ref_mode));
672 assert(mode_is_int(int_mode));
673 ref_mode->eq_unsigned = int_mode;
676 /* initialization, build the default modes */
681 obstack_init(&modes);
684 /* initialize predefined modes */
687 newmode.arithmetic = irma_none;
690 newmode.modulo_shift = 0;
691 newmode.vector_elem = 0;
692 newmode.eq_signed = NULL;
693 newmode.eq_unsigned = NULL;
695 newmode.tv_priv = NULL;
697 /* Control Flow Modes*/
698 newmode.sort = irms_control_flow;
701 newmode.name = new_id_from_chars("BB", 2);
702 newmode.code = irm_BB;
704 mode_BB = register_mode(&newmode);
707 newmode.name = new_id_from_chars("X", 1);
708 newmode.code = irm_X;
710 mode_X = register_mode(&newmode);
713 newmode.sort = irms_memory;
716 newmode.name = new_id_from_chars("M", 1);
717 newmode.code = irm_M;
719 mode_M = register_mode(&newmode);
721 /* Auxiliary Modes */
722 newmode.sort = irms_auxiliary,
725 newmode.name = new_id_from_chars("T", 1);
726 newmode.code = irm_T;
728 mode_T = register_mode(&newmode);
731 newmode.name = new_id_from_chars("ANY", 3);
732 newmode.code = irm_ANY;
734 mode_ANY = register_mode(&newmode);
737 newmode.name = new_id_from_chars("BAD", 3);
738 newmode.code = irm_BAD;
740 mode_BAD = register_mode(&newmode);
742 /* Internal Boolean Modes */
743 newmode.sort = irms_internal_boolean;
746 newmode.name = new_id_from_chars("b", 1);
747 newmode.code = irm_b;
749 mode_b = register_mode(&newmode);
752 newmode.vector_elem = 1;
754 /* Float Number Modes */
755 newmode.sort = irms_float_number;
756 newmode.arithmetic = irma_ieee754;
759 newmode.name = new_id_from_chars("F", 1);
760 newmode.code = irm_F;
764 mode_F = register_mode(&newmode);
767 newmode.name = new_id_from_chars("D", 1);
768 newmode.code = irm_D;
772 mode_D = register_mode(&newmode);
775 newmode.name = new_id_from_chars("E", 1);
776 newmode.code = irm_E;
780 mode_E = register_mode(&newmode);
782 /* Integer Number Modes */
783 newmode.sort = irms_int_number;
784 newmode.arithmetic = irma_twos_complement;
787 newmode.name = new_id_from_chars("Bs", 2);
788 newmode.code = irm_Bs;
791 newmode.modulo_shift = 32;
793 mode_Bs = register_mode(&newmode);
796 newmode.name = new_id_from_chars("Bu", 2);
797 newmode.code = irm_Bu;
798 newmode.arithmetic = irma_twos_complement;
801 newmode.modulo_shift = 32;
803 mode_Bu = register_mode(&newmode);
805 /* signed short integer */
806 newmode.name = new_id_from_chars("Hs", 2);
807 newmode.code = irm_Hs;
810 newmode.modulo_shift = 32;
812 mode_Hs = register_mode(&newmode);
814 /* unsigned short integer */
815 newmode.name = new_id_from_chars("Hu", 2);
816 newmode.code = irm_Hu;
819 newmode.modulo_shift = 32;
821 mode_Hu = register_mode(&newmode);
824 newmode.name = new_id_from_chars("Is", 2);
825 newmode.code = irm_Is;
828 newmode.modulo_shift = 32;
830 mode_Is = register_mode(&newmode);
832 /* unsigned integer */
833 newmode.name = new_id_from_chars("Iu", 2);
834 newmode.code = irm_Iu;
837 newmode.modulo_shift = 32;
839 mode_Iu = register_mode(&newmode);
841 /* signed long integer */
842 newmode.name = new_id_from_chars("Ls", 2);
843 newmode.code = irm_Ls;
846 newmode.modulo_shift = 64;
848 mode_Ls = register_mode(&newmode);
850 /* unsigned long integer */
851 newmode.name = new_id_from_chars("Lu", 2);
852 newmode.code = irm_Lu;
855 newmode.modulo_shift = 64;
857 mode_Lu = register_mode(&newmode);
859 /* signed long long integer */
860 newmode.name = new_id_from_chars("LLs", 3);
861 newmode.code = irm_LLs;
864 newmode.modulo_shift = 128;
866 mode_LLs = register_mode(&newmode);
868 /* unsigned long long integer */
869 newmode.name = new_id_from_chars("LLu", 3);
870 newmode.code = irm_LLu;
873 newmode.modulo_shift = 128;
875 mode_LLu = register_mode(&newmode);
877 /* Character Modes */
878 newmode.sort = irms_character;
879 newmode.arithmetic = irma_twos_complement;
880 newmode.modulo_shift = 0;
883 newmode.name = new_id_from_chars("C", 1);
884 newmode.code = irm_C;
888 mode_C = register_mode(&newmode);
890 /* Unicode character */
891 newmode.name = new_id_from_chars("U", 1);
892 newmode.code = irm_U;
896 mode_U = register_mode(&newmode);
898 /* Reference Modes */
899 newmode.sort = irms_reference;
900 newmode.arithmetic = irma_twos_complement;
903 newmode.name = new_id_from_chars("P", 1);
904 newmode.code = irm_P;
907 newmode.modulo_shift = 0;
908 newmode.eq_signed = mode_Is;
909 newmode.eq_unsigned = mode_Iu;
911 mode_P = register_mode(&newmode);
913 /* set the machine specific modes to the predefined ones */
914 mode_P_code = mode_P;
915 mode_P_data = mode_P;
918 /* find a signed mode for an unsigned integer mode */
919 ir_mode *find_unsigned_mode(const ir_mode *mode) {
922 assert(mode->sort == irms_int_number);
924 return find_mode(&n);
927 /* find an unsigned mode for a signed integer mode */
928 ir_mode *find_signed_mode(const ir_mode *mode) {
931 assert(mode->sort == irms_int_number);
933 return find_mode(&n);
936 /* finds a integer mode with 2*n bits for an integer mode with n bits. */
937 ir_mode *find_double_bits_int_mode(const ir_mode *mode) {
940 assert(mode->sort == irms_int_number && mode->arithmetic == irma_twos_complement);
942 n.size = 2*mode->size;
943 return find_mode(&n);
947 * Returns non-zero if the given mode honors signed zero's, i.e.,
948 * a +0 and a -0 exists and handled differently.
950 int mode_honor_signed_zeros(const ir_mode *mode) {
951 /* for floating point, we know that IEEE 754 has +0 and -0,
952 * but always handles it identical.
955 mode->sort == irms_float_number &&
956 mode->arithmetic != irma_ieee754;
960 * Returns non-zero if the given mode might overflow on unary Minus.
962 * This does NOT happen on IEEE 754.
964 int mode_overflow_on_unary_Minus(const ir_mode *mode) {
965 if (mode->sort == irms_float_number)
966 return mode->arithmetic == irma_ieee754 ? 0 : 1;
971 * Returns non-zero if the mode has a reversed wrap-around
972 * logic, especially (a + x) - x == a.
974 * This is normally true for integer modes, not for floating
977 int mode_wrap_around(const ir_mode *mode) {
978 /* FIXME: better would be an extra mode property */
979 return mode_is_int(mode);
982 void finish_mode(void) {
983 obstack_free(&modes, 0);