This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Another 20020412-1.c mips fix
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 06 Oct 2003 08:50:49 +0100
- Subject: Another 20020412-1.c mips fix
Although this:
http://gcc.gnu.org/ml/gcc-patches/2003-09/msg01696.html
was enough to fix 20020412-1.c for n32 & n64, there's a further
problem for o32 & o64. main() passes the first part of x[] in
the register save area, which foo() then clobbers when saving
the argument registers.
An obvious fix is to make FUNCTION_ARG{,_ADVANCE} skip all registers
if they see a MUST_PASS_IN_STACK argument. This is an ABI change for
o32 & o64, so I don't think it's "obviously correct", just obvious.
OTOH, I doubt things could really work properly the way they were.
This also fixes the case where a constant-sized argument
is passed after a variable-sized one for n32 & n64.
Tested on mips-sgi-irix6.5, mips64-linux-gnu, mipsisa64-elf,
mips64{,el}-elf and mips64vrel-elf. OK to install?
Richard
* config/mips/mips.c (mips_arg_info): If MUST_PASS_IN_STACK,
skip any remaining register arguments.
diff -cpdr config/mips.fix/mips.c config/mips/mips.c
*** config/mips.fix/mips.c Sat Oct 4 13:00:07 2003
--- config/mips/mips.c Sat Oct 4 14:04:39 2003
*************** mips_arg_info (const CUMULATIVE_ARGS *cu
*** 3661,3675 ****
even_reg_p = true;
}
! /* Set REG_OFFSET to the register count we're interested in.
! The EABI allocates the floating-point registers separately,
! but the other ABIs allocate them like integer registers. */
! info->reg_offset = (mips_abi == ABI_EABI && info->fpr_p
! ? cum->num_fprs
! : cum->num_gprs);
! if (even_reg_p)
! info->reg_offset += info->reg_offset & 1;
/* The alignment applied to registers is also applied to stack arguments. */
info->stack_offset = cum->stack_words;
--- 3661,3682 ----
even_reg_p = true;
}
! if (mips_abi != ABI_EABI && MUST_PASS_IN_STACK (mode, type))
! /* This argument must be passed on the stack. Eat up all the
! remaining registers. */
! info->reg_offset = MAX_ARGS_IN_REGISTERS;
! else
! {
! /* Set REG_OFFSET to the register count we're interested in.
! The EABI allocates the floating-point registers separately,
! but the other ABIs allocate them like integer registers. */
! info->reg_offset = (mips_abi == ABI_EABI && info->fpr_p
! ? cum->num_fprs
! : cum->num_gprs);
! if (even_reg_p)
! info->reg_offset += info->reg_offset & 1;
! }
/* The alignment applied to registers is also applied to stack arguments. */
info->stack_offset = cum->stack_words;