This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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));
  	}
      }
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]