From 283996b9d042fb9db640520ab97d67d0a250d6dc Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Tue, 8 Nov 2005 14:33:11 +0000 Subject: [PATCH] a method type now has calling conventions and additional properties. The properties can be overwritten by a entity or a irg [r6889] --- ir/tr/type.c | 29 +++++++++++++++- ir/tr/type.h | 80 ++++++++++++++++++++++++++++++++++++++++++- ir/tr/type_t.h | 92 +++++++++++++++++++++++++++++++++++++------------- 3 files changed, 175 insertions(+), 26 deletions(-) diff --git a/ir/tr/type.c b/ir/tr/type.c index 9403e67bf..0edcb4e6f 100644 --- a/ir/tr/type.c +++ b/ir/tr/type.c @@ -87,9 +87,13 @@ int get_irp_new_node_nr(void); static ident *value_params_suffix = NULL; static ident *value_ress_suffix = NULL; +/** The default calling convention for method types. */ +static unsigned default_cc_mask; + /* Initialize the type module. */ -void firm_init_type(dbg_info *builtin_db) +void firm_init_type(dbg_info *builtin_db, unsigned def_cc_mask) { + default_cc_mask = def_cc_mask; value_params_suffix = new_id_from_str(VALUE_PARAMS_SUFFIX); value_ress_suffix = new_id_from_str(VALUE_RESS_SUFFIX); @@ -1102,6 +1106,7 @@ type *new_d_type_method(ident *name, int n_param, int n_res, dbg_info *db) { res->attr.ma.value_ress = NULL; res->attr.ma.variadicity = variadicity_non_variadic; res->attr.ma.first_variadic_param = -1; + res->attr.ma.irg_calling_conv = default_cc_mask; hook_new_type(res); return res; } @@ -1296,6 +1301,28 @@ void set_method_first_variadic_param_index(type *method, int index) method->attr.ma.first_variadic_param = index; } +unsigned (get_method_additional_properties)(const type *method) { + return _get_method_additional_properties(method); +} + +void (set_method_additional_properties)(type *method, unsigned mask) { + _set_method_additional_properties(method, mask); +} + +void (set_method_additional_property)(type *method, mtp_additional_property flag) { + _set_method_additional_property(method, flag); +} + +/* Returns the calling convention of an entities graph. */ +unsigned (get_method_calling_convention)(const type *method) { + return _get_method_calling_convention(method); +} + +/* Sets the calling convention of an entities graph. */ +void (set_method_calling_convention)(type *method, unsigned cc_mask) { + _set_method_calling_convention(method, cc_mask); +} + /* typecheck */ int (is_Method_type)(const type *method) { return _is_method_type(method); diff --git a/ir/tr/type.h b/ir/tr/type.h index 286962899..4bf2e3b72 100644 --- a/ir/tr/type.h +++ b/ir/tr/type.h @@ -764,11 +764,89 @@ int get_method_first_variadic_param_index(const type *method); */ void set_method_first_variadic_param_index(type *method, int index); +/** + * additional method type properties: + * Tell about special properties of a method type. Some + * of these may be discovered by analyses. + */ +typedef enum { + mtp_no_property = 0x00000000, /**< no additional properties, default */ + mtp_property_const = 0x00000001, /**< This graph did not access memory and calculates + its return values solely from its parameters. + GCC: __attribute__((const)). */ + mtp_property_pure = 0x00000002, /**< This graph did NOT write to memory and calculates + its return values solely form its parameters and + the memory they points to (or global vars). + GCC: __attribute__((pure)). */ + mtp_property_noreturn = 0x00000004, /**< This graph did not return due to an aborting system + call. + GCC: __attribute__((noreturn)). */ + mtp_property_nothrow = 0x00000008, /**< This graph cannot throw an exception. + GCC: __attribute__((nothrow)). */ + mtp_property_naked = 0x00000010, /**< This graph is naked. + GCC: __attribute__((naked)). */ + mtp_property_malloc = 0x00000020, /**< This graph returns newly allocate memory. + GCC: __attribute__((malloc)). */ + mtp_property_inherited = 0x80000000 /**< used only in irgs, means property is inherited + from type. */ +} mtp_additional_property; + +/** Returns the mask of the additional graph properties. */ +unsigned get_method_additional_properties(const type *method); + +/** Sets the mask of the additional graph properties. */ +void set_method_additional_properties(type *method, unsigned property_mask); + +/** Sets one additional graph property. */ +void set_method_additional_property(type *method, mtp_additional_property flag); + +/** + * calling conventions + */ +typedef enum { + cc_reg_param = 0x00000001, /**< Transmit parameters in registers, else the stack is used. + This flag may be set as default on some architectures. */ + cc_last_on_top = 0x00000002, /**< The last non-register parameter is transmitted on top of + the stack. This is equivalent to the stdcall or pascal + calling convention. If this flag is not set, the first + non-register parameter is used (cdecl calling convention) */ + cc_callee_clear_stk = 0x00000004, /**< The callee clears the stack. This forbids variadic + function calls (stdcall). */ + cc_this_call = 0x00000008 /**< The first parameter is a this pointer and is transmitted + in a special way. */ +} calling_convention; + +/** + * check for the CDECL calling convention + */ +#define IS_CDECL(cc_mask) (((cc_mask) & (cc_callee_clear_stk|cc_last_on_top)) == 0) + +/** + * check for the STDCALL calling convention + */ +#define IS_STDCALL(cc_mask) (((cc_mask) & (cc_callee_clear_stk|cc_last_on_top)) == cc_callee_clear_stk) + +/** + * add the CDECL convention bits + */ +#define SET_CDECL(cc_mask) ((cc_mask) & ~(cc_callee_clear_stk|cc_last_on_top)) + +/** + * add the STDCALL convention bits + */ +#define SET_STDCALL(cc_mask) (((cc_mask) & ~cc_last_on_top) | cc_callee_clear_stk) + +/** Returns the calling convention of an entities graph. */ +unsigned get_method_calling_convention(const type *method); + +/** Sets the calling convention of an entities graph. */ +void set_method_calling_convention(type *method, unsigned cc_mask); + /** Returns true if a type is a method type. */ int is_Method_type (const type *method); /** - * @page union_type Representation of a union type. + * @page union_type Representation of a union (variant) type. * * The union type represents union types. * - n_types: Number of unioned types. diff --git a/ir/tr/type_t.h b/ir/tr/type_t.h index 549567897..a5699ea66 100644 --- a/ir/tr/type_t.h +++ b/ir/tr/type_t.h @@ -10,14 +10,15 @@ * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ -# ifndef _TYPE_T_H_ -# define _TYPE_T_H_ +#ifndef _TYPE_T_H_ +#define _TYPE_T_H_ -# include "firm_config.h" -# include "type.h" -# include "tpop_t.h" +#include "firm_config.h" +#include "type.h" +#include "tpop_t.h" +#include "irgraph.h" -# include "array.h" +#include "array.h" /** * @file type_t.h @@ -49,14 +50,16 @@ typedef struct { /** method attributes */ typedef struct { - int n_params; /**< number of parameters */ - tp_ent_pair *param_type; /**< array of parameter type/value entities pairs */ - type *value_params; /**< A type whose entities represent copied value arguments. */ - int n_res; /**< number of results */ - tp_ent_pair *res_type; /**< array of result type/value entity pairs */ - type *value_ress; /**< A type whose entities represent copied value results. */ - variadicity variadicity; /**< variadicity of the method. */ - int first_variadic_param; /**< index of the first variadic param or -1 if non-variadic .*/ + int n_params; /**< number of parameters */ + tp_ent_pair *param_type; /**< array of parameter type/value entities pairs */ + type *value_params; /**< A type whose entities represent copied value arguments. */ + int n_res; /**< number of results */ + tp_ent_pair *res_type; /**< array of result type/value entity pairs */ + type *value_ress; /**< A type whose entities represent copied value results. */ + variadicity variadicity; /**< variadicity of the method. */ + int first_variadic_param; /**< index of the first variadic param or -1 if non-variadic .*/ + unsigned additional_properties; /**< Set of additional method properties. */ + unsigned irg_calling_conv; /**< this is a set of calling convention flags. */ } mtd_attr; /** union attributes */ @@ -66,13 +69,13 @@ typedef struct { /** array attributes */ typedef struct { - int n_dimensions; /**< Number of array dimensions. */ - ir_node **lower_bound; /**< Lower bounds of dimensions. Usually all 0. */ - ir_node **upper_bound; /**< Upper bounds or dimensions. */ - int *order; /**< Ordering of dimensions. */ - type *element_type; /**< The type of the array elements. */ - entity *element_ent; /**< Entity for the array elements, to be used for - element selection with Sel. */ + int n_dimensions; /**< Number of array dimensions. */ + ir_node **lower_bound; /**< Lower bounds of dimensions. Usually all 0. */ + ir_node **upper_bound; /**< Upper bounds or dimensions. */ + int *order; /**< Ordering of dimensions. */ + type *element_type; /**< The type of the array elements. */ + entity *element_ent; /**< Entity for the array elements, to be used for + element selection with Sel. */ } arr_attr; /** enum attributes */ @@ -189,9 +192,10 @@ void set_default_size_bits(type *tp, int size); /** * Initialize the type module. * - * @param builtin_db debug info for builtin objects + * @param builtin_db debug info for builtin objects + * @param default_cc_mask default calling conventions for methods */ -void firm_init_type(dbg_info *builtin_db); +void firm_init_type(dbg_info *builtin_db, unsigned default_cc_mask); /* ------------------- * @@ -393,6 +397,41 @@ _get_method_n_ress(const type *method) { return method->attr.ma.n_res; } +static INLINE unsigned +_get_method_additional_properties(const type *method) { + assert(method && (method->type_op == type_method)); + return method->attr.ma.additional_properties; +} + +static INLINE void +_set_method_additional_properties(type *method, unsigned mask) { + assert(method && (method->type_op == type_method)); + + /* do not allow to set the mtp_property_inherited flag or + * the automatic inheritance of flags will not work */ + method->attr.ma.additional_properties = mask & ~mtp_property_inherited; +} + +static INLINE void +_set_method_additional_property(type *method, mtp_additional_property flag) { + assert(method && (method->type_op == type_method)); + + /* do not allow to set the mtp_property_inherited flag or + * the automatic inheritance of flags will not work */ + method->attr.ma.additional_properties |= flag & ~mtp_property_inherited; +} + +static INLINE unsigned +_get_method_calling_convention(const type *method) { + assert(method && (method->type_op == type_method)); + return method->attr.ma.irg_calling_conv; +} + +static INLINE void +_set_method_calling_convention(type *method, unsigned cc_mask) { + assert(method && (method->type_op == type_method)); + method->attr.ma.irg_calling_conv = cc_mask; +} #define set_master_type_visited(val) _set_master_type_visited(val) #define get_master_type_visited() _get_master_type_visited() @@ -426,5 +465,10 @@ _get_method_n_ress(const type *method) { #define is_atomic_type(tp) _is_atomic_type(tp) #define get_method_n_params(method) _get_method_n_params(method) #define get_method_n_ress(method) _get_method_n_ress(method) +#define get_method_additional_properties(method) _get_method_additional_properties(method) +#define set_method_additional_properties(method, mask) _set_method_additional_properties(method, mask) +#define set_method_additional_property(method, flag) _set_method_additional_property(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) -# endif /* _TYPE_T_H_ */ +#endif /* _TYPE_T_H_ */ -- 2.20.1