diff options
author | Alan Modra <amodra@gmail.com> | 2014-06-07 12:09:04 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2014-06-07 14:55:11 +0930 |
commit | a47622ac1badbd906c7533ef6011b6bb021271ee (patch) | |
tree | 3e6ad4e4cb4ed80e652cf756cbbacf4a7a6ae3d1 /gas/config/tc-ppc.c | |
parent | d634c69f87e9b88a5ff5cd8af7a1f60e738ea0bd (diff) | |
download | gdb-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/config/tc-ppc.c')
-rw-r--r-- | gas/config/tc-ppc.c | 19 |
1 files changed, 16 insertions, 3 deletions
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; } |