merge from gcc
[deliverable/binutils-gdb.git] / gas / config / tc-sparc.c
index ea49bbab1d40d6dc1ea6f0daf02acfb20ff9657d..10a1411b5260f677576f78e3d5729bc8181f7ad3 100644 (file)
@@ -16,8 +16,8 @@
 
    You should have received a copy of the GNU General Public
    License along with GAS; see the file COPYING.  If not, write
-   to the Free Software Foundation, 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   to the Free Software Foundation, 51 Franklin Street - Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include <stdio.h>
 
@@ -174,9 +174,6 @@ const pseudo_typeS md_pseudo_table[] =
   {NULL, 0, 0},
 };
 
-/* Size of relocation record.  */
-const int md_reloc_size = 12;
-
 /* This array holds the chars that always start a comment.  If the
    pre-processor is disabled, these aren't very useful.  */
 const char comment_chars[] = "!";      /* JF removed '|' from
@@ -207,7 +204,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
    changed in read.c.  Ideally it shouldn't have to know about it at all,
    but nothing is ideal around here.  */
 
-#define isoctal(c)  ((unsigned) ((c) - '0') < '8')
+#define isoctal(c)  ((unsigned) ((c) - '0') < 8)
 
 struct sparc_it
   {
@@ -337,6 +334,10 @@ sparc_target_format ()
 #endif
 #endif
 
+#ifdef TE_VXWORKS
+  return "elf32-sparc-vxworks";
+#endif
+
 #ifdef OBJ_ELF
   return sparc_arch_size == 64 ? "elf64-sparc" : "elf32-sparc";
 #endif
@@ -727,7 +728,7 @@ struct
   {NULL, NULL, NULL},
 };
 \f
-/* sparc64 privileged registers.  */
+/* sparc64 privileged and hyperprivileged registers.  */
 
 struct priv_reg_entry
 {
@@ -753,10 +754,22 @@ struct priv_reg_entry priv_reg_table[] =
   {"otherwin", 13},
   {"wstate", 14},
   {"fq", 15},
+  {"gl", 16},
   {"ver", 31},
   {"", -1},                    /* End marker.  */
 };
 
+struct priv_reg_entry hpriv_reg_table[] =
+{
+  {"hpstate", 0},
+  {"htstate", 1},
+  {"hintp", 3},
+  {"htba", 5},
+  {"hver", 6},
+  {"hstick_cmpr", 31},
+  {"", -1},                    /* End marker.  */
+};
+
 /* v9a specific asrs.  */
 
 struct priv_reg_entry v9a_asr_table[] =
@@ -1575,6 +1588,42 @@ sparc_ip (str, pinsn)
                  goto error;
                }
 
+           case '$':
+           case '%':
+             /* Parse a sparc64 hyperprivileged register.  */
+             if (*s == '%')
+               {
+                 struct priv_reg_entry *p = hpriv_reg_table;
+                 unsigned int len = 9999999; /* Init to make gcc happy.  */
+
+                 s += 1;
+                 while (p->name[0] > s[0])
+                   p++;
+                 while (p->name[0] == s[0])
+                   {
+                     len = strlen (p->name);
+                     if (strncmp (p->name, s, len) == 0)
+                       break;
+                     p++;
+                   }
+                 if (p->name[0] != s[0])
+                   {
+                     error_message = _(": unrecognizable hyperprivileged register");
+                     goto error;
+                   }
+                 if (*args == '$')
+                   opcode |= (p->regnum << 14);
+                 else
+                   opcode |= (p->regnum << 25);
+                 s += len;
+                 continue;
+               }
+             else
+               {
+                 error_message = _(": unrecognizable hyperprivileged register");
+                 goto error;
+               }
+
            case '_':
            case '/':
              /* Parse a v9a/v9b ancillary state register.  */
@@ -2486,12 +2535,12 @@ sparc_ip (str, pinsn)
                      goto error;
                    }
 
-                 /* Constants that won't fit are checked in md_apply_fix3
+                 /* Constants that won't fit are checked in md_apply_fix
                     and bfd_install_relocation.
                     ??? It would be preferable to install the constants
                     into the insn here and save having to create a fixS
                     for each one.  There already exists code to handle
-                    all the various cases (e.g. in md_apply_fix3 and
+                    all the various cases (e.g. in md_apply_fix and
                     bfd_install_relocation) so duplicating all that code
                     here isn't right.  */
                }
@@ -2879,7 +2928,7 @@ output_insn (insn, the_insn)
                                 the_insn->pcrel,
                                 the_insn->reloc);
       /* Turn off overflow checking in fixup_segment.  We'll do our
-        own overflow checking in md_apply_fix3.  This is necessary because
+        own overflow checking in md_apply_fix.  This is necessary because
         the insn size is 4 and fixup_segment will signal an overflow for
         large 8 byte quantities.  */
       fixP->fx_no_overflow = 1;
@@ -2998,7 +3047,7 @@ md_number_to_chars (buf, val, n)
    hold.  */
 
 void
-md_apply_fix3 (fixP, valP, segment)
+md_apply_fix (fixP, valP, segment)
      fixS *fixP;
      valueT *valP;
      segT segment ATTRIBUTE_UNUSED;
@@ -3482,6 +3531,10 @@ tc_gen_reloc (section, fixp)
 #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
 #else
 #define GOT_NAME "__GLOBAL_OFFSET_TABLE_"
+#endif
+#ifdef TE_VXWORKS
+#define GOTT_BASE "__GOTT_BASE__"
+#define GOTT_INDEX "__GOTT_INDEX__"
 #endif
 
   /* This code must be parallel to the OBJ_ELF tc_fix_adjustable.  */
@@ -3495,18 +3548,30 @@ tc_gen_reloc (section, fixp)
            code = BFD_RELOC_SPARC_WPLT30;
          break;
        case BFD_RELOC_HI22:
-         if (fixp->fx_addsy != NULL
-             && strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
-           code = BFD_RELOC_SPARC_PC22;
-         else
-           code = BFD_RELOC_SPARC_GOT22;
+         code = BFD_RELOC_SPARC_GOT22;
+         if (fixp->fx_addsy != NULL)
+           {
+             if (strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
+               code = BFD_RELOC_SPARC_PC22;
+#ifdef TE_VXWORKS
+             if (strcmp (S_GET_NAME (fixp->fx_addsy), GOTT_BASE) == 0
+                 || strcmp (S_GET_NAME (fixp->fx_addsy), GOTT_INDEX) == 0)
+               code = BFD_RELOC_HI22; /* Unchanged.  */
+#endif
+           }
          break;
        case BFD_RELOC_LO10:
-         if (fixp->fx_addsy != NULL
-             && strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
-           code = BFD_RELOC_SPARC_PC10;
-         else
-           code = BFD_RELOC_SPARC_GOT10;
+         code = BFD_RELOC_SPARC_GOT10;
+         if (fixp->fx_addsy != NULL)
+           {
+             if (strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
+               code = BFD_RELOC_SPARC_PC10;
+#ifdef TE_VXWORKS
+             if (strcmp (S_GET_NAME (fixp->fx_addsy), GOTT_BASE) == 0
+                 || strcmp (S_GET_NAME (fixp->fx_addsy), GOTT_INDEX) == 0)
+               code = BFD_RELOC_LO10; /* Unchanged.  */
+#endif
+           }
          break;
        case BFD_RELOC_SPARC13:
          code = BFD_RELOC_SPARC_GOT13;
@@ -3961,9 +4026,7 @@ s_common (ignore)
       goto allocate_common;
     }
 
-#ifdef BFD_ASSEMBLER
   symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
-#endif
 
   demand_empty_rest_of_line ();
   return;
This page took 0.026218 seconds and 4 git commands to generate.