if(proj > curr_res_proj)
curr_res_proj = proj;
- if(arg->in_reg)
+ if(arg->in_reg) {
pset_remove_ptr(caller_save, arg->reg);
+ //pmap_insert(arg_regs, arg->reg, INT_TO_PTR(proj + 1))
+ }
}
}
}
int index = low_args[i];
be_abi_call_arg_t *arg = get_call_arg(call, 0, index);
assert(arg->reg != NULL);
- be_set_constr_single_reg(low_call, index, arg->reg);
+
+#if 0
+ if(pmap_contains(arg_regs, (void *) arg->reg)) {
+ int out_proj_num = PTR_TO_INT(be_abi_reg_map_get(arg_regs, arg->reg)) - 1;
+ be_node_set_must_be_same(low_call, out_proj_num, low_args[i]);
+ }
+
+ else
+#endif
+ be_set_constr_single_reg(low_call, index, arg->reg);
}
/* Set the register constraints of the results. */
static void create_barrier(be_abi_irg_t *env, ir_node *bl, ir_node **mem, pmap *regs, int in_req)
{
ir_graph *irg = env->birg->irg;
- int i, j, n;
+ int i, n;
int n_regs = pmap_count(regs);
ir_node *irn;
ir_node **in;
const arch_register_t *reg = rm[n].reg;
proj = new_r_Proj(env->birg->irg, bl, irn, get_irn_mode(rm[i].irn), n);
+ be_node_set_reg_class(irn, n, reg->reg_class);
if(in_req)
be_set_constr_single_reg(irn, n, reg);
be_set_constr_single_reg(irn, pos, reg);
ir_node *end = get_irg_end_block(irg);
ir_node *arg_tuple = get_irg_args(irg);
ir_node *no_mem = get_irg_no_mem(irg);
+ ir_node *mem = get_irg_initial_mem(irg);
type *method_type = get_entity_type(get_irg_entity(irg));
pset *dont_save = pset_new_ptr(8);
pmap *reg_proj_map = pmap_create();
const arch_register_class_t *cls = arch_isa_get_reg_class(isa, i);
for(j = 0; j < cls->n_regs; ++j) {
const arch_register_t *reg = &cls->regs[j];
- if(arch_register_type_is(reg, callee_save))
+ if(arch_register_type_is(reg, callee_save) || arch_register_type_is(reg, ignore))
pmap_insert(env->regs, (void *) reg, NULL);
}
}
obstack_free(&env->obst, rm);
/* Generate the Prologue */
- fp_reg = call->cb->prologue(env->cb, env->regs);
- create_barrier(env, bl, NULL, env->regs, 0);
- env->init_sp = pmap_get(env->regs, (void *) sp);
+ fp_reg = call->cb->prologue(env->cb, &mem, env->regs);
+ create_barrier(env, bl, &mem, env->regs, 0);
+
+ env->init_sp = be_abi_reg_map_get(env->regs, sp);
env->init_sp = be_new_IncSP(sp, irg, bl, env->init_sp, no_mem, BE_STACK_FRAME_SIZE, be_stack_dir_along);
arch_set_irn_register(env->birg->main_env->arch_env, env->init_sp, sp);
- pmap_insert(env->regs, (void *) sp, env->init_sp);
- frame_pointer = pmap_get(env->regs, (void *) fp_reg);
+ be_abi_reg_map_set(env->regs, sp, env->init_sp);
+ frame_pointer = be_abi_reg_map_get(env->regs, sp);
set_irg_frame(irg, frame_pointer);
/* Now, introduce stack param nodes for all parameters passed on the stack */
int n_res = get_Return_n_ress(irn);
pmap *reg_map = pmap_create();
ir_node *mem = get_Return_mem(irn);
+ int in_max;
ir_node *ret;
int i, n;
ir_node **in;
+ const arch_register_t **regs;
pmap_insert(reg_map, (void *) sp, pmap_get(env->regs, (void *) sp));
create_barrier(env, bl, &mem, reg_map, 1);
call->cb->epilogue(env->cb, bl, &mem, reg_map);
- obstack_ptr_grow(&env->obst, mem);
- obstack_ptr_grow(&env->obst, pmap_get(reg_map, (void *) sp));
+ /*
+ Maximum size of the in array for Return nodes is
+ return args + callee save/ignore registers + memory + stack pointer
+ */
+ in_max = pmap_count(reg_map) + get_Return_n_ress(irn) + 2;
+
+ in = obstack_alloc(&env->obst, in_max * sizeof(in[0]));
+ regs = obstack_alloc(&env->obst, in_max * sizeof(regs[0]));
+
+ in[0] = mem;
+ in[1] = be_abi_reg_map_get(reg_map, sp);
+ regs[0] = NULL;
+ regs[1] = sp;
+ n = 2;
/* clear SP entry, since it has already been grown. */
pmap_insert(reg_map, (void *) sp, NULL);
ir_node *res = get_Return_res(irn, i);
be_abi_call_arg_t *arg = get_call_arg(call, 1, i);
- obstack_ptr_grow(&env->obst, pmap_get(reg_map, (void *) arg->reg));
+ in[n] = be_abi_reg_map_get(reg_map, arg->reg);
+ regs[n++] = arg->reg;
/* Clear the map entry to mark the register as processed. */
- pmap_insert(reg_map, (void *) arg->reg, NULL);
+ be_abi_reg_map_set(reg_map, arg->reg, NULL);
}
/* grow the rest of the stuff. */
pmap_foreach(reg_map, ent) {
- if(ent->value)
- obstack_ptr_grow(&env->obst, ent->value);
+ if(ent->value) {
+ in[n] = ent->value;
+ regs[n++] = ent->key;
+ }
}
/* The in array for the new back end return is now ready. */
- n = obstack_object_size(&env->obst) / sizeof(in[0]);
- in = obstack_finish(&env->obst);
ret = be_new_Return(irg, bl, n, in);
+ /* Set the register classes of the return's parameter accordingly. */
+ for(i = 0; i < n; ++i)
+ if(regs[i])
+ be_node_set_reg_class(ret, i, regs[i]->reg_class);
+
/* Free the space of the Epilog's in array and the register <-> proj map. */
obstack_free(&env->obst, in);
exchange(irn, ret);