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);
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;
}
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);
*/
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.
* 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
/** 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 */
/** 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 */
/**
* 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);
/* ------------------- *
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()
#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_ */