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.
This commit is contained in:
parent
d634c69f87
commit
a47622ac1b
9 changed files with 67 additions and 28 deletions
|
@ -1,3 +1,9 @@
|
|||
2014-06-07 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2014-06-05 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* development.sh: New file.
|
||||
|
|
|
@ -9147,10 +9147,11 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
unsigned int insn;
|
||||
|
||||
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
|
||||
if ((insn & (0x3f << 26)) == 28u << 26 /* andi */
|
||||
|| (insn & (0x3f << 26)) == 24u << 26 /* ori */
|
||||
|| (insn & (0x3f << 26)) == 26u << 26 /* xori */
|
||||
|| (insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
|
||||
if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
|
||||
complain = complain_overflow_bitfield;
|
||||
else if ((insn & (0x3f << 26)) == 28u << 26 /* andi */
|
||||
|| (insn & (0x3f << 26)) == 24u << 26 /* ori */
|
||||
|| (insn & (0x3f << 26)) == 26u << 26 /* xori */)
|
||||
complain = complain_overflow_unsigned;
|
||||
}
|
||||
if (howto->complain_on_overflow != complain)
|
||||
|
|
|
@ -14648,14 +14648,15 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
enum complain_overflow complain = complain_overflow_signed;
|
||||
|
||||
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
|
||||
if (howto->rightshift == 0
|
||||
? ((insn & (0x3f << 26)) == 28u << 26 /* andi */
|
||||
|| (insn & (0x3f << 26)) == 24u << 26 /* ori */
|
||||
|| (insn & (0x3f << 26)) == 26u << 26 /* xori */
|
||||
|| (insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
|
||||
: ((insn & (0x3f << 26)) == 29u << 26 /* andis */
|
||||
|| (insn & (0x3f << 26)) == 25u << 26 /* oris */
|
||||
|| (insn & (0x3f << 26)) == 27u << 26 /* xoris */))
|
||||
if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
|
||||
complain = complain_overflow_bitfield;
|
||||
else if (howto->rightshift == 0
|
||||
? ((insn & (0x3f << 26)) == 28u << 26 /* andi */
|
||||
|| (insn & (0x3f << 26)) == 24u << 26 /* ori */
|
||||
|| (insn & (0x3f << 26)) == 26u << 26 /* xori */)
|
||||
: ((insn & (0x3f << 26)) == 29u << 26 /* andis */
|
||||
|| (insn & (0x3f << 26)) == 25u << 26 /* oris */
|
||||
|| (insn & (0x3f << 26)) == 27u << 26 /* xoris */))
|
||||
complain = complain_overflow_unsigned;
|
||||
if (howto->complain_on_overflow != complain)
|
||||
{
|
||||
|
|
|
@ -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:.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
if ((operand->flags & PPC_OPERAND_SIGNOPT) == 0)
|
||||
max = (max >> 1) & -right;
|
||||
/* 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)
|
||||
{
|
||||
max = (max >> 1) & -right;
|
||||
min = ~max & -right;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2014-06-07 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* powerpc.cc (relocate): Treat field of cmpli insn as a bitfield.
|
||||
|
||||
2014-06-06 Cary Coutant <ccoutant@google.com>
|
||||
|
||||
* dwarf_reader.h (Dwarf_pubnames_table): Remove output_section_offset_.
|
||||
|
|
|
@ -7409,14 +7409,15 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|||
Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
|
||||
|
||||
overflow = Reloc::CHECK_SIGNED;
|
||||
if (overflow == Reloc::CHECK_LOW_INSN
|
||||
? ((insn & (0x3f << 26)) == 28u << 26 /* andi */
|
||||
|| (insn & (0x3f << 26)) == 24u << 26 /* ori */
|
||||
|| (insn & (0x3f << 26)) == 26u << 26 /* xori */
|
||||
|| (insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
|
||||
: ((insn & (0x3f << 26)) == 29u << 26 /* andis */
|
||||
|| (insn & (0x3f << 26)) == 25u << 26 /* oris */
|
||||
|| (insn & (0x3f << 26)) == 27u << 26 /* xoris */))
|
||||
if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
|
||||
overflow = Reloc::CHECK_BITFIELD;
|
||||
else if (overflow == Reloc::CHECK_LOW_INSN
|
||||
? ((insn & (0x3f << 26)) == 28u << 26 /* andi */
|
||||
|| (insn & (0x3f << 26)) == 24u << 26 /* ori */
|
||||
|| (insn & (0x3f << 26)) == 26u << 26 /* xori */)
|
||||
: ((insn & (0x3f << 26)) == 29u << 26 /* andis */
|
||||
|| (insn & (0x3f << 26)) == 25u << 26 /* oris */
|
||||
|| (insn & (0x3f << 26)) == 27u << 26 /* xoris */))
|
||||
overflow = Reloc::CHECK_UNSIGNED;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2014-06-07 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* ppc-opc.c (UISIGNOPT): Define and use with cmpli.
|
||||
|
||||
2014-06-05 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* Makefile.am (CONFIG_STATUS_DEPENDENCIES): Add dependency on
|
||||
|
|
|
@ -654,8 +654,11 @@ const struct powerpc_operand powerpc_operands[] =
|
|||
#define UI TO + 1
|
||||
{ 0xffff, 0, NULL, NULL, 0 },
|
||||
|
||||
#define UISIGNOPT UI + 1
|
||||
{ 0xffff, 0, NULL, NULL, PPC_OPERAND_SIGNOPT },
|
||||
|
||||
/* The IMM field in an SE_IM5 instruction. */
|
||||
#define UI5 UI + 1
|
||||
#define UI5 UISIGNOPT + 1
|
||||
{ 0x1f, 4, NULL, NULL, 0 },
|
||||
|
||||
/* The OIMM field in an SE_OIM5 instruction. */
|
||||
|
@ -3500,10 +3503,10 @@ const struct powerpc_opcode powerpc_opcodes[] = {
|
|||
|
||||
{"dozi", OP(9), OP_MASK, M601, PPCNONE, {RT, RA, SI}},
|
||||
|
||||
{"cmplwi", OPL(10,0), OPL_MASK, PPCCOM, PPCNONE, {OBF, RA, UI}},
|
||||
{"cmpldi", OPL(10,1), OPL_MASK, PPC64, PPCNONE, {OBF, RA, UI}},
|
||||
{"cmpli", OP(10), OP_MASK, PPC, PPCNONE, {BF, L, RA, UI}},
|
||||
{"cmpli", OP(10), OP_MASK, PWRCOM, PPC, {BF, RA, UI}},
|
||||
{"cmplwi", OPL(10,0), OPL_MASK, PPCCOM, PPCNONE, {OBF, RA, UISIGNOPT}},
|
||||
{"cmpldi", OPL(10,1), OPL_MASK, PPC64, PPCNONE, {OBF, RA, UISIGNOPT}},
|
||||
{"cmpli", OP(10), OP_MASK, PPC, PPCNONE, {BF, L, RA, UISIGNOPT}},
|
||||
{"cmpli", OP(10), OP_MASK, PWRCOM, PPC, {BF, RA, UISIGNOPT}},
|
||||
|
||||
{"cmpwi", OPL(11,0), OPL_MASK, PPCCOM, PPCNONE, {OBF, RA, SI}},
|
||||
{"cmpdi", OPL(11,1), OPL_MASK, PPC64, PPCNONE, {OBF, RA, SI}},
|
||||
|
|
Loading…
Reference in a new issue