aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-06-07 12:09:04 +0930
committerAlan Modra <amodra@gmail.com>2014-06-07 14:55:11 +0930
commita47622ac1badbd906c7533ef6011b6bb021271ee (patch)
tree3e6ad4e4cb4ed80e652cf756cbbacf4a7a6ae3d1 /gas
parentd634c69f87e9b88a5ff5cd8af7a1f60e738ea0bd (diff)
downloadgdb-a47622ac1badbd906c7533ef6011b6bb021271ee.zip
gdb-a47622ac1badbd906c7533ef6011b6bb021271ee.tar.gz
gdb-a47622ac1badbd906c7533ef6011b6bb021271ee.tar.bz2
Allow both signed and unsigned fields in PowerPC cmpli insn
There are legitimate reasons to allow a signed value in a cmpli insn field, for example to test for a "stw r1,lock@sdarel(r13)" instruction in user code, a kernel might use subis r3,r3,STW_R1_0R13@ha # subtract off high part cmplwi r3,lock@sdarel # is low part accessing lock? Since the lock@sdarel may take a range of -32768 to 32767, the allowed range of cmpli immediate must be at least [-32768,65535]. bfd/ * elf32-ppc.c (ppc_elf_relocate_section): Treat field of cmpli insn as a bitfield; Use complain_overflow_bitfield. * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. opcodes/ * ppc-opc.c (UISIGNOPT): Define and use with cmpli. gas/ * config/tc-ppc.c (ppc_insert_operand): Handle PPC_OPERAND_SIGNOPT on unsigned fields. Comment on PPC_OPERAND_SIGNOPT signed fields in 64-bit mode. gold/ * powerpc.cc (relocate): Treat field of cmpli insn as a bitfield.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/tc-ppc.c19
2 files changed, 22 insertions, 3 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index f68f30c..fd331d7 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2014-06-07 Alan Modra <amodra@gmail.com>
+
+ * config/tc-ppc.c (ppc_insert_operand): Handle PPC_OPERAND_SIGNOPT
+ on unsigned fields. Comment on PPC_OPERAND_SIGNOPT signed fields
+ in 64-bit mode.
+
2014-06-02 Martin Storsjo <martin@martin.st>
* doc/c-aarch64.texi: Fix the documentation on :pg_hi21:.
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 2c8ce6a..ff4ea64 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -1781,10 +1781,23 @@ ppc_insert_operand (unsigned long insn,
right = max & -max;
min = 0;
- if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0)
+ {
+ /* Extend the allowed range for addis to [-65536, 65535].
+ Similarly for some VLE high part insns. For 64-bit it
+ would be good to disable this for signed fields since the
+ value is sign extended into the high 32 bits of the register.
+ If the value is, say, an address, then we might care about
+ the high bits. However, gcc as of 2014-06 uses unsigned
+ values when loading the high part of 64-bit constants using
+ lis.
+ Use the same extended range for cmpli, to allow at least
+ [-32768, 65535]. */
+ min = ~max & -right;
+ }
+ else if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
{
- if ((operand->flags & PPC_OPERAND_SIGNOPT) == 0)
- max = (max >> 1) & -right;
+ max = (max >> 1) & -right;
min = ~max & -right;
}