type *param_type = get_method_param_type(mt, p);
int param_size = get_type_size_bytes(param_type) + arg->space_after;
- curr_ofs += arg->space_before;
- curr_ofs = round_up2(curr_ofs, arg->alignment);
+ /*
+ * If we wanted to build the arguments sequentially,
+ * the stack pointer for the next must be incremented,
+ * and the memory value propagated.
+ */
+ if (do_seq) {
+ curr_ofs = 0;
+ addr = curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, curr_mem,
+ param_size + arg->space_before, be_stack_dir_expand);
+ }
+ else {
+ curr_ofs += arg->space_before;
+ curr_ofs = round_up2(curr_ofs, arg->alignment);
- /* Make the expression to compute the argument's offset. */
- if(curr_ofs > 0) {
- addr = new_r_Const_long(irg, bl, mode_Is, curr_ofs);
- addr = new_r_Add(irg, bl, curr_sp, addr, mach_mode);
+ /* Make the expression to compute the argument's offset. */
+ if(curr_ofs > 0) {
+ addr = new_r_Const_long(irg, bl, mode_Is, curr_ofs);
+ addr = new_r_Add(irg, bl, curr_sp, addr, mach_mode);
+ }
}
/* Insert a store for primitive arguments. */
- if(is_atomic_type(param_type)) {
+ if (is_atomic_type(param_type)) {
mem = new_r_Store(irg, bl, curr_mem, addr, param);
mem = new_r_Proj(irg, bl, mem, mode_M, pn_Store_M);
}
mem = new_r_Proj(irg, bl, mem, mode_M, pn_CopyB_M_regular);
}
- obstack_ptr_grow(obst, mem);
-
curr_ofs += param_size;
- /*
- * If we wanted to build the arguments sequentially,
- * the stack pointer for the next must be incremented,
- * and the memory value propagated.
- */
- if(do_seq) {
- curr_ofs = 0;
- curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, curr_mem, param_size, be_stack_dir_expand);
+ if (do_seq)
curr_mem = mem;
- }
+ else
+ obstack_ptr_grow(obst, mem);
}
in = (ir_node **) obstack_finish(obst);
return irn;
}
+/**
+ * Creates a be_Return for a Return node.
+ *
+ * @param @env the abi environment
+ * @param irn the Return node or NULL if there was none
+ * @param bl the block where the be_Retun should be placed
+ * @param mem the current memory
+ * @param n_res number of return results
+ */
static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, ir_node *mem, int n_res) {
be_abi_call_t *call = env->call;
const arch_isa_t *isa = env->birg->main_env->arch_env->isa;
it then. Else we use the stack from the start block and let
the ssa construction fix the usage.
*/
- stack = keep ? get_irn_n(keep, 0) : be_abi_reg_map_get(env->regs, isa->sp);
+ stack = be_abi_reg_map_get(env->regs, isa->sp);
+ if (keep) {
+ stack = get_irn_n(keep, 0);
+ exchange(keep, new_r_Bad(env->birg->irg));
+ }
be_abi_reg_map_set(reg_map, isa->sp, stack);
/* Insert results for Return into the register map. */
}
/* The in array for the new back end return is now ready. */
- ret = be_new_Return(irn ? get_irn_dbg_info(irn) : NULL, env->birg->irg, bl, n, in);
+ ret = be_new_Return(irn ? get_irn_dbg_info(irn) : NULL, env->birg->irg, bl, n_res, n, in);
/* Set the register classes of the return's parameter accordingly. */
for(i = 0; i < n; ++i)
for (i = 0, n = get_Block_n_cfgpreds(end); i < n; ++i) {
ir_node *irn = get_Block_cfgpred(end, i);
- if (get_irn_opcode(irn) == iro_Return) {
- ir_node *ret = create_be_return(env, irn, get_nodes_block(irn), get_Return_mem(irn), get_Return_n_ress(irn));
- exchange(irn, ret);
+ if (is_Return(irn)) {
+ ir_node *ret = create_be_return(env, irn, get_nodes_block(irn), get_Return_mem(irn), get_Return_n_ress(irn));
+ exchange(irn, ret);
}
}
-
- if (n <= 0) {
- /* we have endless loops, add a dummy return without return vals */
- ir_node *ret = create_be_return(env, NULL, end, get_irg_no_mem(irg), n);
- add_End_keepalive(get_irg_end(irg), ret);
- }
+ /* if we have endless loops here, n might be <= 0. Do NOT create a be_Return than,
+ the code is dead and will never be executed. */
del_pset(dont_save);
obstack_free(&env->obst, args);