Commit ca8f7598 authored by Robin Redeker's avatar Robin Redeker
Browse files

amd64: Added Load and FrameAddr transformation. And fixed some corruption bugs...

amd64: Added Load and FrameAddr transformation. And fixed some corruption bugs w.r.t. node attribute handling.

[r27666]
parent 06949f6a
......@@ -353,15 +353,32 @@ static void emit_be_Copy(const ir_node *irn)
panic("emit_be_Copy: move not supported for FP");
} else if (mode_is_data(mode)) {
be_emit_cstring("\tmov ");
amd64_emit_source_register(irn, 0);
be_emit_cstring(", ");
amd64_emit_dest_register(irn, 0);
be_emit_cstring(", ");
amd64_emit_source_register(irn, 0);
be_emit_finish_line_gas(irn);
} else {
panic("emit_be_Copy: move not supported for this mode");
}
}
static void emit_amd64_FrameAddr(const ir_node *irn)
{
const amd64_SymConst_attr_t *attr = get_irn_generic_attr_const(irn);
be_emit_cstring("\tmov ");
amd64_emit_dest_register(irn, 0);
be_emit_cstring(", ");
amd64_emit_source_register(irn, 0);
be_emit_finish_line_gas(irn);
be_emit_cstring("\tadd ");
amd64_emit_dest_register(irn, 0);
be_emit_cstring(", ");
be_emit_irprintf("$0x%X", attr->fp_offset);
be_emit_finish_line_gas(irn);
}
/**
* Emits code for a return.
*/
......@@ -399,6 +416,7 @@ static void amd64_register_emitters(void)
set_emitter(op_amd64_SymConst, emit_amd64_SymConst);
set_emitter(op_amd64_Jmp, emit_amd64_Jmp);
set_emitter(op_amd64_Jcc, emit_amd64_Jcc);
set_emitter(op_amd64_FrameAddr, emit_amd64_FrameAddr);
set_emitter(op_be_Return, emit_be_Return);
set_emitter(op_be_Call, emit_be_Call);
set_emitter(op_be_Copy, emit_be_Copy);
......
......@@ -170,7 +170,8 @@ static void init_amd64_attributes(ir_node *node, arch_irn_flags_t flags,
static void init_amd64_SymConst_attributes(ir_node *node, ir_entity *entity)
{
amd64_SymConst_attr_t *attr = get_irn_generic_attr (node);
attr->entity = entity;
attr->entity = entity;
attr->fp_offset = 0;
}
/** Compare node attributes for SymConst. */
......@@ -179,7 +180,8 @@ static int cmp_amd64_attr_SymConst(ir_node *a, ir_node *b)
const amd64_SymConst_attr_t *attr_a = get_amd64_SymConst_attr_const(a);
const amd64_SymConst_attr_t *attr_b = get_amd64_SymConst_attr_const(b);
if (attr_a->entity != attr_b->entity)
if (attr_a->entity != attr_b->entity
|| attr_a->fp_offset != attr_b->fp_offset)
return 1;
return 0;
......
......@@ -32,6 +32,7 @@ typedef struct amd64_SymConst_attr_t amd64_SymConst_attr_t;
struct amd64_attr_t
{
except_attr exc; /**< the exception attribute. MUST be the first one. */
const arch_register_req_t **in_req; /**< register requirements for arguments */
const arch_register_req_t **out_req; /**< register requirements for results */
ir_mode *ls_mode; /**< Stores the "input" mode */
......@@ -48,7 +49,9 @@ struct amd64_attr_t
struct amd64_SymConst_attr_t
{
ir_entity *entity;
amd64_attr_t base;
ir_entity *entity;
unsigned fp_offset;
};
#define CAST_AMD64_ATTR(type,ptr) ((type *)(ptr))
......
......@@ -208,8 +208,8 @@ Add => {
reg_req => { in => [ "gp", "gp" ],
out => [ "gp" ] },
in => [ "left", "right" ],
emit => ". mov %S2, %D1\n"
. ". add %S1, %D1\n",
emit => ". mov %D1, %S2\n"
. ". add %D1, %S1\n",
outs => [ "res" ],
mode => $mode_gp,
},
......@@ -218,7 +218,7 @@ Immediate => {
attr => "unsigned imm_value",
init_attr => "attr->ext.imm_value = imm_value;",
reg_req => { out => [ "gp" ] },
emit => '. movq %C, %D1',
emit => '. movq %D1, %C',
mode => $mode_gp,
},
SymConst => {
......@@ -268,6 +268,33 @@ Jcc => {
init_attr => "attr->ext.pnc = pnc;",
mode => "mode_T",
},
Load => {
op_flags => "L|F",
state => "exc_pinned",
reg_req => { in => [ "gp", "none" ],
out => [ "gp", "none" ] },
ins => [ "ptr", "mem" ],
outs => [ "res", "M" ],
emit => ". lea %D1, [%S1]"
},
FrameAddr => {
op_flags => "c",
irn_flags => "R",
reg_req => { in => [ "gp" ], out => [ "gp" ] },
ins => [ "base" ],
attr => "ir_entity *entity",
attr_type => "amd64_SymConst_attr_t",
mode => $mode_gp,
},
#Store => {
# op_flags => "L|F",
# state => "exc_pinned",
# reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none", "none" ] },
# ins => [ "base", "index", "mem", "val" ],
# outs => [ "M", "X_exc" ],
# mode => "mode_M",
#},
#NoReg_GP => {
# state => "pinned",
......
......@@ -37,6 +37,7 @@
#include "../benode.h"
#include "../betranshlp.h"
#include "../beutil.h"
#include "bearch_amd64_t.h"
#include "amd64_nodes_attr.h"
......@@ -357,6 +358,149 @@ static ir_node *gen_Conv(ir_node *node)
}
}
/**
* Transforms a Load.
*
* @return the created AMD64 Load node
*/
static ir_node *gen_Load(ir_node *node)
{
ir_node *block = be_transform_node(get_nodes_block(node));
ir_node *ptr = get_Load_ptr(node);
ir_node *new_ptr = be_transform_node(ptr);
ir_node *mem = get_Load_mem(node);
ir_node *new_mem = be_transform_node(mem);
ir_mode *mode = get_Load_mode(node);
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_load = NULL;
if (mode_is_float(mode)) {
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);
}
set_irn_pinned(new_load, get_irn_pinned(node));
/* check for special case: the loaded value might not be used */
// if (be_get_Proj_for_pn(node, pn_Load_res) == NULL) {
// /* add a result proj and a Keep to produce a pseudo use */
// ir_node *proj = new_r_Proj(new_load, mode_Iu, pn_amd64_Load_res);
// be_new_Keep(block, 1, &proj);
// }
return new_load;
}
/**
* Transform a Proj from a Load.
*/
static ir_node *gen_Proj_Load(ir_node *node)
{
ir_node *load = get_Proj_pred(node);
ir_node *new_load = be_transform_node(load);
dbg_info *dbgi = get_irn_dbg_info(node);
long proj = get_Proj_proj(node);
/* renumber the proj */
switch (get_amd64_irn_opcode(new_load)) {
case iro_amd64_Load:
/* handle all gp loads equal: they have the same proj numbers. */
if (proj == pn_Load_res) {
return new_rd_Proj(dbgi, new_load, mode_Iu, pn_amd64_Load_res);
} else if (proj == pn_Load_M) {
return new_rd_Proj(dbgi, new_load, mode_M, pn_amd64_Load_M);
}
break;
/*
case iro_sparc_fpaLoad:
panic("FP not implemented yet");
break;
*/
default:
panic("Unsupported Proj from Load");
}
return be_duplicate_node(node);
}
/**
* Transform a Proj node.
*/
static ir_node *gen_Proj(ir_node *node)
{
ir_graph *irg = current_ir_graph;
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *pred = get_Proj_pred(node);
long proj = get_Proj_proj(node);
(void) irg;
(void) dbgi;
if (is_Store(pred)) {
if (proj == pn_Store_M) {
return be_transform_node(pred);
} else {
panic("Unsupported Proj from Store");
}
} else if (is_Load(pred)) {
return gen_Proj_Load(node);
// } else if (be_is_SubSP(pred)) {
// //panic("gen_Proj not implemented for SubSP");
// return gen_Proj_be_SubSP(node);
// } else if (be_is_AddSP(pred)) {
// //panic("gen_Proj not implemented for AddSP");
// return gen_Proj_be_AddSP(node);
// } else if (is_Cmp(pred)) {
// //panic("gen_Proj not implemented for Cmp");
// return gen_Proj_Cmp(node);
// } else if (is_Div(pred)) {
// return gen_Proj_Div(node);
} else if (is_Start(pred)) {
// /*
// if (proj == pn_Start_X_initial_exec) {
// ir_node *block = get_nodes_block(pred);
// ir_node *jump;
//
// // we exchange the ProjX with a jump
// block = be_transform_node(block);
// jump = new_rd_Jmp(dbgi, block);
// return jump;
// }
//
// if (node == get_irg_anchor(irg, anchor_tls)) {
// return gen_Proj_tls(node);
// }
// */
// } else {
// ir_node *new_pred = be_transform_node(pred);
// ir_mode *mode = get_irn_mode(node);
// if (mode_needs_gp_reg(mode)) {
// ir_node *new_proj = new_r_Proj(new_pred, mode_Iu, get_Proj_proj(node));
// new_proj->node_nr = node->node_nr;
// return new_proj;
// }
}
return be_duplicate_node(node);
}
/**
* Transforms a FrameAddr into an AMD64 Add.
*/
static ir_node *gen_be_FrameAddr(ir_node *node)
{
ir_node *block = be_transform_node(get_nodes_block(node));
ir_entity *ent = be_get_frame_entity(node);
ir_node *fp = be_get_FrameAddr_frame(node);
ir_node *new_fp = be_transform_node(fp);
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_node;
new_node = new_bd_amd64_FrameAddr(dbgi, block, new_fp, ent);
return new_node;
}
/* Boilerplate code for transformation: */
static void amd64_pretransform_node(void)
......@@ -380,11 +524,14 @@ static void amd64_register_transformers(void)
set_transformer(op_SymConst, gen_SymConst);
set_transformer(op_Add, gen_Add);
set_transformer(op_be_Call, gen_be_Call);
set_transformer(op_be_FrameAddr, gen_be_FrameAddr);
set_transformer(op_Conv, gen_Conv);
set_transformer(op_Jmp, gen_Jmp);
set_transformer(op_Cmp, gen_Cmp);
set_transformer(op_Cond, gen_Cond);
set_transformer(op_Phi, gen_Phi);
set_transformer(op_Load, gen_Load);
set_transformer(op_Proj, gen_Proj);
}
......
......@@ -63,6 +63,11 @@ static arch_irn_class_t amd64_classify(const ir_node *irn)
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;
}
(void) node;
/* TODO: return the ir_entity assigned to the frame */
return NULL;
......@@ -81,9 +86,10 @@ static void amd64_set_frame_entity(ir_node *node, ir_entity *ent)
*/
static void amd64_set_frame_offset(ir_node *irn, int offset)
{
(void) irn;
(void) offset;
/* TODO: correct offset if irn accesses the stack */
if (is_amd64_FrameAddr(irn)) {
amd64_SymConst_attr_t *attr = get_irn_generic_attr(irn);
attr->fp_offset += offset;
}
}
static int amd64_get_sp_bias(const ir_node *irn)
......
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