Commit 5baaf58d authored by Matthias Braun's avatar Matthias Braun
Browse files

record float->int conversion overflow semantics in mode

parent b7a411f5
......@@ -15,6 +15,7 @@
#include "irarch.h"
#include "lowering.h"
#include "iroptimize.h"
#include "irmode.h"
#include "begin.h"
/**
......@@ -152,6 +153,9 @@ typedef struct backend_params {
/** Alignment of stack parameters */
unsigned stack_param_align;
/** Semantic on float->int conversion overflow. */
float_int_conversion_overflow_style_t float_int_overflow;
} backend_params;
/**
......
......@@ -46,6 +46,18 @@ typedef enum ir_mode_arithmetic {
irma_last = irma_x86_extended_float,
} ir_mode_arithmetic;
/**
* Specifies what happens when a float value is converted to an integer and
* overflow happens.
*/
typedef enum float_int_conversion_overflow_style_t {
ir_overflow_indefinite, /**< the integer indefinite value (=INT_MIN) is
returned. (e.g. x86 does this) */
ir_overflow_min_max, /**< INT_MIN/INT_MAX is returned depending on the
sign of the floatingpoint number. (e.g. sparc
does this). */
} float_int_conversion_overflow_style_t;
/**
* Creates a new mode.
*
......@@ -86,11 +98,14 @@ FIRM_API ir_mode *new_reference_mode(const char *name,
* @param exponent_size size of exponent in bits
* @param mantissa_size size of mantissa in bits (number of bits after the
* leading one).
* @param int_conv_overflow Semantic on float to integer conversion overflow.
*/
FIRM_API ir_mode *new_float_mode(const char *name,
ir_mode_arithmetic arithmetic,
unsigned exponent_size,
unsigned mantissa_size);
unsigned mantissa_size,
float_int_conversion_overflow_style_t
int_conv_overflow);
/**
* Creates a new mode for data values which are not used to perform arithmetic.
......@@ -421,6 +436,12 @@ FIRM_API unsigned get_mode_mantissa_size(const ir_mode *mode);
*/
FIRM_API unsigned get_mode_exponent_size(const ir_mode *mode);
/**
* Returns semantic on float to integer conversion overflow.
*/
FIRM_API float_int_conversion_overflow_style_t get_mode_float_int_overflow(
const ir_mode *mode);
/**
* Returns non-zero if the cast from mode src to mode dst is a
* reinterpret cast (i.e. only the bit pattern is reinterpreted,
......
......@@ -260,7 +260,8 @@ static const backend_params *TEMPLATE_get_backend_params(void)
0, /* no trampoline support: size 0 */
0, /* no trampoline support: align 0 */
NULL, /* no trampoline support: no trampoline builder */
4 /* alignment of stack parameter: typically 4 (32bit) or 8 (64bit) */
4, /* alignment of stack parameter: typically 4 (32bit) or 8 (64bit) */
ir_overflow_min_max
};
return &p;
}
......
......@@ -550,7 +550,8 @@ static const backend_params *amd64_get_backend_params(void) {
0, /* no trampoline support: size 0 */
0, /* no trampoline support: align 0 */
NULL, /* no trampoline support: no trampoline builder */
8 /* alignment of stack parameter: typically 4 (32bit) or 8 (64bit) */
8, /* alignment of stack parameter: typically 4 (32bit) or 8 (64bit) */
ir_overflow_indefinite
};
return &p;
}
......
......@@ -431,7 +431,8 @@ static const backend_params *arm_get_libfirm_params(void)
0, /* no trampoline support: size 0 */
0, /* no trampoline support: align 0 */
NULL, /* no trampoline support: no trampoline builder */
4 /* alignment of stack parameter */
4, /* alignment of stack parameter */
ir_overflow_min_max
};
return &p;
......
......@@ -1427,7 +1427,8 @@ static backend_params ia32_backend_params = {
12, /* size of trampoline code */
4, /* alignment of trampoline code */
ia32_create_trampoline_fkt,
4 /* alignment of stack parameter */
4, /* alignment of stack parameter */
ir_overflow_indefinite
};
/**
......@@ -1449,14 +1450,17 @@ static void ia32_init(void)
/* note mantissa is 64bit but with explicitely encoded 1 so the really
* usable part as counted by firm is only 63 bits */
ia32_mode_E = new_float_mode("E", irma_x86_extended_float, 15, 63);
ia32_mode_E = new_float_mode("E", irma_x86_extended_float, 15, 63,
ir_overflow_indefinite);
ia32_type_E = new_type_primitive(ia32_mode_E);
set_type_size_bytes(ia32_type_E, 12);
set_type_alignment_bytes(ia32_type_E, 4);
ia32_mode_gp = new_int_mode("gp", irma_twos_complement, 32, 0, 32);
ia32_mode_float64 = new_float_mode("fp64", irma_ieee754, 11, 52);
ia32_mode_float32 = new_float_mode("fp32", irma_ieee754, 8, 23);
ia32_mode_float64 = new_float_mode("fp64", irma_ieee754, 11, 52,
ir_overflow_indefinite);
ia32_mode_float32 = new_float_mode("fp32", irma_ieee754, 8, 23,
ir_overflow_indefinite);
mode_long_long = new_int_mode("long long", irma_twos_complement, 64, 1, 64);
type_long_long = new_type_primitive(mode_long_long);
......
......@@ -573,7 +573,8 @@ static const backend_params *sparc_get_backend_params(void)
0, /* no trampoline support: size 0 */
0, /* no trampoline support: align 0 */
NULL, /* no trampoline support: no trampoline builder */
4 /* alignment of stack parameter: typically 4 (32bit) or 8 (64bit) */
4, /* alignment of stack parameter: typically 4 (32bit) or 8 (64bit) */
ir_overflow_min_max
};
ir_mode *mode_long_long
......
......@@ -1001,6 +1001,7 @@ static void write_mode(write_env_t *env, ir_mode *mode)
write_mode_arithmetic(env, get_mode_arithmetic(mode));
write_unsigned(env, get_mode_exponent_size(mode));
write_unsigned(env, get_mode_mantissa_size(mode));
write_unsigned(env, get_mode_float_int_overflow(mode));
} else {
panic("Can't write internal modes");
}
......@@ -2276,7 +2277,10 @@ static void read_modes(read_env_t *env)
ir_mode_arithmetic arith = read_mode_arithmetic(env);
int exponent_size = read_long(env);
int mantissa_size = read_long(env);
new_float_mode(name, arith, exponent_size, mantissa_size);
float_int_conversion_overflow_style_t overflow =
(float_int_conversion_overflow_style_t)read_long(env);
new_float_mode(name, arith, exponent_size, mantissa_size,
overflow);
break;
}
......
......@@ -34,10 +34,11 @@ static bool modes_are_equal(const ir_mode *m, const ir_mode *n)
return false;
if (m->sort == irms_auxiliary || m->sort == irms_data)
return strcmp(m->name, n->name) == 0;
return m->arithmetic == n->arithmetic &&
m->size == n->size &&
m->sign == n->sign &&
m->modulo_shift == n->modulo_shift;
return m->arithmetic == n->arithmetic
&& m->size == n->size
&& m->sign == n->sign
&& m->modulo_shift == n->modulo_shift
&& m->int_conv_overflow == n->int_conv_overflow;
}
/**
......@@ -224,7 +225,8 @@ ir_mode *new_reference_mode(const char *name, ir_mode_arithmetic arithmetic,
}
ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic,
unsigned exponent_size, unsigned mantissa_size)
unsigned exponent_size, unsigned mantissa_size,
float_int_conversion_overflow_style_t conv_overflow)
{
bool explicit_one = false;
unsigned bit_size = exponent_size + mantissa_size + 1;
......@@ -242,6 +244,7 @@ ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic,
ir_mode *result
= alloc_mode(name, irms_float_number, arithmetic, bit_size, 1, 0);
result->int_conv_overflow = conv_overflow;
result->float_desc.exponent_size = exponent_size;
result->float_desc.mantissa_size = mantissa_size;
result->float_desc.explicit_one = explicit_one;
......@@ -406,6 +409,12 @@ unsigned (get_mode_exponent_size)(const ir_mode *mode)
return get_mode_exponent_size_(mode);
}
float_int_conversion_overflow_style_t get_mode_float_int_overflow(
const ir_mode *mode)
{
return mode->int_conv_overflow;
}
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
assert(sm != NULL);
......@@ -543,9 +552,9 @@ void init_mode(void)
mode_b = alloc_mode("b", irms_internal_boolean, irma_none, 0, 0, 0);
mode_b = register_mode(mode_b);
mode_F = new_float_mode("F", irma_ieee754, 8, 23);
mode_D = new_float_mode("D", irma_ieee754, 11, 52);
mode_Q = new_float_mode("Q", irma_ieee754, 15, 112);
mode_F = new_float_mode("F", irma_ieee754, 8, 23, ir_overflow_min_max);
mode_D = new_float_mode("D", irma_ieee754, 11, 52, ir_overflow_min_max);
mode_Q = new_float_mode("Q", irma_ieee754, 15, 112, ir_overflow_min_max);
mode_Bs = new_int_mode("Bs", irma_twos_complement, 8, 1, 32);
mode_Bu = new_int_mode("Bu", irma_twos_complement, 8, 0, 32);
......
......@@ -151,8 +151,10 @@ struct ir_mode {
(see irmode.h) */
ir_mode_arithmetic arithmetic; /**< different arithmetic operations possible with a mode */
unsigned size; /**< size of the mode in Bits. */
unsigned sign:1; /**< signedness of this mode */
unsigned int modulo_shift; /**< number of bits a values of this mode will be shifted */
bool sign:1; /**< signedness of this mode */
ENUMBF(float_int_conversion_overflow_style_t)
int_conv_overflow:1;
unsigned char modulo_shift; /**< number of bits a values of this mode will be shifted */
float_descriptor_t float_desc;
/* ---------------------------------------------------------------------- */
......
......@@ -731,7 +731,13 @@ ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
flt2int_result_t cres = fc_flt2int(res, buffer, dst_mode);
switch (cres) {
case FLT2INT_POSITIVE_OVERFLOW:
return get_mode_max(dst_mode);
switch (get_mode_float_int_overflow(src->mode)) {
case ir_overflow_indefinite:
return get_mode_min(dst_mode);
case ir_overflow_min_max:
return get_mode_max(dst_mode);
}
break;
case FLT2INT_NEGATIVE_OVERFLOW:
return get_mode_min(dst_mode);
case FLT2INT_UNKNOWN:
......
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