unsigned in_reg : 1; /**< 1: this argument is transmitted in registers. */
unsigned on_stack : 1; /**< 1: this argument is transmitted on the stack. */
- int pos;
+ int pos;
const arch_register_t *reg;
- ir_entity *stack_ent;
- unsigned alignment; /**< stack alignment */
- unsigned space_before; /**< allocate space before */
- unsigned space_after; /**< allocate space after */
+ ir_entity *stack_ent;
+ ir_mode *load_mode;
+ unsigned alignment; /**< stack alignment */
+ unsigned space_before; /**< allocate space before */
+ unsigned space_after; /**< allocate space after */
} be_abi_call_arg_t;
struct _be_abi_call_t {
}
-void be_abi_call_param_stack(be_abi_call_t *call, int arg_pos, unsigned alignment, unsigned space_before, unsigned space_after)
+void be_abi_call_param_stack(be_abi_call_t *call, int arg_pos, ir_mode *load_mode, unsigned alignment, unsigned space_before, unsigned space_after)
{
be_abi_call_arg_t *arg = get_or_set_call_arg(call, 0, arg_pos, 1);
arg->on_stack = 1;
+ arg->load_mode = load_mode;
arg->alignment = alignment;
arg->space_before = space_before;
arg->space_after = space_after;
ir_graph *irg = env->birg->irg;
const arch_env_t *arch_env = env->birg->main_env->arch_env;
const arch_isa_t *isa = arch_env->isa;
- ir_type *mt = get_Call_type(irn);
+ ir_type *call_tp = get_Call_type(irn);
ir_node *call_ptr = get_Call_ptr(irn);
- int n_params = get_method_n_params(mt);
+ int n_params = get_method_n_params(call_tp);
ir_node *curr_mem = get_Call_mem(irn);
ir_node *bl = get_nodes_block(irn);
pset *results = pset_new_ptr(8);
ir_mode *mach_mode = sp->reg_class->mode;
struct obstack *obst = &env->obst;
int no_alloc = call->flags.bits.frame_is_setup_on_call;
- int n_res = get_method_n_ress(mt);
+ int n_res = get_method_n_ress(call_tp);
ir_node *res_proj = NULL;
int n_reg_params = 0;
int i, n;
/* Let the isa fill out the abi description for that call node. */
- arch_isa_get_call_abi(isa, mt, call);
+ arch_isa_get_call_abi(isa, call_tp, call);
/* Insert code to put the stack arguments on the stack. */
assert(get_Call_n_params(irn) == n_params);
be_abi_call_arg_t *arg = get_call_arg(call, 0, i);
assert(arg);
if (arg->on_stack) {
- int arg_size = get_type_size_bytes(get_method_param_type(mt, i));
+ int arg_size = get_type_size_bytes(get_method_param_type(call_tp, i));
stack_size += round_up2(arg->space_before, arg->alignment);
stack_size += round_up2(arg_size, arg->alignment);
ir_node *param = get_Call_param(irn, p);
ir_node *addr = curr_sp;
ir_node *mem = NULL;
- ir_type *param_type = get_method_param_type(mt, p);
+ ir_type *param_type = get_method_param_type(call_tp, p);
int param_size = get_type_size_bytes(param_type) + arg->space_after;
/*
n_reg_results + pn_be_Call_first_res + pset_count(caller_save),
n_ins, in, get_Call_type(irn));
}
+ be_Call_set_pop(low_call, call->pop);
ARR_APP1(ir_node *, env->calls, low_call);
/* create new stack pointer */
pn = i + pn_be_Call_first_res;
if(proj == NULL) {
- ir_type *res_type = get_method_res_type(mt, i);
+ ir_type *res_type = get_method_res_type(call_tp, i);
ir_mode *mode = get_type_mode(res_type);
proj = new_r_Proj(irg, bl, low_call, mode, pn);
res_projs[i] = proj;
ir_node *frame, *imem, *nmem, *store, *mem, *args, *args_bl;
const ir_edge_t *edge;
optimization_state_t state;
- int offset;
+ unsigned offset;
foreach_block_succ(start_bl, edge) {
ir_node *succ = get_edge_src_irn(edge);
frame_tp = get_irg_frame_type(irg);
offset = get_type_size_bytes(frame_tp);
for (ent = new_list; ent; ent = get_entity_link(ent)) {
- ir_type *tp = get_entity_type(ent);
- int align = get_type_alignment_bytes(tp);
+ ir_type *tp = get_entity_type(ent);
+ unsigned align = get_type_alignment_bytes(tp);
offset += align - 1;
- offset &= -align;
+ offset &= ~(align - 1);
set_entity_owner(ent, frame_tp);
add_class_member(frame_tp, ent);
/* must be automatic to set a fixed layout */
if (arg->in_reg) {
repl = pmap_get(env->regs, (void *) arg->reg);
- }
-
- else if(arg->on_stack) {
+ } else if(arg->on_stack) {
ir_node *addr = be_new_FrameAddr(sp->reg_class, irg, reg_params_bl, frame_pointer, arg->stack_ent);
/* For atomic parameters which are actually used, we create a Load node. */
if(is_atomic_type(param_type) && get_irn_n_edges(args[i]) > 0) {
- ir_mode *mode = get_type_mode(param_type);
- ir_node *load = new_rd_Load(NULL, irg, reg_params_bl,
- new_NoMem(), addr, mode);
+ ir_mode *mode = get_type_mode(param_type);
+ ir_mode *load_mode = arg->load_mode;
+
+ ir_node *load = new_r_Load(irg, reg_params_bl, new_NoMem(), addr, load_mode);
set_irn_pinned(load, op_pin_state_floats);
- repl = new_rd_Proj(NULL, irg, reg_params_bl, load,
- mode, pn_Load_res);
- }
+ repl = new_r_Proj(irg, reg_params_bl, load, load_mode, pn_Load_res);
- /* The stack parameter is not primitive (it is a struct or array),
- we thus will create a node representing the parameter's address
- on the stack. */
- else {
+ if (mode != load_mode) {
+ repl = new_r_Conv(irg, reg_params_bl, repl, mode);
+ }
+ } else {
+ /* The stack parameter is not primitive (it is a struct or array),
+ * we thus will create a node representing the parameter's address
+ * on the stack. */
repl = addr;
}
}
if(be_is_IncSP(irn)) {
if(ofs == BE_STACK_FRAME_SIZE_EXPAND) {
- ofs = get_type_size_bytes(get_irg_frame_type(env->birg->irg));
+ ofs = (int)get_type_size_bytes(get_irg_frame_type(env->birg->irg));
be_set_IncSP_offset(irn, ofs);
} else if(ofs == BE_STACK_FRAME_SIZE_SHRINK) {
- ofs = - get_type_size_bytes(get_irg_frame_type(env->birg->irg));
+ ofs = - (int)get_type_size_bytes(get_irg_frame_type(env->birg->irg));
be_set_IncSP_offset(irn, ofs);
}
}