[PATCH] frv: Handle out-of-range assembler constants on 64-bit hosts
Segher Boessenkool
segher@kernel.crashing.org
Tue Mar 9 17:59:00 GMT 2010
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
More information about the Binutils
mailing list