* config/tc-ppc.c (md_apply_fix3): Allow BRTAKEN, BRNTAKEN relocs.
[deliverable/binutils-gdb.git] / gas / config / tc-ppc.c
index ba058f667bb2a1565b8dc1abb161160d04b50028..c4c32d1aeab00689d296b4954e3c0431d1517ae3 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
@@ -182,6 +182,10 @@ const char EXP_CHARS[] = "eE";
 /* Characters which mean that a number is a floating point constant,
    as in 0d1.0.  */
 const char FLT_CHARS[] = "dD";
+
+/* '+' and '-' can be used as postfix predicate predictors for conditional 
+   branches.  So they need to be accepted as symbol characters.  */
+const char ppc_symbol_chars[] = "+-";
 \f
 /* The target specific pseudo-ops which we support.  */
 
@@ -233,8 +237,6 @@ const pseudo_typeS md_pseudo_table[] =
   { "rdata",   ppc_elf_rdata,  0 },
   { "rodata",  ppc_elf_rdata,  0 },
   { "lcomm",   ppc_elf_lcomm,  0 },
-  { "file",    (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
-  { "loc",     dwarf2_directive_loc, 0 },
 #endif
 
 #ifdef TE_PE
@@ -1060,36 +1062,40 @@ md_show_usage (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\
 -mppc, -mppc32, -m603, -m604\n\
                        generate code for PowerPC 603/604\n\
--m403, -m405            generate code for PowerPC 403/405\n\
+-m403, -m405           generate code for PowerPC 403/405\n\
 -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, _("\
 -mppc64, -m620         generate code for PowerPC 620/625/630\n\
 -mppc64bridge          generate code for PowerPC 64, including bridge insns\n\
 -mbooke64              generate code for 64-bit PowerPC BookE\n\
 -mbooke, mbooke32      generate code for 32-bit PowerPC BookE\n\
 -mpower4               generate code for Power4 architecture\n\
--maltivec              generate code for AltiVec\n\
 -mcom                  generate code Power/PowerPC common instructions\n\
--many                  generate code for any architecture (PWR/PWRX/PPC)\n\
--mregnames             Allow symbolic names for registers\n\
--mno-regnames          Do not allow symbolic names for registers\n"));
+-many                  generate code for any architecture (PWR/PWRX/PPC)\n"));
   fprintf (stream, _("\
+-maltivec              generate code for AltiVec\n\
 -me500, -me500x2       generate code for Motorola e500 core complex\n\
--mspe                  generate code for Motorola SPE instructions\n"));
+-mspe                  generate code for Motorola SPE instructions\n\
+-mregnames             Allow symbolic names for registers\n\
+-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\
--mlittle, -mlittle-endian\n\
+-mlittle, -mlittle-endian, -l, -le\n\
                        generate code for a little endian machine\n\
--mbig, -mbig-endian    generate code for a big endian machine\n\
+-mbig, -mbig-endian, -b, -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\
 -V                     print assembler version number\n\
@@ -1460,60 +1466,94 @@ ppc_elf_suffix (str_p, exp_p)
 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
 
   static const struct map_bfd mapping[] = {
-    MAP ("l",          (int) BFD_RELOC_LO16),
-    MAP ("h",          (int) BFD_RELOC_HI16),
-    MAP ("ha",         (int) BFD_RELOC_HI16_S),
-    MAP ("brtaken",    (int) BFD_RELOC_PPC_B16_BRTAKEN),
-    MAP ("brntaken",   (int) BFD_RELOC_PPC_B16_BRNTAKEN),
-    MAP ("got",                (int) BFD_RELOC_16_GOTOFF),
-    MAP ("got@l",      (int) BFD_RELOC_LO16_GOTOFF),
-    MAP ("got@h",      (int) BFD_RELOC_HI16_GOTOFF),
-    MAP ("got@ha",     (int) BFD_RELOC_HI16_S_GOTOFF),
-    MAP ("fixup",      (int) BFD_RELOC_CTOR), /* warning with -mrelocatable */
-    MAP ("plt",                (int) BFD_RELOC_24_PLT_PCREL),
-    MAP ("pltrel24",   (int) BFD_RELOC_24_PLT_PCREL),
-    MAP ("copy",       (int) BFD_RELOC_PPC_COPY),
-    MAP ("globdat",    (int) BFD_RELOC_PPC_GLOB_DAT),
-    MAP ("local24pc",  (int) BFD_RELOC_PPC_LOCAL24PC),
-    MAP ("local",      (int) BFD_RELOC_PPC_LOCAL24PC),
-    MAP ("pltrel",     (int) BFD_RELOC_32_PLT_PCREL),
-    MAP ("plt@l",      (int) BFD_RELOC_LO16_PLTOFF),
-    MAP ("plt@h",      (int) BFD_RELOC_HI16_PLTOFF),
-    MAP ("plt@ha",     (int) BFD_RELOC_HI16_S_PLTOFF),
-    MAP ("sdarel",     (int) BFD_RELOC_GPREL16),
-    MAP ("sectoff",    (int) BFD_RELOC_16_BASEREL),
-    MAP ("sectoff@l",  (int) BFD_RELOC_LO16_BASEREL),
-    MAP ("sectoff@h",  (int) BFD_RELOC_HI16_BASEREL),
-    MAP ("sectoff@ha", (int) BFD_RELOC_HI16_S_BASEREL),
-    MAP ("naddr",      (int) BFD_RELOC_PPC_EMB_NADDR32),
-    MAP ("naddr16",    (int) BFD_RELOC_PPC_EMB_NADDR16),
-    MAP ("naddr@l",    (int) BFD_RELOC_PPC_EMB_NADDR16_LO),
-    MAP ("naddr@h",    (int) BFD_RELOC_PPC_EMB_NADDR16_HI),
-    MAP ("naddr@ha",   (int) BFD_RELOC_PPC_EMB_NADDR16_HA),
-    MAP ("sdai16",     (int) BFD_RELOC_PPC_EMB_SDAI16),
-    MAP ("sda2rel",    (int) BFD_RELOC_PPC_EMB_SDA2REL),
-    MAP ("sda2i16",    (int) BFD_RELOC_PPC_EMB_SDA2I16),
-    MAP ("sda21",      (int) BFD_RELOC_PPC_EMB_SDA21),
-    MAP ("mrkref",     (int) BFD_RELOC_PPC_EMB_MRKREF),
-    MAP ("relsect",    (int) BFD_RELOC_PPC_EMB_RELSEC16),
-    MAP ("relsect@l",  (int) BFD_RELOC_PPC_EMB_RELST_LO),
-    MAP ("relsect@h",  (int) BFD_RELOC_PPC_EMB_RELST_HI),
-    MAP ("relsect@ha", (int) BFD_RELOC_PPC_EMB_RELST_HA),
-    MAP ("bitfld",     (int) BFD_RELOC_PPC_EMB_BIT_FLD),
-    MAP ("relsda",     (int) BFD_RELOC_PPC_EMB_RELSDA),
-    MAP ("xgot",       (int) BFD_RELOC_PPC_TOC16),
+    MAP ("l",                  (int) BFD_RELOC_LO16),
+    MAP ("h",                  (int) BFD_RELOC_HI16),
+    MAP ("ha",                 (int) BFD_RELOC_HI16_S),
+    MAP ("brtaken",            (int) BFD_RELOC_PPC_B16_BRTAKEN),
+    MAP ("brntaken",           (int) BFD_RELOC_PPC_B16_BRNTAKEN),
+    MAP ("got",                        (int) BFD_RELOC_16_GOTOFF),
+    MAP ("got@l",              (int) BFD_RELOC_LO16_GOTOFF),
+    MAP ("got@h",              (int) BFD_RELOC_HI16_GOTOFF),
+    MAP ("got@ha",             (int) BFD_RELOC_HI16_S_GOTOFF),
+    MAP ("fixup",              (int) BFD_RELOC_CTOR),
+    MAP ("plt",                        (int) BFD_RELOC_24_PLT_PCREL),
+    MAP ("pltrel24",           (int) BFD_RELOC_24_PLT_PCREL),
+    MAP ("copy",               (int) BFD_RELOC_PPC_COPY),
+    MAP ("globdat",            (int) BFD_RELOC_PPC_GLOB_DAT),
+    MAP ("local24pc",          (int) BFD_RELOC_PPC_LOCAL24PC),
+    MAP ("local",              (int) BFD_RELOC_PPC_LOCAL24PC),
+    MAP ("pltrel",             (int) BFD_RELOC_32_PLT_PCREL),
+    MAP ("plt@l",              (int) BFD_RELOC_LO16_PLTOFF),
+    MAP ("plt@h",              (int) BFD_RELOC_HI16_PLTOFF),
+    MAP ("plt@ha",             (int) BFD_RELOC_HI16_S_PLTOFF),
+    MAP ("sdarel",             (int) BFD_RELOC_GPREL16),
+    MAP ("sectoff",            (int) BFD_RELOC_16_BASEREL),
+    MAP ("sectoff@l",          (int) BFD_RELOC_LO16_BASEREL),
+    MAP ("sectoff@h",          (int) BFD_RELOC_HI16_BASEREL),
+    MAP ("sectoff@ha",         (int) BFD_RELOC_HI16_S_BASEREL),
+    MAP ("naddr",              (int) BFD_RELOC_PPC_EMB_NADDR32),
+    MAP ("naddr16",            (int) BFD_RELOC_PPC_EMB_NADDR16),
+    MAP ("naddr@l",            (int) BFD_RELOC_PPC_EMB_NADDR16_LO),
+    MAP ("naddr@h",            (int) BFD_RELOC_PPC_EMB_NADDR16_HI),
+    MAP ("naddr@ha",           (int) BFD_RELOC_PPC_EMB_NADDR16_HA),
+    MAP ("sdai16",             (int) BFD_RELOC_PPC_EMB_SDAI16),
+    MAP ("sda2rel",            (int) BFD_RELOC_PPC_EMB_SDA2REL),
+    MAP ("sda2i16",            (int) BFD_RELOC_PPC_EMB_SDA2I16),
+    MAP ("sda21",              (int) BFD_RELOC_PPC_EMB_SDA21),
+    MAP ("mrkref",             (int) BFD_RELOC_PPC_EMB_MRKREF),
+    MAP ("relsect",            (int) BFD_RELOC_PPC_EMB_RELSEC16),
+    MAP ("relsect@l",          (int) BFD_RELOC_PPC_EMB_RELST_LO),
+    MAP ("relsect@h",          (int) BFD_RELOC_PPC_EMB_RELST_HI),
+    MAP ("relsect@ha",         (int) BFD_RELOC_PPC_EMB_RELST_HA),
+    MAP ("bitfld",             (int) BFD_RELOC_PPC_EMB_BIT_FLD),
+    MAP ("relsda",             (int) BFD_RELOC_PPC_EMB_RELSDA),
+    MAP ("xgot",               (int) BFD_RELOC_PPC_TOC16),
+    MAP ("tls",                        (int) BFD_RELOC_PPC_TLS),
+    MAP ("dtpmod",             (int) BFD_RELOC_PPC_DTPMOD),
+    MAP ("dtprel",             (int) BFD_RELOC_PPC_DTPREL),
+    MAP ("dtprel@l",           (int) BFD_RELOC_PPC_DTPREL16_LO),
+    MAP ("dtprel@h",           (int) BFD_RELOC_PPC_DTPREL16_HI),
+    MAP ("dtprel@ha",          (int) BFD_RELOC_PPC_DTPREL16_HA),
+    MAP ("tprel",              (int) BFD_RELOC_PPC_TPREL),
+    MAP ("tprel@l",            (int) BFD_RELOC_PPC_TPREL16_LO),
+    MAP ("tprel@h",            (int) BFD_RELOC_PPC_TPREL16_HI),
+    MAP ("tprel@ha",           (int) BFD_RELOC_PPC_TPREL16_HA),
+    MAP ("got@tlsgd",          (int) BFD_RELOC_PPC_GOT_TLSGD16),
+    MAP ("got@tlsgd@l",                (int) BFD_RELOC_PPC_GOT_TLSGD16_LO),
+    MAP ("got@tlsgd@h",                (int) BFD_RELOC_PPC_GOT_TLSGD16_HI),
+    MAP ("got@tlsgd@ha",       (int) BFD_RELOC_PPC_GOT_TLSGD16_HA),
+    MAP ("got@tlsld",          (int) BFD_RELOC_PPC_GOT_TLSLD16),
+    MAP ("got@tlsld@l",                (int) BFD_RELOC_PPC_GOT_TLSLD16_LO),
+    MAP ("got@tlsld@h",                (int) BFD_RELOC_PPC_GOT_TLSLD16_HI),
+    MAP ("got@tlsld@ha",       (int) BFD_RELOC_PPC_GOT_TLSLD16_HA),
+    MAP ("got@dtprel",         (int) BFD_RELOC_PPC_GOT_DTPREL16),
+    MAP ("got@dtprel@l",       (int) BFD_RELOC_PPC_GOT_DTPREL16_LO),
+    MAP ("got@dtprel@h",       (int) BFD_RELOC_PPC_GOT_DTPREL16_HI),
+    MAP ("got@dtprel@ha",      (int) BFD_RELOC_PPC_GOT_DTPREL16_HA),
+    MAP ("got@tprel",          (int) BFD_RELOC_PPC_GOT_TPREL16),
+    MAP ("got@tprel@l",                (int) BFD_RELOC_PPC_GOT_TPREL16_LO),
+    MAP ("got@tprel@h",                (int) BFD_RELOC_PPC_GOT_TPREL16_HI),
+    MAP ("got@tprel@ha",       (int) BFD_RELOC_PPC_GOT_TPREL16_HA),
     /* The following are only valid for ppc64.  Negative values are
        used instead of a flag.  */
-    MAP ("higher",     - (int) BFD_RELOC_PPC64_HIGHER),
-    MAP ("highera",    - (int) BFD_RELOC_PPC64_HIGHER_S),
-    MAP ("highest",    - (int) BFD_RELOC_PPC64_HIGHEST),
-    MAP ("highesta",   - (int) BFD_RELOC_PPC64_HIGHEST_S),
-    MAP ("tocbase",    - (int) BFD_RELOC_PPC64_TOC),
-    MAP ("toc",                - (int) BFD_RELOC_PPC_TOC16),
-    MAP ("toc@l",      - (int) BFD_RELOC_PPC64_TOC16_LO),
-    MAP ("toc@h",      - (int) BFD_RELOC_PPC64_TOC16_HI),
-    MAP ("toc@ha",     - (int) BFD_RELOC_PPC64_TOC16_HA),
-    { (char *) 0, 0,   (int) BFD_RELOC_UNUSED }
+    MAP ("higher",             - (int) BFD_RELOC_PPC64_HIGHER),
+    MAP ("highera",            - (int) BFD_RELOC_PPC64_HIGHER_S),
+    MAP ("highest",            - (int) BFD_RELOC_PPC64_HIGHEST),
+    MAP ("highesta",           - (int) BFD_RELOC_PPC64_HIGHEST_S),
+    MAP ("tocbase",            - (int) BFD_RELOC_PPC64_TOC),
+    MAP ("toc",                        - (int) BFD_RELOC_PPC_TOC16),
+    MAP ("toc@l",              - (int) BFD_RELOC_PPC64_TOC16_LO),
+    MAP ("toc@h",              - (int) BFD_RELOC_PPC64_TOC16_HI),
+    MAP ("toc@ha",             - (int) BFD_RELOC_PPC64_TOC16_HA),
+    MAP ("dtprel@higher",      - (int) BFD_RELOC_PPC64_DTPREL16_HIGHER),
+    MAP ("dtprel@highera",     - (int) BFD_RELOC_PPC64_DTPREL16_HIGHERA),
+    MAP ("dtprel@highest",     - (int) BFD_RELOC_PPC64_DTPREL16_HIGHEST),
+    MAP ("dtprel@highesta",    - (int) BFD_RELOC_PPC64_DTPREL16_HIGHESTA),
+    MAP ("tprel@higher",       - (int) BFD_RELOC_PPC64_TPREL16_HIGHER),
+    MAP ("tprel@highera",      - (int) BFD_RELOC_PPC64_TPREL16_HIGHERA),
+    MAP ("tprel@highest",      - (int) BFD_RELOC_PPC64_TPREL16_HIGHEST),
+    MAP ("tprel@highesta",     - (int) BFD_RELOC_PPC64_TPREL16_HIGHESTA),
+    { (char *) 0, 0,           (int) BFD_RELOC_UNUSED }
   };
 
   if (*str++ != '@')
@@ -1545,12 +1585,13 @@ ppc_elf_suffix (str_p, exp_p)
            reloc = -reloc;
          }
 
-       if (exp_p->X_add_number != 0
-           && (reloc == (int) BFD_RELOC_16_GOTOFF
-               || reloc == (int) BFD_RELOC_LO16_GOTOFF
-               || reloc == (int) BFD_RELOC_HI16_GOTOFF
-               || reloc == (int) BFD_RELOC_HI16_S_GOTOFF))
-         as_warn (_("identifier+constant@got means identifier@got+constant"));
+       if (!ppc_obj64)
+         if (exp_p->X_add_number != 0
+             && (reloc == (int) BFD_RELOC_16_GOTOFF
+                 || reloc == (int) BFD_RELOC_LO16_GOTOFF
+                 || reloc == (int) BFD_RELOC_HI16_GOTOFF
+                 || reloc == (int) BFD_RELOC_HI16_S_GOTOFF))
+           as_warn (_("identifier+constant@got means identifier@got+constant"));
 
        /* Now check for identifier@suffix+constant.  */
        if (*str == '-' || *str == '+')
@@ -2363,6 +2404,25 @@ md_assemble (str)
 #ifdef OBJ_ELF
       else if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
        {
+         /* Some TLS tweaks.  */
+         switch (reloc)
+           {
+           default:
+             break;
+           case BFD_RELOC_PPC_TLS:
+             insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2,
+                                        (char *) NULL, 0);
+             break;
+         /* We'll only use the 32 (or 64) bit form of these relocations
+            in constants.  Instructions get the 16 bit form.  */
+           case BFD_RELOC_PPC_DTPREL:
+             reloc = BFD_RELOC_PPC_DTPREL16;
+             break;
+           case BFD_RELOC_PPC_TPREL:
+             reloc = BFD_RELOC_PPC_TPREL16;
+             break;
+           }
+
          /* For the absolute forms of branches, convert the PC
             relative form back into the absolute.  */
          if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
@@ -2387,7 +2447,7 @@ md_assemble (str)
            }
 
          if (ppc_obj64
-             && (operand->flags & PPC_OPERAND_DS) != 0)
+             && (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
            {
              switch (reloc)
                {
@@ -2424,6 +2484,23 @@ md_assemble (str)
                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;
@@ -2675,7 +2752,7 @@ ppc_section_letter (letter, ptr_msg)
     return SHF_EXCLUDE;
 
   *ptr_msg = _("Bad .section directive: want a,e,w,x,M,S,G,T in string");
-  return 0;
+  return -1;
 }
 
 int
@@ -5256,7 +5333,7 @@ ppc_force_relocation (fix)
                  <= fix->fx_frag->fr_address))))
     return 1;
 
-  return S_FORCE_RELOC (fix->fx_addsy);
+  return generic_force_reloc (fix);
 }
 
 #endif /* OBJ_XCOFF */
@@ -5278,14 +5355,16 @@ ppc_force_relocation (fix)
     case BFD_RELOC_PPC_BA16_BRTAKEN:
     case BFD_RELOC_PPC_BA16_BRNTAKEN:
     case BFD_RELOC_PPC64_TOC:
-    case BFD_RELOC_VTABLE_INHERIT:
-    case BFD_RELOC_VTABLE_ENTRY:
       return 1;
     default:
       break;
     }
 
-  return S_FORCE_RELOC (fix->fx_addsy);
+  if (fix->fx_r_type >= BFD_RELOC_PPC_TLS
+      && fix->fx_r_type <= BFD_RELOC_PPC64_DTPREL16_HIGHESTA)
+    return 1;
+
+  return generic_force_reloc (fix);
 }
 
 int
@@ -5299,6 +5378,8 @@ ppc_fix_adjustable (fix)
          && fix->fx_r_type != BFD_RELOC_GPREL16
          && 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_pcrel
              || (fix->fx_subsy != NULL
                  && (S_GET_SEGMENT (fix->fx_subsy)
@@ -5447,15 +5528,26 @@ md_apply_fix3 (fixP, valP, seg)
 #if defined (OBJ_XCOFF) || defined (OBJ_ELF)
       else if ((operand->flags & PPC_OPERAND_PARENS) != 0
               && operand->bits == 16
-              && operand->shift == 0
-              && ppc_is_toc_sym (fixP->fx_addsy))
+              && operand->shift == 0)
        {
-         fixP->fx_r_type = BFD_RELOC_PPC_TOC16;
+         if (ppc_is_toc_sym (fixP->fx_addsy))
+           {
+             fixP->fx_r_type = BFD_RELOC_PPC_TOC16;
 #ifdef OBJ_ELF
-         if (ppc_obj64
-             && (operand->flags & PPC_OPERAND_DS) != 0)
-           fixP->fx_r_type = BFD_RELOC_PPC64_TOC16_DS;
+             if (ppc_obj64
+                 && (operand->flags & PPC_OPERAND_DS) != 0)
+               fixP->fx_r_type = BFD_RELOC_PPC64_TOC16_DS;
 #endif
+           }
+         else
+           {
+             fixP->fx_r_type = BFD_RELOC_16;
+#ifdef OBJ_ELF
+             if (ppc_obj64
+                 && (operand->flags & PPC_OPERAND_DS) != 0)
+               fixP->fx_r_type = BFD_RELOC_PPC64_ADDR16_DS;
+#endif
+           }
          fixP->fx_size = 2;
          if (target_big_endian)
            fixP->fx_where += 2;
@@ -5622,19 +5714,72 @@ md_apply_fix3 (fixP, valP, seg)
            abort ();
          {
            unsigned char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
-           unsigned long val;
+           long val, mask;
 
            if (target_big_endian)
-             val = bfd_getb16 (where);
+             val = bfd_getb32 (where - 2);
            else
-             val = bfd_getl16 (where);
-           val |= (value & 0xfffc);
+             val = bfd_getl32 (where);
+           mask = 0xfffc;
+           /* lq insns reserve the four lsbs.  */
+           if ((ppc_cpu & PPC_OPCODE_POWER4) != 0
+               && (val & (0x3f << 26)) == (56 << 26))
+             mask = 0xfff0;
+           val |= value & mask;
            if (target_big_endian)
              bfd_putb16 ((bfd_vma) val, where);
            else
              bfd_putl16 ((bfd_vma) val, where);
          }
          break;
+
+       case BFD_RELOC_PPC_B16_BRTAKEN:
+       case BFD_RELOC_PPC_B16_BRNTAKEN:
+       case BFD_RELOC_PPC_BA16_BRTAKEN:
+       case BFD_RELOC_PPC_BA16_BRNTAKEN:
+         break;
+
+       case BFD_RELOC_PPC_TLS:
+       case BFD_RELOC_PPC_DTPMOD:
+       case BFD_RELOC_PPC_TPREL16:
+       case BFD_RELOC_PPC_TPREL16_LO:
+       case BFD_RELOC_PPC_TPREL16_HI:
+       case BFD_RELOC_PPC_TPREL16_HA:
+       case BFD_RELOC_PPC_TPREL:
+       case BFD_RELOC_PPC_DTPREL16:
+       case BFD_RELOC_PPC_DTPREL16_LO:
+       case BFD_RELOC_PPC_DTPREL16_HI:
+       case BFD_RELOC_PPC_DTPREL16_HA:
+       case BFD_RELOC_PPC_DTPREL:
+       case BFD_RELOC_PPC_GOT_TLSGD16:
+       case BFD_RELOC_PPC_GOT_TLSGD16_LO:
+       case BFD_RELOC_PPC_GOT_TLSGD16_HI:
+       case BFD_RELOC_PPC_GOT_TLSGD16_HA:
+       case BFD_RELOC_PPC_GOT_TLSLD16:
+       case BFD_RELOC_PPC_GOT_TLSLD16_LO:
+       case BFD_RELOC_PPC_GOT_TLSLD16_HI:
+       case BFD_RELOC_PPC_GOT_TLSLD16_HA:
+       case BFD_RELOC_PPC_GOT_TPREL16:
+       case BFD_RELOC_PPC_GOT_TPREL16_LO:
+       case BFD_RELOC_PPC_GOT_TPREL16_HI:
+       case BFD_RELOC_PPC_GOT_TPREL16_HA:
+       case BFD_RELOC_PPC_GOT_DTPREL16:
+       case BFD_RELOC_PPC_GOT_DTPREL16_LO:
+       case BFD_RELOC_PPC_GOT_DTPREL16_HI:
+       case BFD_RELOC_PPC_GOT_DTPREL16_HA:
+       case BFD_RELOC_PPC64_TPREL16_DS:
+       case BFD_RELOC_PPC64_TPREL16_LO_DS:
+       case BFD_RELOC_PPC64_TPREL16_HIGHER:
+       case BFD_RELOC_PPC64_TPREL16_HIGHERA:
+       case BFD_RELOC_PPC64_TPREL16_HIGHEST:
+       case BFD_RELOC_PPC64_TPREL16_HIGHESTA:
+       case BFD_RELOC_PPC64_DTPREL16_DS:
+       case BFD_RELOC_PPC64_DTPREL16_LO_DS:
+       case BFD_RELOC_PPC64_DTPREL16_HIGHER:
+       case BFD_RELOC_PPC64_DTPREL16_HIGHERA:
+       case BFD_RELOC_PPC64_DTPREL16_HIGHEST:
+       case BFD_RELOC_PPC64_DTPREL16_HIGHESTA:
+         break;
 #endif
          /* Because SDA21 modifies the register field, the size is set to 4
             bytes, rather than 2, so offset it here appropriately.  */
This page took 0.067449 seconds and 4 git commands to generate.