nicer indenting
[libfirm] / ir / be / ia32 / ia32_transform.c
index 9e807ec..f551944 100644 (file)
@@ -181,12 +181,12 @@ static ir_type *get_prim_type(pmap *types, ir_mode *mode)
 }
 
 /**
- * Get an entity that is initialized with a tarval
+ * Get an atomic entity that is initialized with a tarval
  */
-static ir_entity *get_entity_for_tv(ia32_code_gen_t *cg, ir_node *cnst)
+static ir_entity *ia32_get_entity_for_tv(ia32_isa_t *isa, ir_node *cnst)
 {
        tarval *tv    = get_Const_tarval(cnst);
-       pmap_entry *e = pmap_find(cg->isa->tv_ent, tv);
+       pmap_entry *e = pmap_find(isa->tv_ent, tv);
        ir_entity *res;
        ir_graph *rem;
 
@@ -194,7 +194,7 @@ static ir_entity *get_entity_for_tv(ia32_code_gen_t *cg, ir_node *cnst)
                ir_mode *mode = get_irn_mode(cnst);
                ir_type *tp = get_Const_type(cnst);
                if (tp == firm_unknown_type)
-                       tp = get_prim_type(cg->isa->types, mode);
+                       tp = get_prim_type(isa->types, mode);
 
                res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);
 
@@ -210,7 +210,7 @@ static ir_entity *get_entity_for_tv(ia32_code_gen_t *cg, ir_node *cnst)
                set_atomic_ent_value(res, new_Const_type(tv, tp));
                current_ir_graph = rem;
 
-               pmap_insert(cg->isa->tv_ent, tv, res);
+               pmap_insert(isa->tv_ent, tv, res);
        } else {
                res = e->value;
        }
@@ -233,10 +233,15 @@ static int is_Const_1(ir_node *node) {
 }
 
 static int is_Const_Minus_1(ir_node *node) {
-       tarval *tv;
+       tarval  *tv;
+       ir_mode *mode;
        if(!is_Const(node))
                return 0;
 
+       mode = get_irn_mode(node);
+       if(!mode_is_signed(mode))
+               return 0;
+
        tv = get_Const_tarval(node);
        tv = tarval_neg(tv);
 
@@ -259,10 +264,24 @@ static ir_node *gen_Const(ir_node *node) {
                ir_node   *nomem = new_NoMem();
                ir_node   *load;
                ir_entity *floatent;
+               cnst_classify_t clss = classify_Const(node);
 
-               if (! USE_SSE2(env_cg)) {
-                       cnst_classify_t clss = classify_Const(node);
+               if (USE_SSE2(env_cg)) {
+                       if (clss == CNST_NULL) {
+                               load = new_rd_ia32_xZero(dbgi, irg, block);
+                               set_ia32_ls_mode(load, mode);
+                               res  = load;
+                       } else {
+                               floatent = ia32_get_entity_for_tv(env_cg->isa, node);
 
+                               load     = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
+                                                                                        mode);
+                               set_ia32_op_type(load, ia32_AddrModeS);
+                               set_ia32_am_sc(load, floatent);
+                               set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
+                               res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
+                       }
+               } else {
                        if (clss == CNST_NULL) {
                                load = new_rd_ia32_vfldz(dbgi, irg, block);
                                res  = load;
@@ -270,7 +289,7 @@ static ir_node *gen_Const(ir_node *node) {
                                load = new_rd_ia32_vfld1(dbgi, irg, block);
                                res  = load;
                        } else {
-                               floatent = get_entity_for_tv(env_cg, node);
+                               floatent = ia32_get_entity_for_tv(env_cg->isa, node);
 
                                load     = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
                                set_ia32_op_type(load, ia32_AddrModeS);
@@ -279,16 +298,6 @@ static ir_node *gen_Const(ir_node *node) {
                                res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
                        }
                        set_ia32_ls_mode(load, mode);
-               } else {
-                       floatent = get_entity_for_tv(env_cg, node);
-
-                       load     = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
-                                                    mode);
-                       set_ia32_op_type(load, ia32_AddrModeS);
-                       set_ia32_am_sc(load, floatent);
-                       set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
-
-                       res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
                }
 
                SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
@@ -402,6 +411,9 @@ ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
                //mode = mode_xmm;
                tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
                tp  = new_type_primitive(new_id_from_str(tp_name), mode);
+               /* these constants are loaded as part of an instruction, so they must be aligned
+                  to 128 bit. */
+               set_type_alignment_bytes(tp, 16);
                ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
 
                set_entity_ld_ident(ent, get_entity_ident(ent));
@@ -1213,7 +1225,7 @@ static ir_node *gen_Quot(ir_node *node) {
 static ir_node *gen_Shl(ir_node *node) {
        ir_node *right = get_Shl_right(node);
 
-       /* test wether we can build a lea */
+       /* test whether we can build a lea */
        if(is_Const(right)) {
                tarval *tv = get_Const_tarval(right);
                if(tarval_is_long(tv)) {
@@ -2432,7 +2444,10 @@ static ir_node *gen_x87_fp_to_gp(ir_node *node) {
        return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
 }
 
-static ir_node *create_strict_conv(ir_mode *tgt_mode, ir_node *node)
+/**
+ * Creates a x87 strict Conv by placing a Sore and a Load
+ */
+static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
 {
        ir_node  *block    = get_nodes_block(node);
        ir_graph *irg      = current_ir_graph;
@@ -2624,7 +2639,7 @@ static ir_node *gen_Conv(ir_node *node) {
                                set_ia32_ls_mode(res, tgt_mode);
                        } else {
                                if(get_Conv_strict(node)) {
-                                       res = create_strict_conv(tgt_mode, new_op);
+                                       res = gen_x87_strict_conv(tgt_mode, new_op);
                                        SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
                                        return res;
                                }
@@ -2652,7 +2667,7 @@ static ir_node *gen_Conv(ir_node *node) {
                        } else {
                                res = gen_x87_gp_to_fp(node, src_mode);
                                if(get_Conv_strict(node)) {
-                                       res = create_strict_conv(tgt_mode, res);
+                                       res = gen_x87_strict_conv(tgt_mode, res);
                                        SET_IA32_ORIG_NODE(get_Proj_pred(res),
                                                           ia32_get_old_node_name(env_cg, node));
                                }
@@ -3081,7 +3096,10 @@ void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
        panic("Clobbers not supported yet");
 }
 
-ir_node *gen_ASM(ir_node *node)
+/**
+ * generates code for a ASM node
+ */
+static ir_node *gen_ASM(ir_node *node)
 {
        int                   i, arity;
        ir_graph             *irg   = current_ir_graph;
@@ -3471,8 +3489,8 @@ static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
        new_op  = func(dbgi, irg, block, new_ptr, noreg, new_mem);
 
        set_ia32_op_type(new_op, ia32_AddrModeS);
-       set_ia32_am_offs_int(new_op, 0);
-       set_ia32_am_scale(new_op, 1);
+       set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
+       set_ia32_am_scale(new_op, get_ia32_am_scale(node));
        set_ia32_am_sc(new_op, get_ia32_am_sc(node));
        if (is_ia32_am_sc_sign(node))
                set_ia32_am_sc_sign(new_op);
@@ -3525,7 +3543,7 @@ static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
 /**
  * Transforms an ia32_l_XXX into a "real" XXX node
  *
- * @param env   The transformation environment
+ * @param node   The node to transform
  * @return the created ia32 XXX node
  */
 #define GEN_LOWERED_OP(op)                                                \
@@ -3542,27 +3560,12 @@ static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
                return new_op;                                                         \
        }
 
-#define GEN_LOWERED_UNOP(op)                                                   \
-       static ir_node *gen_ia32_l_##op(ir_node *node) {\
-               return gen_unop(node, get_unop_op(node), new_rd_ia32_##op);       \
-       }
-
 #define GEN_LOWERED_SHIFT_OP(l_op, op)                                         \
        static ir_node *gen_ia32_##l_op(ir_node *node) {                           \
                return gen_shift_binop(node, get_irn_n(node, 0),                       \
                                       get_irn_n(node, 1), new_rd_ia32_##op);          \
        }
 
-#define GEN_LOWERED_LOAD(op)                                   \
-       static ir_node *gen_ia32_l_##op(ir_node *node) {           \
-               return gen_lowered_Load(node, new_rd_ia32_##op);       \
-       }
-
-#define GEN_LOWERED_STORE(op)                                \
-       static ir_node *gen_ia32_l_##op(ir_node *node) {         \
-               return gen_lowered_Store(node, new_rd_ia32_##op);    \
-       }
-
 GEN_LOWERED_OP(Adc)
 GEN_LOWERED_OP(Add)
 GEN_LOWERED_OP(Sbb)
@@ -3571,17 +3574,56 @@ GEN_LOWERED_OP(Xor)
 GEN_LOWERED_x87_OP(vfprem)
 GEN_LOWERED_x87_OP(vfmul)
 GEN_LOWERED_x87_OP(vfsub)
+GEN_LOWERED_SHIFT_OP(l_ShlDep, Shl)
+GEN_LOWERED_SHIFT_OP(l_ShrDep, Shr)
+GEN_LOWERED_SHIFT_OP(l_Sar,    Sar)
+GEN_LOWERED_SHIFT_OP(l_SarDep, Sar)
 
-GEN_LOWERED_UNOP(Neg)
 
-GEN_LOWERED_LOAD(vfild)
-GEN_LOWERED_LOAD(Load)
-GEN_LOWERED_STORE(Store)
+/**
+ * Transforms an ia32_l_Neg into a "real" ia32_Neg node
+ *
+ * @param node   The node to transform
+ * @return the created ia32 Neg node
+ */
+static ir_node *gen_ia32_l_Neg(ir_node *node) {
+       return gen_unop(node, get_unop_op(node), new_rd_ia32_Neg);
+}
+
+/**
+ * Transforms an ia32_l_vfild into a "real" ia32_vfild node
+ *
+ * @param node   The node to transform
+ * @return the created ia32 vfild node
+ */
+static ir_node *gen_ia32_l_vfild(ir_node *node) {
+       return gen_lowered_Load(node, new_rd_ia32_vfild);
+}
+
+/**
+ * Transforms an ia32_l_Load into a "real" ia32_Load node
+ *
+ * @param node   The node to transform
+ * @return the created ia32 Load node
+ */
+static ir_node *gen_ia32_l_Load(ir_node *node) {
+       return gen_lowered_Load(node, new_rd_ia32_Load);
+}
+
+/**
+ * Transforms an ia32_l_Store into a "real" ia32_Store node
+ *
+ * @param node   The node to transform
+ * @return the created ia32 Store node
+ */
+static ir_node *gen_ia32_l_Store(ir_node *node) {
+       return gen_lowered_Store(node, new_rd_ia32_Store);
+}
 
 /**
  * Transforms a l_vfist into a "real" vfist node.
  *
- * @param env   The transformation environment
+ * @param node   The node to transform
  * @return the created ia32 vfist node
  */
 static ir_node *gen_ia32_l_vfist(ir_node *node) {
@@ -3698,11 +3740,6 @@ static ir_node *gen_ia32_l_IMul(ir_node *node) {
        return muls;
 }
 
-GEN_LOWERED_SHIFT_OP(l_ShlDep, Shl)
-GEN_LOWERED_SHIFT_OP(l_ShrDep, Shr)
-GEN_LOWERED_SHIFT_OP(l_Sar,    Sar)
-GEN_LOWERED_SHIFT_OP(l_SarDep, Sar)
-
 /**
  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
  * op1 - target to be shifted