Commit 9887aa54 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

be: Factorise code to get the register Projs of the backend start nodes.

parent 79885a18
......@@ -38,17 +38,12 @@
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
typedef struct reg_info_t {
size_t offset;
ir_node *irn;
} reg_info_t;
static ir_mode *mode_gp;
static ir_mode *mode_flags;
static amd64_cconv_t *current_cconv = NULL;
static reg_info_t start_mem;
static reg_info_t start_sp;
static reg_info_t start_fp;
static be_start_info_t start_mem;
static be_start_info_t start_sp;
static be_start_info_t start_fp;
static size_t start_callee_saves_offset;
static size_t start_params_offset;
static pmap *node_to_stack;
......@@ -279,32 +274,19 @@ static ir_node *skip_sameconv(ir_node *node)
return node;
}
static ir_node *get_reg(ir_graph *const irg, reg_info_t *const reg)
{
if (!reg->irn) {
/* this is already the transformed start node */
ir_node *const start = get_irg_start(irg);
assert(is_amd64_Start(start));
arch_register_class_t const *const cls
= arch_get_irn_register_req_out(start, reg->offset)->cls;
reg->irn = new_r_Proj(start, cls ? cls->mode : mode_M, reg->offset);
}
return reg->irn;
}
static ir_node *get_initial_sp(ir_graph *irg)
{
return get_reg(irg, &start_sp);
return be_get_start_proj(irg, &start_sp);
}
static ir_node *get_initial_fp(ir_graph *irg)
{
return get_reg(irg, &start_fp);
return be_get_start_proj(irg, &start_fp);
}
static ir_node *get_initial_mem(ir_graph *irg)
{
return get_reg(irg, &start_mem);
return be_get_start_proj(irg, &start_mem);
}
static ir_node *get_frame_base(ir_graph *irg)
......@@ -1295,19 +1277,6 @@ static ir_node *gen_Switch(ir_node *node)
return out;
}
static void make_start_out(reg_info_t *const info, struct obstack *const obst,
ir_node *const start, size_t const offset,
arch_register_t const *const reg,
arch_register_req_type_t const flags)
{
info->offset = offset;
info->irn = NULL;
arch_register_req_t const *const req
= be_create_reg_req(obst, reg, arch_register_req_type_ignore | flags);
arch_set_irn_register_req_out(start, offset, req);
arch_set_irn_register_out(start, offset, reg);
}
static ir_node *gen_Start(ir_node *node)
{
ir_graph *irg = get_irn_irg(node);
......@@ -1335,14 +1304,10 @@ static ir_node *gen_Start(ir_node *node)
size_t o = 0;
/* first output is memory */
start_mem.offset = o;
start_mem.irn = NULL;
arch_set_irn_register_req_out(start, o, arch_no_register_req);
++o;
be_make_start_mem(&start_mem, start, o++);
/* the stack pointer */
make_start_out(&start_sp, obst, start, o++, &amd64_registers[REG_RSP],
arch_register_req_type_produces_sp);
be_make_start_out(&start_sp, obst, start, o++, &amd64_registers[REG_RSP], arch_register_req_type_ignore | arch_register_req_type_produces_sp);
/* function parameters in registers */
start_params_offset = o;
......@@ -1362,8 +1327,7 @@ static ir_node *gen_Start(ir_node *node)
if (!rbitset_is_set(cconv->callee_saves, i))
continue;
if (!cconv->omit_fp && i == REG_RBP) {
make_start_out(&start_fp, obst, start, o++, &amd64_registers[REG_RBP],
arch_register_req_type_none);
be_make_start_out(&start_fp, obst, start, o++, &amd64_registers[REG_RBP], arch_register_req_type_ignore);
} else {
const arch_register_t *reg = &amd64_registers[i];
arch_set_irn_register_req_out(start, o, reg->single_req);
......
......@@ -42,17 +42,12 @@
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
typedef struct start_val_t {
unsigned offset;
ir_node *irn;
} start_val_t;
static const arch_register_t *sp_reg = &arm_registers[REG_SP];
static ir_mode *mode_fp;
static be_stackorder_t *stackorder;
static calling_convention_t *cconv = NULL;
static start_val_t start_mem;
static start_val_t start_sp;
static be_start_info_t start_mem;
static be_start_info_t start_sp;
static unsigned start_params_offset;
static unsigned start_callee_saves_offset;
static pmap *node_to_stack;
......@@ -172,31 +167,6 @@ static ir_node *create_const_graph(ir_node *irn, ir_node *block)
return create_const_graph_value(get_irn_dbg_info(irn), block, value);
}
static void make_start_out(start_val_t *const info, struct obstack *const obst,
ir_node *const start, size_t const offset,
arch_register_t const *const reg,
arch_register_req_type_t const flags)
{
info->offset = offset;
info->irn = NULL;
arch_register_req_t const *const req
= be_create_reg_req(obst, reg, arch_register_req_type_ignore | flags);
arch_set_irn_register_req_out(start, offset, req);
arch_set_irn_register_out(start, offset, reg);
}
static ir_node *get_start_val(ir_graph *irg, start_val_t *const info)
{
if (info->irn == NULL) {
ir_node *const start = get_irg_start(irg);
arch_register_class_t const *const cls
= arch_get_irn_register_req_out(start, info->offset)->cls;
ir_mode *mode = cls != NULL ? cls->mode : mode_M;
info->irn = new_r_Proj(start, mode, info->offset);
}
return info->irn;
}
/**
* Create an And that will zero out upper bits.
*
......@@ -1561,13 +1531,13 @@ static ir_node *gen_Proj_Start(ir_node *node)
unsigned pn = get_Proj_num(node);
switch ((pn_Start)pn) {
case pn_Start_M:
return get_start_val(get_irn_irg(node), &start_mem);
return be_get_start_proj(get_irn_irg(node), &start_mem);
case pn_Start_T_args:
return new_r_Bad(get_irn_irg(node), mode_T);
case pn_Start_P_frame_base:
return get_start_val(get_irn_irg(node), &start_sp);
return be_get_start_proj(get_irn_irg(node), &start_sp);
}
panic("unexpected start proj: %u\n", pn);
}
......@@ -1602,7 +1572,7 @@ static ir_node *gen_Proj_Proj_Start(ir_node *node)
value1 = new_r_Proj(new_start, mode, new_pn+1);
} else if (param->entity != NULL) {
ir_node *const fp = get_irg_frame(irg);
ir_node *const mem = get_start_val(irg, &start_mem);
ir_node *const mem = be_get_start_proj(irg, &start_mem);
ir_node *const ldr = new_bd_arm_Ldr(NULL, new_block, fp, mem,
arm_mode_gp, param->entity,
0, 0, true);
......@@ -1620,7 +1590,7 @@ static ir_node *gen_Proj_Proj_Start(ir_node *node)
} else {
/* argument transmitted on stack */
ir_node *const fp = get_irg_frame(irg);
ir_node *const mem = get_start_val(irg, &start_mem);
ir_node *const mem = be_get_start_proj(irg, &start_mem);
ir_mode *const mode = get_type_mode(param->type);
ir_node *load;
......@@ -1815,13 +1785,9 @@ static ir_node *gen_Start(ir_node *node)
ir_node *start = new_bd_arm_Start(dbgi, new_block, n_outs);
unsigned o = 0;
start_mem.offset = o++;
start_mem.irn = NULL;
arch_set_irn_register_req_out(start, start_mem.offset,
arch_no_register_req);
be_make_start_mem(&start_mem, start, o++);
make_start_out(&start_sp, obst, start, o++, &arm_registers[REG_SP],
arch_register_req_type_produces_sp);
be_make_start_out(&start_sp, obst, start, o++, &arm_registers[REG_SP], arch_register_req_type_ignore | arch_register_req_type_produces_sp);
/* function parameters in registers */
start_params_offset = o;
......@@ -1861,7 +1827,7 @@ static ir_node *get_stack_pointer_for(ir_node *node)
/* first stack user in the current block. We can simply use the
* initial sp_proj for it */
ir_graph *irg = get_irn_irg(node);
return get_start_val(irg, &start_sp);
return be_get_start_proj(irg, &start_sp);
}
be_transform_node(stack_pred);
......
......@@ -258,3 +258,32 @@ void arch_dump_reqs_and_registers(FILE *F, const ir_node *node)
}
fprintf(F, " (0x%x)\n", (unsigned)flags);
}
void be_make_start_mem(be_start_info_t *const info, ir_node *const start, unsigned const pos)
{
info->pos = pos;
info->irn = NULL;
arch_set_irn_register_req_out(start, pos, arch_no_register_req);
}
void be_make_start_out(be_start_info_t *const info, struct obstack *const obst, ir_node *const start, unsigned const pos, arch_register_t const *const reg, arch_register_req_type_t const flags)
{
info->pos = pos;
info->irn = NULL;
arch_register_req_t const *const req =
flags == arch_register_req_type_none ? reg->single_req :
be_create_reg_req(obst, reg, flags);
arch_set_irn_register_req_out(start, pos, req);
arch_set_irn_register_out(start, pos, reg);
}
ir_node *be_get_start_proj(ir_graph *const irg, be_start_info_t *const info)
{
if (!info->irn) {
/* This is already the transformed start node. */
ir_node *const start = get_irg_start(irg);
arch_register_class_t const *const cls = arch_get_irn_register_req_out(start, info->pos)->cls;
info->irn = new_r_Proj(start, cls ? cls->mode : mode_M, info->pos);
}
return info->irn;
}
......@@ -561,4 +561,15 @@ static inline const arch_register_class_t *arch_get_irn_reg_class(
bool arch_reg_is_allocatable(const arch_register_req_t *req,
const arch_register_t *reg);
typedef struct be_start_info_t {
unsigned pos;
ir_node *irn;
} be_start_info_t;
void be_make_start_mem(be_start_info_t *info, ir_node *start, unsigned pos);
void be_make_start_out(be_start_info_t *info, struct obstack *obst, ir_node *start, unsigned pos, arch_register_t const *reg, arch_register_req_type_t flags);
ir_node *be_get_start_proj(ir_graph *irg, be_start_info_t *info);
#endif
......@@ -59,16 +59,11 @@
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
typedef struct reg_info_t {
unsigned pn;
ir_node *irn;
} reg_info_t;
static ia32_cconv_t *current_cconv;
static reg_info_t start_mem;
static reg_info_t start_sp;
static reg_info_t start_fp;
static reg_info_t start_fpcw;
static be_start_info_t start_mem;
static be_start_info_t start_sp;
static be_start_info_t start_fp;
static be_start_info_t start_fpcw;
static unsigned start_callee_saves_offset;
static unsigned start_params_offset;
static pmap *node_to_stack;
......@@ -199,37 +194,24 @@ static ir_node *get_global_base(ir_graph *const irg)
return noreg_GP;
}
static ir_node *get_reg(ir_graph *const irg, reg_info_t *const reg)
{
if (!reg->irn) {
/* this is already the transformed start node */
ir_node *const start = get_irg_start(irg);
assert(is_ia32_Start(start));
arch_register_class_t const *const cls
= arch_get_irn_register_req_out(start, reg->pn)->cls;
reg->irn = new_r_Proj(start, cls ? cls->mode : mode_M, reg->pn);
}
return reg->irn;
}
static ir_node *get_initial_sp(ir_graph *irg)
{
return get_reg(irg, &start_sp);
return be_get_start_proj(irg, &start_sp);
}
static ir_node *get_initial_fp(ir_graph *irg)
{
return get_reg(irg, &start_fp);
return be_get_start_proj(irg, &start_fp);
}
static ir_node *get_initial_mem(ir_graph *irg)
{
return get_reg(irg, &start_mem);
return be_get_start_proj(irg, &start_mem);
}
static ir_node *get_initial_fpcw(ir_graph *irg)
{
return get_reg(irg, &start_fpcw);
return be_get_start_proj(irg, &start_fpcw);
}
/**
......@@ -4169,19 +4151,6 @@ static ir_node *gen_Member(ir_node *node)
return new_node;
}
static void make_start_out(reg_info_t *const info, struct obstack *const obst,
ir_node *const start, unsigned const pn,
arch_register_t const *const reg,
arch_register_req_type_t const flags)
{
info->pn = pn;
info->irn = NULL;
arch_register_req_t const *const req
= be_create_reg_req(obst, reg, flags);
arch_set_irn_register_req_out(start, pn, req);
arch_set_irn_register_out(start, pn, reg);
}
static ir_node *gen_Start(ir_node *node)
{
ir_graph *irg = get_irn_irg(node);
......@@ -4209,14 +4178,10 @@ static ir_node *gen_Start(ir_node *node)
unsigned o = 0;
/* first output is memory */
start_mem.pn = o++;
start_mem.irn = NULL;
arch_set_irn_register_req_out(start, start_mem.pn, arch_no_register_req);
be_make_start_mem(&start_mem, start, o++);
/* the stack pointer */
make_start_out(&start_sp, obst, start, o++, &ia32_registers[REG_ESP],
arch_register_req_type_ignore
| arch_register_req_type_produces_sp);
be_make_start_out(&start_sp, obst, start, o++, &ia32_registers[REG_ESP], arch_register_req_type_ignore | arch_register_req_type_produces_sp);
/* function parameters in registers */
start_params_offset = o;
......@@ -4236,13 +4201,10 @@ static ir_node *gen_Start(ir_node *node)
if (!rbitset_is_set(cconv->callee_saves, i))
continue;
if (!cconv->omit_fp && i == REG_EBP) {
make_start_out(&start_fp, obst, start, o++, &ia32_registers[REG_EBP],
arch_register_req_type_ignore|arch_register_req_type_none);
be_make_start_out(&start_fp, obst, start, o++, &ia32_registers[REG_EBP], arch_register_req_type_ignore);
} else if (i == REG_FPCW) {
/* floating point control word (fpcw) */
make_start_out(&start_fpcw, obst, start, o++,
&ia32_registers[REG_FPCW],
arch_register_req_type_none);
be_make_start_out(&start_fpcw, obst, start, o++, &ia32_registers[REG_FPCW], arch_register_req_type_none);
} else {
const arch_register_t *reg = &ia32_registers[i];
arch_set_irn_register_req_out(start, o, reg->single_req);
......
......@@ -43,11 +43,6 @@
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
typedef struct reg_info_t {
size_t offset;
ir_node *irn;
} reg_info_t;
static const arch_register_t *sp_reg = &sparc_registers[REG_SP];
static const arch_register_t *fp_reg = &sparc_registers[REG_FRAME_POINTER];
static calling_convention_t *current_cconv = NULL;
......@@ -58,11 +53,11 @@ static ir_mode *mode_fp;
static ir_mode *mode_fp2;
//static ir_mode *mode_fp4;
static pmap *node_to_stack;
static reg_info_t start_mem;
static reg_info_t start_g0;
static reg_info_t start_g7;
static reg_info_t start_sp;
static reg_info_t start_fp;
static be_start_info_t start_mem;
static be_start_info_t start_g0;
static be_start_info_t start_g7;
static be_start_info_t start_sp;
static be_start_info_t start_fp;
static ir_node *frame_base;
static size_t start_params_offset;
static size_t start_callee_saves_offset;
......@@ -733,26 +728,14 @@ static ir_node *gen_helper_binopx(ir_node *node, match_flags_t match_flags,
}
static ir_node *get_reg(ir_graph *const irg, reg_info_t *const reg)
{
if (!reg->irn) {
/* this is already the transformed start node */
ir_node *const start = get_irg_start(irg);
assert(is_sparc_Start(start));
arch_register_class_t const *const cls = arch_get_irn_register_req_out(start, reg->offset)->cls;
reg->irn = new_r_Proj(start, cls ? cls->mode : mode_M, reg->offset);
}
return reg->irn;
}
static ir_node *get_g0(ir_graph *irg)
{
return get_reg(irg, &start_g0);
return be_get_start_proj(irg, &start_g0);
}
static ir_node *get_g7(ir_graph *irg)
{
return get_reg(irg, &start_g7);
return be_get_start_proj(irg, &start_g7);
}
static ir_node *make_tls_offset(dbg_info *dbgi, ir_node *block,
......@@ -1757,15 +1740,6 @@ static ir_node *gen_Unknown(ir_node *node)
panic("Unexpected Unknown mode");
}
static void make_start_out(reg_info_t *const info, struct obstack *const obst, ir_node *const start, size_t const offset, arch_register_t const *const reg, arch_register_req_type_t const flags)
{
info->offset = offset;
info->irn = NULL;
arch_register_req_t const *const req = be_create_reg_req(obst, reg, arch_register_req_type_ignore | flags);
arch_set_irn_register_req_out(start, offset, req);
arch_set_irn_register_out(start, offset, reg);
}
/**
* transform the start node to the prolog code
*/
......@@ -1797,22 +1771,19 @@ static ir_node *gen_Start(ir_node *node)
size_t o = 0;
/* first output is memory */
start_mem.offset = o;
start_mem.irn = NULL;
arch_set_irn_register_req_out(start, o, arch_no_register_req);
++o;
be_make_start_mem(&start_mem, start, o++);
/* the zero register */
make_start_out(&start_g0, obst, start, o++, &sparc_registers[REG_G0], arch_register_req_type_none);
be_make_start_out(&start_g0, obst, start, o++, &sparc_registers[REG_G0], arch_register_req_type_ignore);
/* g7 is used for TLS data */
make_start_out(&start_g7, obst, start, o++, &sparc_registers[REG_G7], arch_register_req_type_none);
be_make_start_out(&start_g7, obst, start, o++, &sparc_registers[REG_G7], arch_register_req_type_ignore);
/* we need an output for the stack pointer */
make_start_out(&start_sp, obst, start, o++, sp_reg, arch_register_req_type_produces_sp);
be_make_start_out(&start_sp, obst, start, o++, sp_reg, arch_register_req_type_ignore | arch_register_req_type_produces_sp);
if (!current_cconv->omit_fp) {
make_start_out(&start_fp, obst, start, o++, fp_reg, arch_register_req_type_none);
be_make_start_out(&start_fp, obst, start, o++, fp_reg, arch_register_req_type_ignore);
}
/* function parameters in registers */
......@@ -1851,17 +1822,17 @@ static ir_node *gen_Start(ir_node *node)
static ir_node *get_initial_sp(ir_graph *irg)
{
return get_reg(irg, &start_sp);
return be_get_start_proj(irg, &start_sp);
}
static ir_node *get_initial_fp(ir_graph *irg)
{
return get_reg(irg, &start_fp);
return be_get_start_proj(irg, &start_fp);
}
static ir_node *get_initial_mem(ir_graph *irg)
{
return get_reg(irg, &start_mem);
return be_get_start_proj(irg, &start_mem);
}
static ir_node *get_stack_pointer_for(ir_node *node)
......
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