From fe4435d988378b1ee56c2dc0c387d729cb44421d Mon Sep 17 00:00:00 2001 From: James Van Artsdalen Date: Fri, 12 Mar 1993 09:34:38 +0000 Subject: [PATCH] (truncdfsf2): Rewrite to allow FLOAT_REGS in constraints for better register preferences. (truncdfsf2): Rewrite to allow FLOAT_REGS in constraints for better register preferences. (movM): If REG_WAS_0, make sure the reg hasn't changed since then. (cmpM expanders): Don't allow both operands to be MEM. Use VOIDmode for the COMPARE rtx instead of CCmode. (cmpM recognizers): Likewise. Remove constraints for constants from operand 0. (cmpdf,cmpsf recognizers): When using VOIDmode as mode of the COMPARE rtx, require that the mode be exactly VOIDmode. From-SVN: r3716 --- gcc/config/i386/i386.md | 265 ++++++++++++++++++++++++---------------- 1 file changed, 160 insertions(+), 105 deletions(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 7073b251b80..c701df61d57 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -69,7 +69,7 @@ ;; 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"))] "" @@ -88,12 +88,12 @@ "" " { - 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"))] "" @@ -112,12 +112,12 @@ "" " { - 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"))] "" @@ -136,7 +136,7 @@ "" " { - i386_compare_gen = gen_tstqi_cc; + i386_compare_gen = gen_tstqi_1; i386_compare_op0 = operands[0]; DONE; }") @@ -210,11 +210,11 @@ ;;- 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) @@ -227,22 +227,25 @@ (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) @@ -255,22 +258,25 @@ (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) @@ -283,12 +289,15 @@ (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; @@ -298,101 +307,111 @@ ;; 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);") @@ -406,8 +425,8 @@ (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" " { @@ -420,8 +439,8 @@ (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" " { @@ -432,6 +451,14 @@ 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" "") @@ -444,6 +471,14 @@ 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" "") @@ -623,10 +658,12 @@ 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); @@ -654,10 +691,12 @@ 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); @@ -685,10 +724,12 @@ 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); @@ -727,10 +768,12 @@ 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); @@ -763,10 +806,12 @@ 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); @@ -808,9 +853,9 @@ 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") @@ -909,9 +954,9 @@ 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") @@ -1194,26 +1239,36 @@ ;; 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 (); }") -- 2.30.2