This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix amd64 xfmode splits
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 7 May 2003 17:52:21 -0700
- Subject: fix amd64 xfmode splits
Test case for this is FreeBSD vfprintf.c (i.e. a tad big) and
I wasn't able to reduce the test. The cause is evident though:
the second part of a 12-byte quantity is SImode, not DImode,
and so is invalid as a base address.
I've asked the reporter to file a proper bug report so that
this gets applied to the 3.3 branch once it opens again.
r~
* config/i386/i386.c (ix86_split_long_move): Fix base register
mode for XFmode splits for TARGET_64BIT.
Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.562
diff -c -p -d -r1.562 i386.c
*** i386.c 27 Apr 2003 02:15:25 -0000 1.562
--- i386.c 8 May 2003 00:46:30 -0000
*************** ix86_split_long_move (operands)
*** 10593,10607 ****
Do an lea to the last part and use only one colliding move. */
else if (collisions > 1)
{
collisions = 1;
! emit_insn (gen_rtx_SET (VOIDmode, part[0][nparts - 1],
! XEXP (part[1][0], 0)));
! part[1][0] = change_address (part[1][0],
! TARGET_64BIT ? DImode : SImode,
! part[0][nparts - 1]);
! part[1][1] = adjust_address (part[1][0], VOIDmode, UNITS_PER_WORD);
if (nparts == 3)
! part[1][2] = adjust_address (part[1][0], VOIDmode, 8);
}
}
--- 10593,10616 ----
Do an lea to the last part and use only one colliding move. */
else if (collisions > 1)
{
+ rtx base;
+
collisions = 1;
!
! base = part[0][nparts - 1];
!
! /* Handle the case when the last part isn't valid for lea.
! Happens in 64-bit mode storing the 12-byte XFmode. */
! if (GET_MODE (base) != Pmode)
! base = gen_rtx_REG (Pmode, REGNO (base));
!
! emit_insn (gen_rtx_SET (VOIDmode, base, XEXP (part[1][0], 0)));
! part[1][0] = replace_equiv_address (part[1][0], base);
! part[1][1] = replace_equiv_address (part[1][1],
! plus_constant (base, UNITS_PER_WORD));
if (nparts == 3)
! part[1][2] = replace_equiv_address (part[1][2],
! plus_constant (base, 8));
}
}