From a47622ac1badbd906c7533ef6011b6bb021271ee Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Sat, 7 Jun 2014 12:09:04 +0930
Subject: 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.
---
 bfd/elf64-ppc.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

(limited to 'bfd/elf64-ppc.c')

diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index e7e2e39..b8d7465 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -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)
 	    {
-- 
cgit v1.1