This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] frv: Handle out-of-range assembler constants on 64-bit hosts
- From: Segher Boessenkool <segher at kernel dot crashing dot org>
- To: binutils at sourceware dot org
- Cc: Segher Boessenkool <segher at kernel dot crashing dot org>
- Date: Tue, 9 Mar 2010 18:59:32 +0100
- Subject: [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