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");
351 void free_tarval_entity(entity *ent) {
352 /* There can be a tarval referencing this entity. Even if the
353 tarval is not used by the code any more, it can still reference
354 the entity as tarvals live indepently of the entity referenced.
355 Further the tarval is hashed into a set. If a hash function
356 evaluation happens to collide with this tarval, we will vrfy that
357 it contains a proper entity and we will crash if the entity is
360 Unluckily, tarvals can neither be changed nor deleted, and to find
361 one, all existing reference modes have to be tried -> a facility
362 to retrieve all modes of a kind is needed. */
367 * Access routines for tarval fields ========================================
369 ir_mode *get_tarval_mode (tarval *tv) /* get the mode of the tarval */
377 * Special value query functions ============================================
379 * These functions calculate and return a tarval representing the requested
381 * The functions get_mode_{Max,Min,...} return tarvals retrieved from these
382 * functions, but these are stored on initialization of the irmode module and
383 * therefore the irmode functions should be prefered to the functions below.
386 tarval *get_tarval_bad(void)
391 tarval *get_tarval_undefined(void)
394 return tarval_undefined;
396 tarval *get_tarval_b_false(void)
399 return tarval_b_false;
401 tarval *get_tarval_b_true(void)
404 return tarval_b_true;
406 tarval *get_tarval_P_void(void)
409 return tarval_P_void;
412 tarval *get_tarval_max(ir_mode *mode)
417 switch(get_mode_sort(mode))
424 case internal_boolean:
425 return tarval_b_true;
428 fc_get_max(get_mode_size_bits(mode));
429 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
433 sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode));
434 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
439 tarval *get_tarval_min(ir_mode *mode)
444 switch(get_mode_sort(mode))
451 case internal_boolean:
452 return tarval_b_false;
455 fc_get_min(get_mode_size_bits(mode));
456 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
460 sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode));
461 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
466 tarval *get_tarval_null(ir_mode *mode)
471 switch(get_mode_sort(mode))
474 case internal_boolean:
479 return new_tarval_from_double(0.0, mode);
483 return new_tarval_from_long(0l, mode);
486 return tarval_P_void;
491 tarval *get_tarval_one(ir_mode *mode)
496 switch(get_mode_sort(mode))
499 case internal_boolean:
505 return new_tarval_from_double(1.0, mode);
509 return new_tarval_from_long(1l, mode);
515 tarval *get_tarval_nan(ir_mode *mode)
520 if (get_mode_sort(mode) == float_number) {
522 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
525 assert(0 && "tarval is not floating point");
530 tarval *get_tarval_inf(ir_mode *mode)
535 if (get_mode_sort(mode) == float_number) {
537 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
540 assert(0 && "tarval is not floating point");
546 * Arithmethic operations on tarvals ========================================
549 /* test if negative number, 1 means 'yes' */
550 int tarval_is_negative(tarval *a)
555 switch (get_mode_sort(a->mode))
558 if (!mode_is_signed(a->mode)) return 0;
560 return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
563 return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
566 assert(0 && "not implemented");
572 pnc_number tarval_cmp(tarval *a, tarval *b)
578 if (a == tarval_bad || b == tarval_bad) assert(0 && "Comparison with tarval_bad");
579 if (a == tarval_undefined || b == tarval_undefined) return False;
580 if (a == b) return Eq;
581 if (get_tarval_mode(a) != get_tarval_mode(b)) return Uo;
583 /* Here the two tarvals are unequal and of the same mode */
584 switch (get_mode_sort(a->mode))
590 return (fc_comp(a->value, b->value)==1)?(Gt):(Lt);
594 return (sc_comp(a->value, b->value)==1)?(Gt):(Lt);
596 case internal_boolean:
597 return (a == tarval_b_true)?(Gt):(Lt);
605 tarval *tarval_convert_to(tarval *src, ir_mode *m)
613 if (src->mode == m) return src;
615 switch (get_mode_sort(src->mode))
624 switch (get_mode_sort(m))
629 tv.length = src->length;
630 tv.value = src->value;
635 return INSERT_TARVAL(&tv);
637 case internal_boolean:
638 /* XXX C semantics */
639 if (src == get_mode_null(src->mode)) return tarval_b_false;
640 else return tarval_b_true;
647 case internal_boolean:
648 switch (get_mode_sort(m))
651 if (src == tarval_b_true) return get_mode_one(m);
652 else return get_mode_null(m);
668 tarval *tarval_neg(tarval *a) /* negation */
672 assert(mode_is_num(a->mode)); /* negation only for numerical values */
673 assert(mode_is_signed(a->mode)); /* negation is difficult without negative numbers, isn't it */
675 switch (get_mode_sort(a->mode))
679 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
683 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
690 tarval *tarval_add(tarval *a, tarval *b) /* addition */
695 assert((a->mode == b->mode) || (get_mode_sort(a->mode) == character && mode_is_int(b->mode)));
697 switch (get_mode_sort(a->mode))
701 /* modes of a,b are equal, so result has mode of a as this might be the character */
702 sc_add(a->value, b->value);
703 /* FIXME: Check for overflow */
704 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
707 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
708 fc_add(a->value, b->value);
709 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
716 tarval *tarval_sub(tarval *a, tarval *b) /* subtraction */
721 assert((a->mode == b->mode) || (get_mode_sort(a->mode) == character && mode_is_int(b->mode)));
723 switch (get_mode_sort(a->mode))
727 /* modes of a,b are equal, so result has mode of a as this might be the character */
728 sc_sub(a->value, b->value);
729 /* FIXME: check for overflow */
730 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
733 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
734 fc_add(a->value, b->value);
735 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
742 tarval *tarval_mul(tarval *a, tarval *b) /* multiplication */
747 assert((a->mode == b->mode) && mode_is_num(a->mode));
749 switch (get_mode_sort(a->mode))
752 /* modes of a,b are equal */
753 sc_mul(a->value, b->value);
754 /* FIXME: check for overflow */
755 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
758 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
759 fc_add(a->value, b->value);
760 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
767 tarval *tarval_quo(tarval *a, tarval *b) /* floating point division */
772 assert((a->mode == b->mode) && mode_is_float(a->mode));
774 /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
775 fc_div(a->value, b->value);
776 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
779 tarval *tarval_div(tarval *a, tarval *b) /* integer division */
784 assert((a->mode == b->mode) && mode_is_int(a->mode));
786 /* modes of a,b are equal */
787 sc_div(a->value, b->value);
788 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
791 tarval *tarval_mod(tarval *a, tarval *b) /* remainder */
796 assert((a->mode == b->mode) && mode_is_int(a->mode));
798 /* modes of a,b are equal */
799 sc_mod(a->value, b->value);
800 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
803 tarval *tarval_abs(tarval *a) /* absolute value */
807 assert(mode_is_num(a->mode));
809 switch (get_mode_sort(a->mode))
812 if (sc_comp(a->value, get_mode_null(a->mode)->value) == -1)
815 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
828 tarval *tarval_and(tarval *a, tarval *b) /* bitwise and */
833 assert((a->mode == b->mode) && mode_is_int(a->mode));
835 sc_and(a->value, b->value);
836 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
838 tarval *tarval_or (tarval *a, tarval *b) /* bitwise or */
843 assert((a->mode == b->mode) && mode_is_int(a->mode));
845 sc_or(a->value, b->value);
846 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
848 tarval *tarval_eor(tarval *a, tarval *b) /* bitwise exclusive or (xor) */
853 assert((a->mode == b->mode) && mode_is_int(a->mode));
855 sc_or(a->value, b->value);
856 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
859 tarval *tarval_shl(tarval *a, tarval *b) /* bitwise left shift */
864 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
866 sc_shl(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
867 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
869 tarval *tarval_shr(tarval *a, tarval *b) /* bitwise unsigned right shift */
874 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
876 sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
877 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
879 tarval *tarval_shrs(tarval *a, tarval *b) /* bitwise signed right shift */
884 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
886 sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
887 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
889 tarval *tarval_rot(tarval *a, tarval *b) /* bitwise rotation */
894 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
896 sc_rot(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
897 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
900 /** *********** Output of tarvals *********** **/
901 int tarval_print(XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
908 tv = XP_GETARG(tarval *, 0);
909 switch (get_mode_sort(tv->mode))
913 str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC);
914 return XPF1R("%s", str);
917 return XPF1R("%s", fc_print_dec(tv->value, buf, sizeof(buf)));
920 if (tv->value != NULL)
921 if (tarval_is_entity(tv))
922 if (get_entity_peculiarity((entity *)tv->value) == existent)
923 return XPF1R("&(%I)", get_entity_ld_ident((entity *)tv->value));
927 return XPMR((char*)tv->value, tv->length);
931 case internal_boolean:
932 if (tv == tarval_b_true) return XPSR("true");
933 else return XPSR("false");
936 return XPSR("<BAD>");
942 char *tarval_bitpattern(tarval *tv)
948 * access to the bitpattern
950 unsigned char tarval_sub_bits(tarval *tv, unsigned byte_ofs)
952 switch (get_mode_sort(tv->mode)) {
955 return sc_sub_bits(tv->value, tv->length, byte_ofs);
958 return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
965 /* Identifying some tarvals ??? */
966 /* Implemented in old tv.c as such:
967 * return 0 for additive neutral,
968 * 1 for multiplicative neutral,
969 * -1 for bitwise-and neutral
972 * Implemented for completeness */
973 long tarval_classify(tarval *tv)
976 if (!tv || tv == tarval_bad) return 2;
978 if (tv == get_mode_null(tv->mode)) return 0;
979 else if (tv == get_mode_one(tv->mode)) return 1;
980 else if ((get_mode_sort(tv->mode) == int_number)
981 && (tv == new_tarval_from_long(-1, tv->mode))) return -1;
986 /* Initialization of the tarval module: called before init_mode() */
987 void init_tarval_1(void)
990 /* initialize the sets holding the tarvals with a comparison function and
991 * an initial size, which is the expected number of constants */
992 tarvals = new_set(memcmp, TUNE_NCONSTANTS);
993 values = new_set(memcmp, TUNE_NCONSTANTS);
994 /* init with default precision */
996 /* init_fltcalc(0); not yet*/
999 /* Initialization of the tarval module: called after init_mode() */
1000 void init_tarval_2(void)
1004 tarval_bad = (tarval*)malloc(sizeof(tarval));
1005 tarval_bad->mode = NULL;
1007 tarval_undefined = (tarval*)malloc(sizeof(tarval));
1008 tarval_undefined->mode = NULL;
1010 tarval_b_true = (tarval*)malloc(sizeof(tarval));
1011 tarval_b_true->mode = mode_b;
1013 tarval_b_false = (tarval*)malloc(sizeof(tarval));
1014 tarval_b_false->mode = mode_b;
1016 tarval_P_void = (tarval*)malloc(sizeof(tarval));
1017 tarval_P_void->mode = mode_P;
1020 /****************************************************************************
1022 ****************************************************************************/