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 * @brief Representation of and static computations on target machine
25 * @author Mathias Heil
29 * Values are stored in a format depending upon chosen arithmetic
30 * module. Default uses strcalc and fltcalc.
31 * This implementation assumes:
32 * - target has IEEE-754 floating-point arithmetic.
38 #include <assert.h> /* assertions */
39 #include <stdlib.h> /* atoi() */
41 # include <string.h> /* nice things for strings */
44 #include <strings.h> /* strings.h also includes bsd only function strcasecmp */
51 #include "set.h" /* to store tarvals in */
52 #include "entity_t.h" /* needed to store pointers to entities */
54 #include "irnode.h" /* defines boolean return values (pnc_number)*/
59 #include "firm_common.h"
61 /** Size of hash tables. Should correspond to average number of distinct constant
63 #define N_CONSTANTS 2048
65 /* get the integer overflow mode */
66 #define GET_OVERFLOW_MODE() int_overflow_mode
68 /* unused, float to int doesn't work yet */
69 enum float_to_int_mode {
74 #define GET_FLOAT_TO_INT_MODE() TRUNCATE
76 #define SWITCH_NOINFINITY 0
77 #define SWITCH_NODENORMALS 0
79 /****************************************************************************
80 * local definitions and macros
81 ****************************************************************************/
83 # define TARVAL_VERIFY(a) tarval_verify((a))
85 # define TARVAL_VERIFY(a) ((void)0)
88 #define INSERT_TARVAL(tv) ((tarval*)set_insert(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
89 #define FIND_TARVAL(tv) ((tarval*)set_find(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
91 #define INSERT_VALUE(val, size) (set_insert(values, (val), size, hash_val((val), size)))
92 #define FIND_VALUE(val, size) (set_find(values, (val), size, hash_val((val), size)))
94 #define fail_verify(a) _fail_verify((a), __FILE__, __LINE__)
96 /****************************************************************************
98 ****************************************************************************/
99 static struct set *tarvals = NULL; /* container for tarval structs */
100 static struct set *values = NULL; /* container for values */
101 static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP;
105 /****************************************************************************
107 ****************************************************************************/
109 static int hash_val(const void *value, unsigned int length);
110 static int hash_tv(tarval *tv);
111 static void _fail_verify(tarval *tv, const char* file, int line)
113 /* print a memory image of the tarval and throw an assertion */
115 printf("%s:%d: Invalid tarval:\n mode: %s\n value: [%p]\n", file, line, get_mode_name(tv->mode), tv->value);
117 printf("%s:%d: Invalid tarval (null)", file, line);
121 INLINE static void tarval_verify(tarval *tv) __attribute__ ((unused));
124 INLINE static void tarval_verify(tarval *tv)
130 if ((tv == tarval_bad) || (tv == tarval_undefined)) return;
131 if ((tv == tarval_b_true) || (tv == tarval_b_false)) return;
133 if (!FIND_TARVAL(tv)) fail_verify(tv);
134 if (tv->length > 0 && !FIND_VALUE(tv->value, tv->length)) fail_verify(tv);
140 /** Hash a tarval. */
141 static int hash_tv(tarval *tv) {
142 return (PTR_TO_INT(tv->value) ^ PTR_TO_INT(tv->mode)) + tv->length;
145 /** Hash a value. Treat it as a byte array. */
146 static int hash_val(const void *value, unsigned int length) {
148 unsigned int hash = 0;
150 /* scramble the byte - array */
151 for (i = 0; i < length; ++i) {
152 hash += (hash << 5) ^ (hash >> 27) ^ ((char*)value)[i];
153 hash += (hash << 11) ^ (hash >> 17);
159 /** finds tarval with value/mode or creates new tarval */
160 static tarval *get_tarval(const void *value, int length, ir_mode *mode) {
167 /* if there already is such a value, it is returned, else value
168 * is copied into the set */
169 tv.value = INSERT_VALUE(value, length);
173 /* if there is such a tarval, it is returned, else tv is copied
175 return (tarval *)INSERT_TARVAL(&tv);
181 static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode)
183 switch (get_mode_sort(mode)) {
184 case irms_int_number:
185 if (sc_comp(value, get_mode_max(mode)->value) == 1) {
186 switch (GET_OVERFLOW_MODE()) {
187 case TV_OVERFLOW_SATURATE:
188 return get_mode_max(mode);
189 case TV_OVERFLOW_WRAP:
191 char *temp = alloca(sc_get_buffer_length());
192 sc_val_from_ulong(-1, temp);
193 sc_and(temp, value, temp);
194 /* the sc_ module expects that all bits are set ... */
195 sign_extend(temp, mode);
196 return get_tarval(temp, length, mode);
198 case TV_OVERFLOW_BAD:
201 return get_tarval(value, length, mode);
204 if (sc_comp(value, get_mode_min(mode)->value) == -1) {
205 switch (GET_OVERFLOW_MODE()) {
206 case TV_OVERFLOW_SATURATE:
207 return get_mode_min(mode);
208 case TV_OVERFLOW_WRAP: {
209 char *temp = alloca(sc_get_buffer_length());
210 sc_val_from_ulong(-1, temp);
211 sc_and(temp, value, temp);
212 return get_tarval(temp, length, mode);
214 case TV_OVERFLOW_BAD:
217 return get_tarval(value, length, mode);
222 case irms_float_number:
223 if (SWITCH_NOINFINITY && fc_is_inf(value)) {
224 return fc_is_negative(value)?get_mode_min(mode):get_mode_max(mode);
227 if (SWITCH_NODENORMALS && fc_is_subnormal(value)) {
228 return get_mode_null(mode);
235 return get_tarval(value, length, mode);
239 * public variables declared in tv.h
241 static tarval reserved_tv[4];
243 tarval *tarval_bad = &reserved_tv[0];
244 tarval *tarval_undefined = &reserved_tv[1];
245 tarval *tarval_b_false = &reserved_tv[2];
246 tarval *tarval_b_true = &reserved_tv[3];
249 * public functions declared in tv.h
253 * Constructors =============================================================
255 tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
261 switch (get_mode_sort(mode)) {
262 case irms_control_flow:
268 case irms_internal_boolean:
269 /* match [tT][rR][uU][eE]|[fF][aA][lL][sS][eE] */
270 if (strcasecmp(str, "true")) return tarval_b_true;
271 else if (strcasecmp(str, "false")) return tarval_b_true;
273 /* XXX This is C semantics */
274 return atoi(str) ? tarval_b_true : tarval_b_false;
276 case irms_float_number:
277 switch(get_mode_size_bits(mode)) {
279 fc_val_from_str(str, len, 8, 23, NULL);
282 fc_val_from_str(str, len, 11, 52, NULL);
285 fc_val_from_str(str, len, 15, 64, NULL);
288 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
291 /* same as integer modes */
292 case irms_int_number:
294 sc_val_from_str(str, len, NULL, mode);
295 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
298 assert(0); /* can't be reached, can it? */
303 * helper function, create a tarval from long
305 tarval *new_tarval_from_long(long l, ir_mode *mode) {
308 switch(get_mode_sort(mode)) {
309 case irms_internal_boolean:
310 /* XXX C semantics ! */
311 return l ? tarval_b_true : tarval_b_false ;
314 /* same as integer modes */
315 case irms_int_number:
317 sc_val_from_long(l, NULL);
318 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
320 case irms_float_number:
321 return new_tarval_from_double((long double)l, mode);
324 assert(0 && "unsupported mode sort");
329 /* returns non-zero if can be converted to long */
330 int tarval_is_long(tarval *tv) {
331 mode_sort sort = get_mode_sort(tv->mode);
333 if (sort != irms_int_number && sort != irms_character) return 0;
335 if (get_mode_size_bits(tv->mode) > (int) (sizeof(long) << 3)) {
336 /* the value might be too big to fit in a long */
337 sc_max_from_bits(sizeof(long) << 3, 0, NULL);
338 if (sc_comp(sc_get_buffer(), tv->value) == -1) {
339 /* really doesn't fit */
346 /* this might overflow the machine's long, so use only with small values */
347 long get_tarval_long(tarval* tv) {
348 assert(tarval_is_long(tv) && "tarval too big to fit in long");
350 return sc_val_to_long(tv->value);
353 tarval *new_tarval_from_double(long double d, ir_mode *mode) {
354 assert(mode && (get_mode_sort(mode) == irms_float_number));
356 switch (get_mode_size_bits(mode)) {
358 fc_val_from_float(d, 8, 23, NULL);
361 fc_val_from_float(d, 11, 52, NULL);
364 fc_val_from_float(d, 15, 64, NULL);
367 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
370 /* returns non-zero if can be converted to double */
371 int tarval_is_double(tarval *tv) {
374 return (get_mode_sort(tv->mode) == irms_float_number);
377 long double get_tarval_double(tarval *tv) {
378 assert(tarval_is_double(tv));
380 return fc_val_to_float(tv->value);
385 * Access routines for tarval fields ========================================
388 /* get the mode of the tarval */
389 ir_mode *(get_tarval_mode)(const tarval *tv) {
390 return _get_tarval_mode(tv);
394 * Special value query functions ============================================
396 * These functions calculate and return a tarval representing the requested
398 * The functions get_mode_{Max,Min,...} return tarvals retrieved from these
399 * functions, but these are stored on initialization of the irmode module and
400 * therefore the irmode functions should be prefered to the functions below.
403 tarval *(get_tarval_bad)(void) {
404 return _get_tarval_bad();
407 tarval *(get_tarval_undefined)(void) {
408 return _get_tarval_undefined();
411 tarval *(get_tarval_b_false)(void) {
412 return _get_tarval_b_false();
415 tarval *(get_tarval_b_true)(void) {
416 return _get_tarval_b_true();
419 tarval *get_tarval_max(ir_mode *mode) {
422 if (get_mode_n_vector_elems(mode) > 1) {
423 /* vector arithmetic not implemented yet */
427 switch(get_mode_sort(mode)) {
429 case irms_control_flow:
435 case irms_internal_boolean:
436 return tarval_b_true;
438 case irms_float_number:
439 switch(get_mode_size_bits(mode)) {
441 fc_get_max(8, 23, NULL);
444 fc_get_max(11, 52, NULL);
447 fc_get_max(15, 64, NULL);
450 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
452 case irms_int_number:
454 sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
455 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
460 tarval *get_tarval_min(ir_mode *mode) {
463 if (get_mode_n_vector_elems(mode) > 1) {
464 /* vector arithmetic not implemented yet */
468 switch(get_mode_sort(mode)) {
470 case irms_control_flow:
476 case irms_internal_boolean:
477 return tarval_b_false;
479 case irms_float_number:
480 switch(get_mode_size_bits(mode)) {
482 fc_get_min(8, 23, NULL);
485 fc_get_min(11, 52, NULL);
488 fc_get_min(15, 64, NULL);
491 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
493 case irms_int_number:
495 sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
496 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
501 /** The bit pattern for the pointer NULL */
502 static long _null_value;
504 tarval *get_tarval_null(ir_mode *mode) {
507 if (get_mode_n_vector_elems(mode) > 1) {
508 /* vector arithmetic not implemented yet */
512 switch(get_mode_sort(mode)) {
513 case irms_control_flow:
516 case irms_internal_boolean:
520 case irms_float_number:
521 return new_tarval_from_double(0.0, mode);
523 case irms_int_number:
525 return new_tarval_from_long(0l, mode);
528 return new_tarval_from_long(_null_value, mode);
533 tarval *get_tarval_one(ir_mode *mode) {
536 if (get_mode_n_vector_elems(mode) > 1) {
537 /* vector arithmetic not implemented yet */
541 switch(get_mode_sort(mode)) {
542 case irms_control_flow:
545 case irms_internal_boolean:
550 case irms_float_number:
551 return new_tarval_from_double(1.0, mode);
553 case irms_int_number:
555 return new_tarval_from_long(1l, mode);
561 tarval *get_tarval_minus_one(ir_mode *mode) {
564 if (get_mode_n_vector_elems(mode) > 1) {
565 /* vector arithmetic not implemented yet */
569 switch(get_mode_sort(mode)) {
570 case irms_control_flow:
573 case irms_internal_boolean:
578 case irms_float_number:
579 return mode_is_signed(mode) ? new_tarval_from_double(-1.0, mode) : tarval_bad;
581 case irms_int_number:
583 return mode_is_signed(mode) ? new_tarval_from_long(-1l, mode) : tarval_bad;
588 tarval *get_tarval_nan(ir_mode *mode) {
591 if (get_mode_n_vector_elems(mode) > 1) {
592 /* vector arithmetic not implemented yet */
596 if (get_mode_sort(mode) == irms_float_number) {
597 switch(get_mode_size_bits(mode)) {
599 fc_get_qnan(8, 23, NULL);
602 fc_get_qnan(11, 52, NULL);
605 fc_get_qnan(15, 64, NULL);
608 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
610 assert(0 && "tarval is not floating point");
615 tarval *get_tarval_plus_inf(ir_mode *mode) {
618 if (get_mode_n_vector_elems(mode) > 1) {
619 /* vector arithmetic not implemented yet */
623 if (get_mode_sort(mode) == irms_float_number) {
624 switch(get_mode_size_bits(mode)) {
626 fc_get_plusinf(8, 23, NULL);
629 fc_get_plusinf(11, 52, NULL);
632 fc_get_plusinf(15, 64, NULL);
635 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
637 assert(0 && "tarval is not floating point");
642 tarval *get_tarval_minus_inf(ir_mode *mode) {
645 if (get_mode_n_vector_elems(mode) > 1) {
646 /* vector arithmetic not implemented yet */
650 if (get_mode_sort(mode) == irms_float_number) {
651 switch(get_mode_size_bits(mode)) {
653 fc_get_minusinf(8, 23, NULL);
656 fc_get_minusinf(11, 52, NULL);
659 fc_get_minusinf(15, 64, NULL);
662 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
664 assert(0 && "tarval is not floating point");
670 * Arithmethic operations on tarvals ========================================
674 * test if negative number, 1 means 'yes'
676 int tarval_is_negative(tarval *a) {
679 if (get_mode_n_vector_elems(a->mode) > 1) {
680 /* vector arithmetic not implemented yet */
681 assert(0 && "tarval_is_negative is not allowed for vector modes");
685 switch (get_mode_sort(a->mode)) {
686 case irms_int_number:
687 if (!mode_is_signed(a->mode)) return 0;
689 return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
691 case irms_float_number:
692 return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
695 assert(0 && "not implemented");
701 * test if null, 1 means 'yes'
703 int tarval_is_null(tarval *a) {
704 ir_mode *m = get_tarval_mode(a);
706 return a == get_tarval_null(m);
710 * test if one, 1 means 'yes'
712 int tarval_is_one(tarval *a) {
713 ir_mode *m = get_tarval_mode(a);
715 return a == get_tarval_one(m);
721 pn_Cmp tarval_cmp(tarval *a, tarval *b) {
725 if (a == tarval_bad || b == tarval_bad) {
726 assert(0 && "Comparison with tarval_bad");
730 if (a == tarval_undefined || b == tarval_undefined)
733 if (a->mode != b->mode)
736 if (get_mode_n_vector_elems(a->mode) > 1) {
737 /* vector arithmetic not implemented yet */
738 assert(0 && "cmp not implemented for vector modes");
741 /* Here the two tarvals are unequal and of the same mode */
742 switch (get_mode_sort(a->mode)) {
743 case irms_control_flow:
751 case irms_float_number:
755 * BEWARE: we cannot compare a == b here, because
756 * a NaN is always Unordered to any other value, even to itself!
758 switch (fc_comp(a->value, b->value)) {
759 case -1: return pn_Cmp_Lt;
760 case 0: return pn_Cmp_Eq;
761 case 1: return pn_Cmp_Gt;
762 case 2: return pn_Cmp_Uo;
763 default: return pn_Cmp_False;
765 case irms_int_number:
769 return sc_comp(a->value, b->value) == 1 ? pn_Cmp_Gt : pn_Cmp_Lt;
771 case irms_internal_boolean:
774 return a == tarval_b_true ? pn_Cmp_Gt : pn_Cmp_Lt;
780 * convert to other mode
782 tarval *tarval_convert_to(tarval *src, ir_mode *m) {
788 if (src->mode == m) return src;
790 if (get_mode_n_vector_elems(src->mode) > 1) {
791 /* vector arithmetic not implemented yet */
795 switch (get_mode_sort(src->mode)) {
796 case irms_control_flow:
801 /* cast float to something */
802 case irms_float_number:
803 switch (get_mode_sort(m)) {
804 case irms_float_number:
805 switch (get_mode_size_bits(m)) {
807 fc_cast(src->value, 8, 23, NULL);
810 fc_cast(src->value, 11, 52, NULL);
813 fc_cast(src->value, 15, 64, NULL);
818 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), m);
820 case irms_int_number:
821 switch (GET_FLOAT_TO_INT_MODE()) {
823 fc_int(src->value, NULL);
826 fc_rnd(src->value, NULL);
832 /* FIXME: floating point unit can't produce a value in integer
834 * an intermediate representation is needed here first. */
835 /* return get_tarval(); */
839 /* the rest can't be converted */
844 /* cast int/characters to something */
845 case irms_int_number:
847 switch (get_mode_sort(m)) {
848 case irms_int_number:
850 buffer = alloca(sc_get_buffer_length());
851 memcpy(buffer, src->value, sc_get_buffer_length());
852 sign_extend(buffer, m);
853 return get_tarval_overflow(buffer, src->length, m);
855 case irms_internal_boolean:
856 /* XXX C semantics */
857 if (src == get_mode_null(src->mode)) return tarval_b_false;
858 else return tarval_b_true;
860 case irms_float_number:
861 /* XXX floating point unit does not understand internal integer
862 * representation, convert to string first, then create float from
864 buffer = alloca(100);
865 /* decimal string representation because hexadecimal output is
866 * interpreted unsigned by fc_val_from_str, so this is a HACK */
867 snprintf(buffer, 100, "%s",
868 sc_print(src->value, get_mode_size_bits(src->mode), SC_DEC, mode_is_signed(src->mode)));
869 buffer[100 - 1] = '\0';
870 switch (get_mode_size_bits(m)) {
872 fc_val_from_str(buffer, 0, 8, 23, NULL);
875 fc_val_from_str(buffer, 0, 11, 52, NULL);
878 fc_val_from_str(buffer, 0, 15, 64, NULL);
881 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), m);
884 /* allow 0 to be casted */
885 if (src == get_mode_null(src->mode))
886 return get_mode_null(m);
894 case irms_internal_boolean:
895 switch (get_mode_sort(m)) {
896 case irms_int_number:
897 if (src == tarval_b_true) return get_mode_one(m);
898 else return get_mode_null(m);
906 switch(get_mode_sort(m)) {
907 case irms_int_number:
908 buffer = alloca(sc_get_buffer_length());
909 memcpy(buffer, src->value, sc_get_buffer_length());
910 sign_extend(buffer, src->mode);
911 return get_tarval_overflow(buffer, src->length, m);
925 tarval *tarval_not(tarval *a) {
930 /* works for vector mode without changes */
932 switch (get_mode_sort(a->mode)) {
933 case irms_int_number:
934 buffer = alloca(sc_get_buffer_length());
935 sc_not(a->value, buffer);
936 return get_tarval(buffer, a->length, a->mode);
938 case irms_internal_boolean:
939 if (a == tarval_b_true)
940 return tarval_b_false;
941 if (a == tarval_b_false)
942 return tarval_b_true;
946 assert(0 && "bitwise negation is only allowed for integer and boolean");
952 * arithmetic negation
954 tarval *tarval_neg(tarval *a) {
958 assert(mode_is_num(a->mode)); /* negation only for numerical values */
960 /* note: negation is allowed even for unsigned modes. */
962 if (get_mode_n_vector_elems(a->mode) > 1) {
963 /* vector arithmetic not implemented yet */
967 switch (get_mode_sort(a->mode)) {
968 case irms_int_number:
969 buffer = alloca(sc_get_buffer_length());
970 sc_neg(a->value, buffer);
971 return get_tarval_overflow(buffer, a->length, a->mode);
973 case irms_float_number:
977 fc_neg(a->value, NULL);
978 return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
988 tarval *tarval_add(tarval *a, tarval *b) {
993 assert(a->mode == b->mode);
995 if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) {
996 /* vector arithmetic not implemented yet */
1000 switch (get_mode_sort(a->mode)) {
1001 case irms_character:
1002 case irms_int_number:
1003 /* modes of a,b are equal, so result has mode of a as this might be the character */
1004 buffer = alloca(sc_get_buffer_length());
1005 sc_add(a->value, b->value, buffer);
1006 return get_tarval_overflow(buffer, a->length, a->mode);
1008 case irms_float_number:
1012 fc_add(a->value, b->value, NULL);
1013 return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1023 tarval *tarval_sub(tarval *a, tarval *b) {
1028 assert(a->mode == b->mode);
1030 if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) {
1031 /* vector arithmetic not implemented yet */
1034 switch (get_mode_sort(a->mode)) {
1035 case irms_character:
1036 case irms_int_number:
1037 /* modes of a,b are equal, so result has mode of a as this might be the character */
1038 buffer = alloca(sc_get_buffer_length());
1039 sc_sub(a->value, b->value, buffer);
1040 return get_tarval_overflow(buffer, a->length, a->mode);
1042 case irms_float_number:
1046 fc_sub(a->value, b->value, NULL);
1047 return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1057 tarval *tarval_mul(tarval *a, tarval *b) {
1062 assert(a->mode == b->mode);
1064 if (get_mode_n_vector_elems(a->mode) > 1) {
1065 /* vector arithmetic not implemented yet */
1069 switch (get_mode_sort(a->mode)) {
1070 case irms_int_number:
1071 /* modes of a,b are equal */
1072 buffer = alloca(sc_get_buffer_length());
1073 sc_mul(a->value, b->value, buffer);
1074 return get_tarval_overflow(buffer, a->length, a->mode);
1076 case irms_float_number:
1080 fc_mul(a->value, b->value, NULL);
1081 return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1089 * floating point division
1091 tarval *tarval_quo(tarval *a, tarval *b) {
1094 assert((a->mode == b->mode) && mode_is_float(a->mode));
1099 if (get_mode_n_vector_elems(a->mode) > 1) {
1100 /* vector arithmetic not implemented yet */
1104 fc_div(a->value, b->value, NULL);
1105 return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1110 * overflow is impossible, but look out for division by zero
1112 tarval *tarval_div(tarval *a, tarval *b) {
1115 assert((a->mode == b->mode) && mode_is_int(a->mode));
1117 if (get_mode_n_vector_elems(a->mode) > 1) {
1118 /* vector arithmetic not implemented yet */
1123 if (b == get_mode_null(b->mode)) return tarval_bad;
1124 /* modes of a,b are equal */
1125 sc_div(a->value, b->value, NULL);
1126 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1131 * overflow is impossible, but look out for division by zero
1133 tarval *tarval_mod(tarval *a, tarval *b) {
1136 assert((a->mode == b->mode) && mode_is_int(a->mode));
1138 if (get_mode_n_vector_elems(a->mode) > 1) {
1139 /* vector arithmetic not implemented yet */
1144 if (b == get_mode_null(b->mode)) return tarval_bad;
1145 /* modes of a,b are equal */
1146 sc_mod(a->value, b->value, NULL);
1147 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1153 tarval *tarval_abs(tarval *a) {
1157 assert(mode_is_num(a->mode));
1159 if (get_mode_n_vector_elems(a->mode) > 1) {
1160 /* vector arithmetic not implemented yet */
1164 switch (get_mode_sort(a->mode)) {
1165 case irms_int_number:
1166 if (sc_comp(a->value, get_mode_null(a->mode)->value) == -1) {
1167 buffer = alloca(sc_get_buffer_length());
1168 sc_neg(a->value, buffer);
1169 return get_tarval_overflow(buffer, a->length, a->mode);
1173 case irms_float_number:
1177 if (fc_comp(a->value, get_mode_null(a->mode)->value) == -1) {
1178 fc_neg(a->value, NULL);
1179 return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1192 tarval *tarval_and(tarval *a, tarval *b) {
1195 assert(a->mode == b->mode);
1197 /* works even for vector modes */
1199 switch(get_mode_sort(a->mode)) {
1200 case irms_internal_boolean:
1201 return (a == tarval_b_false) ? a : b;
1203 case irms_int_number:
1204 sc_and(a->value, b->value, NULL);
1205 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1208 assert(0 && "operation not defined on mode");
1216 tarval *tarval_or (tarval *a, tarval *b) {
1219 assert(a->mode == b->mode);
1221 /* works even for vector modes */
1223 switch (get_mode_sort(a->mode)) {
1224 case irms_internal_boolean:
1225 return (a == tarval_b_true) ? a : b;
1227 case irms_int_number:
1228 sc_or(a->value, b->value, NULL);
1229 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1232 assert(0 && "operation not defined on mode");
1238 * bitwise exclusive or (xor)
1240 tarval *tarval_eor(tarval *a, tarval *b) {
1243 assert((a->mode == b->mode));
1245 /* works even for vector modes */
1247 switch (get_mode_sort(a->mode)) {
1248 case irms_internal_boolean:
1249 return (a == b)? tarval_b_false : tarval_b_true;
1251 case irms_int_number:
1252 sc_xor(a->value, b->value, NULL);
1253 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1256 assert(0 && "operation not defined on mode");
1262 * bitwise left shift
1264 tarval *tarval_shl(tarval *a, tarval *b) {
1265 char *temp_val = NULL;
1269 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1271 if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1272 /* vector arithmetic not implemented yet */
1276 if (get_mode_modulo_shift(a->mode) != 0) {
1277 temp_val = alloca(sc_get_buffer_length());
1279 sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1280 sc_mod(b->value, temp_val, temp_val);
1282 temp_val = (char*)b->value;
1284 sc_shl(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1285 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1289 * bitwise unsigned right shift
1291 tarval *tarval_shr(tarval *a, tarval *b) {
1292 char *temp_val = NULL;
1296 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1298 if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1299 /* vector arithmetic not implemented yet */
1303 if (get_mode_modulo_shift(a->mode) != 0) {
1304 temp_val = alloca(sc_get_buffer_length());
1306 sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1307 sc_mod(b->value, temp_val, temp_val);
1309 temp_val = (char*)b->value;
1311 sc_shr(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1312 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1316 * bitwise signed right shift
1318 tarval *tarval_shrs(tarval *a, tarval *b) {
1319 char *temp_val = NULL;
1323 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1325 if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1326 /* vector arithmetic not implemented yet */
1330 if (get_mode_modulo_shift(a->mode) != 0) {
1331 temp_val = alloca(sc_get_buffer_length());
1333 sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1334 sc_mod(b->value, temp_val, temp_val);
1336 temp_val = (char*)b->value;
1338 sc_shrs(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1339 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1345 tarval *tarval_rot(tarval *a, tarval *b) {
1346 char *temp_val = NULL;
1350 assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1352 if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1353 /* vector arithmetic not implemented yet */
1357 if (get_mode_modulo_shift(a->mode) != 0) {
1358 temp_val = alloca(sc_get_buffer_length());
1360 sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1361 sc_mod(b->value, temp_val, temp_val);
1363 temp_val = (char*)b->value;
1365 sc_rot(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1366 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1370 * carry flag of the last operation
1372 int tarval_carry(void) {
1373 return sc_had_carry();
1379 int tarval_snprintf(char *buf, size_t len, tarval *tv) {
1380 static const tarval_mode_info default_info = { TVO_NATIVE, NULL, NULL };
1384 const tarval_mode_info *mode_info;
1385 const char *prefix, *suffix;
1387 mode_info = tv->mode->tv_priv;
1389 mode_info = &default_info;
1390 prefix = mode_info->mode_prefix ? mode_info->mode_prefix : "";
1391 suffix = mode_info->mode_suffix ? mode_info->mode_suffix : "";
1393 switch (get_mode_sort(tv->mode)) {
1394 case irms_reference:
1395 if (tv == tv->mode->null) return snprintf(buf, len, "NULL");
1397 case irms_int_number:
1398 case irms_character:
1399 switch (mode_info->mode_output) {
1402 str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC, mode_is_signed(tv->mode));
1406 str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT, 0);
1412 str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX, 0);
1415 return snprintf(buf, len, "%s%s%s", prefix, str, suffix);
1417 case irms_float_number:
1418 switch (mode_info->mode_output) {
1420 return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_PACKED), suffix);
1423 return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_HEX), suffix);
1428 return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_DEC), suffix);
1432 case irms_internal_boolean:
1433 switch (mode_info->mode_output) {
1439 return snprintf(buf, len, "%s%c%s", prefix, (tv == tarval_b_true) ? '1' : '0', suffix);
1443 return snprintf(buf, len, "%s%s%s", prefix, (tv == tarval_b_true) ? "true" : "false", suffix);
1446 case irms_control_flow:
1448 case irms_auxiliary:
1449 return snprintf(buf, len, "<TV_OVERFLOW_BAD>");
1456 * Output of tarvals to stdio.
1458 int tarval_printf(tarval *tv) {
1462 res = tarval_snprintf(buf, sizeof(buf), tv);
1463 assert(res < (int) sizeof(buf) && "buffer to small for tarval_snprintf");
1468 char *get_tarval_bitpattern(tarval *tv) {
1470 int n = get_mode_size_bits(tv->mode);
1471 int bytes = (n + 7) / 8;
1472 char *res = xmalloc((n + 1) * sizeof(char));
1475 for(i = 0; i < bytes; i++) {
1476 byte = get_tarval_sub_bits(tv, i);
1477 for(j = 1; j < 256; j <<= 1)
1479 res[pos++] = j & byte ? '1' : '0';
1488 * access to the bitpattern
1490 unsigned char get_tarval_sub_bits(tarval *tv, unsigned byte_ofs) {
1491 switch (get_mode_sort(tv->mode)) {
1492 case irms_int_number:
1493 case irms_character:
1494 return sc_sub_bits(tv->value, tv->length, byte_ofs);
1496 case irms_float_number:
1497 return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
1505 * Specify the output options of one mode.
1507 * This functions stores the modinfo, so DO NOT DESTROY it.
1509 * Returns zero on success.
1511 int set_tarval_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo) {
1514 mode->tv_priv = modeinfo;
1519 * Returns the output options of one mode.
1521 * This functions returns the mode info of a given mode.
1523 const tarval_mode_info *get_tarval_mode_output_option(ir_mode *mode) {
1526 return mode->tv_priv;
1530 * Identifying tarvals values for algebraic simplifications.
1533 * - TV_CLASSIFY_NULL for additive neutral or the NULL tarval for reference modes,
1534 * - TV_CLASSIFY_ONE for multiplicative neutral,
1535 * - TV_CLASSIFY_ALL_ONE for bitwise-and neutral
1536 * - TV_CLASSIFY_OTHER else
1538 tarval_classification_t classify_tarval(tarval *tv) {
1539 if (!tv || tv == tarval_bad) return TV_CLASSIFY_OTHER;
1541 if (tv == get_mode_null(tv->mode))
1542 return TV_CLASSIFY_NULL;
1543 else if (tv == get_mode_one(tv->mode))
1544 return TV_CLASSIFY_ONE;
1545 else if ((get_mode_sort(tv->mode) == irms_int_number)
1546 && (tv == new_tarval_from_long(-1, tv->mode)))
1547 return TV_CLASSIFY_ALL_ONE;
1549 return TV_CLASSIFY_OTHER;
1553 * Returns non-zero if a given (integer) tarval has only one single bit
1556 int is_single_bit_tarval(tarval *tv) {
1560 if (!tv || tv == tarval_bad) return 0;
1561 if (! mode_is_int(tv->mode)) return 0;
1563 l = get_mode_size_bytes(tv->mode);
1564 for (bits = 0, i = l - 1; i >= 0; --i) {
1565 unsigned char v = get_tarval_sub_bits(tv, (unsigned)i);
1567 /* check for more than one bit in these */
1579 * Sets the overflow mode for integer operations.
1581 void tarval_set_integer_overflow_mode(tarval_int_overflow_mode_t ov_mode) {
1582 int_overflow_mode = ov_mode;
1586 * Get the overflow mode for integer operations.
1588 tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void) {
1589 return int_overflow_mode;
1593 * default mode_info for output as HEX
1595 static const tarval_mode_info hex_output = {
1602 * Initialization of the tarval module: called before init_mode()
1604 void init_tarval_1(long null_value) {
1605 _null_value = null_value;
1607 /* initialize the sets holding the tarvals with a comparison function and
1608 * an initial size, which is the expected number of constants */
1609 tarvals = new_set(memcmp, N_CONSTANTS);
1610 values = new_set(memcmp, N_CONSTANTS);
1611 /* init strcalc with precision of 68 to support floating point values with 64
1612 * bit mantissa (needs extra bits for rounding and overflow) */
1618 * Initialization of the tarval module: called after init_mode()
1620 void init_tarval_2(void) {
1621 tarval_bad->kind = k_tarval;
1622 tarval_bad->mode = mode_BAD;
1623 tarval_bad->value = INT_TO_PTR(resid_tarval_bad);
1625 tarval_undefined->kind = k_tarval;
1626 tarval_undefined->mode = mode_ANY;
1627 tarval_undefined->value = INT_TO_PTR(resid_tarval_undefined);
1629 tarval_b_true->kind = k_tarval;
1630 tarval_b_true->mode = mode_b;
1631 tarval_b_true->value = INT_TO_PTR(resid_tarval_b_true);
1633 tarval_b_false->kind = k_tarval;
1634 tarval_b_false->mode = mode_b;
1635 tarval_b_false->value = INT_TO_PTR(resid_tarval_b_false);
1638 * assign output modes that are compatible with the
1639 * old implementation: Hex output
1641 set_tarval_mode_output_option(mode_U, &hex_output);
1642 set_tarval_mode_output_option(mode_C, &hex_output);
1643 set_tarval_mode_output_option(mode_Bs, &hex_output);
1644 set_tarval_mode_output_option(mode_Bu, &hex_output);
1645 set_tarval_mode_output_option(mode_Hs, &hex_output);
1646 set_tarval_mode_output_option(mode_Hu, &hex_output);
1647 set_tarval_mode_output_option(mode_Is, &hex_output);
1648 set_tarval_mode_output_option(mode_Iu, &hex_output);
1649 set_tarval_mode_output_option(mode_Ls, &hex_output);
1650 set_tarval_mode_output_option(mode_Lu, &hex_output);
1651 set_tarval_mode_output_option(mode_P, &hex_output);
1654 /* free all memory occupied by tarval. */
1655 void finish_tarval(void) {
1658 del_set(tarvals); tarvals = NULL;
1659 del_set(values); values = NULL;
1662 /****************************************************************************
1664 ****************************************************************************/