/* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
- Copyright (C) 1994-2019 Free Software Foundation, Inc.
+ Copyright (C) 1994-2020 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GAS, the GNU Assembler.
return 1;
}
+static int
+is_ppc64_target (const bfd_target *targ, void *data ATTRIBUTE_UNUSED)
+{
+ switch (targ->flavour)
+ {
+#ifdef OBJ_ELF
+ case bfd_target_elf_flavour:
+ return strncmp (targ->name, "elf64-powerpc", 13) == 0;
+#endif
+#ifdef OBJ_XCOFF
+ case bfd_target_xcoff_flavour:
+ return (strcmp (targ->name, "aixcoff64-rs6000") == 0
+ || strcmp (targ->name, "aix5coff64-rs6000") == 0);
+#endif
+ default:
+ return 0;
+ }
+}
+
void
md_show_usage (FILE *stream)
{
fprintf (stream, _("\
-PowerPC options:\n\
--a32 generate ELF32/XCOFF32\n\
--a64 generate ELF64/XCOFF64\n\
--u ignored\n\
--mpwrx, -mpwr2 generate code for POWER/2 (RIOS2)\n\
--mpwr generate code for POWER (RIOS1)\n\
--m601 generate code for PowerPC 601\n\
+PowerPC options:\n"));
+ fprintf (stream, _("\
+-a32 generate ELF32/XCOFF32\n"));
+ if (bfd_iterate_over_targets (is_ppc64_target, NULL))
+ fprintf (stream, _("\
+-a64 generate ELF64/XCOFF64\n"));
+ fprintf (stream, _("\
+-u ignored\n"));
+ fprintf (stream, _("\
+-mpwrx, -mpwr2 generate code for POWER/2 (RIOS2)\n"));
+ fprintf (stream, _("\
+-mpwr generate code for POWER (RIOS1)\n"));
+ fprintf (stream, _("\
+-m601 generate code for PowerPC 601\n"));
+ fprintf (stream, _("\
-mppc, -mppc32, -m603, -m604\n\
- generate code for PowerPC 603/604\n\
--m403 generate code for PowerPC 403\n\
--m405 generate code for PowerPC 405\n\
--m440 generate code for PowerPC 440\n\
--m464 generate code for PowerPC 464\n\
--m476 generate code for PowerPC 476\n\
+ generate code for PowerPC 603/604\n"));
+ fprintf (stream, _("\
+-m403 generate code for PowerPC 403\n"));
+ fprintf (stream, _("\
+-m405 generate code for PowerPC 405\n"));
+ fprintf (stream, _("\
+-m440 generate code for PowerPC 440\n"));
+ fprintf (stream, _("\
+-m464 generate code for PowerPC 464\n"));
+ fprintf (stream, _("\
+-m476 generate code for PowerPC 476\n"));
+ fprintf (stream, _("\
-m7400, -m7410, -m7450, -m7455\n\
- generate code for PowerPC 7400/7410/7450/7455\n\
+ generate code for PowerPC 7400/7410/7450/7455\n"));
+ fprintf (stream, _("\
-m750cl, -mgekko, -mbroadway\n\
- generate code for PowerPC 750cl/Gekko/Broadway\n\
+ generate code for PowerPC 750cl/Gekko/Broadway\n"));
+ fprintf (stream, _("\
-m821, -m850, -m860 generate code for PowerPC 821/850/860\n"));
fprintf (stream, _("\
--mppc64, -m620 generate code for PowerPC 620/625/630\n\
--mppc64bridge generate code for PowerPC 64, including bridge insns\n\
--mbooke generate code for 32-bit PowerPC BookE\n\
--ma2 generate code for A2 architecture\n\
--mpower4, -mpwr4 generate code for Power4 architecture\n\
+-mppc64, -m620 generate code for PowerPC 620/625/630\n"));
+ fprintf (stream, _("\
+-mppc64bridge generate code for PowerPC 64, including bridge insns\n"));
+ fprintf (stream, _("\
+-mbooke generate code for 32-bit PowerPC BookE\n"));
+ fprintf (stream, _("\
+-ma2 generate code for A2 architecture\n"));
+ fprintf (stream, _("\
+-mpower4, -mpwr4 generate code for Power4 architecture\n"));
+ fprintf (stream, _("\
-mpower5, -mpwr5, -mpwr5x\n\
- generate code for Power5 architecture\n\
--mpower6, -mpwr6 generate code for Power6 architecture\n\
--mpower7, -mpwr7 generate code for Power7 architecture\n\
--mpower8, -mpwr8 generate code for Power8 architecture\n\
--mpower9, -mpwr9 generate code for Power9 architecture\n\
--mcell generate code for Cell Broadband Engine architecture\n\
--mcom generate code for Power/PowerPC common instructions\n\
+ generate code for Power5 architecture\n"));
+ fprintf (stream, _("\
+-mpower6, -mpwr6 generate code for Power6 architecture\n"));
+ fprintf (stream, _("\
+-mpower7, -mpwr7 generate code for Power7 architecture\n"));
+ fprintf (stream, _("\
+-mpower8, -mpwr8 generate code for Power8 architecture\n"));
+ fprintf (stream, _("\
+-mpower9, -mpwr9 generate code for Power9 architecture\n"));
+ fprintf (stream, _("\
+-mcell generate code for Cell Broadband Engine architecture\n"));
+ fprintf (stream, _("\
+-mcom generate code for Power/PowerPC common instructions\n"));
+ fprintf (stream, _("\
-many generate code for any architecture (PWR/PWRX/PPC)\n"));
fprintf (stream, _("\
--maltivec generate code for AltiVec\n\
--mvsx generate code for Vector-Scalar (VSX) instructions\n\
--me300 generate code for PowerPC e300 family\n\
--me500, -me500x2 generate code for Motorola e500 core complex\n\
--me500mc, generate code for Freescale e500mc core complex\n\
--me500mc64, generate code for Freescale e500mc64 core complex\n\
--me5500, generate code for Freescale e5500 core complex\n\
--me6500, generate code for Freescale e6500 core complex\n\
--mspe generate code for Motorola SPE instructions\n\
--mspe2 generate code for Freescale SPE2 instructions\n\
--mvle generate code for Freescale VLE instructions\n\
--mtitan generate code for AppliedMicro Titan core complex\n\
--mregnames Allow symbolic names for registers\n\
+-maltivec generate code for AltiVec\n"));
+ fprintf (stream, _("\
+-mvsx generate code for Vector-Scalar (VSX) instructions\n"));
+ fprintf (stream, _("\
+-me300 generate code for PowerPC e300 family\n"));
+ fprintf (stream, _("\
+-me500, -me500x2 generate code for Motorola e500 core complex\n"));
+ fprintf (stream, _("\
+-me500mc, generate code for Freescale e500mc core complex\n"));
+ fprintf (stream, _("\
+-me500mc64, generate code for Freescale e500mc64 core complex\n"));
+ fprintf (stream, _("\
+-me5500, generate code for Freescale e5500 core complex\n"));
+ fprintf (stream, _("\
+-me6500, generate code for Freescale e6500 core complex\n"));
+ fprintf (stream, _("\
+-mspe generate code for Motorola SPE instructions\n"));
+ fprintf (stream, _("\
+-mspe2 generate code for Freescale SPE2 instructions\n"));
+ fprintf (stream, _("\
+-mvle generate code for Freescale VLE instructions\n"));
+ fprintf (stream, _("\
+-mtitan generate code for AppliedMicro Titan core complex\n"));
+ fprintf (stream, _("\
+-mregnames Allow symbolic names for registers\n"));
+ fprintf (stream, _("\
-mno-regnames Do not allow symbolic names for registers\n"));
#ifdef OBJ_ELF
fprintf (stream, _("\
--mrelocatable support for GCC's -mrelocatble option\n\
--mrelocatable-lib support for GCC's -mrelocatble-lib option\n\
--memb set PPC_EMB bit in ELF flags\n\
+-mrelocatable support for GCC's -mrelocatble option\n"));
+ fprintf (stream, _("\
+-mrelocatable-lib support for GCC's -mrelocatble-lib option\n"));
+ fprintf (stream, _("\
+-memb set PPC_EMB bit in ELF flags\n"));
+ fprintf (stream, _("\
-mlittle, -mlittle-endian, -le\n\
- generate code for a little endian machine\n\
+ generate code for a little endian machine\n"));
+ fprintf (stream, _("\
-mbig, -mbig-endian, -be\n\
- generate code for a big endian machine\n\
--msolaris generate code for Solaris\n\
--mno-solaris do not generate code for Solaris\n\
--K PIC set EF_PPC_RELOCATABLE_LIB in ELF flags\n\
--V print assembler version number\n\
+ generate code for a big endian machine\n"));
+ fprintf (stream, _("\
+-msolaris generate code for Solaris\n"));
+ fprintf (stream, _("\
+-mno-solaris do not generate code for Solaris\n"));
+ fprintf (stream, _("\
+-K PIC set EF_PPC_RELOCATABLE_LIB in ELF flags\n"));
+ fprintf (stream, _("\
+-V print assembler version number\n"));
+ fprintf (stream, _("\
-Qy, -Qn ignored\n"));
#endif
fprintf (stream, _("\
--nops=count when aligning, more than COUNT nops uses a branch\n\
+-nops=count when aligning, more than COUNT nops uses a branch\n"));
+ fprintf (stream, _("\
-ppc476-workaround warn if emitting data to code sections\n"));
}
\f
/* Create the .PPC.EMB.apuinfo section. */
apuinfo_secp = subseg_new (APUINFO_SECTION_NAME, 0);
- bfd_set_section_flags (stdoutput,
- apuinfo_secp,
- SEC_HAS_CONTENTS | SEC_READONLY);
+ bfd_set_section_flags (apuinfo_secp, SEC_HAS_CONTENTS | SEC_READONLY);
p = frag_more (4);
md_number_to_chars (p, (valueT) 8, 4);
MAP64 ("pcrel", BFD_RELOC_PPC64_PCREL34),
MAP64 ("got@pcrel", BFD_RELOC_PPC64_GOT_PCREL34),
MAP64 ("plt@pcrel", BFD_RELOC_PPC64_PLT_PCREL34),
+ MAP64 ("tls@pcrel", BFD_RELOC_PPC64_TLS_PCREL),
+ MAP64 ("got@tlsgd@pcrel", BFD_RELOC_PPC64_GOT_TLSGD34),
+ MAP64 ("got@tlsld@pcrel", BFD_RELOC_PPC64_GOT_TLSLD34),
+ MAP64 ("got@tprel@pcrel", BFD_RELOC_PPC64_GOT_TPREL34),
+ MAP64 ("got@dtprel@pcrel", BFD_RELOC_PPC64_GOT_DTPREL34),
MAP64 ("higher34", BFD_RELOC_PPC64_ADDR16_HIGHER34),
MAP64 ("highera34", BFD_RELOC_PPC64_ADDR16_HIGHERA34),
MAP64 ("highest34", BFD_RELOC_PPC64_ADDR16_HIGHEST34),
case BFD_RELOC_LO16_GOTOFF:
case BFD_RELOC_HI16_GOTOFF:
case BFD_RELOC_HI16_S_GOTOFF:
- as_warn (_("identifier+constant@got means "
- "identifier@got+constant"));
+ as_warn (_("symbol+offset@%s means symbol@%s+offset"),
+ ptr->string, ptr->string);
break;
case BFD_RELOC_PPC_GOT_TLSGD16:
case BFD_RELOC_PPC_GOT_TPREL16_LO:
case BFD_RELOC_PPC_GOT_TPREL16_HI:
case BFD_RELOC_PPC_GOT_TPREL16_HA:
- as_bad (_("symbol+offset not supported for got tls"));
+ as_bad (_("symbol+offset@%s not supported"), ptr->string);
break;
}
}
elf_elfheader (stdoutput)->e_flags &= ~EF_PPC64_ABI;
elf_elfheader (stdoutput)->e_flags |= ppc_abiversion & EF_PPC64_ABI;
}
+ /* Any selection of opcodes based on ppc_cpu after gas has finished
+ parsing the file is invalid. md_apply_fix and ppc_handle_align
+ must select opcodes based on the machine in force at the point
+ where the fixup or alignment frag was created, not the machine in
+ force at the end of file. */
+ ppc_cpu = 0;
}
/* Validate any relocations emitted for -mrelocatable, possibly adding
toc = bfd_get_section_by_name (stdoutput, ".toc");
if (toc != NULL
&& toc_reloc_types != has_large_toc_reloc
- && bfd_section_size (stdoutput, toc) > 0x10000)
+ && bfd_section_size (toc) > 0x10000)
as_warn (_("TOC section size exceeds 64k"));
}
case BFD_RELOC_PPC_VLE_SDAREL_HI16D:
case BFD_RELOC_PPC_VLE_SDAREL_LO16A:
case BFD_RELOC_PPC_VLE_SDAREL_LO16D:
+ case BFD_RELOC_PPC64_TLS_PCREL:
case BFD_RELOC_RVA:
size = 4;
break;
case BFD_RELOC_PPC64_D34_LO:
case BFD_RELOC_PPC64_D34_HI30:
case BFD_RELOC_PPC64_D34_HA30:
+ case BFD_RELOC_PPC64_TPREL34:
+ case BFD_RELOC_PPC64_DTPREL34:
case BFD_RELOC_PPC64_TOC:
size = 8;
break;
case BFD_RELOC_64_PCREL:
case BFD_RELOC_64_PLT_PCREL:
case BFD_RELOC_PPC64_GOT_PCREL34:
+ case BFD_RELOC_PPC64_GOT_TLSGD34:
+ case BFD_RELOC_PPC64_GOT_TLSLD34:
+ case BFD_RELOC_PPC64_GOT_TPREL34:
+ case BFD_RELOC_PPC64_GOT_DTPREL34:
case BFD_RELOC_PPC64_PCREL28:
case BFD_RELOC_PPC64_PCREL34:
case BFD_RELOC_PPC64_PLT_PCREL34:
break;
case BFD_RELOC_PPC_TLS:
+ case BFD_RELOC_PPC64_TLS_PCREL:
if (!_bfd_elf_ppc_at_tls_transform (opcode->opcode, 0))
as_bad (_("@tls may not be used with \"%s\" operands"),
opcode->name);
break;
/* We'll only use the 32 (or 64) bit form of these relocations
- in constants. Instructions get the 16 bit form. */
+ in constants. Instructions get the 16 or 34 bit form. */
case BFD_RELOC_PPC_DTPREL:
- reloc = BFD_RELOC_PPC_DTPREL16;
+ if (operand->bitm == 0x3ffffffffULL)
+ reloc = BFD_RELOC_PPC64_DTPREL34;
+ else
+ reloc = BFD_RELOC_PPC_DTPREL16;
break;
case BFD_RELOC_PPC_TPREL:
- reloc = BFD_RELOC_PPC_TPREL16;
+ if (operand->bitm == 0x3ffffffffULL)
+ reloc = BFD_RELOC_PPC64_TPREL34;
+ else
+ reloc = BFD_RELOC_PPC_TPREL16;
break;
case BFD_RELOC_PPC64_PCREL34:
/* Fall through. */
case BFD_RELOC_PPC64_GOT_PCREL34:
case BFD_RELOC_PPC64_PLT_PCREL34:
+ case BFD_RELOC_PPC64_GOT_TLSGD34:
+ case BFD_RELOC_PPC64_GOT_TLSLD34:
+ case BFD_RELOC_PPC64_GOT_TPREL34:
+ case BFD_RELOC_PPC64_GOT_DTPREL34:
if (operand->bitm != 0x3ffffffffULL
|| (operand->flags & PPC_OPERAND_NEGATIVE) != 0)
as_warn (_("%s unsupported on this instruction"), "@pcrel");
const struct xcoff_dwsect_name *dw = &xcoff_dwsect_names[idx];
sec = subseg_new (dw->name, subseg);
- oldflags = bfd_get_section_flags (stdoutput, sec);
+ oldflags = bfd_section_flags (sec);
if (oldflags == SEC_NO_FLAGS)
{
/* Just created section. */
gas_assert (dw_sections[idx].sect == NULL);
- bfd_set_section_flags (stdoutput, sec, SEC_DEBUGGING);
- bfd_set_section_alignment (stdoutput, sec, 0);
+ bfd_set_section_flags (sec, SEC_DEBUGGING);
+ bfd_set_section_alignment (sec, 0);
dw_sections[idx].sect = sec;
}
symbol_set_value_now (dwss->end_exp.X_add_symbol);
}
}
+ ppc_cpu = 0;
}
#endif /* OBJ_XCOFF */
{
pdata_section = subseg_new (".pdata", 0);
- bfd_set_section_flags (stdoutput, pdata_section,
- (SEC_ALLOC | SEC_LOAD | SEC_RELOC
- | SEC_READONLY | SEC_DATA ));
+ bfd_set_section_flags (pdata_section, (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA));
- bfd_set_section_alignment (stdoutput, pdata_section, 2);
+ bfd_set_section_alignment (pdata_section, 2);
}
else
{
if (ydata_section == 0)
{
ydata_section = subseg_new (".ydata", 0);
- bfd_set_section_flags (stdoutput, ydata_section,
- (SEC_ALLOC | SEC_LOAD | SEC_RELOC
- | SEC_READONLY | SEC_DATA ));
+ bfd_set_section_flags (ydata_section, (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA ));
- bfd_set_section_alignment (stdoutput, ydata_section, 3);
+ bfd_set_section_alignment (ydata_section, 3);
}
else
{
{
reldata_section = subseg_new (".reldata", 0);
- bfd_set_section_flags (stdoutput, reldata_section,
- (SEC_ALLOC | SEC_LOAD | SEC_RELOC
- | SEC_DATA));
+ bfd_set_section_flags (reldata_section, (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_DATA));
- bfd_set_section_alignment (stdoutput, reldata_section, 2);
+ bfd_set_section_alignment (reldata_section, 2);
}
else
{
if (rdata_section == 0)
{
rdata_section = subseg_new (".rdata", 0);
- bfd_set_section_flags (stdoutput, rdata_section,
- (SEC_ALLOC | SEC_LOAD | SEC_RELOC
- | SEC_READONLY | SEC_DATA ));
+ bfd_set_section_flags (rdata_section, (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA ));
- bfd_set_section_alignment (stdoutput, rdata_section, 2);
+ bfd_set_section_alignment (rdata_section, 2);
}
else
{
if (flags != SEC_NO_FLAGS)
{
- if (! bfd_set_section_flags (stdoutput, sec, flags))
+ if (!bfd_set_section_flags (sec, flags))
as_bad (_("error setting flags for \"%s\": %s"),
- bfd_section_name (stdoutput, sec),
+ bfd_section_name (sec),
bfd_errmsg (bfd_get_error ()));
}
- bfd_set_section_alignment (stdoutput, sec, align);
+ bfd_set_section_alignment (sec, align);
}
static void
{
tocdata_section = subseg_new (".tocd", 0);
/* FIXME: section flags won't work. */
- bfd_set_section_flags (stdoutput, tocdata_section,
- (SEC_ALLOC | SEC_LOAD | SEC_RELOC
- | SEC_READONLY | SEC_DATA));
+ bfd_set_section_flags (tocdata_section, (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA));
- bfd_set_section_alignment (stdoutput, tocdata_section, 2);
+ bfd_set_section_alignment (tocdata_section, 2);
}
else
{
/* This is a csect symbol. x_scnlen is the size of the
csect. */
if (symbol_get_tc (sym)->next == (symbolS *) NULL)
- a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput,
- S_GET_SEGMENT (sym))
+ a->x_csect.x_scnlen.l = (bfd_section_size (S_GET_SEGMENT (sym))
- S_GET_VALUE (sym));
else
{
|| symbol_get_tc (next)->symbol_class != XMC_TC)
{
if (ppc_after_toc_frag == (fragS *) NULL)
- a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput,
- data_section)
+ a->x_csect.x_scnlen.l = (bfd_section_size (data_section)
- S_GET_VALUE (sym));
else
a->x_csect.x_scnlen.l = (ppc_after_toc_frag->fr_address
static bfd_vma vma = 0;
/* Dwarf sections start at 0. */
- if (bfd_get_section_flags (NULL, sec) & SEC_DEBUGGING)
+ if (bfd_section_flags (sec) & SEC_DEBUGGING)
return;
vma = md_section_align (sec, vma);
- bfd_set_section_vma (stdoutput, sec, vma);
- vma += bfd_section_size (stdoutput, sec);
+ bfd_set_section_vma (sec, vma);
+ vma += bfd_section_size (sec);
}
#endif /* OBJ_XCOFF */
#ifdef OBJ_ELF
return addr;
#else
- int align = bfd_get_section_alignment (stdoutput, seg);
+ int align = bfd_section_alignment (seg);
return ((addr + (1 << align) - 1) & -(1 << align));
#endif
return 0;
/* Always adjust symbols in debugging sections. */
- if (bfd_get_section_flags (stdoutput, symseg) & SEC_DEBUGGING)
+ if (bfd_section_flags (symseg) & SEC_DEBUGGING)
return 1;
if (ppc_toc_csect != (symbolS *) NULL
}
if (fix->fx_r_type >= BFD_RELOC_PPC_TLS
- && fix->fx_r_type <= BFD_RELOC_PPC64_DTPREL16_HIGHESTA)
+ && fix->fx_r_type <= BFD_RELOC_PPC64_TLS_PCREL)
return 1;
return generic_force_reloc (fix);
&& fix->fx_r_type != BFD_RELOC_VTABLE_INHERIT
&& fix->fx_r_type != BFD_RELOC_VTABLE_ENTRY
&& !(fix->fx_r_type >= BFD_RELOC_PPC_TLS
- && fix->fx_r_type <= BFD_RELOC_PPC64_DTPREL16_HIGHESTA));
+ && fix->fx_r_type <= BFD_RELOC_PPC64_TLS_PCREL));
}
#endif
fragP->insn_addr + 1);
}
-/* Implement HANDLE_ALIGN. This writes the NOP pattern into an
- rs_align_code frag. */
+/* rs_align_code frag handling. */
+
+enum ppc_nop_encoding_for_rs_align_code
+{
+ PPC_NOP_VANILLA,
+ PPC_NOP_VLE,
+ PPC_NOP_GROUP_P6,
+ PPC_NOP_GROUP_P7
+};
+
+unsigned int
+ppc_nop_select (void)
+{
+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
+ return PPC_NOP_VLE;
+ if ((ppc_cpu & (PPC_OPCODE_POWER9 | PPC_OPCODE_E500MC)) == 0)
+ {
+ if ((ppc_cpu & PPC_OPCODE_POWER7) != 0)
+ return PPC_NOP_GROUP_P7;
+ if ((ppc_cpu & PPC_OPCODE_POWER6) != 0)
+ return PPC_NOP_GROUP_P6;
+ }
+ return PPC_NOP_VANILLA;
+}
void
ppc_handle_align (struct frag *fragP)
{
valueT count = (fragP->fr_next->fr_address
- (fragP->fr_address + fragP->fr_fix));
+ char *dest = fragP->fr_literal + fragP->fr_fix;
+ enum ppc_nop_encoding_for_rs_align_code nop_select = *dest & 0xff;
+
+ /* Pad with zeros if not inserting a whole number of instructions.
+ We could pad with zeros up to an instruction boundary then follow
+ with nops but odd counts indicate data in an executable section
+ so padding with zeros is most appropriate. */
+ if (count == 0
+ || (nop_select == PPC_NOP_VLE ? (count & 1) != 0 : (count & 3) != 0))
+ {
+ *dest = 0;
+ return;
+ }
- if ((ppc_cpu & PPC_OPCODE_VLE) != 0 && count != 0 && (count & 1) == 0)
+ if (nop_select == PPC_NOP_VLE)
{
- char *dest = fragP->fr_literal + fragP->fr_fix;
fragP->fr_var = 2;
md_number_to_chars (dest, 0x4400, 2);
}
- else if (count != 0 && (count & 3) == 0)
+ else
{
- char *dest = fragP->fr_literal + fragP->fr_fix;
-
fragP->fr_var = 4;
if (count > 4 * nop_limit && count < 0x2000000)
md_number_to_chars (dest, 0x60000000, 4);
- if ((ppc_cpu & PPC_OPCODE_POWER6) != 0
- && (ppc_cpu & PPC_OPCODE_POWER9) == 0)
+ if (nop_select >= PPC_NOP_GROUP_P6)
{
/* For power6, power7, and power8, we want the last nop to
be a group terminating one. Do this by inserting an
dest = group_nop->fr_literal;
}
- if ((ppc_cpu & PPC_OPCODE_POWER7) != 0)
- {
- if (ppc_cpu & PPC_OPCODE_E500MC)
- /* e500mc group terminating nop: "ori 0,0,0". */
- md_number_to_chars (dest, 0x60000000, 4);
- else
- /* power7/power8 group terminating nop: "ori 2,2,0". */
- md_number_to_chars (dest, 0x60420000, 4);
- }
- else
+ if (nop_select == PPC_NOP_GROUP_P6)
/* power6 group terminating nop: "ori 1,1,0". */
md_number_to_chars (dest, 0x60210000, 4);
+ else
+ /* power7/power8 group terminating nop: "ori 2,2,0". */
+ md_number_to_chars (dest, 0x60420000, 4);
}
}
}
case BFD_RELOC_PPC64_DTPREL16_HIGHERA:
case BFD_RELOC_PPC64_DTPREL16_HIGHEST:
case BFD_RELOC_PPC64_DTPREL16_HIGHESTA:
+ case BFD_RELOC_PPC64_TPREL34:
+ case BFD_RELOC_PPC64_DTPREL34:
+ case BFD_RELOC_PPC64_GOT_TLSGD34:
+ case BFD_RELOC_PPC64_GOT_TLSLD34:
+ case BFD_RELOC_PPC64_GOT_TPREL34:
+ case BFD_RELOC_PPC64_GOT_DTPREL34:
gas_assert (fixP->fx_addsy != NULL);
S_SET_THREAD_LOCAL (fixP->fx_addsy);
fieldval = 0;
case BFD_RELOC_PPC_TLS:
case BFD_RELOC_PPC_TLSGD:
case BFD_RELOC_PPC_TLSLD:
+ case BFD_RELOC_PPC64_TLS_PCREL:
fieldval = 0;
break;
#endif
case BFD_RELOC_PPC64_TPREL16_HIGHERA:
case BFD_RELOC_PPC64_TPREL16_HIGHEST:
case BFD_RELOC_PPC64_TPREL16_HIGHESTA:
+ case BFD_RELOC_PPC64_TLS_PCREL:
fixP->fx_done = 0;
break;
#endif
#else
/* We want to use the offset within the toc, not the actual VMA
of the symbol. */
- fixP->fx_addnumber =
- - bfd_get_section_vma (stdoutput, S_GET_SEGMENT (fixP->fx_addsy))
- - S_GET_VALUE (ppc_toc_csect);
+ fixP->fx_addnumber = (- bfd_section_vma (S_GET_SEGMENT (fixP->fx_addsy))
+ - S_GET_VALUE (ppc_toc_csect));
/* Set *valP to avoid errors. */
*valP = value;
#endif
reloc->sym_ptr_ptr = XNEW (asymbol *);
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ /* BFD_RELOC_PPC64_TLS_PCREL generates R_PPC64_TLS with an odd r_offset. */
+ if (fixp->fx_r_type == BFD_RELOC_PPC64_TLS_PCREL)
+ reloc->address++;
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
if (reloc->howto == (reloc_howto_type *) NULL)
{