amd64: fixed spill code. added Sub and Neg. Fixed Cmp.
authorRobin Redeker <rredeker@ipd.info.uni-karlsruhe.de>
Wed, 30 Jun 2010 12:08:59 +0000 (12:08 +0000)
committerRobin Redeker <rredeker@ipd.info.uni-karlsruhe.de>
Wed, 30 Jun 2010 12:08:59 +0000 (12:08 +0000)
[r27680]

ir/be/amd64/amd64_emitter.c
ir/be/amd64/amd64_emitter.h
ir/be/amd64/amd64_spec.pl
ir/be/amd64/amd64_transform.c
ir/be/amd64/bearch_amd64.c

index df68dfe..cbdbde1 100644 (file)
@@ -128,6 +128,13 @@ void amd64_emit_immediate(const ir_node *node)
        be_emit_irprintf("0x%X", attr->ext.imm_value);
 }
 
+void amd64_emit_fp_offset(const ir_node *node)
+{
+       const amd64_SymConst_attr_t *attr = get_amd64_SymConst_attr_const(node);
+       if (attr->fp_offset)
+               be_emit_irprintf("%d", attr->fp_offset);
+}
+
 void amd64_emit_source_register(const ir_node *node, int pos)
 {
        amd64_emit_register(get_in_reg(node, pos));
@@ -314,8 +321,8 @@ static void emit_amd64_Jcc(const ir_node *irn)
                case pn_Cmp_Eq:  suffix = "e"; break;
                case pn_Cmp_Lt:  suffix = is_signed ? "l"  : "b"; break;
                case pn_Cmp_Le:  suffix = is_signed ? "le" : "be"; break;
-               case pn_Cmp_Gt:  suffix = is_signed ? "g"  : "o"; break;
-               case pn_Cmp_Ge:  suffix = is_signed ? "ge" : "oe"; break;
+               case pn_Cmp_Gt:  suffix = is_signed ? "g"  : "a"; break;
+               case pn_Cmp_Ge:  suffix = is_signed ? "ge" : "ae"; break;
                case pn_Cmp_Lg:  suffix = "ne"; break;
                case pn_Cmp_Leg: suffix = "mp"; break;
                default: panic("Cmp has unsupported pnc");
@@ -442,14 +449,24 @@ static void emit_amd64_binop_op(const ir_node *irn, int second_op)
 {
        if (irn->op == op_amd64_Add) {
                be_emit_cstring("\tadd ");
+               amd64_emit_source_register(irn, second_op);
+               be_emit_cstring(", ");
+               amd64_emit_dest_register(irn, 0);
+               be_emit_finish_line_gas(irn);
        } else if (irn->op == op_amd64_Sub) {
-               be_emit_cstring("\tsub ");
+               be_emit_cstring("\tneg ");
+               amd64_emit_source_register(irn, second_op);
+               be_emit_finish_line_gas(irn);
+               be_emit_cstring("\tadd ");
+               amd64_emit_source_register(irn, second_op);
+               be_emit_cstring(", ");
+               amd64_emit_dest_register(irn, 0);
+               be_emit_finish_line_gas(irn);
+               be_emit_cstring("\tneg ");
+               amd64_emit_source_register(irn, second_op);
+               be_emit_finish_line_gas(irn);
        }
 
-       amd64_emit_source_register(irn, second_op);
-       be_emit_cstring(", ");
-       amd64_emit_dest_register(irn, 0);
-       be_emit_finish_line_gas(irn);
 }
 
 /**
@@ -515,6 +532,7 @@ static void amd64_register_emitters(void)
        set_emitter(op_be_IncSP,         emit_be_IncSP);
 
        set_emitter(op_amd64_Add,        emit_amd64_binop);
+       set_emitter(op_amd64_Sub,        emit_amd64_binop);
 
        set_emitter(op_be_Start,         emit_nothing);
        set_emitter(op_be_Keep,          emit_nothing);
index c0142ff..2e0b757 100644 (file)
@@ -38,6 +38,7 @@ void amd64_emit_register(const arch_register_t *reg);
 void amd64_emit_source_register(const ir_node *node, int pos);
 void amd64_emit_dest_register(const ir_node *node, int pos);
 void amd64_emit_immediate(const ir_node *node);
+void amd64_emit_fp_offset(const ir_node *node);
 
 int get_amd64_reg_nr(ir_node *irn, int posi, int in_out);
 const char *get_amd64_in_reg_name(ir_node *irn, int pos);
index 8d81010..2b71d2a 100644 (file)
@@ -171,7 +171,8 @@ $custom_init_attr_func = \&amd64_custom_init_attr;
        D4 => "${arch}_emit_dest_register(node, 3);",
        D5 => "${arch}_emit_dest_register(node, 4);",
        D6 => "${arch}_emit_dest_register(node, 5);",
-       C  => "${arch}_emit_immediate(node);"
+       C  => "${arch}_emit_immediate(node);",
+       O  => "${arch}_emit_fp_offset(node);",
 );
 
 %init_attr = (
@@ -236,6 +237,16 @@ Sub => {
        mode       => $mode_gp,
        modified_flags => 1,
 },
+Neg => {
+       irn_flags => "R",
+       reg_req   => { in => [ "gp" ],
+                      out => [ "in_r1", "flags" ] },
+       emit      => '. neg %S1',
+       ins       => [ "val" ],
+       outs      => [ "res", "flags" ],
+       mode      => $mode_gp,
+       modified_flags => $status_flags
+},
 Immediate => {
        op_flags  => "c",
        attr      => "unsigned imm_value",
@@ -246,10 +257,11 @@ Immediate => {
 },
 SymConst => {
        op_flags  => "c",
-       irn_flags => "R",
+#      irn_flags => "R",
        attr      => "ir_entity *entity",
        attr_type => "amd64_SymConst_attr_t",
        reg_req   => { out => [ "gp" ] },
+       outs      => [ "res" ],
        mode      => $mode_gp,
 },
 Conv => {
@@ -298,7 +310,9 @@ Load => {
                       out => [ "gp", "none" ] },
        ins       => [ "ptr", "mem" ],
        outs      => [ "res",  "M" ],
-       emit      => ". mov (%S1), %D1"
+       attr      => "ir_entity *entity",
+       attr_type => "amd64_SymConst_attr_t",
+       emit      => ". mov %O(%S1), %D1"
 },
 FrameAddr => {
        op_flags  => "c",
@@ -315,8 +329,10 @@ Store => {
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
        ins       => [ "ptr", "val", "mem" ],
        outs      => [ "M" ],
+       attr      => "ir_entity *entity",
+       attr_type => "amd64_SymConst_attr_t",
        mode      => "mode_M",
-       emit      => ". mov %S2, (%S1)"
+       emit      => ". mov %S2, %O(%S1)"
 },
 
 #NoReg_GP => {
index 958f762..1142ce8 100644 (file)
@@ -139,6 +139,25 @@ static ir_node *gen_Add(ir_node *node) {
        return res;
 }
 
+/**
+ * Transforms an Sub node.
+ *
+ * @return The transformed AMD64 node.
+ */
+static ir_node *gen_Sub(ir_node *node) {
+       ir_node  *block = be_transform_node(get_nodes_block(node));
+       /* ir_mode  *mode  = get_irn_mode(node); */
+       ir_node  *op1   = get_Sub_left(node);
+       ir_node  *op2   = get_Sub_right(node);
+       dbg_info *dbgi  = get_irn_dbg_info(node);
+       ir_node  *new_op1 = be_transform_node(op1);
+       ir_node  *new_op2 = be_transform_node(op2);
+
+       ir_node *res = new_bd_amd64_Sub(dbgi, block, new_op1, new_op2);
+       be_dep_on_frame (res);
+       return res;
+}
+
 static ir_node *gen_Mul(ir_node *node) {
        ir_node  *block = be_transform_node(get_nodes_block(node));
        /* ir_mode  *mode  = get_irn_mode(node); */
@@ -153,6 +172,15 @@ static ir_node *gen_Mul(ir_node *node) {
        return res;
 }
 
+static ir_node *gen_Minus(ir_node *node)
+{
+       ir_node  *block    = be_transform_node(get_nodes_block(node));
+       ir_node  *val      = be_transform_node(get_Minus_op(node));
+       dbg_info *dbgi     = get_irn_dbg_info(node);
+
+       return new_bd_amd64_Neg(dbgi, block, val);
+}
+
 static ir_node *gen_Jmp(ir_node *node)
 {
        ir_node  *block     = get_nodes_block(node);
@@ -358,7 +386,9 @@ static ir_node *gen_Conv(ir_node *node)
                        min_mode = dst_mode;
                }
 
-               return new_bd_amd64_Conv(dbgi, block, new_op, min_mode);
+
+               ir_node *n = new_bd_amd64_Conv(dbgi, block, new_op, min_mode);
+               return n;
 
                //if (upper_bits_clean(new_op, min_mode)) {
                //      return new_op;
@@ -394,7 +424,7 @@ static ir_node *gen_Store(ir_node *node)
                panic("Float not supported yet");
        } else {
                assert(mode_is_data(mode) && "unsupported mode for Store");
-               new_store = new_bd_amd64_Store(dbgi, block, new_ptr, new_val, new_mem);
+               new_store = new_bd_amd64_Store(dbgi, block, new_ptr, new_val, new_mem, 0);
        }
        set_irn_pinned(new_store, get_irn_pinned(node));
        return new_store;
@@ -420,7 +450,7 @@ static ir_node *gen_Load(ir_node *node)
                panic("Float not supported yet");
        } else {
                assert(mode_is_data(mode) && "unsupported mode for Load");
-               new_load = new_bd_amd64_Load(dbgi, block, new_ptr, new_mem);
+               new_load = new_bd_amd64_Load(dbgi, block, new_ptr, new_mem, 0);
        }
        set_irn_pinned(new_load, get_irn_pinned(node));
 
@@ -565,6 +595,7 @@ static void amd64_register_transformers(void)
        set_transformer(op_Const,        gen_Const);
        set_transformer(op_SymConst,     gen_SymConst);
        set_transformer(op_Add,          gen_Add);
+       set_transformer(op_Sub,          gen_Sub);
        set_transformer(op_Mul,          gen_Mul);
        set_transformer(op_be_Call,      gen_be_Call);
        set_transformer(op_be_FrameAddr, gen_be_FrameAddr);
@@ -576,6 +607,7 @@ static void amd64_register_transformers(void)
        set_transformer(op_Load,         gen_Load);
        set_transformer(op_Store,        gen_Store);
        set_transformer(op_Proj,         gen_Proj);
+       set_transformer(op_Minus,        gen_Minus);
 }
 
 
index a63a5cf..50a725c 100644 (file)
@@ -67,6 +67,14 @@ static ir_entity *amd64_get_frame_entity(const ir_node *node)
        if (is_amd64_FrameAddr(node)) {
                const amd64_SymConst_attr_t *attr = get_irn_generic_attr_const(node);
                return attr->entity;
+
+       } else if (is_amd64_Store(node)) {
+               const amd64_SymConst_attr_t *attr = get_irn_generic_attr_const(node);
+               return attr->entity;
+
+       } else if (is_amd64_Load(node)) {
+               const amd64_SymConst_attr_t *attr = get_irn_generic_attr_const(node);
+               return attr->entity;
        }
 
        (void) node;
@@ -90,6 +98,15 @@ static void amd64_set_frame_offset(ir_node *irn, int offset)
        if (is_amd64_FrameAddr(irn)) {
                amd64_SymConst_attr_t *attr = get_irn_generic_attr(irn);
                attr->fp_offset += offset;
+
+       } else if (is_amd64_Store(irn)) {
+               amd64_SymConst_attr_t *attr = get_irn_generic_attr(irn);
+               attr->fp_offset += offset;
+
+       } else if (is_amd64_Load(irn)) {
+               amd64_SymConst_attr_t *attr = get_irn_generic_attr(irn);
+               attr->fp_offset += offset;
+
        }
 }
 
@@ -158,14 +175,14 @@ static void transform_Reload(ir_node *node)
        ir_node   *ptr    = get_irg_frame(irg);
        ir_node   *mem    = get_irn_n(node, be_pos_Reload_mem);
        ir_mode   *mode   = get_irn_mode(node);
-       //ir_entity *entity = be_get_frame_entity(node);
+       ir_entity *entity = be_get_frame_entity(node);
        const arch_register_t *reg;
        ir_node   *proj;
        ir_node   *load;
 
        ir_node  *sched_point = sched_prev(node);
 
-       load = new_bd_amd64_Load(dbgi, block, ptr, mem);
+       load = new_bd_amd64_Load(dbgi, block, ptr, mem, entity);
        sched_add_after(sched_point, load);
        sched_remove(node);
 
@@ -186,12 +203,12 @@ static void transform_Spill(ir_node *node)
        ir_node   *mem    = new_NoMem();
        ir_node   *val    = get_irn_n(node, be_pos_Spill_val);
        //ir_mode   *mode   = get_irn_mode(val);
-       //ir_entity *entity = be_get_frame_entity(node);
+       ir_entity *entity = be_get_frame_entity(node);
        ir_node   *sched_point;
        ir_node   *store;
 
        sched_point = sched_prev(node);
-       store = new_bd_amd64_Store(dbgi, block, ptr, val, mem);
+       store = new_bd_amd64_Store(dbgi, block, ptr, val, mem, entity);
 
        sched_remove(node);
        sched_add_after(sched_point, store);