;; actually generating RTL. The bCOND or sCOND (emitted immediately
;; after the tstM or cmp) will actually emit the tstM or cmpM.
-(define_insn "tstsi_cc"
+(define_insn "tstsi_1"
[(set (cc0)
(match_operand:SI 0 "nonimmediate_operand" "rm"))]
""
""
"
{
- i386_compare_gen = gen_tstsi_cc;
+ i386_compare_gen = gen_tstsi_1;
i386_compare_op0 = operands[0];
DONE;
}")
-(define_insn "tsthi_cc"
+(define_insn "tsthi_1"
[(set (cc0)
(match_operand:HI 0 "nonimmediate_operand" "rm"))]
""
""
"
{
- i386_compare_gen = gen_tsthi_cc;
+ i386_compare_gen = gen_tsthi_1;
i386_compare_op0 = operands[0];
DONE;
}")
-(define_insn "tstqi_cc"
+(define_insn "tstqi_1"
[(set (cc0)
(match_operand:QI 0 "nonimmediate_operand" "qm"))]
""
""
"
{
- i386_compare_gen = gen_tstqi_cc;
+ i386_compare_gen = gen_tstqi_1;
i386_compare_op0 = operands[0];
DONE;
}")
;;- compare instructions. See comments above tstM patterns about
;; expansion of these insns.
-(define_insn "cmpsi_cc"
+(define_insn "cmpsi_1"
[(set (cc0)
- (compare:CC (match_operand:SI 0 "nonimmediate_operand" "mr,ri")
- (match_operand:SI 1 "general_operand" "ri,mr")))]
- ""
+ (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
+ (match_operand:SI 1 "general_operand" "ri,mr")))]
+ "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"*
{
if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
(define_expand "cmpsi"
[(set (cc0)
- (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
- (match_operand:SI 1 "general_operand" "")))]
+ (compare (match_operand:SI 0 "nonimmediate_operand" "")
+ (match_operand:SI 1 "general_operand" "")))]
""
"
{
- i386_compare_gen = gen_cmpsi_cc;
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+ operands[0] = force_reg (SImode, operands[0]);
+
+ i386_compare_gen = gen_cmpsi_1;
i386_compare_op0 = operands[0];
i386_compare_op1 = operands[1];
DONE;
}")
-(define_insn "cmphi_cc"
+(define_insn "cmphi_1"
[(set (cc0)
- (compare:CC (match_operand:HI 0 "nonimmediate_operand" "mr,ri")
- (match_operand:HI 1 "general_operand" "ri,mr")))]
- ""
+ (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
+ (match_operand:HI 1 "general_operand" "ri,mr")))]
+ "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"*
{
if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
(define_expand "cmphi"
[(set (cc0)
- (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
- (match_operand:HI 1 "general_operand" "")))]
+ (compare (match_operand:HI 0 "nonimmediate_operand" "")
+ (match_operand:HI 1 "general_operand" "")))]
""
"
{
- i386_compare_gen = gen_cmphi_cc;
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+ operands[0] = force_reg (HImode, operands[0]);
+
+ i386_compare_gen = gen_cmphi_1;
i386_compare_op0 = operands[0];
i386_compare_op1 = operands[1];
DONE;
}")
-(define_insn "cmpqi_cc"
+(define_insn "cmpqi_1"
[(set (cc0)
- (compare:CC (match_operand:QI 0 "nonimmediate_operand" "qn,mq")
- (match_operand:QI 1 "general_operand" "qm,nq")))]
- ""
+ (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
+ (match_operand:QI 1 "general_operand" "qm,nq")))]
+ "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"*
{
if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
(define_expand "cmpqi"
[(set (cc0)
- (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
- (match_operand:QI 1 "general_operand" "")))]
+ (compare (match_operand:QI 0 "nonimmediate_operand" "")
+ (match_operand:QI 1 "general_operand" "")))]
""
"
{
- i386_compare_gen = gen_cmpqi_cc;
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+ operands[0] = force_reg (QImode, operands[0]);
+
+ i386_compare_gen = gen_cmpqi_1;
i386_compare_op0 = operands[0];
i386_compare_op1 = operands[1];
DONE;
;; SFmode, there is the normal insn, and an insn where the second operand
;; is converted to the desired mode.
-(define_insn "cmpdf_cc"
+(define_insn ""
[(set (cc0)
- (compare:CC (match_operand:DF 0 "nonimmediate_operand" "f,fm")
- (match_operand:DF 1 "nonimmediate_operand" "fm,f")))
- (clobber (match_scratch:HI 2 "=a,a"))]
+ (match_operator 2 "VOIDmode_compare_op"
+ [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
+ (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
+ (clobber (match_scratch:HI 3 "=a,a"))]
"TARGET_80387
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"* return (char *) output_float_compare (insn, operands);")
(define_insn ""
[(set (cc0)
- (compare:CC (match_operand:DF 0 "register_operand" "f")
- (float:DF
- (match_operand:SI 1 "nonimmediate_operand" "rm"))))
- (clobber (match_scratch:HI 2 "=a"))]
- "TARGET_80387"
- "* return (char *) output_float_compare (insn, operands);")
-
-(define_insn ""
- [(set (cc0)
- (compare:CC (float:DF
- (match_operand:SI 0 "nonimmediate_operand" "rm"))
- (match_operand:DF 1 "register_operand" "f")))
- (clobber (match_scratch:HI 2 "=a"))]
+ (match_operator 2 "VOIDmode_compare_op"
+ [(match_operand:DF 0 "register_operand" "f")
+ (float:DF
+ (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
+ (clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
"* return (char *) output_float_compare (insn, operands);")
(define_insn ""
[(set (cc0)
- (compare:CC (match_operand:DF 0 "register_operand" "f")
- (float_extend:DF
- (match_operand:SF 1 "nonimmediate_operand" "fm"))))
- (clobber (match_scratch:HI 2 "=a"))]
+ (match_operator 2 "VOIDmode_compare_op"
+ [(float:DF
+ (match_operand:SI 0 "nonimmediate_operand" "rm"))
+ (match_operand:DF 1 "register_operand" "f")]))
+ (clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
"* return (char *) output_float_compare (insn, operands);")
(define_insn ""
[(set (cc0)
- (compare:CC (float_extend:DF
- (match_operand:SF 0 "nonimmediate_operand" "fm"))
- (match_operand:DF 1 "register_operand" "f")))
- (clobber (match_scratch:HI 2 "=a"))]
+ (match_operator 2 "VOIDmode_compare_op"
+ [(match_operand:DF 0 "register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
+ (clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
"* return (char *) output_float_compare (insn, operands);")
(define_insn ""
[(set (cc0)
- (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
- (match_operand:DF 1 "register_operand" "f")))
- (clobber (match_scratch:HI 2 "=a"))]
+ (match_operator 2 "VOIDmode_compare_op"
+ [(float_extend:DF
+ (match_operand:SF 0 "nonimmediate_operand" "fm"))
+ (match_operand:DF 1 "register_operand" "f")]))
+ (clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
"* return (char *) output_float_compare (insn, operands);")
(define_insn ""
[(set (cc0)
(compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
- (float_extend:DF
- (match_operand:SF 1 "register_operand" "f"))))
- (clobber (match_scratch:HI 2 "=a"))]
- "TARGET_80387"
- "* return (char *) output_float_compare (insn, operands);")
-
-(define_insn ""
- [(set (cc0)
- (compare:CCFPEQ (float_extend:DF
- (match_operand:SF 0 "register_operand" "f"))
(match_operand:DF 1 "register_operand" "f")))
(clobber (match_scratch:HI 2 "=a"))]
"TARGET_80387"
"* return (char *) output_float_compare (insn, operands);")
-(define_insn "cmpsf_cc"
+;; These two insns will never be generated by combine due to the mode of
+;; the COMPARE.
+;(define_insn ""
+; [(set (cc0)
+; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
+; (float_extend:DF
+; (match_operand:SF 1 "register_operand" "f"))))
+; (clobber (match_scratch:HI 2 "=a"))]
+; "TARGET_80387"
+; "* return (char *) output_float_compare (insn, operands);")
+;
+;(define_insn ""
+; [(set (cc0)
+; (compare:CCFPEQ (float_extend:DF
+; (match_operand:SF 0 "register_operand" "f"))
+; (match_operand:DF 1 "register_operand" "f")))
+; (clobber (match_scratch:HI 2 "=a"))]
+; "TARGET_80387"
+; "* return (char *) output_float_compare (insn, operands);")
+
+(define_insn "cmpsf_cc_1"
[(set (cc0)
- (compare:CC (match_operand:SF 0 "nonimmediate_operand" "f,fm")
- (match_operand:SF 1 "nonimmediate_operand" "fm,f")))
- (clobber (match_scratch:HI 2 "=a,a"))]
+ (match_operator 2 "VOIDmode_compare_op"
+ [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
+ (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
+ (clobber (match_scratch:HI 3 "=a,a"))]
"TARGET_80387
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"* return (char *) output_float_compare (insn, operands);")
(define_insn ""
[(set (cc0)
- (compare:CC (match_operand:SF 0 "register_operand" "f")
- (float:SF
- (match_operand:SI 1 "nonimmediate_operand" "rm"))))
- (clobber (match_scratch:HI 2 "=a"))]
+ (match_operator 2 "VOIDmode_compare_op"
+ [(match_operand:SF 0 "register_operand" "f")
+ (float:SF
+ (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
+ (clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
"* return (char *) output_float_compare (insn, operands);")
(define_insn ""
[(set (cc0)
- (compare:CC (float:SF
- (match_operand:SI 0 "nonimmediate_operand" "rm"))
- (match_operand:SF 1 "register_operand" "f")))
- (clobber (match_scratch:HI 2 "=a"))]
+ (match_operator 2 "VOIDmode_compare_op"
+ [(float:SF
+ (match_operand:SI 0 "nonimmediate_operand" "rm"))
+ (match_operand:SF 1 "register_operand" "f")]))
+ (clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
"* return (char *) output_float_compare (insn, operands);")
(define_expand "cmpdf"
[(set (cc0)
- (compare:CC (match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "nonimmediate_operand" "")))]
+ (compare (match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "nonimmediate_operand" "")))]
"TARGET_80387"
"
{
(define_expand "cmpsf"
[(set (cc0)
- (compare:CC (match_operand:SF 0 "register_operand" "")
- (match_operand:SF 1 "nonimmediate_operand" "")))]
+ (compare (match_operand:SF 0 "register_operand" "")
+ (match_operand:SF 1 "nonimmediate_operand" "")))]
"TARGET_80387"
"
{
DONE;
}")
+(define_expand "cmpdf_cc"
+ [(parallel [(set (cc0)
+ (compare (match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "register_operand" "")))
+ (clobber (match_scratch:HI 2 ""))])]
+ "TARGET_80387"
+ "")
+
(define_expand "cmpdf_ccfpeq"
[(parallel [(set (cc0)
(compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
operands[1] = copy_to_mode_reg (DFmode, operands[1]);
}")
+(define_expand "cmpsf_cc"
+ [(parallel [(set (cc0)
+ (compare (match_operand:SF 0 "register_operand" "")
+ (match_operand:SF 1 "register_operand" "")))
+ (clobber (match_scratch:HI 2 ""))])]
+ "TARGET_80387"
+ "")
+
(define_expand "cmpsf_ccfpeq"
[(parallel [(set (cc0)
(compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
if (operands[1] == const1_rtx
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
- && ! XEXP (link, 0)->volatil
+ && ! INSN_DELETED_P (XEXP (link, 0))
&& GET_CODE (XEXP (link, 0)) != NOTE
/* Make sure cross jumping didn't happen here. */
- && no_labels_between_p (XEXP (link, 0), insn))
+ && no_labels_between_p (XEXP (link, 0), insn)
+ /* Make sure the reg hasn't been clobbered. */
+ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
/* Fastest way to change a 0 to a 1. */
return AS1 (inc%L0,%0);
if (REG_P (operands[0]) && operands[1] == const1_rtx
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
- && ! XEXP (link, 0)->volatil
+ && ! INSN_DELETED_P (XEXP (link, 0))
&& GET_CODE (XEXP (link, 0)) != NOTE
/* Make sure cross jumping didn't happen here. */
- && no_labels_between_p (XEXP (link, 0), insn))
+ && no_labels_between_p (XEXP (link, 0), insn)
+ /* Make sure the reg hasn't been clobbered. */
+ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
/* Fastest way to change a 0 to a 1. */
return AS1 (inc%L0,%k0);
if (operands[1] == const1_rtx
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
- && ! XEXP (link, 0)->volatil
+ && ! INSN_DELETED_P (XEXP (link, 0))
&& GET_CODE (XEXP (link, 0)) != NOTE
/* Make sure cross jumping didn't happen here. */
- && no_labels_between_p (XEXP (link, 0), insn))
+ && no_labels_between_p (XEXP (link, 0), insn)
+ /* Make sure the reg hasn't been clobbered. */
+ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
/* Fastest way to change a 0 to a 1. */
return AS1 (inc%W0,%0);
if (operands[1] == const1_rtx
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
- && ! XEXP (link, 0)->volatil
+ && ! INSN_DELETED_P (XEXP (link, 0))
&& GET_CODE (XEXP (link, 0)) != NOTE
/* Make sure cross jumping didn't happen here. */
- && no_labels_between_p (XEXP (link, 0), insn))
+ && no_labels_between_p (XEXP (link, 0), insn)
+ /* Make sure the reg hasn't been clobbered. */
+ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
/* Fastest way to change a 0 to a 1. */
return AS1 (inc%B0,%0);
if (operands[1] == const1_rtx
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
- && ! XEXP (link, 0)->volatil
+ && ! INSN_DELETED_P (XEXP (link, 0))
&& GET_CODE (XEXP (link, 0)) != NOTE
/* Make sure cross jumping didn't happen here. */
- && no_labels_between_p (XEXP (link, 0), insn))
+ && no_labels_between_p (XEXP (link, 0), insn)
+ /* Make sure the reg hasn't been clobbered. */
+ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
/* Fastest way to change a 0 to a 1. */
return AS1 (inc%B0,%0);
return AS1 (push%L1,%1);
}")
-;; The constraints used to be:
-;; op 0 "=f,fm,!*rf,!*rm"
-;; op 1 "fmG,f,*rfm,*rfF"
+;; Allow MEM-MEM moves before reload. The reload class for such a
+;; move will be ALL_REGS. PREFERRED_RELOAD_CLASS will narrow this to
+;; GENERAL_REGS. For the purposes of regclass, prefer FLOAT_REGS.
(define_insn "movsf"
[(set (match_operand:SF 0 "general_operand" "=*rf,*rfm,f,!*rm")
return AS1 (fxch,%0);
}")
-;; The constraints used to be:
-;; op 0 "=f,fm,!*rf,!*rm"
-;; op 1 "fmG,f,*rfm,*rfF"
+;; Allow MEM-MEM moves before reload. The reload class for such a
+;; move will be ALL_REGS. PREFERRED_RELOAD_CLASS will narrow this to
+;; GENERAL_REGS. For the purposes of regclass, prefer FLOAT_REGS.
(define_insn "movdf"
[(set (match_operand:DF 0 "general_operand" "=*rf,*rfm,f,!*rm")
;; insn.
(define_insn "truncdfsf2"
- [(set (match_operand:SF 0 "general_operand" "=m,!*r")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
(float_truncate:SF
- (match_operand:DF 1 "register_operand" "f,f")))]
+ (match_operand:DF 1 "register_operand" "0,f")))]
"TARGET_80387"
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
- if (NON_STACK_REG_P (operands[0]))
- {
- output_to_reg (operands[0], stack_top_dies);
- RET;
- }
- else if (GET_CODE (operands[0]) == MEM)
+ if (GET_CODE (operands[0]) == MEM)
{
if (stack_top_dies)
return AS1 (fstp%z0,%0);
else
return AS1 (fst%z0,%0);
}
+ else if (STACK_TOP_P (operands[0]))
+ {
+ rtx xops[4];
+
+ xops[0] = AT_SP (SFmode);
+ xops[1] = stack_pointer_rtx;
+ xops[2] = GEN_INT (GET_MODE_SIZE (SFmode));
+ xops[3] = operands[0];
+
+ output_asm_insn (AS2 (sub%L1,%2,%1), xops);
+ output_asm_insn (AS1 (fstp%z0,%y0), xops);
+ output_asm_insn (AS1 (fld%z0,%y0), xops);
+ output_asm_insn (AS2 (add%L1,%2,%1), xops);
+ RET;
+ }
else
abort ();
}")