Richard Sandiford wrote:
I think we should only use define_expands if there's a truly MIPS-specific feature in the expansion (as there is in the block move stuff, for example, where we use left/right loads and stores).
Fair enough.
Now obviously I'm only guessing what insn sequence you're using,
OK, the simplest thing is for me to attach the define_insns. See below.
Note that there is one slightly controversial aspect of these sequences, which is that they don't truncate the shift count, so a shift outside of the range 0 to 63 will generate an "unusual" result. This didn't cause any regression failures, and I believe that this is strictly speaking acceptable for C, since a shift is undefined outside of this range - but it could cause some "buggy" code to break. It wouldn't be hard to add an extra mask with 0x3f if people were nervous about this - it's just that I didn't have enough spare temp registers within the constraints of the existing DImode patterns.
---- cut here ---
;; XXX Would be better done using define_expand, so it can be scheduled ;; XXX Note won't handle a shift count outside the range 0 - 63 (define_insn "ashldi3_internal_movc" [(set (match_operand:DI 0 "register_operand" "=&d") (ashift:DI (match_operand:DI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d"))) (clobber (match_operand:SI 3 "register_operand" "=&d"))] "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 && ISA_HAS_CONDMOVE" "subu\t%3,%.,%2\;\ sll\t%M0,%M1,%2\;\ srl\t%3,%L1,%3\;\ sll\t%L0,%L1,%2\;\ movz\t%3,%.,%2\;\ or\t%M0,%M0,%3\;\ and\t%3,%2,32\;\ movn\t%M0,%L0,%3\;\ movn\t%L0,%.,%3" [(set_attr "type" "darith") (set_attr "mode" "DI") (set_attr "length" "36")])
;; Same length as before, but avoids branches ;; XXX Note won't handle a shift count outside the range 0 - 63 (define_insn "ashrdi3_internal_movc" [(set (match_operand:DI 0 "register_operand" "=&d") (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d"))) (clobber (match_operand:SI 3 "register_operand" "=&d"))] "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 && ISA_HAS_CONDMOVE" "subu\t%3,%.,%2\;\ srl\t%L0,%L1,%2\;\ sll\t%3,%M1,%3\;\ sra\t%M0,%M1,%2\;\ movz\t%3,%.,%2\;\ or\t%L0,%L0,%3\;\ and\t%3,%2,32\;\ movn\t%L0,%M0,%3\;\ movn\t%M0,%.,%3\;\ movn\t%3,%L0,%3\;\ sra\t%3,%3,31\;\ or\t%M0,%M0,%3" [(set_attr "type" "darith") (set_attr "mode" "DI") (set_attr "length" "48")])
;;; XXX Note won't handle a shift count outside the range 0 - 63 (define_insn "lshrdi3_internal_movc" [(set (match_operand:DI 0 "register_operand" "=&d") (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d"))) (clobber (match_operand:SI 3 "register_operand" "=&d"))] "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 && ISA_HAS_CONDMOVE" "subu\t%3,%.,%2\;\ srl\t%L0,%L1,%2\;\ sll\t%3,%M1,%3\;\ srl\t%M0,%M1,%2\;\ movz\t%3,%.,%2\;\ or\t%L0,%L0,%3\;\ and\t%3,%2,32\;\ movn\t%L0,%M0,%3\;\ movn\t%M0,%.,%3" [(set_attr "type" "darith") (set_attr "mode" "DI") (set_attr "length" "36")])