summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpu/ChangeLog5
-rw-r--r--cpu/frv.opc10
-rw-r--r--gas/config/tc-arm.c11
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/frv/allinsn.exp2
-rw-r--r--gas/testsuite/gas/frv/immediates.d12
-rw-r--r--gas/testsuite/gas/frv/immediates.s9
-rw-r--r--opcodes/ChangeLog6
-rw-r--r--opcodes/cgen-asm.c22
-rw-r--r--opcodes/frv-asm.c10
10 files changed, 78 insertions, 16 deletions
diff --git a/cpu/ChangeLog b/cpu/ChangeLog
index d04a554a71..1f5418714d 100644
--- a/cpu/ChangeLog
+++ b/cpu/ChangeLog
@@ -1,3 +1,8 @@
+2011-12-15 Nick Clifton <nickc@redhat.com>
+
+ * frv.opc (parse_uhi16): Fix handling of %hi operator on 64-bit
+ hosts.
+
2011-10-26 Joern Rennecke <joern.rennecke@embecosm.com>
* epiphany.opc (parse_branch_addr): Fix type of valuep.
diff --git a/cpu/frv.opc b/cpu/frv.opc
index f81cef0d60..869155d67a 100644
--- a/cpu/frv.opc
+++ b/cpu/frv.opc
@@ -1343,11 +1343,11 @@ parse_uhi16 (CGEN_CPU_DESC cd,
if (errmsg == NULL
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
{
- /* If bfd_vma is wider than 32 bits, but we have a sign-
- or zero-extension, truncate it. */
- if (value >= - ((bfd_vma)1 << 31)
- || value <= ((bfd_vma)1 << 31) - (bfd_vma)1)
- value &= (((bfd_vma)1 << 16) << 16) - 1;
+ /* If value is wider than 32 bits then be
+ careful about how we extract bits 16-31. */
+ if (sizeof (value) > 4)
+ value &= (((bfd_vma)1 << 16) << 16) - 1;
+
value >>= 16;
}
*valuep = value;
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index a73f01a73d..865f430cd5 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -3540,6 +3540,7 @@ s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
record_alignment (now_seg, 2);
ptr = frag_more (8);
+ memset (ptr, 0, 8);
where = frag_now_fix () - 8;
/* Self relative offset of the function start. */
@@ -19926,8 +19927,12 @@ create_unwind_entry (int have_data)
size = unwind.opcode_count - 2;
}
else
- /* An extra byte is required for the opcode count. */
- size = unwind.opcode_count + 1;
+ {
+ gas_assert (unwind.personality_index == -1);
+
+ /* An extra byte is required for the opcode count. */
+ size = unwind.opcode_count + 1;
+ }
size = (size + 3) >> 2;
if (size > 0xff)
@@ -19953,7 +19958,7 @@ create_unwind_entry (int have_data)
ptr += 4;
/* Set the first byte to the number of additional words. */
- data = size - 1;
+ data = size > 0 ? size - 1 : 0;
n = 3;
break;
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 939d56a5b9..5fa4335265 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2011-12-15 Nick Clifton <nickc@redhat.com>
+
+ * gas/frv/immediates.s: New test file - checks assembly of
+ constant values.
+ * gas/frv/immediates.d: Expected disassembly.
+ * gas/frv/allinsn.exp: Run the new test.
+
2011-12-14 Stuart Henderson <shenders@gcc.gnu.org>
* gas/bfin/move.d: Update SRCx field expectations.
diff --git a/gas/testsuite/gas/frv/allinsn.exp b/gas/testsuite/gas/frv/allinsn.exp
index b6950aeb61..4796b8a33b 100644
--- a/gas/testsuite/gas/frv/allinsn.exp
+++ b/gas/testsuite/gas/frv/allinsn.exp
@@ -17,4 +17,6 @@ if [istarget frv*-*-*] {
run_list_test "fr450-media-issue" "-mcpu=fr450"
run_dump_test "fr550-pack1"
+
+ run_dump_test "immediates"
}
diff --git a/gas/testsuite/gas/frv/immediates.d b/gas/testsuite/gas/frv/immediates.d
new file mode 100644
index 0000000000..7ac8c40f35
--- /dev/null
+++ b/gas/testsuite/gas/frv/immediates.d
@@ -0,0 +1,12 @@
+#as:
+#objdump: -d
+#name: Parsing immediate values
+
+.*: +file format .*
+
+Disassembly of section \.text:
+
+00000000 <foo>:
+ 0:[ ]+86 fc e0 00[ ]+setlos 0xff+e000,gr3
+ 4:[ ]+08 f8 3f ff[ ]+sethi.p 0x3fff,gr4
+
diff --git a/gas/testsuite/gas/frv/immediates.s b/gas/testsuite/gas/frv/immediates.s
new file mode 100644
index 0000000000..d3fe66805f
--- /dev/null
+++ b/gas/testsuite/gas/frv/immediates.s
@@ -0,0 +1,9 @@
+ ;; These instructions can be found in the FRV Linux kernel.
+ ;; They used to fail to assemble on 64-bit host machines
+ ;; because of sign-extension problems.
+
+ .text
+ .global foo
+foo:
+ setlos #0xffffe000, gr3
+ sethi.p %hi(~(0x80000000 | 0x40000000)), gr4
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index ffe1002e33..413f3dc0d9 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,9 @@
+2011-12-15 Nick Clifton <nickc@redhat.com>
+
+ * cgen-asm.c (cgen_parse_signed_integer): Add code to handle the
+ sign extension of negative values on a 64-bit host.
+ * frv-asm.c: Regenerate.
+
2011-12-13 Alan Modra <amodra@gmail.com>
* ppc-opc.c (ISA_V2): Define and use for relevant BO field tests.
diff --git a/opcodes/cgen-asm.c b/opcodes/cgen-asm.c
index f5fde40829..901a578f54 100644
--- a/opcodes/cgen-asm.c
+++ b/opcodes/cgen-asm.c
@@ -1,6 +1,6 @@
/* CGEN generic assembler support code.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007,
+ 2011 Free Software Foundation, Inc.
This file is part of libopcodes.
@@ -268,7 +268,23 @@ cgen_parse_signed_integer (CGEN_CPU_DESC cd,
&result, &value);
/* FIXME: Examine `result'. */
if (!errmsg)
- *valuep = value;
+ {
+ /* Handle the case where a hex value is parsed on a 64-bit host.
+ A value like 0xffffe000 is clearly intended to be a negative
+ 16-bit value, but on a 64-bit host it will be parsed by gas
+ as 0x00000000ffffe000.
+
+ The shifts below are designed not to produce compile time
+ warnings on a 32-bit host. */
+ if (sizeof (value) > 4
+ && result == CGEN_PARSE_OPERAND_RESULT_NUMBER
+ && value > 0
+ && (value & 0x80000000)
+ && ((value >> 31) == 1))
+ value |= -1 << 31;
+
+ *valuep = value;
+ }
return errmsg;
}
diff --git a/opcodes/frv-asm.c b/opcodes/frv-asm.c
index dffa059ec2..3da8261621 100644
--- a/opcodes/frv-asm.c
+++ b/opcodes/frv-asm.c
@@ -465,11 +465,11 @@ parse_uhi16 (CGEN_CPU_DESC cd,
if (errmsg == NULL
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
{
- /* If bfd_vma is wider than 32 bits, but we have a sign-
- or zero-extension, truncate it. */
- if (value >= - ((bfd_vma)1 << 31)
- || value <= ((bfd_vma)1 << 31) - (bfd_vma)1)
- value &= (((bfd_vma)1 << 16) << 16) - 1;
+ /* If value is wider than 32 bits then be
+ careful about how we extract bits 16-31. */
+ if (sizeof (value) > 4)
+ value &= (((bfd_vma)1 << 16) << 16) - 1;
+
value >>= 16;
}
*valuep = value;