This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Patch for i386.md to fix SF / DF / XF move inconsistencies.
- To: egcs-bugs at cygnus dot com
- Subject: Patch for i386.md to fix SF / DF / XF move inconsistencies.
- From: john at feith dot com (John Wehle)
- Date: Sat, 17 Jan 1998 22:30:24 -0500
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:
Sat Jan 17 21:48:48 EST 1998 John Wehle (john@feith.com)
* i386.md (movsf_push, movsf_mem): Remove.
(movsf_push_memory): New pattern.
(movsf_push): Rename from movsf_push_nomove and move in front of
movsf. Don't bother checking TARGET_MOVE.
(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): Don't check for !TARGET_MOVE or GET_CODE (...) != MEM.
Likewise for movdf, movxf, and friends.
-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/config/i386/i386.md.ORIGINAL Wed Nov 5 14:29:37 1997
--- gcc/config/i386/i386.md Sat Jan 17 21:38:54 1998
***************
*** 1167,1221 ****
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]))
! {
! rtx insn, note, fp_const;
!
! fp_const = force_const_mem (SFmode, operands[1]);
! if (flag_pic)
! current_function_uses_pic_offset_table = 1;
!
! insn = emit_insn (gen_rtx (SET, SFmode, operands[0], fp_const));
! note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
!
! if (note)
! XEXP (note, 0) = operands[1];
! else
! REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1], REG_NOTES (insn));
! }
! }")
! (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]))
--- 1144,1159 ----
return AS2 (mov%B0,%1,%0);
}")
! (define_insn "movsf_push_memory"
! [(set (match_operand:SF 0 "push_operand" "=<")
! (match_operand:SF 1 "memory_operand" "m"))]
! "TARGET_PUSH_MEMORY"
! "push%L0,%1")
! (define_insn "movsf_push"
[(set (match_operand:SF 0 "push_operand" "=<,<")
! (match_operand:SF 1 "general_operand" "rF,f"))]
! ""
"*
{
if (STACK_REG_P (operands[1]))
***************
*** 1237,1300 ****
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)"
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
--- 1175,1228 ----
output_asm_insn (AS1 (fst%S0,%0), xops);
RET;
}
! 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]))
! {
! rtx insn, note, fp_const;
! fp_const = force_const_mem (SFmode, operands[1]);
! if (flag_pic)
! current_function_uses_pic_offset_table = 1;
! insn = emit_insn (gen_rtx (SET, SFmode, operands[0], fp_const));
! note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
! if (note)
! XEXP (note, 0) = operands[1];
else
! REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1], REG_NOTES (insn));
}
}")
;; 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"))]
! ""
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
***************
*** 1347,1353 ****
}"
[(set_attr "type" "fld")])
-
(define_insn "swapsf"
[(set (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f"))
--- 1275,1280 ----
***************
*** 1362,1392 ****
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]))
--- 1289,1348 ----
return AS1 (fxch,%0);
}")
+ (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_insn "movdf_push"
+ [(set (match_operand:DF 0 "push_operand" "=<,<")
+ (match_operand:DF 1 "general_operand" "rF,f"))]
+ ""
+ "*
+ {
+ if (STACK_REG_P (operands[1]))
+ {
+ rtx xops[3];
+
+ if (! STACK_TOP_P (operands[1]))
+ abort ();
+
+ 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_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]))
***************
*** 1407,1486 ****
}
}")
- (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")
(match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
! "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
! || (GET_CODE (operands[1]) != MEM)"
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
--- 1363,1373 ----
}
}")
;; For the purposes of regclass, prefer FLOAT_REGS.
! (define_insn "movdf_normal"
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
(match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
! ""
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
***************
*** 1533,1540 ****
}"
[(set_attr "type" "fld")])
-
-
(define_insn "swapdf"
[(set (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f"))
--- 1420,1425 ----
***************
*** 1549,1579 ****
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]))
--- 1434,1492 ----
return AS1 (fxch,%0);
}")
+ (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_insn "movxf_push"
+ [(set (match_operand:XF 0 "push_operand" "=<,<")
+ (match_operand:XF 1 "general_operand" "rF,f"))]
+ ""
+ "*
+ {
+ if (STACK_REG_P (operands[1]))
+ {
+ rtx xops[3];
+
+ if (! STACK_TOP_P (operands[1]))
+ abort ();
+
+ 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_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]))
***************
*** 1594,1670 ****
}
}")
!
! (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")
(match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
! "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
! || (GET_CODE (operands[1]) != MEM)"
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
--- 1507,1516 ----
}
}")
! (define_insn "movxf_normal"
[(set (match_operand:XF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
(match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
! ""
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
-------------------------------------------------------------------------
| Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com |
| John Wehle | Fax: 1-215-540-5495 | |
-------------------------------------------------------------------------