Blob Blame History Raw
diff -Nrup a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
--- a/gas/config/tc-ppc.c	2015-05-07 09:21:42.738374151 -0600
+++ b/gas/config/tc-ppc.c	2015-05-07 14:58:51.607894208 -0600
@@ -3143,103 +3143,6 @@ md_assemble (char *str)
 		      break;
 		    }
 		}
-
-	      /* For the absolute forms of branches, convert the PC
-		 relative form back into the absolute.  */
-	      if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
-		{
-		  switch (reloc)
-		    {
-		    case BFD_RELOC_PPC_B26:
-		      reloc = BFD_RELOC_PPC_BA26;
-		      break;
-		    case BFD_RELOC_PPC_B16:
-		      reloc = BFD_RELOC_PPC_BA16;
-		      break;
-		    case BFD_RELOC_PPC_B16_BRTAKEN:
-		      reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
-		      break;
-		    case BFD_RELOC_PPC_B16_BRNTAKEN:
-		      reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
-		      break;
-		    default:
-		      break;
-		    }
-		}
-
-	      switch (reloc)
-		{
-		case BFD_RELOC_PPC_TOC16:
-		  toc_reloc_types |= has_small_toc_reloc;
-		  break;
-		case BFD_RELOC_PPC64_TOC16_LO:
-		case BFD_RELOC_PPC64_TOC16_HI:
-		case BFD_RELOC_PPC64_TOC16_HA:
-		  toc_reloc_types |= has_large_toc_reloc;
-		  break;
-		default:
-		  break;
-		}
-
-	      if ((operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
-		{
-		  switch (reloc)
-		    {
-		    case BFD_RELOC_16:
-		      reloc = BFD_RELOC_PPC64_ADDR16_DS;
-		      break;
-		    case BFD_RELOC_LO16:
-		      reloc = BFD_RELOC_PPC64_ADDR16_LO_DS;
-		      break;
-		    case BFD_RELOC_16_GOTOFF:
-		      reloc = BFD_RELOC_PPC64_GOT16_DS;
-		      break;
-		    case BFD_RELOC_LO16_GOTOFF:
-		      reloc = BFD_RELOC_PPC64_GOT16_LO_DS;
-		      break;
-		    case BFD_RELOC_LO16_PLTOFF:
-		      reloc = BFD_RELOC_PPC64_PLT16_LO_DS;
-		      break;
-		    case BFD_RELOC_16_BASEREL:
-		      reloc = BFD_RELOC_PPC64_SECTOFF_DS;
-		      break;
-		    case BFD_RELOC_LO16_BASEREL:
-		      reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS;
-		      break;
-		    case BFD_RELOC_PPC_TOC16:
-		      reloc = BFD_RELOC_PPC64_TOC16_DS;
-		      break;
-		    case BFD_RELOC_PPC64_TOC16_LO:
-		      reloc = BFD_RELOC_PPC64_TOC16_LO_DS;
-		      break;
-		    case BFD_RELOC_PPC64_PLTGOT16:
-		      reloc = BFD_RELOC_PPC64_PLTGOT16_DS;
-		      break;
-		    case BFD_RELOC_PPC64_PLTGOT16_LO:
-		      reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS;
-		      break;
-		    case BFD_RELOC_PPC_DTPREL16:
-		      reloc = BFD_RELOC_PPC64_DTPREL16_DS;
-		      break;
-		    case BFD_RELOC_PPC_DTPREL16_LO:
-		      reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS;
-		      break;
-		    case BFD_RELOC_PPC_TPREL16:
-		      reloc = BFD_RELOC_PPC64_TPREL16_DS;
-		      break;
-		    case BFD_RELOC_PPC_TPREL16_LO:
-		      reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
-		      break;
-		    case BFD_RELOC_PPC_GOT_DTPREL16:
-		    case BFD_RELOC_PPC_GOT_DTPREL16_LO:
-		    case BFD_RELOC_PPC_GOT_TPREL16:
-		    case BFD_RELOC_PPC_GOT_TPREL16_LO:
-		      break;
-		    default:
-		      as_bad (_("unsupported relocation for DS offset field"));
-		      break;
-		    }
-		}
 	    }
 #endif /* OBJ_ELF */
 
@@ -3248,11 +3151,13 @@ md_assemble (char *str)
 	  /* Determine a BFD reloc value based on the operand information.
 	     We are only prepared to turn a few of the operands into
 	     relocs.  */
-	  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+	  else if ((operand->flags & (PPC_OPERAND_RELATIVE
+				      | PPC_OPERAND_ABSOLUTE)) != 0
 		   && operand->bitm == 0x3fffffc
 		   && operand->shift == 0)
 	    reloc = BFD_RELOC_PPC_B26;
-	  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+	  else if ((operand->flags & (PPC_OPERAND_RELATIVE
+				      | PPC_OPERAND_ABSOLUTE)) != 0
 		   && operand->bitm == 0xfffc
 		   && operand->shift == 0)
 	    reloc = BFD_RELOC_PPC_B16;
@@ -3268,40 +3173,126 @@ md_assemble (char *str)
 		   && operand->bitm == 0x1fffffe
 		   && operand->shift == 0)
 	    reloc = BFD_RELOC_PPC_VLE_REL24;
-	  else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
-		   && operand->bitm == 0x3fffffc
-		   && operand->shift == 0)
-	    reloc = BFD_RELOC_PPC_BA26;
-	  else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
-		   && operand->bitm == 0xfffc
-		   && operand->shift == 0)
-	    reloc = BFD_RELOC_PPC_BA16;
-#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
-	  else if ((operand->flags & PPC_OPERAND_PARENS) != 0
+	  else if ((operand->flags & PPC_OPERAND_NEGATIVE) == 0
 		   && (operand->bitm & 0xfff0) == 0xfff0
 		   && operand->shift == 0)
 	    {
+	      reloc = BFD_RELOC_16;
+#if defined OBJ_XCOFF || defined OBJ_ELF
 	      /* Note: the symbol may be not yet defined.  */
-	      if (ppc_is_toc_sym (ex.X_add_symbol))
+	      if ((operand->flags & PPC_OPERAND_PARENS) != 0
+		  && ppc_is_toc_sym (ex.X_add_symbol))
 		{
 		  reloc = BFD_RELOC_PPC_TOC16;
 #ifdef OBJ_ELF
-		  if (ppc_obj64
-		      && (operand->flags & PPC_OPERAND_DS) != 0)
-		    reloc = BFD_RELOC_PPC64_TOC16_DS;
+		  as_warn (_("assuming %s on symbol"),
+			   ppc_obj64 ? "@toc" : "@xgot");
 #endif
 		}
-	      else
+#endif
+	    }
+
+	  /* For the absolute forms of branches, convert the PC
+	     relative form back into the absolute.  */
+	  if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+	    {
+	      switch (reloc)
 		{
-		  reloc = BFD_RELOC_16;
+		case BFD_RELOC_PPC_B26:
+		  reloc = BFD_RELOC_PPC_BA26;
+		  break;
+		case BFD_RELOC_PPC_B16:
+		  reloc = BFD_RELOC_PPC_BA16;
+		  break;
 #ifdef OBJ_ELF
-		  if (ppc_obj64
-		      && (operand->flags & PPC_OPERAND_DS) != 0)
-		    reloc = BFD_RELOC_PPC64_ADDR16_DS;
+		case BFD_RELOC_PPC_B16_BRTAKEN:
+		  reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
+		  break;
+		case BFD_RELOC_PPC_B16_BRNTAKEN:
+		  reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
+		  break;
 #endif
+		default:
+		  break;
+		}
+	    }
+
+#ifdef OBJ_ELF
+	  switch (reloc)
+	    {
+	    case BFD_RELOC_PPC_TOC16:
+	      toc_reloc_types |= has_small_toc_reloc;
+	      break;
+	    case BFD_RELOC_PPC64_TOC16_LO:
+	    case BFD_RELOC_PPC64_TOC16_HI:
+	    case BFD_RELOC_PPC64_TOC16_HA:
+	      toc_reloc_types |= has_large_toc_reloc;
+	      break;
+	    default:
+	      break;
+	    }
+
+	  if (ppc_obj64
+	      && (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
+	    {
+	      switch (reloc)
+		{
+		case BFD_RELOC_16:
+		  reloc = BFD_RELOC_PPC64_ADDR16_DS;
+		  break;
+		case BFD_RELOC_LO16:
+		  reloc = BFD_RELOC_PPC64_ADDR16_LO_DS;
+		  break;
+		case BFD_RELOC_16_GOTOFF:
+		  reloc = BFD_RELOC_PPC64_GOT16_DS;
+		  break;
+		case BFD_RELOC_LO16_GOTOFF:
+		  reloc = BFD_RELOC_PPC64_GOT16_LO_DS;
+		  break;
+		case BFD_RELOC_LO16_PLTOFF:
+		  reloc = BFD_RELOC_PPC64_PLT16_LO_DS;
+		  break;
+		case BFD_RELOC_16_BASEREL:
+		  reloc = BFD_RELOC_PPC64_SECTOFF_DS;
+		  break;
+		case BFD_RELOC_LO16_BASEREL:
+		  reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS;
+		  break;
+		case BFD_RELOC_PPC_TOC16:
+		  reloc = BFD_RELOC_PPC64_TOC16_DS;
+		  break;
+		case BFD_RELOC_PPC64_TOC16_LO:
+		  reloc = BFD_RELOC_PPC64_TOC16_LO_DS;
+		  break;
+		case BFD_RELOC_PPC64_PLTGOT16:
+		  reloc = BFD_RELOC_PPC64_PLTGOT16_DS;
+		  break;
+		case BFD_RELOC_PPC64_PLTGOT16_LO:
+		  reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS;
+		  break;
+		case BFD_RELOC_PPC_DTPREL16:
+		  reloc = BFD_RELOC_PPC64_DTPREL16_DS;
+		  break;
+		case BFD_RELOC_PPC_DTPREL16_LO:
+		  reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS;
+		  break;
+		case BFD_RELOC_PPC_TPREL16:
+		  reloc = BFD_RELOC_PPC64_TPREL16_DS;
+		  break;
+		case BFD_RELOC_PPC_TPREL16_LO:
+		  reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
+		  break;
+		case BFD_RELOC_PPC_GOT_DTPREL16:
+		case BFD_RELOC_PPC_GOT_DTPREL16_LO:
+		case BFD_RELOC_PPC_GOT_TPREL16:
+		case BFD_RELOC_PPC_GOT_TPREL16_LO:
+		  break;
+		default:
+		  as_bad (_("unsupported relocation for DS offset field"));
+		  break;
 		}
 	    }
-#endif /* defined (OBJ_XCOFF) || defined (OBJ_ELF) */
+#endif
 
 	  /* We need to generate a fixup for this expression.  */
 	  if (fc >= MAX_INSN_FIXUPS)
diff -Nrup a/ld/testsuite/ld-powerpc/elfv2exe.d b/ld/testsuite/ld-powerpc/elfv2exe.d
--- a/ld/testsuite/ld-powerpc/elfv2exe.d	2015-05-07 09:21:42.727374395 -0600
+++ b/ld/testsuite/ld-powerpc/elfv2exe.d	2015-05-07 09:26:49.048581753 -0600
@@ -21,7 +21,7 @@ Disassembly of section \.text:
 
 0+100000e0 <_start>:
 .*:	(02 10 40 3c|3c 40 10 02) 	lis     r2,4098
-.*:	(40 81 42 38|38 42 81 40) 	addi    r2,r2,-32448
+.*:	(38 81 42 38|38 42 81 38) 	addi    r2,r2,-32456
 .*:	(a6 02 08 7c|7c 08 02 a6) 	mflr    r0
 .*:	(e1 ff 21 f8|f8 21 ff e1) 	stdu    r1,-32\(r1\)
 .*:	(30 00 01 f8|f8 01 00 30) 	std     r0,48\(r1\)
diff -Nrup a/ld/testsuite/ld-powerpc/elfv2so.d b/ld/testsuite/ld-powerpc/elfv2so.d
--- a/ld/testsuite/ld-powerpc/elfv2so.d	2015-05-07 09:21:42.688375260 -0600
+++ b/ld/testsuite/ld-powerpc/elfv2so.d	2015-05-07 09:26:49.048581753 -0600
@@ -7,33 +7,33 @@
 
 Disassembly of section \.text:
 
-0+300 <.*\.plt_call\.f4>:
+0+320 <.*\.plt_call\.f4>:
 .*:	(18 00 41 f8|f8 41 00 18) 	std     r2,24\(r1\)
 .*:	(38 80 82 e9|e9 82 80 38) 	ld      r12,-32712\(r2\)
 .*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
 .*:	(20 04 80 4e|4e 80 04 20) 	bctr
 
-0+310 <.*\.plt_call\.f3>:
+0+330 <.*\.plt_call\.f3>:
 .*:	(18 00 41 f8|f8 41 00 18) 	std     r2,24\(r1\)
 .*:	(28 80 82 e9|e9 82 80 28) 	ld      r12,-32728\(r2\)
 .*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
 .*:	(20 04 80 4e|4e 80 04 20) 	bctr
 
-0+320 <.*\.plt_call\.f2>:
+0+340 <.*\.plt_call\.f2>:
 .*:	(18 00 41 f8|f8 41 00 18) 	std     r2,24\(r1\)
 .*:	(30 80 82 e9|e9 82 80 30) 	ld      r12,-32720\(r2\)
 .*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
 .*:	(20 04 80 4e|4e 80 04 20) 	bctr
 
-0+330 <.*\.plt_call\.f1>:
+0+350 <.*\.plt_call\.f1>:
 .*:	(18 00 41 f8|f8 41 00 18) 	std     r2,24\(r1\)
 .*:	(40 80 82 e9|e9 82 80 40) 	ld      r12,-32704\(r2\)
 .*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
 .*:	(20 04 80 4e|4e 80 04 20) 	bctr
 
-0+340 <f1>:
+0+360 <f1>:
 .*:	(02 00 4c 3c|3c 4c 00 02) 	addis   r2,r12,2
-.*:	(e0 81 42 38|38 42 81 e0) 	addi    r2,r2,-32288
+.*:	(d8 81 42 38|38 42 81 d8) 	addi    r2,r2,-32296
 .*:	(a6 02 08 7c|7c 08 02 a6) 	mflr    r0
 .*:	(e1 ff 21 f8|f8 21 ff e1) 	stdu    r1,-32\(r1\)
 .*:	(30 00 01 f8|f8 01 00 30) 	std     r0,48\(r1\)
@@ -50,10 +50,10 @@ Disassembly of section \.text:
 .*:	(20 00 21 38|38 21 00 20) 	addi    r1,r1,32
 .*:	(a6 03 08 7c|7c 08 03 a6) 	mtlr    r0
 .*:	(20 00 80 4e|4e 80 00 20) 	blr
-.*:	(a0 01 01 00|00 00 00 00) 	.*
-.*:	(00 00 00 00|00 01 01 a0) 	.*
+.*:	(98 01 01 00|00 00 00 00) 	.*
+.*:	(00 00 00 00|00 01 01 98) 	.*
 
-0+390 <__glink_PLTresolve>:
+0+3b0 <__glink_PLTresolve>:
 .*:	(a6 02 08 7c|7c 08 02 a6) 	mflr    r0
 .*:	(05 00 9f 42|42 9f 00 05) 	bcl     .*
 .*:	(a6 02 68 7d|7d 68 02 a6) 	mflr    r11