* @file
* @brief calling convention helpers
* @author Matthias Braun
- * @version $Id$
*/
#include "config.h"
#include "arm_cconv.h"
+#include "beirg.h"
#include "irmode.h"
#include "typerep.h"
#include "xmalloc.h"
REG_FL,
};
-/* determine how function parameters and return values are passed. */
+static const arch_register_t* const param_regs[] = {
+ &arm_registers[REG_R0],
+ &arm_registers[REG_R1],
+ &arm_registers[REG_R2],
+ &arm_registers[REG_R3]
+};
+
+static const arch_register_t* const result_regs[] = {
+ &arm_registers[REG_R0],
+ &arm_registers[REG_R1],
+ &arm_registers[REG_R2],
+ &arm_registers[REG_R3]
+};
+
+static const arch_register_t* const float_result_regs[] = {
+ &arm_registers[REG_F0],
+ &arm_registers[REG_F1]
+};
+
calling_convention_t *arm_decide_calling_convention(const ir_graph *irg,
ir_type *function_type)
{
- int stack_offset = 0;
+ unsigned stack_offset = 0;
+ unsigned n_param_regs_used = 0;
reg_or_stackslot_t *params;
reg_or_stackslot_t *results;
- int n_param_regs
- = sizeof(param_regs)/sizeof(param_regs[0]);
- int n_result_regs
- = sizeof(result_regs)/sizeof(result_regs[0]);
- int n_float_result_regs
- = sizeof(float_result_regs)/sizeof(float_result_regs[0]);
- int n_params;
- int n_results;
- int i;
- int regnum;
- int float_regnum;
+ size_t const n_param_regs = ARRAY_SIZE(param_regs);
+ size_t const n_result_regs = ARRAY_SIZE(result_regs);
+ size_t const n_float_result_regs = ARRAY_SIZE(float_result_regs);
+ size_t n_params;
+ size_t n_results;
+ size_t i;
+ size_t regnum;
+ size_t float_regnum;
calling_convention_t *cconv;
/* determine how parameters are passed */
/* we might need a 2nd 32bit component (for 64bit or double values) */
if (bits > 32) {
if (bits > 64)
- panic("only 32 and 64bit modes supported in arm backend");
+ panic("only 32 and 64bit modes supported");
if (regnum < n_param_regs) {
const arch_register_t *reg = param_regs[regnum++];
param->reg1 = reg;
} else {
- ir_mode *mode = param_regs[0]->reg_class->mode;
- ir_type *type = get_type_for_mode(mode);
- param->type = type;
- param->offset = stack_offset;
- assert(get_mode_size_bits(mode) == 32);
+ ir_mode *pmode = param_regs[0]->reg_class->mode;
+ ir_type *type = get_type_for_mode(pmode);
+ param->type = type;
+ param->offset = stack_offset;
+ assert(get_mode_size_bits(pmode) == 32);
stack_offset += 4;
}
}
}
+ n_param_regs_used = regnum;
n_results = get_method_n_ress(function_type);
regnum = 0;
if (mode_is_float(result_mode)) {
if (float_regnum >= n_float_result_regs) {
- panic("Too many float results for arm backend");
+ panic("Too many float results");
} else {
const arch_register_t *reg = float_result_regs[float_regnum++];
result->reg0 = reg;
}
} else {
if (get_mode_size_bits(result_mode) > 32) {
- panic("Results with more than 32bits not supported by arm backend yet");
+ panic("Results with more than 32bits not supported yet");
}
if (regnum >= n_result_regs) {
- panic("Too many results for arm backend");
+ panic("Too many results");
} else {
const arch_register_t *reg = result_regs[regnum++];
result->reg0 = reg;
cconv = XMALLOCZ(calling_convention_t);
cconv->parameters = params;
cconv->param_stack_size = stack_offset;
+ cconv->n_reg_params = n_param_regs_used;
cconv->results = results;
/* setup allocatable registers */