Add support for the GBZ80, Z180, and eZ80 variants of the Z80 architecure. Add an...
[deliverable/binutils-gdb.git] / gas / config / tc-ppc.c
index 64ff149b215a53af06224c4a2c93ccbe64e02a21..896b6b345635c2dcb34ed24165e7d251b6b6f240 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
@@ -1320,76 +1320,146 @@ md_parse_option (int c, const char *arg)
   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
@@ -1905,9 +1975,7 @@ ppc_cleanup (void)
 
     /* 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);
@@ -2154,6 +2222,11 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
     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),
@@ -2192,8 +2265,8 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
              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:
@@ -2212,7 +2285,7 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
              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;
              }
          }
@@ -2538,6 +2611,12 @@ ppc_elf_end (void)
       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
@@ -2622,7 +2701,7 @@ ppc_frob_file_before_adjust (void)
   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"));
 }
 
@@ -3079,6 +3158,7 @@ fixup_size (bfd_reloc_code_real_type reloc, bfd_boolean *pc_relative)
     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;
@@ -3120,6 +3200,8 @@ fixup_size (bfd_reloc_code_real_type reloc, bfd_boolean *pc_relative)
     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;
@@ -3127,6 +3209,10 @@ fixup_size (bfd_reloc_code_real_type reloc, bfd_boolean *pc_relative)
     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:
@@ -3668,6 +3754,7 @@ md_assemble (char *str)
                  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);
@@ -3680,13 +3767,19 @@ md_assemble (char *str)
                  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:
@@ -3698,6 +3791,10 @@ md_assemble (char *str)
                  /* 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");
@@ -4582,14 +4679,14 @@ ppc_change_debug_section (unsigned int idx, subsegT subseg)
   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;
     }
 
@@ -5492,6 +5589,7 @@ ppc_xcoff_end (void)
             symbol_set_value_now (dwss->end_exp.X_add_symbol);
           }
     }
+  ppc_cpu = 0;
 }
 
 #endif /* OBJ_XCOFF */
@@ -5704,11 +5802,10 @@ ppc_pdata (int ignore ATTRIBUTE_UNUSED)
     {
       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
     {
@@ -5737,11 +5834,10 @@ ppc_ydata (int ignore ATTRIBUTE_UNUSED)
   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
     {
@@ -5774,11 +5870,10 @@ ppc_reldata (int ignore ATTRIBUTE_UNUSED)
     {
       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
     {
@@ -5803,11 +5898,10 @@ ppc_rdata (int ignore ATTRIBUTE_UNUSED)
   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
     {
@@ -6161,13 +6255,13 @@ ppc_pe_section (int ignore ATTRIBUTE_UNUSED)
 
   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
@@ -6198,11 +6292,10 @@ ppc_pe_tocd (int ignore ATTRIBUTE_UNUSED)
     {
       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
     {
@@ -6473,8 +6566,7 @@ ppc_frob_symbol (symbolS *sym)
          /* 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
            {
@@ -6522,8 +6614,7 @@ ppc_frob_symbol (symbolS *sym)
              || 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
@@ -6687,12 +6778,12 @@ ppc_frob_section (asection *sec)
   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 */
@@ -6723,7 +6814,7 @@ md_section_align (asection *seg ATTRIBUTE_UNUSED, valueT addr)
 #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
@@ -6786,7 +6877,7 @@ ppc_fix_adjustable (fixS *fix)
     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
@@ -6926,7 +7017,7 @@ ppc_force_relocation (fixS *fix)
     }
 
   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);
@@ -6994,7 +7085,7 @@ ppc_fix_adjustable (fixS *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
 
@@ -7007,26 +7098,58 @@ ppc_frag_check (struct frag *fragP)
                  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)
@@ -7055,8 +7178,7 @@ ppc_handle_align (struct frag *fragP)
 
       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
@@ -7076,18 +7198,12 @@ ppc_handle_align (struct frag *fragP)
              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);
        }
     }
 }
@@ -7401,6 +7517,12 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
        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;
@@ -7471,6 +7593,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
        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
@@ -7724,6 +7847,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
        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
@@ -7794,9 +7918,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
 #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
@@ -7816,6 +7939,9 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
   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)
     {
This page took 0.033069 seconds and 4 git commands to generate.