Commit e1e04a12 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

mips: Handle parameters on the stack.

Now 'int f(int a, int b, int c, int d, int e, int f) { return d + e + f; }' can be translated.
parent 72599823
......@@ -5,7 +5,9 @@
#include "mips_cconv.h"
#include "betranshlp.h"
#include "gen_mips_regalloc_if.h"
#include "mips_bearch_t.h"
#include "util.h"
static unsigned const regs_param_gp[] = {
......@@ -39,6 +41,7 @@ void mips_determine_calling_convention(mips_calling_convention_t *const cconv, i
++gp_param;
if (gp_param < ARRAY_SIZE(regs_param_gp))
params[i].reg = &mips_registers[regs_param_gp[gp_param]];
params[i].offset = gp_param * (MIPS_MACHINE_SIZE / 8);
++gp_param;
}
}
......@@ -71,6 +74,30 @@ void mips_determine_calling_convention(mips_calling_convention_t *const cconv, i
cconv->results = results;
}
void mips_layout_parameter_entities(mips_calling_convention_t *const cconv, ir_graph *const irg)
{
ir_entity **const param_map = be_collect_parameter_entities(irg);
ir_type *const frame_type = get_irg_frame_type(irg);
ir_entity *const fun_ent = get_irg_entity(irg);
ir_type *const fun_type = get_entity_type(fun_ent);
size_t const n_params = get_method_n_params(fun_type);
for (size_t i = 0; i != n_params; ++i) {
mips_reg_or_slot_t *const param = &cconv->parameters[i];
ir_type *const param_type = get_method_param_type(fun_type, i);
if (!is_atomic_type(param_type))
panic("unhandled parameter type");
ir_entity *param_ent = param_map[i];
if (!param->reg) {
if (!param_ent)
param_ent = new_parameter_entity(frame_type, i, param_type);
assert(get_entity_offset(param_ent) == INVALID_OFFSET);
set_entity_offset(param_ent, param->offset);
}
param->entity = param_ent;
}
free(param_map);
}
void mips_free_calling_convention(mips_calling_convention_t *const cconv)
{
free(cconv->parameters);
......
......@@ -10,6 +10,8 @@
typedef struct mips_reg_or_slot_t {
arch_register_t const *reg;
unsigned offset;
ir_entity *entity;
} mips_reg_or_slot_t;
typedef struct mips_calling_convention_t {
......@@ -19,6 +21,8 @@ typedef struct mips_calling_convention_t {
void mips_determine_calling_convention(mips_calling_convention_t *cconv, ir_type *fun_type);
void mips_layout_parameter_entities(mips_calling_convention_t *cconv, ir_graph *irg);
void mips_free_calling_convention(mips_calling_convention_t *cconv);
#endif
......@@ -810,7 +810,12 @@ static ir_node *gen_Proj_Proj_Start(ir_node *const node)
if (param->reg) {
return be_get_Start_proj(irg, param->reg);
} else {
panic("TODO");
dbg_info *const dbgi = get_irn_dbg_info(node);
ir_node *const block = be_transform_nodes_block(node);
ir_node *const mem = be_get_Start_mem(irg);
ir_node *const base = get_Start_sp(irg);
ir_node *const load = new_bd_mips_lw(dbgi, block, mem, base, param->entity, 0);
return be_new_Proj(load, pn_mips_lw_res);
}
}
......@@ -1100,6 +1105,8 @@ void mips_transform_graph(ir_graph *const irg)
ir_entity *const fun_ent = get_irg_entity(irg);
ir_type *const fun_type = get_entity_type(fun_ent);
mips_determine_calling_convention(&cur_cconv, fun_type);
mips_layout_parameter_entities(&cur_cconv, irg);
be_add_parameter_entity_stores(irg);
be_transform_graph(irg, NULL);
mips_free_calling_convention(&cur_cconv);
......
Markdown is supported
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