This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] frv: Handle out-of-range assembler constants on 64-bit hosts


Tested on x86_64-linux cross to frv-elf, no new failures.  Okay to apply?


Segher
---
 opcodes/frv-ibld.c |   26 ++++++++++++++++++++++----
 1 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/opcodes/frv-ibld.c b/opcodes/frv-ibld.c
index 61db1bf..8e86457 100644
--- a/opcodes/frv-ibld.c
+++ b/opcodes/frv-ibld.c
@@ -175,8 +175,9 @@ insert_normal (CGEN_CPU_DESC cd,
 	 extended beyond 32 bits.  If so then ignore these higher sign bits
 	 as the user is attempting to store a 32-bit signed value into an
 	 unsigned 32-bit field which is allowed.  */
-      if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
-	val &= 0xFFFFFFFF;
+      /* We also need to handle this for fields smaller than 32 bits.  */
+      if (sizeof (unsigned long) > 4 && ((value << (32 - length) >> 32) == -1))
+	val &= mask;
 
       if (val > maxval)
 	{
@@ -193,8 +194,25 @@ insert_normal (CGEN_CPU_DESC cd,
 	{
 	  long minval = - (1L << (length - 1));
 	  long maxval =   (1L << (length - 1)) - 1;
-	  
-	  if (value < minval || value > maxval)
+
+	  /* Some people write constants with the sign extension done by
+	     hand but only up to 32 bits.  This shouldn't really be valid,
+	     but, to permit this code to assemble on a 64-bit host, we
+	     sign extend the 32-bit value to 64 bits if so doing makes the
+	     value valid.  */
+	  if (value > maxval
+	      && (value - 0x80000000 - 0x80000000) >= minval
+	      && (value - 0x80000000 - 0x80000000) <= maxval)
+	    value = value - 0x80000000 - 0x80000000;
+
+	  /* Similarly, people write expressions like ~(1<<15), and expect
+	     this to be OK for a 32-bit unsigned value.  */
+	  else if (value < minval
+		   && (value + 0x80000000 + 0x80000000) >= minval
+		   && (value + 0x80000000 + 0x80000000) <= maxval)
+	    value = value + 0x80000000 + 0x80000000;
+
+	  else if (value < minval || value > maxval)
 	    {
 	      sprintf
 		/* xgettext:c-format */
-- 
1.6.5.2.154.g549c


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]