sparc: panic instead of segfault for struct parameters
[libfirm] / ir / be / sparc / sparc_cconv.c
index af2c09c..d1b38f6 100644 (file)
@@ -60,6 +60,7 @@ static const arch_register_t* const param_regs[] = {
        &sparc_registers[REG_I4],
        &sparc_registers[REG_I5],
 };
+COMPILETIME_ASSERT(ARRAY_SIZE(param_regs) == SPARC_N_PARAM_REGS, sparcparamregs)
 
 static const arch_register_t* const float_result_regs[] = {
        &sparc_registers[REG_F0],
@@ -198,9 +199,26 @@ calling_convention_t *sparc_decide_calling_convention(ir_type *function_type,
 
        for (i = 0; i < n_params; ++i) {
                ir_type            *param_type = get_method_param_type(function_type,i);
-               ir_mode            *mode       = get_type_mode(param_type);
-               int                 bits       = get_mode_size_bits(mode);
-               reg_or_stackslot_t *param      = &params[i];
+               ir_mode            *mode;
+               int                 bits;
+               reg_or_stackslot_t *param;
+
+               if (is_compound_type(param_type))
+                       panic("sparc: compound arguments not supported yet");
+
+               mode  = get_type_mode(param_type);
+               bits  = get_mode_size_bits(mode);
+               param = &params[i];
+
+               if (i == 0 &&
+                   (get_method_calling_convention(function_type) & cc_compound_ret)) {
+                       assert(mode_is_reference(mode) && bits == 32);
+                       /* special case, we have reserved space for this on the between
+                        * type */
+                       param->type   = param_type;
+                       param->offset = -SPARC_MIN_STACKSIZE+SPARC_AGGREGATE_RETURN_OFFSET;
+                       continue;
+               }
 
                if (regnum < n_param_regs) {
                        const arch_register_t *reg = param_regs[regnum];
@@ -314,7 +332,6 @@ calling_convention_t *sparc_decide_calling_convention(ir_type *function_type,
                struct obstack *obst      = &birg->obst;
                size_t          r;
 
-               assert(birg->allocatable_regs == NULL);
                birg->allocatable_regs = rbitset_obstack_alloc(obst, N_SPARC_REGISTERS);
                rbitset_set_all(birg->allocatable_regs, N_SPARC_REGISTERS);
                for (r = 0; r < n_ignores; ++r) {