void (*_hook_arch_dep_replace_division_by_const)(void *context, ir_node *irn);
/** This hook is called after a new mode was registered. */
- void (*_hook_new_mode)(void *context, const ir_mode *tmpl, ir_mode *mode);
+ void (*_hook_new_mode)(void *context, ir_mode *mode);
/** This hook is called after a new entity was created. */
void (*_hook_new_entity)(void *context, ir_entity *ent);
hook_exec(hook_arch_dep_replace_mul_with_shifts, (hook_ctx_, irn))
#define hook_arch_dep_replace_division_by_const(irn) \
hook_exec(hook_arch_dep_replace_division_by_const, (hook_ctx_, irn))
-#define hook_new_mode(tmpl, mode) hook_exec(hook_new_mode, (hook_ctx_, tmpl, mode))
+#define hook_new_mode(mode) hook_exec(hook_new_mode, (hook_ctx_, mode))
#define hook_new_entity(ent) hook_exec(hook_new_entity, (hook_ctx_, ent))
#define hook_new_type(tp) hook_exec(hook_new_type, (hook_ctx_, tp))
#define hook_node_info(F, node) hook_exec(hook_node_info, (hook_ctx_, F, node))
#include "firm_types.h"
#include "begin.h"
-/** Helper values for ir_mode_sort. */
-enum ir_mode_sort_helper {
- irmsh_is_num = 0x10, /**< mode represents a number */
- irmsh_is_data = 0x20, /**< mode represents data (can be carried in registers) */
- irmsh_is_datab = 0x40, /**< mode represents data or is internal boolean */
- irmsh_is_dataM = 0x80, /**< mode represents data or is memory */
-};
-
-/**
- * These values represent the different mode classes of value representations.
- * Beware: do not change the order of these values without checking
- * the mode_is
- */
-typedef enum ir_mode_sort {
- irms_auxiliary = 0, /**< Only for Firm use. Not extensible. (irm_T) */
- irms_control_flow = 1, /**< Marks all control flow modes. Not extensible. (irm_BB, irm_X) */
- irms_memory = 2 | irmsh_is_dataM, /**< Marks the memory mode. Not extensible. (irm_M) */
-
- /** Internal boolean representation.
- Storing to memory impossible, convert first. (irm_b) */
- irms_internal_boolean = 3 | irmsh_is_datab,
-
- /** A mode to represent entities.
- Restricted int computations can be performed */
- irms_reference = 4 | irmsh_is_data | irmsh_is_datab | irmsh_is_dataM,
- /** A mode to represent int numbers.
- Integer computations can be performed. */
- irms_int_number = 5 | irmsh_is_data | irmsh_is_datab | irmsh_is_dataM | irmsh_is_num,
- /** A mode to represent float numbers.
- Floating point computations can be performed. */
- irms_float_number = 6 | irmsh_is_data | irmsh_is_datab | irmsh_is_dataM | irmsh_is_num,
-} ir_mode_sort;
-
/**
* These values represent the different arithmetic operations possible with a
* mode.
irma_ieee754 = 256, /**< Values of the mode are represented according
to ieee754 floating point standard. Only
legal for modes of sort float_number. */
+ irma_x86_extended_float, /**< x86 extended floatingpoint values */
irma_max
} ir_mode_arithmetic;
* This function constructs a new mode given by the parameters.
* If the parameters match an already defined mode, this mode is returned
* (including the default modes).
- * If the mode is newly allocated, a new unique mode_code is chosen.
- * Also, special value tarvals will be calculated such as null,
- * min, max and can be retrieved using the get_mode_* functions
*
* @return
* The new mode or NULL on error.
+ */
+FIRM_API ir_mode *new_int_mode(const char *name,
+ ir_mode_arithmetic arithmetic,
+ unsigned bit_size, int sign,
+ unsigned modulo_shift);
+
+/**
+ * Create a new reference mode.
+ *
+ * Reference modes are always unsigned.
+ */
+FIRM_API ir_mode *new_reference_mode(const char *name,
+ ir_mode_arithmetic arithmetic,
+ unsigned bit_size,
+ unsigned modulo_shift);
+
+/**
+ * Create a new ieee754 float mode.
*
- * @note
- * It is allowed to construct the default modes. So, a call
- * new_ir_mode("Is", irms_int_number, 32, 1, irma_twos_complement, 32) will
- * return mode_Is.
+ * float-modes are always signed and have no modulo shift.
+ * @param name the name of the mode to be created
+ * @param arithmetic arithmetic/representation of the mode
+ * @param exponent_size size of exponent in bits
+ * @param mantissa_size size of mantissa in bits
*/
-FIRM_API ir_mode *new_ir_mode(const char *name, ir_mode_sort sort, int bit_size,
- int sign, ir_mode_arithmetic arithmetic,
- unsigned int modulo_shift);
+FIRM_API ir_mode *new_float_mode(const char *name,
+ ir_mode_arithmetic arithmetic,
+ unsigned exponent_size,
+ unsigned mantissa_size);
/**
* Checks whether a pointer points to a mode.
/** Returns the null-terminated name of this mode. */
FIRM_API const char *get_mode_name(const ir_mode *mode);
-/** Returns a coarse classification of the mode. */
-FIRM_API ir_mode_sort get_mode_sort(const ir_mode *mode);
-
/** Returns the size of values of the mode in bits. */
FIRM_API unsigned get_mode_size_bits(const ir_mode *mode);
FIRM_API ir_mode *mode_M; /**< memory */
-FIRM_API ir_mode *mode_F; /**< float (32) */
-FIRM_API ir_mode *mode_D; /**< double (64) */
-FIRM_API ir_mode *mode_E; /**< long double (80/128/...) */
+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 */
FIRM_API ir_mode *get_modeF(void);
FIRM_API ir_mode *get_modeD(void);
-FIRM_API ir_mode *get_modeE(void);
+FIRM_API ir_mode *get_modeQ(void);
FIRM_API ir_mode *get_modeBs(void);
FIRM_API ir_mode *get_modeBu(void);
FIRM_API ir_mode *get_modeHs(void);
*/
FIRM_API void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode);
+/**
+ * Return size of mantissa in bits (for float modes)
+ */
+FIRM_API unsigned get_mode_mantissa_size(const ir_mode *mode);
+
+/**
+ * Return size of exponent in bits (for float modes)
+ */
+FIRM_API unsigned get_mode_exponent_size(const ir_mode *mode);
+
/**
* Returns non-zero if the cast from mode src to mode dst is a
* reinterpret cast (ie. only the bit pattern is reinterpreted,
FIRM_API int tarval_printf(ir_tarval *tv);
/**
- * Returns non-zero if the mantissa of a floating point IEEE-754
- * tarval is zero (i.e. 1.0Exxx)
+ * Returns non-zero if the mantissa of a floating point tarval is zero
+ * (i.e. 1.0Exxx)
*
* @param tv the tarval
*/
-FIRM_API int tarval_ieee754_zero_mantissa(ir_tarval *tv);
+FIRM_API int tarval_zero_mantissa(ir_tarval *tv);
/**
* Returns the exponent of a floating point IEEE-754
*
* @param tv the tarval
*/
-FIRM_API int tarval_ieee754_get_exponent(ir_tarval *tv);
+FIRM_API int tarval_get_exponent(ir_tarval *tv);
/**
* Check if the tarval can be converted to the given mode without
FIRM_API int tarval_ieee754_can_conv_lossless(ir_tarval *tv, ir_mode *mode);
/**
- * Returns non-zero if the result of the last IEEE-754 operation was exact.
+ * Returns non-zero if the result of the last IEEE-754 operation was exact.
*/
FIRM_API unsigned tarval_ieee754_get_exact(void);
-/**
- * Return the size of the mantissa in bits (including possible
- * implicit bits) for the given mode.
- */
-FIRM_API unsigned tarval_ieee754_get_mantissa_size(const ir_mode *mode);
-
/**
* Enable/Disable floating point constant folding.
*/
if (ent_mode != mode) {
if (ent_mode == NULL ||
get_mode_size_bits(ent_mode) != get_mode_size_bits(mode) ||
- get_mode_sort(ent_mode) != get_mode_sort(mode) ||
get_mode_arithmetic(ent_mode) != irma_twos_complement ||
get_mode_arithmetic(mode) != irma_twos_complement)
return true;
# Modes
#
$mode_gp = "mode_Iu"; # mode used by general purpose registers
-$mode_fp = "mode_E"; # mode used by floatingpoint registers
+$mode_fp = "mode_F"; # mode used by floatingpoint registers
# The node description is done as a perl hash initializer with the
# following structure:
#
$mode_gp = "mode_Iu";
$mode_flags = "mode_Bu";
-$mode_fp = "mode_E";
+$mode_fp = "mode_F";
# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
%reg_classes = (
if (USE_FPA(isa)) {
return new_bd_arm_Adf(dbgi, block, new_op1, new_op2, mode);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
if (USE_FPA(isa)) {
return new_bd_arm_Muf(dbg, block, new_op1, new_op2, mode);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
ir_mode *mode = get_Div_resmode(node);
dbg_info *dbg = get_irn_dbg_info(node);
- assert(mode != mode_E && "IEEE Extended FP not supported");
/* integer division should be replaced by builtin call */
assert(mode_is_float(mode));
if (USE_FPA(isa)) {
return new_bd_arm_Dvf(dbg, block, new_op1, new_op2, mode);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
if (USE_FPA(isa)) {
return new_bd_arm_Suf(dbgi, block, new_op1, new_op2, mode);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
if (USE_FPA(isa)) {
return new_bd_arm_Mvf(dbgi, block, op, mode);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
new_load = new_bd_arm_Ldf(dbgi, block, new_ptr, new_mem, mode,
NULL, 0, 0, false);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
new_store = new_bd_arm_Stf(dbgi, block, new_ptr, new_val,
new_mem, mode, NULL, 0, 0, false);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
enum fpa_imm_mode {
FPA_IMM_FLOAT = 0,
FPA_IMM_DOUBLE = 1,
- FPA_IMM_EXTENDED = 2,
- FPA_IMM_MAX = FPA_IMM_EXTENDED
+ FPA_IMM_MAX = FPA_IMM_DOUBLE
};
static ir_tarval *fpa_imm[FPA_IMM_MAX + 1][fpa_max];
case 64:
i = FPA_IMM_DOUBLE;
break;
- default:
- i = FPA_IMM_EXTENDED;
}
if (tarval_is_negative(tv)) {
node = new_bd_arm_fConst(dbg, block, tv);
return node;
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
fpa_imm[FPA_IMM_DOUBLE][fpa_five] = new_tarval_from_str("5", 1, mode_D);
fpa_imm[FPA_IMM_DOUBLE][fpa_ten] = new_tarval_from_str("10", 2, mode_D);
fpa_imm[FPA_IMM_DOUBLE][fpa_half] = new_tarval_from_str("0.5", 3, mode_D);
-
- fpa_imm[FPA_IMM_EXTENDED][fpa_null] = get_mode_null(mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_one] = get_mode_one(mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_two] = new_tarval_from_str("2", 1, mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_three] = new_tarval_from_str("3", 1, mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_four] = new_tarval_from_str("4", 1, mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_five] = new_tarval_from_str("5", 1, mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_ten] = new_tarval_from_str("10", 2, mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_half] = new_tarval_from_str("0.5", 3, mode_E);
}
/**
ir_type *frame_type;
mode_gp = mode_Iu;
- mode_fp = mode_E;
+ mode_fp = mode_F;
if (! imm_initialized) {
arm_init_fpa_immediate();
* @param tv the tarval
* @param bytes the width of the tarvals value in bytes
*/
-static void emit_arith_tarval(ir_tarval *tv, int bytes)
+static void emit_arith_tarval(ir_tarval *tv, unsigned bytes)
{
switch (bytes) {
case 1:
return;
case 2:
- be_emit_irprintf("0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
+ be_emit_irprintf("0x%02x%02x",
+ get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
return;
case 4:
be_emit_irprintf("0x%02x%02x%02x%02x",
- get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
+ get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
+ get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
return;
case 8:
be_emit_irprintf("0x%02x%02x%02x%02x%02x%02x%02x%02x",
- get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
- get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
- return;
-
- case 12:
- /* Beware: Mixed endian output! One little endian number emitted as
- * three longs. Each long initializer is written in big endian. */
- be_emit_irprintf(
- "\t.long\t0x%02x%02x%02x%02x\n"
- "\t.long\t0x%02x%02x%02x%02x\n"
- "\t.long\t0x%02x%02x%02x%02x",
- get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
- get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0),
- get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
- get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
- get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
- get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8)
- );
- return;
-
- case 16:
- /* Beware: Mixed endian output! One little endian number emitted as
- * three longs. Each long initializer is written in big endian. */
- be_emit_irprintf(
- "\t.long\t0x%02x%02x%02x%02x\n"
- "\t.long\t0x%02x%02x%02x%02x\n"
- "\t.long\t0x%02x%02x%02x%02x\n"
- "\t.long\t0x%02x%02x%02x%02x",
- get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
- get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0),
- get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
- get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
- get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
- get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
- get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 14),
- get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12)
- );
+ get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
+ get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
+ get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
+ get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
return;
}
* @param env the gas output environment
* @param init a node representing the atomic value (on the const code irg)
*/
-static void do_emit_atomic_init(be_gas_decl_env_t *env, ir_node *init)
+static void emit_init_expression(be_gas_decl_env_t *env, ir_node *init)
{
ir_mode *mode = get_irn_mode(init);
int bytes = get_mode_size_bytes(mode);
switch (get_irn_opcode(init)) {
case iro_Cast:
- do_emit_atomic_init(env, get_Cast_op(init));
+ emit_init_expression(env, get_Cast_op(init));
return;
case iro_Conv:
- do_emit_atomic_init(env, get_Conv_op(init));
+ emit_init_expression(env, get_Conv_op(init));
return;
case iro_Const:
if (!mode_is_int(mode) && !mode_is_reference(mode)) {
panic("Constant must be int or pointer for '+' to work");
}
- do_emit_atomic_init(env, get_Add_left(init));
+ emit_init_expression(env, get_Add_left(init));
be_emit_cstring(" + ");
- do_emit_atomic_init(env, get_Add_right(init));
+ emit_init_expression(env, get_Add_right(init));
return;
case iro_Sub:
if (!mode_is_int(mode) && !mode_is_reference(mode)) {
panic("Constant must be int or pointer for '-' to work");
}
- do_emit_atomic_init(env, get_Sub_left(init));
+ emit_init_expression(env, get_Sub_left(init));
be_emit_cstring(" - ");
- do_emit_atomic_init(env, get_Sub_right(init));
+ emit_init_expression(env, get_Sub_right(init));
return;
case iro_Mul:
if (!mode_is_int(mode) && !mode_is_reference(mode)) {
panic("Constant must be int or pointer for '*' to work");
}
- do_emit_atomic_init(env, get_Mul_left(init));
+ emit_init_expression(env, get_Mul_left(init));
be_emit_cstring(" * ");
- do_emit_atomic_init(env, get_Mul_right(init));
+ emit_init_expression(env, get_Mul_right(init));
return;
case iro_Unknown:
static void emit_size_type(size_t size)
{
switch (size) {
- case 1:
- be_emit_cstring("\t.byte\t");
- break;
-
- case 2:
- be_emit_cstring("\t.short\t");
- break;
-
- case 4:
- be_emit_cstring("\t.long\t");
- break;
-
- case 8:
- be_emit_cstring("\t.quad\t");
- break;
-
- case 10:
- case 12:
- case 16: /* Note: .octa does not work on mac */
- /* handled in arith */
- break;
+ case 1: be_emit_cstring("\t.byte\t"); break;
+ case 2: be_emit_cstring("\t.short\t"); break;
+ case 4: be_emit_cstring("\t.long\t"); break;
+ case 8: be_emit_cstring("\t.quad\t"); break;
default:
panic("Try to dump a type with %u bytes", (unsigned)size);
}
}
-/**
- * Emit an atomic value.
- *
- * @param env the gas output environment
- * @param init a node representing the atomic value (on the const code irg)
- */
-static void emit_atomic_init(be_gas_decl_env_t *env, ir_node *init)
-{
- ir_mode *mode = get_irn_mode(init);
- int bytes = get_mode_size_bytes(mode);
-
- emit_size_type(bytes);
- do_emit_atomic_init(env, init);
- be_emit_char('\n');
- be_emit_write_line();
-}
-
/**
* Dump a string constant.
* No checks are made!!
typedef struct {
normal_or_bitfield_kind kind;
+ ir_type *type;
union {
ir_node *value;
ir_tarval *tarval;
assert(vals->kind != BITFIELD);
vals->kind = TARVAL;
+ vals->type = type;
vals->v.tarval = get_initializer_tarval_value(initializer);
assert(get_type_mode(type) == get_tarval_mode(vals->v.tarval));
for (i = 1; i < get_type_size_bytes(type); ++i) {
vals[i].kind = NORMAL;
+ vals[i].type = NULL;
vals[i].v.value = NULL;
}
return;
assert(vals->kind != BITFIELD);
vals->kind = NORMAL;
+ vals->type = type;
vals->v.value = get_initializer_const_value(initializer);
for (i = 1; i < get_type_size_bytes(type); ++i) {
vals[i].kind = NORMAL;
+ vals[i].type = NULL;
vals[i].v.value = NULL;
}
return;
panic("invalid ir_initializer kind found");
}
+static void emit_tarval_data(ir_type *type, ir_tarval *tv)
+{
+ size_t size = get_type_size_bytes(type);
+ if (size == 12) {
+ /* this should be an x86 extended float */
+ assert(be_get_backend_param()->byte_order_big_endian == 0);
+
+ /* Beware: Mixed endian output! One little endian number emitted as
+ * three longs. Each long initializer is written in big endian. */
+ be_emit_irprintf(
+ "\t.long\t0x%02x%02x%02x%02x\n"
+ "\t.long\t0x%02x%02x%02x%02x\n"
+ "\t.long\t0x%02x%02x%02x%02x\n",
+ get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
+ get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0),
+ get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
+ get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
+ get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
+ get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8)
+ );
+ be_emit_write_line();
+ } else if (size == 16) {
+ if (be_get_backend_param()->byte_order_big_endian) {
+ be_emit_irprintf(
+ "\t.long\t0x%02x%02x%02x%02x\n"
+ "\t.long\t0x%02x%02x%02x%02x\n"
+ "\t.long\t0x%02x%02x%02x%02x\n"
+ "\t.long\t0x%02x%02x%02x%02x\n",
+ get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 14),
+ get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
+ get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
+ get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
+ get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
+ get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
+ get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
+ get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0)
+ );
+ } else {
+ /* Beware: Mixed endian output! One little endian number emitted as
+ * three longs. Each long initializer is written in big endian. */
+ be_emit_irprintf(
+ "\t.long\t0x%02x%02x%02x%02x\n"
+ "\t.long\t0x%02x%02x%02x%02x\n"
+ "\t.long\t0x%02x%02x%02x%02x\n"
+ "\t.long\t0x%02x%02x%02x%02x\n",
+ get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
+ get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0),
+ get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
+ get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
+ get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
+ get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
+ get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 14),
+ get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12)
+ );
+ }
+ be_emit_write_line();
+ return;
+ } else {
+ /* default case */
+ emit_size_type(size);
+ emit_arith_tarval(tv, size);
+ be_emit_char('\n');
+ be_emit_write_line();
+ }
+}
+
+/**
+ * Emit an atomic value.
+ *
+ * @param env the gas output environment
+ * @param init a node representing the atomic value (on the const code irg)
+ */
+static void emit_node_data(be_gas_decl_env_t *env, ir_node *init, ir_type *type)
+{
+ size_t size = get_type_size_bytes(type);
+ if (size == 12 || size == 16) {
+ ir_tarval *tv;
+ if (!is_Const(init)) {
+ panic("12/16byte initializers only support Const nodes yet");
+ }
+ tv = get_Const_tarval(init);
+ emit_tarval_data(type, tv);
+ return;
+ }
+
+ emit_size_type(size);
+ emit_init_expression(env, init);
+ be_emit_char('\n');
+ be_emit_write_line();
+}
+
static void emit_initializer(be_gas_decl_env_t *env, const ir_entity *entity)
{
const ir_initializer_t *initializer = entity->initializer;
/* now write values sorted */
for (k = 0; k < size; ) {
int space = 0;
- int elem_size = 1;
normal_or_bitfield_kind kind = vals[k].kind;
+ int elem_size;
switch (kind) {
case NORMAL:
if (vals[k].v.value != NULL) {
- emit_atomic_init(env, vals[k].v.value);
- elem_size = get_mode_size_bytes(get_irn_mode(vals[k].v.value));
+ emit_node_data(env, vals[k].v.value, vals[k].type);
+ elem_size = get_type_size_bytes(vals[k].type);
} else {
elem_size = 0;
}
break;
- case TARVAL: {
- ir_tarval *tv = vals[k].v.tarval;
- size_t size = get_mode_size_bytes(get_tarval_mode(tv));
-
- assert(tv != NULL);
-
- elem_size = size;
- emit_size_type(size);
- emit_arith_tarval(tv, size);
- be_emit_char('\n');
- be_emit_write_line();
+ case TARVAL:
+ emit_tarval_data(vals[k].type, vals[k].v.tarval);
+ elem_size = get_type_size_bytes(vals[k].type);
break;
- }
case STRING:
elem_size = emit_string_initializer(vals[k].v.string);
break;
case BITFIELD:
be_emit_irprintf("\t.byte\t%d\n", vals[k].v.bf_val);
be_emit_write_line();
+ elem_size = 1;
break;
+ default:
+ panic("internal compiler error (invalid normal_or_bitfield_kind");
}
k += elem_size;
int space = 0, skip = 0;
if (vals[k].kind == NORMAL) {
if (vals[k].v.value != NULL) {
- emit_atomic_init(env, vals[k].v.value);
+ emit_node_data(env, vals[k].v.value, vals[k].type);
skip = get_mode_size_bytes(get_irn_mode(vals[k].v.value)) - 1;
} else {
space = 1;
transformer_t be_transformer = TRANSFORMER_DEFAULT;
#endif
-ir_mode *ia32_mode_fpcw = NULL;
+ir_mode *ia32_mode_fpcw;
+ir_mode *ia32_mode_E;
+ir_type *ia32_type_E;
/** The current omit-fp state */
static ir_type *omit_fp_between_type = NULL;
5, /* costs for a reload instruction */
false, /* no custom abi handling */
},
- NULL, /* types */
NULL, /* tv_ents */
NULL, /* abstract machine */
IA32_FPU_ARCH_X87, /* FPU architecture */
*isa = ia32_isa_template;
if (ia32_mode_fpcw == NULL) {
- ia32_mode_fpcw = new_ir_mode("Fpcw", irms_int_number, 16, 0, irma_none, 0);
+ ia32_mode_fpcw = new_int_mode("Fpcw", irma_twos_complement, 16, 0, 0);
}
ia32_register_init();
ia32_create_opcodes(&ia32_irn_ops);
be_emit_init(file_handle);
- isa->types = pmap_create();
isa->tv_ent = pmap_create();
isa->cpu = ia32_init_machine_description();
be_gas_emit_decls(isa->base.main_env);
pmap_destroy(isa->tv_ent);
- pmap_destroy(isa->types);
be_emit_exit();
ia32_create_trampoline_fkt,
4 /* alignment of stack parameter */
};
+
+ if (ia32_mode_E == NULL) {
+ /* 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_type_E = new_type_primitive(ia32_mode_E);
+ set_type_size_bytes(ia32_type_E, 12);
+ set_type_alignment_bytes(ia32_type_E, 16);
+ }
+
ir_mode *mode_long_long
- = new_ir_mode("long long", irms_int_number, 64, 1, irma_twos_complement,
- 64);
+ = new_int_mode("long long", irma_twos_complement, 64, 1, 64);
ir_type *type_long_long = new_type_primitive(mode_long_long);
ir_mode *mode_unsigned_long_long
- = new_ir_mode("unsigned long long", irms_int_number, 64, 0,
- irma_twos_complement, 64);
+ = new_int_mode("unsigned long long", irma_twos_complement, 64, 0, 64);
ir_type *type_unsigned_long_long
= new_type_primitive(mode_unsigned_long_long);
p.mode_float_arithmetic = NULL;
p.type_long_double = NULL;
} else {
- p.mode_float_arithmetic = mode_E;
- ir_mode *mode = new_ir_mode("long double", irms_float_number, 80, 1,
- irma_ieee754, 0);
- ir_type *type = new_type_primitive(mode);
- set_type_size_bytes(type, 12);
- set_type_alignment_bytes(type, 4);
- p.type_long_double = type;
+ p.mode_float_arithmetic = ia32_mode_E;
+ p.type_long_double = ia32_type_E;
}
return &p;
}
* IA32 ISA object
*/
struct ia32_isa_t {
- arch_env_t base; /**< must be derived from arch_env_t */
- pmap *types; /**< A map of modes to primitivetypes */
- pmap *tv_ent; /**< A map of entities that store const tarvals */
- const be_machine_t *cpu; /**< the abstract machine */
- int fpu_arch; /**< FPU architecture */
+ arch_env_t base; /**< must be derived from arch_env_t */
+ pmap *tv_ent; /**< A map of entities that store const tarvals */
+ const be_machine_t *cpu; /**< the abstract machine */
+ int fpu_arch; /**< FPU architecture */
};
/**
/** The mode for the floating point control word. */
extern ir_mode *ia32_mode_fpcw;
+/** extended floatingpoint mode */
+extern ir_mode *ia32_mode_E;
+extern ir_type *ia32_type_E;
static inline ia32_irg_data_t *ia32_get_irg_data(const ir_graph *irg)
{
}
}
-/**
- * Get a primitive type for a mode with alignment 16.
- */
-static ir_type *ia32_get_prim_type(pmap *types, ir_mode *mode)
+ir_type *ia32_get_prim_type(const ir_mode *mode)
{
- ir_type *res = (ir_type*)pmap_get(types, mode);
- if (res != NULL)
- return res;
-
- res = new_type_primitive(mode);
- if (get_mode_size_bits(mode) >= 80) {
- set_type_alignment_bytes(res, 16);
+ if (mode == ia32_mode_E) {
+ return ia32_type_E;
+ } else {
+ return get_type_for_mode(mode);
}
- pmap_insert(types, mode, res);
- return res;
}
-ir_entity *ia32_create_float_const_entity(ir_node *cnst)
+ir_entity *ia32_create_float_const_entity(ia32_isa_t *isa, ir_tarval *tv,
+ ident *name)
{
- ir_graph *irg = get_irn_irg(cnst);
- const arch_env_t *arch_env = be_get_irg_arch_env(irg);
- ia32_isa_t *isa = (ia32_isa_t*) arch_env;
- ir_tarval *tv = get_Const_tarval(cnst);
- ir_entity *res = (ir_entity*)pmap_get(isa->tv_ent, tv);
+ ir_entity *res = (ir_entity*)pmap_get(isa->tv_ent, tv);
ir_initializer_t *initializer;
ir_mode *mode;
ir_type *tp;
}
}
- tp = ia32_get_prim_type(isa->types, mode);
- res = new_entity(get_glob_type(), id_unique("C%u"), tp);
+ if (name == NULL)
+ name = id_unique("C%u");
+
+ tp = ia32_get_prim_type(mode);
+ res = new_entity(get_glob_type(), name, tp);
set_entity_ld_ident(res, get_entity_ident(res));
set_entity_visibility(res, ir_visibility_private);
add_entity_linkage(res, IR_LINKAGE_CONSTANT);
extern ir_heights_t *ia32_heights;
extern int ia32_no_pic_adjust;
+ir_type *ia32_get_prim_type(const ir_mode *mode);
+
/**
* Get an atomic entity that is initialized with a tarval forming
* a given constant.
- *
- * @param cnst the node representing the constant
*/
-ir_entity *ia32_create_float_const_entity(ir_node *cnst);
+ir_entity *ia32_create_float_const_entity(ia32_isa_t *isa, ir_tarval *tv,
+ ident *name);
/**
* Creates an immediate.
if (arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
return;
- if (get_irn_mode(node) == mode_E) {
- ia32_emitf(node, "\tmovsd %R, %R\n", in, out);
- } else {
- ia32_emitf(node, "\tmovl %R, %R\n", in, out);
- }
+ ia32_emitf(node, "\tmovl %R, %R\n", in, out);
}
static void emit_be_Copy(const ir_node *node)
if (arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
return;
- if (get_irn_mode(copy) == mode_E) {
- panic("NIY");
- } else {
- assert(arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_gp]);
- bemit8(0x8B);
- bemit_modrr(in, out);
- }
+ assert(arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_gp]);
+ bemit8(0x8B);
+ bemit_modrr(in, out);
}
static void bemit_perm(const ir_node *node)
$arch = "ia32";
+$mode_xmm = "mode_D";
+$mode_mmx = "mode_D";
+$mode_fp87 = "ia32_mode_E";
+$mode_gp = "mode_Iu";
+$mode_flags = "mode_Iu";
+$mode_fpcw = "ia32_mode_fpcw";
+
# register types:
$normal = 0; # no special type
$ignore = 1; # ignore (do not assign this register)
{ name => "ebp" },
{ name => "esp", type => $ignore },
{ name => "gp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
- { mode => "mode_Iu" }
+ { mode => $mode_gp }
],
mmx => [
{ name => "mm0", type => $ignore },
{ name => "mm5", type => $ignore },
{ name => "mm6", type => $ignore },
{ name => "mm7", type => $ignore },
- { mode => "mode_E", flags => "manual_ra" }
+ { mode => $mode_mmx, flags => "manual_ra" }
],
xmm => [
{ name => "xmm0" },
{ name => "xmm6" },
{ name => "xmm7" },
{ name => "xmm_NOREG", type => $ignore | $virtual }, # we need a dummy register for NoReg nodes
- { mode => "mode_E" }
+ { mode => $mode_xmm }
],
vfp => [
{ name => "vf0" },
{ name => "vf6" },
{ name => "vf7" },
{ name => "vfp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
- { mode => "mode_E" }
+ { mode => $mode_fp87 }
],
st => [
{ name => "st0", realname => "st", type => $ignore },
{ name => "st5", realname => "st(5)", type => $ignore },
{ name => "st6", realname => "st(6)", type => $ignore },
{ name => "st7", realname => "st(7)", type => $ignore },
- { mode => "mode_E", flags => "manual_ra" }
+ { mode => $mode_fp87, flags => "manual_ra" }
],
fp_cw => [ # the floating point control word
{ name => "fpcw", type => $ignore | $state },
- { mode => "ia32_mode_fpcw", flags => "manual_ra|state" }
+ { mode => $mode_fpcw, flags => "manual_ra|state" }
],
flags => [
{ name => "eflags", type => 0 },
%operands = (
);
-$mode_xmm = "mode_E";
-$mode_gp = "mode_Iu";
-$mode_flags = "mode_Iu";
-$mode_fpcw = "ia32_mode_fpcw";
$status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
$status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
$fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
reg_req => { out => [ "vfp_NOREG:I" ] },
units => [],
emit => "",
- mode => "mode_E",
+ mode => $mode_fp87,
latency => 0,
attr_type => "ia32_x87_attr_t",
},
units => [],
emit => "",
latency => 0,
- mode => "mode_E"
+ mode => $mode_xmm,
},
ChangeCW => {
am => "source,binary",
latency => 4,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
am => "source,binary",
latency => 4,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
am => "source,binary",
latency => 4,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
ins => [ "left", "right", "fpcw" ],
latency => 20,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
ins => [ "value" ],
latency => 2,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
ins => [ "value" ],
latency => 2,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
outs => [ "res" ],
latency => 4,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
outs => [ "res" ],
latency => 4,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
outs => [ "res" ],
latency => 4,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
outs => [ "res" ],
latency => 4,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
outs => [ "res" ],
latency => 4,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
outs => [ "res" ],
latency => 4,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
outs => [ "res" ],
latency => 4,
units => [ "VFP" ],
- mode => "mode_E",
+ mode => $mode_fp87,
attr_type => "ia32_x87_attr_t",
},
/* define this to construct SSE constants instead of load them */
#undef CONSTRUCT_SSE_CONST
-
-#define SFP_SIGN "0x80000000"
-#define DFP_SIGN "0x8000000000000000"
-#define SFP_ABS "0x7FFFFFFF"
-#define DFP_ABS "0x7FFFFFFFFFFFFFFF"
-#define DFP_INTMAX "9223372036854775807"
-#define ULL_BIAS "18446744073709551616"
-
-#define ENT_SFP_SIGN "C_ia32_sfp_sign"
-#define ENT_DFP_SIGN "C_ia32_dfp_sign"
-#define ENT_SFP_ABS "C_ia32_sfp_abs"
-#define ENT_DFP_ABS "C_ia32_dfp_abs"
-#define ENT_ULL_BIAS "C_ia32_ull_bias"
-
#define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
#define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
*/
static ir_node *gen_Const(ir_node *node)
{
- ir_node *old_block = get_nodes_block(node);
- ir_node *block = be_transform_node(old_block);
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_mode *mode = get_irn_mode(node);
+ ir_node *old_block = get_nodes_block(node);
+ ir_node *block = be_transform_node(old_block);
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_mode *mode = get_irn_mode(node);
+ ir_tarval *tv = get_Const_tarval(node);
assert(is_Const(node));
if (mode_is_float(mode)) {
- ir_node *res = NULL;
- ir_node *load;
- ir_entity *floatent;
+ ir_graph *irg = get_irn_irg(node);
+ const arch_env_t *arch_env = be_get_irg_arch_env(irg);
+ ia32_isa_t *isa = (ia32_isa_t*) arch_env;
+ ir_node *res = NULL;
+ ir_node *load;
+ ir_entity *floatent;
if (ia32_cg_config.use_sse2) {
- ir_tarval *tv = get_Const_tarval(node);
if (tarval_is_null(tv)) {
load = new_bd_ia32_xZero(dbgi, block);
set_ia32_ls_mode(load, mode);
}
}
#endif /* CONSTRUCT_SSE_CONST */
- floatent = ia32_create_float_const_entity(node);
+ floatent = ia32_create_float_const_entity(isa, tv, NULL);
base = get_symconst_base();
load = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
}
} else {
- if (is_Const_null(node)) {
+ if (tarval_is_null(tv)) {
load = new_bd_ia32_vfldz(dbgi, block);
res = load;
set_ia32_ls_mode(load, mode);
- } else if (is_Const_one(node)) {
+ } else if (tarval_is_one(tv)) {
load = new_bd_ia32_vfld1(dbgi, block);
res = load;
set_ia32_ls_mode(load, mode);
ir_mode *ls_mode;
ir_node *base;
- floatent = ia32_create_float_const_entity(node);
+ floatent = ia32_create_float_const_entity(isa, tv, NULL);
/* create_float_const_ent is smart and sometimes creates
smaller entities */
ls_mode = get_type_mode(get_entity_type(floatent));
SET_IA32_ORIG_NODE(load, node);
return res;
} else { /* non-float mode */
- ir_node *cnst;
- ir_tarval *tv = get_Const_tarval(node);
- long val;
+ ir_node *cnst;
+ long val;
tv = tarval_convert_to(tv, mode_Iu);
if (mode_is_float(mode)) {
if (ia32_cg_config.use_sse2)
- cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
+ cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_D);
else
- cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
+ cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, ia32_mode_E);
set_ia32_am_sc(cnst, get_SymConst_entity(node));
set_ia32_use_frame(cnst);
} else {
return cnst;
}
-/**
- * Create a float type for the given mode and cache it.
- *
- * @param mode the mode for the float type (might be integer mode for SSE2 types)
- * @param align alignment
- */
-static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
+static ir_type *make_array_type(ir_type *tp)
{
- ir_type *tp;
-
- assert(align <= 16);
-
- if (mode == mode_Iu) {
- static ir_type *int_Iu[16] = {NULL, };
-
- if (int_Iu[align] == NULL) {
- int_Iu[align] = tp = new_type_primitive(mode);
- /* set the specified alignment */
- set_type_alignment_bytes(tp, align);
- }
- return int_Iu[align];
- } else if (mode == mode_Lu) {
- static ir_type *int_Lu[16] = {NULL, };
-
- if (int_Lu[align] == NULL) {
- int_Lu[align] = tp = new_type_primitive(mode);
- /* set the specified alignment */
- set_type_alignment_bytes(tp, align);
- }
- return int_Lu[align];
- } else if (mode == mode_F) {
- static ir_type *float_F[16] = {NULL, };
-
- if (float_F[align] == NULL) {
- float_F[align] = tp = new_type_primitive(mode);
- /* set the specified alignment */
- set_type_alignment_bytes(tp, align);
- }
- return float_F[align];
- } else if (mode == mode_D) {
- static ir_type *float_D[16] = {NULL, };
-
- if (float_D[align] == NULL) {
- float_D[align] = tp = new_type_primitive(mode);
- /* set the specified alignment */
- set_type_alignment_bytes(tp, align);
- }
- return float_D[align];
- } else {
- static ir_type *float_E[16] = {NULL, };
-
- if (float_E[align] == NULL) {
- float_E[align] = tp = new_type_primitive(mode);
- /* set the specified alignment */
- set_type_alignment_bytes(tp, align);
- }
- return float_E[align];
- }
+ unsigned alignment = get_type_alignment_bytes(tp);
+ unsigned size = get_type_size_bytes(tp);
+ ir_type *res = new_type_array(1, tp);
+ set_type_alignment_bytes(res, alignment);
+ set_array_bounds_int(res, 0, 0, 2);
+ if (alignment > size)
+ size = alignment;
+ set_type_size_bytes(res, 2 * size);
+ set_type_state(res, layout_fixed);
+ return res;
}
/**
static ir_type *ia32_create_float_array(ir_type *tp)
{
ir_mode *mode = get_type_mode(tp);
- unsigned align = get_type_alignment_bytes(tp);
ir_type *arr;
- assert(align <= 16);
-
if (mode == mode_F) {
- static ir_type *float_F[16] = {NULL, };
+ static ir_type *float_F;
- if (float_F[align] != NULL)
- return float_F[align];
- arr = float_F[align] = new_type_array(1, tp);
+ arr = float_F;
+ if (arr == NULL)
+ arr = float_F = make_array_type(tp);
} else if (mode == mode_D) {
- static ir_type *float_D[16] = {NULL, };
+ static ir_type *float_D;
- if (float_D[align] != NULL)
- return float_D[align];
- arr = float_D[align] = new_type_array(1, tp);
+ arr = float_D;
+ if (arr == NULL)
+ arr = float_D = make_array_type(tp);
} else {
- static ir_type *float_E[16] = {NULL, };
+ static ir_type *float_E;
- if (float_E[align] != NULL)
- return float_E[align];
- arr = float_E[align] = new_type_array(1, tp);
+ arr = float_E;
+ if (arr == NULL)
+ arr = float_E = make_array_type(tp);
}
- set_type_alignment_bytes(arr, align);
- set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
- set_type_state(arr, layout_fixed);
return arr;
}
ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
{
static const struct {
- const char *ent_name;
+ const char *name;
const char *cnst_str;
- char mode;
- unsigned char align;
+ char mode;
} names [ia32_known_const_max] = {
- { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
- { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
- { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
- { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
- { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
+ { "C_sfp_sign", "0x80000000", 0 },
+ { "C_dfp_sign", "0x8000000000000000", 1 },
+ { "C_sfp_abs", "0x7FFFFFFF", 0 },
+ { "C_dfp_abs", "0x7FFFFFFFFFFFFFFF", 1 },
+ { "C_ull_bias", "0x10000000000000000", 2 }
};
static ir_entity *ent_cache[ia32_known_const_max];
- const char *ent_name, *cnst_str;
- ir_type *tp;
- ir_entity *ent;
- ir_tarval *tv;
- ir_mode *mode;
-
- ent_name = names[kct].ent_name;
- if (! ent_cache[kct]) {
- cnst_str = names[kct].cnst_str;
+ ir_entity *ent = ent_cache[kct];
+ if (ent == NULL) {
+ ir_graph *irg = current_ir_graph;
+ const arch_env_t *arch_env = be_get_irg_arch_env(irg);
+ ia32_isa_t *isa = (ia32_isa_t*) arch_env;
+ const char *cnst_str = names[kct].cnst_str;
+ ident *name = new_id_from_str(names[kct].name);
+ ir_mode *mode;
+ ir_tarval *tv;
switch (names[kct].mode) {
case 0: mode = mode_Iu; break;
case 1: mode = mode_Lu; break;
- default: mode = mode_F; break;
+ case 2: mode = mode_F; break;
+ default: panic("internal compiler error (ia32_gen_fp_known_const)");
}
- tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
- tp = ia32_create_float_type(mode, names[kct].align);
+ tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
- if (kct == ia32_ULLBIAS)
- tp = ia32_create_float_array(tp);
- ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
+ if (kct == ia32_ULLBIAS) {
+ ir_type *type = ia32_get_prim_type(mode_F);
+ ir_type *atype = ia32_create_float_array(type);
+ ir_initializer_t *initializer;
- set_entity_ld_ident(ent, get_entity_ident(ent));
- add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
- set_entity_visibility(ent, ir_visibility_private);
+ ent = new_entity(get_glob_type(), name, atype);
- if (kct == ia32_ULLBIAS) {
- ir_initializer_t *initializer = create_initializer_compound(2);
+ set_entity_ld_ident(ent, name);
+ set_entity_visibility(ent, ir_visibility_private);
+ add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
+ initializer = create_initializer_compound(2);
set_initializer_compound_value(initializer, 0,
create_initializer_tarval(get_mode_null(mode)));
set_initializer_compound_value(initializer, 1,
create_initializer_tarval(tv));
-
set_entity_initializer(ent, initializer);
} else {
- set_entity_initializer(ent, create_initializer_tarval(tv));
+ ent = ia32_create_float_const_entity(isa, tv, name);
}
-
/* cache the entry */
ent_cache[kct] = ent;
}
/* floating point immediates */
if (is_Const(node)) {
- ir_entity *entity = ia32_create_float_const_entity(node);
+ ir_graph *irg = get_irn_irg(node);
+ const arch_env_t *arch_env = be_get_irg_arch_env(irg);
+ ia32_isa_t *isa = (ia32_isa_t*) arch_env;
+ ir_tarval *tv = get_Const_tarval(node);
+ ir_entity *entity = ia32_create_float_const_entity(isa, tv, NULL);
addr->base = get_symconst_base();
addr->index = noreg_GP;
addr->mem = nomem;
/* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
if other users exists */
ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
- ir_node *value = new_r_Proj(vfisttp, mode_E, pn_ia32_vfisttp_res);
+ ir_node *value = new_r_Proj(vfisttp, ia32_mode_E, pn_ia32_vfisttp_res);
be_new_Keep(block, 1, &value);
return vfisttp;
*/
static ir_node *gen_Store(ir_node *node)
{
- ir_node *val = get_Store_value(node);
- ir_mode *mode = get_irn_mode(val);
+ ir_node *val = get_Store_value(node);
+ ir_mode *mode = get_irn_mode(val);
if (mode_is_float(mode) && is_Const(val)) {
/* We can transform every floating const store
}
- tp = ia32_create_float_type(mode, 4);
+ tp = ia32_get_prim_type(mode);
tp = ia32_create_float_array(tp);
ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
- switch (get_mode_size_bytes(new_mode)) {
- case 4:
+ if (new_mode == mode_F) {
scale = 2;
- break;
- case 8:
+ } else if (new_mode == mode_D) {
scale = 3;
- break;
- case 10:
- /* use 2 * 5 */
- scale = 1;
- new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
- set_ia32_am_scale(new_node, 2);
- break;
- case 12:
- /* use 4 * 3 */
- scale = 2;
- new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
- set_ia32_am_scale(new_node, 1);
- break;
- case 16:
+ } else if (new_mode == ia32_mode_E) {
/* arg, shift 16 NOT supported */
scale = 3;
new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
- break;
- default:
+ } else {
panic("Unsupported constant size");
}
set_ia32_op_type(load, ia32_AddrModeS);
SET_IA32_ORIG_NODE(load, node);
- new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
+ new_node = new_r_Proj(load, ia32_mode_E, pn_ia32_vfld_res);
return new_node;
}
set_ia32_ls_mode(res, tgt_mode);
} else {
unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
- unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
+ unsigned float_mantissa = get_mode_mantissa_size(tgt_mode);
res = gen_x87_gp_to_fp(node, src_mode);
/* we need a strict-Conv, if the int mode has more bits than the
} else if (mode_is_int(mode) || mode_is_reference(mode)) {
mode = mode_Iu;
} else if (mode_is_float(mode)) {
- mode = mode_E;
+ mode = ia32_mode_E;
} else {
panic("unexpected proj mode at ASM");
}
};
ir_mode *mode_long_long
- = new_ir_mode("long long", irms_int_number, 64, 1, irma_twos_complement,
- 64);
+ = new_int_mode("long long", irma_twos_complement, 64, 1, 64);
ir_type *type_long_long = new_type_primitive(mode_long_long);
ir_mode *mode_unsigned_long_long
- = new_ir_mode("unsigned long long", irms_int_number, 64, 0,
- irma_twos_complement, 64);
+ = new_int_mode("unsigned long long", irma_twos_complement, 64, 0, 64);
ir_type *type_unsigned_long_long
= new_type_primitive(mode_unsigned_long_long);
p.mode_float_arithmetic = NULL;
p.type_long_double = NULL;
} else {
- ir_mode *mode_long_double
- = new_ir_mode("long double", irms_float_number, 128, 1,
- irma_ieee754, 0);
- ir_type *type_long_double = new_type_primitive(mode_long_double);
+ ir_type *type_long_double = new_type_primitive(mode_Q);
set_type_alignment_bytes(type_long_double, 8);
- p.type_long_double = type_long_double;
+ set_type_size_bytes(type_long_double, 16);
+ p.type_long_double = type_long_double;
}
return &p;
}
#include "xmalloc.h"
#include "bearch.h"
+#include "bearch_sparc_t.h"
#include "sparc_nodes_attr.h"
#include "sparc_new_nodes.h"
$mode_fpflags = "mode_Bu";
$mode_fp = "mode_F";
$mode_fp2 = "mode_D";
-$mode_fp4 = "mode_E"; # not correct, we need to register a new mode
+$mode_fp4 = "mode_Q";
# available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals)
%reg_classes = (
tt_initializer,
tt_iro,
tt_keyword,
- tt_mode_sort,
tt_mode_arithmetic,
tt_pin_state,
tt_tpo,
kw_constirg,
kw_entity,
kw_irg,
- kw_mode,
+ kw_int_mode,
+ kw_reference_mode,
+ kw_float_mode,
kw_modes,
kw_type,
kw_typegraph,
INSERT(tt_tpo, "union", tpo_union);
INSERT(tt_tpo, "Unknown", tpo_unknown);
- INSERT(tt_mode_sort, "auxiliary", irms_auxiliary);
- INSERT(tt_mode_sort, "control_flow", irms_control_flow);
- INSERT(tt_mode_sort, "memory", irms_memory);
- INSERT(tt_mode_sort, "internal_boolean", irms_internal_boolean);
- INSERT(tt_mode_sort, "reference", irms_reference);
- INSERT(tt_mode_sort, "int_number", irms_int_number);
- INSERT(tt_mode_sort, "float_number", irms_float_number);
-
INSERT(tt_segment, "global", IR_SEGMENT_GLOBAL);
INSERT(tt_segment, "thread_local", IR_SEGMENT_THREAD_LOCAL);
INSERT(tt_segment, "constructors", IR_SEGMENT_CONSTRUCTORS);
INSERTKEYWORD(constirg);
INSERTKEYWORD(entity);
INSERTKEYWORD(irg);
- INSERTKEYWORD(mode);
+ INSERTKEYWORD(int_mode);
+ INSERTKEYWORD(float_mode);
+ INSERTKEYWORD(reference_mode);
INSERTKEYWORD(modes);
INSERTKEYWORD(type);
INSERTKEYWORD(typegraph);
fputs("}\n", env->file);
}
-static const char *get_mode_sort_name(ir_mode_sort sort)
-{
- switch (sort) {
- case irms_auxiliary: return "auxiliary";
- case irms_control_flow: return "control_flow";
- case irms_memory: return "memory";
- case irms_internal_boolean: return "internal_boolean";
- case irms_reference: return "reference";
- case irms_int_number: return "int_number";
- case irms_float_number: return "float_number";
- }
- panic("invalid mode sort found");
-}
-
static void export_modes(io_env_t *env)
{
size_t i, n_modes = get_irp_n_modes();
for (i = 0; i < n_modes; i++) {
ir_mode *mode = get_irp_mode(i);
- switch (get_mode_sort(mode)) {
- case irms_auxiliary:
- case irms_control_flow:
- case irms_memory:
- case irms_internal_boolean:
- /* skip "internal" modes, which may not be user defined */
- continue;
- default:
- break;
- }
- fprintf(env->file, "\tmode ");
- write_string(env, get_mode_name(mode));
- fprintf(env->file, "%s %u %d %s %u ",
- get_mode_sort_name(get_mode_sort(mode)),
- get_mode_size_bits(mode), get_mode_sign(mode),
- get_mode_arithmetic_name(get_mode_arithmetic(mode)),
- get_mode_modulo_shift(mode));
- if (mode_is_reference(mode)) {
+ if (mode_is_int(mode)) {
+ fprintf(env->file, "\tint_mode ");
+ write_string(env, get_mode_name(mode));
+ fprintf(env->file, "%s %u %d %u ",
+ get_mode_arithmetic_name(get_mode_arithmetic(mode)),
+ get_mode_size_bits(mode), get_mode_sign(mode),
+ get_mode_modulo_shift(mode));
+ } else if (mode_is_reference(mode)) {
+ fprintf(env->file, "\treference_mode ");
+ write_string(env, get_mode_name(mode));
+ fprintf(env->file, "%s %u %u ",
+ get_mode_arithmetic_name(get_mode_arithmetic(mode)),
+ get_mode_size_bits(mode),
+ get_mode_modulo_shift(mode));
write_mode(env, get_reference_mode_signed_eq(mode));
write_mode(env, get_reference_mode_unsigned_eq(mode));
write_int(env, (mode == mode_P ? 1 : 0));
+ } else if (mode_is_float(mode)) {
+ fprintf(env->file, "\tfloat_mode ");
+ write_string(env, get_mode_name(mode));
+ fprintf(env->file, "%s %u %u ",
+ get_mode_arithmetic_name(get_mode_arithmetic(mode)),
+ get_mode_exponent_size(mode),
+ get_mode_mantissa_size(mode));
+ } else {
+ /* skip "internal" modes */
}
fputc('\n', env->file);
}
case tt_keyword: return "keyword";
case tt_linkage: return "linkage";
case tt_mode_arithmetic: return "mode_arithmetic";
- case tt_mode_sort: return "mode_sort";
case tt_pin_state: return "pin state";
case tt_segment: return "segment";
case tt_tpo: return "type";
kwkind = (keyword_t) read_enum(env, tt_keyword);
switch (kwkind) {
- case kw_mode: {
+ case kw_int_mode: {
const char *name = read_string(env);
- ir_mode_sort sort = (ir_mode_sort)read_enum(env, tt_mode_sort);
+ ir_mode_arithmetic arith = read_mode_arithmetic(env);
int size = read_long(env);
int sign = read_long(env);
+ unsigned modulo_shift = read_long(env);
+ new_int_mode(name, arith, size, sign, modulo_shift);
+ break;
+ }
+ case kw_reference_mode: {
+ const char *name = read_string(env);
ir_mode_arithmetic arith = read_mode_arithmetic(env);
+ int size = read_long(env);
unsigned modulo_shift = read_long(env);
- int vector_elems = read_long(env);
- ir_mode *mode;
-
- if (vector_elems != 1) {
- panic("no support for import of vector modes yes");
- }
-
- mode = new_ir_mode(name, sort, size, sign, arith, modulo_shift);
- if (mode_is_reference(mode)) {
- set_reference_mode_signed_eq(mode, read_mode(env));
- set_reference_mode_unsigned_eq(mode, read_mode(env));
- int is_mode_P = read_int(env);
- if (is_mode_P) {
- set_modeP_data(mode);
- set_modeP_code(mode);
- }
+ ir_mode *mode = new_reference_mode(name, arith, size, modulo_shift);
+ set_reference_mode_signed_eq(mode, read_mode(env));
+ set_reference_mode_unsigned_eq(mode, read_mode(env));
+ int is_mode_P = read_int(env);
+ if (is_mode_P) {
+ set_modeP_data(mode);
+ set_modeP_code(mode);
}
break;
}
+ case kw_float_mode: {
+ const char *name = read_string(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);
+ break;
+ }
default:
skip_to(env, '\n');
#include <stdlib.h>
#include <string.h>
-
#include <stddef.h>
+#include <stdbool.h>
#include "irprog_t.h"
#include "irmode_t.h"
X(irma_none);
X(irma_twos_complement);
X(irma_ieee754);
+ X(irma_x86_extended_float);
default: return "<unknown>";
}
#undef X
}
-static inline int modes_are_equal(const ir_mode *m, const ir_mode *n)
+static bool modes_are_equal(const ir_mode *m, const ir_mode *n)
{
- if (m == n) return 1;
- if (m->sort == n->sort &&
- m->arithmetic == n->arithmetic &&
- m->size == n->size &&
- m->sign == n->sign &&
- m->modulo_shift == n->modulo_shift)
- return 1;
-
- return 0;
+ return m->sort == n->sort &&
+ m->arithmetic == n->arithmetic &&
+ m->size == n->size &&
+ m->sign == n->sign &&
+ m->modulo_shift == n->modulo_shift;
}
/**
mode->all_one = tarval_b_true;
break;
- case irms_auxiliary:
- case irms_memory:
case irms_control_flow:
+ case irms_block:
+ case irms_tuple:
+ case irms_any:
+ case irms_bad:
+ case irms_memory:
mode->min = tarval_bad;
mode->max = tarval_bad;
mode->null = tarval_bad;
ir_mode *mode_BAD;
/* predefined numerical modes: */
-ir_mode *mode_F; /* float */
-ir_mode *mode_D; /* double */
-ir_mode *mode_E; /* long double */
+ir_mode *mode_F;
+ir_mode *mode_D;
+ir_mode *mode_Q;
ir_mode *mode_Bs; /* integral values, signed and unsigned */
ir_mode *mode_Bu; /* 8 bit */
* functions defined in irmode.h
* * */
-/* JNI access functions */
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_modeE(void) { return mode_E; }
+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; }
mode_P = p;
}
-/**
- * Registers a new mode.
- *
- * @param new_mode The new mode template.
+/*
+ * Creates a new mode.
*/
-static ir_mode *register_mode(const ir_mode *new_mode)
-{
- ir_mode *mode = NULL;
-
- assert(new_mode);
-
- /* copy mode struct to modes array */
- mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode));
- ARR_APP1(ir_mode*, mode_list, mode);
+static ir_mode *alloc_mode(const char *name, ir_mode_sort sort,
+ ir_mode_arithmetic arithmetic, unsigned bit_size,
+ int sign, unsigned modulo_shift)
+{
+ ir_mode *mode_tmpl = OALLOCZ(&modes, ir_mode);
+
+ mode_tmpl->name = new_id_from_str(name);
+ mode_tmpl->sort = sort;
+ mode_tmpl->size = bit_size;
+ mode_tmpl->sign = sign ? 1 : 0;
+ mode_tmpl->modulo_shift = modulo_shift;
+ mode_tmpl->arithmetic = arithmetic;
+ mode_tmpl->link = NULL;
+ mode_tmpl->tv_priv = NULL;
+ return mode_tmpl;
+}
+
+static ir_mode *register_mode(ir_mode *mode)
+{
+ /* does any of the existing modes have the same properties? */
+ ir_mode *old = find_mode(mode);
+ if (old != NULL) {
+ /* remove new mode from obstack */
+ obstack_free(&modes, mode);
+ return old;
+ }
mode->kind = k_ir_mode;
mode->type = new_type_primitive(mode);
-
- /* add the new mode to the irp list of modes */
+ ARR_APP1(ir_mode*, mode_list, mode);
add_irp_mode(mode);
-
set_mode_values(mode);
-
- hook_new_mode(new_mode, mode);
+ hook_new_mode(mode);
return mode;
}
-/*
- * Creates a new mode.
- */
-ir_mode *new_ir_mode(const char *name, ir_mode_sort sort, int bit_size, int sign,
- ir_mode_arithmetic arithmetic, unsigned int modulo_shift)
-{
- ir_mode mode_tmpl;
- ir_mode *mode = NULL;
-
- mode_tmpl.name = new_id_from_str(name);
- mode_tmpl.sort = sort;
- mode_tmpl.size = bit_size;
- mode_tmpl.sign = sign ? 1 : 0;
- mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number ||
- mode_tmpl.sort == irms_reference) ? modulo_shift : 0;
- mode_tmpl.arithmetic = arithmetic;
- mode_tmpl.link = NULL;
- mode_tmpl.tv_priv = NULL;
-
- mode = find_mode(&mode_tmpl);
- if (mode) {
- hook_new_mode(&mode_tmpl, mode);
- return mode;
- }
+ir_mode *new_int_mode(const char *name, ir_mode_arithmetic arithmetic,
+ unsigned bit_size, int sign, unsigned modulo_shift)
+{
+ ir_mode *result = alloc_mode(name, irms_int_number, arithmetic, bit_size,
+ sign, modulo_shift);
+ return register_mode(result);
+}
- /* sanity checks */
- switch (sort) {
- case irms_auxiliary:
- case irms_control_flow:
- case irms_memory:
- case irms_internal_boolean:
- panic("internal modes cannot be user defined");
+ir_mode *new_reference_mode(const char *name, ir_mode_arithmetic arithmetic,
+ unsigned bit_size, unsigned modulo_shift)
+{
+ ir_mode *result = alloc_mode(name, irms_reference, arithmetic, bit_size,
+ 0, modulo_shift);
+ return register_mode(result);
+}
- case irms_float_number:
- case irms_int_number:
- case irms_reference:
- mode = register_mode(&mode_tmpl);
- break;
+ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic,
+ unsigned exponent_size, unsigned mantissa_size)
+{
+ bool explicit_one = false;
+ unsigned bit_size = exponent_size + mantissa_size + 1;
+ ir_mode *result;
+
+ if (arithmetic == irma_x86_extended_float) {
+ explicit_one = true;
+ bit_size++;
+ } else if (arithmetic != irma_ieee754) {
+ panic("Arithmetic %s invalid for float");
}
- assert(mode != NULL);
- return mode;
+ if (exponent_size >= 256)
+ panic("Exponents >= 256 bits not supported");
+ if (mantissa_size >= 256)
+ panic("Mantissa >= 256 bits not supported");
+
+ result = alloc_mode(name, irms_float_number, irma_ieee754, bit_size, 1, 0);
+ result->float_desc.exponent_size = exponent_size;
+ result->float_desc.mantissa_size = mantissa_size;
+ result->float_desc.explicit_one = explicit_one;
+ return register_mode(result);
}
/* Functions for the direct access to all attributes of an ir_mode */
return get_id_str(mode->name);
}
-ir_mode_sort (get_mode_sort)(const ir_mode* mode)
-{
- return get_mode_sort_(mode);
-}
-
unsigned (get_mode_size_bits)(const ir_mode *mode)
{
return get_mode_size_bits_(mode);
return mode_is_dataM_(mode);
}
+unsigned (get_mode_mantissa_size)(const ir_mode *mode)
+{
+ return get_mode_mantissa_size_(mode);
+}
+
+unsigned (get_mode_exponent_size)(const ir_mode *mode)
+{
+ return get_mode_exponent_size_(mode);
+}
+
/* Returns true if sm can be converted to lm without loss. */
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
ref_mode->eq_unsigned = int_mode;
}
+static ir_mode *new_internal_mode(const char *name, ir_mode_sort sort)
+{
+ ir_mode *mode = alloc_mode(name, sort, irma_none, 0, 0, 0);
+ return register_mode(mode);
+}
+
/* initialization, build the default modes */
void init_mode(void)
{
- ir_mode newmode;
-
obstack_init(&modes);
mode_list = NEW_ARR_F(ir_mode*, 0);
/* initialize predefined modes */
-
- /* Internal Modes */
- newmode.arithmetic = irma_none;
- newmode.size = 0;
- newmode.sign = 0;
- newmode.modulo_shift = 0;
- newmode.eq_signed = NULL;
- newmode.eq_unsigned = NULL;
- newmode.link = NULL;
- newmode.tv_priv = NULL;
-
- /* Control Flow Modes*/
- newmode.sort = irms_control_flow;
-
- /* Basic Block */
- newmode.name = new_id_from_chars("BB", 2);
- mode_BB = register_mode(&newmode);
-
- /* eXecution */
- newmode.name = new_id_from_chars("X", 1);
- mode_X = register_mode(&newmode);
-
- /* Memory Modes */
- newmode.sort = irms_memory;
-
- /* Memory */
- newmode.name = new_id_from_chars("M", 1);
- mode_M = register_mode(&newmode);
-
- /* Auxiliary Modes */
- newmode.sort = irms_auxiliary,
-
- /* Tuple */
- newmode.name = new_id_from_chars("T", 1);
- mode_T = register_mode(&newmode);
-
- /* ANY */
- newmode.name = new_id_from_chars("ANY", 3);
- mode_ANY = register_mode(&newmode);
-
- /* BAD */
- newmode.name = new_id_from_chars("BAD", 3);
- mode_BAD = register_mode(&newmode);
-
- /* Internal Boolean Modes */
- newmode.sort = irms_internal_boolean;
-
- /* boolean */
- newmode.name = new_id_from_chars("b", 1);
- mode_b = register_mode(&newmode);
-
- /* Float Number Modes */
- newmode.sort = irms_float_number;
- newmode.arithmetic = irma_ieee754;
-
- /* float */
- newmode.name = new_id_from_chars("F", 1);
- newmode.sign = 1;
- newmode.size = 32;
- mode_F = register_mode(&newmode);
-
- /* double */
- newmode.name = new_id_from_chars("D", 1);
- newmode.sign = 1;
- newmode.size = 64;
- mode_D = register_mode(&newmode);
-
- /* extended */
- newmode.name = new_id_from_chars("E", 1);
- newmode.sign = 1;
- /* note that the tarval module is calculating with 80 bits, but we use
- * 96 bits, as that is what will be stored to memory by most hardware */
- newmode.size = 96;
- mode_E = register_mode(&newmode);
-
- /* Integer Number Modes */
- newmode.sort = irms_int_number;
- newmode.arithmetic = irma_twos_complement;
-
- /* signed byte */
- newmode.name = new_id_from_chars("Bs", 2);
- newmode.sign = 1;
- newmode.size = 8;
- newmode.modulo_shift = 32;
- mode_Bs = register_mode(&newmode);
-
- /* unsigned byte */
- newmode.name = new_id_from_chars("Bu", 2);
- newmode.arithmetic = irma_twos_complement;
- newmode.sign = 0;
- newmode.size = 8;
- newmode.modulo_shift = 32;
- mode_Bu = register_mode(&newmode);
-
- /* signed short integer */
- newmode.name = new_id_from_chars("Hs", 2);
- newmode.sign = 1;
- newmode.size = 16;
- newmode.modulo_shift = 32;
- mode_Hs = register_mode(&newmode);
-
- /* unsigned short integer */
- newmode.name = new_id_from_chars("Hu", 2);
- newmode.sign = 0;
- newmode.size = 16;
- newmode.modulo_shift = 32;
- mode_Hu = register_mode(&newmode);
-
- /* signed integer */
- newmode.name = new_id_from_chars("Is", 2);
- newmode.sign = 1;
- newmode.size = 32;
- newmode.modulo_shift = 32;
- mode_Is = register_mode(&newmode);
-
- /* unsigned integer */
- newmode.name = new_id_from_chars("Iu", 2);
- newmode.sign = 0;
- newmode.size = 32;
- newmode.modulo_shift = 32;
- mode_Iu = register_mode(&newmode);
-
- /* signed long integer */
- newmode.name = new_id_from_chars("Ls", 2);
- newmode.sign = 1;
- newmode.size = 64;
- newmode.modulo_shift = 64;
- mode_Ls = register_mode(&newmode);
-
- /* unsigned long integer */
- newmode.name = new_id_from_chars("Lu", 2);
- newmode.sign = 0;
- newmode.size = 64;
- newmode.modulo_shift = 64;
- mode_Lu = register_mode(&newmode);
-
- /* signed long long integer */
- newmode.name = new_id_from_chars("LLs", 3);
- newmode.sign = 1;
- newmode.size = 128;
- newmode.modulo_shift = 128;
- mode_LLs = register_mode(&newmode);
-
- /* unsigned long long integer */
- newmode.name = new_id_from_chars("LLu", 3);
- newmode.sign = 0;
- newmode.size = 128;
- newmode.modulo_shift = 128;
- mode_LLu = register_mode(&newmode);
-
- /* Reference Mode */
- newmode.sort = irms_reference;
- newmode.arithmetic = irma_twos_complement;
-
- /* pointer */
- newmode.name = new_id_from_chars("P", 1);
- newmode.sign = 0;
- newmode.size = 32;
- newmode.modulo_shift = 32;
- newmode.eq_signed = mode_Is;
- newmode.eq_unsigned = mode_Iu;
- mode_P = register_mode(&newmode);
+ mode_BB = new_internal_mode("BB", irms_block);
+ mode_X = new_internal_mode("X", irms_control_flow);
+ mode_M = new_internal_mode("M", irms_memory);
+ mode_T = new_internal_mode("T", irms_tuple);
+ mode_ANY = new_internal_mode("ANY", irms_any);
+ mode_BAD = new_internal_mode("BAD", irms_bad);
+ mode_b = new_internal_mode("b", irms_internal_boolean);
+
+ 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_Bs = new_int_mode("Bs", irma_twos_complement, 8, 1, 32);
+ mode_Bu = new_int_mode("Bu", irma_twos_complement, 8, 0, 32);
+ mode_Hs = new_int_mode("Hs", irma_twos_complement, 16, 1, 32);
+ mode_Hu = new_int_mode("Hu", irma_twos_complement, 16, 0, 32);
+ mode_Is = new_int_mode("Is", irma_twos_complement, 32, 1, 32);
+ 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 the machine specific modes to the predefined ones */
mode_P_code = mode_P;
mode_F = NULL;
mode_D = NULL;
- mode_E = NULL;
mode_Bs = NULL;
mode_Bu = NULL;
return mode->type;
}
+static inline unsigned get_mode_mantissa_size_(const ir_mode *mode)
+{
+ return mode->float_desc.mantissa_size;
+}
+
+static inline unsigned get_mode_exponent_size_(const ir_mode *mode)
+{
+ return mode->float_desc.exponent_size;
+}
+
/** mode module initialization, call once before use of any other function **/
void init_mode(void);
#define mode_is_datab(mode) mode_is_datab_(mode)
#define mode_is_dataM(mode) mode_is_dataM_(mode)
#define get_type_for_mode(mode) get_type_for_mode_(mode)
+#define get_mode_mantissa_size(mode) get_mode_mantissa_size_(mode)
+#define get_mode_exponent_size(mode) get_mode_exponent_size_(mode)
#endif
if (mode_is_int(n_mode) && get_mode_arithmetic(a_mode) == irma_ieee754) {
/* ConvI(ConvF(I)) -> I, iff float mantissa >= int mode */
unsigned int_mantissa = get_mode_size_bits(n_mode) - (mode_is_signed(n_mode) ? 1 : 0);
- unsigned float_mantissa = tarval_ieee754_get_mantissa_size(a_mode);
+ unsigned float_mantissa = get_mode_mantissa_size(a_mode);
if (float_mantissa >= int_mantissa) {
n = b;
return n;
}
}
- if (get_mode_arithmetic(mode) == irma_ieee754) {
+ if (get_mode_arithmetic(mode) == irma_ieee754
+ || get_mode_arithmetic(mode) == irma_x86_extended_float) {
if (is_Const(a)) {
ir_tarval *tv = get_Const_tarval(a);
- if (tarval_ieee754_get_exponent(tv) == 1 && tarval_ieee754_zero_mantissa(tv)
+ if (tarval_get_exponent(tv) == 1 && tarval_zero_mantissa(tv)
&& !tarval_is_negative(tv)) {
/* 2.0 * b = b + b */
n = new_rd_Add(get_irn_dbg_info(n), get_nodes_block(n), b, b, mode);
}
else if (is_Const(b)) {
ir_tarval *tv = get_Const_tarval(b);
- if (tarval_ieee754_get_exponent(tv) == 1 && tarval_ieee754_zero_mantissa(tv)
+ if (tarval_get_exponent(tv) == 1 && tarval_zero_mantissa(tv)
&& !tarval_is_negative(tv)) {
/* a * 2.0 = a + a */
n = new_rd_Add(get_irn_dbg_info(n), get_nodes_block(n), a, a, mode);
#ifndef FIRM_IR_IRDEFS_H
#define FIRM_IR_IRDEFS_H
+#include <stdbool.h>
+
#include "firm_types.h"
#include "irdom_t.h"
#include "irmode.h"
ir_op_ops ops; /**< The operations of the this op. */
};
+/** Helper values for ir_mode_sort. */
+enum ir_mode_sort_helper {
+ irmsh_is_num = 0x10, /**< mode represents a number */
+ irmsh_is_data = 0x20, /**< mode represents data (can be carried in registers) */
+ irmsh_is_datab = 0x40, /**< mode represents data or is internal boolean */
+ irmsh_is_dataM = 0x80, /**< mode represents data or is memory */
+};
+
+/**
+ * These values represent the different mode classes of value representations.
+ * Beware: do not change the order of these values without checking
+ * the mode_is
+ */
+typedef enum ir_mode_sort {
+ irms_control_flow = 0, /**< Marks all control flow modes. */
+ irms_block = 1,
+ irms_tuple = 2,
+ irms_any = 3,
+ irms_bad = 4,
+ irms_memory = 5 | irmsh_is_dataM, /**< Marks the memory mode. Not extensible. (irm_M) */
+
+ /** Internal boolean representation.
+ Storing to memory impossible, convert first. (irm_b) */
+ irms_internal_boolean = 6 | irmsh_is_datab,
+
+ /** A mode to represent entities.
+ Restricted int computations can be performed */
+ irms_reference = 7 | irmsh_is_data | irmsh_is_datab | irmsh_is_dataM,
+ /** A mode to represent int numbers.
+ Integer computations can be performed. */
+ irms_int_number = 8 | irmsh_is_data | irmsh_is_datab | irmsh_is_dataM | irmsh_is_num,
+ /** A mode to represent float numbers.
+ Floating point computations can be performed. */
+ irms_float_number = 9 | irmsh_is_data | irmsh_is_datab | irmsh_is_dataM | irmsh_is_num,
+} ir_mode_sort;
+
+/**
+ * A descriptor for an IEEE754 float value.
+ */
+typedef struct float_descriptor_t {
+ unsigned char exponent_size; /**< size of exponent in bits */
+ unsigned char mantissa_size; /**< size of mantissa in bits */
+ bool explicit_one; /**< set if the leading one is explicit */
+} float_descriptor_t;
+
/**
* Contains relevant information about a mode.
*
ident *name; /**< Name ident of this mode */
ir_type *type; /**< corresponding primitive type */
- /* ----------------------------------------------------------------------- */
+ /* ---------------------------------------------------------------------- */
/* On changing this struct you have to evaluate the mode_are_equal function!*/
- ir_mode_sort sort; /**< coarse classification of this mode:
- int, float, reference ...
- (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 */
-
- /* ----------------------------------------------------------------------- */
+ ir_mode_sort sort; /**< coarse classification of this mode:
+ int, float, reference ...
+ (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 */
+ float_descriptor_t float_desc;
+
+ /* ---------------------------------------------------------------------- */
ir_tarval *min; /**< the minimum value that can be expressed */
ir_tarval *max; /**< the maximum value that can be expressed */
ir_tarval *null; /**< the value 0 */
/* produce lowered modes */
env->high_signed = doubleword_signed;
env->high_unsigned = doubleword_unsigned;
- env->low_signed = new_ir_mode("WS", irms_int_number, size_bits, 1,
- arithmetic, modulo_shift);
- env->low_unsigned = new_ir_mode("WU", irms_int_number, size_bits, 0,
- arithmetic, modulo_shift);
+ env->low_signed = new_int_mode("WS", arithmetic, size_bits, 1,
+ modulo_shift);
+ env->low_unsigned = new_int_mode("WU", arithmetic, size_bits, 0,
+ modulo_shift);
}
static void enqueue_preds(ir_node *node)
if (ent_mode != mode) {
if (ent_mode == NULL ||
get_mode_size_bits(ent_mode) != get_mode_size_bits(mode) ||
- get_mode_sort(ent_mode) != get_mode_sort(mode) ||
get_mode_arithmetic(ent_mode) != irma_twos_complement ||
get_mode_arithmetic(mode) != irma_twos_complement)
return false;
return STAT_FC_0;
else if (tv == get_mode_one(mode))
return STAT_FC_1;
- else if (tarval_is_finite(tv) && tarval_ieee754_zero_mantissa(tv)) {
- int exp = tarval_ieee754_get_exponent(tv);
+ else if (tarval_is_finite(tv) && tarval_zero_mantissa(tv)) {
+ int exp = tarval_get_exponent(tv);
if (! tarval_is_negative(tv)) {
if (exp == 1)
/* our floating point value */
struct fp_value {
- ieee_descriptor_t desc;
+ float_descriptor_t desc;
unsigned char clss;
char sign;
char value[1]; /* exp[value_size] + mant[value_size] */
}
#if 0
-static void _power_of_ten(int exp, ieee_descriptor_t *desc, char *result)
+static void _power_of_ten(int exp, float_descriptor_t *desc, char *result)
{
char *build;
char *temp;
}
void *fc_val_from_str(const char *str, size_t len,
- const ieee_descriptor_t *desc, void *result)
+ const float_descriptor_t *desc, void *result)
{
char *buffer;
/* XXX excuse of an implementation to make things work */
long double val;
fp_value *tmp = (fp_value*) alloca(calc_buffer_size);
- ieee_descriptor_t tmp_desc;
+ float_descriptor_t tmp_desc;
buffer = (char*) alloca(len+1);
memcpy(buffer, str, len);
return fc_cast(tmp, desc, (fp_value*) result);
}
-fp_value *fc_val_from_ieee754(long double l, const ieee_descriptor_t *desc,
+fp_value *fc_val_from_ieee754(long double l, const float_descriptor_t *desc,
fp_value *result)
{
char *temp;
uint32_t mantissa1;
value_t buildval;
- ieee_descriptor_t desc;
+ float_descriptor_t desc;
unsigned mantissa_size;
size_t long_double_size = sizeof(long double);
return buildval.d;
}
-fp_value *fc_cast(const fp_value *value, const ieee_descriptor_t *desc,
+fp_value *fc_cast(const fp_value *value, const float_descriptor_t *desc,
fp_value *result)
{
char *temp;
return result;
}
-fp_value *fc_get_max(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_max(const float_descriptor_t *desc, fp_value *result)
{
if (result == NULL) result = calc_buffer;
return result;
}
-fp_value *fc_get_min(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_min(const float_descriptor_t *desc, fp_value *result)
{
if (result == NULL) result = calc_buffer;
return result;
}
-fp_value *fc_get_snan(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_snan(const float_descriptor_t *desc, fp_value *result)
{
if (result == NULL) result = calc_buffer;
return result;
}
-fp_value *fc_get_qnan(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_qnan(const float_descriptor_t *desc, fp_value *result)
{
if (result == NULL) result = calc_buffer;
return result;
}
-fp_value *fc_get_plusinf(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_plusinf(const float_descriptor_t *desc, fp_value *result)
{
char *mant;
return result;
}
-fp_value *fc_get_minusinf(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_minusinf(const float_descriptor_t *desc, fp_value *result)
{
if (result == NULL) result = calc_buffer;
}
/* Return non-zero if a given value can be converted lossless into another precision */
-int fc_can_lossless_conv_to(const fp_value *value, const ieee_descriptor_t *desc)
+int fc_can_lossless_conv_to(const fp_value *value, const float_descriptor_t *desc)
{
int v;
int exp_bias;
#include <stdlib.h>
#include "firm_types.h"
+#include "irtypes.h"
enum {
FC_DEC,
FC_NAN, /**< Not A Number */
} value_class_t;
-/**
- * A descriptor for an IEEE float value.
- */
-typedef struct ieee_descriptor_t {
- unsigned char exponent_size; /**< size of exponent in bits */
- unsigned char mantissa_size; /**< size of mantissa in bits */
- unsigned char explicit_one; /**< set if the leading one is explicit */
-} ieee_descriptor_t;
-
struct fp_value;
typedef struct fp_value fp_value;
int fc_get_buffer_length(void);
/*}@*/
-void *fc_val_from_str(const char *str, size_t len, const ieee_descriptor_t *desc, void *result);
+void *fc_val_from_str(const char *str, size_t len, const float_descriptor_t *desc, void *result);
/** get the representation of a floating point value
* This function tries to builds a representation having the same value as the
* @return The result pointer passed to the function. If this was NULL this returns
* a pointer to the internal accumulator buffer
*/
-fp_value *fc_val_from_ieee754(long double l, const ieee_descriptor_t *desc,
+fp_value *fc_val_from_ieee754(long double l, const float_descriptor_t *desc,
fp_value *result);
/** retrieve the float value of an internal value
* @return The result pointer passed to the function. If this was NULL this returns
* a pointer to the internal accumulator buffer
*/
-fp_value *fc_cast(const fp_value *val, const ieee_descriptor_t *desc, fp_value *result);
+fp_value *fc_cast(const fp_value *val, const float_descriptor_t *desc, fp_value *result);
/*@{*/
/** build a special float value
* @return The result pointer passed to the function. If this was NULL this returns
* a pointer to the internal accumulator buffer
*/
-fp_value *fc_get_min(const ieee_descriptor_t *desc, fp_value *result);
-fp_value *fc_get_max(const ieee_descriptor_t *desc, fp_value *result);
-fp_value *fc_get_snan(const ieee_descriptor_t *desc, fp_value *result);
-fp_value *fc_get_qnan(const ieee_descriptor_t *desc, fp_value *result);
-fp_value *fc_get_plusinf(const ieee_descriptor_t *desc, fp_value *result);
-fp_value *fc_get_minusinf(const ieee_descriptor_t *desc, fp_value *result);
+fp_value *fc_get_min(const float_descriptor_t *desc, fp_value *result);
+fp_value *fc_get_max(const float_descriptor_t *desc, fp_value *result);
+fp_value *fc_get_snan(const float_descriptor_t *desc, fp_value *result);
+fp_value *fc_get_qnan(const float_descriptor_t *desc, fp_value *result);
+fp_value *fc_get_plusinf(const float_descriptor_t *desc, fp_value *result);
+fp_value *fc_get_minusinf(const float_descriptor_t *desc, fp_value *result);
/*@}*/
int fc_is_zero(const fp_value *a);
/**
* Return non-zero if a given value can be converted lossless into another precision.
*/
-int fc_can_lossless_conv_to(const fp_value *value, const ieee_descriptor_t *desc);
+int fc_can_lossless_conv_to(const fp_value *value, const float_descriptor_t *desc);
/** Set new rounding mode
* This function sets the rounding mode to one of the following, returning
/** if this is set non-zero, the constant folding for floating point is OFF */
static int no_float = 0;
-/** IEEE-754r half precision */
-static const ieee_descriptor_t half_desc = { 5, 10, 0 };
-/** IEEE-754 single precision */
-static const ieee_descriptor_t single_desc = { 8, 23, 0 };
-/** IEEE-754 double precision */
-static const ieee_descriptor_t double_desc = { 11, 52, 0 };
-/** Intel x87 extended precision */
-static const ieee_descriptor_t extended_desc = { 15, 63, 1 };
-
-/** IEEE-754r quad precision */
-static const ieee_descriptor_t quad_desc = { 15, 112, 0 };
-
/****************************************************************************
* private functions
****************************************************************************/
/**
* get the float descriptor for given mode.
*/
-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:
- (void) quad_desc;
- panic("Unsupported mode in get_descriptor()");
- }
+static const float_descriptor_t *get_descriptor(const ir_mode *mode)
+{
+ return &mode->float_desc;
}
ir_tarval *new_integer_tarval_from_str(const char *str, size_t len, char sign,
*/
ir_tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
{
- const ieee_descriptor_t *desc;
+ const float_descriptor_t *desc;
assert(str);
assert(len);
assert(mode);
switch (get_mode_sort(mode)) {
- case irms_control_flow:
- case irms_memory:
- case irms_auxiliary:
- panic("Unsupported tarval creation with mode %F", mode);
-
case irms_internal_boolean:
/* match [tT][rR][uU][eE]|[fF][aA][lL][sS][eE] */
if (!strcasecmp(str, "true"))
/* FALLTHROUGH */
case irms_int_number:
return new_tarval_from_str_int(str, len, mode);
+ default:
+ panic("Unsupported tarval creation with mode %F", mode);
}
- panic("Unsupported tarval creation with mode %F", mode);
}
/*
ir_tarval *new_tarval_from_long_double(long double d, ir_mode *mode)
{
- const ieee_descriptor_t *desc;
+ const float_descriptor_t *desc;
assert(mode && (get_mode_sort(mode) == irms_float_number));
desc = get_descriptor(mode);
ir_tarval *get_tarval_max(ir_mode *mode)
{
- const ieee_descriptor_t *desc;
+ const float_descriptor_t *desc;
switch (get_mode_sort(mode)) {
- case irms_control_flow:
- case irms_memory:
- case irms_auxiliary:
- panic("mode %F does not support maximum value", mode);
-
case irms_internal_boolean:
return tarval_b_true;
case irms_int_number:
sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+ default:
+ panic("mode %F does not support maximum value", mode);
}
- return tarval_bad;
}
ir_tarval *get_tarval_min(ir_mode *mode)
{
- const ieee_descriptor_t *desc;
+ const float_descriptor_t *desc;
switch (get_mode_sort(mode)) {
- case irms_control_flow:
- case irms_memory:
- case irms_auxiliary:
- panic("mode %F does not support minimum value", mode);
-
case irms_internal_boolean:
return tarval_b_false;
case irms_int_number:
sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+ default:
+ panic("mode %F does not support minimum value", mode);
}
- return tarval_bad;
}
/** The bit pattern for the pointer NULL */
ir_tarval *get_tarval_null(ir_mode *mode)
{
switch (get_mode_sort(mode)) {
- case irms_control_flow:
- case irms_memory:
- case irms_auxiliary:
- panic("mode %F does not support null value", mode);
-
case irms_float_number:
return new_tarval_from_double(0.0, mode);
case irms_reference:
return new_tarval_from_long(_null_value, mode);
+ default:
+ panic("mode %F does not support null value", mode);
}
- return tarval_bad;
}
ir_tarval *get_tarval_one(ir_mode *mode)
{
switch (get_mode_sort(mode)) {
- case irms_control_flow:
- case irms_memory:
- case irms_auxiliary:
- panic("mode %F does not support one value", mode);
-
case irms_internal_boolean:
return tarval_b_true;
case irms_reference:
case irms_int_number:
return new_tarval_from_long(1l, mode);
+ default:
+ panic("mode %F does not support one value", mode);
}
- return tarval_bad;
}
ir_tarval *get_tarval_all_one(ir_mode *mode)
{
switch (get_mode_sort(mode)) {
- case irms_control_flow:
- case irms_memory:
- case irms_auxiliary:
- panic("mode %F does not support all-one value", mode);
-
case irms_int_number:
case irms_internal_boolean:
case irms_reference:
return tarval_not(get_mode_null(mode));
-
case irms_float_number:
return new_tarval_from_double(1.0, mode);
+
+ default:
+ panic("mode %F does not support all-one value", mode);
}
- return tarval_bad;
}
int tarval_is_constant(ir_tarval *tv)
ir_tarval *get_tarval_minus_one(ir_mode *mode)
{
switch (get_mode_sort(mode)) {
- case irms_control_flow:
- case irms_memory:
- case irms_auxiliary:
- case irms_internal_boolean:
- panic("mode %F does not support minus one value", mode);
-
case irms_reference:
return tarval_bad;
case irms_int_number:
return new_tarval_from_long(-1l, mode);
+
+ default:
+ panic("mode %F does not support minus one value", mode);
}
- return tarval_bad;
}
ir_tarval *get_tarval_nan(ir_mode *mode)
{
- const ieee_descriptor_t *desc;
+ const float_descriptor_t *desc;
if (get_mode_sort(mode) == irms_float_number) {
desc = get_descriptor(mode);
ir_tarval *get_tarval_plus_inf(ir_mode *mode)
{
if (get_mode_sort(mode) == irms_float_number) {
- const ieee_descriptor_t *desc = get_descriptor(mode);
+ const float_descriptor_t *desc = get_descriptor(mode);
fc_get_plusinf(desc, NULL);
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
} else
ir_tarval *get_tarval_minus_inf(ir_mode *mode)
{
if (get_mode_sort(mode) == irms_float_number) {
- const ieee_descriptor_t *desc = get_descriptor(mode);
+ const float_descriptor_t *desc = get_descriptor(mode);
fc_get_minusinf(desc, NULL);
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
} else
/* Here the two tarvals are unequal and of the same mode */
switch (get_mode_sort(a->mode)) {
- case irms_control_flow:
- case irms_memory:
- case irms_auxiliary:
- if (a == b)
- return ir_relation_equal;
- return ir_relation_false;
-
case irms_float_number:
/*
* BEWARE: we cannot compare a == b here, because
if (a == b)
return ir_relation_equal;
return a == tarval_b_true ? ir_relation_greater : ir_relation_less;
+
+ default:
+ panic("can't compare values of mode %F", a->mode);
}
- return ir_relation_false;
}
/*
{
char *buffer;
fp_value *res = NULL;
- const ieee_descriptor_t *desc;
+ const float_descriptor_t *desc;
int len;
carry_flag = -1;
return src;
switch (get_mode_sort(src->mode)) {
- case irms_control_flow:
- case irms_memory:
- case irms_auxiliary:
- break;
-
- /* cast float to something */
+ /* cast float to something */
case irms_float_number:
switch (get_mode_sort(dst_mode)) {
case irms_float_number:
return get_tarval_overflow(buffer, src->length, dst_mode);
}
break;
+ default:
+ return tarval_bad;
}
return tarval_bad;
return snprintf(buf, len, "%s%s%s", prefix, (tv == tarval_b_true) ? "true" : "false", suffix);
}
- case irms_control_flow:
- case irms_memory:
- case irms_auxiliary:
- if (tv == tarval_bad)
- return snprintf(buf, len, "<TV_BAD>");
- if (tv == tarval_undefined)
- return snprintf(buf, len, "<TV_UNDEF>");
- if (tv == tarval_unreachable)
- return snprintf(buf, len, "<TV_UNREACHABLE>");
- if (tv == tarval_reachable)
- return snprintf(buf, len, "<TV_REACHABLE>");
+ default:
return snprintf(buf, len, "<TV_??""?>");
}
-
- return 0;
}
/**
* Returns non-zero if the mantissa of a floating point IEEE-754
* tarval is zero (i.e. 1.0Exxx)
*/
-int tarval_ieee754_zero_mantissa(ir_tarval *tv)
+int tarval_zero_mantissa(ir_tarval *tv)
{
- assert(get_mode_arithmetic(tv->mode) == irma_ieee754);
+ assert(get_mode_arithmetic(tv->mode) == irma_ieee754
+ || get_mode_arithmetic(tv->mode) == irma_x86_extended_float);
return fc_zero_mantissa((const fp_value*) tv->value);
}
/* Returns the exponent of a floating point IEEE-754 tarval. */
-int tarval_ieee754_get_exponent(ir_tarval *tv)
+int tarval_get_exponent(ir_tarval *tv)
{
- assert(get_mode_arithmetic(tv->mode) == irma_ieee754);
+ assert(get_mode_arithmetic(tv->mode) == irma_ieee754
+ || get_mode_arithmetic(tv->mode) == irma_x86_extended_float);
return fc_get_exponent((const fp_value*) tv->value);
}
*/
int tarval_ieee754_can_conv_lossless(ir_tarval *tv, ir_mode *mode)
{
- const ieee_descriptor_t *desc = get_descriptor(mode);
+ const float_descriptor_t *desc = get_descriptor(mode);
return fc_can_lossless_conv_to((const fp_value*) tv->value, desc);
}
return fc_is_exact();
}
-/* Return the size of the mantissa in bits (including possible
- implicit bits) for the given mode. */
-unsigned tarval_ieee754_get_mantissa_size(const ir_mode *mode)
-{
- const ieee_descriptor_t *desc;
-
- assert(get_mode_arithmetic(mode) == irma_ieee754);
- desc = get_descriptor(mode);
-
- return desc->mantissa_size + desc->explicit_one;
-}
-
/* check if its the a floating point NaN */
int tarval_is_NaN(ir_tarval *tv)
{