1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
4 ** Authors: Martin Trapp, Christian Schaefer
14 # include "irmode_t.h"
24 static long long count = 0;
25 # define ANNOUNCE() printf(__FILE__": call no. %lld (%s)\n", count++, __FUNCTION__)
27 # define ANNOUNCE() ((void)0)
35 /** dynamic array to hold all modes */
36 static struct obstack modes;
38 /** number of defined modes */
46 * Compare modes that don't need to have their code field
49 * TODO: Add other fields
51 INLINE static int modes_are_equal(const ir_mode *m, const ir_mode *n)
54 if (0 == memcmp(&m->sort, &n->sort, offsetof(ir_mode,min) - offsetof(ir_mode,sort))) return 1;
60 * searches the modes obstack for the given mode and returns
61 * a pointer on an equal mode already in the array, NULL if
64 static ir_mode *find_mode(const ir_mode *m)
67 struct _obstack_chunk *p;
70 for( n=(ir_mode*) p->contents; (char *)n < modes.next_free; n+=sizeof(ir_mode) )
72 if(modes_are_equal(n,m)) return n;
75 for (p = p->prev; p; p = p->prev)
77 for( n=(ir_mode*) p->contents; (char *)n < p->limit; n+=sizeof(ir_mode) )
79 if(modes_are_equal(n,m)) return n;
87 * sets special values of modes
89 static void set_mode_values(ir_mode* mode)
91 switch (get_mode_sort(mode))
94 case irms_float_number:
95 mode->min = get_tarval_min(mode);
96 mode->max = get_tarval_max(mode);
97 mode->null = get_tarval_null(mode);
98 mode->one = get_tarval_one(mode);
101 case irms_internal_boolean:
102 mode->min = tarval_b_false;
103 mode->max = tarval_b_true;
104 mode->null = tarval_b_false;
105 mode->one = tarval_b_true;
109 mode->min = tarval_bad;
110 mode->max = tarval_bad;
111 mode->null = (get_mode_modecode(mode)==irm_P)?tarval_P_void:tarval_bad;
112 mode->one = tarval_bad;
118 case irms_control_flow:
119 mode->min = tarval_bad;
120 mode->max = tarval_bad;
121 mode->null = tarval_bad;
122 mode->one = tarval_bad;
128 * globals defined in irmode.h
131 /* --- Predefined modes --- */
133 /* FIRM internal modes: */
141 /* predefined numerical modes: */
142 ir_mode *mode_F; /* float */
143 ir_mode *mode_D; /* double */
144 ir_mode *mode_E; /* long double */
146 ir_mode *mode_Bs; /* integral values, signed and unsigned */
147 ir_mode *mode_Bu; /* 8 bit */
148 ir_mode *mode_Hs; /* 16 bit */
150 ir_mode *mode_Is; /* 32 bit */
152 ir_mode *mode_Ls; /* 64 bit */
159 ir_mode *mode_P_mach;
162 * functions defined in irmode.h
165 /* JNI access functions */
166 INLINE ir_mode *get_modeT(void) { ANNOUNCE(); return mode_T; }
167 INLINE ir_mode *get_modeF(void) { ANNOUNCE(); return mode_F; }
168 INLINE ir_mode *get_modeD(void) { ANNOUNCE(); return mode_D; }
169 INLINE ir_mode *get_modeE(void) { ANNOUNCE(); return mode_E; }
170 INLINE ir_mode *get_modeBs(void) { ANNOUNCE(); return mode_Bs; }
171 INLINE ir_mode *get_modeBu(void) { ANNOUNCE(); return mode_Bu; }
172 INLINE ir_mode *get_modeHs(void) { ANNOUNCE(); return mode_Hs; }
173 INLINE ir_mode *get_modeHu(void) { ANNOUNCE(); return mode_Hu; }
174 INLINE ir_mode *get_modeIs(void) { ANNOUNCE(); return mode_Is; }
175 INLINE ir_mode *get_modeIu(void) { ANNOUNCE(); return mode_Iu; }
176 INLINE ir_mode *get_modeLs(void) { ANNOUNCE(); return mode_Ls; }
177 INLINE ir_mode *get_modeLu(void) { ANNOUNCE(); return mode_Lu; }
178 INLINE ir_mode *get_modeC(void) { ANNOUNCE(); return mode_C; }
179 INLINE ir_mode *get_modeU(void) { ANNOUNCE(); return mode_U; }
180 INLINE ir_mode *get_modeb(void) { ANNOUNCE(); return mode_b; }
181 INLINE ir_mode *get_modeP(void) { ANNOUNCE(); return mode_P; }
182 INLINE ir_mode *get_modeX(void) { ANNOUNCE(); return mode_X; }
183 INLINE ir_mode *get_modeM(void) { ANNOUNCE(); return mode_M; }
184 INLINE ir_mode *get_modeBB(void) { ANNOUNCE(); return mode_BB; }
185 INLINE ir_mode *get_modeANY(void) { ANNOUNCE(); return mode_ANY; }
186 INLINE ir_mode *get_modeBAD(void) { ANNOUNCE(); return mode_BAD; }
189 ir_mode *get_modeP_mach(void) { ANNOUNCE(); return mode_P_mach; }
190 void set_modeP_mach(ir_mode *p) {
192 assert(mode_is_reference(p));
197 * Registers a new mode if not defined yet, else returns
198 * the "equivalent" one.
200 static ir_mode *register_mode(const ir_mode* new_mode)
202 ir_mode *mode = NULL;
207 /* copy mode struct to modes array */
208 mode=(ir_mode*) obstack_copy(&modes, new_mode, sizeof(ir_mode));
210 mode->kind = k_ir_mode;
211 if(num_modes>=irm_max) mode->code = num_modes;
214 set_mode_values(mode);
220 * Creates a new mode.
222 ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int align, int sign, mode_arithmetic arithmetic )
231 case irms_control_flow:
233 case irms_internal_boolean:
234 assert(0 && "internal modes cannot be user defined");
238 case irms_float_number:
239 assert(0 && "not yet implemented");
243 case irms_int_number:
248 mode_tmpl.name = new_id_from_str(name);
249 mode_tmpl.sort = sort;
250 mode_tmpl.size = bit_size;
251 mode_tmpl.align = align;
252 mode_tmpl.sign = sign ? 1 : 0;
253 mode_tmpl.arithmetic = arithmetic;
254 mode_tmpl.tv_priv = NULL;
256 /* first check if there already is a matching mode */
257 mode = find_mode(&mode_tmpl);
264 return register_mode(&mode_tmpl);
268 /* Functions for the direct access to all attributes od a ir_mode */
270 get_mode_modecode(const ir_mode *mode)
277 get_mode_ident(const ir_mode *mode)
284 get_mode_name(const ir_mode *mode)
287 return id_to_str(mode->name);
291 get_mode_sort(const ir_mode* mode)
298 get_mode_size_bits(const ir_mode *mode)
304 int get_mode_size_bytes(const ir_mode *mode) {
305 int size = get_mode_size_bits(mode);
307 if ((size & 7) != 0) return -1;
312 get_mode_align (const ir_mode *mode)
319 get_mode_sign (const ir_mode *mode)
325 int get_mode_arithmetic (const ir_mode *mode)
328 return mode->arithmetic;
331 void* get_mode_link(const ir_mode *mode)
337 void set_mode_link(ir_mode *mode, void *l)
344 get_mode_min (ir_mode *mode)
348 assert(get_mode_modecode(mode) < num_modes);
349 assert(mode_is_data(mode));
355 get_mode_max (ir_mode *mode)
359 assert(get_mode_modecode(mode) < num_modes);
360 assert(mode_is_data(mode));
366 get_mode_null (ir_mode *mode)
370 assert(get_mode_modecode(mode) < num_modes);
371 assert(mode_is_data(mode));
377 get_mode_one (ir_mode *mode)
381 assert(get_mode_modecode(mode) < num_modes);
382 assert(mode_is_data(mode));
388 get_mode_infinite(ir_mode *mode)
392 assert(get_mode_modecode(mode) < num_modes);
393 assert(mode_is_float(mode));
395 return get_tarval_inf(mode);
399 get_mode_NAN(ir_mode *mode)
403 assert(get_mode_modecode(mode) < num_modes);
404 assert(mode_is_float(mode));
406 return get_tarval_nan(mode);
410 is_mode (void *thing) {
412 if (get_kind(thing) == k_ir_mode)
418 /* Functions to check, whether a modecode is signed, float, int, num, data,
419 datab or dataM. For more exact definitions read the corresponding pages
420 in the firm documentation or the followingenumeration
422 The set of "float" is defined as:
423 ---------------------------------
424 float = {irm_F, irm_D, irm_E}
426 The set of "int" is defined as:
427 -------------------------------
428 int = {irm_Bs, irm_Bu, irm_Hs, irm_Hu, irm_Is, irm_Iu, irm_Ls, irm_Lu}
430 The set of "num" is defined as:
431 -------------------------------
432 num = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
433 irm_Is, irm_Iu, irm_Ls, irm_Lu}
436 The set of "data" is defined as:
437 -------------------------------
438 data = {irm_F, irm_D, irm_E irm_Bs, irm_Bu, irm_Hs, irm_Hu,
439 irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P}
440 = {num || irm_C || irm_U || irm_P}
442 The set of "datab" is defined as:
443 ---------------------------------
444 datab = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
445 irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P, irm_b}
448 The set of "dataM" is defined as:
449 ---------------------------------
450 dataM = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
451 irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P, irm_M}
455 #ifdef MODE_ACCESS_DEFINES
456 # undef mode_is_signed
457 # undef mode_is_float
461 # undef mode_is_datab
462 # undef mode_is_dataM
465 mode_is_signed (const ir_mode *mode)
473 mode_is_float (const ir_mode *mode)
477 return (get_mode_sort(mode) == irms_float_number);
481 mode_is_int (const ir_mode *mode)
485 return (get_mode_sort(mode) == irms_int_number);
488 int mode_is_character (const ir_mode *mode)
492 return (get_mode_sort(mode) == irms_character);
495 int mode_is_reference (const ir_mode *mode)
499 return (get_mode_sort(mode) == irms_reference);
503 mode_is_num (const ir_mode *mode)
507 return (mode_is_int(mode) || mode_is_float(mode));
511 mode_is_data (const ir_mode *mode)
515 return (mode_is_num(mode) || get_mode_sort(mode) == irms_character || get_mode_sort(mode) == irms_reference);
519 mode_is_datab (const ir_mode *mode)
523 return (mode_is_data(mode) || get_mode_sort(mode) == irms_internal_boolean);
527 mode_is_dataM (const ir_mode *mode)
531 return (mode_is_data(mode) || get_mode_modecode(mode) == irm_M);
533 #ifdef MODE_ACCESS_DEFINES
534 # define mode_is_signed(mode) (mode)->sign
535 # define mode_is_float(mode) ((mode)->sort == irms_float_number)
536 # define mode_is_int(mode) ((mode)->sort == irms_int_number)
537 # define mode_is_num(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number))
538 # define mode_is_data(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number) || ((mode)->sort == irms_character) || ((mode)->sort == irms_reference))
539 # define mode_is_datab(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number) || ((mode)->sort == irms_character) || ((mode)->sort == irms_reference) || ((mode)->sort == irms_internal_boolean))
540 # define mode_is_dataM(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number) || ((mode)->sort == irms_character) || ((mode)->sort == irms_reference) || ((mode)->code == irm_M))
542 /* Returns true if sm can be converted to lm without loss. */
544 smaller_mode(const ir_mode *sm, const ir_mode *lm)
550 if (sm == lm) return 1;
552 switch(get_mode_sort(sm))
554 case irms_int_number:
555 switch(get_mode_sort(lm))
557 case irms_int_number:
558 /* integers are convertable if
559 * - both have the same sign and lm is the larger one
560 * - lm is the signed one and is at least two bits larger
561 * (one for the sign, one for the highest bit of sm)
563 if (mode_is_signed(sm))
565 if ( mode_is_signed(lm) && (get_mode_size_bits(lm) > get_mode_size_bits(sm)) )
568 else if (mode_is_signed(lm))
570 if (get_mode_size_bits(lm) > get_mode_size_bits(sm) + 1)
573 else if (get_mode_size_bits(lm) > get_mode_size_bits(sm))
579 case irms_float_number:
580 /* int to float works if the float is large enough */
588 case irms_float_number:
589 /* XXX currently only the three standard 32,64,80 bit floats
590 * are supported which can safely be converted */
591 if ( (get_mode_sort(lm) == irms_float_number)
592 && (get_mode_size_bits(lm) > get_mode_size_bits(sm)) )
597 /* do exist machines out there with different pointer lenghts ?*/
608 /* ** initialization ** */
614 /* init flexible array */
616 obstack_init(&modes);
619 /* initialize predefined modes */
622 newmode.arithmetic = irma_none;
626 newmode.tv_priv = NULL;
628 /* Control Flow Modes*/
629 newmode.sort = irms_control_flow;
632 newmode.name = id_from_str("BB", 2);
633 newmode.code = irm_BB;
635 mode_BB = register_mode(&newmode);
638 newmode.name = id_from_str("X", 1);
639 newmode.code = irm_X;
641 mode_X = register_mode(&newmode);
644 newmode.sort = irms_memory;
647 newmode.name = id_from_str("M", 1);
648 newmode.code = irm_M;
650 mode_M = register_mode(&newmode);
652 /* Auxiliary Modes */
653 newmode.sort = irms_auxiliary,
656 newmode.name = id_from_str("T", 1);
657 newmode.code = irm_T;
659 mode_T = register_mode(&newmode);
662 newmode.name = id_from_str("ANY", 3);
663 newmode.code = irm_ANY;
665 mode_ANY = register_mode(&newmode);
668 newmode.name = id_from_str("BAD", 3);
669 newmode.code = irm_BAD;
671 mode_BAD = register_mode(&newmode);
673 /* Internal Boolean Modes */
674 newmode.sort = irms_internal_boolean;
677 newmode.name = id_from_str("b", 1);
678 newmode.code = irm_b;
680 mode_b = register_mode(&newmode);
684 /* Float Number Modes */
685 newmode.sort = irms_float_number;
686 newmode.arithmetic = irma_ieee754;
689 newmode.name = id_from_str("F", 1);
690 newmode.code = irm_F;
695 mode_F = register_mode(&newmode);
698 newmode.name = id_from_str("D", 1);
699 newmode.code = irm_D;
704 mode_D = register_mode(&newmode);
707 newmode.name = id_from_str("E", 1);
708 newmode.code = irm_E;
713 mode_E = register_mode(&newmode);
715 /* Integer Number Modes */
716 newmode.sort = irms_int_number;
717 newmode.arithmetic = irma_twos_complement;
720 newmode.name = id_from_str("Bs", 2);
721 newmode.code = irm_Bs;
726 mode_Bs = register_mode(&newmode);
729 newmode.name = id_from_str("Bu", 2);
730 newmode.code = irm_Bu;
731 newmode.arithmetic = irma_twos_complement;
736 mode_Bu = register_mode(&newmode);
738 /* signed short integer */
739 newmode.name = id_from_str("Hs", 2);
740 newmode.code = irm_Hs;
745 mode_Hs = register_mode(&newmode);
747 /* unsigned short integer */
748 newmode.name = id_from_str("Hu", 2);
749 newmode.code = irm_Hu;
754 mode_Hu = register_mode(&newmode);
757 newmode.name = id_from_str("Is", 2);
758 newmode.code = irm_Is;
763 mode_Is = register_mode(&newmode);
765 /* unsigned integer */
766 newmode.name = id_from_str("Iu", 2);
767 newmode.code = irm_Iu;
772 mode_Iu = register_mode(&newmode);
774 /* signed long integer */
775 newmode.name = id_from_str("Ls", 2);
776 newmode.code = irm_Ls;
781 mode_Ls = register_mode(&newmode);
783 /* unsigned long integer */
784 newmode.name = id_from_str("Lu", 2);
785 newmode.code = irm_Lu;
790 mode_Lu = register_mode(&newmode);
792 /* Character Modes */
793 newmode.sort = irms_character;
794 newmode.arithmetic = irma_none;
797 newmode.name = id_from_str("C", 1);
798 newmode.code = irm_C;
803 mode_C = register_mode(&newmode);
805 /* Unicode character */
806 newmode.name = id_from_str("U", 1);
807 newmode.code = irm_U;
812 mode_U = register_mode(&newmode);
814 /* Reference Modes */
815 newmode.sort = irms_reference;
816 newmode.arithmetic = irma_twos_complement;
819 newmode.name = id_from_str("P", 1);
820 newmode.code = irm_P;
825 mode_P = register_mode(&newmode);