+static const ieee_descriptor_t *get_descriptor(const ir_mode *mode)
+{
+ switch (get_mode_size_bits(mode)) {
+ case 16: return &half_desc;
+ case 32: return &single_desc;
+ case 64: return &double_desc;
+ case 80:
+ case 96:
+ case 128: return &extended_desc; /* FIXME: HACK for x86 where we have
+ sizeof(long double)==16 with 10 byte
+ real payload */
+ /* case 128: return &quad_desc; */
+ default:
+ panic("Unsupported mode in get_descriptor()");
+ }
+}
+
+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);
+}