IA-64 patch to fix ICE with long double after float HFA

James E Wilson wilson@specifixinc.com
Tue Jan 18 04:00:00 GMT 2005


This fixes PR target/19357.  The float HFA argument fills the FP
registers, and then the long double argument gets passed in int
registers.  This then requires the need to perform an XFmode store from
the int registers, but this support was missing from the movxf pattern. 
This patch adds it.

This was tested with an ia64-linux bootstrap and make check.  The new
testcase passes with the patch at all optimization levels, and fails at
all optimization levels without the patch.  The RTL dumps and assembler
output for the testcase was checked by hand to make sure it was
reasonable.

I have checked in these patches.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

-------------- next part --------------
2005-01-17  James E Wilson  <wilson@specifixinc.com>

	PR target/19357
	* config/ia64/ia64.md (movxf): Handle general register source.  Adjust
	comment to document why.

Index: ia64.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.md,v
retrieving revision 1.140
diff -p -p -r1.140 ia64.md
*** ia64.md	3 Jan 2005 19:59:11 -0000	1.140
--- ia64.md	14 Jan 2005 21:51:39 -0000
***************
*** 685,694 ****
    if (GET_CODE (op0) == SUBREG)
      op0 = SUBREG_REG (op0);
  
!   /* We must support XFmode loads into general registers for stdarg/vararg
!      and unprototyped calls.  We split them into DImode loads for convenience.
!      We don't need XFmode stores from general regs, because a stdarg/vararg
!      routine does a block store to memory of unnamed arguments.  */
  
    if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0)))
      {
--- 685,696 ----
    if (GET_CODE (op0) == SUBREG)
      op0 = SUBREG_REG (op0);
  
!   /* We must support XFmode loads into general registers for stdarg/vararg,
!      unprototyped calls, and a rare case where a long double is passed as
!      an argument after a float HFA fills the FP registers.  We split them into
!      DImode loads for convenience.  We also need to support XFmode stores
!      for the last case.  This case does not happen for stdarg/vararg routines,
!      because we do a block store to memory of unnamed arguments.  */
  
    if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0)))
      {
***************
*** 708,714 ****
  	  if (GET_CODE (op1) == SUBREG)
  	    op1 = SUBREG_REG (op1);
  	  else
- 	    /* ??? Maybe we should make a SUBREG here?  */
  	    op1 = gen_rtx_REG (TImode, REGNO (op1));
  
  	  emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1);
--- 710,715 ----
***************
*** 743,748 ****
--- 744,783 ----
        abort ();
      }
  
+   if (GET_CODE (operands[1]) == REG && GR_REGNO_P (REGNO (operands[1])))
+     {
+       /* We're hoping to transform everything that deals with XFmode
+ 	 quantities and GR registers early in the compiler.  */
+       if (no_new_pseudos)
+ 	abort ();
+ 
+       /* Op0 can't be a GR_REG here, as that case is handled above.
+ 	 If op0 is a register, then we spill op1, so that we now have a
+ 	 MEM operand.  This requires creating an XFmode subreg of a TImode reg
+ 	 to force the spill.  */
+       if (register_operand (operands[0], XFmode))
+ 	{
+ 	  rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
+ 	  op1 = gen_rtx_SUBREG (XFmode, op1, 0);
+ 	  operands[1] = spill_xfmode_operand (op1, 0);
+ 	}
+ 
+       else if (GET_CODE (operands[0]) == MEM)
+ 	{
+ 	  rtx in[2];
+ 
+ 	  in[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[1]));
+ 	  in[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
+ 
+ 	  emit_move_insn (adjust_address (operands[0], DImode, 0), in[0]);
+ 	  emit_move_insn (adjust_address (operands[0], DImode, 8), in[1]);
+ 	  DONE;
+ 	}
+ 
+       else
+ 	abort ();
+     }
+ 
    if (! reload_in_progress && ! reload_completed)
      {
        operands[1] = spill_xfmode_operand (operands[1], 0);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr19357.c
Type: text/x-c
Size: 664 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20050118/47847277/attachment.bin>


More information about the Gcc-patches mailing list