This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] S/390: 64 bit register support for 32 bit apps - sibcall fix
- From: "Andreas Krebbel" <krebbel at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 15 Apr 2010 18:31:22 +0200
- Subject: [Committed] S/390: 64 bit register support for 32 bit apps - sibcall fix
Hi,
there is a thinko in the "64 bit register for 32 bit apps" patch.
Since the s390_call_saved_register_used function deals with function
arguments I thought it is illegal to use HARD_REGNO_NREGS here.
HARD_REGNO_NREGS uses UNITS_PER_WORD to calculate the number of
registers and that to my thinking was wrong for a function argument
since this is ABI relevant. UNITS_PER_WORD is 8 for -m31 -mzarch but
for function arguments only 32 bit registers can be used to stay with
the 32 bit ABI. So I've mimiced the HARD_REGNO_NREGS calculation
using UNITS_PER_LONG without taking into account that
s390_function_arg already takes care of that. It would never generate
a (reg:DI x) for -m31 -mzarch. Instead it generates a PARALLEL
containing 2 SI mode registers. So using HARD_REGNO_NREGS is
perfectly fine here.
Committed to mainline.
Bye,
-Andreas-
2010-04-15 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* config/s390/s390.c (s390_call_save_register_used): Switch back
to HARD_REGNO_NREGS.
Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig
--- gcc/config/s390/s390.c
*************** s390_call_saved_register_used (tree call
*** 9449,9465 ****
if (REG_P (parm_rtx))
{
! int n_regs;
!
! /* Only integer registers (r6) are call saved and used for
! parameter passing. */
! if (REGNO_REG_CLASS (REGNO (parm_rtx)) == FP_REGS)
! continue;
!
! n_regs = ((GET_MODE_SIZE (GET_MODE (parm_rtx)) + UNITS_PER_LONG - 1)
! / UNITS_PER_LONG);
!
! for (reg = 0; reg < n_regs; reg++)
if (!call_used_regs[reg + REGNO (parm_rtx)])
return true;
}
--- 9449,9457 ----
if (REG_P (parm_rtx))
{
! for (reg = 0;
! reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
! reg++)
if (!call_used_regs[reg + REGNO (parm_rtx)])
return true;
}
*************** s390_call_saved_register_used (tree call
*** 9467,9488 ****
if (GET_CODE (parm_rtx) == PARALLEL)
{
int i;
for (i = 0; i < XVECLEN (parm_rtx, 0); i++)
{
rtx r = XEXP (XVECEXP (parm_rtx, 0, i), 0);
- int n_regs;
gcc_assert (REG_P (r));
! /* Only integer registers (r6) are call saved and used
! for parameter passing. */
! if (REGNO_REG_CLASS (REGNO (r)) == FP_REGS)
! continue;
!
! n_regs = ((GET_MODE_SIZE (GET_MODE (r)) + UNITS_PER_LONG - 1)
! / UNITS_PER_LONG);
!
! for (reg = 0; reg < n_regs; reg++)
if (!call_used_regs[reg + REGNO (r)])
return true;
}
--- 9459,9474 ----
if (GET_CODE (parm_rtx) == PARALLEL)
{
int i;
+
for (i = 0; i < XVECLEN (parm_rtx, 0); i++)
{
rtx r = XEXP (XVECEXP (parm_rtx, 0, i), 0);
gcc_assert (REG_P (r));
! for (reg = 0;
! reg < HARD_REGNO_NREGS (REGNO (r), GET_MODE (r));
! reg++)
if (!call_used_regs[reg + REGNO (r)])
return true;
}