diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md index 65e951774b1..1ec219c0680 100644 --- a/gcc/config/msp430/msp430.md +++ b/gcc/config/msp430/msp430.md @@ -1724,6 +1724,28 @@ [(set_attr "length" "2")] ) +(define_expand "mulhi3" + [(set (match_operand:HI 0 "register_operand" "=r") + (mult:HI (match_operand:HI 1 "register_operand" "%0") + (match_operand:HI 2 "register_operand" "r")))] + "msp430_has_hwmult ()" + { + msp430_expand_helper (operands, "__mspabi_mpyi", false); + DONE; + } +) + +(define_expand "mulsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (mult:SI (match_operand:SI 1 "register_operand" "%0") + (match_operand:SI 2 "register_operand" "r")))] + "msp430_has_hwmult ()" + { + msp430_expand_helper (operands, "__mspabi_mpyl", false); + DONE; + } +) + ; libgcc helper functions for widening multiplication aren't currently ; generated by gcc, so we can't catch them later and map them to the mspabi ; functions. @@ -1733,9 +1755,7 @@ ; If we don't have hardware multiply support, it will generally be slower and ; result in larger code to call the mspabi library function to perform the ; widening multiplication than just leaving GCC to widen the arguments itself. -; -; We don't use library functions for SImode->DImode widening since its always -; larger and slower than letting GCC widen the arguments inline. + (define_expand "mulhisi3" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) @@ -1766,6 +1786,37 @@ } ) +(define_expand "mulsidi3" + [(set (match_operand:DI 0 "register_operand" "=r") + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] + "msp430_has_hwmult ()" + { + /* Leave the other case for the inline insn. */ + if (!(optimize > 2 && msp430_has_hwmult ())) + { + msp430_expand_helper (operands, "__mspabi_mpysll", false); + DONE; + } + } +) + +(define_expand "umulsidi3" + [(set (match_operand:DI 0 "register_operand" "=r") + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] + "msp430_has_hwmult ()" + { + /* Leave the other case for the inline insn. */ + if (!(optimize > 2 && msp430_has_hwmult ())) + { + msp430_expand_helper (operands, "__mspabi_mpyull", false); + DONE; + } + } +) + + (define_insn "*mulhisi3_inline" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) @@ -1794,7 +1845,7 @@ [(set_attr "length" "24")] ) -(define_insn "mulsidi3" +(define_insn "*mulsidi3_inline" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0")) (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] @@ -1808,7 +1859,7 @@ [(set_attr "length" "40")] ) -(define_insn "umulsidi3" +(define_insn "*umulsidi3_inline" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]