Blob Blame History Raw
commit a47622ac1badbd906c7533ef6011b6bb021271ee
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Jun 7 12:09:04 2014 +0930

    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.

### a/bfd/ChangeLog
### b/bfd/ChangeLog
## -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.
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -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)
--- 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)
 	    {
### a/opcodes/ChangeLog
### b/opcodes/ChangeLog
## -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
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -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}},