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]

Patch to correct x86 FP extend splits


This should address the issues raised by you and Zack.
It passes bootstrap and make check on x86 FreeBSD 3.1
configured for aout.

ChangeLog:

Tue Apr 13 02:52:35 EDT 1999  John Wehle  (john@feith.com)

	* i386.md (extendsfdf, extendsfxf, extenddfxf): Use
	output_float_extend instead specifying '#' as the template.
	* i386.c (output_float_extend): Define.
	* i386.h (output_float_extend): Declare.

Enjoy!

-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/config/i386/i386.md.ORIGINAL	Tue Apr 13 22:40:39 1999
--- gcc/config/i386/i386.md	Wed Apr 14 02:17:15 1999
***************
*** 2256,2262 ****
     (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))]
    "TARGET_80387 && (GET_CODE (operands[0]) != MEM
  		    || GET_CODE (operands[1]) != MEM)"
!   "#")
  
  (define_split
    [(set (match_operand:DF 0 "register_operand" "")
--- 2256,2267 ----
     (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))]
    "TARGET_80387 && (GET_CODE (operands[0]) != MEM
  		    || GET_CODE (operands[1]) != MEM)"
!   "*
! {
!   output_float_extend (insn, operands);
!   return \"\";
! }"
!   [(set_attr "type" "fld,fpop,fld,fpop")])
  
  (define_split
    [(set (match_operand:DF 0 "register_operand" "")
***************
*** 2299,2319 ****
  		    || GET_CODE (operands[1]) != MEM)"
    "*
  {
!   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
! 
!   if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1]))
!     abort ();
! 
!   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
      return \"\";
- 
-   if (STACK_TOP_P (operands[0]))
-     return AS1 (fld%z1,%y1);
- 
-   if (stack_top_dies)
-     return AS1 (fstp%z0,%y0);
-   else
-     return AS1 (fst%z0,%y0);
  }"
    [(set_attr "type" "fld,fpop")])
  
--- 2304,2311 ----
  		    || GET_CODE (operands[1]) != MEM)"
    "*
  {
!     output_float_extend (insn, operands);
      return \"\";
  }"
    [(set_attr "type" "fld,fpop")])
  
***************
*** 2341,2347 ****
     (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
    "TARGET_80387 && (GET_CODE (operands[0]) != MEM
  		    || GET_CODE (operands[1]) != MEM)"
!   "#")
  
  (define_split
    [(set (match_operand:XF 0 "register_operand" "")
--- 2333,2344 ----
     (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
    "TARGET_80387 && (GET_CODE (operands[0]) != MEM
  		    || GET_CODE (operands[1]) != MEM)"
!   "*
! {
!     output_float_extend (insn, operands);
!     return \"\";
! }"
!   [(set_attr "type" "fld,fpop,fld,fpop")])
  
  (define_split
    [(set (match_operand:XF 0 "register_operand" "")
***************
*** 2384,2409 ****
  		    || GET_CODE (operands[1]) != MEM)"
    "*
  {
!   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
! 
!   if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1]))
!     abort ();
! 
!   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
      return \"\";
- 
-   if (STACK_TOP_P (operands[0]))
-     return AS1 (fld%z1,%y1);
- 
-   if (stack_top_dies || GET_CODE (operands[0]) == MEM)
-     output_asm_insn (AS1 (fstp%z0,%y0), operands);
-   else
-     return AS1 (fst%z0,%y0);
- 
-   if (! stack_top_dies)
-     return AS1 (fld%z0,%y0);
- 
-   return \"\";
  }"
    [(set_attr "type" "fld,fpop")])
  
--- 2381,2388 ----
  		    || GET_CODE (operands[1]) != MEM)"
    "*
  {
!     output_float_extend (insn, operands);
      return \"\";
  }"
    [(set_attr "type" "fld,fpop")])
  
***************
*** 2431,2437 ****
     (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
    "TARGET_80387 && (GET_CODE (operands[0]) != MEM
  		    || GET_CODE (operands[1]) != MEM)"
!   "#")
  
  (define_split
    [(set (match_operand:XF 0 "register_operand" "")
--- 2410,2421 ----
     (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
    "TARGET_80387 && (GET_CODE (operands[0]) != MEM
  		    || GET_CODE (operands[1]) != MEM)"
!   "*
! {
!     output_float_extend (insn, operands);
!     return \"\";
! }"
!   [(set_attr "type" "fld,fpop,fld,fpop")])
  
  (define_split
    [(set (match_operand:XF 0 "register_operand" "")
***************
*** 2475,2500 ****
  		    || GET_CODE (operands[1]) != MEM)"
    "*
  {
!   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
! 
!   if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1]))
!     abort ();
! 
!   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
      return \"\";
- 
-   if (STACK_TOP_P (operands[0]))
-     return AS1 (fld%z1,%y1);
- 
-   if (stack_top_dies || GET_CODE (operands[0]) == MEM)
-     output_asm_insn (AS1 (fstp%z0,%y0), operands);
-   else
-     return AS1 (fst%z0,%y0);
- 
-   if (! stack_top_dies)
-     return AS1 (fld%z0,%y0);
- 
-   return \"\";
  }"
    [(set_attr "type" "fld,fpop")])
  
--- 2459,2466 ----
  		    || GET_CODE (operands[1]) != MEM)"
    "*
  {
!     output_float_extend (insn, operands);
      return \"\";
  }"
    [(set_attr "type" "fld,fpop")])
  
*** gcc/config/i386/i386.c.ORIGINAL	Tue Apr 13 22:40:03 1999
--- gcc/config/i386/i386.c	Wed Apr 14 03:03:41 1999
*************** output_fix_trunc (insn, operands)
*** 4179,4184 ****
--- 4179,4244 ----
    return AS1 (fldc%W2,%2);
  }
  
+ /* Output code for INSN to extend a float.  OPERANDS are the insn
+    operands.  The output may be DFmode or XFmode and the input operand
+    may be SFmode or DFmode.  Operands 2 and 3 are scratch memory and
+    are only necessary if operands 0 or 1 are non-stack registers.  */
+ 
+ void
+ output_float_extend (insn, operands)
+      rtx insn;
+      rtx *operands;
+ {
+   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+   rtx xops[2];
+ 
+   if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1]))
+     abort ();
+ 
+   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]) && stack_top_dies)
+     return;
+ 
+   if (STACK_TOP_P (operands[0]) )
+     {
+       if (NON_STACK_REG_P (operands[1]))
+ 	{
+ 	  if (GET_MODE (operands[1]) == SFmode)
+ 	    output_asm_insn (AS2 (mov%L0,%1,%2), operands);
+ 	  else
+ 	    {
+ 	      xops[0] = operands[2];
+ 	      xops[1] = operands[1];
+ 	      output_asm_insn (output_move_double (xops), xops);
+ 	    }
+ 	}
+ 
+       xops[0] = NON_STACK_REG_P (operands[1]) ? operands[2] : operands[1];
+ 
+       output_asm_insn (AS1 (fld%z0,%y0), xops);
+     }
+   else
+     {
+       xops[0] = NON_STACK_REG_P (operands[0]) ? operands[3] : operands[0];
+ 
+       if (stack_top_dies
+ 	  || (GET_CODE (xops[0]) == MEM && GET_MODE (xops[0]) == XFmode))
+ 	{
+ 	  output_asm_insn (AS1 (fstp%z0,%y0), xops);
+ 	  if (! stack_top_dies)
+ 	    output_asm_insn (AS1 (fld%z0,%y0), xops);
+ 	}
+       else
+ 	output_asm_insn (AS1 (fst%z0,%y0), xops);
+ 
+       if (NON_STACK_REG_P (operands[0]))
+ 	{
+ 	  xops[0] = operands[0];
+ 	  xops[1] = operands[3];
+ 	  output_asm_insn (output_move_double (xops), xops);
+ 	}
+     }
+ }
+ 
  /* Output code for INSN to compare OPERANDS.  The two operands might
     not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
     expression.  If the compare is in mode CCFPEQmode, use an opcode that
*** gcc/config/i386/i386.h.ORIGINAL	Tue Apr 13 22:40:09 1999
--- gcc/config/i386/i386.h	Wed Apr 14 01:59:35 1999
*************** extern int shift_op ();
*** 2743,2748 ****
--- 2743,2749 ----
  extern int VOIDmode_compare_op ();
  extern char *output_387_binary_op ();
  extern char *output_fix_trunc ();
+ extern void output_float_extend ();
  extern char *output_float_compare ();
  extern char *output_fp_cc0_set ();
  extern void save_386_machine_status ();
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------



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