target values */
#define N_CONSTANTS 2048
-/* get the integer overflow mode */
-#define GET_OVERFLOW_MODE() int_overflow_mode
-
/* unused, float to int doesn't work yet */
-enum float_to_int_mode {
+typedef enum float_to_int_mode {
TRUNCATE,
ROUND
-};
+} float_to_int_mode;
-#define GET_FLOAT_TO_INT_MODE() TRUNCATE
+static float_to_int_mode current_float_to_int_mode = TRUNCATE;
#define SWITCH_NOINFINITY 0
#define SWITCH_NODENORMALS 0
case irms_int_number:
if (sc_comp(value, get_mode_max(mode)->value) == 1) {
- switch (GET_OVERFLOW_MODE()) {
+ switch (tarval_get_integer_overflow_mode()) {
case TV_OVERFLOW_SATURATE:
return get_mode_max(mode);
case TV_OVERFLOW_WRAP:
}
}
if (sc_comp(value, get_mode_min(mode)->value) == -1) {
- switch (GET_OVERFLOW_MODE()) {
+ switch (tarval_get_integer_overflow_mode()) {
case TV_OVERFLOW_SATURATE:
return get_mode_min(mode);
case TV_OVERFLOW_WRAP: {
break;
case irms_float_number:
- if (SWITCH_NOINFINITY && fc_is_inf(value)) {
+#ifdef SWITCH_NOINFINITY
+ if (fc_is_inf(value)) {
/* clip infinity to maximum value */
return fc_is_negative(value) ? get_mode_min(mode) : get_mode_max(mode);
}
+#endif
- if (SWITCH_NODENORMALS && fc_is_subnormal(value)) {
+#ifdef SWITCH_NODENORMALS
+ if (fc_is_subnormal(value)) {
/* clip denormals to zero */
return get_mode_null(mode);
}
+#endif
break;
default:
/* case 128: return &quad_desc; */
default:
panic("Unsupported mode in get_descriptor()");
- return NULL;
}
}
-/*
- * public functions declared in tv.h
- */
+tarval *new_integer_tarval_from_str(const char *str, size_t len, char sign,
+ unsigned char base, ir_mode *mode)
+{
+ void *buffer;
+ int ok;
+
+ buffer = alloca(sc_get_buffer_length());
+
+ ok = sc_val_from_str(sign, base, str, len, buffer);
+ if (!ok)
+ return tarval_bad;
+
+ return get_tarval_overflow(buffer, sc_get_buffer_length(), mode);
+}
+
+static tarval *new_tarval_from_str_int(const char *str, size_t len,
+ ir_mode *mode)
+{
+ void *buffer;
+ unsigned base = 10;
+ char sign = 1;
+ int ok;
+
+ /* skip leading spaces */
+ while (len > 0 && str[0] == ' ') {
+ ++str;
+ --len;
+ }
+ if (len == 0)
+ return tarval_bad;
+
+ /* 1 sign character allowed */
+ if (str[0] == '-') {
+ sign = -1;
+ ++str;
+ --len;
+ } else if (str[0] == '+') {
+ ++str;
+ --len;
+ }
+
+ /* a number starting with '0x' is hexadeciaml,
+ * a number starting with '0' (and at least 1 more char) is octal */
+ if (len >= 2 && str[0] == '0') {
+ if (str[1] == 'x' || str[1] == 'X') {
+ str += 2;
+ len -= 2;
+ base = 16;
+ } else {
+ ++str;
+ --len;
+ base = 8;
+ }
+ }
+ if (len == 0)
+ return tarval_bad;
+
+ buffer = alloca(sc_get_buffer_length());
+
+ ok = sc_val_from_str(sign, base, str, len, buffer);
+ if (!ok)
+ return tarval_bad;
+
+ return get_tarval_overflow(buffer, sc_get_buffer_length(), mode);
+}
/*
* Constructors =============================================================
return get_tarval_null(mode);
/* FALLTHROUGH */
case irms_int_number:
- sc_val_from_str(str, len, NULL, mode);
- return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+ return new_tarval_from_str_int(str, len, mode);
}
panic("Unsupported tarval creation with mode %F", mode);
}
return new_tarval_from_double((long double)l, mode);
default:
- assert(0 && "unsupported mode sort");
+ panic("unsupported mode sort");
}
- return NULL;
}
/* returns non-zero if can be converted to long */
if (a == tarval_bad || b == tarval_bad) {
panic("Comparison with tarval_bad");
- return pn_Cmp_False;
}
if (a == tarval_undefined || b == tarval_undefined)
if (get_mode_n_vector_elems(a->mode) > 1) {
/* vector arithmetic not implemented yet */
- assert(0 && "cmp not implemented for vector modes");
+ panic("cmp not implemented for vector modes");
}
/* Here the two tarvals are unequal and of the same mode */
char *buffer;
fp_value *res;
const ieee_descriptor_t *desc;
+ int len;
carry_flag = -1;
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), dst_mode);
case irms_int_number:
- switch (GET_FLOAT_TO_INT_MODE()) {
+ switch (current_float_to_int_mode) {
case TRUNCATE:
res = fc_int(src->value, NULL);
break;
case ROUND:
res = fc_rnd(src->value, NULL);
break;
- default:
- panic("Unsupported float to int conversion mode in tarval_convert_to()");
- break;
}
buffer = alloca(sc_get_buffer_length());
if (! fc_flt2int(res, buffer, dst_mode))
buffer = alloca(100);
/* decimal string representation because hexadecimal output is
* interpreted unsigned by fc_val_from_str, so this is a HACK */
- snprintf(buffer, 100, "%s",
+ len = snprintf(buffer, 100, "%s",
sc_print(src->value, get_mode_size_bits(src->mode), SC_DEC, mode_is_signed(src->mode)));
buffer[100 - 1] = '\0';
desc = get_descriptor(dst_mode);
- fc_val_from_str(buffer, 0, desc, NULL);
+ fc_val_from_str(buffer, len, desc, NULL);
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), dst_mode);
default:
return tarval_bad;
default:
- assert(0 && "bitwise negation is only allowed for integer and boolean");
- return tarval_bad;
+ panic("bitwise negation is only allowed for integer and boolean");
}
}
return a;
default:
- return tarval_bad;
+ break;
}
return tarval_bad;
}
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
default:
- assert(0 && "operation not defined on mode");
- return tarval_bad;
+ panic("operation not defined on mode");
}
}
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
default:
- assert(0 && "operation not defined on mode");
- return tarval_bad;
+ panic("operation not defined on mode");
}
}
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
default:
- assert(0 && "operation not defined on mode");
- return tarval_bad;
+ panic("operation not defined on mode");
}
}
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
default:
- assert(0 && "operation not defined on mode");
- return tarval_bad;;
+ panic("operation not defined on mode");
}
}