Commit d0d0663d authored by Matthias Braun's avatar Matthias Braun
Browse files

remove per-mode output settings from tarval module

The new design simply lets you specify hex or not in tarval_snprintf.
This is way simpler than the previous machinery and enough for all users in
libfirm.
parent 2a877611
...@@ -596,61 +596,6 @@ FIRM_API ir_tarval *tarval_shrs(ir_tarval *a, ir_tarval *b); ...@@ -596,61 +596,6 @@ FIRM_API ir_tarval *tarval_shrs(ir_tarval *a, ir_tarval *b);
*/ */
FIRM_API ir_tarval *tarval_shrs_unsigned(ir_tarval *a, unsigned b); FIRM_API ir_tarval *tarval_shrs_unsigned(ir_tarval *a, unsigned b);
/**
* The output mode for tarval values.
*
* Some modes allow more that one representation, for instance integers
* can be represented hex or decimal. Of course it would be enough to have
* one and let every backend convert it into the 'right' one.
* However, we can do this in the tarval much simpler...
*/
typedef enum {
TVO_NATIVE, /**< the default output mode, depends on the mode */
TVO_HEX, /**< use hex representation, always possible */
TVO_DECIMAL, /**< use decimal representation */
TVO_OCTAL, /**< use octal representation */
TVO_BINARY, /**< use binary representation */
TVO_FLOAT, /**< use floating point representation (i.e 1.342e-2)*/
TVO_HEXFLOAT /**< use hexadecimal floating point representation
(i.e 0x1.ea32p-12)*/
} tv_output_mode;
/**
* This structure contains helper information to format the output
* of a tarval of a mode.
*/
typedef struct tarval_mode_info {
tv_output_mode mode_output; /**< if != TVO_NATIVE select a special mode */
const char *mode_prefix; /**< if set, this prefix will be printed
before a value of this mode */
const char *mode_suffix; /**< if set, this suffix will be printed
after a value of this mode */
} tarval_mode_info;
/**
* Specify the output options of one mode.
*
* This functions stores the mode info, so DO NOT DESTROY it.
*
* @param mode a ir_mode that should be associated
* @param modeinfo the output format info
*
* @return zero on success.
*/
FIRM_API int set_tarval_mode_output_option(ir_mode *mode,
const tarval_mode_info *modeinfo);
/**
* Returns the output options of one mode.
*
* This functions returns the mode info of a given mode.
*
* @param mode a ir_mode that should be associated
*
* @return the output option
*/
FIRM_API const tarval_mode_info *get_tarval_mode_output_option(ir_mode *mode);
/** /**
* Returns Bit representation of a tarval value, as string of '0' and '1' * Returns Bit representation of a tarval value, as string of '0' and '1'
* *
...@@ -745,8 +690,10 @@ FIRM_API int get_tarval_highest_bit(ir_tarval *tv); ...@@ -745,8 +690,10 @@ FIRM_API int get_tarval_highest_bit(ir_tarval *tv);
* @param buf the output buffer * @param buf the output buffer
* @param buflen the length of the buffer * @param buflen the length of the buffer
* @param tv the tarval * @param tv the tarval
* @param hex print value in hexadecimal if true, else decimal
*/ */
FIRM_API int tarval_snprintf(char *buf, size_t buflen, ir_tarval *tv); FIRM_API int tarval_snprintf(char *buf, size_t buflen, ir_tarval *tv,
int hex);
/** /**
* Output a tarval to stdio. * Output a tarval to stdio.
......
...@@ -163,7 +163,8 @@ static int firm_emit(lc_appendable_t *app, const lc_arg_occ_t *occ, ...@@ -163,7 +163,8 @@ static int firm_emit(lc_appendable_t *app, const lc_arg_occ_t *occ,
if (is_Const(node)) { if (is_Const(node)) {
ir_tarval *tv = get_Const_tarval(node); ir_tarval *tv = get_Const_tarval(node);
if (tv) if (tv)
tarval_snprintf(tv_buf, sizeof(tv_buf), tv); tarval_snprintf(tv_buf, sizeof(tv_buf), tv,
!mode_is_float(get_tarval_mode(tv)));
else else
strncpy(tv_buf, "(NULL)", sizeof(tv_buf)); strncpy(tv_buf, "(NULL)", sizeof(tv_buf));
snprintf(buf, sizeof(buf), "%s%s %s<%s>", A("irn"), get_irn_opname(node), snprintf(buf, sizeof(buf), "%s%s %s<%s>", A("irn"), get_irn_opname(node),
...@@ -196,7 +197,8 @@ static int firm_emit(lc_appendable_t *app, const lc_arg_occ_t *occ, ...@@ -196,7 +197,8 @@ static int firm_emit(lc_appendable_t *app, const lc_arg_occ_t *occ,
} }
case k_tarval: { case k_tarval: {
ir_tarval *tarval = (ir_tarval*)X; ir_tarval *tarval = (ir_tarval*)X;
tarval_snprintf(tv_buf, sizeof(tv_buf), tarval); tarval_snprintf(tv_buf, sizeof(tv_buf), tarval,
!mode_is_float(get_tarval_mode(tarval)));
snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv_buf); snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv_buf);
break; break;
} }
......
...@@ -420,8 +420,9 @@ static void write_tarval(write_env_t *env, ir_tarval *tv) ...@@ -420,8 +420,9 @@ static void write_tarval(write_env_t *env, ir_tarval *tv)
if (tv == tarval_bad) { if (tv == tarval_bad) {
write_symbol(env, "bad"); write_symbol(env, "bad");
} else { } else {
fputs("0x", env->file);
char buf[1024]; char buf[1024];
tarval_snprintf(buf, sizeof(buf), tv); tarval_snprintf(buf, sizeof(buf), tv, true);
fputs(buf, env->file); fputs(buf, env->file);
fputc(' ', env->file); fputc(' ', env->file);
} }
......
...@@ -188,7 +188,6 @@ static ir_mode *alloc_mode(const char *name, ir_mode_sort sort, ...@@ -188,7 +188,6 @@ static ir_mode *alloc_mode(const char *name, ir_mode_sort sort,
mode_tmpl->modulo_shift = modulo_shift; mode_tmpl->modulo_shift = modulo_shift;
mode_tmpl->arithmetic = arithmetic; mode_tmpl->arithmetic = arithmetic;
mode_tmpl->link = NULL; mode_tmpl->link = NULL;
mode_tmpl->tv_priv = NULL;
return mode_tmpl; return mode_tmpl;
} }
......
...@@ -176,7 +176,6 @@ struct ir_mode { ...@@ -176,7 +176,6 @@ struct ir_mode {
ir_mode *eq_signed; /**< For pointer modes, the equivalent signed integer one. */ ir_mode *eq_signed; /**< For pointer modes, the equivalent signed integer one. */
ir_mode *eq_unsigned; /**< For pointer modes, the equivalent unsigned integer one. */ ir_mode *eq_unsigned; /**< For pointer modes, the equivalent unsigned integer one. */
void *link; /**< To store some intermediate information */ void *link; /**< To store some intermediate information */
const void *tv_priv; /**< tarval module will save private data here */
}; };
/* note: we use "long" here because that is the type used for Proj-Numbers */ /* note: we use "long" here because that is the type used for Proj-Numbers */
......
...@@ -1111,55 +1111,44 @@ bool fc_is_subnormal(const fp_value *a) ...@@ -1111,55 +1111,44 @@ bool fc_is_subnormal(const fp_value *a)
return a->clss == FC_SUBNORMAL; return a->clss == FC_SUBNORMAL;
} }
char *fc_print(const fp_value *val, char *buf, int buflen, unsigned base) int fc_print(const fp_value *val, char *buf, int buflen, unsigned base)
{ {
long double flt_val;
switch (base) { switch (base) {
case FC_DEC: case FC_DEC:
switch ((value_class_t)val->clss) { switch ((value_class_t)val->clss) {
case FC_INF: case FC_INF:
snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+'); return snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
break;
case FC_NAN: case FC_NAN:
snprintf(buf, buflen, "NaN"); return snprintf(buf, buflen, "NaN");
break;
case FC_ZERO: case FC_ZERO:
snprintf(buf, buflen, "0.0"); return snprintf(buf, buflen, "0.0");
break; default: {
default: long double flt_val = fc_val_to_ieee754(val);
flt_val = fc_val_to_ieee754(val);
/* XXX 30 is arbitrary */ /* XXX 30 is arbitrary */
snprintf(buf, buflen, "%.30LE", flt_val); return snprintf(buf, buflen, "%.30LE", flt_val);
}
} }
break;
case FC_HEX: case FC_HEX:
switch ((value_class_t)val->clss) { switch ((value_class_t)val->clss) {
case FC_INF: case FC_INF:
snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+'); return snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
break;
case FC_NAN: case FC_NAN:
snprintf(buf, buflen, "NaN"); return snprintf(buf, buflen, "NaN");
break;
case FC_ZERO: case FC_ZERO:
snprintf(buf, buflen, "0.0"); return snprintf(buf, buflen, "0.0");
break; default: {
default: long double flt_val = fc_val_to_ieee754(val);
flt_val = fc_val_to_ieee754(val); return snprintf(buf, buflen, "%LA", flt_val);
snprintf(buf, buflen, "%LA", flt_val); }
} }
break;
case FC_PACKED: case FC_PACKED:
default: { default: {
char *mul_1 = (char*) alloca(calc_buffer_size); char *mul_1 = (char*) alloca(calc_buffer_size);
snprintf(buf, buflen, "%s", sc_print(pack(val, mul_1), value_size*4, SC_HEX, 0)); return snprintf(buf, buflen, "%s", sc_print(pack(val, mul_1), value_size*4, SC_HEX, 0));
buf[buflen - 1] = '\0';
break;
} }
} }
return buf;
} }
unsigned char fc_sub_bits(const fp_value *value, unsigned num_bits, unsigned char fc_sub_bits(const fp_value *value, unsigned num_bits,
......
...@@ -139,7 +139,7 @@ fp_value *fc_neg(const fp_value *a, fp_value *result); ...@@ -139,7 +139,7 @@ fp_value *fc_neg(const fp_value *a, fp_value *result);
fp_value *fc_int(const fp_value *a, fp_value *result); fp_value *fc_int(const fp_value *a, fp_value *result);
fp_value *fc_rnd(const fp_value *a, fp_value *result); fp_value *fc_rnd(const fp_value *a, fp_value *result);
char *fc_print(const fp_value *a, char *buf, int buflen, unsigned base); int fc_print(const fp_value *a, char *buf, int buflen, unsigned base);
/** Compare two values /** Compare two values
* This function compares two values * This function compares two values
......
...@@ -1137,70 +1137,29 @@ ir_tarval *tarval_shrs_unsigned(ir_tarval *a, unsigned b) ...@@ -1137,70 +1137,29 @@ ir_tarval *tarval_shrs_unsigned(ir_tarval *a, unsigned b)
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
} }
int tarval_snprintf(char *buf, size_t len, ir_tarval *tv) int tarval_snprintf(char *buf, size_t len, ir_tarval *tv, int hex)
{ {
static const tarval_mode_info default_info = { TVO_NATIVE, NULL, NULL };
const tarval_mode_info *mode_info
= (const tarval_mode_info*)tv->mode->tv_priv;
if (mode_info == NULL)
mode_info = &default_info;
const char *prefix = mode_info->mode_prefix ? mode_info->mode_prefix : "";
const char *suffix = mode_info->mode_suffix ? mode_info->mode_suffix : "";
const char *str;
switch (get_mode_sort(tv->mode)) { switch (get_mode_sort(tv->mode)) {
case irms_reference: case irms_reference:
if (tv == tv->mode->null) return snprintf(buf, len, "NULL"); if (tv == tv->mode->null)
return snprintf(buf, len, "NULL");
/* FALLTHROUGH */ /* FALLTHROUGH */
case irms_int_number: case irms_int_number: {
switch (mode_info->mode_output) { const char *str;
if (hex)
case TVO_DECIMAL:
str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC, mode_is_signed(tv->mode));
break;
case TVO_OCTAL:
str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT, 0);
break;
case TVO_NATIVE:
prefix = "0x";
case TVO_HEX:
default:
str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX, 0); str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX, 0);
break; else
} str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC, mode_is_signed(tv->mode));
return snprintf(buf, len, "%s%s%s", prefix, str, suffix); return snprintf(buf, len, "%s", str);
case irms_float_number: {
char tv_buf[100];
switch (mode_info->mode_output) {
case TVO_HEX:
return snprintf(buf, len, "%s%s%s", prefix, fc_print((const fp_value*) tv->value, tv_buf, sizeof(tv_buf), FC_PACKED), suffix);
case TVO_HEXFLOAT:
return snprintf(buf, len, "%s%s%s", prefix, fc_print((const fp_value*) tv->value, tv_buf, sizeof(tv_buf), FC_HEX), suffix);
case TVO_FLOAT:
case TVO_NATIVE:
default:
return snprintf(buf, len, "%s%s%s", prefix, fc_print((const fp_value*) tv->value, tv_buf, sizeof(tv_buf), FC_DEC), suffix);
}
} }
case irms_internal_boolean: case irms_float_number:
switch (mode_info->mode_output) { return fc_print((const fp_value*)tv->value, buf, len,
hex ? FC_HEX : FC_DEC);
case TVO_DECIMAL:
case TVO_OCTAL:
case TVO_HEX:
case TVO_BINARY:
return snprintf(buf, len, "%s%c%s", prefix, (tv == tarval_b_true) ? '1' : '0', suffix);
case TVO_NATIVE: case irms_internal_boolean:
default: return snprintf(buf, len, "%s",
return snprintf(buf, len, "%s%s%s", prefix, (tv == tarval_b_true) ? "true" : "false", suffix); (tv == tarval_b_true) ? "true" : "false");
}
default: default:
if (tv == tarval_bad) if (tv == tarval_bad)
...@@ -1219,8 +1178,9 @@ int tarval_snprintf(char *buf, size_t len, ir_tarval *tv) ...@@ -1219,8 +1178,9 @@ int tarval_snprintf(char *buf, size_t len, ir_tarval *tv)
int tarval_printf(ir_tarval *tv) int tarval_printf(ir_tarval *tv)
{ {
char buf[1024]; char buf[1024];
int res = tarval_snprintf(buf, sizeof(buf), tv); int res = tarval_snprintf(buf, sizeof(buf), tv,
assert(res < (int) sizeof(buf) && "buffer to small for tarval_snprintf"); !mode_is_float(get_tarval_mode(tv)));
assert(res >= (int) sizeof(buf) && "buffer to small for tarval_snprintf");
printf("%s", buf); printf("%s", buf);
return res; return res;
} }
...@@ -1254,17 +1214,6 @@ unsigned char get_tarval_sub_bits(ir_tarval *tv, unsigned byte_ofs) ...@@ -1254,17 +1214,6 @@ unsigned char get_tarval_sub_bits(ir_tarval *tv, unsigned byte_ofs)
} }
} }
int set_tarval_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo)
{
mode->tv_priv = modeinfo;
return 0;
}
const tarval_mode_info *get_tarval_mode_output_option(ir_mode *mode)
{
return (const tarval_mode_info*) mode->tv_priv;
}
int tarval_is_single_bit(ir_tarval *tv) int tarval_is_single_bit(ir_tarval *tv)
{ {
if (!mode_is_int(tv->mode)) if (!mode_is_int(tv->mode))
...@@ -1396,15 +1345,6 @@ tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void) ...@@ -1396,15 +1345,6 @@ tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void)
return int_overflow_mode; return int_overflow_mode;
} }
/**
* default mode_info for output as HEX
*/
static const tarval_mode_info hex_output = {
TVO_HEX,
"0x",
NULL,
};
void init_tarval_1(long null_value, int support_quad_precision) void init_tarval_1(long null_value, int support_quad_precision)
{ {
_null_value = null_value; _null_value = null_value;
...@@ -1436,20 +1376,6 @@ void init_tarval_2(void) ...@@ -1436,20 +1376,6 @@ void init_tarval_2(void)
tarval_reachable->kind = k_tarval; tarval_reachable->kind = k_tarval;
tarval_reachable->mode = mode_X; tarval_reachable->mode = mode_X;
/*
* assign output modes that are compatible with the
* old implementation: Hex output
*/
set_tarval_mode_output_option(mode_Bs, &hex_output);
set_tarval_mode_output_option(mode_Bu, &hex_output);
set_tarval_mode_output_option(mode_Hs, &hex_output);
set_tarval_mode_output_option(mode_Hu, &hex_output);
set_tarval_mode_output_option(mode_Is, &hex_output);
set_tarval_mode_output_option(mode_Iu, &hex_output);
set_tarval_mode_output_option(mode_Ls, &hex_output);
set_tarval_mode_output_option(mode_Lu, &hex_output);
set_tarval_mode_output_option(mode_P, &hex_output);
} }
void finish_tarval(void) void finish_tarval(void)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment