Some areas of the MSP430 backend modify code generation based on whether the
target device has hardware multiply support. However comparisons of the form
"msp430_hwmult_type != MSP430_HWMULT_NONE" are invalid, since MSP430_HWMULT_AUTO
might be set (to infer hwmult support from the MCU specified with -mmcu), and
the target might still not have hardware multiply support.

This is causing hardware multiply instructions to be generated for 16-bit and
32-bit widening multiplication at -O3, when the target does not have hardware
multiply support. This results in incorrect execution.

This patch fixes that and replaces the msp430_no_hwmult() function with
msp430_has_hwmult(), since the former was only ever used as
"!msp430_no_hwmult()".

Regtested and applied on trunk as obvious.
>From c5edfbaf16a73b91faa30a8b4ce9204f0ff02d3e Mon Sep 17 00:00:00 2001
From: jozefl <jozefl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Wed, 23 Oct 2019 16:55:44 +0000
Subject: [PATCH] 2019-10-23  Jozef Lawrynowicz  <joze...@mittosystems.com>

	* config/msp430/msp430-protos.h (msp430_has_hwmult): New.
	* config/msp430/msp430.c (msp430_no_hwmult): Remove.
	(msp430_has_hwmult): New.
	(msp430_output_labelref):
	s/msp430_hwmult_type != MSP430_HWMULT_NONE/msp430_has_hwmult ()/
	* config/msp430/msp430.md (mulhisi3): Likewise.
	(umulhisi3): Likewise.
	(mulsidi3): Likewise.
	(umulsidi3): Likewise.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@277341 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                     | 12 ++++++++++++
 gcc/config/msp430/msp430-protos.h |  1 +
 gcc/config/msp430/msp430.c        | 22 ++++++++++++----------
 gcc/config/msp430/msp430.md       |  8 ++++----
 4 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ad2cb01d49a..7dc6885399c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2019-10-23  Jozef Lawrynowicz  <joze...@mittosystems.com>
+
+	* config/msp430/msp430-protos.h (msp430_has_hwmult): New.
+	* config/msp430/msp430.c (msp430_no_hwmult): Remove.
+	(msp430_has_hwmult): New.
+	(msp430_output_labelref):
+	s/msp430_hwmult_type != MSP430_HWMULT_NONE/msp430_has_hwmult ()/
+	* config/msp430/msp430.md (mulhisi3): Likewise.
+	(umulhisi3): Likewise.
+	(mulsidi3): Likewise.
+	(umulsidi3): Likewise.
+
 2019-10-23  Jan Hubicka  <hubi...@ucw.cz>
 
 	PR ipa/92074
diff --git a/gcc/config/msp430/msp430-protos.h b/gcc/config/msp430/msp430-protos.h
index 37ca48297ac..98470ef647e 100644
--- a/gcc/config/msp430/msp430-protos.h
+++ b/gcc/config/msp430/msp430-protos.h
@@ -48,6 +48,7 @@ int msp430_split_addsi (rtx *);
 void    msp430_start_function (FILE *, const char *, tree);
 rtx	msp430_subreg (machine_mode, rtx, machine_mode, int);
 bool    msp430_use_f5_series_hwmult (void);
+bool	msp430_has_hwmult (void);
 bool msp430_op_not_in_high_mem (rtx op);
 
 #endif /* GCC_MSP430_PROTOS_H */
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 31029395c3d..cd394333983 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -3097,20 +3097,22 @@ use_32bit_hwmult (void)
 /* Returns true if the current MCU does not have a
    hardware multiplier of any kind.  */
 
-static bool
-msp430_no_hwmult (void)
+bool
+msp430_has_hwmult (void)
 {
   static const char * cached_match = NULL;
   static bool cached_result;
 
   if (msp430_hwmult_type == MSP430_HWMULT_NONE)
-    return true;
+    return false;
 
+  /* TRUE for any other explicit hwmult specified.  */
   if (msp430_hwmult_type != MSP430_HWMULT_AUTO)
-    return false;
+    return true;
 
+  /* Now handle -mhwmult=auto.  */
   if (target_mcu == NULL)
-    return true;
+    return false;
 
   if (target_mcu == cached_match)
     return cached_result;
@@ -3119,11 +3121,11 @@ msp430_no_hwmult (void)
 
   msp430_extract_mcu_data (target_mcu);
   if (extracted_mcu_data.name != NULL)
-    return cached_result = extracted_mcu_data.hwmpy == 0;
+    return cached_result = extracted_mcu_data.hwmpy != 0;
 
   /* If we do not recognise the MCU name, we assume that it does not support
      any kind of hardware multiply - this is the safest assumption to make.  */
-  return cached_result = true;
+  return cached_result = false;
 }
 
 /* This function does the same as the default, but it will replace GCC
@@ -3143,13 +3145,13 @@ msp430_output_labelref (FILE *file, const char *name)
 
   /* If we have been given a specific MCU name then we may be
      able to make use of its hardware multiply capabilities.  */
-  if (msp430_hwmult_type != MSP430_HWMULT_NONE)
+  if (msp430_has_hwmult ())
     {
       if (strcmp ("__mspabi_mpyi", name) == 0)
 	{
 	  if (msp430_use_f5_series_hwmult ())
 	    name = "__mulhi2_f5";
-	  else if (! msp430_no_hwmult ())
+	  else
 	    name = "__mulhi2";
 	}
       else if (strcmp ("__mspabi_mpyl", name) == 0)
@@ -3158,7 +3160,7 @@ msp430_output_labelref (FILE *file, const char *name)
 	    name = "__mulsi2_f5";
 	  else if (use_32bit_hwmult ())
 	    name = "__mulsi2_hw32";
-	  else if (! msp430_no_hwmult ())
+	  else
 	    name = "__mulsi2";
 	}
     }
diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md
index da4abe94031..e5ba445c60d 100644
--- a/gcc/config/msp430/msp430.md
+++ b/gcc/config/msp430/msp430.md
@@ -1642,7 +1642,7 @@
   [(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"))))]
-  "optimize > 2 && msp430_hwmult_type != MSP430_HWMULT_NONE"
+  "optimize > 2 && msp430_has_hwmult ()"
   "*
     if (msp430_use_f5_series_hwmult ())
       return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x04C2 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\";
@@ -1655,7 +1655,7 @@
   [(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"))))]
-  "optimize > 2 && msp430_hwmult_type != MSP430_HWMULT_NONE"
+  "optimize > 2 && msp430_has_hwmult ()"
   "*
     if (msp430_use_f5_series_hwmult ())
       return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x04C0 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\";
@@ -1668,7 +1668,7 @@
   [(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"))))]
-  "optimize > 2 && msp430_hwmult_type != MSP430_HWMULT_NONE"
+  "optimize > 2 && msp430_has_hwmult ()"
   "*
     if (msp430_use_f5_series_hwmult ())
       return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x04D4 { MOV.W %H1, &0x04D6 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\";
@@ -1681,7 +1681,7 @@
   [(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"))))]
-  "optimize > 2 && msp430_hwmult_type != MSP430_HWMULT_NONE"
+  "optimize > 2 && msp430_has_hwmult ()"
   "*
     if (msp430_use_f5_series_hwmult ())
       return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x04D0 { MOV.W %H1, &0x04D2 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\";
-- 
2.17.1

Reply via email to