Patch for i386.md to fix SF / DF / XF move inconsistencies.

John Wehle john@feith.com
Sun Apr 5 13:08:00 GMT 1998


[ This patch has been updated for egcs-980328 and replaces the ones
  sent in January. ]

This patch changes the SF / DF / XF move patterns so that they work
in a fashion similar to the integer patterns.  These changes seem
to be worth about 3-5% speed increase on the BRL-CAD ray tracing
benchmark.

ChangeLog:

Sun Apr  5 15:55:34 EDT 1998  John Wehle  (john@feith.com)

	* i386.md (movsf_push, movsf_mem): Remove.
	(movsf_push): Rename from movsf_push_nomove and move in front of
	movsf.  Use nonmemory_operand predicate and don't bother checking
	TARGET_MOVE.
	(movsf_push_memory): New pattern.
	(movsf): Don't bother checking for push_operand.  If TARGET_MOVE and
	both operands refer to memory then force operand[1] into a register.
	(movsf_normal): Change to unnamed pattern.
	Likewise for movdf, movxf, and friends.

-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/config/i386/i386.md.ORIGINAL	Thu Mar 12 07:43:42 1998
--- gcc/config/i386/i386.md	Sun Apr  5 15:31:58 1998
***************
*** 1179,1209 ****
    return AS2 (mov%B0,%1,%0);
  }")
  
  (define_expand "movsf"
    [(set (match_operand:SF 0 "general_operand" "")
  	(match_operand:SF 1 "general_operand" ""))]
    ""
    "
  {
!   /* Special case memory->memory moves and pushes */
    if (TARGET_MOVE
        && (reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) == MEM
!       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], SFmode)))
      {
!       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode))
! 						? gen_movsf_push
! 						: gen_movsf_mem;
! 
!       emit_insn ((*genfunc) (operands[0], operands[1]));
!       DONE;
      }
  
    /* If we are loading a floating point constant that isn't 0 or 1
       into a register, indicate we need the pic register loaded.  This could
       be optimized into stores of constants if the target eventually moves
       to memory, but better safe than sorry.  */
!   if ((reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) != MEM
        && GET_CODE (operands[1]) == CONST_DOUBLE
        && !standard_80387_constant_p (operands[1]))
--- 1179,1239 ----
    return AS2 (mov%B0,%1,%0);
  }")
  
+ (define_insn "movsf_push"
+   [(set (match_operand:SF 0 "push_operand" "=<,<")
+ 	(match_operand:SF 1 "nonmemory_operand" "rF,f"))]
+   ""
+   "*
+ {
+   if (STACK_REG_P (operands[1]))
+     {
+       rtx xops[3];
+ 
+       if (! STACK_TOP_P (operands[1]))
+         abort ();
+ 
+       xops[0] = AT_SP (SFmode);
+       xops[1] = GEN_INT (4);
+       xops[2] = stack_pointer_rtx;
+ 
+       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
+ 
+       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+         output_asm_insn (AS1 (fstp%S0,%0), xops);
+       else
+         output_asm_insn (AS1 (fst%S0,%0), xops);
+ 
+       RET;
+     }
+   return AS1 (push%L0,%1);
+ }")
+ 
+ (define_insn "movsf_push_memory"
+   [(set (match_operand:SF 0 "push_operand" "=<")
+ 	(match_operand:SF 1 "memory_operand" "m"))]
+   "TARGET_PUSH_MEMORY"
+   "* return AS1 (push%L0,%1);")
+ 
  (define_expand "movsf"
    [(set (match_operand:SF 0 "general_operand" "")
  	(match_operand:SF 1 "general_operand" ""))]
    ""
    "
  {
!   /* Don't generate memory->memory moves, go through a register */
    if (TARGET_MOVE
        && (reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) == MEM
!       && GET_CODE (operands[1]) == MEM)
      {
!       operands[1] = force_reg (SFmode, operands[1]);
      }
  
    /* If we are loading a floating point constant that isn't 0 or 1
       into a register, indicate we need the pic register loaded.  This could
       be optimized into stores of constants if the target eventually moves
       to memory, but better safe than sorry.  */
!   else if ((reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) != MEM
        && GET_CODE (operands[1]) == CONST_DOUBLE
        && !standard_80387_constant_p (operands[1]))
***************
*** 1224,1309 ****
      }
  }")
  
- (define_insn "movsf_push_nomove"
-   [(set (match_operand:SF 0 "push_operand" "=<,<")
- 	(match_operand:SF 1 "general_operand" "gF,f"))]
-   "!TARGET_MOVE"
-   "*
- {
-   if (STACK_REG_P (operands[1]))
-     {
-       rtx xops[3];
- 
-       if (! STACK_TOP_P (operands[1]))
-         abort ();
- 
-       xops[0] = AT_SP (SFmode);
-       xops[1] = GEN_INT (4);
-       xops[2] = stack_pointer_rtx;
- 
-       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
- 
-       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
-         output_asm_insn (AS1 (fstp%S0,%0), xops);
-       else
-         output_asm_insn (AS1 (fst%S0,%0), xops);
-       RET;
-     }
-   return AS1 (push%L1,%1);
- }")
- 
- (define_insn "movsf_push"
-   [(set (match_operand:SF 0 "push_operand" "=<,<,<,<")
- 	(match_operand:SF 1 "general_operand" "rF,f,m,m"))
-    (clobber (match_scratch:SI 2 "=X,X,r,X"))]
-   ""
-   "*
- {
-   if (STACK_REG_P (operands[1]))
-     {
-       rtx xops[3];
- 
-       if (! STACK_TOP_P (operands[1]))
-         abort ();
- 
-       xops[0] = AT_SP (SFmode);
-       xops[1] = GEN_INT (4);
-       xops[2] = stack_pointer_rtx;
- 
-       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
- 
-       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
-         output_asm_insn (AS1 (fstp%S0,%0), xops);
-       else
-         output_asm_insn (AS1 (fst%S0,%0), xops);
-       RET;
-     }
- 
-   else if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != REG)
-     return AS1 (push%L1,%1);
- 
-   else
-     {
-       output_asm_insn (AS2 (mov%L2,%1,%2), operands);
-       return AS1 (push%L2,%2);
-     }
- }")
- 
- ;; Special memory<->memory pattern that combine will recreate from the
- ;; moves to pseudos.
- (define_insn "movsf_mem"
-   [(set (match_operand:SF 0 "memory_operand" "=m")
- 	(match_operand:SF 1 "memory_operand" "m"))
-    (clobber (match_scratch:SI 2 "=&r"))]
-   ""
-   "*
- {
-   output_asm_insn (AS2 (mov%L2,%1,%2), operands);
-   return AS2 (mov%L0,%2,%0);
- }")
- 
  ;; For the purposes of regclass, prefer FLOAT_REGS.
! (define_insn "movsf_normal"
    [(set (match_operand:SF 0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm")
  	(match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
    "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
--- 1254,1261 ----
      }
  }")
  
  ;; For the purposes of regclass, prefer FLOAT_REGS.
! (define_insn ""
    [(set (match_operand:SF 0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm")
  	(match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
    "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
***************
*** 1374,1404 ****
      return AS1 (fxch,%0);
  }")
  
  (define_expand "movdf"
    [(set (match_operand:DF 0 "general_operand" "")
  	(match_operand:DF 1 "general_operand" ""))]
    ""
    "
  {
!   /* Special case memory->memory moves and pushes */
    if (TARGET_MOVE
        && (reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) == MEM
!       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], DFmode)))
      {
!       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], DFmode))
! 						? gen_movdf_push
! 						: gen_movdf_mem;
! 
!       emit_insn ((*genfunc) (operands[0], operands[1]));
!       DONE;
      }
  
    /* If we are loading a floating point constant that isn't 0 or 1 into a
       register, indicate we need the pic register loaded.  This could be
       optimized into stores of constants if the target eventually moves to
       memory, but better safe than sorry.  */
!   if ((reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) != MEM
        && GET_CODE (operands[1]) == CONST_DOUBLE
        && !standard_80387_constant_p (operands[1]))
--- 1326,1383 ----
      return AS1 (fxch,%0);
  }")
  
+ (define_insn "movdf_push"
+   [(set (match_operand:DF 0 "push_operand" "=<,<")
+ 	(match_operand:DF 1 "nonmemory_operand" "rF,f"))]
+   ""
+   "*
+ {
+   if (STACK_REG_P (operands[1]))
+     {
+       rtx xops[3];
+ 
+       xops[0] = AT_SP (DFmode);
+       xops[1] = GEN_INT (8);
+       xops[2] = stack_pointer_rtx;
+ 
+       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
+ 
+       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+         output_asm_insn (AS1 (fstp%Q0,%0), xops);
+       else
+         output_asm_insn (AS1 (fst%Q0,%0), xops);
+ 
+       RET;
+     }
+   return output_move_double (operands);
+ }")
+ 
+ (define_insn "movdf_push_memory"
+   [(set (match_operand:DF 0 "push_operand" "=<")
+ 	(match_operand:DF 1 "memory_operand" "o"))]
+   "TARGET_PUSH_MEMORY"
+   "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode),0,0);")
+ 
  (define_expand "movdf"
    [(set (match_operand:DF 0 "general_operand" "")
  	(match_operand:DF 1 "general_operand" ""))]
    ""
    "
  {
!   /* Don't generate memory->memory moves, go through a register */
    if (TARGET_MOVE
        && (reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) == MEM
!       && GET_CODE (operands[1]) == MEM)
      {
!       operands[1] = force_reg (DFmode, operands[1]);
      }
  
    /* If we are loading a floating point constant that isn't 0 or 1 into a
       register, indicate we need the pic register loaded.  This could be
       optimized into stores of constants if the target eventually moves to
       memory, but better safe than sorry.  */
!   else if ((reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) != MEM
        && GET_CODE (operands[1]) == CONST_DOUBLE
        && !standard_80387_constant_p (operands[1]))
***************
*** 1419,1492 ****
      }
  }")
  
- (define_insn "movdf_push_nomove"
-   [(set (match_operand:DF 0 "push_operand" "=<,<")
- 	(match_operand:DF 1 "general_operand" "gF,f"))]
-   "!TARGET_MOVE"
-   "*
- {
-   if (STACK_REG_P (operands[1]))
-     {
-       rtx xops[3];
- 
-       xops[0] = AT_SP (SFmode);
-       xops[1] = GEN_INT (8);
-       xops[2] = stack_pointer_rtx;
- 
-       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
- 
-       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
-         output_asm_insn (AS1 (fstp%Q0,%0), xops);
-       else
-         output_asm_insn (AS1 (fst%Q0,%0), xops);
- 
-       RET;
-     }
-   else
-     return output_move_double (operands);
- }")
- 
- (define_insn "movdf_push"
-   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<")
- 	(match_operand:DF 1 "general_operand" "rF,f,o,o,o"))
-    (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
-    (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
-   ""
-   "*
- {
-   if (STACK_REG_P (operands[1]))
-     {
-       rtx xops[3];
- 
-       xops[0] = AT_SP (SFmode);
-       xops[1] = GEN_INT (8);
-       xops[2] = stack_pointer_rtx;
- 
-       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
- 
-       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
-         output_asm_insn (AS1 (fstp%Q0,%0), xops);
-       else
-         output_asm_insn (AS1 (fst%Q0,%0), xops);
- 
-       RET;
-     }
- 
-   else if (GET_CODE (operands[1]) != MEM)
-     return output_move_double (operands);
- 
-   else
-     return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);
- }")
- 
- (define_insn "movdf_mem"
-   [(set (match_operand:DF 0 "memory_operand" "=o,o")
- 	(match_operand:DF 1 "memory_operand" "o,o"))
-    (clobber (match_scratch:SI 2 "=&r,&r"))
-    (clobber (match_scratch:SI 3 "=&r,X"))]
-   ""
-   "* return output_move_memory (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);")
- 
  ;; For the purposes of regclass, prefer FLOAT_REGS.
  (define_insn ""
    [(set (match_operand:DF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
--- 1398,1403 ----
***************
*** 1561,1591 ****
      return AS1 (fxch,%0);
  }")
  
  (define_expand "movxf"
    [(set (match_operand:XF 0 "general_operand" "")
  	(match_operand:XF 1 "general_operand" ""))]
    ""
    "
  {
!   /* Special case memory->memory moves and pushes */
    if (TARGET_MOVE
        && (reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) == MEM
!       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], XFmode)))
      {
!       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode))
! 						? gen_movxf_push
! 						: gen_movxf_mem;
! 
!       emit_insn ((*genfunc) (operands[0], operands[1]));
!       DONE;
      }
  
    /* If we are loading a floating point constant that isn't 0 or 1
       into a register, indicate we need the pic register loaded.  This could
       be optimized into stores of constants if the target eventually moves
       to memory, but better safe than sorry.  */
!   if ((reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) != MEM
        && GET_CODE (operands[1]) == CONST_DOUBLE
        && !standard_80387_constant_p (operands[1]))
--- 1472,1528 ----
      return AS1 (fxch,%0);
  }")
  
+ (define_insn "movxf_push"
+   [(set (match_operand:XF 0 "push_operand" "=<,<")
+  	(match_operand:XF 1 "nonmemory_operand" "rF,f"))]
+   ""
+   "*
+ {
+   if (STACK_REG_P (operands[1]))
+     {
+       rtx xops[3];
+ 
+       xops[0] = AT_SP (XFmode);
+       xops[1] = GEN_INT (12);
+       xops[2] = stack_pointer_rtx;
+ 
+       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
+ 
+       output_asm_insn (AS1 (fstp%T0,%0), xops);
+       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+ 	output_asm_insn (AS1 (fld%T0,%0), xops);
+ 
+       RET;
+     }
+   return output_move_double (operands);
+  }")
+ 
+ (define_insn "movxf_push_memory"
+   [(set (match_operand:XF 0 "push_operand" "=<")
+  	(match_operand:XF 1 "memory_operand" "o"))]
+   "TARGET_PUSH_MEMORY"
+   "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode),0,0);")
+ 
  (define_expand "movxf"
    [(set (match_operand:XF 0 "general_operand" "")
  	(match_operand:XF 1 "general_operand" ""))]
    ""
    "
  {
!   /* Don't generate memory->memory moves, go through a register */
    if (TARGET_MOVE
        && (reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) == MEM
!       && GET_CODE (operands[1]) == MEM)
      {
!       operands[1] = force_reg (XFmode, operands[1]);
      }
  
    /* If we are loading a floating point constant that isn't 0 or 1
       into a register, indicate we need the pic register loaded.  This could
       be optimized into stores of constants if the target eventually moves
       to memory, but better safe than sorry.  */
!   else if ((reload_in_progress | reload_completed) == 0
        && GET_CODE (operands[0]) != MEM
        && GET_CODE (operands[1]) == CONST_DOUBLE
        && !standard_80387_constant_p (operands[1]))
***************
*** 1605,1676 ****
  	REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn));
      }
  }")
- 
- 
- (define_insn "movxf_push_nomove"
-   [(set (match_operand:XF 0 "push_operand" "=<,<")
-  	(match_operand:XF 1 "general_operand" "gF,f"))]
-   "!TARGET_MOVE"
-   "*
- {
-   if (STACK_REG_P (operands[1]))
-     {
-       rtx xops[3];
- 
-       xops[0] = AT_SP (SFmode);
-       xops[1] = GEN_INT (12);
-       xops[2] = stack_pointer_rtx;
- 
-       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
-       output_asm_insn (AS1 (fstp%T0,%0), xops);
-       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
- 	output_asm_insn (AS1 (fld%T0,%0), xops);
- 
-       RET;
-     }
-   else
-     return output_move_double (operands);
-  }")
- 
- (define_insn "movxf_push"
-   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
-  	(match_operand:XF 1 "general_operand" "rF,f,o,o,o"))
-    (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
-    (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
-   ""
-   "*
- {
-   if (STACK_REG_P (operands[1]))
-     {
-       rtx xops[3];
- 
-       xops[0] = AT_SP (SFmode);
-       xops[1] = GEN_INT (12);
-       xops[2] = stack_pointer_rtx;
- 
-       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
-       output_asm_insn (AS1 (fstp%T0,%0), xops);
-       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
- 	output_asm_insn (AS1 (fld%T0,%0), xops);
- 
-       RET;
-     }
- 
-   else if (GET_CODE (operands[1]) != MEM
- 	   || GET_CODE (operands[2]) != REG)
-     return output_move_double (operands);
- 
-   else
-     return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);
- }")
- 
- (define_insn "movxf_mem"
-   [(set (match_operand:XF 0 "memory_operand" "=o,o")
- 	(match_operand:XF 1 "memory_operand" "o,o"))
-    (clobber (match_scratch:SI 2 "=&r,&r"))
-    (clobber (match_scratch:SI 3 "=&r,X"))]
-   ""
-   "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
--- 1542,1547 ----
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------




More information about the Gcc-bugs mailing list