From 499a39af5dd093a676a77e5694e185dea3a96121 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Wed, 30 Oct 2019 14:15:02 +0000 Subject: [PATCH] msp430.c (msp430_expand_helper): Support expansion of calls to __mspabi_mpy* functions. 2019-10-30 Jozef Lawrynowicz * config/msp430/msp430.c (msp430_expand_helper): Support expansion of calls to __mspabi_mpy* functions. * config/msp430/msp430.md (mulhisi3): New define_expand. (umulhisi3): New define_expand. (*mulhisi3_inline): Use old mulhisi3 define_insn. (*umulhisi3_inline): Use old umulhisi3 define_insn. From-SVN: r277624 --- gcc/ChangeLog | 9 +++++ gcc/config/msp430/msp430.c | 69 ++++++++++++++++++++++++++++++------- gcc/config/msp430/msp430.md | 46 +++++++++++++++++++++++-- 3 files changed, 110 insertions(+), 14 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b90915be66..70412cdb2f3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-10-30 Jozef Lawrynowicz + + * config/msp430/msp430.c (msp430_expand_helper): Support expansion of + calls to __mspabi_mpy* functions. + * config/msp430/msp430.md (mulhisi3): New define_expand. + (umulhisi3): New define_expand. + (*mulhisi3_inline): Use old mulhisi3 define_insn. + (*umulhisi3_inline): Use old umulhisi3 define_insn. + 2019-10-30 Jozef Lawrynowicz * config/msp430/msp430.c (msp430_check_index_not_high_mem): New. diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index a3d0d9cf64b..c058690e827 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -53,6 +53,7 @@ static void msp430_compute_frame_info (void); +static bool use_32bit_hwmult (void); @@ -2691,7 +2692,7 @@ void msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variants) { - rtx c, f; + rtx c, fusage, fsym; char *helper_const = NULL; int arg1 = 12; int arg2 = 13; @@ -2700,8 +2701,14 @@ msp430_expand_helper (rtx *operands, const char *helper_name, machine_mode arg1mode = GET_MODE (operands[1]); machine_mode arg2mode = GET_MODE (operands[2]); int have_430x = msp430x ? 1 : 0; + int expand_mpy = strncmp (helper_name, "__mspabi_mpy", + sizeof ("__mspabi_mpy") - 1) == 0; + /* This function has been used incorrectly if CONST_VARIANTS is TRUE for a + hwmpy function. */ + gcc_assert (!(expand_mpy && const_variants)); - if (CONST_INT_P (operands[2])) + /* Emit size-optimal insns for small shifts we can easily do inline. */ + if (CONST_INT_P (operands[2]) && !expand_mpy) { int i; @@ -2718,6 +2725,10 @@ msp430_expand_helper (rtx *operands, const char *helper_name, } } + if (arg1mode != VOIDmode && arg2mode != VOIDmode) + /* Modes of arguments must be equal if not constants. */ + gcc_assert (arg1mode == arg2mode); + if (arg1mode == VOIDmode) arg1mode = arg0mode; if (arg2mode == VOIDmode) @@ -2730,12 +2741,13 @@ msp430_expand_helper (rtx *operands, const char *helper_name, } else if (arg1mode == DImode) { - /* Shift value in R8:R11, shift amount in R12. */ arg1 = 8; arg1sz = 4; arg2 = 12; } + /* Use the "const_variant" of a shift library function if requested. + These are faster, but have larger code size. */ if (const_variants && CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 1 @@ -2749,25 +2761,58 @@ msp430_expand_helper (rtx *operands, const char *helper_name, (int) INTVAL (operands[2])); } + /* Setup the arguments to the helper function. */ emit_move_insn (gen_rtx_REG (arg1mode, arg1), operands[1]); if (!helper_const) emit_move_insn (gen_rtx_REG (arg2mode, arg2), operands[2]); - c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12), - gen_rtx_SYMBOL_REF (VOIDmode, helper_const - ? helper_const - : helper_name), - GEN_INT (0)); + if (expand_mpy) + { + if (msp430_use_f5_series_hwmult ()) + fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name, + "_f5hw", NULL)); + else if (use_32bit_hwmult ()) + { + /* When the arguments are 16-bits, the 16-bit hardware multiplier is + used. */ + if (arg1mode == HImode) + fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name, + "_hw", NULL)); + else + fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name, + "_hw32", NULL)); + } + /* 16-bit hardware multiply. */ + else if (msp430_has_hwmult ()) + fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name, + "_hw", NULL)); + else + fsym = gen_rtx_SYMBOL_REF (VOIDmode, helper_name); + } + else + fsym = gen_rtx_SYMBOL_REF (VOIDmode, + helper_const ? helper_const : helper_name); + + c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12), fsym, GEN_INT (0)); + c = emit_call_insn (c); RTL_CONST_CALL_P (c) = 1; - f = 0; - use_regs (&f, arg1, arg1sz); + /* Add register usage information for the arguments to the call. */ + fusage = NULL; + use_regs (&fusage, arg1, arg1sz); if (!helper_const) - use_regs (&f, arg2, 1); - add_function_usage_to (c, f); + { + /* If we are expanding a shift, we only need to use the low register + for the shift amount. */ + if (!expand_mpy) + use_regs (&fusage, arg2, 1); + else + use_regs (&fusage, arg2, arg1sz); + } + add_function_usage_to (c, fusage); emit_move_insn (operands[0], /* Return value will always start in R12. */ diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md index ed4c370261a..c3d85071a58 100644 --- a/gcc/config/msp430/msp430.md +++ b/gcc/config/msp430/msp430.md @@ -1642,7 +1642,49 @@ "NOP" ) -(define_insn "mulhisi3" +; 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. +; We catch the patterns here and either generate a call to the helper function, +; or emit the hardware multiply instruction sequence inline. +; +; 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")) + (sign_extend:SI (match_operand:HI 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_mpysl", false); + DONE; + } + } +) + +(define_expand "umulhisi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0")) + (zero_extend:SI (match_operand:HI 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_mpyul", 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")) (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] @@ -1655,7 +1697,7 @@ " ) -(define_insn "umulhisi3" +(define_insn "*umulhisi3_inline" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0")) (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))] -- 2.30.2