From: Nick Clifton Date: Thu, 15 Dec 2011 10:21:51 +0000 (+0000) Subject: * frv.opc (parse_uhi16): Fix handling of %hi operator on 64-bit X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5011093dd0015bc0eaff522b4e0a18250725d4b4;p=binutils-gdb.git * frv.opc (parse_uhi16): Fix handling of %hi operator on 64-bit hosts. * 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. * gas/frv/immediates.s: New test file - checks assembly of constant values. * gas/frv/immediates.d: Expected disassmbly. * gas/frv/allinsn.exp: Run the new test. --- diff --git a/cpu/ChangeLog b/cpu/ChangeLog index d04a554a715..1f5418714d8 100644 --- a/cpu/ChangeLog +++ b/cpu/ChangeLog @@ -1,3 +1,8 @@ +2011-12-15 Nick Clifton + + * frv.opc (parse_uhi16): Fix handling of %hi operator on 64-bit + hosts. + 2011-10-26 Joern Rennecke * epiphany.opc (parse_branch_addr): Fix type of valuep. diff --git a/cpu/frv.opc b/cpu/frv.opc index f81cef0d608..869155d67af 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 a73f01a73d8..865f430cd53 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 939d56a5b91..5fa43352656 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-12-15 Nick Clifton + + * 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 * 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 b6950aeb614..4796b8a33b0 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 00000000000..7ac8c40f35a --- /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 : + 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 00000000000..d3fe66805fd --- /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 ffe1002e330..413f3dc0d9d 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,9 @@ +2011-12-15 Nick Clifton + + * 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 * 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 f5fde408290..901a578f545 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 dffa059ec29..3da82616219 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;