include/coff/
[deliverable/binutils-gdb.git] / gas / config / tc-ppc.c
index 2515ab5abfd391e18da8e5df2b91992bce4277d1..537b676be7e5d234801ca7fecfa2a43cc0c9bc28 100644 (file)
@@ -1,6 +1,6 @@
 /* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
 /* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of GAS, the GNU Assembler.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of GAS, the GNU Assembler.
@@ -358,9 +358,42 @@ static const struct pd_reg pre_defined_registers[] =
   { "f.3", 3 },
   { "f.30", 30 },
   { "f.31", 31 },
   { "f.3", 3 },
   { "f.30", 30 },
   { "f.31", 31 },
+
+  { "f.32", 32 },    /* Extended floating point scalar registers (ISA 2.06).  */
+  { "f.33", 33 },
+  { "f.34", 34 },
+  { "f.35", 35 },
+  { "f.36", 36 },
+  { "f.37", 37 },
+  { "f.38", 38 },
+  { "f.39", 39 },
   { "f.4", 4 },
   { "f.4", 4 },
+  { "f.40", 40 },
+  { "f.41", 41 },
+  { "f.42", 42 },
+  { "f.43", 43 },
+  { "f.44", 44 },
+  { "f.45", 45 },
+  { "f.46", 46 },
+  { "f.47", 47 },
+  { "f.48", 48 },
+  { "f.49", 49 },
   { "f.5", 5 },
   { "f.5", 5 },
+  { "f.50", 50 },
+  { "f.51", 51 },
+  { "f.52", 52 },
+  { "f.53", 53 },
+  { "f.54", 54 },
+  { "f.55", 55 },
+  { "f.56", 56 },
+  { "f.57", 57 },
+  { "f.58", 58 },
+  { "f.59", 59 },
   { "f.6", 6 },
   { "f.6", 6 },
+  { "f.60", 60 },
+  { "f.61", 61 },
+  { "f.62", 62 },
+  { "f.63", 63 },
   { "f.7", 7 },
   { "f.8", 8 },
   { "f.9", 9 },
   { "f.7", 7 },
   { "f.8", 8 },
   { "f.9", 9 },
@@ -391,9 +424,42 @@ static const struct pd_reg pre_defined_registers[] =
   { "f3", 3 },
   { "f30", 30 },
   { "f31", 31 },
   { "f3", 3 },
   { "f30", 30 },
   { "f31", 31 },
+
+  { "f32", 32 },    /* Extended floating point scalar registers (ISA 2.06).  */
+  { "f33", 33 },
+  { "f34", 34 },
+  { "f35", 35 },
+  { "f36", 36 },
+  { "f37", 37 },
+  { "f38", 38 },
+  { "f39", 39 },
   { "f4", 4 },
   { "f4", 4 },
+  { "f40", 40 },
+  { "f41", 41 },
+  { "f42", 42 },
+  { "f43", 43 },
+  { "f44", 44 },
+  { "f45", 45 },
+  { "f46", 46 },
+  { "f47", 47 },
+  { "f48", 48 },
+  { "f49", 49 },
   { "f5", 5 },
   { "f5", 5 },
+  { "f50", 50 },
+  { "f51", 51 },
+  { "f52", 52 },
+  { "f53", 53 },
+  { "f54", 54 },
+  { "f55", 55 },
+  { "f56", 56 },
+  { "f57", 57 },
+  { "f58", 58 },
+  { "f59", 59 },
   { "f6", 6 },
   { "f6", 6 },
+  { "f60", 60 },
+  { "f61", 61 },
+  { "f62", 62 },
+  { "f63", 63 },
   { "f7", 7 },
   { "f8", 8 },
   { "f9", 9 },
   { "f7", 7 },
   { "f8", 8 },
   { "f9", 9 },
@@ -501,7 +567,7 @@ static const struct pd_reg pre_defined_registers[] =
   { "srr0", 26 }, /* Machine Status Save/Restore Register 0 */
   { "srr1", 27 }, /* Machine Status Save/Restore Register 1 */
 
   { "srr0", 26 }, /* Machine Status Save/Restore Register 0 */
   { "srr1", 27 }, /* Machine Status Save/Restore Register 1 */
 
-  { "v.0", 0 },     /* Vector registers */
+  { "v.0", 0 },     /* Vector (Altivec/VMX) registers */
   { "v.1", 1 },
   { "v.10", 10 },
   { "v.11", 11 },
   { "v.1", 1 },
   { "v.10", 10 },
   { "v.11", 11 },
@@ -567,6 +633,136 @@ static const struct pd_reg pre_defined_registers[] =
   { "v8", 8 },
   { "v9", 9 },
 
   { "v8", 8 },
   { "v9", 9 },
 
+  { "vs.0", 0 },     /* Vector Scalar (VSX) registers (ISA 2.06).  */
+  { "vs.1", 1 },
+  { "vs.10", 10 },
+  { "vs.11", 11 },
+  { "vs.12", 12 },
+  { "vs.13", 13 },
+  { "vs.14", 14 },
+  { "vs.15", 15 },
+  { "vs.16", 16 },
+  { "vs.17", 17 },
+  { "vs.18", 18 },
+  { "vs.19", 19 },
+  { "vs.2", 2 },
+  { "vs.20", 20 },
+  { "vs.21", 21 },
+  { "vs.22", 22 },
+  { "vs.23", 23 },
+  { "vs.24", 24 },
+  { "vs.25", 25 },
+  { "vs.26", 26 },
+  { "vs.27", 27 },
+  { "vs.28", 28 },
+  { "vs.29", 29 },
+  { "vs.3", 3 },
+  { "vs.30", 30 },
+  { "vs.31", 31 },
+  { "vs.32", 32 },
+  { "vs.33", 33 },
+  { "vs.34", 34 },
+  { "vs.35", 35 },
+  { "vs.36", 36 },
+  { "vs.37", 37 },
+  { "vs.38", 38 },
+  { "vs.39", 39 },
+  { "vs.4", 4 },
+  { "vs.40", 40 },
+  { "vs.41", 41 },
+  { "vs.42", 42 },
+  { "vs.43", 43 },
+  { "vs.44", 44 },
+  { "vs.45", 45 },
+  { "vs.46", 46 },
+  { "vs.47", 47 },
+  { "vs.48", 48 },
+  { "vs.49", 49 },
+  { "vs.5", 5 },
+  { "vs.50", 50 },
+  { "vs.51", 51 },
+  { "vs.52", 52 },
+  { "vs.53", 53 },
+  { "vs.54", 54 },
+  { "vs.55", 55 },
+  { "vs.56", 56 },
+  { "vs.57", 57 },
+  { "vs.58", 58 },
+  { "vs.59", 59 },
+  { "vs.6", 6 },
+  { "vs.60", 60 },
+  { "vs.61", 61 },
+  { "vs.62", 62 },
+  { "vs.63", 63 },
+  { "vs.7", 7 },
+  { "vs.8", 8 },
+  { "vs.9", 9 },
+
+  { "vs0", 0 },
+  { "vs1", 1 },
+  { "vs10", 10 },
+  { "vs11", 11 },
+  { "vs12", 12 },
+  { "vs13", 13 },
+  { "vs14", 14 },
+  { "vs15", 15 },
+  { "vs16", 16 },
+  { "vs17", 17 },
+  { "vs18", 18 },
+  { "vs19", 19 },
+  { "vs2", 2 },
+  { "vs20", 20 },
+  { "vs21", 21 },
+  { "vs22", 22 },
+  { "vs23", 23 },
+  { "vs24", 24 },
+  { "vs25", 25 },
+  { "vs26", 26 },
+  { "vs27", 27 },
+  { "vs28", 28 },
+  { "vs29", 29 },
+  { "vs3", 3 },
+  { "vs30", 30 },
+  { "vs31", 31 },
+  { "vs32", 32 },
+  { "vs33", 33 },
+  { "vs34", 34 },
+  { "vs35", 35 },
+  { "vs36", 36 },
+  { "vs37", 37 },
+  { "vs38", 38 },
+  { "vs39", 39 },
+  { "vs4", 4 },
+  { "vs40", 40 },
+  { "vs41", 41 },
+  { "vs42", 42 },
+  { "vs43", 43 },
+  { "vs44", 44 },
+  { "vs45", 45 },
+  { "vs46", 46 },
+  { "vs47", 47 },
+  { "vs48", 48 },
+  { "vs49", 49 },
+  { "vs5", 5 },
+  { "vs50", 50 },
+  { "vs51", 51 },
+  { "vs52", 52 },
+  { "vs53", 53 },
+  { "vs54", 54 },
+  { "vs55", 55 },
+  { "vs56", 56 },
+  { "vs57", 57 },
+  { "vs58", 58 },
+  { "vs59", 59 },
+  { "vs6", 6 },
+  { "vs60", 60 },
+  { "vs61", 61 },
+  { "vs62", 62 },
+  { "vs63", 63 },
+  { "vs7", 7 },
+  { "vs8", 8 },
+  { "vs9", 9 },
+
   { "xer", 1 },
 
 };
   { "xer", 1 },
 
 };
@@ -819,156 +1015,11 @@ const struct option md_longopts[] = {
 };
 const size_t md_longopts_size = sizeof (md_longopts);
 
 };
 const size_t md_longopts_size = sizeof (md_longopts);
 
-
-/* Handle -m options that set cpu type, and .machine arg.  */
-
-static int
-parse_cpu (const char *arg)
-{
-  ppc_cpu_t retain_flags =
-    ppc_cpu & (PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX | PPC_OPCODE_SPE);
-
-  /* -mpwrx and -mpwr2 mean to assemble for the IBM POWER/2
-     (RIOS2).  */
-  if (strcmp (arg, "pwrx") == 0 || strcmp (arg, "pwr2") == 0)
-    ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32;
-  /* -mpwr means to assemble for the IBM POWER (RIOS1).  */
-  else if (strcmp (arg, "pwr") == 0)
-    ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
-  /* -m601 means to assemble for the PowerPC 601, which includes
-     instructions that are holdovers from the Power.  */
-  else if (strcmp (arg, "601") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-              | PPC_OPCODE_601 | PPC_OPCODE_32);
-  /* -mppc, -mppc32, -m603, and -m604 mean to assemble for the
-     PowerPC 603/604.  */
-  else if (strcmp (arg, "ppc") == 0
-          || strcmp (arg, "ppc32") == 0
-          || strcmp (arg, "603") == 0
-          || strcmp (arg, "604") == 0)
-    ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
-  /* Do all PPC750s have paired single ops?  */
-  else if (strcmp (arg, "750cl") == 0)
-    ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_PPCPS;
-  else if (strcmp (arg, "403") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-              | PPC_OPCODE_403 | PPC_OPCODE_32);
-  else if (strcmp (arg, "405") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-              | PPC_OPCODE_403 | PPC_OPCODE_405 | PPC_OPCODE_32);
-  else if (strcmp (arg, "440") == 0
-          || strcmp (arg, "464") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
-              | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI);
-  else if (strcmp (arg, "7400") == 0
-          || strcmp (arg, "7410") == 0
-          || strcmp (arg, "7450") == 0
-          || strcmp (arg, "7455") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-              | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32);
-  else if (strcmp (arg, "e300") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32
-              | PPC_OPCODE_E300);
-  else if (strcmp (arg, "altivec") == 0)
-    {
-      if (ppc_cpu == 0)
-       ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC;
-
-      retain_flags |= PPC_OPCODE_ALTIVEC;
-    }
-  else if (strcmp (arg, "vsx") == 0)
-    {
-      if (ppc_cpu == 0)
-       ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC;
-
-      retain_flags |= PPC_OPCODE_VSX;
-    }
-  else if (strcmp (arg, "e500") == 0 || strcmp (arg, "e500x2") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
-                | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
-                | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
-                | PPC_OPCODE_RFMCI | PPC_OPCODE_E500MC);
-    }
-  else if (strcmp (arg, "e500mc") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
-                | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
-                | PPC_OPCODE_RFMCI | PPC_OPCODE_E500MC);
-    }
-  else if (strcmp (arg, "spe") == 0)
-    {
-      if (ppc_cpu == 0)
-       ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_EFS;
-
-      retain_flags |= PPC_OPCODE_SPE;
-    }
-  /* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC
-     620.  */
-  else if (strcmp (arg, "ppc64") == 0 || strcmp (arg, "620") == 0)
-    {
-      ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
-    }
-  else if (strcmp (arg, "ppc64bridge") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-                | PPC_OPCODE_64_BRIDGE | PPC_OPCODE_64);
-    }
-  /* -mbooke/-mbooke32 mean enable 32-bit BookE support.  */
-  else if (strcmp (arg, "booke") == 0 || strcmp (arg, "booke32") == 0)
-    {
-      ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32;
-    }
-  else if (strcmp (arg, "power4") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-                | PPC_OPCODE_64 | PPC_OPCODE_POWER4);
-    }
-  else if (strcmp (arg, "power5") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-                | PPC_OPCODE_64 | PPC_OPCODE_POWER4
-                | PPC_OPCODE_POWER5);
-    }
-  else if (strcmp (arg, "power6") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-                | PPC_OPCODE_64 | PPC_OPCODE_POWER4
-                | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
-                | PPC_OPCODE_ALTIVEC);
-    }
-  else if (strcmp (arg, "power7") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-                | PPC_OPCODE_64 | PPC_OPCODE_POWER4
-                | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
-                | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX);
-    }
-  else if (strcmp (arg, "cell") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-                | PPC_OPCODE_64 | PPC_OPCODE_POWER4
-                | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC);
-    }
-  /* -mcom means assemble for the common intersection between Power
-     and PowerPC.  At present, we just allow the union, rather
-     than the intersection.  */
-  else if (strcmp (arg, "com") == 0)
-    ppc_cpu = PPC_OPCODE_COMMON | PPC_OPCODE_32;
-  /* -many means to assemble for any architecture (PWR/PWRX/PPC).  */
-  else if (strcmp (arg, "any") == 0)
-    ppc_cpu |= PPC_OPCODE_ANY;
-  else
-    return 0;
-
-  /* Make sure the the Altivec, VSX and SPE bits are not lost.  */
-  ppc_cpu |= retain_flags;
-  return 1;
-}
-
 int
 md_parse_option (int c, char *arg)
 {
 int
 md_parse_option (int c, char *arg)
 {
+  ppc_cpu_t new_cpu;
+
   switch (c)
     {
     case 'u':
   switch (c)
     {
     case 'u':
@@ -1031,8 +1082,8 @@ md_parse_option (int c, char *arg)
       break;
 
     case 'm':
       break;
 
     case 'm':
-      if (parse_cpu (arg))
-       ;
+      if ((new_cpu = ppc_parse_cpu (ppc_cpu, arg)) != 0)
+       ppc_cpu = new_cpu;
 
       else if (strcmp (arg, "regnames") == 0)
        reg_names_p = TRUE;
 
       else if (strcmp (arg, "regnames") == 0)
        reg_names_p = TRUE;
@@ -1777,13 +1828,38 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
       {
        int reloc = ptr->reloc;
 
       {
        int reloc = ptr->reloc;
 
-       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"));
+       if (!ppc_obj64 && exp_p->X_add_number != 0)
+         {
+           switch (reloc)
+             {
+             case BFD_RELOC_16_GOTOFF:
+             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"));
+               break;
+
+             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_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_PPC_GOT_TPREL16:
+             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"));
+               break;
+             }
+         }
 
        /* Now check for identifier@suffix+constant.  */
        if (*str == '-' || *str == '+')
 
        /* Now check for identifier@suffix+constant.  */
        if (*str == '-' || *str == '+')
@@ -2600,121 +2676,168 @@ md_assemble (char *str)
                                     ppc_cpu, (char *) NULL, 0);
        }
 #ifdef OBJ_ELF
                                     ppc_cpu, (char *) NULL, 0);
        }
 #ifdef OBJ_ELF
-      else if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+      else
        {
        {
-         /* Some TLS tweaks.  */
-         switch (reloc)
+         if (ex.X_op == O_symbol && str[0] == '(')
            {
            {
-           default:
-             break;
-           case BFD_RELOC_PPC_TLS:
-             insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2,
-                                        ppc_cpu, (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;
-           }
+             const char *sym_name = S_GET_NAME (ex.X_add_symbol);
+             if (sym_name[0] == '.')
+               ++sym_name;
 
 
-         /* For the absolute forms of branches, convert the PC
-            relative form back into the absolute.  */
-         if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
-           {
-             switch (reloc)
+             if (strcasecmp (sym_name, "__tls_get_addr") == 0)
                {
                {
-               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;
+                 expressionS tls_exp;
+
+                 hold = input_line_pointer;
+                 input_line_pointer = str + 1;
+                 expression (&tls_exp);
+                 if (tls_exp.X_op == O_symbol)
+                   {
+                     reloc = BFD_RELOC_UNUSED;
+                     if (strncasecmp (input_line_pointer, "@tlsgd)", 7) == 0)
+                       {
+                         reloc = BFD_RELOC_PPC_TLSGD;
+                         input_line_pointer += 7;
+                       }
+                     else if (strncasecmp (input_line_pointer, "@tlsld)", 7) == 0)
+                       {
+                         reloc = BFD_RELOC_PPC_TLSLD;
+                         input_line_pointer += 7;
+                       }
+                     if (reloc != BFD_RELOC_UNUSED)
+                       {
+                         SKIP_WHITESPACE ();
+                         str = input_line_pointer;
+
+                         if (fc >= MAX_INSN_FIXUPS)
+                           as_fatal (_("too many fixups"));
+                         fixups[fc].exp = tls_exp;
+                         fixups[fc].opindex = *opindex_ptr;
+                         fixups[fc].reloc = reloc;
+                         ++fc;
+                       }
+                   }
+                 input_line_pointer = hold;
                }
            }
 
                }
            }
 
-         if (ppc_obj64
-             && (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
+         if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
            {
            {
+             /* Some TLS tweaks.  */
              switch (reloc)
                {
              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;
+               default:
                  break;
                  break;
-               case BFD_RELOC_PPC_TPREL16_LO:
-                 reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
+
+               case BFD_RELOC_PPC_TLS:
+                 insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2,
+                                            ppc_cpu, (char *) NULL, 0);
                  break;
                  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:
+
+                 /* 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;
                  break;
-               default:
-                 as_bad (_("unsupported relocation for DS offset field"));
+               case BFD_RELOC_PPC_TPREL:
+                 reloc = BFD_RELOC_PPC_TPREL16;
                  break;
                }
                  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;
+                   }
+               }
+
+             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;
+                   }
+               }
            }
 
          /* We need to generate a fixup for this expression.  */
          if (fc >= MAX_INSN_FIXUPS)
            as_fatal (_("too many fixups"));
          fixups[fc].exp = ex;
            }
 
          /* We need to generate a fixup for this expression.  */
          if (fc >= MAX_INSN_FIXUPS)
            as_fatal (_("too many fixups"));
          fixups[fc].exp = ex;
-         fixups[fc].opindex = 0;
+         fixups[fc].opindex = *opindex_ptr;
          fixups[fc].reloc = reloc;
          ++fc;
        }
          fixups[fc].reloc = reloc;
          ++fc;
        }
-#endif /* OBJ_ELF */
-
+#else /* OBJ_ELF */
       else
        {
          /* We need to generate a fixup for this expression.  */
       else
        {
          /* We need to generate a fixup for this expression.  */
@@ -2725,6 +2848,7 @@ md_assemble (char *str)
          fixups[fc].reloc = BFD_RELOC_UNUSED;
          ++fc;
        }
          fixups[fc].reloc = BFD_RELOC_UNUSED;
          ++fc;
        }
+#endif /* OBJ_ELF */
 
       if (need_paren)
        {
 
       if (need_paren)
        {
@@ -2768,10 +2892,7 @@ md_assemble (char *str)
 
 #ifdef OBJ_ELF
   /* Do we need/want a APUinfo section? */
 
 #ifdef OBJ_ELF
   /* Do we need/want a APUinfo section? */
-  if (ppc_cpu & (PPC_OPCODE_SPE
-              | PPC_OPCODE_ISEL | PPC_OPCODE_EFS
-              | PPC_OPCODE_BRLOCK | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
-              | PPC_OPCODE_RFMCI))
+  if ((ppc_cpu & PPC_OPCODE_E500MC) != 0)
     {
       /* These are all version "1".  */
       if (opcode->flags & PPC_OPCODE_SPE)
     {
       /* These are all version "1".  */
       if (opcode->flags & PPC_OPCODE_SPE)
@@ -2812,9 +2933,6 @@ md_assemble (char *str)
      md_apply_fix.  */
   for (i = 0; i < fc; i++)
     {
      md_apply_fix.  */
   for (i = 0; i < fc; i++)
     {
-      const struct powerpc_operand *operand;
-
-      operand = &powerpc_operands[fixups[i].opindex];
       if (fixups[i].reloc != BFD_RELOC_UNUSED)
        {
          reloc_howto_type *reloc_howto;
       if (fixups[i].reloc != BFD_RELOC_UNUSED)
        {
          reloc_howto_type *reloc_howto;
@@ -2861,13 +2979,18 @@ md_assemble (char *str)
            }
        }
       else
            }
        }
       else
-       fix_new_exp (frag_now,
-                    f - frag_now->fr_literal,
-                    4,
-                    &fixups[i].exp,
-                    (operand->flags & PPC_OPERAND_RELATIVE) != 0,
-                    ((bfd_reloc_code_real_type)
-                     (fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
+       {
+         const struct powerpc_operand *operand;
+
+         operand = &powerpc_operands[fixups[i].opindex];
+         fix_new_exp (frag_now,
+                      f - frag_now->fr_literal,
+                      4,
+                      &fixups[i].exp,
+                      (operand->flags & PPC_OPERAND_RELATIVE) != 0,
+                      ((bfd_reloc_code_real_type)
+                       (fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
+       }
     }
 }
 
     }
 }
 
@@ -4158,6 +4281,7 @@ ppc_machine (int ignore ATTRIBUTE_UNUSED)
   if (cpu_string != NULL)
     {
       ppc_cpu_t old_cpu = ppc_cpu;
   if (cpu_string != NULL)
     {
       ppc_cpu_t old_cpu = ppc_cpu;
+      ppc_cpu_t new_cpu;
       char *p;
 
       for (p = cpu_string; *p != 0; p++)
       char *p;
 
       for (p = cpu_string; *p != 0; p++)
@@ -4180,8 +4304,8 @@ ppc_machine (int ignore ATTRIBUTE_UNUSED)
          else
            ppc_cpu = cpu_history[--curr_hist];
        }
          else
            ppc_cpu = cpu_history[--curr_hist];
        }
-      else if (parse_cpu (cpu_string))
-       ;
+      else if ((new_cpu = ppc_parse_cpu (ppc_cpu, cpu_string)) != 0)
+       ppc_cpu = new_cpu;
       else
        as_bad (_("invalid machine `%s'"), cpu_string);
 
       else
        as_bad (_("invalid machine `%s'"), cpu_string);
 
@@ -5046,6 +5170,7 @@ ppc_frob_symbol (symbolS *sym)
     S_SET_STORAGE_CLASS (sym, C_HIDEXT);
 
   if (S_GET_STORAGE_CLASS (sym) == C_EXT
     S_SET_STORAGE_CLASS (sym, C_HIDEXT);
 
   if (S_GET_STORAGE_CLASS (sym) == C_EXT
+      || S_GET_STORAGE_CLASS (sym) == C_AIX_WEAKEXT
       || S_GET_STORAGE_CLASS (sym) == C_HIDEXT)
     {
       int i;
       || S_GET_STORAGE_CLASS (sym) == C_HIDEXT)
     {
       int i;
@@ -5617,18 +5742,19 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
      going to use the symbol value.  That means that if the reloc is
      fully resolved we want to use *valP since bfd_install_relocation is
      not being used.
      going to use the symbol value.  That means that if the reloc is
      fully resolved we want to use *valP since bfd_install_relocation is
      not being used.
-     However, if the reloc is not fully resolved we do not want to use
-     *valP, and must use fx_offset instead.  However, if the reloc
-     is PC relative, we do want to use *valP since it includes the
-     result of md_pcrel_from.  This is confusing.  */
+     However, if the reloc is not fully resolved we do not want to
+     use *valP, and must use fx_offset instead.  If the relocation
+     is PC-relative, we then need to re-apply md_pcrel_from_section
+     to this new relocation value.  */
   if (fixP->fx_addsy == (symbolS *) NULL)
     fixP->fx_done = 1;
 
   if (fixP->fx_addsy == (symbolS *) NULL)
     fixP->fx_done = 1;
 
-  else if (fixP->fx_pcrel)
-    ;
-
   else
   else
-    value = fixP->fx_offset;
+    {
+      value = fixP->fx_offset;
+      if (fixP->fx_pcrel)
+       value -= md_pcrel_from_section (fixP, seg);
+    }
 #endif
 
   if (fixP->fx_subsy != (symbolS *) NULL)
 #endif
 
   if (fixP->fx_subsy != (symbolS *) NULL)
@@ -5961,6 +6087,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
          break;
 
        case BFD_RELOC_PPC_TLS:
          break;
 
        case BFD_RELOC_PPC_TLS:
+       case BFD_RELOC_PPC_TLSGD:
+       case BFD_RELOC_PPC_TLSLD:
          break;
 
        case BFD_RELOC_PPC_DTPMOD:
          break;
 
        case BFD_RELOC_PPC_DTPMOD:
This page took 0.07764 seconds and 4 git commands to generate.