1 /* TV --- Target Values, aka Constant Table.
2 Copyright (C) 1995, 1996 Christian von Roques */
6 /****i* tv/implementation
13 * Internal storage for tarvals, 1st draft:
14 * Integers as well as pointers are stored in a hex formatted string holding
15 * 16 characters. Booleans are not stored as there are only two of them.
17 * Floats are just reinterpreted as byte strings, because I am not sure if
18 * there is loss if I convert float to long double and back and furthermore
19 * the implementation of a fully ieee compatible floating point emulation
20 * is not sensible for now
21 * With this information it is easy to decide the kind of stored value:
22 * Integers have size 16, floats 4, doubles 8, long doubles 12.
25 /* This implementation assumes:
26 * both host and target have IEEE-754 floating-point arithmetic. */
28 /* !!! float and double divides MUST NOT SIGNAL !!! */
29 /* @@@ query the floating-point expception status flags */
31 /* @@@ Problem: All Values are stored twice, once as Univ_*s and a 2nd
32 time in their real target mode. :-( */
34 #define MAX_INT_LENGTH 8
35 #define CHAR_BUFFER_SIZE ((MAX_INT_LENGTH) * 2)
41 #include <assert.h> /* assertions */
42 #include <stdlib.h> /* atoi() */
43 #include <string.h> /* nice things for strings */
47 #include "set.h" /* to store tarvals in */
48 #include "tune.h" /* some constants */
49 #include "entity_t.h" /* needed to store pointers to entities */
50 #include "irmode.h" /* defines modes etc */
51 #include "irnode.h" /* defines boolean return values */
58 /****************************************************************************
59 * local definitions and macros
60 ****************************************************************************/
62 # define TARVAL_VERIFY(a) tarval_verify((a))
64 # define TARVAL_VERIFY(a) ((void)0)
67 #define INSERT_TARVAL(tv) ((tarval*)set_insert(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
68 #define FIND_TARVAL(tv) ((tarval*)set_find(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
70 #define INSERT_VALUE(val, size) (set_insert(values, (val), size, hash_val((val), size)))
71 #define FIND_VALUE(val, size) (set_find(values, (val), size, hash_val((val), size)))
73 #define fail_verify(a) _fail_verify((a), __FILE__, __LINE__)
75 static long long count = 0;
76 # define ANNOUNCE() printf(__FILE__": call no. %lld (%s)\n", count++, __FUNCTION__);
78 # define ANNOUNCE() ((void)0)
80 /****************************************************************************
82 ****************************************************************************/
83 static struct set *tarvals; /* container for tarval structs */
84 static struct set *values; /* container for values */
86 /****************************************************************************
88 ****************************************************************************/
90 static int hash_val(const void *value, unsigned int length);
91 static int hash_tv(tarval *tv);
92 static void _fail_verify(tarval *tv, const char* file, int line)
94 /* print a memory image of the tarval and throw an assertion */
96 printf("%s:%d: Invalid tarval:\n mode: %s\n value: [%p]\n", file, line, get_mode_name(tv->mode), tv->value);
98 printf("%s:%d: Invalid tarval (null)", file, line);
102 static void tarval_verify(tarval *tv)
108 if ((tv == tarval_bad) || (tv == tarval_undefined)) return;
109 if ((tv == tarval_b_true) || (tv == tarval_b_false)) return;
111 if (!FIND_TARVAL(tv)) fail_verify(tv);
112 if (tv->length > 0 && !FIND_VALUE(tv->value, tv->length)) fail_verify(tv);
118 static int hash_tv(tarval *tv)
120 return ((unsigned int)tv->value ^ (unsigned int)tv->mode) + tv->length;
123 static int hash_val(const void *value, unsigned int length)
126 unsigned int hash = 0;
128 /* scramble the byte - array */
129 for (i = 0; i < length; i++)
131 hash += (hash << 5) ^ (hash >> 27) ^ ((char*)value)[i];
132 hash += (hash << 11) ^ (hash >> 17);
138 /* finds tarval with value/mode or creates new tarval*/
139 static tarval *get_tarval(const void *value, int length, ir_mode *mode)
146 /* if there already is such a value, it is returned, else value
147 * is copied into the set */
148 tv.value = INSERT_VALUE(value, length);
152 /* if there is such a tarval, it is returned, else tv is copied
154 return (tarval *)INSERT_TARVAL(&tv);
158 * Returns non-zero if a tarval overflows.
160 * @todo Implementation did not work on all modes
162 static int overflows(tarval *tv)
164 switch (get_mode_sort(tv->mode))
168 if (sc_comp(tv->value, get_mode_max(tv->mode)->value) == 1) return 1;
169 if (sc_comp(tv->value, get_mode_min(tv->mode)->value) == -1) return 1;
173 if (fc_comp(tv->value, get_mode_max(tv->mode)->value) == 1) return 1;
174 if (fc_comp(tv->value, get_mode_min(tv->mode)->value) == -1) return 1;
184 /****************************************************************************
185 * public variables declared in tv.h
186 ****************************************************************************/
188 tarval *tarval_undefined;
189 tarval *tarval_b_false;
190 tarval *tarval_b_true;
191 tarval *tarval_P_void;
193 /****************************************************************************
194 * public functions declared in tv.h
195 ****************************************************************************/
197 * Constructors =============================================================
199 tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
206 switch (get_mode_sort(mode))
212 case internal_boolean:
213 /* match tTrRuUeE/fFaAlLsSeE */
214 if (strcasecmp(str, "true")) return tarval_b_true;
215 else if (strcasecmp(str, "false")) return tarval_b_true;
217 return atoi(str) ? tarval_b_true : tarval_b_false;
220 fc_val_from_str(str, len);
221 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
225 sc_val_from_str(str, len);
226 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
229 return get_tarval(str, len, mode);
232 assert(0); /* can't be reached, can it? */
237 int tarval_is_str(tarval *tv)
242 return ((get_mode_sort(tv->mode) == reference) && (tv->value != NULL) && (tv->length > 0));
244 char *tarval_to_str(tarval *tv)
247 assert(tarval_is_str(tv));
248 return (char *)tv->value;
252 tarval *new_tarval_from_long(long l, ir_mode *mode)
255 assert(mode && !(get_mode_sort(mode) == auxiliary));
257 switch(get_mode_sort(mode))
259 case internal_boolean:
260 /* XXX C-Semantics ! */
261 return l ? tarval_b_true : tarval_b_false ;
266 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
269 return new_tarval_from_double((long double)l, mode);
272 return l ? tarval_bad : get_tarval(NULL, 0, mode); /* null pointer or tarval_bad */
280 int tarval_is_long(tarval *tv)
283 return ((get_mode_sort(tv->mode) == int_number) || (get_mode_sort(tv->mode) == character));
286 /* this might overflow the machine's long, so use only with small values */
287 long tarval_to_long(tarval* tv)
290 assert(tv && get_mode_sort(tv->mode) == int_number);
292 return sc_val_to_long(tv->value); /* might overflow */
295 tarval *new_tarval_from_double(long double d, ir_mode *mode)
298 assert(mode && (get_mode_sort(mode) == float_number));
300 fc_val_from_float(d);
301 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
304 int tarval_is_double(tarval *tv)
309 return (get_mode_sort(tv->mode) == float_number);
312 long double tarval_to_double(tarval *tv)
315 assert(tarval_is_double(tv));
317 return fc_val_to_float(tv->value);
320 /* The tarval represents the address of the entity. As the address must
321 be constant the entity must have as owner the global type. */
322 tarval *new_tarval_from_entity (entity *ent, ir_mode *mode)
326 assert(mode && (get_mode_sort(mode) == reference));
328 return get_tarval((void *)ent, 0, mode);
330 int tarval_is_entity(tarval *tv)
334 /* tv->value == NULL means dereferencing a null pointer */
335 return ((get_mode_sort(tv->mode) == reference) && (tv->value != NULL) && (tv->length == 0));
338 entity *tarval_to_entity(tarval *tv)
343 if (tarval_is_entity(tv))
344 return (entity *)tv->value;
346 assert(0 && "tarval did not represent an entity");
352 * Access routines for tarval fields ========================================
354 #ifdef TARVAL_ACCESS_DEFINES
355 # undef get_tarval_mode
357 ir_mode *get_tarval_mode (tarval *tv) /* get the mode of the tarval */
363 #ifdef TARVAL_ACCESS_DEFINES
364 # define get_tarval_mode(tv) (tv)->mode
368 * Special value query functions ============================================
370 * These functions calculate and return a tarval representing the requested
372 * The functions get_mode_{Max,Min,...} return tarvals retrieved from these
373 * functions, but these are stored on initialization of the irmode module and
374 * therefore the irmode functions should be prefered to the functions below.
377 tarval *get_tarval_bad(void)
382 tarval *get_tarval_undefined(void)
385 return tarval_undefined;
387 tarval *get_tarval_b_false(void)
390 return tarval_b_false;
392 tarval *get_tarval_b_true(void)
395 return tarval_b_true;
397 tarval *get_tarval_P_void(void)
400 return tarval_P_void;
403 tarval *get_tarval_max(ir_mode *mode)
408 switch(get_mode_sort(mode))
415 case internal_boolean:
416 return tarval_b_true;
419 fc_get_max(get_mode_size_bits(mode));
420 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
424 sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode));
425 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
430 tarval *get_tarval_min(ir_mode *mode)
435 switch(get_mode_sort(mode))
442 case internal_boolean:
443 return tarval_b_false;
446 fc_get_min(get_mode_size_bits(mode));
447 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
451 sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode));
452 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
457 tarval *get_tarval_null(ir_mode *mode)
462 switch(get_mode_sort(mode))
465 case internal_boolean:
470 return new_tarval_from_double(0.0, mode);
474 return new_tarval_from_long(0l, mode);
477 return tarval_P_void;
482 tarval *get_tarval_one(ir_mode *mode)
487 switch(get_mode_sort(mode))
490 case internal_boolean:
496 return new_tarval_from_double(1.0, mode);
500 return new_tarval_from_long(1l, mode);
506 tarval *get_tarval_nan(ir_mode *mode)
510 assert(get_mode_sort(mode) == float_number);
513 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
516 tarval *get_tarval_inf(ir_mode *mode)
520 assert(get_mode_sort(mode) == float_number);
523 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
527 * Arithmethic operations on tarvals ========================================
530 /* test if negative number, 1 means 'yes' */
531 int tarval_is_negative(tarval *a)
536 switch (get_mode_sort(a->mode))
539 if (!mode_is_signed(a->mode)) return 0;
540 else return sc_comp(a->value, get_mode_null(a->mode)->value);
543 return fc_comp(a->value, get_mode_null(a->mode)->value);
546 assert(0 && "not implemented");
551 pnc_number tarval_cmp(tarval *a, tarval *b)
557 if (a == tarval_bad || b == tarval_bad) assert(0 && "Comparison with tarval_bad");
558 if (a == tarval_undefined || b == tarval_undefined) return False;
559 if (a == b) return Eq;
560 if (get_tarval_mode(a) != get_tarval_mode(b)) return Uo;
562 /* Here the two tarvals are unequal and of the same mode */
563 switch (get_mode_sort(a->mode))
569 return (fc_comp(a->value, b->value)==1)?(Gt):(Lt);
573 return (sc_comp(a->value, b->value)==1)?(Gt):(Lt);
575 case internal_boolean:
576 return (a == tarval_b_true)?(Gt):(Lt);
584 tarval *tarval_convert_to(tarval *src, ir_mode *m)
592 if (src->mode == m) return src;
594 switch (get_mode_sort(src->mode))
603 switch (get_mode_sort(m))
608 tv.length = src->length;
609 tv.value = src->value;
614 return INSERT_TARVAL(&tv);
616 case internal_boolean:
617 /* XXX C semantics */
618 if (src == get_mode_null(src->mode)) return tarval_b_false;
619 else return tarval_b_true;
626 case internal_boolean:
627 switch (get_mode_sort(m))
630 if (src == tarval_b_true) return get_mode_one(m);
631 else return get_mode_null(m);
647 tarval *tarval_neg(tarval *a) /* negation */
651 assert(mode_is_num(a->mode)); /* negation only for numerical values */
652 assert(mode_is_signed(a->mode)); /* negation is difficult without negative numbers, isn't it */
654 switch (get_mode_sort(a->mode))
658 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
662 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
669 tarval *tarval_add(tarval *a, tarval *b) /* addition */
674 assert((a->mode == b->mode) || (get_mode_sort(a->mode) == character && mode_is_int(b->mode)));
676 switch (get_mode_sort(a->mode))
680 /* modes of a,b are equal, so result has mode of a as this might be the character */
681 sc_add(a->value, b->value);
682 /* FIXME: Check for overflow */
683 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
686 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
687 fc_add(a->value, b->value);
688 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
695 tarval *tarval_sub(tarval *a, tarval *b) /* subtraction */
700 assert((a->mode == b->mode) || (get_mode_sort(a->mode) == character && mode_is_int(b->mode)));
702 switch (get_mode_sort(a->mode))
706 /* modes of a,b are equal, so result has mode of a as this might be the character */
707 sc_sub(a->value, b->value);
708 /* FIXME: check for overflow */
709 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
712 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
713 fc_add(a->value, b->value);
714 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
721 tarval *tarval_mul(tarval *a, tarval *b) /* multiplication */
726 assert((a->mode == b->mode) && mode_is_num(a->mode));
728 switch (get_mode_sort(a->mode))
731 /* modes of a,b are equal */
732 sc_mul(a->value, b->value);
733 /* FIXME: check for overflow */
734 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
737 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
738 fc_add(a->value, b->value);
739 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
746 tarval *tarval_quo(tarval *a, tarval *b) /* floating point division */
751 assert((a->mode == b->mode) && mode_is_float(a->mode));
753 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
754 fc_div(a->value, b->value);
755 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
758 tarval *tarval_div(tarval *a, tarval *b) /* integer division */
763 assert((a->mode == b->mode) && mode_is_int(a->mode));
765 /* modes of a,b are equal */
766 sc_div(a->value, b->value);
767 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
770 tarval *tarval_mod(tarval *a, tarval *b) /* remainder */
775 assert((a->mode == b->mode) && mode_is_int(a->mode));
777 /* modes of a,b are equal */
778 sc_mod(a->value, b->value);
779 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
782 tarval *tarval_abs(tarval *a) /* absolute value */
786 assert(mode_is_num(a->mode));
788 switch (get_mode_sort(a->mode))
791 if (sc_comp(a->value, get_mode_null(a->mode)->value) == -1)
794 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
807 tarval *tarval_and(tarval *a, tarval *b) /* bitwise and */
812 assert((a->mode == b->mode) && mode_is_int(a->mode));
814 sc_and(a->value, b->value);
815 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
817 tarval *tarval_or (tarval *a, tarval *b) /* bitwise or */
822 assert((a->mode == b->mode) && mode_is_int(a->mode));
824 sc_or(a->value, b->value);
825 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
827 tarval *tarval_eor(tarval *a, tarval *b) /* bitwise exclusive or (xor) */
832 assert((a->mode == b->mode) && mode_is_int(a->mode));
834 sc_or(a->value, b->value);
835 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
838 tarval *tarval_shl(tarval *a, tarval *b) /* bitwise left shift */
843 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
845 sc_shl(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
846 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
848 tarval *tarval_shr(tarval *a, tarval *b) /* bitwise unsigned right shift */
853 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
855 sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
856 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
858 tarval *tarval_shrs(tarval *a, tarval *b) /* bitwise signed right shift */
863 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
865 sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
866 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
868 tarval *tarval_rot(tarval *a, tarval *b) /* bitwise rotation */
873 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
875 sc_rot(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
876 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
879 /** *********** Output of tarvals *********** **/
880 int tarval_print(XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
888 tv = XP_GETARG(tarval *, 0);
889 switch (get_mode_sort(tv->mode))
893 offset = 16 - (get_mode_size_bits(tv->mode)/4);
894 str = sc_print_hex(tv->value);
895 return XPF1R("0x%s", str + offset);
898 return XPF1R("%s", fc_print_dec(tv->value, buf, sizeof(buf)));
901 if (tv->value != NULL)
902 if (tarval_is_entity(tv))
903 if (get_entity_peculiarity((entity *)tv->value) == existent)
904 return XPF1R("&(%I)", get_entity_ld_ident((entity *)tv->value));
908 return XPMR((char*)tv->value, tv->length);
912 case internal_boolean:
913 if (tv == tarval_b_true) return XPSR("true");
914 else return XPSR("false");
917 return XPSR("<BAD>");
923 char *tarval_bitpattern(tarval *tv)
928 /* Identifying some tarvals ??? */
929 /* Implemented in old tv.c as such:
930 * return 0 for additive neutral,
931 * 1 for multiplicative neutral,
932 * -1 for bitwise-and neutral
935 * Implemented for completeness */
936 long tarval_classify(tarval *tv)
939 if (!tv || tv == tarval_bad) return 2;
941 if (tv == get_mode_null(tv->mode)) return 0;
942 else if (tv == get_mode_one(tv->mode)) return 1;
943 else if ((get_mode_sort(tv->mode) == int_number)
944 && (tv == new_tarval_from_long(-1, tv->mode))) return -1;
949 /* Initialization of the tarval module: called before init_mode() */
950 void init_tarval_1(void)
953 /* initialize the sets holding the tarvals with a comparison function and
954 * an initial size, which is the expected number of constants */
955 tarvals = new_set(memcmp, TUNE_NCONSTANTS);
956 values = new_set(memcmp, TUNE_NCONSTANTS);
959 /* Initialization of the tarval module: called after init_mode() */
960 void init_tarval_2(void)
964 tarval_bad = (tarval*)malloc(sizeof(tarval));
965 tarval_bad->mode = NULL;
967 tarval_undefined = (tarval*)malloc(sizeof(tarval));
968 tarval_undefined->mode = NULL;
970 tarval_b_true = (tarval*)malloc(sizeof(tarval));
971 tarval_b_true->mode = mode_b;
973 tarval_b_false = (tarval*)malloc(sizeof(tarval));
974 tarval_b_false->mode = mode_b;
976 tarval_P_void = (tarval*)malloc(sizeof(tarval));
977 tarval_P_void->mode = mode_P;
980 /****************************************************************************
982 ****************************************************************************/
985 free_tarval_entity(entity *ent) {
986 /* There can be a tarval referencing this entity. Even if the
987 tarval is not used by the code any more, it can still reference
988 the entity as tarvals live forever (They live on an obstack.).
989 Further the tarval is hashed into a set. If a hash function
990 evaluation happens to collide with this tarval, we will vrfy that
991 it contains a proper entity and we will crash if the entity is
992 freed. We cannot remove tarvals from the obstack but we can
993 remove the entry in the hash table. */
994 /* this will be re-implemented later */