]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/config/tc-sparc.c
Annotate sparc objects with cpu hardware capabilities used.
[thirdparty/binutils-gdb.git] / gas / config / tc-sparc.c
index c98081c959aabb27ba839fadc905565eac0c01c4..974524b147ae54f14e90e8364be8fd52c0345531 100644 (file)
@@ -1,12 +1,13 @@
 /* tc-sparc.c -- Assemble for the SPARC
    Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011
    Free Software Foundation, Inc.
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
 #define U0xffffffff ((((unsigned long) 1 << 16) << 16) - 1)
 #define U0x80000000 ((((unsigned long) 1 << 16) << 15))
 
-static struct sparc_arch *lookup_arch PARAMS ((char *));
-static void init_default_arch PARAMS ((void));
-static int sparc_ip PARAMS ((char *, const struct sparc_opcode **));
-static int in_signed_range PARAMS ((bfd_signed_vma, bfd_signed_vma));
-static int in_unsigned_range PARAMS ((bfd_vma, bfd_vma));
-static int in_bitfield_range PARAMS ((bfd_signed_vma, bfd_signed_vma));
-static int sparc_ffs PARAMS ((unsigned int));
-static void synthetize_setuw PARAMS ((const struct sparc_opcode *));
-static void synthetize_setsw PARAMS ((const struct sparc_opcode *));
-static void synthetize_setx PARAMS ((const struct sparc_opcode *));
-static bfd_vma BSR PARAMS ((bfd_vma, int));
-static int cmp_reg_entry PARAMS ((const PTR, const PTR));
-static int parse_keyword_arg PARAMS ((int (*) (const char *), char **, int *));
-static int parse_const_expr_arg PARAMS ((char **, int *));
-static int get_expression PARAMS ((char *str));
+static int sparc_ip (char *, const struct sparc_opcode **);
+static int parse_keyword_arg (int (*) (const char *), char **, int *);
+static int parse_const_expr_arg (char **, int *);
+static int get_expression (char *);
 
 /* Default architecture.  */
 /* ??? The default value should be V8, but sparclite support was added
@@ -86,6 +76,12 @@ static int default_arch_size;
 /* The currently selected v9 memory model.  Currently only used for
    ELF.  */
 static enum { MM_TSO, MM_PSO, MM_RMO } sparc_memory_model = MM_RMO;
+
+#ifndef TE_SOLARIS
+/* Bitmask of instruction types seen so far, used to populate the
+   GNU attributes section with hwcap information.  */
+static int hwcap_seen;
+#endif
 #endif
 
 static int architecture_requested;
@@ -131,17 +127,16 @@ int sparc_cie_data_alignment;
 /* Handle of the OPCODE hash table.  */
 static struct hash_control *op_hash;
 
-static int mylog2 PARAMS ((int));
-static void s_data1 PARAMS ((void));
-static void s_seg PARAMS ((int));
-static void s_proc PARAMS ((int));
-static void s_reserve PARAMS ((int));
-static void s_common PARAMS ((int));
-static void s_empty PARAMS ((int));
-static void s_uacons PARAMS ((int));
-static void s_ncons PARAMS ((int));
+static void s_data1 (void);
+static void s_seg (int);
+static void s_proc (int);
+static void s_reserve (int);
+static void s_common (int);
+static void s_empty (int);
+static void s_uacons (int);
+static void s_ncons (int);
 #ifdef OBJ_ELF
-static void s_register PARAMS ((int));
+static void s_register (int);
 #endif
 
 const pseudo_typeS md_pseudo_table[] =
@@ -217,8 +212,7 @@ struct sparc_it
 
 struct sparc_it the_insn, set_insn;
 
-static void output_insn
-  PARAMS ((const struct sparc_opcode *, struct sparc_it *));
+static void output_insn (const struct sparc_opcode *, struct sparc_it *);
 \f
 /* Table of arguments to -A.
    The sparc_opcode_arch table in sparc-opc.c is insufficient and incorrect
@@ -260,8 +254,7 @@ static struct sparc_arch {
 static enum sparc_arch_types default_arch_type;
 
 static struct sparc_arch *
-lookup_arch (name)
-     char *name;
+lookup_arch (char *name)
 {
   struct sparc_arch *sa;
 
@@ -277,7 +270,7 @@ lookup_arch (name)
    architecture name.  */
 
 static void
-init_default_arch ()
+init_default_arch (void)
 {
   struct sparc_arch *sa = lookup_arch (default_arch);
 
@@ -296,7 +289,7 @@ init_default_arch ()
 /* Called by TARGET_FORMAT.  */
 
 const char *
-sparc_target_format ()
+sparc_target_format (void)
 {
   /* We don't get a chance to initialize anything before we're called,
      so handle that now.  */
@@ -451,9 +444,7 @@ struct option md_longopts[] = {
 size_t md_longopts_size = sizeof (md_longopts);
 
 int
-md_parse_option (c, arg)
-     int c;
-     char *arg;
+md_parse_option (int c, char *arg)
 {
   /* We don't get a chance to initialize anything before we're called,
      so handle that now.  */
@@ -558,6 +549,10 @@ md_parse_option (c, arg)
          as_fatal (_("No compiled in support for %d bit object file format"),
                    sparc_arch_size);
        free (list);
+
+       if (sparc_arch_size == 64
+           && max_architecture < SPARC_OPCODE_ARCH_V9)
+         max_architecture = SPARC_OPCODE_ARCH_V9;
       }
       break;
 
@@ -622,8 +617,7 @@ md_parse_option (c, arg)
 }
 
 void
-md_show_usage (stream)
-     FILE *stream;
+md_show_usage (FILE *stream)
 {
   const struct sparc_arch *arch;
   int column;
@@ -768,27 +762,31 @@ struct priv_reg_entry hpriv_reg_table[] =
   {"", -1},                    /* End marker.  */
 };
 
-/* v9a specific asrs.  */
+/* v9a specific asrs.  This table is ordered by initial
+   letter, in reverse.  */
 
 struct priv_reg_entry v9a_asr_table[] =
 {
   {"tick_cmpr", 23},
   {"sys_tick_cmpr", 25},
   {"sys_tick", 24},
+  {"stick_cmpr", 25},
+  {"stick", 24},
+  {"softint_clear", 21},
+  {"softint_set", 20},
   {"softint", 22},
   {"set_softint", 20},
   {"pic", 17},
   {"pcr", 16},
   {"gsr", 19},
   {"dcr", 18},
+  {"cps", 28},
   {"clear_softint", 21},
   {"", -1},                    /* End marker.  */
 };
 
 static int
-cmp_reg_entry (parg, qarg)
-     const PTR parg;
-     const PTR qarg;
+cmp_reg_entry (const void *parg, const void *qarg)
 {
   const struct priv_reg_entry *p = (const struct priv_reg_entry *) parg;
   const struct priv_reg_entry *q = (const struct priv_reg_entry *) qarg;
@@ -801,7 +799,7 @@ cmp_reg_entry (parg, qarg)
    need.  */
 
 void
-md_begin ()
+md_begin (void)
 {
   register const char *retval = NULL;
   int lose = 0;
@@ -819,7 +817,7 @@ md_begin ()
   while (i < (unsigned int) sparc_num_opcodes)
     {
       const char *name = sparc_opcodes[i].name;
-      retval = hash_insert (op_hash, name, (PTR) &sparc_opcodes[i]);
+      retval = hash_insert (op_hash, name, (void *) &sparc_opcodes[i]);
       if (retval != NULL)
        {
          as_bad (_("Internal error: can't hash `%s': %s\n"),
@@ -855,7 +853,8 @@ md_begin ()
        }
       else
        {
-         retval = hash_insert (op_hash, native_op_table[i].name, (PTR) insn);
+         retval = hash_insert (op_hash, native_op_table[i].name,
+                               (void *) insn);
          if (retval != NULL)
            {
              as_bad (_("Internal error: can't hash `%s': %s\n"),
@@ -899,7 +898,7 @@ md_begin ()
 /* Called after all assembly has been done.  */
 
 void
-sparc_md_end ()
+sparc_md_end (void)
 {
   unsigned long mach = bfd_mach_sparc;
 
@@ -923,13 +922,54 @@ sparc_md_end ()
       default: break;
       }
   bfd_set_arch_mach (stdoutput, bfd_arch_sparc, mach);
+
+#if defined(OBJ_ELF) && !defined(TE_SOLARIS)
+  if (hwcap_seen)
+    {
+      int bits = 0;
+
+      if (hwcap_seen & F_MUL32)
+       bits |= ELF_SPARC_HWCAP_MUL32;
+      if (hwcap_seen & F_DIV32)
+       bits |= ELF_SPARC_HWCAP_DIV32;
+      if (hwcap_seen & F_FSMULD)
+       bits |= ELF_SPARC_HWCAP_FSMULD;
+      if (hwcap_seen & F_V8PLUS)
+       bits |= ELF_SPARC_HWCAP_V8PLUS;
+      if (hwcap_seen & F_POPC)
+       bits |= ELF_SPARC_HWCAP_POPC;
+      if (hwcap_seen & F_VIS)
+       bits |= ELF_SPARC_HWCAP_VIS;
+      if (hwcap_seen & F_VIS2)
+       bits |= ELF_SPARC_HWCAP_VIS2;
+      if (hwcap_seen & F_ASI_BLK_INIT)
+       bits |= ELF_SPARC_HWCAP_ASI_BLK_INIT;
+      if (hwcap_seen & F_FMAF)
+       bits |= ELF_SPARC_HWCAP_FMAF;
+      if (hwcap_seen & F_VIS3)
+       bits |= ELF_SPARC_HWCAP_VIS3;
+      if (hwcap_seen & F_HPC)
+       bits |= ELF_SPARC_HWCAP_HPC;
+      if (hwcap_seen & F_RANDOM)
+       bits |= ELF_SPARC_HWCAP_RANDOM;
+      if (hwcap_seen & F_TRANS)
+       bits |= ELF_SPARC_HWCAP_TRANS;
+      if (hwcap_seen & F_FJFMAU)
+       bits |= ELF_SPARC_HWCAP_FJFMAU;
+      if (hwcap_seen & F_IMA)
+       bits |= ELF_SPARC_HWCAP_IMA;
+      if (hwcap_seen & F_ASI_CACHE_SPARING)
+       bits |= ELF_SPARC_HWCAP_ASI_CACHE_SPARING;
+
+      bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU, Tag_GNU_Sparc_HWCAPS, bits);
+    }
+#endif
 }
 \f
 /* Return non-zero if VAL is in the range -(MAX+1) to MAX.  */
 
-static INLINE int
-in_signed_range (val, max)
-     bfd_signed_vma val, max;
+static inline int
+in_signed_range (bfd_signed_vma val, bfd_signed_vma max)
 {
   if (max <= 0)
     abort ();
@@ -949,9 +989,8 @@ in_signed_range (val, max)
 
 /* Return non-zero if VAL is in the range 0 to MAX.  */
 
-static INLINE int
-in_unsigned_range (val, max)
-     bfd_vma val, max;
+static inline int
+in_unsigned_range (bfd_vma val, bfd_vma max)
 {
   if (val > max)
     return 0;
@@ -961,9 +1000,8 @@ in_unsigned_range (val, max)
 /* Return non-zero if VAL is in the range -(MAX/2+1) to MAX.
    (e.g. -15 to +31).  */
 
-static INLINE int
-in_bitfield_range (val, max)
-     bfd_signed_vma val, max;
+static inline int
+in_bitfield_range (bfd_signed_vma val, bfd_signed_vma max)
 {
   if (max <= 0)
     abort ();
@@ -975,8 +1013,7 @@ in_bitfield_range (val, max)
 }
 
 static int
-sparc_ffs (mask)
-     unsigned int mask;
+sparc_ffs (unsigned int mask)
 {
   int i;
 
@@ -990,9 +1027,7 @@ sparc_ffs (mask)
 
 /* Implement big shift right.  */
 static bfd_vma
-BSR (val, amount)
-     bfd_vma val;
-     int amount;
+BSR (bfd_vma val, int amount)
 {
   if (sizeof (bfd_vma) <= 4 && amount >= 32)
     as_fatal (_("Support for 64-bit arithmetic not compiled in."));
@@ -1029,8 +1064,7 @@ static unsigned long last_opcode;
 /* Handle the set and setuw synthetic instructions.  */
 
 static void
-synthetize_setuw (insn)
-     const struct sparc_opcode *insn;
+synthetize_setuw (const struct sparc_opcode *insn)
 {
   int need_hi22_p = 0;
   int rd = (the_insn.opcode & RD (~0)) >> 25;
@@ -1088,8 +1122,7 @@ synthetize_setuw (insn)
 /* Handle the setsw synthetic instruction.  */
 
 static void
-synthetize_setsw (insn)
-     const struct sparc_opcode *insn;
+synthetize_setsw (const struct sparc_opcode *insn)
 {
   int low32, rd, opc;
 
@@ -1140,8 +1173,7 @@ synthetize_setsw (insn)
 /* Handle the setsw synthetic instruction.  */
 
 static void
-synthetize_setx (insn)
-     const struct sparc_opcode *insn;
+synthetize_setx (const struct sparc_opcode *insn)
 {
   int upper32, lower32;
   int tmpreg = (the_insn.opcode & RS1 (~0)) >> 14;
@@ -1307,8 +1339,7 @@ synthetize_setx (insn)
 /* Main entry point to assemble one instruction.  */
 
 void
-md_assemble (str)
-     char *str;
+md_assemble (char *str)
 {
   const struct sparc_opcode *insn;
   int special_case;
@@ -1375,7 +1406,7 @@ md_assemble (str)
           The workaround is to add an fmovs of the destination register to
           itself just after the instruction.  This was true on machines
           with Weitek 1165 float chips, such as the Sun-4/260 and /280.  */
-       assert (the_insn.reloc == BFD_RELOC_NONE);
+       gas_assert (the_insn.reloc == BFD_RELOC_NONE);
        the_insn.opcode = FMOVS_INSN | rd | RD (rd);
        output_insn (insn, &the_insn);
        return;
@@ -1389,9 +1420,7 @@ md_assemble (str)
 /* Subroutine of md_assemble to do the actual parsing.  */
 
 static int
-sparc_ip (str, pinsn)
-     char *str;
-     const struct sparc_opcode **pinsn;
+sparc_ip (char *str, const struct sparc_opcode **pinsn)
 {
   char *error_message = "";
   char *s;
@@ -1467,15 +1496,15 @@ sparc_ip (str, pinsn)
                  {
                    while (*s == '#')
                      {
-                       int mask;
+                       int jmask;
 
                        if (! parse_keyword_arg (sparc_encode_membar, &s,
-                                                &mask))
+                                                &jmask))
                          {
                            error_message = _(": invalid membar mask name");
                            goto error;
                          }
-                       kmask |= mask;
+                       kmask |= jmask;
                        while (*s == ' ')
                          ++s;
                        if (*s == '|' || *s == '+')
@@ -1860,16 +1889,19 @@ sparc_ip (str, pinsn)
            case '\0':          /* End of args.  */
              if (s[0] == ',' && s[1] == '%')
                {
-                 static const struct tls_ops {
+                 static const struct ops
+                 {
                    /* The name as it appears in assembler.  */
                    char *name;
                    /* strlen (name), precomputed for speed */
                    int len;
                    /* The reloc this pseudo-op translates to.  */
                    int reloc;
-                   /* 1 if call.  */
-                   int call;
-                 } tls_ops[] = {
+                   /* 1 if tls call.  */
+                   int tls_call;
+                 }
+                 ops[] =
+                 {
                    { "tgd_add", 7, BFD_RELOC_SPARC_TLS_GD_ADD, 0 },
                    { "tgd_call", 8, BFD_RELOC_SPARC_TLS_GD_CALL, 1 },
                    { "tldm_add", 8, BFD_RELOC_SPARC_TLS_LDM_ADD, 0 },
@@ -1877,13 +1909,15 @@ sparc_ip (str, pinsn)
                    { "tldo_add", 8, BFD_RELOC_SPARC_TLS_LDO_ADD, 0 },
                    { "tie_ldx", 7, BFD_RELOC_SPARC_TLS_IE_LDX, 0 },
                    { "tie_ld", 6, BFD_RELOC_SPARC_TLS_IE_LD, 0 },
-                   { "tie_add", 7, BFD_RELOC_SPARC_TLS_IE_ADD, 0 }
+                   { "tie_add", 7, BFD_RELOC_SPARC_TLS_IE_ADD, 0 },
+                   { "gdop", 4, BFD_RELOC_SPARC_GOTDATA_OP, 0 },
+                   { NULL, 0, 0, 0 }
                  };
-                 const struct tls_ops *o;
+                 const struct ops *o;
                  char *s1;
                  int npar = 0;
 
-                 for (o = tls_ops; o->name; o++)
+                 for (o = ops; o->name; o++)
                    if (strncmp (s + 2, o->name, o->len) == 0)
                      break;
                  if (o->name == NULL)
@@ -1895,14 +1929,14 @@ sparc_ip (str, pinsn)
                      return special_case;
                    }
 
-                 if (! o->call && the_insn.reloc != BFD_RELOC_NONE)
+                 if (! o->tls_call && the_insn.reloc != BFD_RELOC_NONE)
                    {
                      as_bad (_("Illegal operands: %%%s cannot be used together with other relocs in the insn ()"),
                              o->name);
                      return special_case;
                    }
 
-                 if (o->call
+                 if (o->tls_call
                      && (the_insn.reloc != BFD_RELOC_32_PCREL_S2
                          || the_insn.exp.X_add_number != 0
                          || the_insn.exp.X_add_symbol
@@ -2152,6 +2186,9 @@ sparc_ip (str, pinsn)
            case 'B':
            case 'R':
 
+           case '4':
+           case '5':
+
            case 'g':
            case 'H':
            case 'J':
@@ -2169,6 +2206,7 @@ sparc_ip (str, pinsn)
 
                    if ((*args == 'v'
                         || *args == 'B'
+                        || *args == '5'
                         || *args == 'H')
                        && (mask & 1))
                      {
@@ -2230,6 +2268,11 @@ sparc_ip (str, pinsn)
                    opcode |= RS2 (mask);
                    continue;
 
+                 case '4':
+                 case '5':
+                   opcode |= RS3 (mask);
+                   continue;
+
                  case 'g':
                  case 'H':
                  case 'J':
@@ -2249,6 +2292,14 @@ sparc_ip (str, pinsn)
                }
              break;
 
+           case '(':
+             if (strncmp (s, "%efsr", 5) == 0)
+               {
+                 s += 5;
+                 continue;
+               }
+             break;
+
            case '0':           /* 64 bit immediate (set, setsw, setx insn)  */
              the_insn.reloc = BFD_RELOC_NONE; /* reloc handled elsewhere  */
              goto immediate;
@@ -2304,6 +2355,8 @@ sparc_ip (str, pinsn)
                      { "lox", 3, BFD_RELOC_SPARC_LOX10, 1, 0 },
                      { "hi", 2, BFD_RELOC_HI22, 0, 1 },
                      { "lo", 2, BFD_RELOC_LO10, 0, 1 },
+                     { "pc22", 4, BFD_RELOC_SPARC_PC22, 0, 1 },
+                     { "pc10", 4, BFD_RELOC_SPARC_PC10, 0, 1 },
                      { "hh", 2, BFD_RELOC_SPARC_HH22, 1, 1 },
                      { "hm", 2, BFD_RELOC_SPARC_HM10, 1, 1 },
                      { "lm", 2, BFD_RELOC_SPARC_LM22, 1, 1 },
@@ -2324,6 +2377,10 @@ sparc_ip (str, pinsn)
                      { "tie_lo10", 8, BFD_RELOC_SPARC_TLS_IE_LO10, 0, 0 },
                      { "tle_hix22", 9, BFD_RELOC_SPARC_TLS_LE_HIX22, 0, 0 },
                      { "tle_lox10", 9, BFD_RELOC_SPARC_TLS_LE_LOX10, 0, 0 },
+                     { "gdop_hix22", 10, BFD_RELOC_SPARC_GOTDATA_OP_HIX22,
+                       0, 0 },
+                     { "gdop_lox10", 10, BFD_RELOC_SPARC_GOTDATA_OP_LOX10,
+                       0, 0 },
                      { NULL, 0, 0, 0, 0 }
                    };
                    const struct ops *o;
@@ -2400,8 +2457,10 @@ sparc_ip (str, pinsn)
                  {
                    if (s1[-2] == '%' && s1[-3] == '+')
                      s1 -= 3;
-                   else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
+                   else if (strchr ("golir0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
                      s1 -= 4;
+                   else if (s1[-3] == 'r' && s1[-4] == '%' && s1[-5] == '+')
+                     s1 -= 5;
                    else
                      s1 = NULL;
                    if (s1)
@@ -2733,7 +2792,12 @@ sparc_ip (str, pinsn)
        {
          /* We have a match.  Now see if the architecture is OK.  */
          int needed_arch_mask = insn->architecture;
+#if defined(OBJ_ELF) && !defined(TE_SOLARIS)
+         int hwcaps = insn->flags & F_HWCAP_MASK;
 
+         if (hwcaps)
+                 hwcap_seen |= hwcaps;
+#endif
          if (v9_arg_p)
            {
              needed_arch_mask &=
@@ -2755,7 +2819,7 @@ sparc_ip (str, pinsn)
                sparc_ffs (SPARC_OPCODE_SUPPORTED (max_architecture)
                           & needed_arch_mask);
 
-             assert (needed_architecture <= SPARC_OPCODE_ARCH_MAX);
+             gas_assert (needed_architecture <= SPARC_OPCODE_ARCH_MAX);
              if (warn_on_bump
                  && needed_architecture > warn_after_architecture)
                {
@@ -2816,10 +2880,9 @@ sparc_ip (str, pinsn)
    If successful, INPUT_POINTER is updated.  */
 
 static int
-parse_keyword_arg (lookup_fn, input_pointerP, valueP)
-     int (*lookup_fn) PARAMS ((const char *));
-     char **input_pointerP;
-     int *valueP;
+parse_keyword_arg (int (*lookup_fn) (const char *),
+                  char **input_pointerP,
+                  int *valueP)
 {
   int value;
   char c, *p, *q;
@@ -2844,9 +2907,7 @@ parse_keyword_arg (lookup_fn, input_pointerP, valueP)
    The result is a boolean indicating success.  */
 
 static int
-parse_const_expr_arg (input_pointerP, valueP)
-     char **input_pointerP;
-     int *valueP;
+parse_const_expr_arg (char **input_pointerP, int *valueP)
 {
   char *save = input_line_pointer;
   expressionS exp;
@@ -2876,8 +2937,7 @@ parse_const_expr_arg (input_pointerP, valueP)
 /* Subroutine of sparc_ip to parse an expression.  */
 
 static int
-get_expression (str)
-     char *str;
+get_expression (char *str)
 {
   char *save_in;
   segT seg;
@@ -2904,131 +2964,53 @@ get_expression (str)
 /* Subroutine of md_assemble to output one insn.  */
 
 static void
-output_insn (insn, the_insn)
-     const struct sparc_opcode *insn;
-     struct sparc_it *the_insn;
+output_insn (const struct sparc_opcode *insn, struct sparc_it *theinsn)
 {
   char *toP = frag_more (4);
 
   /* Put out the opcode.  */
   if (INSN_BIG_ENDIAN)
-    number_to_chars_bigendian (toP, (valueT) the_insn->opcode, 4);
+    number_to_chars_bigendian (toP, (valueT) theinsn->opcode, 4);
   else
-    number_to_chars_littleendian (toP, (valueT) the_insn->opcode, 4);
+    number_to_chars_littleendian (toP, (valueT) theinsn->opcode, 4);
 
   /* Put out the symbol-dependent stuff.  */
-  if (the_insn->reloc != BFD_RELOC_NONE)
+  if (theinsn->reloc != BFD_RELOC_NONE)
     {
       fixS *fixP =  fix_new_exp (frag_now,     /* Which frag.  */
                                 (toP - frag_now->fr_literal),  /* Where.  */
                                 4,             /* Size.  */
-                                &the_insn->exp,
-                                the_insn->pcrel,
-                                the_insn->reloc);
+                                &theinsn->exp,
+                                theinsn->pcrel,
+                                theinsn->reloc);
       /* Turn off overflow checking in fixup_segment.  We'll do our
         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;
-      if (the_insn->reloc == BFD_RELOC_SPARC_OLO10)
-       fixP->tc_fix_data = the_insn->exp2.X_add_number;
+      if (theinsn->reloc == BFD_RELOC_SPARC_OLO10)
+       fixP->tc_fix_data = theinsn->exp2.X_add_number;
     }
 
   last_insn = insn;
-  last_opcode = the_insn->opcode;
+  last_opcode = theinsn->opcode;
 
 #ifdef OBJ_ELF
   dwarf2_emit_insn (4);
 #endif
 }
 \f
-/* This is identical to the md_atof in m68k.c.  I think this is right,
-   but I'm not sure.
-
-   Turn a string in input_line_pointer into a floating point constant
-   of type TYPE, and store the appropriate bytes in *LITP.  The number
-   of LITTLENUMS emitted is stored in *SIZEP.  An error message is
-   returned, or NULL on OK.  */
-
-/* Equal to MAX_PRECISION in atof-ieee.c.  */
-#define MAX_LITTLENUMS 6
-
 char *
-md_atof (type, litP, sizeP)
-     char type;
-     char *litP;
-     int *sizeP;
+md_atof (int type, char *litP, int *sizeP)
 {
-  int i, prec;
-  LITTLENUM_TYPE words[MAX_LITTLENUMS];
-  char *t;
-
-  switch (type)
-    {
-    case 'f':
-    case 'F':
-    case 's':
-    case 'S':
-      prec = 2;
-      break;
-
-    case 'd':
-    case 'D':
-    case 'r':
-    case 'R':
-      prec = 4;
-      break;
-
-    case 'x':
-    case 'X':
-      prec = 6;
-      break;
-
-    case 'p':
-    case 'P':
-      prec = 6;
-      break;
-
-    default:
-      *sizeP = 0;
-      return _("Bad call to MD_ATOF()");
-    }
-
-  t = atof_ieee (input_line_pointer, type, words);
-  if (t)
-    input_line_pointer = t;
-  *sizeP = prec * sizeof (LITTLENUM_TYPE);
-
-  if (target_big_endian)
-    {
-      for (i = 0; i < prec; i++)
-       {
-         md_number_to_chars (litP, (valueT) words[i],
-                             sizeof (LITTLENUM_TYPE));
-         litP += sizeof (LITTLENUM_TYPE);
-       }
-    }
-  else
-    {
-      for (i = prec - 1; i >= 0; i--)
-       {
-         md_number_to_chars (litP, (valueT) words[i],
-                             sizeof (LITTLENUM_TYPE));
-         litP += sizeof (LITTLENUM_TYPE);
-       }
-    }
-
-  return 0;
+  return ieee_md_atof (type, litP, sizeP, target_big_endian);
 }
 
 /* Write a value out to the object file, using the appropriate
    endianness.  */
 
 void
-md_number_to_chars (buf, val, n)
-     char *buf;
-     valueT val;
-     int n;
+md_number_to_chars (char *buf, valueT val, int n)
 {
   if (target_big_endian)
     number_to_chars_bigendian (buf, val, n);
@@ -3045,16 +3027,13 @@ md_number_to_chars (buf, val, n)
    hold.  */
 
 void
-md_apply_fix (fixP, valP, segment)
-     fixS *fixP;
-     valueT *valP;
-     segT segment ATTRIBUTE_UNUSED;
+md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
 {
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
   offsetT val = * (offsetT *) valP;
   long insn;
 
-  assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
+  gas_assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
 
   fixP->fx_addnumber = val;    /* Remember value for emit_reloc.  */
 
@@ -3309,9 +3288,9 @@ md_apply_fix (fixP, valP, segment)
          break;
 
        case BFD_RELOC_SPARC_WDISP16:
-         /* FIXME: simplify.  */
-         if (((val > 0) && (val & ~0x3fffc))
-             || ((val < 0) && (~(val - 1) & ~0x3fffc)))
+         if ((val & 3)
+             || val >= 0x1fffc
+             || val <= -(offsetT) 0x20008)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          _("relocation overflow"));
          /* FIXME: The +1 deserves a comment.  */
@@ -3320,9 +3299,9 @@ md_apply_fix (fixP, valP, segment)
          break;
 
        case BFD_RELOC_SPARC_WDISP19:
-         /* FIXME: simplify.  */
-         if (((val > 0) && (val & ~0x1ffffc))
-             || ((val < 0) && (~(val - 1) & ~0x1ffffc)))
+         if ((val & 3)
+             || val >= 0xffffc
+             || val <= -(offsetT) 0x100008)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          _("relocation overflow"));
          /* FIXME: The +1 deserves a comment.  */
@@ -3436,9 +3415,7 @@ md_apply_fix (fixP, valP, segment)
    format.  */
 
 arelent **
-tc_gen_reloc (section, fixp)
-     asection *section;
-     fixS *fixp;
+tc_gen_reloc (asection *section, fixS *fixp)
 {
   static arelent *relocs[3];
   arelent *reloc;
@@ -3460,6 +3437,8 @@ tc_gen_reloc (section, fixp)
     case BFD_RELOC_32_PCREL_S2:
     case BFD_RELOC_SPARC13:
     case BFD_RELOC_SPARC22:
+    case BFD_RELOC_SPARC_PC22:
+    case BFD_RELOC_SPARC_PC10:
     case BFD_RELOC_SPARC_BASE13:
     case BFD_RELOC_SPARC_WDISP16:
     case BFD_RELOC_SPARC_WDISP19:
@@ -3514,6 +3493,9 @@ tc_gen_reloc (section, fixp)
     case BFD_RELOC_SPARC_TLS_LE_LOX10:
     case BFD_RELOC_SPARC_TLS_DTPOFF32:
     case BFD_RELOC_SPARC_TLS_DTPOFF64:
+    case BFD_RELOC_SPARC_GOTDATA_OP_HIX22:
+    case BFD_RELOC_SPARC_GOTDATA_OP_LOX10:
+    case BFD_RELOC_SPARC_GOTDATA_OP:
       code = fixp->fx_r_type;
       break;
     default:
@@ -3661,8 +3643,7 @@ tc_gen_reloc (section, fixp)
 /* We have no need to default values of symbols.  */
 
 symbolS *
-md_undefined_symbol (name)
-     char *name ATTRIBUTE_UNUSED;
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
 {
   return 0;
 }
@@ -3670,9 +3651,7 @@ md_undefined_symbol (name)
 /* Round up a section size to the appropriate boundary.  */
 
 valueT
-md_section_align (segment, size)
-     segT segment ATTRIBUTE_UNUSED;
-     valueT size;
+md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
 {
 #ifndef OBJ_ELF
   /* This is not right for ELF; a.out wants it, and COFF will force
@@ -3695,8 +3674,7 @@ md_section_align (segment, size)
    its size.  This gets us to the following instruction.
    (??? Is this right?  FIXME-SOON)  */
 long
-md_pcrel_from (fixP)
-     fixS *fixP;
+md_pcrel_from (fixS *fixP)
 {
   long ret;
 
@@ -3712,8 +3690,7 @@ md_pcrel_from (fixP)
    of two.  */
 
 static int
-mylog2 (value)
-     int value;
+mylog2 (int value)
 {
   int shift;
 
@@ -3733,8 +3710,7 @@ static int max_alignment = 15;
 #endif
 
 static void
-s_reserve (ignore)
-     int ignore ATTRIBUTE_UNUSED;
+s_reserve (int ignore ATTRIBUTE_UNUSED)
 {
   char *name;
   char *p;
@@ -3870,16 +3846,15 @@ s_reserve (ignore)
     }
   else
     {
-      as_warn ("Ignoring attempt to re-define symbol %s",
+      as_warn (_("Ignoring attempt to re-define symbol %s"),
               S_GET_NAME (symbolP));
-    }                          /* if not redefining.  */
+    }
 
   demand_empty_rest_of_line ();
 }
 
 static void
-s_common (ignore)
-     int ignore ATTRIBUTE_UNUSED;
+s_common (int ignore ATTRIBUTE_UNUSED)
 {
   char *name;
   char c;
@@ -3968,7 +3943,6 @@ s_common (ignore)
        {
          segT old_sec;
          int old_subsec;
-         char *p;
          int align;
 
          old_sec = now_seg;
@@ -4058,8 +4032,7 @@ s_common (ignore)
    invalid delay slot usage.  */
 
 static void
-s_empty (ignore)
-     int ignore ATTRIBUTE_UNUSED;
+s_empty (int ignore ATTRIBUTE_UNUSED)
 {
   /* The easy way to implement is to just forget about the last
      instruction.  */
@@ -4067,8 +4040,7 @@ s_empty (ignore)
 }
 
 static void
-s_seg (ignore)
-     int ignore ATTRIBUTE_UNUSED;
+s_seg (int ignore ATTRIBUTE_UNUSED)
 {
 
   if (strncmp (input_line_pointer, "\"text\"", 6) == 0)
@@ -4103,15 +4075,14 @@ s_seg (ignore)
 }
 
 static void
-s_data1 ()
+s_data1 (void)
 {
   subseg_set (data_section, 1);
   demand_empty_rest_of_line ();
 }
 
 static void
-s_proc (ignore)
-     int ignore ATTRIBUTE_UNUSED;
+s_proc (int ignore ATTRIBUTE_UNUSED)
 {
   while (!is_end_of_line[(unsigned char) *input_line_pointer])
     {
@@ -4135,8 +4106,7 @@ static const char *sparc_cons_special_reloc;
    to be aligned.  */
 
 static void
-s_uacons (bytes)
-     int bytes;
+s_uacons (int bytes)
 {
   /* Tell sparc_cons_align not to align this value.  */
   sparc_no_align_cons = 1;
@@ -4149,8 +4119,7 @@ s_uacons (bytes)
    sparc_arch_size 64 it is equivalent to .xword.  */
 
 static void
-s_ncons (bytes)
-     int bytes ATTRIBUTE_UNUSED;
+s_ncons (int bytes ATTRIBUTE_UNUSED)
 {
   cons (sparc_arch_size == 32 ? 4 : 8);
 }
@@ -4164,8 +4133,7 @@ s_ncons (bytes)
 */
 
 static void
-s_register (ignore)
-     int ignore ATTRIBUTE_UNUSED;
+s_register (int ignore ATTRIBUTE_UNUSED)
 {
   char c;
   int reg;
@@ -4253,7 +4221,7 @@ s_register (ignore)
    symbols which need it.  */
 
 void
-sparc_adjust_symtab ()
+sparc_adjust_symtab (void)
 {
   symbolS *sym;
 
@@ -4284,11 +4252,9 @@ sparc_adjust_symtab ()
    option to check for it.  */
 
 void
-sparc_cons_align (nbytes)
-     int nbytes;
+sparc_cons_align (int nbytes)
 {
   int nalign;
-  char *p;
 
   /* Only do this if we are enforcing aligned data.  */
   if (! enforce_aligned_data)
@@ -4302,7 +4268,7 @@ sparc_cons_align (nbytes)
   if (nalign == 0)
     return;
 
-  assert (nalign > 0);
+  gas_assert (nalign > 0);
 
   if (now_seg == absolute_section)
     {
@@ -4311,8 +4277,8 @@ sparc_cons_align (nbytes)
       return;
     }
 
-  p = frag_var (rs_align_test, 1, 1, (relax_substateT) 0,
-               (symbolS *) NULL, (offsetT) nalign, (char *) NULL);
+  frag_var (rs_align_test, 1, 1, (relax_substateT) 0,
+           (symbolS *) NULL, (offsetT) nalign, (char *) NULL);
 
   record_alignment (now_seg, nalign);
 }
@@ -4320,8 +4286,7 @@ sparc_cons_align (nbytes)
 /* This is called from HANDLE_ALIGN in tc-sparc.h.  */
 
 void
-sparc_handle_align (fragp)
-     fragS *fragp;
+sparc_handle_align (fragS *fragp)
 {
   int count, fix;
   char *p;
@@ -4377,7 +4342,7 @@ sparc_handle_align (fragp)
 /* Some special processing for a Sparc ELF file.  */
 
 void
-sparc_elf_final_processing ()
+sparc_elf_final_processing (void)
 {
   /* Set the Sparc ELF flag bits.  FIXME: There should probably be some
      sort of BFD interface for this.  */
@@ -4404,9 +4369,7 @@ sparc_elf_final_processing ()
 }
 
 void
-sparc_cons (exp, size)
-     expressionS *exp;
-     int size;
+sparc_cons (expressionS *exp, int size)
 {
   char *save;
 
@@ -4547,11 +4510,10 @@ sparc_cons (exp, size)
    we want to handle little endian relocs specially.  */
 
 void
-cons_fix_new_sparc (frag, where, nbytes, exp)
-     fragS *frag;
-     int where;
-     unsigned int nbytes;
-     expressionS *exp;
+cons_fix_new_sparc (fragS *frag,
+                   int where,
+                   unsigned int nbytes,
+                   expressionS *exp)
 {
   bfd_reloc_code_real_type r;
 
@@ -4604,7 +4566,7 @@ cons_fix_new_sparc (frag, where, nbytes, exp)
 }
 
 void
-sparc_cfi_frame_initial_instructions ()
+sparc_cfi_frame_initial_instructions (void)
 {
   cfi_add_CFA_def_cfa (14, sparc_arch_size == 64 ? 0x7ff : 0);
 }