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);
*/
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'
*
......@@ -745,8 +690,10 @@ FIRM_API int get_tarval_highest_bit(ir_tarval *tv);
* @param buf the output buffer
* @param buflen the length of the buffer
* @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.
......
......@@ -163,7 +163,8 @@ static int firm_emit(lc_appendable_t *app, const lc_arg_occ_t *occ,
if (is_Const(node)) {
ir_tarval *tv = get_Const_tarval(node);
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
strncpy(tv_buf, "(NULL)", sizeof(tv_buf));
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,
}
case k_tarval: {
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);
break;
}
......
......@@ -420,8 +420,9 @@ static void write_tarval(write_env_t *env, ir_tarval *tv)
if (tv == tarval_bad) {
write_symbol(env, "bad");
} else {
fputs("0x", env->file);
char buf[1024];
tarval_snprintf(buf, sizeof(buf), tv);
tarval_snprintf(buf, sizeof(buf), tv, true);
fputs(buf, env->file);
fputc(' ', env->file);
}
......
......@@ -188,7 +188,6 @@ static ir_mode *alloc_mode(const char *name, ir_mode_sort sort,
mode_tmpl->modulo_shift = modulo_shift;
mode_tmpl->arithmetic = arithmetic;
mode_tmpl->link = NULL;
mode_tmpl->tv_priv = NULL;
return mode_tmpl;
}
......
......@@ -176,7 +176,6 @@ struct ir_mode {
ir_mode *eq_signed; /**< For pointer modes, the equivalent signed integer one. */
ir_mode *eq_unsigned; /**< For pointer modes, the equivalent unsigned integer one. */
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 */
......
......@@ -1111,55 +1111,44 @@ bool fc_is_subnormal(const fp_value *a)
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) {
case FC_DEC:
switch ((value_class_t)val->clss) {
case FC_INF:
snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
break;
return snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
case FC_NAN:
snprintf(buf, buflen, "NaN");
break;
return snprintf(buf, buflen, "NaN");
case FC_ZERO:
snprintf(buf, buflen, "0.0");
break;
default:
flt_val = fc_val_to_ieee754(val);
return snprintf(buf, buflen, "0.0");
default: {
long double flt_val = fc_val_to_ieee754(val);
/* XXX 30 is arbitrary */
snprintf(buf, buflen, "%.30LE", flt_val);
return snprintf(buf, buflen, "%.30LE", flt_val);
}
}
break;
case FC_HEX:
switch ((value_class_t)val->clss) {
case FC_INF:
snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
break;
return snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
case FC_NAN:
snprintf(buf, buflen, "NaN");
break;
return snprintf(buf, buflen, "NaN");
case FC_ZERO:
snprintf(buf, buflen, "0.0");
break;
default:
flt_val = fc_val_to_ieee754(val);
snprintf(buf, buflen, "%LA", flt_val);
return snprintf(buf, buflen, "0.0");
default: {
long double flt_val = fc_val_to_ieee754(val);
return snprintf(buf, buflen, "%LA", flt_val);
}
}
break;
case FC_PACKED:
default: {
char *mul_1 = (char*) alloca(calc_buffer_size);
snprintf(buf, buflen, "%s", sc_print(pack(val, mul_1), value_size*4, SC_HEX, 0));
buf[buflen - 1] = '\0';
break;
return snprintf(buf, buflen, "%s", sc_print(pack(val, mul_1), value_size*4, SC_HEX, 0));
}
}
return buf;
}
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);
fp_value *fc_int(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
* This function compares two values
......
......@@ -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);
}
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)) {
case irms_reference:
if (tv == tv->mode->null) return snprintf(buf, len, "NULL");
if (tv == tv->mode->null)
return snprintf(buf, len, "NULL");
/* FALLTHROUGH */
case irms_int_number:
switch (mode_info->mode_output) {
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:
case irms_int_number: {
const char *str;
if (hex)
str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX, 0);
break;
}
return snprintf(buf, len, "%s%s%s", prefix, str, suffix);
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);
}
else
str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC, mode_is_signed(tv->mode));
return snprintf(buf, len, "%s", str);
}
case irms_internal_boolean:
switch (mode_info->mode_output) {
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 irms_float_number:
return fc_print((const fp_value*)tv->value, buf, len,
hex ? FC_HEX : FC_DEC);
case TVO_NATIVE:
default:
return snprintf(buf, len, "%s%s%s", prefix, (tv == tarval_b_true) ? "true" : "false", suffix);
}
case irms_internal_boolean:
return snprintf(buf, len, "%s",
(tv == tarval_b_true) ? "true" : "false");
default:
if (tv == tarval_bad)
......@@ -1219,8 +1178,9 @@ int tarval_snprintf(char *buf, size_t len, ir_tarval *tv)
int tarval_printf(ir_tarval *tv)
{
char buf[1024];
int res = tarval_snprintf(buf, sizeof(buf), tv);
assert(res < (int) sizeof(buf) && "buffer to small for tarval_snprintf");
int res = tarval_snprintf(buf, sizeof(buf), tv,
!mode_is_float(get_tarval_mode(tv)));
assert(res >= (int) sizeof(buf) && "buffer to small for tarval_snprintf");
printf("%s", buf);
return res;
}
......@@ -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)
{
if (!mode_is_int(tv->mode))
......@@ -1396,15 +1345,6 @@ tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void)
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)
{
_null_value = null_value;
......@@ -1436,20 +1376,6 @@ void init_tarval_2(void)
tarval_reachable->kind = k_tarval;
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)
......
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