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

Set the calling convention right when construction a method type.

parent 5e867110
......@@ -1195,11 +1195,12 @@ FIRM_API int is_Union_type(const ir_type *uni);
* @param n_param the number of parameters
* @param n_res the number of results
* @param is_variadic whether the function is variadic
* @param cc_mask the calling convention
*
* The arrays for the parameter and result types are not initialized by
* the constructor.
*/
FIRM_API ir_type *new_type_method(size_t n_param, size_t n_res, int is_variadic);
FIRM_API ir_type *new_type_method(size_t n_param, size_t n_res, int is_variadic, unsigned cc_mask);
/** Returns the number of parameters of this method. */
FIRM_API size_t get_method_n_params(const ir_type *method);
......@@ -1296,15 +1297,9 @@ typedef enum {
/** Returns the calling convention of an entities graph. */
FIRM_API unsigned get_method_calling_convention(const ir_type *method);
/** Sets the calling convention of an entities graph. */
FIRM_API void set_method_calling_convention(ir_type *method, unsigned cc_mask);
/** Returns the number of registers parameters, 0 means default. */
FIRM_API unsigned get_method_n_regparams(ir_type *method);
/** Sets the number of registers parameters, 0 means default. */
FIRM_API void set_method_n_regparams(ir_type *method, unsigned n_regs);
/** Returns true if a type is a method type. */
FIRM_API int is_Method_type(const ir_type *method);
......
......@@ -117,7 +117,7 @@ static void handle_intrinsic(ir_node *node, void *data)
static ir_type *make_divmod_type(ir_type *const tp)
{
ir_type *const mtp = new_type_method(2, 1, false);
ir_type *const mtp = new_type_method(2, 1, false, cc_cdecl_set);
set_method_param_type(mtp, 0, tp);
set_method_param_type(mtp, 1, tp);
set_method_res_type(mtp, 0, tp);
......
......@@ -106,7 +106,7 @@ static ir_entity *uldivmod;
static ir_entity *make_divmod(char const *const name, ir_type *const even, ir_type *const odd)
{
ir_type *const mtp = new_type_method(4, 4, false);
ir_type *const mtp = new_type_method(4, 4, false, cc_cdecl_set);
set_method_param_type(mtp, 0, even);
set_method_param_type(mtp, 1, odd);
set_method_param_type(mtp, 2, even);
......
......@@ -1135,7 +1135,7 @@ static void ia32_select_instructions(ir_graph *irg)
static ir_entity *mcount = NULL;
if (mcount == NULL) {
ir_type *tp = new_type_method(0, 0, false);
ir_type *tp = new_type_method(0, 0, false, cc_cdecl_set);
ident *id = new_id_from_str("mcount");
mcount = new_global_entity(get_glob_type(), id, tp,
ir_visibility_external,
......
......@@ -1188,7 +1188,7 @@ zero_neg:
static ir_type *get_thunk_type(void)
{
if (!thunk_type) {
ir_type *const tp = new_type_method(0, 1, false);
ir_type *const tp = new_type_method(0, 1, false, cc_cdecl_set);
set_method_res_type(tp, 0, get_type_for_mode(mode_P));
thunk_type = tp;
}
......
......@@ -288,7 +288,7 @@ static void handle_intrinsic(ir_node *node, void *data)
static ir_type *make_mod_type(ir_type *const tp)
{
ir_type *const mtp = new_type_method(2, 1, false);
ir_type *const mtp = new_type_method(2, 1, false, cc_cdecl_set);
set_method_param_type(mtp, 0, tp);
set_method_param_type(mtp, 1, tp);
set_method_res_type(mtp, 0, tp);
......
......@@ -160,7 +160,8 @@ bool sparc_variadic_fixups(ir_graph *irg, calling_convention_t *cconv)
size_t const n_params = get_method_n_params(mtp);
size_t const n_ress = get_method_n_ress(mtp);
size_t const new_n_params = n_params + (SPARC_N_PARAM_REGS - cconv->n_param_regs);
ir_type *const new_mtp = new_type_method(new_n_params, n_ress, true);
unsigned const cc_mask = get_method_calling_convention(mtp);
ir_type *const new_mtp = new_type_method(new_n_params, n_ress, true, cc_mask);
type_dbg_info *const dbgi = get_type_dbg_info(mtp);
set_type_dbg_info(new_mtp, dbgi);
......
......@@ -1634,7 +1634,7 @@ static void read_type(read_env_t *env)
size_t const nparams = read_size_t(env);
size_t const nresults = read_size_t(env);
bool const is_variadic = read_long(env);
type = new_type_method(nparams, nresults, is_variadic);
type = new_type_method(nparams, nresults, is_variadic, callingconv);
for (size_t i = 0; i < nparams; i++) {
long ptypenr = read_long(env);
......@@ -1649,7 +1649,6 @@ static void read_type(read_env_t *env)
set_method_res_type(type, i, restype);
}
set_method_calling_convention(type, callingconv);
set_method_additional_properties(type, addprops);
goto finish_type;
}
......
......@@ -152,7 +152,7 @@ static void add_constructor(ir_entity *method)
static ir_entity *get_init_firmprof_ref(void)
{
ident *const init_name = new_id_from_str("__init_firmprof");
ir_type *const init_type = new_type_method(3, 0, false);
ir_type *const init_type = new_type_method(3, 0, false, cc_cdecl_set);
ir_type *const uint = get_type_for_mode(mode_Iu);
ir_type *const uintptr = new_type_pointer(uint);
ir_type *const string = new_type_pointer(get_type_for_mode(mode_Bs));
......@@ -177,7 +177,7 @@ static ir_graph *gen_initializer_irg(ir_entity *ent_filename, ir_entity *bblock_
{
ident *const name = new_id_from_str("__firmprof_initializer");
ir_type *const owner = get_glob_type();
ir_type *const type = new_type_method(0, 0, false);
ir_type *const type = new_type_method(0, 0, false, cc_cdecl_set);
ir_entity *const ent = new_global_entity(owner, name, type, ir_visibility_local, IR_LINKAGE_DEFAULT);
ir_graph *const irg = new_ir_graph(ent, 0);
......
......@@ -95,7 +95,7 @@ static void widen_builtin(ir_node *node)
ir_type *new_arg1 = get_type_for_mode(target_mode);
ir_type *new_result = get_method_res_type(mtp, 0);
ir_type *new_type = new_type_method(1, 1, false);
ir_type *new_type = new_type_method(1, 1, false, cc_cdecl_set);
set_method_param_type(new_type, 0, new_arg1);
set_method_res_type(new_type, 0, new_result);
set_Builtin_type(node, new_type);
......
......@@ -179,9 +179,13 @@ static ir_type *lower_mtp(lowering_env_t const *const env, ir_type *mtp)
assert(nn_ress <= n_ress*2);
assert(nn_params <= n_params + n_ress);
unsigned cconv = get_method_calling_convention(mtp);
if (nn_params > n_params)
cconv |= cc_compound_ret;
/* create the new type */
bool const is_variadic = is_method_variadic(mtp);
lowered = new_type_method(nn_params, nn_ress, is_variadic);
lowered = new_type_method(nn_params, nn_ress, is_variadic, cconv);
set_type_dbg_info(lowered, get_type_dbg_info(mtp));
/* fill it */
......@@ -190,12 +194,6 @@ static ir_type *lower_mtp(lowering_env_t const *const env, ir_type *mtp)
for (size_t i = 0; i < nn_ress; ++i)
set_method_res_type(lowered, i, results[i]);
unsigned cconv = get_method_calling_convention(mtp);
if (nn_params > n_params) {
cconv |= cc_compound_ret;
}
set_method_calling_convention(lowered, cconv);
mtp_additional_properties mtp_properties = get_method_additional_properties(mtp);
/* after lowering the call is not pure anymore, since it writes to the
* memory for the return value passed to it */
......
......@@ -92,7 +92,7 @@ static void lower_small_copyb_node(ir_node *irn)
static ir_type *get_memcpy_methodtype(void)
{
ir_type *tp = new_type_method(3, 1, false);
ir_type *tp = new_type_method(3, 1, false, cc_cdecl_set);
ir_mode *size_t_mode = get_ir_mode(native_mode_bytes);
set_method_param_type(tp, 0, get_type_for_mode(mode_P));
......
......@@ -149,7 +149,7 @@ static ir_type *get_conv_type(ir_mode *imode, ir_mode *omode)
n_res = 2;
/* create a new method type */
mtd = new_type_method(n_param, n_res, false);
mtd = new_type_method(n_param, n_res, false, cc_cdecl_set);
/* set param types and result types */
n_param = 0;
......@@ -1571,8 +1571,9 @@ static ir_type *lower_mtp(ir_type *mtp)
return mtp;
}
bool const is_variadic = is_method_variadic(mtp);
res = new_type_method(n_param, n_res, is_variadic);
bool const is_variadic = is_method_variadic(mtp);
unsigned const cc_mask = get_method_calling_convention(mtp);
res = new_type_method(n_param, n_res, is_variadic, cc_mask);
set_type_dbg_info(res, get_type_dbg_info(mtp));
/* set param types and result types */
......@@ -2113,7 +2114,8 @@ static ir_type *lower_Builtin_type(pmap *const type_map, ir_type *const mtp, ir_
return mtp;
}
res = new_type_method(n_params, n_results, false);
unsigned const cc_mask = get_method_calling_convention(mtp);
res = new_type_method(n_params, n_results, false, cc_mask);
set_type_dbg_info(res, get_type_dbg_info(mtp));
/* set param types and result types */
......@@ -2587,7 +2589,7 @@ static int lower_mux_cb(ir_node *mux)
static ir_type *make_type_4_2(ir_type *const even, ir_type *const odd)
{
ir_type *const tp = new_type_method(4, 2, false);
ir_type *const tp = new_type_method(4, 2, false, cc_cdecl_set);
set_method_param_type(tp, 0, even);
set_method_param_type(tp, 1, odd);
set_method_param_type(tp, 2, even);
......@@ -2599,7 +2601,7 @@ static ir_type *make_type_4_2(ir_type *const even, ir_type *const odd)
static ir_type *make_type_2_2(ir_type *const even, ir_type *const odd)
{
ir_type *const tp = new_type_method(2, 2, false);
ir_type *const tp = new_type_method(2, 2, false, cc_cdecl_set);
set_method_param_type(tp, 0, even);
set_method_param_type(tp, 1, odd);
set_method_res_type(tp, 0, even);
......
......@@ -327,10 +327,11 @@ static ir_type *lower_method_type(ir_type *mtp)
if (res != NULL)
return res;
size_t const n_param = get_method_n_params(mtp);
size_t const n_res = get_method_n_ress(mtp);
bool const is_variadic = is_method_variadic(mtp);
res = new_type_method(n_param, n_res, is_variadic);
size_t const n_param = get_method_n_params(mtp);
size_t const n_res = get_method_n_ress(mtp);
bool const is_variadic = is_method_variadic(mtp);
unsigned const cc_mask = get_method_calling_convention(mtp);
res = new_type_method(n_param, n_res, is_variadic, cc_mask);
/* set param types and result types */
for (size_t i = 0; i < n_param; ++i) {
......@@ -765,7 +766,7 @@ static void make_binop_type(ir_type **const memoized, ir_type *const left,
ir_type *const right, ir_type *const res)
{
if (!*memoized) {
ir_type *const type = *memoized = new_type_method(2, 1, false);
ir_type *const type = *memoized = new_type_method(2, 1, false, cc_cdecl_set);
set_method_param_type(type, 0, left);
set_method_param_type(type, 1, right);
set_method_res_type( type, 0, res);
......@@ -776,7 +777,7 @@ static void make_unop_type(ir_type **const memoized, ir_type *const op,
ir_type *const res)
{
if (!*memoized) {
ir_type *const type = *memoized = new_type_method(1, 1, false);
ir_type *const type = *memoized = new_type_method(1, 1, false, cc_cdecl_set);
set_method_param_type(type, 0, op);
set_method_res_type( type, 0, res);
}
......
......@@ -423,7 +423,7 @@ static void change_entity_type(const quadruple_t *q, ir_entity *ent)
/* Create the new type for our clone. It must have one parameter
less then the original.*/
ir_type *const new_mtp = new_type_method(n_params - 1, n_ress, false);
ir_type *const new_mtp = new_type_method(n_params - 1, n_ress, false, cc_cdecl_set);
/* We must set the type of the methods parameters.*/
for (size_t i = 0, j = 0; i < n_params; ++i) {
......
......@@ -519,17 +519,18 @@ int (is_Struct_type)(const ir_type *strct)
return is_struct_type_(strct);
}
ir_type *new_type_method(size_t const n_param, size_t const n_res, int const is_variadic)
ir_type *new_type_method(size_t const n_param, size_t const n_res, int const is_variadic, unsigned const cc_mask)
{
ir_type *res = new_type(tpo_method, sizeof(method_attr), mode_P);
res->flags |= tf_layout_fixed;
res->size = get_mode_size_bytes(mode_P);
res->attr.method.n_params = n_param;
res->attr.method.params = XMALLOCNZ(ir_type*, n_param);
res->attr.method.n_res = n_res;
res->attr.method.res_type = XMALLOCNZ(ir_type*, n_res);
res->attr.method.variadic = is_variadic;
res->attr.method.properties = mtp_no_property;
res->flags |= tf_layout_fixed;
res->size = get_mode_size_bytes(mode_P);
res->attr.method.n_params = n_param;
res->attr.method.params = XMALLOCNZ(ir_type*, n_param);
res->attr.method.n_res = n_res;
res->attr.method.res_type = XMALLOCNZ(ir_type*, n_res);
res->attr.method.variadic = is_variadic;
res->attr.method.irg_calling_conv = cc_mask;
res->attr.method.properties = mtp_no_property;
set_type_alignment(res, 1);
hook_new_type(res);
return res;
......@@ -636,11 +637,6 @@ unsigned (get_method_calling_convention)(const ir_type *method)
return get_method_calling_convention_(method);
}
void (set_method_calling_convention)(ir_type *method, unsigned cc_mask)
{
set_method_calling_convention_(method, cc_mask);
}
unsigned get_method_n_regparams(ir_type *method)
{
unsigned cc = get_method_calling_convention(method);
......@@ -649,14 +645,6 @@ unsigned get_method_n_regparams(ir_type *method)
return cc & ~cc_bits;
}
void set_method_n_regparams(ir_type *method, unsigned n_regs)
{
unsigned cc = get_method_calling_convention(method);
assert(IS_FASTCALL(cc));
set_method_calling_convention(method, (cc & cc_bits) | (n_regs & ~cc_bits));
}
int (is_Method_type)(const ir_type *method)
{
return is_method_type_(method);
......
......@@ -49,7 +49,6 @@
#define set_method_additional_properties(method, mask) set_method_additional_properties_(method, mask)
#define add_method_additional_properties(method, flag) add_method_additional_properties_(method, flag)
#define get_method_calling_convention(method) get_method_calling_convention_(method)
#define set_method_calling_convention(method, cc_mask) set_method_calling_convention_(method, cc_mask)
/** Compound type attributes. */
typedef struct {
......@@ -360,12 +359,6 @@ static inline unsigned get_method_calling_convention_(const ir_type *method)
return method->attr.method.irg_calling_conv;
}
static inline void set_method_calling_convention_(ir_type *method, unsigned cc_mask)
{
assert(is_Method_type(method));
method->attr.method.irg_calling_conv = cc_mask;
}
/**
* Check if type is a compound or array type.
* This function returns true iff a value of this type cannot be represented by
......@@ -381,7 +374,6 @@ ir_type *new_type_segment(ident *name, type_flags flags);
static inline void copy_method_properties(ir_type *const dst, ir_type const *const src)
{
set_method_calling_convention(dst, get_method_calling_convention(src));
set_method_additional_properties(dst, get_method_additional_properties(src));
}
......
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