Commit 2210d1a1 authored by Matthias Braun's avatar Matthias Braun
Browse files

assert that no bigger modes are created than the tarval precision limit

The tarval module has a maximally supported precision. Assert that no
modes with higher precision are created, otherwise the tarval module
will silently drop the higher bits on calculation. TODO: Change tarval
module to dynamically use smaller/bigger representations depending on
the mode.

Removed mode_LLs, mode_LLu, mode_Q for now as they are bigger than the
limit.
parent 820f6aee
......@@ -228,7 +228,6 @@ FIRM_API ir_mode *mode_M; /**< memory */
FIRM_API ir_mode *mode_F; /**< ieee754 binary32 float (single precision) */
FIRM_API ir_mode *mode_D; /**< ieee754 binary64 float (double precision) */
FIRM_API ir_mode *mode_Q; /**< ieee754 binary128 float (quadruple precision)*/
FIRM_API ir_mode *mode_Bs; /**< int8 */
FIRM_API ir_mode *mode_Bu; /**< uint8 */
FIRM_API ir_mode *mode_Hs; /**< int16 */
......@@ -237,8 +236,6 @@ FIRM_API ir_mode *mode_Is; /**< int32 */
FIRM_API ir_mode *mode_Iu; /**< uint32 */
FIRM_API ir_mode *mode_Ls; /**< int64 */
FIRM_API ir_mode *mode_Lu; /**< uint64 */
FIRM_API ir_mode *mode_LLs; /**< int128 */
FIRM_API ir_mode *mode_LLu; /**< uint128 */
FIRM_API ir_mode *mode_P; /**< pointer */
FIRM_API ir_mode *mode_P_code; /**< A pointer mode that is set by the client of libfirm. This mode
......@@ -269,8 +266,6 @@ FIRM_API ir_mode *mode_BAD;/**< bad mode */
FIRM_API ir_mode *get_modeF(void);
/** Returns double mode */
FIRM_API ir_mode *get_modeD(void);
/** Returns quadruple prevision mode */
FIRM_API ir_mode *get_modeQ(void);
/** Returns byte signed mode */
FIRM_API ir_mode *get_modeBs(void);
/** Returns byte unsigned mode */
......@@ -287,10 +282,6 @@ FIRM_API ir_mode *get_modeIu(void);
FIRM_API ir_mode *get_modeLs(void);
/** Returns long unsigned mode */
FIRM_API ir_mode *get_modeLu(void);
/** Returns long long signed mode */
FIRM_API ir_mode *get_modeLLs(void);
/** Returns long long unsigned mode */
FIRM_API ir_mode *get_modeLLu(void);
/** Returns pointer mode */
FIRM_API ir_mode *get_modeP(void);
/** Returns internal boolean mode */
......
......@@ -72,6 +72,8 @@ static sparc_isa_t sparc_isa_template = {
NULL, /* constants */
};
ir_mode *sparc_mode_Q;
typedef enum {
cpu_generic,
cpu_v8plus,
......@@ -588,10 +590,17 @@ static const backend_params *sparc_get_backend_params(void)
p.type_long_long = type_long_long;
p.type_unsigned_long_long = type_unsigned_long_long;
ir_type *type_long_double = new_type_primitive(mode_Q);
#if 0
sparc_mode_Q
= new_float_mode("Q", irma_ieee754, 15, 112, ir_overflow_min_max);
ir_type *type_long_double = new_type_primitive(sparc_mode_Q);
set_type_alignment_bytes(type_long_double, 8);
set_type_size_bytes(type_long_double, 16);
#else
ir_type *type_long_double = new_type_primitive(mode_D);
set_type_alignment_bytes(type_long_double, 8);
set_type_size_bytes(type_long_double, 8);
#endif
p.type_long_double = type_long_double;
return &p;
}
......
......@@ -31,6 +31,8 @@ typedef struct sparc_isa_t {
extern const arch_irn_ops_t sparc_irn_ops;
extern ir_mode *sparc_mode_Q;
/**
* SPARC ABI requires some space which is always available at the top of
* the stack. It contains:
......
......@@ -7,7 +7,7 @@ $mode_flags = "mode_Bu";
$mode_fpflags = "mode_Bu";
$mode_fp = "mode_F";
$mode_fp2 = "mode_D";
$mode_fp4 = "mode_Q";
$mode_fp4 = "sparc_mode_Q";
# available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals)
%reg_classes = (
......
......@@ -21,6 +21,7 @@
#include "array.h"
#include "error.h"
#include "pattern_dmp.h"
#include "strcalc.h"
/** Obstack to hold all modes. */
static struct obstack modes;
......@@ -106,7 +107,6 @@ ir_mode *mode_BAD;
ir_mode *mode_F;
ir_mode *mode_D;
ir_mode *mode_Q;
ir_mode *mode_Bs;
ir_mode *mode_Bu;
......@@ -116,8 +116,6 @@ ir_mode *mode_Is;
ir_mode *mode_Iu;
ir_mode *mode_Ls;
ir_mode *mode_Lu;
ir_mode *mode_LLs;
ir_mode *mode_LLu;
ir_mode *mode_b;
ir_mode *mode_P;
......@@ -128,7 +126,6 @@ ir_mode *mode_P_data;
ir_mode *get_modeT(void) { return mode_T; }
ir_mode *get_modeF(void) { return mode_F; }
ir_mode *get_modeD(void) { return mode_D; }
ir_mode *get_modeQ(void) { return mode_Q; }
ir_mode *get_modeBs(void) { return mode_Bs; }
ir_mode *get_modeBu(void) { return mode_Bu; }
ir_mode *get_modeHs(void) { return mode_Hs; }
......@@ -137,8 +134,6 @@ ir_mode *get_modeIs(void) { return mode_Is; }
ir_mode *get_modeIu(void) { return mode_Iu; }
ir_mode *get_modeLs(void) { return mode_Ls; }
ir_mode *get_modeLu(void) { return mode_Lu; }
ir_mode *get_modeLLs(void) { return mode_LLs; }
ir_mode *get_modeLLu(void) { return mode_LLu; }
ir_mode *get_modeb(void) { return mode_b; }
ir_mode *get_modeP(void) { return mode_P; }
ir_mode *get_modeX(void) { return mode_X; }
......@@ -211,6 +206,9 @@ static ir_mode *register_mode(ir_mode *mode)
ir_mode *new_int_mode(const char *name, ir_mode_arithmetic arithmetic,
unsigned bit_size, int sign, unsigned modulo_shift)
{
if (bit_size >= (unsigned)sc_get_precision())
panic("Can't create mode: more bits than tarval module maximum");
ir_mode *result = alloc_mode(name, irms_int_number, arithmetic, bit_size,
sign, modulo_shift);
return register_mode(result);
......@@ -219,6 +217,9 @@ ir_mode *new_int_mode(const char *name, ir_mode_arithmetic arithmetic,
ir_mode *new_reference_mode(const char *name, ir_mode_arithmetic arithmetic,
unsigned bit_size, unsigned modulo_shift)
{
if (bit_size >= (unsigned)sc_get_precision())
panic("Can't create mode: more bits than tarval module maximum");
ir_mode *result = alloc_mode(name, irms_reference, arithmetic, bit_size,
0, modulo_shift);
return register_mode(result);
......@@ -241,6 +242,10 @@ ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic,
panic("Exponents >= 256 bits not supported");
if (mantissa_size >= 256)
panic("Mantissa >= 256 bits not supported");
if (exponent_size >= (unsigned)sc_get_precision())
panic("Can't create mode: more bits than tarval module maximum");
if (mantissa_size >= (unsigned)sc_get_precision())
panic("Can't create mode: more bits than tarval module maximum");
ir_mode *result
= alloc_mode(name, irms_float_number, arithmetic, bit_size, 1, 0);
......@@ -554,7 +559,6 @@ void init_mode(void)
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);
......@@ -564,8 +568,6 @@ void init_mode(void)
mode_Iu = new_int_mode("Iu", irma_twos_complement, 32, 0, 32);
mode_Ls = new_int_mode("Ls", irma_twos_complement, 64, 1, 64);
mode_Lu = new_int_mode("Lu", irma_twos_complement, 64, 0, 64);
mode_LLs = new_int_mode("LLs", irma_twos_complement, 128, 1, 128);
mode_LLu = new_int_mode("LLu", irma_twos_complement, 128, 0, 128);
mode_P = new_reference_mode("P", irma_twos_complement, 32, 32);
set_reference_mode_signed_eq(mode_P, mode_Is);
......
......@@ -47,7 +47,6 @@ static ir_mode *get_ir_mode(unsigned mode_bytes)
case 2: return mode_Hu;
case 4: return mode_Iu;
case 8: return mode_Lu;
case 16: return mode_LLu;
default:
panic("unexpected mode size requested in copyb lowering");
}
......
......@@ -10,6 +10,11 @@ int main(void)
{
ir_init();
ir_mode *big_s = new_int_mode("big signed", irma_twos_complement,
66, 1, 0);
ir_mode *big_u = new_int_mode("big signed", irma_twos_complement,
66, 0, 0);
ir_tarval *ulongmax
= sizeof(long) == 8 ? get_mode_max(mode_Lu)
: sizeof(long) == 4 ? get_mode_max(mode_Iu)
......@@ -17,20 +22,20 @@ int main(void)
assert(tarval_is_long(ulongmax));
ir_tarval *ulongmax_s = tarval_convert_to(ulongmax, mode_Ls);
assert(tarval_is_long(ulongmax_s));
ir_tarval *ulongmax_se = tarval_convert_to(ulongmax_s, mode_LLs);
ir_tarval *ulongmax_se = tarval_convert_to(ulongmax_s, big_s);
assert(tarval_is_long(ulongmax_se));
ir_tarval *ulongmax_z = tarval_convert_to(ulongmax_s, mode_LLu);
ir_tarval *ulongmax_z = tarval_convert_to(ulongmax_s, big_u);
assert(!tarval_is_long(ulongmax_z));
ir_tarval *longmax = new_tarval_from_long(LONG_MAX, mode_LLs);
ir_tarval *longmin = new_tarval_from_long(LONG_MIN, mode_LLs);
ir_tarval *longmax = new_tarval_from_long(LONG_MAX, big_s);
ir_tarval *longmin = new_tarval_from_long(LONG_MIN, big_s);
assert(tarval_is_long(longmin));
assert(tarval_is_long(longmax));
ir_tarval *one = new_tarval_from_long(1, mode_LLs);
ir_tarval *one = new_tarval_from_long(1, big_s);
ir_tarval *longmaxp = tarval_add(longmax, one);
assert(!tarval_is_long(longmaxp));
ir_tarval *longmax3 = tarval_sub(longmaxp, one, mode_LLs);
ir_tarval *longmax3 = tarval_sub(longmaxp, one, big_s);
assert(tarval_is_long(longmax3));
ir_tarval *longmax2 = sizeof(long) == 8 ? get_mode_max(mode_Ls)
......
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