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