Commit 11504f3d authored by Robin Redeker's avatar Robin Redeker
Browse files

amd64: fixed spill code. added Sub and Neg. Fixed Cmp.

[r27680]
parent ec692968
......@@ -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);
......
......@@ -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);
......
......@@ -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 => {
......
......@@ -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);
}
......
......@@ -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);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment