aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1994-10-20 13:14:46 -0700
committerJim Wilson <wilson@gcc.gnu.org>1994-10-20 13:14:46 -0700
commitc25d3f2094341937f95677be38ef0df06666cd06 (patch)
tree174a5d25762bab679ed9c67bfd8604a82e4057a9
parent0f1d97b8f6692d3e798f9f52759c7e8a3fe40c01 (diff)
downloadgcc-c25d3f2094341937f95677be38ef0df06666cd06.zip
gcc-c25d3f2094341937f95677be38ef0df06666cd06.tar.gz
gcc-c25d3f2094341937f95677be38ef0df06666cd06.tar.bz2
(VARARGS_STDARG_FUNCTION): New macro.
(i960_function_name_declare, output_function_profiler, i960_function_epilogue, i960_output_call_insn, i960_output_ret_insn, i960_reg_parm_stack_space): Use it. (compute_frame_size): Don't use current_function_pretend_args_size. (i960_function_arg_advance, i960_function_arg): Don't use parameter named. (i960_setup_incoming_varargs): No need to adjust first_reg_offset after setting it. Don't save last named argument to stack. Don't set pretend_size. From-SVN: r8322
-rw-r--r--gcc/config/i960/i960.c70
1 files changed, 45 insertions, 25 deletions
diff --git a/gcc/config/i960/i960.c b/gcc/config/i960/i960.c
index fb24855..a0ac218 100644
--- a/gcc/config/i960/i960.c
+++ b/gcc/config/i960/i960.c
@@ -75,6 +75,14 @@ char epilogue_string[1000];
static int ret_label = 0;
+/* This is true if FNDECL is either a varargs or a stdarg function.
+ This is used to help identify functions that use an argument block. */
+
+#define VARARGS_STDARG_FUNCTION(FNDECL) \
+((TYPE_ARG_TYPES (TREE_TYPE (FNDECL)) != 0 \
+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (FNDECL)))) != void_type_node)) \
+ || current_function_varargs)
+
#if 0
/* Handle pragmas for compatibility with Intel's compilers. */
@@ -823,7 +831,7 @@ i960_function_name_declare (file, name, fndecl)
/* Even if nobody uses extra parms, can't have leafroc or tail calls if
argblock, because argblock uses g14 implicitly. */
- if (current_function_args_size != 0)
+ if (current_function_args_size != 0 || VARARGS_STDARG_FUNCTION (fndecl))
{
tail_call_ok = 0;
leaf_proc_ok = 0;
@@ -960,8 +968,7 @@ compute_frame_size (size)
int size;
{
int actual_fsize;
- int outgoing_args_size
- = current_function_outgoing_args_size + current_function_pretend_args_size;
+ int outgoing_args_size = current_function_outgoing_args_size;
/* The STARTING_FRAME_OFFSET is totally hidden to us as far
as size is concerned. */
@@ -1158,6 +1165,8 @@ output_function_profiler (file, labelno)
/* The last used parameter register. */
int last_parm_reg;
int i, j, increment;
+ int varargs_stdarg_function
+ = VARARGS_STDARG_FUNCTION (current_function_decl);
/* Figure out the last used parameter register. The proper thing to do
is to walk incoming args of the function. A function might have live
@@ -1194,7 +1203,7 @@ output_function_profiler (file, labelno)
/* If this function uses the arg pointer, then save it in r3 and then
set it to zero. */
- if (current_function_args_size != 0)
+ if (current_function_args_size != 0 || varargs_stdarg_function)
fprintf (file, "\tmov g14,r3\n\tmov 0,g14\n");
/* Load location address into g0 and call mcount. */
@@ -1203,7 +1212,7 @@ output_function_profiler (file, labelno)
/* If this function uses the arg pointer, restore it. */
- if (current_function_args_size != 0)
+ if (current_function_args_size != 0 || varargs_stdarg_function)
fprintf (file, "\tmov r3,g14\n");
/* Restore parameter registers. */
@@ -1280,7 +1289,8 @@ i960_function_epilogue (file, size)
/* Must clear g14 on return. */
- if (current_function_args_size != 0)
+ if (current_function_args_size != 0
+ || VARARGS_STDARG_FUNCTION (current_function_decl))
fprintf (file, "\tmov 0,g14\n");
fprintf (file, "\tret\n");
@@ -1296,16 +1306,18 @@ i960_output_call_insn (target, argsize_rtx, arg_pointer, insn)
int argsize = INTVAL (argsize_rtx);
rtx nexti = next_real_insn (insn);
rtx operands[2];
+ int varargs_stdarg_function
+ = VARARGS_STDARG_FUNCTION (current_function_decl);
operands[0] = target;
operands[1] = arg_pointer;
- if (current_function_args_size != 0)
+ if (current_function_args_size != 0 || varargs_stdarg_function)
output_asm_insn ("mov g14,r3", operands);
if (argsize > 48)
output_asm_insn ("lda %a1,g14", operands);
- else if (current_function_args_size != 0)
+ else if (current_function_args_size != 0 || varargs_stdarg_function)
output_asm_insn ("mov 0,g14", operands);
/* The code used to assume that calls to SYMBOL_REFs could not be more
@@ -1326,7 +1338,7 @@ i960_output_call_insn (target, argsize_rtx, arg_pointer, insn)
output_asm_insn ("callx %0", operands);
- if (current_function_args_size != 0)
+ if (current_function_args_size != 0 || varargs_stdarg_function)
output_asm_insn ("mov r3,g14", operands);
return "";
@@ -1349,7 +1361,8 @@ i960_output_ret_insn (insn)
return lbuf;
}
- if (current_function_args_size != 0)
+ if (current_function_args_size != 0
+ || VARARGS_STDARG_FUNCTION (current_function_decl))
output_asm_insn ("mov 0,g14", 0);
if (i960_leaf_ret_reg >= 0)
@@ -2045,7 +2058,7 @@ i960_function_arg_advance (cum, mode, type, named)
i960_arg_size_and_align (mode, type, &size, &align);
- if (named == 0 || size > 4 || cum->ca_nstackparms != 0
+ if (size > 4 || cum->ca_nstackparms != 0
|| (size + ROUND_PARM (cum->ca_nregparms, align)) > NPARM_REGS
|| MUST_PASS_IN_STACK (mode, type))
cum->ca_nstackparms = ROUND_PARM (cum->ca_nstackparms, align) + size;
@@ -2068,7 +2081,7 @@ i960_function_arg (cum, mode, type, named)
i960_arg_size_and_align (mode, type, &size, &align);
- if (named == 0 || size > 4 || cum->ca_nstackparms != 0
+ if (size > 4 || cum->ca_nstackparms != 0
|| (size + ROUND_PARM (cum->ca_nregparms, align)) > NPARM_REGS
|| MUST_PASS_IN_STACK (mode, type))
{
@@ -2184,14 +2197,17 @@ i960_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
{
int first_reg_offset = cum->ca_nregparms;
- if (first_reg_offset > NPARM_REGS)
- first_reg_offset = NPARM_REGS;
-
- if (! (no_rtl) && first_reg_offset != NPARM_REGS)
+ if (! (no_rtl))
{
rtx label = gen_label_rtx ();
rtx regblock;
+ /* If arg_pointer_rtx == 0, no arguments were passed on the stack
+ and we need to allocate a chunk to save the registers (if any
+ arguments were passed on the stack the caller would allocate the
+ 48 bytes as well). We must allocate all 48 bytes (12*4) because
+ arg_pointer_rtx is saved at the front, the anonymous args are
+ saved at the end. */
emit_insn (gen_cmpsi (arg_pointer_rtx, const0_rtx));
emit_jump_insn (gen_bne (label));
emit_insn (gen_rtx (SET, VOIDmode, arg_pointer_rtx,
@@ -2202,15 +2218,19 @@ i960_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
48))));
emit_label (label);
- regblock = gen_rtx (MEM, BLKmode,
- plus_constant (arg_pointer_rtx,
- first_reg_offset * 4));
- move_block_from_reg (first_reg_offset, regblock,
- NPARM_REGS - first_reg_offset,
- ((NPARM_REGS - first_reg_offset)
- * UNITS_PER_WORD));
+ /* Any anonymous args passed in regs? */
+ if (first_reg_offset + 1 < NPARM_REGS)
+ {
+ rtx regblock;
+ regblock = gen_rtx (MEM, BLKmode,
+ plus_constant (arg_pointer_rtx,
+ (first_reg_offset + 1) * 4));
+ move_block_from_reg (first_reg_offset + 1, regblock,
+ NPARM_REGS - first_reg_offset - 1,
+ ((NPARM_REGS - first_reg_offset - 1)
+ * UNITS_PER_WORD));
+ }
}
- *pretend_size = (NPARM_REGS - first_reg_offset) * UNITS_PER_WORD;
}
}
@@ -2247,7 +2267,7 @@ i960_reg_parm_stack_space (fndecl)
/* Otherwise, we have an arg block if the current function has more than
48 bytes of parameters. */
- if (current_function_args_size != 0)
+ if (current_function_args_size != 0 || VARARGS_STDARG_FUNCTION (fndecl))
return 48;
else
return 0;