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" ""))]
""
"
{
- /* Special case memory->memory moves and pushes */
+ /* 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 || push_operand (operands[0], SFmode)))
+ && GET_CODE (operands[1]) == MEM)
{
- rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode))
- ? gen_movsf_push
- : gen_movsf_mem;
-
- emit_insn ((*genfunc) (operands[0], operands[1]));
- DONE;
+ 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. */
- if ((reload_in_progress | reload_completed) == 0
+ 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]))
}
}")
-(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"
+(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)"
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" ""))]
""
"
{
- /* Special case memory->memory moves and pushes */
+ /* 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 || push_operand (operands[0], DFmode)))
+ && GET_CODE (operands[1]) == MEM)
{
- rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], DFmode))
- ? gen_movdf_push
- : gen_movdf_mem;
-
- emit_insn ((*genfunc) (operands[0], operands[1]));
- DONE;
+ 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. */
- if ((reload_in_progress | reload_completed) == 0
+ 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]))
}
}")
-(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")
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" ""))]
""
"
{
- /* Special case memory->memory moves and pushes */
+ /* 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 || push_operand (operands[0], XFmode)))
+ && GET_CODE (operands[1]) == MEM)
{
- rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode))
- ? gen_movxf_push
- : gen_movxf_mem;
-
- emit_insn ((*genfunc) (operands[0], operands[1]));
- DONE;
+ 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. */
- if ((reload_in_progress | reload_completed) == 0
+ 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]))
}")
-(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"))]