- C99 feature removed
[libfirm] / ir / be / ia32 / ia32_transform.c
index 145af7a..7c8d69b 100644 (file)
@@ -272,15 +272,19 @@ static ir_node *gen_Const(ir_node *node)
                                res  = load;
                                set_ia32_ls_mode(load, mode);
                        } else {
+                               ir_mode *ls_mode;
+
                                floatent = create_float_const_entity(node);
+                               /* create_float_const_ent is smart and sometimes creates
+                                  smaller entities */
+                               ls_mode  = get_type_mode(get_entity_type(floatent));
 
-                               load     = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode);
+                               load     = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem,
+                                                           ls_mode);
                                set_ia32_op_type(load, ia32_AddrModeS);
                                set_ia32_am_sc(load, floatent);
                                arch_irn_add_flags(load, arch_irn_flags_rematerializable);
                                res = new_r_Proj(current_ir_graph, block, load, mode_vfp, pn_ia32_vfld_res);
-                               /* take the mode from the entity */
-                               set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
                        }
                }
 end:
@@ -2568,8 +2572,8 @@ static ir_node *create_Switch(ir_node *node)
        ir_node  *block      = be_transform_node(get_nodes_block(node));
        ir_node  *sel        = get_Cond_selector(node);
        ir_node  *new_sel    = be_transform_node(sel);
-       int       switch_min = INT_MAX;
-       int       switch_max = INT_MIN;
+       long      switch_min = LONG_MAX;
+       long      switch_max = LONG_MIN;
        long      default_pn = get_Cond_defaultProj(node);
        ir_node  *new_node;
        const ir_edge_t *edge;
@@ -2589,7 +2593,7 @@ static ir_node *create_Switch(ir_node *node)
                        switch_max = pn;
        }
 
-       if ((unsigned) (switch_max - switch_min) > 256000) {
+       if ((unsigned long) (switch_max - switch_min) > 256000) {
                panic("Size of switch %+F bigger than 256000", node);
        }
 
@@ -3514,11 +3518,15 @@ static ir_node *gen_Conv(ir_node *node)
                new_op = be_transform_node(op);
                /* we convert from float ... */
                if (mode_is_float(tgt_mode)) {
+#if 0
+                       /* Matze: I'm a bit unsure what the following is for? seems wrong
+                        * to me... */
                        if (src_mode == mode_E && tgt_mode == mode_D
                                        && !get_Conv_strict(node)) {
                                DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
                                return new_op;
                        }
+#endif
 
                        /* ... to float */
                        if (ia32_cg_config.use_sse2) {
@@ -3528,9 +3536,18 @@ static ir_node *gen_Conv(ir_node *node)
                                set_ia32_ls_mode(res, tgt_mode);
                        } else {
                                if (get_Conv_strict(node)) {
-                                       res = gen_x87_strict_conv(tgt_mode, new_op);
-                                       SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
-                                       return res;
+                                       /* if fp_no_float_fold is not set then we assume that we
+                                        * don't have any float operations in a non
+                                        * mode_float_arithmetic mode and can skip strict upconvs */
+                                       if (src_bits < tgt_bits
+                                                       && !(get_irg_fp_model(current_ir_graph) & fp_no_float_fold)) {
+                                               DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
+                                               return new_op;
+                                       } else {
+                                               res = gen_x87_strict_conv(tgt_mode, new_op);
+                                               SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
+                                               return res;
+                                       }
                                }
                                DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
                                return new_op;
@@ -3557,24 +3574,15 @@ static ir_node *gen_Conv(ir_node *node)
                                                            nomem, new_op);
                                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);
                                res = gen_x87_gp_to_fp(node, src_mode);
-                               if (get_Conv_strict(node)) {
-                                       /* The strict-Conv is only necessary, if the int mode has more bits
-                                        * than the float mantissa */
-                                       size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
-                                       size_t float_mantissa;
-                                       /* FIXME There is no way to get the mantissa size of a mode */
-                                       switch (get_mode_size_bits(tgt_mode)) {
-                                               case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
-                                               case 64: float_mantissa = 52 + 1; break;
-                                               case 80:
-                                               case 96: float_mantissa = 64;     break;
-                                               default: float_mantissa = 0;      break;
-                                       }
-                                       if (float_mantissa < int_mantissa) {
-                                               res = gen_x87_strict_conv(tgt_mode, res);
-                                               SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
-                                       }
+
+                               /* we need a strict-Conv, if the int mode has more bits than the
+                                * float mantissa */
+                               if (float_mantissa < int_mantissa) {
+                                       res = gen_x87_strict_conv(tgt_mode, res);
+                                       SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
                                }
                                return res;
                        }