sparc: va_arg functions may not use omit-fp
[libfirm] / ir / be / sparc / sparc_cconv.c
index d7a1629..d0129ae 100644 (file)
@@ -196,7 +196,13 @@ calling_convention_t *sparc_decide_calling_convention(ir_type *function_type,
        if (irg != NULL) {
                const be_options_t *options = be_get_irg_options(irg);
                omit_fp = options->omit_fp;
-               irg_walk_graph(irg, check_omit_fp, NULL, &omit_fp);
+               /* our current vaarg handling needs the standard space to store the
+                * args 0-5 in it */
+               if (get_method_variadicity(function_type) == variadicity_variadic)
+                       omit_fp = false;
+               if (omit_fp == true) {
+                       irg_walk_graph(irg, check_omit_fp, NULL, &omit_fp);
+               }
        }
 
        caller_saves = rbitset_malloc(N_SPARC_REGISTERS);
@@ -246,8 +252,8 @@ calling_convention_t *sparc_decide_calling_convention(ir_type *function_type,
                } else {
                        param->type   = param_type;
                        param->offset = stack_offset;
-                       /* increase offset 4 bytes so everything is aligned */
-                       stack_offset += bits > 32 ? bits/8 : 4;
+                       /* increase offset by at least SPARC_REGISTER_SIZE bytes so everything is aligned */
+                       stack_offset += bits > 8 * SPARC_REGISTER_SIZE ? bits / 8 : SPARC_REGISTER_SIZE;
                        continue;
                }
 
@@ -269,7 +275,7 @@ calling_convention_t *sparc_decide_calling_convention(ir_type *function_type,
                                param->type      = type;
                                param->offset    = stack_offset;
                                assert(get_mode_size_bits(regmode) == 32);
-                               stack_offset += 4;
+                               stack_offset += SPARC_REGISTER_SIZE;
                        }
                }
        }