ir_mode *mode;
unsigned cc = get_method_calling_convention(method_type);
int n = get_method_n_params(method_type);
- int biggest_n = -1;
- int stack_idx = 0;
int i;
- ir_mode **modes;
- const arch_register_t *reg;
be_abi_call_flags_t call_flags = be_abi_call_get_flags(abi);
unsigned use_push = !IS_P6_ARCH(isa->opt_arch);
call_flags.bits.fp_free = 0; /* the frame pointer is fixed in IA32 */
call_flags.bits.call_has_imm = 1; /* IA32 calls can have immediate address */
- /* set stack parameter passing style */
+ /* set parameter passing style */
be_abi_call_set_flags(abi, call_flags, &ia32_abi_callbacks);
- /* collect the mode for each type */
- modes = alloca(n * sizeof(modes[0]));
-
for (i = 0; i < n; i++) {
- tp = get_method_param_type(method_type, i);
- modes[i] = get_type_mode(tp);
- }
-
- /* set register parameters */
- if (cc & cc_reg_param) {
- /* determine the number of parameters passed via registers */
- biggest_n = ia32_get_n_regparam_class(isa->cg, n, modes);
+ ir_mode *mode;
+ const arch_register_t *reg;
- /* loop over all parameters and set the register requirements */
- for (i = 0; i <= biggest_n; i++) {
- ir_mode *mode = modes[i];
+ tp = get_method_param_type(method_type, i);
+ mode = get_type_mode(tp);
+ reg = ia32_get_RegParam_reg(isa->cg, cc, i, mode);
- reg = ia32_get_RegParam_reg(isa->cg, cc, i, mode);
- assert(reg != NULL);
+ if(reg != NULL) {
be_abi_call_param_reg(abi, i, reg);
+ } else {
+ be_abi_call_param_stack(abi, i, 4, 0, 0);
}
-
- stack_idx = i;
- }
-
-
- /* set stack parameters */
- for (i = stack_idx; i < n; i++) {
- /* parameters on the stack are 32 bit aligned */
- be_abi_call_param_stack(abi, i, 4, 0, 0);
}
-
/* set return registers */
n = get_method_n_ress(method_type);
#include "bearch_ia32_t.h"
#include "../benodesets.h"
-static int maxnum_gpreg_args = 3; /* maximum number of int arguments passed in registers; default 3 */
-static int maxnum_sse_args = 5; /* maximum number of float arguments passed in registers; default 5 */
+#define MAXNUM_GPREG_ARGS 3
+#define MAXNUM_SSE_ARGS 5
/* this is the order of the assigned registers usesd for parameter passing */
return e->value;
}
-/**
- * Check all parameters and determine the maximum number of parameters
- * to pass in gp regs resp. in fp regs.
- */
-int ia32_get_n_regparam_class(ia32_code_gen_t *cg, int n, ir_mode **modes)
-{
- int i;
- int max_fp_regs;
- int n_int = 0;
- int n_float = 0;
-
- if(USE_SSE2(cg)) {
- max_fp_regs = maxnum_sse_args;
- } else {
- max_fp_regs = 0;
- }
-
- for (i = 0; i < n; i++) {
- if (mode_is_int(modes[i]) || mode_is_reference(modes[i])) {
- ++n_int;
- } else if (mode_is_float(modes[i])) {
- ++n_float;
- } else {
- panic("Unknown parameter mode encountered");
- }
-
- if (n_int >= maxnum_gpreg_args || n_float >= max_fp_regs)
- break;
- }
-
- return i;
-}
-
-
/**
* Returns the register for parameter nr.
- *
- * @param n The number of parameters
- * @param modes The list of the parameter modes
- * @param nr The number of the parameter to return the requirements for
- * @param cc The calling convention
- * @return The register
*/
const arch_register_t *ia32_get_RegParam_reg(ia32_code_gen_t *cg, unsigned cc,
- unsigned nr, ir_mode *mode)
+ size_t nr, ir_mode *mode)
{
+ if(! (cc & cc_reg_param))
+ return NULL;
+
if(mode_is_float(mode)) {
if(!USE_SSE2(cg))
return NULL;
- assert(nr < maxnum_sse_args);
+ if(nr >= MAXNUM_SSE_ARGS)
+ return NULL;
+
if(cc & cc_this_call) {
return fpreg_sse_param_reg_this[nr];
}
return fpreg_sse_param_reg_std[nr];
- }
-
- assert(mode_is_int(mode) || mode_is_reference(mode));
+ } else if(mode_is_int(mode) || mode_is_reference(mode)) {
+ if(nr >= MAXNUM_GPREG_ARGS)
+ return NULL;
- if(cc & cc_this_call) {
- assert(nr < maxnum_gpreg_args);
- return gpreg_param_reg_this[nr];
+ if(cc & cc_this_call) {
+ return gpreg_param_reg_this[nr];
+ }
+ return gpreg_param_reg_std[nr];
}
- return gpreg_param_reg_std[nr];
+
+ panic("unknown argument mode");
}
*/
const char *ia32_get_mapped_reg_name(pmap *reg_map, const arch_register_t *reg);
-/**
- * Check all parameters and determine the maximum number of parameters
- * to pass in gp regs resp. in fp regs.
- */
-int ia32_get_n_regparam_class(ia32_code_gen_t *cg, int n, ir_mode **modes);
-
/**
* Returns the register for parameter nr.
*/
const arch_register_t *ia32_get_RegParam_reg(ia32_code_gen_t *cg, unsigned cc,
- unsigned nr, ir_mode *mode);
+ size_t nr, ir_mode *mode);
#endif /* FIRM_BE_IA32_IA32_MAP_REGS_H */