GCC generates better code when multiplication operations, which require
library functions to perform, are caught in early in RTL, rather than
leaving the operation to be mapped to a library function later on.

When there is hardware multiply support, it is more efficient to perform
widening multiplication using the hardware multiplier instead of letting
GCC widen the arguments before calling the multiplication routine in the
wider mode.

Successfully regtested GCC and G++ testsuites for:
    msp430-sim
    msp430-sim/-mcpu=msp430
    msp430-sim/-mhwmult=f5series
    
msp430-sim/-mhwmult=f5series/-mlarge/-mdata-region=either/-mcode-region=either
    msp430-sim/-mlarge
    msp430-sim/-mlarge/-mdata-region=either/-mcode-region=either

Additionally regtested GCC execute.exp for:
    msp430-sim/-mhwmult=16bit
    msp430-sim/-mhwmult=32bit
    msp430-sim/-mhwmult=f5series
    msp430-sim/-mhwmult=none
    msp430-sim/-mlarge/-mcode-region=either/-mdata-region=either/-mhwmult=16bit
    msp430-sim/-mlarge/-mcode-region=either/-mdata-region=either/-mhwmult=32bit
    
msp430-sim/-mlarge/-mcode-region=either/-mdata-region=either/-mhwmult=f5series
    msp430-sim/-mlarge/-mcode-region=either/-mdata-region=either/-mhwmult=none

Ok for trunk?
>From 2f9bbb5dde866627c0dc321ec102ba3ef73d591c Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <joze...@mittosystems.com>
Date: Sun, 15 Nov 2020 21:03:10 +0000
Subject: [PATCH 1/2] MSP430: Add mulhi, mulsi and {u,}mulsidi3 expanders

GCC generates better code when multiplication operations, which require
library functions to perform, are caught in early in RTL, rather than
leaving the operation to be mapped to a library function later on.

When there is hardware multiply support, it is more efficient to perform
widening multiplication using the hardware multiplier instead of letting
GCC widen the arguments before calling the multiplication routine in the
wider mode.

gcc/ChangeLog:

        * config/msp430/msp430.md (mulhi3): New.
        (mulsi3): New.
        (mulsidi3): Rename to *mulsidi3_inline.
        (umulsidi3): Rename to *umulsidi3_inline.
        (mulsidi3): New define_expand.
        (umulsidi3): New define_expand.
---
 gcc/config/msp430/msp430.md | 61 ++++++++++++++++++++++++++++++++++---
 1 file changed, 56 insertions(+), 5 deletions(-)

diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md
index 65e951774b1..714cd84a095 100644
--- a/gcc/config/msp430/msp430.md
+++ b/gcc/config/msp430/msp430.md
@@ -1724,6 +1724,28 @@ (define_insn "delay_cycles_1"
   [(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 @@ (define_insn "delay_cycles_1"
 ; 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 "umulhisi3"
   }
 )
 
+(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 @@ (define_insn "*umulhisi3_inline"
   [(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 @@ (define_insn "mulsidi3"
   [(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"))))]
-- 
2.29.2

Reply via email to