ir_mode: simplify interface, improve float-mode handling
authorMatthias Braun <matze@braunis.de>
Tue, 25 Oct 2011 12:47:25 +0000 (14:47 +0200)
committerMatthias Braun <matze@braunis.de>
Thu, 27 Oct 2011 12:25:14 +0000 (14:25 +0200)
The main change here is splitting new_ir_mode into new_int_mode,
new_reference_mode and new_float_mode. You can now specify
mantissa+exponent size in new_float_mode. This also changes:

- x86 80bit-FP mode is NOT a ieee754 don't put "ieee754" into functions
  names that can also handle x86 80bit fps
- Move ieee_descriptor_t from tarval module into ir_mode struct
  (and rename to float_descriptor_t)
- Introduce mode_Q which represents binary128 from ieee754
- You can ask float modes for mantissa/exponent sizes now
- Fix endianess when emitting big float values in begnuas
- A bunch of long double fixes in ia32: the mode there has 10bytes
  (80bit) but the variables typically are 12 or 16 byte big
- This fixes some problems of sparc binary128 handling

29 files changed:
include/libfirm/irhooks.h
include/libfirm/irmode.h
include/libfirm/tv.h
ir/ana/irmemory.c
ir/be/TEMPLATE/TEMPLATE_spec.pl
ir/be/arm/arm_spec.pl
ir/be/arm/arm_transform.c
ir/be/begnuas.c
ir/be/ia32/bearch_ia32.c
ir/be/ia32/bearch_ia32_t.h
ir/be/ia32/ia32_common_transform.c
ir/be/ia32/ia32_common_transform.h
ir/be/ia32/ia32_emitter.c
ir/be/ia32/ia32_spec.pl
ir/be/ia32/ia32_transform.c
ir/be/sparc/bearch_sparc.c
ir/be/sparc/sparc_new_nodes.c
ir/be/sparc/sparc_spec.pl
ir/ir/irio.c
ir/ir/irmode.c
ir/ir/irmode_t.h
ir/ir/iropt.c
ir/ir/irtypes.h
ir/lower/lower_dw.c
ir/opt/scalar_replace.c
ir/stat/const_stat.c
ir/tv/fltcalc.c
ir/tv/fltcalc.h
ir/tv/tv.c

index c981f63..914ec5c 100644 (file)
@@ -163,7 +163,7 @@ typedef struct hook_entry {
                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);
@@ -281,7 +281,7 @@ FIRM_API hook_entry_t *hooks[hook_last];
   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))
index c07e4cd..e6d4af8 100644 (file)
 #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.
@@ -86,6 +53,7 @@ typedef enum ir_mode_arithmetic {
        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;
 
@@ -105,21 +73,38 @@ FIRM_API const char *get_mode_arithmetic_name(ir_mode_arithmetic ari);
  * 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.
@@ -137,9 +122,6 @@ FIRM_API ident *get_mode_ident(const ir_mode *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);
 
@@ -237,9 +219,9 @@ FIRM_API ir_tarval *get_mode_NAN(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 */
@@ -270,7 +252,7 @@ FIRM_API ir_mode *mode_BAD;/**< bad mode */
 
 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);
@@ -424,6 +406,16 @@ FIRM_API ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode);
  */
 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,
index f5c877e..10693fb 100644 (file)
@@ -753,12 +753,12 @@ FIRM_API int tarval_snprintf(char *buf, size_t buflen, ir_tarval *tv);
 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
@@ -766,7 +766,7 @@ FIRM_API int tarval_ieee754_zero_mantissa(ir_tarval *tv);
  *
  * @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
@@ -778,16 +778,10 @@ FIRM_API int tarval_ieee754_get_exponent(ir_tarval *tv);
 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.
  */
index f1f5870..bbf1a6f 100644 (file)
@@ -820,7 +820,6 @@ static int is_hidden_cast(const ir_mode *mode, const ir_mode *ent_mode)
        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;
index 63ed205..0a63c5b 100644 (file)
@@ -9,7 +9,7 @@ $arch = "TEMPLATE";
 # 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:
index 306770e..39419ff 100644 (file)
@@ -10,7 +10,7 @@ $arch = "arm";
 #
 $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 = (
index 3cc07d8..7e73777 100644 (file)
@@ -539,7 +539,6 @@ static ir_node *gen_Add(ir_node *node)
                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");
@@ -586,7 +585,6 @@ static ir_node *gen_Mul(ir_node *node)
                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");
@@ -606,14 +604,12 @@ static ir_node *gen_Div(ir_node *node)
        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");
@@ -700,7 +696,6 @@ static ir_node *gen_Sub(ir_node *node)
                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");
@@ -926,7 +921,6 @@ static ir_node *gen_Minus(ir_node *node)
                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");
@@ -955,7 +949,6 @@ static ir_node *gen_Load(ir_node *node)
                        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");
@@ -998,7 +991,6 @@ static ir_node *gen_Store(ir_node *node)
                        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");
@@ -1119,8 +1111,7 @@ static ir_node *gen_Cond(ir_node *node)
 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];
@@ -1142,8 +1133,6 @@ static int is_fpa_immediate(tarval *tv)
        case 64:
                i = FPA_IMM_DOUBLE;
                break;
-       default:
-               i = FPA_IMM_EXTENDED;
        }
 
        if (tarval_is_negative(tv)) {
@@ -1171,7 +1160,6 @@ static ir_node *gen_Const(ir_node *node)
                        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");
@@ -2142,15 +2130,6 @@ static void arm_init_fpa_immediate(void)
        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);
 }
 
 /**
@@ -2164,7 +2143,7 @@ void arm_transform_graph(ir_graph *irg)
        ir_type   *frame_type;
 
        mode_gp = mode_Iu;
-       mode_fp = mode_E;
+       mode_fp = mode_F;
 
        if (! imm_initialized) {
                arm_init_fpa_immediate();
index b89f43b..0946e50 100644 (file)
@@ -577,7 +577,7 @@ void be_gas_emit_function_epilog(const ir_entity *entity)
  * @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:
@@ -585,53 +585,22 @@ static void emit_arith_tarval(ir_tarval *tv, int bytes)
                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;
        }
 
@@ -701,7 +670,7 @@ static ir_tarval *get_atomic_init_tv(ir_node *init)
  * @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);
@@ -712,11 +681,11 @@ static void do_emit_atomic_init(be_gas_decl_env_t *env, ir_node *init)
 
        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:
@@ -760,27 +729,27 @@ static void do_emit_atomic_init(be_gas_decl_env_t *env, ir_node *init)
                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:
@@ -800,50 +769,16 @@ static void do_emit_atomic_init(be_gas_decl_env_t *env, ir_node *init)
 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!!
@@ -948,6 +883,7 @@ typedef enum normal_or_bitfield_kind {
 
 typedef struct {
        normal_or_bitfield_kind kind;
+       ir_type                *type;
        union {
                ir_node                *value;
                ir_tarval              *tarval;
@@ -1099,10 +1035,12 @@ static void emit_ir_initializer(normal_or_bitfield *vals,
 
                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;
@@ -1112,9 +1050,11 @@ static void emit_ir_initializer(normal_or_bitfield *vals,
 
                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;
@@ -1179,6 +1119,97 @@ static void emit_ir_initializer(normal_or_bitfield *vals,
        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;
@@ -1214,37 +1245,31 @@ static void emit_initializer(be_gas_decl_env_t *env, const ir_entity *entity)
        /* 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;
@@ -1346,7 +1371,7 @@ static void emit_compound_graph_init(be_gas_decl_env_t *env,
                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;
index 2be449e..f6b4eee 100644 (file)
@@ -99,7 +99,9 @@
 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;
@@ -1466,7 +1468,6 @@ static ia32_isa_t ia32_isa_template = {
                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 */
@@ -1531,14 +1532,13 @@ static arch_env_t *ia32_init(FILE *file_handle)
        *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();
 
@@ -1561,7 +1561,6 @@ static void ia32_done(void *self)
        be_gas_emit_decls(isa->base.main_env);
 
        pmap_destroy(isa->tv_ent);
-       pmap_destroy(isa->types);
 
        be_emit_exit();
 
@@ -2125,13 +2124,21 @@ static const backend_params *ia32_get_libfirm_params(void)
                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);
 
@@ -2148,13 +2155,8 @@ static const backend_params *ia32_get_libfirm_params(void)
                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;
 }
index 0e1a968..8763064 100644 (file)
@@ -64,11 +64,10 @@ typedef struct ia32_irg_data_t {
  * 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 */
 };
 
 /**
@@ -101,6 +100,9 @@ extern transformer_t be_transformer;
 
 /** 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)
 {
index e374eea..758c09c 100644 (file)
@@ -64,30 +64,19 @@ static int check_immediate_constraint(long val, char immediate_constraint_type)
        }
 }
 
-/**
- * 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;
@@ -112,8 +101,11 @@ ir_entity *ia32_create_float_const_entity(ir_node *cnst)
                }
        }
 
-       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);
index 3faf53f..9b03bb6 100644 (file)
@@ -46,13 +46,14 @@ struct constraint_t {
 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.
index b362e0a..31a60d5 100644 (file)
@@ -1364,11 +1364,7 @@ static void Copy_emitter(const ir_node *node, const ir_node *op)
        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)
@@ -2345,13 +2341,9 @@ static void bemit_copy(const ir_node *copy)
        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)
index 5aad7f0..a939448 100644 (file)
@@ -4,6 +4,13 @@
 
 $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)
@@ -22,7 +29,7 @@ $state       =  8; # register represents a state
                { 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 },
@@ -33,7 +40,7 @@ $state       =  8; # register represents a state
                { 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" },
@@ -45,7 +52,7 @@ $state       =  8; # register represents a state
                { 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" },
@@ -57,7 +64,7 @@ $state       =  8; # register represents a state
                { 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 },
@@ -68,11 +75,11 @@ $state       =  8; # register represents a state
                { 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 },
@@ -208,10 +215,6 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
 %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",
@@ -1119,7 +1122,7 @@ NoReg_VFP => {
        reg_req   => { out => [ "vfp_NOREG:I" ] },
        units     => [],
        emit      => "",
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        latency   => 0,
        attr_type => "ia32_x87_attr_t",
 },
@@ -1132,7 +1135,7 @@ NoReg_XMM => {
        units     => [],
        emit      => "",
        latency   => 0,
-       mode      => "mode_E"
+       mode      => $mode_xmm,
 },
 
 ChangeCW => {
@@ -2042,7 +2045,7 @@ vfadd => {
        am        => "source,binary",
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2056,7 +2059,7 @@ vfmul => {
        am        => "source,binary",
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2070,7 +2073,7 @@ vfsub => {
        am        => "source,binary",
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2091,7 +2094,7 @@ vfprem => {
        ins       => [ "left", "right", "fpcw" ],
        latency   => 20,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2101,7 +2104,7 @@ vfabs => {
        ins       => [ "value" ],
        latency   => 2,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2111,7 +2114,7 @@ vfchs => {
        ins       => [ "value" ],
        latency   => 2,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2187,7 +2190,7 @@ vfldz => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2197,7 +2200,7 @@ vfld1 => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2207,7 +2210,7 @@ vfldpi => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2217,7 +2220,7 @@ vfldln2 => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2227,7 +2230,7 @@ vfldlg2 => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2237,7 +2240,7 @@ vfldl2t => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2247,7 +2250,7 @@ vfldl2e => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
index 7e3bfd6..8319bbe 100644 (file)
 /* 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)
 
@@ -215,20 +201,23 @@ static ir_node *get_symconst_base(void)
  */
 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);
@@ -285,7 +274,7 @@ static ir_node *gen_Const(ir_node *node)
                                        }
                                }
 #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,
@@ -296,11 +285,11 @@ static ir_node *gen_Const(ir_node *node)
                                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);
@@ -308,7 +297,7 @@ static ir_node *gen_Const(ir_node *node)
                                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));
@@ -327,9 +316,8 @@ end:
                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);
 
@@ -359,9 +347,9 @@ static ir_node *gen_SymConst(ir_node *node)
 
        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 {
@@ -386,64 +374,18 @@ static ir_node *gen_SymConst(ir_node *node)
        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;
 }
 
 /**
@@ -454,33 +396,27 @@ static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
 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;
 }
 
@@ -488,58 +424,56 @@ static ir_type *ia32_create_float_array(ir_type *tp)
 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;
        }
@@ -639,7 +573,11 @@ static void build_address(ia32_address_mode_t *am, ir_node *node,
 
        /* 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;
@@ -2681,7 +2619,7 @@ static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base,
                /* 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;
@@ -2799,8 +2737,8 @@ static ir_node *gen_general_Store(ir_node *node)
  */
 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
@@ -3258,7 +3196,7 @@ static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **ne
 
        }
 
-       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);
@@ -3508,31 +3446,15 @@ static ir_node *gen_Mux(ir_node *node)
 
                        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");
                        }
 
@@ -3733,7 +3655,7 @@ static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
        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;
 }
 
@@ -3987,7 +3909,7 @@ static ir_node *gen_Conv(ir_node *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
@@ -5674,7 +5596,7 @@ static ir_node *gen_Proj_ASM(ir_node *node)
        } 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");
        }
index a4c86ef..aca94f0 100644 (file)
@@ -479,12 +479,10 @@ static const backend_params *sparc_get_backend_params(void)
        };
 
        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);
 
@@ -495,13 +493,11 @@ static const backend_params *sparc_get_backend_params(void)
                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;
 }
index 12be7e2..5ae98a6 100644 (file)
@@ -40,6 +40,7 @@
 #include "xmalloc.h"
 
 #include "bearch.h"
+#include "bearch_sparc_t.h"
 
 #include "sparc_nodes_attr.h"
 #include "sparc_new_nodes.h"
index 4881f74..61ac07c 100644 (file)
@@ -8,7 +8,7 @@ $mode_flags   = "mode_Bu";
 $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 = (
index 863f4fc..c2b3702 100644 (file)
@@ -71,7 +71,6 @@ typedef enum typetag_t
        tt_initializer,
        tt_iro,
        tt_keyword,
-       tt_mode_sort,
        tt_mode_arithmetic,
        tt_pin_state,
        tt_tpo,
@@ -87,7 +86,9 @@ typedef enum keyword_t
        kw_constirg,
        kw_entity,
        kw_irg,
-       kw_mode,
+       kw_int_mode,
+       kw_reference_mode,
+       kw_float_mode,
        kw_modes,
        kw_type,
        kw_typegraph,
@@ -181,14 +182,6 @@ static void symtbl_init(void)
        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);
@@ -208,7 +201,9 @@ static void symtbl_init(void)
        INSERTKEYWORD(constirg);
        INSERTKEYWORD(entity);
        INSERTKEYWORD(irg);
-       INSERTKEYWORD(mode);
+       INSERTKEYWORD(int_mode);
+       INSERTKEYWORD(float_mode);
+       INSERTKEYWORD(reference_mode);
        INSERTKEYWORD(modes);
        INSERTKEYWORD(type);
        INSERTKEYWORD(typegraph);
@@ -788,20 +783,6 @@ static void export_node(ir_node *irn, void *ctx)
        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();
@@ -810,28 +791,33 @@ static void export_modes(io_env_t *env)
 
        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);
        }
@@ -1249,7 +1235,6 @@ static const char *get_typetag_name(typetag_t typetag)
        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";
@@ -1754,32 +1739,38 @@ static int parse_modes(io_env_t *env)
 
                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');
index 3e76847..31e27c2 100644 (file)
@@ -27,8 +27,8 @@
 
 #include <stdlib.h>
 #include <string.h>
-
 #include <stddef.h>
+#include <stdbool.h>
 
 #include "irprog_t.h"
 #include "irmode_t.h"
@@ -55,22 +55,19 @@ const char *get_mode_arithmetic_name(ir_mode_arithmetic ari)
                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;
 }
 
 /**
@@ -119,9 +116,12 @@ static void set_mode_values(ir_mode* mode)
                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;
@@ -146,9 +146,9 @@ ir_mode *mode_ANY;
 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 */
@@ -172,11 +172,10 @@ ir_mode *mode_P_data;   /**< machine specific pointer mode for data addresses */
  * 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; }
@@ -219,74 +218,84 @@ void set_modeP_data(ir_mode *p)
        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 */
@@ -300,11 +309,6 @@ const char *get_mode_name(const ir_mode *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);
@@ -453,6 +457,16 @@ int (mode_is_dataM)(const ir_mode *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)
 {
@@ -583,177 +597,43 @@ void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
        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;
@@ -873,7 +753,6 @@ void finish_mode(void)
 
        mode_F   = NULL;
        mode_D   = NULL;
-       mode_E   = NULL;
 
        mode_Bs  = NULL;
        mode_Bu  = NULL;
index 06cf8a8..19d8f5c 100644 (file)
@@ -143,6 +143,16 @@ static inline ir_type *get_type_for_mode_(const ir_mode *mode)
        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);
 
@@ -169,5 +179,7 @@ void finish_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
index b67e8ed..a2300fc 100644 (file)
@@ -1249,7 +1249,7 @@ restart:
                        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;
@@ -3230,10 +3230,11 @@ static ir_node *transform_node_Mul(ir_node *n)
                        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);
@@ -3243,7 +3244,7 @@ static ir_node *transform_node_Mul(ir_node *n)
                }
                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);
index e10eced..b5786a5 100644 (file)
@@ -26,6 +26,8 @@
 #ifndef FIRM_IR_IRDEFS_H
 #define FIRM_IR_IRDEFS_H
 
+#include <stdbool.h>
+
 #include "firm_types.h"
 #include "irdom_t.h"
 #include "irmode.h"
@@ -72,6 +74,51 @@ struct ir_op {
        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.
  *
@@ -97,18 +144,18 @@ struct ir_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 */
index a7b908a..04bab7b 100644 (file)
@@ -2758,10 +2758,10 @@ static void setup_modes(void)
        /* 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)
index 053b680..85779e1 100644 (file)
@@ -174,7 +174,6 @@ static bool check_load_store_mode(ir_mode *mode, ir_mode *ent_mode)
        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;
index 296e74b..c6df3d6 100644 (file)
@@ -73,8 +73,8 @@ static float_classify_t classify_float_value(ir_tarval *tv)
                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)
index f9ac91f..2d9d9ec 100644 (file)
@@ -110,7 +110,7 @@ typedef union {
 
 /* 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] */
@@ -722,7 +722,7 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result)
 }
 
 #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;
@@ -838,14 +838,14 @@ int fc_get_buffer_length(void)
 }
 
 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);
@@ -861,7 +861,7 @@ void *fc_val_from_str(const char *str, size_t 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;
@@ -973,7 +973,7 @@ long double fc_val_to_ieee754(const fp_value *val)
        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);
@@ -1027,7 +1027,7 @@ long double fc_val_to_ieee754(const fp_value *val)
        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;
@@ -1087,7 +1087,7 @@ fp_value *fc_cast(const fp_value *value, const ieee_descriptor_t *desc,
        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;
 
@@ -1104,7 +1104,7 @@ fp_value *fc_get_max(const ieee_descriptor_t *desc, fp_value *result)
        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;
 
@@ -1114,7 +1114,7 @@ fp_value *fc_get_min(const ieee_descriptor_t *desc, fp_value *result)
        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;
 
@@ -1130,7 +1130,7 @@ fp_value *fc_get_snan(const ieee_descriptor_t *desc, fp_value *result)
        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;
 
@@ -1149,7 +1149,7 @@ fp_value *fc_get_qnan(const ieee_descriptor_t *desc, fp_value *result)
        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;
 
@@ -1170,7 +1170,7 @@ fp_value *fc_get_plusinf(const ieee_descriptor_t *desc, fp_value *result)
        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;
 
@@ -1332,7 +1332,7 @@ int fc_get_exponent(const fp_value *value)
 }
 
 /* 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;
index 1b07f6d..dd5d4f8 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <stdlib.h>
 #include "firm_types.h"
+#include "irtypes.h"
 
 enum {
        FC_DEC,
@@ -58,15 +59,6 @@ typedef enum {
        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;
 
@@ -81,7 +73,7 @@ const void *fc_get_buffer(void);
 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
@@ -100,7 +92,7 @@ void *fc_val_from_str(const char *str, size_t len, const ieee_descriptor_t *desc
  * @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
@@ -130,7 +122,7 @@ long double fc_val_to_ieee754(const fp_value *val);
  * @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
@@ -145,12 +137,12 @@ fp_value *fc_cast(const fp_value *val, const ieee_descriptor_t *desc, fp_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);
@@ -200,7 +192,7 @@ int fc_get_exponent(const fp_value *value);
 /**
  * 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
index d15de35..47ef2d4 100644 (file)
@@ -100,18 +100,6 @@ static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP;
 /** 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
  ****************************************************************************/
@@ -304,22 +292,9 @@ ir_tarval *tarval_unreachable = &reserved_tv[5];
 /**
  * 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,
@@ -393,18 +368,13 @@ static ir_tarval *new_tarval_from_str_int(const char *str, size_t len,
  */
 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"))
@@ -426,8 +396,9 @@ ir_tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
                /* 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);
 }
 
 /*
@@ -483,7 +454,7 @@ long get_tarval_long(ir_tarval* tv)
 
 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);
@@ -569,14 +540,9 @@ ir_tarval *(get_tarval_unreachable)(void)
 
 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;
 
@@ -589,20 +555,16 @@ ir_tarval *get_tarval_max(ir_mode *mode)
        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;
 
@@ -615,8 +577,9 @@ ir_tarval *get_tarval_min(ir_mode *mode)
        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 */
@@ -625,11 +588,6 @@ static long _null_value = 0;
 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);
 
@@ -639,18 +597,14 @@ ir_tarval *get_tarval_null(ir_mode *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;
 
@@ -660,28 +614,25 @@ ir_tarval *get_tarval_one(ir_mode *mode)
        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)
@@ -696,12 +647,6 @@ 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;
 
@@ -710,13 +655,15 @@ ir_tarval *get_tarval_minus_one(ir_mode *mode)
 
        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);
@@ -729,7 +676,7 @@ ir_tarval *get_tarval_nan(ir_mode *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
@@ -739,7 +686,7 @@ ir_tarval *get_tarval_plus_inf(ir_mode *mode)
 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
@@ -825,13 +772,6 @@ ir_relation tarval_cmp(ir_tarval *a, ir_tarval *b)
 
        /* 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
@@ -854,8 +794,10 @@ ir_relation tarval_cmp(ir_tarval *a, ir_tarval *b)
                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;
 }
 
 /*
@@ -865,7 +807,7 @@ ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
 {
        char                    *buffer;
        fp_value                *res = NULL;
-       const ieee_descriptor_t *desc;
+       const float_descriptor_t *desc;
        int                      len;
 
        carry_flag = -1;
@@ -877,12 +819,7 @@ ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
                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:
@@ -958,6 +895,8 @@ ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
                        return get_tarval_overflow(buffer, src->length, dst_mode);
                }
                break;
+       default:
+               return tarval_bad;
        }
 
        return tarval_bad;
@@ -1494,21 +1433,9 @@ int tarval_snprintf(char *buf, size_t len, ir_tarval *tv)
                        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;
 }
 
 /**
@@ -1662,16 +1589,18 @@ int get_tarval_lowest_bit(ir_tarval *tv)
  * 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);
 }
 
@@ -1681,7 +1610,7 @@ int tarval_ieee754_get_exponent(ir_tarval *tv)
  */
 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);
 }
 
@@ -1691,18 +1620,6 @@ unsigned tarval_ieee754_get_exact(void)
        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)
 {