diff options
Diffstat (limited to 'gcc/config/cris/cris.md')
-rw-r--r-- | gcc/config/cris/cris.md | 105 |
1 files changed, 57 insertions, 48 deletions
diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md index e700819..ae6a27f 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -183,6 +183,25 @@ (define_code_attr u [(sign_extend "") (zero_extend "u")]) (define_code_attr su [(sign_extend "s") (zero_extend "u")]) +;; For extended-operand variants. +(define_code_iterator plusminus [plus minus]) +(define_code_attr addsub [(plus "add") (minus "sub")]) + +;; Similar, other cases also matching bound/umin. +(define_code_iterator plusminusumin [plus minus umin]) + +;; Ditto, commutative operators (i.e. not minus). +(define_code_iterator plusumin [plus umin]) + +;; The addsubbo and nd code-attributes form a hack. We need to output +;; "addu.b", "subu.b" but "bound.b" (no "u"-suffix) which means we'd +;; need to refer to one iterator from the next. But, that can't be +;; done. Instead output the "u" for unsigned as the "u" in "bound", +;; i.e. the mnemonic as three parts including the extend-letter, and +;; with an empty third part for "add" and "sub". +(define_code_attr addsubbo [(plus "add") (minus "sub") (umin "bo")]) +(define_code_attr nd [(plus "") (minus "") (umin "nd")]) + ;; For the shift variants. (define_code_iterator shift [ashiftrt lshiftrt ashift]) (define_code_iterator shiftrt [ashiftrt lshiftrt]) @@ -1113,42 +1132,37 @@ ;; QImode to HImode ;; FIXME: GCC should widen. -(define_insn "*extopqihi" +(define_insn "*<addsub><su>qihi" [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") - (match_operator:HI - 3 "cris_additive_operand_extend_operator" - [(match_operand:HI 1 "register_operand" "0,0,0,r") - (match_operator:HI - 4 "cris_extend_operator" - [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])])) + (plusminus:HI + (match_operand:HI 1 "register_operand" "0,0,0,r") + (szext:HI (match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")))) (clobber (reg:CC CRIS_CC0_REGNUM))] "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD - && (operands[1] != frame_pointer_rtx || GET_CODE (operands[3]) != PLUS)" + && (operands[1] != frame_pointer_rtx || <plusminus:CODE> != PLUS)" "@ - %x3%E4.%m4 %2,%0 - %x3%E4.%m4 %2,%0 - %x3%E4.%m4 %2,%0 - %x3%E4.%m4 %2,%1,%0" + <addsub><su>.b %2,%0 + <addsub><su>.b %2,%0 + <addsub><su>.b %2,%0 + <addsub><su>.b %2,%1,%0" [(set_attr "slottable" "yes,yes,no,no") (set_attr "cc" "clobber")]) -(define_insn "*extop<mode>si<setnz>" +;; FIXME: bound is actually also <setnzvc>, but is so rarely used in this +;; form that it's not worthwhile to make that distinction. +(define_insn "*<addsubbo><su><nd><mode>si<setnz>" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") - (match_operator:SI - 3 "cris_operand_extend_operator" - [(match_operand:SI 1 "register_operand" "0,0,0,r") - (match_operator:SI - 4 "cris_extend_operator" - [(match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")])])) - (clobber (reg:CC CRIS_CC0_REGNUM))] - "(GET_CODE (operands[3]) != UMIN || GET_CODE (operands[4]) == ZERO_EXTEND) - && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD - && (operands[1] != frame_pointer_rtx || GET_CODE (operands[3]) != PLUS)" + (plusminusumin:SI + (match_operand:SI 1 "register_operand" "0,0,0,r") + (szext:SI (match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")))) + (clobber (reg:CC CRIS_CC0_REGNUM))] + "(<plusminusumin:CODE> != UMIN || <szext:CODE> == ZERO_EXTEND) + && (operands[1] != frame_pointer_rtx || <plusminusumin:CODE> != PLUS)" "@ - %x3%E4<m> %2,%0 - %x3%E4<m> %2,%0 - %x3%E4<m> %2,%0 - %x3%E4<m> %2,%1,%0" + <addsubbo><su><nd><m> %2,%0 + <addsubbo><su><nd><m> %2,%0 + <addsubbo><su><nd><m> %2,%0 + <addsubbo><su><nd><m> %2,%1,%0" [(set_attr "slottable" "yes,yes,no,no")]) ;; We may have swapped operands for add or bound. @@ -1156,39 +1170,34 @@ ;; QImode to HImode -(define_insn "*addxqihi_swap" +(define_insn "*add<su>qihi_swap" [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") (plus:HI - (match_operator:HI - 3 "cris_extend_operator" - [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")]) + (szext:HI (match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")) (match_operand:HI 1 "register_operand" "0,0,0,r"))) (clobber (reg:CC CRIS_CC0_REGNUM))] "operands[1] != frame_pointer_rtx" "@ - add%e3.b %2,%0 - add%e3.b %2,%0 - add%e3.b %2,%0 - add%e3.b %2,%1,%0" + add<su>.b %2,%0 + add<su>.b %2,%0 + add<su>.b %2,%0 + add<su>.b %2,%1,%0" [(set_attr "slottable" "yes,yes,no,no") (set_attr "cc" "clobber")]) -(define_insn "*extop<mode>si<setnz>_swap" +(define_insn "*<addsubbo><su><nd><mode>si<setnz>_swap" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") - (match_operator:SI - 4 "cris_plus_or_bound_operator" - [(match_operator:SI - 3 "cris_extend_operator" - [(match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")]) - (match_operand:SI 1 "register_operand" "0,0,0,r")])) - (clobber (reg:CC CRIS_CC0_REGNUM))] - "(GET_CODE (operands[4]) != UMIN || GET_CODE (operands[3]) == ZERO_EXTEND) + (plusumin:SI + (szext:SI (match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")) + (match_operand:SI 1 "register_operand" "0,0,0,r"))) + (clobber (reg:CC CRIS_CC0_REGNUM))] + "(<plusumin:CODE> != UMIN || <szext:CODE> == ZERO_EXTEND) && operands[1] != frame_pointer_rtx" "@ - %x4%E3<m> %2,%0 - %x4%E3<m> %2,%0 - %x4%E3<m> %2,%0 - %x4%E3<m> %2,%1,%0" + <addsubbo><su><nd><m> %2,%0 + <addsubbo><su><nd><m> %2,%0 + <addsubbo><su><nd><m> %2,%0 + <addsubbo><su><nd><m> %2,%1,%0" [(set_attr "slottable" "yes,yes,no,no")]) ;; This is the special case when we use what corresponds to the |