share common phi code, fix missing phi input reqs
[libfirm] / ir / be / arm / arm_cconv.c
index 88e6638..8ca715c 100644 (file)
@@ -21,7 +21,6 @@
  * @file
  * @brief   calling convention helpers
  * @author  Matthias Braun
- * @version $Id$
  */
 #include "config.h"
 
@@ -39,23 +38,40 @@ static const unsigned ignore_regs[] = {
        REG_FL,
 };
 
-calling_convention_t *arm_decide_calling_convention(ir_graph *irg,
+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 */
@@ -83,21 +99,22 @@ calling_convention_t *arm_decide_calling_convention(ir_graph *irg,
                /* 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;
@@ -110,18 +127,18 @@ calling_convention_t *arm_decide_calling_convention(ir_graph *irg,
 
                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;
@@ -132,6 +149,7 @@ calling_convention_t *arm_decide_calling_convention(ir_graph *irg,
        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 */