a094f6
commit a47622ac1badbd906c7533ef6011b6bb021271ee
a094f6
Author: Alan Modra <amodra@gmail.com>
a094f6
Date:   Sat Jun 7 12:09:04 2014 +0930
a094f6
a094f6
    Allow both signed and unsigned fields in PowerPC cmpli insn
a094f6
    
a094f6
    There are legitimate reasons to allow a signed value in a cmpli insn
a094f6
    field, for example to test for a "stw r1,lock@sdarel(r13)" instruction
a094f6
    in user code, a kernel might use
a094f6
            subis r3,r3,STW_R1_0R13@ha      # subtract off high part
a094f6
            cmplwi r3,lock@sdarel           # is low part accessing lock?
a094f6
    Since the lock@sdarel may take a range of -32768 to 32767,
a094f6
    the allowed range of cmpli immediate must be at least [-32768,65535].
a094f6
    
a094f6
    bfd/
a094f6
            * elf32-ppc.c (ppc_elf_relocate_section): Treat field of cmpli
a094f6
            insn as a bitfield; Use complain_overflow_bitfield.
a094f6
            * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
a094f6
    opcodes/
a094f6
            * ppc-opc.c (UISIGNOPT): Define and use with cmpli.
a094f6
    gas/
a094f6
            * config/tc-ppc.c (ppc_insert_operand): Handle PPC_OPERAND_SIGNOPT
a094f6
            on unsigned fields.  Comment on PPC_OPERAND_SIGNOPT signed fields
a094f6
            in 64-bit mode.
a094f6
    gold/
a094f6
            * powerpc.cc (relocate): Treat field of cmpli insn as a bitfield.
a094f6
a094f6
### a/bfd/ChangeLog
a094f6
### b/bfd/ChangeLog
a094f6
## -1,3 +1,9 @@
a094f6
+2014-06-07  Alan Modra  <amodra@gmail.com>
a094f6
+
a094f6
+	* elf32-ppc.c (ppc_elf_relocate_section): Treat field of cmpli
a094f6
+	insn as a bitfield; Use complain_overflow_bitfield.
a094f6
+	* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
a094f6
+
a094f6
 2014-06-05  Joel Brobecker  <brobecker@adacore.com>
a094f6
 
a094f6
 	* development.sh: New file.
a094f6
--- a/bfd/elf32-ppc.c
a094f6
+++ b/bfd/elf32-ppc.c
a094f6
@@ -9147,10 +9147,11 @@ ppc_elf_relocate_section (bfd *output_bfd,
a094f6
 	      unsigned int insn;
a094f6
 
a094f6
 	      insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
a094f6
-	      if ((insn & (0x3f << 26)) == 28u << 26 /* andi */
a094f6
-		  || (insn & (0x3f << 26)) == 24u << 26 /* ori */
a094f6
-		  || (insn & (0x3f << 26)) == 26u << 26 /* xori */
a094f6
-		  || (insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
a094f6
+	      if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
a094f6
+		complain = complain_overflow_bitfield;
a094f6
+	      else if ((insn & (0x3f << 26)) == 28u << 26 /* andi */
a094f6
+		       || (insn & (0x3f << 26)) == 24u << 26 /* ori */
a094f6
+		       || (insn & (0x3f << 26)) == 26u << 26 /* xori */)
a094f6
 		complain = complain_overflow_unsigned;
a094f6
 	    }
a094f6
 	  if (howto->complain_on_overflow != complain)
a094f6
--- a/bfd/elf64-ppc.c
a094f6
+++ b/bfd/elf64-ppc.c
a094f6
@@ -14648,14 +14648,15 @@ ppc64_elf_relocate_section (bfd *output_bfd,
a094f6
 	  enum complain_overflow complain = complain_overflow_signed;
a094f6
 
a094f6
 	  insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
a094f6
-	  if (howto->rightshift == 0
a094f6
-	      ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */
a094f6
-		 || (insn & (0x3f << 26)) == 24u << 26 /* ori */
a094f6
-		 || (insn & (0x3f << 26)) == 26u << 26 /* xori */
a094f6
-		 || (insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
a094f6
-	      : ((insn & (0x3f << 26)) == 29u << 26 /* andis */
a094f6
-		 || (insn & (0x3f << 26)) == 25u << 26 /* oris */
a094f6
-		 || (insn & (0x3f << 26)) == 27u << 26 /* xoris */))
a094f6
+	  if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
a094f6
+	    complain = complain_overflow_bitfield;
a094f6
+	  else if (howto->rightshift == 0
a094f6
+		   ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */
a094f6
+		      || (insn & (0x3f << 26)) == 24u << 26 /* ori */
a094f6
+		      || (insn & (0x3f << 26)) == 26u << 26 /* xori */)
a094f6
+		   : ((insn & (0x3f << 26)) == 29u << 26 /* andis */
a094f6
+		      || (insn & (0x3f << 26)) == 25u << 26 /* oris */
a094f6
+		      || (insn & (0x3f << 26)) == 27u << 26 /* xoris */))
a094f6
 	    complain = complain_overflow_unsigned;
a094f6
 	  if (howto->complain_on_overflow != complain)
a094f6
 	    {
a094f6
### a/opcodes/ChangeLog
a094f6
### b/opcodes/ChangeLog
a094f6
## -1,3 +1,7 @@
a094f6
+2014-06-07  Alan Modra  <amodra@gmail.com>
a094f6
+
a094f6
+	* ppc-opc.c (UISIGNOPT): Define and use with cmpli.
a094f6
+
a094f6
 2014-06-05  Joel Brobecker  <brobecker@adacore.com>
a094f6
 
a094f6
 	* Makefile.am (CONFIG_STATUS_DEPENDENCIES): Add dependency on
a094f6
--- a/opcodes/ppc-opc.c
a094f6
+++ b/opcodes/ppc-opc.c
a094f6
@@ -654,8 +654,11 @@ const struct powerpc_operand powerpc_operands[] =
a094f6
 #define UI TO + 1
a094f6
   { 0xffff, 0, NULL, NULL, 0 },
a094f6
 
a094f6
+#define UISIGNOPT UI + 1
a094f6
+  { 0xffff, 0, NULL, NULL, PPC_OPERAND_SIGNOPT },
a094f6
+
a094f6
   /* The IMM field in an SE_IM5 instruction.  */
a094f6
-#define UI5 UI + 1
a094f6
+#define UI5 UISIGNOPT + 1
a094f6
   { 0x1f, 4, NULL, NULL, 0 },
a094f6
 
a094f6
   /* The OIMM field in an SE_OIM5 instruction.  */
a094f6
@@ -3500,10 +3503,10 @@ const struct powerpc_opcode powerpc_opcodes[] = {
a094f6
 
a094f6
 {"dozi",	OP(9),		OP_MASK,     M601,	PPCNONE,	{RT, RA, SI}},
a094f6
 
a094f6
-{"cmplwi",	OPL(10,0),	OPL_MASK,    PPCCOM,	PPCNONE,	{OBF, RA, UI}},
a094f6
-{"cmpldi",	OPL(10,1),	OPL_MASK,    PPC64,	PPCNONE,	{OBF, RA, UI}},
a094f6
-{"cmpli",	OP(10),		OP_MASK,     PPC,	PPCNONE,	{BF, L, RA, UI}},
a094f6
-{"cmpli",	OP(10),		OP_MASK,     PWRCOM,	PPC,		{BF, RA, UI}},
a094f6
+{"cmplwi",	OPL(10,0),	OPL_MASK,    PPCCOM,	PPCNONE,	{OBF, RA, UISIGNOPT}},
a094f6
+{"cmpldi",	OPL(10,1),	OPL_MASK,    PPC64,	PPCNONE,	{OBF, RA, UISIGNOPT}},
a094f6
+{"cmpli",	OP(10),		OP_MASK,     PPC,	PPCNONE,	{BF, L, RA, UISIGNOPT}},
a094f6
+{"cmpli",	OP(10),		OP_MASK,     PWRCOM,	PPC,		{BF, RA, UISIGNOPT}},
a094f6
 
a094f6
 {"cmpwi",	OPL(11,0),	OPL_MASK,    PPCCOM,	PPCNONE,	{OBF, RA, SI}},
a094f6
 {"cmpdi",	OPL(11,1),	OPL_MASK,    PPC64,	PPCNONE,	{OBF, RA, SI}},