Commit 7167b92e authored by Matthias Braun's avatar Matthias Braun
Browse files

mark methods with lowered struct params, correctly handle x86 abi for this case

[r16018]
parent f2062b3d
......@@ -1946,6 +1946,8 @@ typedef enum {
function calls (stdcall). */
cc_this_call = 0x08000000, /**< The first parameter is a this pointer and is transmitted
in a special way. */
cc_compound_ret = 0x10000000, /**< the method returns a compound
type */
cc_bits = (0xFF << 24) /**< the calling convention bits */
} calling_convention;
......
......@@ -780,6 +780,11 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
/* Clean up the stack frame if we allocated it */
if (! no_alloc) {
/* the callee pops the shadow parameter */
if(get_method_calling_convention(mt) & cc_compound_ret) {
stack_size -= get_mode_size_bytes(mode_P_data);
}
curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, -stack_size);
add_irn_dep(curr_sp, mem_proj);
}
......@@ -1361,15 +1366,21 @@ static ir_node *create_barrier(be_abi_irg_t *env, ir_node *bl, ir_node **mem, pm
* @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;
static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl,
ir_node *mem, int n_res)
{
ir_graph *irg = env->birg->irg;
ir_entity *entity = get_irg_entity(irg);
ir_type *method_type = get_entity_type(entity);
be_abi_call_t *call = env->call;
const arch_isa_t *isa = env->birg->main_env->arch_env->isa;
dbg_info *dbgi;
pmap *reg_map = pmap_create();
ir_node *keep = pmap_get(env->keep_map, bl);
int in_max;
ir_node *ret;
int i, n;
unsigned pop;
ir_node **in;
ir_node *stack;
const arch_register_t **regs;
......@@ -1446,7 +1457,17 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, i
}
/* 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_res, n, in);
if(irn != NULL) {
dbgi = get_irn_dbg_info(irn);
} else {
dbgi = NULL;
}
/* we have to pop the shadow parameter in in case of struct returns */
pop = 0;
if(get_method_calling_convention(method_type) & cc_compound_ret) {
pop = get_mode_size_bytes(mode_P_data);
}
ret = be_new_Return(dbgi, env->birg->irg, bl, n_res, pop, n, in);
/* Set the register classes of the return's parameter accordingly. */
for(i = 0; i < n; ++i)
......
......@@ -85,6 +85,7 @@ typedef struct {
typedef struct {
be_node_attr_t node_attr;
int num_ret_vals; /**< number of return values */
unsigned pop; /**< number of bytes that should be popped */
} be_return_attr_t;
/** The be_Stack attribute type. */
......@@ -196,6 +197,8 @@ static int Return_cmp_attr(ir_node *a, ir_node *b) {
if (a_attr->num_ret_vals != b_attr->num_ret_vals)
return 1;
if (a_attr->pop != b_attr->pop)
return 1;
return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr);
}
......@@ -640,7 +643,7 @@ void be_Call_set_type(ir_node *call, ir_type *call_tp) {
/* Construct a new be_Return. */
ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *block, int n_res,
int n, ir_node *in[])
unsigned pop, int n, ir_node *in[])
{
be_return_attr_t *a;
ir_node *res;
......@@ -655,17 +658,24 @@ ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *block, int n_res,
a = get_irn_attr(res);
a->num_ret_vals = n_res;
a->pop = pop;
return res;
}
/* Returns the number of real returns values */
int be_Return_get_n_rets(ir_node *ret)
int be_Return_get_n_rets(const ir_node *ret)
{
be_return_attr_t *a = get_irn_attr(ret);
const be_return_attr_t *a = get_irn_generic_attr_const(ret);
return a->num_ret_vals;
}
unsigned be_Return_get_pop(const ir_node *ret)
{
const be_return_attr_t *a = get_irn_generic_attr_const(ret);
return a->pop;
}
int be_Return_append_node(ir_node *ret, ir_node *node)
{
int pos;
......
......@@ -335,12 +335,15 @@ enum {
* @param bl the block where the new node will be placed
* @param n_res number of "real" results
* @param n number of inputs
* @param pop pop number of bytes on return
* @param in input array
*/
ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *bl, int n_res, int n, ir_node *in[]);
ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *bl, int n_res, unsigned pop, int n, ir_node *in[]);
/** Returns the number of real returns values */
int be_Return_get_n_rets(ir_node *ret);
int be_Return_get_n_rets(const ir_node *ret);
unsigned be_Return_get_pop(const ir_node *ret);
/** appends a node to the return node, returns the position of the node */
int be_Return_append_node(ir_node *ret, ir_node *node);
......
......@@ -1752,7 +1752,13 @@ zero_neg:
static void emit_be_Return(const ir_node *node)
{
unsigned pop;
be_emit_cstring("\tret");
pop = be_Return_get_pop(node);
if(pop > 0) {
be_emit_irprintf(" $%d", pop);
}
be_emit_finish_line_gas(node);
}
......
......@@ -177,6 +177,8 @@ static ir_type *create_modified_mtd_type(const lower_params_t *lp, ir_type *mtp)
set_method_first_variadic_param_index(lowered, first_variadic);
/* associate the lowered type with the original one for easier access */
set_method_calling_convention(lowered,
get_method_calling_convention(mtp) | cc_compound_ret);
set_lowered_type(mtp, lowered);
return lowered;
......
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