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)
511 if (get_mode_sort(mode) == float_number) {
513 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
516 assert(0 && "tarval is not floating point");
521 tarval *get_tarval_inf(ir_mode *mode)
526 if (get_mode_sort(mode) == float_number) {
528 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
531 assert(0 && "tarval is not floating point");
537 * Arithmethic operations on tarvals ========================================
540 /* test if negative number, 1 means 'yes' */
541 int tarval_is_negative(tarval *a)
546 switch (get_mode_sort(a->mode))
549 if (!mode_is_signed(a->mode)) return 0;
551 return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
554 return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
557 assert(0 && "not implemented");
563 pnc_number tarval_cmp(tarval *a, tarval *b)
569 if (a == tarval_bad || b == tarval_bad) assert(0 && "Comparison with tarval_bad");
570 if (a == tarval_undefined || b == tarval_undefined) return False;
571 if (a == b) return Eq;
572 if (get_tarval_mode(a) != get_tarval_mode(b)) return Uo;
574 /* Here the two tarvals are unequal and of the same mode */
575 switch (get_mode_sort(a->mode))
581 return (fc_comp(a->value, b->value)==1)?(Gt):(Lt);
585 return (sc_comp(a->value, b->value)==1)?(Gt):(Lt);
587 case internal_boolean:
588 return (a == tarval_b_true)?(Gt):(Lt);
596 tarval *tarval_convert_to(tarval *src, ir_mode *m)
604 if (src->mode == m) return src;
606 switch (get_mode_sort(src->mode))
615 switch (get_mode_sort(m))
620 tv.length = src->length;
621 tv.value = src->value;
626 return INSERT_TARVAL(&tv);
628 case internal_boolean:
629 /* XXX C semantics */
630 if (src == get_mode_null(src->mode)) return tarval_b_false;
631 else return tarval_b_true;
638 case internal_boolean:
639 switch (get_mode_sort(m))
642 if (src == tarval_b_true) return get_mode_one(m);
643 else return get_mode_null(m);
659 tarval *tarval_neg(tarval *a) /* negation */
663 assert(mode_is_num(a->mode)); /* negation only for numerical values */
664 assert(mode_is_signed(a->mode)); /* negation is difficult without negative numbers, isn't it */
667 switch (get_mode_sort(a->mode))
671 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
676 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
683 tarval *tarval_add(tarval *a, tarval *b) /* addition */
688 assert((a->mode == b->mode) || (get_mode_sort(a->mode) == character && mode_is_int(b->mode)));
690 switch (get_mode_sort(a->mode))
694 /* modes of a,b are equal, so result has mode of a as this might be the character */
695 sc_add(a->value, b->value);
696 /* FIXME: Check for overflow */
697 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
700 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
701 fc_add(a->value, b->value);
702 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
709 tarval *tarval_sub(tarval *a, tarval *b) /* subtraction */
714 assert((a->mode == b->mode) || (get_mode_sort(a->mode) == character && mode_is_int(b->mode)));
716 switch (get_mode_sort(a->mode))
720 /* modes of a,b are equal, so result has mode of a as this might be the character */
721 sc_sub(a->value, b->value);
722 /* FIXME: check for overflow */
723 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
726 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
727 fc_add(a->value, b->value);
728 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
735 tarval *tarval_mul(tarval *a, tarval *b) /* multiplication */
740 assert((a->mode == b->mode) && mode_is_num(a->mode));
742 switch (get_mode_sort(a->mode))
745 /* modes of a,b are equal */
746 sc_mul(a->value, b->value);
747 /* FIXME: check for overflow */
748 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
751 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
752 fc_add(a->value, b->value);
753 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
760 tarval *tarval_quo(tarval *a, tarval *b) /* floating point division */
765 assert((a->mode == b->mode) && mode_is_float(a->mode));
767 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
768 fc_div(a->value, b->value);
769 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
772 tarval *tarval_div(tarval *a, tarval *b) /* integer division */
777 assert((a->mode == b->mode) && mode_is_int(a->mode));
779 /* modes of a,b are equal */
780 sc_div(a->value, b->value);
781 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
784 tarval *tarval_mod(tarval *a, tarval *b) /* remainder */
789 assert((a->mode == b->mode) && mode_is_int(a->mode));
791 /* modes of a,b are equal */
792 sc_mod(a->value, b->value);
793 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
796 tarval *tarval_abs(tarval *a) /* absolute value */
800 assert(mode_is_num(a->mode));
802 switch (get_mode_sort(a->mode))
805 if (sc_comp(a->value, get_mode_null(a->mode)->value) == -1)
808 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
821 tarval *tarval_and(tarval *a, tarval *b) /* bitwise and */
826 assert((a->mode == b->mode) && mode_is_int(a->mode));
828 sc_and(a->value, b->value);
829 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
831 tarval *tarval_or (tarval *a, tarval *b) /* bitwise or */
836 assert((a->mode == b->mode) && mode_is_int(a->mode));
838 sc_or(a->value, b->value);
839 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
841 tarval *tarval_eor(tarval *a, tarval *b) /* bitwise exclusive or (xor) */
846 assert((a->mode == b->mode) && mode_is_int(a->mode));
848 sc_or(a->value, b->value);
849 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
852 tarval *tarval_shl(tarval *a, tarval *b) /* bitwise left shift */
857 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
859 sc_shl(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
860 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
862 tarval *tarval_shr(tarval *a, tarval *b) /* bitwise unsigned right shift */
867 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
869 sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
870 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
872 tarval *tarval_shrs(tarval *a, tarval *b) /* bitwise signed right shift */
877 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
879 sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
880 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
882 tarval *tarval_rot(tarval *a, tarval *b) /* bitwise rotation */
887 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
889 sc_rot(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
890 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
893 /** *********** Output of tarvals *********** **/
894 int tarval_print(XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
902 tv = XP_GETARG(tarval *, 0);
903 switch (get_mode_sort(tv->mode))
907 offset = 16 - (get_mode_size_bits(tv->mode)/4);
908 str = sc_print_hex(tv->value);
909 return XPF1R("0x%s", str + offset);
912 return XPF1R("%s", fc_print_dec(tv->value, buf, sizeof(buf)));
915 if (tv->value != NULL)
916 if (tarval_is_entity(tv))
917 if (get_entity_peculiarity((entity *)tv->value) == existent)
918 return XPF1R("&(%I)", get_entity_ld_ident((entity *)tv->value));
922 return XPMR((char*)tv->value, tv->length);
926 case internal_boolean:
927 if (tv == tarval_b_true) return XPSR("true");
928 else return XPSR("false");
931 return XPSR("<BAD>");
937 char *tarval_bitpattern(tarval *tv)
943 * access to the bitpattern
945 unsigned char tarval_sub_bits(tarval *tv, unsigned byte_ofs)
947 switch (get_mode_sort(tv->mode)) {
950 return sc_sub_bits(tv->value, tv->length, byte_ofs);
953 return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
960 /* Identifying some tarvals ??? */
961 /* Implemented in old tv.c as such:
962 * return 0 for additive neutral,
963 * 1 for multiplicative neutral,
964 * -1 for bitwise-and neutral
967 * Implemented for completeness */
968 long tarval_classify(tarval *tv)
971 if (!tv || tv == tarval_bad) return 2;
973 if (tv == get_mode_null(tv->mode)) return 0;
974 else if (tv == get_mode_one(tv->mode)) return 1;
975 else if ((get_mode_sort(tv->mode) == int_number)
976 && (tv == new_tarval_from_long(-1, tv->mode))) return -1;
981 /* Initialization of the tarval module: called before init_mode() */
982 void init_tarval_1(void)
985 /* initialize the sets holding the tarvals with a comparison function and
986 * an initial size, which is the expected number of constants */
987 tarvals = new_set(memcmp, TUNE_NCONSTANTS);
988 values = new_set(memcmp, TUNE_NCONSTANTS);
991 /* Initialization of the tarval module: called after init_mode() */
992 void init_tarval_2(void)
996 tarval_bad = (tarval*)malloc(sizeof(tarval));
997 tarval_bad->mode = NULL;
999 tarval_undefined = (tarval*)malloc(sizeof(tarval));
1000 tarval_undefined->mode = NULL;
1002 tarval_b_true = (tarval*)malloc(sizeof(tarval));
1003 tarval_b_true->mode = mode_b;
1005 tarval_b_false = (tarval*)malloc(sizeof(tarval));
1006 tarval_b_false->mode = mode_b;
1008 tarval_P_void = (tarval*)malloc(sizeof(tarval));
1009 tarval_P_void->mode = mode_P;
1012 /****************************************************************************
1014 ****************************************************************************/
1017 free_tarval_entity(entity *ent) {
1018 /* There can be a tarval referencing this entity. Even if the
1019 tarval is not used by the code any more, it can still reference
1020 the entity as tarvals live forever (They live on an obstack.).
1021 Further the tarval is hashed into a set. If a hash function
1022 evaluation happens to collide with this tarval, we will vrfy that
1023 it contains a proper entity and we will crash if the entity is
1024 freed. We cannot remove tarvals from the obstack but we can
1025 remove the entry in the hash table. */
1026 /* this will be re-implemented later */