* sparc-dis.c (HASH_SIZE, HASH_INSN): Define.
authorDavid Edelsohn <dje.gcc@gmail.com>
Wed, 2 Aug 1995 16:06:17 +0000 (16:06 +0000)
committerDavid Edelsohn <dje.gcc@gmail.com>
Wed, 2 Aug 1995 16:06:17 +0000 (16:06 +0000)
(opcode_bits, opcode_hash_table, sparc64_p): New variables.
(opcodes_initialized): Renamed from opcodes_sorted.
(build_hash_table): New function.
(is_delayed_branch): Use hash table.
(print_insn): Renamed from print_insn_sparc, made static.
Build and use hash table.
(print_insn_sparc, print_insn_sparc64): New functions.
(compare_opcodes): If !sparc64, move sparc64 opcodes to end,
and vice-versa if sparc64.
* sparc-opc.c (all non-v9 insns): Use flag F_NOTV9 instead of F_ALIAS.

opcodes/ChangeLog
opcodes/sparc-dis.c
opcodes/sparc-opc.c

index 393e457a86b7e4469a3ce4f330291a9e7d9cbaa2..a5188c298429d7ed4ca0bce109d207f744636532 100644 (file)
@@ -1,3 +1,42 @@
+Wed Aug  2 08:23:38 1995  Doug Evans  <dje@canuck.cygnus.com>
+
+       * sparc-dis.c (HASH_SIZE, HASH_INSN): Define.
+       (opcode_bits, opcode_hash_table, sparc64_p): New variables.
+       (opcodes_initialized): Renamed from opcodes_sorted.
+       (build_hash_table): New function.
+       (is_delayed_branch): Use hash table.
+       (print_insn): Renamed from print_insn_sparc, made static.
+       Build and use hash table.
+       (print_insn_sparc, print_insn_sparc64): New functions.
+       (compare_opcodes): If !sparc64, move sparc64 opcodes to end,
+       and vice-versa if sparc64.
+       * sparc-opc.c (all non-v9 insns): Use flag F_NOTV9 instead of F_ALIAS.
+
+Tue Aug  1 00:12:49 1995  Ian Lance Taylor  <ian@cygnus.com>
+
+       * sh-dis.c (print_insn_shx): Remove unused local dslot.  Use
+       print_address_func for A_BDISP12 and A_BDISP8.  Correct test which
+       avoids printing a delay slot in a delay slot.
+       * sh-opc.h (sh_table): Fully bracket last entry.
+
+Mon Jul 31 12:04:47 1995  Doug Evans  <dje@canuck.cygnus.com>
+
+       * sparc-opc.c (sllx, srax, srlx): Fix disassembly.
+
+Wed Jul 12 00:59:34 1995  Ken Raeburn  <raeburn@kr-pc.cygnus.com>
+
+       * configure.in: Get host_makefile_frag from ${srcdir}.
+
+       * configure.in: Autoconfiscated.  Check for string[s].h.  Create
+       config.h from config.in.  Don't set up sysdep.h link.
+       * sysdep.h: New file.
+       * configure, config.in: New files, generated from configure.in.
+       * Makefile.in: Updated to be processed autoconf-style.
+       (distclean): Keep sysdep.h.  Remove config.log and config.cache.
+       (Makefile): Depend on config.status.
+       (config.status): New rule.
+       * configure.bat: Update Makefile substitutions.
+
 Tue Jul 11 14:23:37 1995  Jeff Spiegel  <jeffs@lsil.com>
 
        * mips-opc.c (L1): Define.
index a3d59b8be83e5d81f695021c34bdd70a7af0f210..532fb94c2285f99ca6edf52693efd7fd60d1dac5 100644 (file)
@@ -1,5 +1,5 @@
 /* Print SPARC instructions.
-   Copyright 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
+   Copyright 1989, 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -13,14 +13,38 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
+#include "ansidecl.h"
 #include "opcode/sparc.h"
 #include "dis-asm.h"
+#include "libiberty.h"
 #include <string.h>
 
+/* For faster lookup, after insns are sorted they are hashed.  */
+/* ??? I think there is room for even more improvement.  */
+
+#define HASH_SIZE 256
+/* It is important that we only look at insn code bits as that is how the
+   opcode table is hashed.  OPCODE_BITS is a table of valid bits for each
+   of the main types (0,1,2,3).  */
+static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
+#define HASH_INSN(INSN) \
+  ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
+struct opcode_hash {
+  struct opcode_hash *next;
+  struct sparc_opcode *opcode;
+};
+static struct opcode_hash *opcode_hash_table[HASH_SIZE];
+static void build_hash_table ();
+
+/* Sign-extend a value which is N bits long.  */
+#define        SEX(value, bits) \
+       ((((int)(value)) << ((8 * sizeof (int)) - bits))        \
+                        >> ((8 * sizeof (int)) - bits) )
+
 static  char *reg_names[] =
- { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",     
+{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",      
   "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",      
   "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",      
   "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",      
@@ -28,123 +52,166 @@ static  char *reg_names[] =
   "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",        
   "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
   "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
-  "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
+#ifndef NO_V9
+  "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",      
+  "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",      
+  "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
+  "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
+/* psr, wim, tbr, fpsr, cpsr are v8 only.  */
+#endif
+  "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
+};
 
 #define        freg_names      (&reg_names[4 * 8])
 
-/* FIXME--need to deal with byte order (probably using masking and
-   shifting rather than bitfields is easiest).  */
+#ifndef NO_V9
+/* These are ordered according to there register number in
+   rdpr and wrpr insns.  */
+static char *v9_priv_reg_names[] =
+{
+  "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
+  "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
+  "wstate", "fq"
+  /* "ver" - special cased */
+};
+#endif
+
+/* Macros used to extract instruction fields.  Not all fields have
+   macros defined here, only those which are actually used.  */
+
+#define X_RD(i) (((i) >> 25) & 0x1f)
+#define X_RS1(i) (((i) >> 14) & 0x1f)
+#define X_LDST_I(i) (((i) >> 13) & 1)
+#define X_ASI(i) (((i) >> 5) & 0xff)
+#define X_RS2(i) (((i) >> 0) & 0x1f)
+#define X_IMM13(i) (((i) >> 0) & 0x1fff)
+#define X_DISP22(i) (((i) >> 0) & 0x3fffff)
+#define X_IMM22(i) X_DISP22 (i)
+#define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
 
-union sparc_insn
-  {
-    unsigned long int code;
-    struct
-      {
-       unsigned int anop:2;
-#define        op      ldst.anop
-       unsigned int anrd:5;
-#define        rd      ldst.anrd
-       unsigned int op3:6;
-       unsigned int anrs1:5;
-#define        rs1     ldst.anrs1
-       unsigned int i:1;
-       unsigned int anasi:8;
-#define        asi     ldst.anasi
-       unsigned int anrs2:5;
-#define        rs2     ldst.anrs2
-#define        shcnt   rs2
-      } ldst;
-    struct
-      {
-       unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
-       unsigned int IMM13:13;
-#define        imm13   IMM13.IMM13
-      } IMM13;
-    struct
-      {
-       unsigned int anop:2;
-       unsigned int a:1;
-       unsigned int cond:4;
-       unsigned int op2:3;
-       unsigned int DISP22:22;
-#define        disp22  branch.DISP22
-      } branch;
 #ifndef NO_V9
-    struct
-      {
-       unsigned int _OP:2, _RD:5, op3:6, _RS1:5;
-       unsigned int DISP14:14;
-#define        disp14  DISP14.DISP14
-      } DISP14;
-    struct
-      {
-       unsigned int _OP:2;
-       unsigned int a:1;
-       unsigned int cond:4;
-       unsigned int op2:3;
-       unsigned int p:1;
-       unsigned int DISP21:21;
-#define        disp21  branch2.DISP21
-      } branch2;
-#endif /* NO_V9 */
-
-#define        imm22   disp22
-    struct
-      {
-       unsigned int anop:2;
-       unsigned int adisp30:30;
-#define        disp30  call.adisp30
-      } call;
-  };
+#define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
+#endif
+
+/* Here is the union which was used to extract instruction fields
+   before the shift and mask macros were written.
+
+   union sparc_insn
+     {
+       unsigned long int code;
+       struct
+        {
+          unsigned int anop:2;
+          #define      op      ldst.anop
+          unsigned int anrd:5;
+          #define      rd      ldst.anrd
+          unsigned int op3:6;
+          unsigned int anrs1:5;
+          #define      rs1     ldst.anrs1
+          unsigned int i:1;
+          unsigned int anasi:8;
+          #define      asi     ldst.anasi
+          unsigned int anrs2:5;
+          #define      rs2     ldst.anrs2
+          #define      shcnt   rs2
+        } ldst;
+       struct
+        {
+          unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
+          unsigned int IMM13:13;
+          #define      imm13   IMM13.IMM13
+        } IMM13;
+       struct
+        {
+          unsigned int anop:2;
+          unsigned int a:1;
+          unsigned int cond:4;
+          unsigned int op2:3;
+          unsigned int DISP22:22;
+          #define      disp22  branch.DISP22
+          #define      imm22   disp22
+        } branch;
+        #ifndef NO_V9
+       struct
+        {
+          unsigned int anop:2;
+          unsigned int a:1;
+          unsigned int z:1;
+          unsigned int rcond:3;
+          unsigned int op2:3;
+          unsigned int DISP16HI:2;
+          unsigned int p:1;
+          unsigned int _rs1:5;
+          unsigned int DISP16LO:14;
+        } branch16;
+        #endif
+       struct
+        {
+          unsigned int anop:2;
+          unsigned int adisp30:30;
+          #define      disp30  call.adisp30
+        } call;
+     };
+
+   */
 
 /* Nonzero if INSN is the opcode for a delayed branch.  */
 static int
 is_delayed_branch (insn)
-     union sparc_insn insn;
+     unsigned long insn;
 {
-  unsigned int i;
+  struct opcode_hash *op;
 
-  for (i = 0; i < NUMOPCODES; ++i)
+  for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
     {
-      const struct sparc_opcode *opcode = &sparc_opcodes[i];
-      if ((opcode->match & insn.code) == opcode->match
-         && (opcode->lose & insn.code) == 0)
+      CONST struct sparc_opcode *opcode = op->opcode;
+      if ((opcode->match & insn) == opcode->match
+         && (opcode->lose & insn) == 0)
        return (opcode->flags & F_DELAYED);
     }
   return 0;
 }
 
-static int opcodes_sorted = 0;
-extern void qsort ();
+/* Nonzero of opcode table has been initialized.  */
+static int opcodes_initialized = 0;
 
-/* Print one instruction from MEMADDR on STREAM.
+/* Nonzero of the current architecture is sparc64.
+   This is kept in a global because compare_opcodes uses it.  */
+static int sparc64_p;
+
+/* extern void qsort (); */
+static int compare_opcodes ();
+
+/* Print one instruction from MEMADDR on INFO->STREAM.
 
    We suffix the instruction with a comment that gives the absolute
    address involved, as well as its symbolic form, if the instruction
    is preceded by a findable `sethi' and it either adds an immediate
    displacement to that register, or it is an `add' or `or' instruction
    on that register.  */
-int
-print_insn_sparc (memaddr, info)
+
+static int
+print_insn (memaddr, info)
      bfd_vma memaddr;
      disassemble_info *info;
 {
   FILE *stream = info->stream;
-  union sparc_insn insn;
-
+  bfd_byte buffer[4];
+  unsigned long insn;
   register unsigned int i;
+  register struct opcode_hash *op;
 
-  if (!opcodes_sorted)
+  if (!opcodes_initialized)
     {
-      static int compare_opcodes ();
       qsort ((char *) sparc_opcodes, NUMOPCODES,
             sizeof (sparc_opcodes[0]), compare_opcodes);
-      opcodes_sorted = 1;
+      build_hash_table (sparc_opcodes, opcode_hash_table, NUMOPCODES);
+      opcodes_initialized = 1;
     }
 
   {
     int status =
-      (*info->read_memory_func) (memaddr, (char *) &insn, sizeof (insn), info);
+      (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
     if (status != 0)
       {
        (*info->memory_error_func) (status, memaddr, info);
@@ -152,11 +219,19 @@ print_insn_sparc (memaddr, info)
       }
   }
 
-  for (i = 0; i < NUMOPCODES; ++i)
+  insn = bfd_getb32 (buffer);
+
+  info->insn_info_valid = 1;                   /* We do return this info */
+  info->insn_type = dis_nonbranch;             /* Assume non branch insn */
+  info->branch_delay_insns = 0;                        /* Assume no delay */
+  info->target = 0;                            /* Assume no target known */
+
+  for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
     {
-      const struct sparc_opcode *opcode = &sparc_opcodes[i];
-      if ((opcode->match & insn.code) == opcode->match
-         && (opcode->lose & insn.code) == 0)
+      CONST struct sparc_opcode *opcode = op->opcode;
+
+      if ((opcode->match & insn) == opcode->match
+         && (opcode->lose & insn) == 0)
        {
          /* Nonzero means that we have found an instruction which has
             the effect of adding or or'ing the imm13 field to rs1.  */
@@ -166,14 +241,17 @@ print_insn_sparc (memaddr, info)
             field of the opcode table.  */
          int found_plus = 0;
          
+         /* Nonzero means we have an annulled branch.  */
+         int is_annulled = 0;
+
          /* Do we have an `add' or `or' instruction where rs1 is the same
             as rsd, and which has the i bit set?  */
          if ((opcode->match == 0x80102000 || opcode->match == 0x80002000)
          /*                      (or)                           (add)  */
-             && insn.rs1 == insn.rd)
+             && X_RS1 (insn) == X_RD (insn))
            imm_added_to_rs1 = 1;
 
-         if (insn.rs1 != insn.rd
+         if (X_RS1 (insn) != X_RD (insn)
              && strchr (opcode->args, 'r') != 0)
              /* Can't do simple format if source and dest are different.  */
              continue;
@@ -181,7 +259,7 @@ print_insn_sparc (memaddr, info)
          (*info->fprintf_func) (stream, opcode->name);
 
          {
-           register const char *s;
+           register CONST char *s;
 
            if (opcode->args[0] != ',')
              (*info->fprintf_func) (stream, " ");
@@ -194,6 +272,7 @@ print_insn_sparc (memaddr, info)
                    switch (*s) {
                    case 'a':
                      (*info->fprintf_func) (stream, "a");
+                     is_annulled = 1;
                      ++s;
                      continue;
 #ifndef NO_V9
@@ -206,7 +285,7 @@ print_insn_sparc (memaddr, info)
                      (*info->fprintf_func) (stream, "pt");
                      ++s;
                      continue;
-#endif                         /* NO_V9 */
+#endif /* NO_V9 */
 
                    default:
                      break;
@@ -232,62 +311,69 @@ print_insn_sparc (memaddr, info)
 #define        reg(n)  (*info->fprintf_func) (stream, "%%%s", reg_names[n])
                  case '1':
                  case 'r':
-                   reg (insn.rs1);
+                   reg (X_RS1 (insn));
                    break;
 
                  case '2':
-                   reg (insn.rs2);
+                   reg (X_RS2 (insn));
                    break;
 
                  case 'd':
-                   reg (insn.rd);
+                   reg (X_RD (insn));
                    break;
 #undef reg
 
-#define        freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
+#define        freg(n)         (*info->fprintf_func) (stream, "%%%s", freg_names[n])
+#define        fregx(n)        (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
                  case 'e':
+                   freg (X_RS1 (insn));
+                   break;
                  case 'v':     /* double/even */
                  case 'V':     /* quad/multiple of 4 */
-                   freg (insn.rs1);
+                   fregx (X_RS1 (insn));
                    break;
 
                  case 'f':
+                   freg (X_RS2 (insn));
+                   break;
                  case 'B':     /* double/even */
                  case 'R':     /* quad/multiple of 4 */
-                   freg (insn.rs2);
+                   fregx (X_RS2 (insn));
                    break;
 
                  case 'g':
+                   freg (X_RD (insn));
+                   break;
                  case 'H':     /* double/even */
                  case 'J':     /* quad/multiple of 4 */
-                   freg (insn.rd);
+                   fregx (X_RD (insn));
                    break;
 #undef freg
+#undef fregx
 
 #define        creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
                  case 'b':
-                   creg (insn.rs1);
+                   creg (X_RS1 (insn));
                    break;
 
                  case 'c':
-                   creg (insn.rs2);
+                   creg (X_RS2 (insn));
                    break;
 
                  case 'D':
-                   creg (insn.rd);
+                   creg (X_RD (insn));
                    break;
 #undef creg
 
                  case 'h':
                    (*info->fprintf_func) (stream, "%%hi(%#x)",
-                                          (int) insn.imm22 << 10);
+                                          (0xFFFFFFFF
+                                           & ((int) X_IMM22 (insn) << 10)));
                    break;
 
                  case 'i':
                    {
-                     /* We cannot trust the compiler to sign-extend
-                        when extracting the bitfield, hence the shifts.  */
-                     int imm = ((int) insn.imm13 << 19) >> 19;
+                     int imm = SEX (X_IMM13 (insn), 13);
 
                      /* Check to see whether we have a 1+i, and take
                         note of that fact.
@@ -310,14 +396,12 @@ print_insn_sparc (memaddr, info)
                  case 'I':     /* 11 bit immediate.  */
                  case 'j':     /* 10 bit immediate.  */
                    {
-                     /* We cannot trust the compiler to sign-extend
-                        when extracting the bitfield, hence the shifts.  */
                      int imm;
 
                      if (*s == 'I')
-                       imm = ((int) insn.imm13 << 21) >> 21;
+                       imm = SEX (X_IMM13 (insn), 11);
                      else
-                       imm = ((int) insn.imm13 << 22) >> 22;
+                       imm = SEX (X_IMM13 (insn), 10);
 
                      /* Check to see whether we have a 1+i, and take
                         note of that fact.
@@ -336,37 +420,29 @@ print_insn_sparc (memaddr, info)
                    }
                    break;
 
-
-
-
                  case 'k':
-                   (*info->print_address_func)
-                     ((bfd_vma) (memaddr
-                                 + (((int) insn.disp14 << 18) >> 18) * 4),
-                      info);
+                   info->target = memaddr + (SEX (X_DISP16 (insn), 16)) * 4;
+                   (*info->print_address_func) (info->target, info);
                    break;
 
                  case 'G':
-                   (*info->print_address_func)
-                     ((bfd_vma) (memaddr
-                                 /* We use only 19 of the 21 bits.  */
-                                 + (((int) insn.disp21 << 13) >> 13) * 4),
-                      info);
+                   info->target = memaddr + (SEX (X_DISP22 (insn), 19)) * 4;
+                   (*info->print_address_func) (info->target, info);
                    break;
 
                  case '6':
                  case '7':
                  case '8':
                  case '9':
-                   (*info->fprintf_func) (stream, "fcc%c", *s - '6' + '0');
+                   (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
                    break;
 
                  case 'z':
-                   (*info->fprintf_func) (stream, "icc");
+                   (*info->fprintf_func) (stream, "%%icc");
                    break;
 
                  case 'Z':
-                   (*info->fprintf_func) (stream, "xcc");
+                   (*info->fprintf_func) (stream, "%%xcc");
                    break;
 
                  case 'E':
@@ -376,40 +452,64 @@ print_insn_sparc (memaddr, info)
                  case 's':
                    (*info->fprintf_func) (stream, "%%fprs");
                    break;
-#endif                         /* NO_V9 */
+
+                 case 'o':
+                   (*info->fprintf_func) (stream, "%%asi");
+                   break;
+
+                 case 'W':
+                   (*info->fprintf_func) (stream, "%%tick");
+                   break;
+
+                 case 'P':
+                   (*info->fprintf_func) (stream, "%%pc");
+                   break;
+
+                 case '?':
+                   if (X_RS1 (insn) == 31)
+                     (*info->fprintf_func) (stream, "%%ver");
+                   else if ((unsigned) X_RS1 (insn) < 16)
+                     (*info->fprintf_func) (stream, "%%%s",
+                                            v9_priv_reg_names[X_RS1 (insn)]);
+                   else
+                     (*info->fprintf_func) (stream, "%%reserved");
+                   break;
+
+                 case '!':
+                   if ((unsigned) X_RD (insn) < 15)
+                     (*info->fprintf_func) (stream, "%%%s",
+                                            v9_priv_reg_names[X_RD (insn)]);
+                   else
+                     (*info->fprintf_func) (stream, "%%reserved");
+                   break;
+                   break;
+#endif /* NO_V9 */
 
                  case 'M':
-                   (*info->fprintf_func) (stream, "%%asr%d", insn.rs1);
+                   (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
                    break;
                    
                  case 'm':
-                   (*info->fprintf_func) (stream, "%%asr%d", insn.rd);
+                   (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
                    break;
                    
                  case 'L':
-                   (*info->print_address_func)
-                    ((bfd_vma) memaddr + insn.disp30 * 4,
-                     info);
+                   info->target = memaddr + X_DISP30 (insn) * 4;
+                   (*info->print_address_func) (info->target, info);
+                   break;
+
+                 case 'n':
+                   (*info->fprintf_func)
+                     (stream, "%#x", (SEX (X_DISP22 (insn), 22)));
                    break;
 
                  case 'l':
-                   if ((insn.code >> 22) == 0)
-                     /* Special case for `unimp'.  Don't try to turn
-                        it's operand into a function offset.  */
-                     (*info->fprintf_func)
-                       (stream, "%#x",
-                        (int) (((int) insn.disp22 << 10) >> 10));
-                   else
-                     /* We cannot trust the compiler to sign-extend
-                        when extracting the bitfield, hence the shifts.  */
-                     (*info->print_address_func)
-                       ((bfd_vma) (memaddr
-                                   + (((int) insn.disp22 << 10) >> 10) * 4),
-                        info);
+                   info->target = memaddr + (SEX (X_DISP22 (insn), 22)) * 4;
+                   (*info->print_address_func) (info->target, info);
                    break;
 
                  case 'A':
-                   (*info->fprintf_func) (stream, "(%d)", (int) insn.asi);
+                   (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
                    break;
 
                  case 'C':
@@ -440,6 +540,12 @@ print_insn_sparc (memaddr, info)
                    (*info->fprintf_func) (stream, "%%wim");
                    break;
 
+                 case 'x':
+                   (*info->fprintf_func) (stream, "%d",
+                                          ((X_LDST_I (insn) << 8)
+                                           + X_ASI (insn)));
+                   break;
+
                  case 'y':
                    (*info->fprintf_func) (stream, "%%y");
                    break;
@@ -455,13 +561,13 @@ print_insn_sparc (memaddr, info)
             and its symbolic value.  */
          if (imm_added_to_rs1)
            {
-             union sparc_insn prev_insn;
+             unsigned long prev_insn;
              int errcode;
 
              errcode =
                (*info->read_memory_func)
-                 (memaddr - 4,
-                  (char *)&prev_insn, sizeof (prev_insn), info);
+                 (memaddr - 4, buffer, sizeof (buffer), info);
+             prev_insn = bfd_getb32 (buffer);
 
              if (errcode == 0)
                {
@@ -475,9 +581,11 @@ print_insn_sparc (memaddr, info)
                     */
 
                  if (is_delayed_branch (prev_insn))
-                   errcode = (*info->read_memory_func)
-                     (memaddr - 8, (char *)&prev_insn, sizeof (prev_insn),
-                      info);
+                   {
+                     errcode = (*info->read_memory_func)
+                       (memaddr - 8, buffer, sizeof (buffer), info);
+                     prev_insn = bfd_getb32 (buffer);
+                   }
                }
 
              /* If there was a problem reading memory, then assume
@@ -485,26 +593,40 @@ print_insn_sparc (memaddr, info)
              if (errcode == 0)
                {
                  /* Is it sethi to the same register?  */
-                 if ((prev_insn.code & 0xc1c00000) == 0x01000000
-                     && prev_insn.rd == insn.rs1)
+                 if ((prev_insn & 0xc1c00000) == 0x01000000
+                     && X_RD (prev_insn) == X_RS1 (insn))
                    {
                      (*info->fprintf_func) (stream, "\t! ");
-                     /* We cannot trust the compiler to sign-extend
-                        when extracting the bitfield, hence the shifts.  */
-                     (*info->print_address_func)
-                       (((int) prev_insn.imm22 << 10)
-                        | (insn.imm13 << 19) >> 19,
-                        info);
+                     info->target = 
+                       (0xFFFFFFFF & (int) X_IMM22 (prev_insn) << 10)
+                       | SEX (X_IMM13 (insn), 13);
+                     (*info->print_address_func) (info->target, info);
+                     info->insn_type = dis_dref;
+                     info->data_size = 4;  /* FIXME!!! */
                    }
                }
            }
 
-         return sizeof (insn);
+         if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
+           {
+               /* FIXME -- check is_annulled flag */
+             if (opcode->flags & F_UNBR)
+               info->insn_type = dis_branch;
+             if (opcode->flags & F_CONDBR)
+               info->insn_type = dis_condbranch;
+             if (opcode->flags & F_JSR)
+               info->insn_type = dis_jsr;
+             if (opcode->flags & F_DELAYED)
+               info->branch_delay_insns = 1;
+           }
+
+         return sizeof (buffer);
        }
     }
 
-  (*info->fprintf_func) (stream, "%#8x", insn.code);
-  return sizeof (insn);
+  info->insn_type = dis_noninsn;       /* Mark as non-valid instruction */
+  (*info->fprintf_func) (stream, "%#8x", insn);
+  return sizeof (buffer);
 }
 
 /* Compare opcodes A and B.  */
@@ -537,6 +659,20 @@ compare_opcodes (a, b)
       lose1 = op1->lose;
     }
 
+  /* If the current architecture isn't sparc64, move v9 insns to the end.
+     Only do this when one isn't v9 and one is.  If both are v9 we still
+     need to properly sort them.
+     This must be done before checking match and lose.  */
+  if (!sparc64_p
+      && (op0->architecture == v9) != (op1->architecture == v9))
+    return (op0->architecture == v9) - (op1->architecture == v9);
+
+  /* If the current architecture is sparc64, move non-v9 insns to the end.
+     This must be done before checking match and lose.  */
+  if (sparc64_p
+      && (op0->flags & F_NOTV9) != (op1->flags & F_NOTV9))
+    return (op0->flags & F_NOTV9) - (op1->flags & F_NOTV9);
+
   /* Because the bits that are variable in one opcode are constant in
      another, it is important to order the opcodes in the right order.  */
   for (i = 0; i < 32; ++i)
@@ -614,3 +750,78 @@ compare_opcodes (a, b)
      written, so just say there are equal.  */
   return 0;
 }
+
+/* Build a hash table from the opcode table.  */
+
+static void
+build_hash_table (table, hash_table, num_opcodes)
+     struct sparc_opcode *table;
+     struct opcode_hash **hash_table;
+     int num_opcodes;
+{
+  int i;
+  int hash_count[HASH_SIZE];
+
+  /* Start at the end of the table and work backwards so that each
+     chain is sorted.  */
+  /*  ??? Do we really need to sort them now?  */
+
+  memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
+  memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
+  for (i = num_opcodes - 1; i >= 0; --i)
+    {
+      int hash = HASH_INSN (sparc_opcodes[i].match);
+      struct opcode_hash *h = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash));
+      h->next = hash_table[hash];
+      h->opcode = &sparc_opcodes[i];
+      hash_table[hash] = h;
+      ++hash_count[hash];
+    }
+
+#if 0 /* for debugging */
+  {
+    int min_count = num_opcodes, max_count = 0;
+    int total;
+
+    for (i = 0; i < HASH_SIZE; ++i)
+      {
+        if (hash_count[i] < min_count)
+         min_count = hash_count[i];
+       if (hash_count[i] > max_count)
+         max_count = hash_count[i];
+       total += hash_count[i];
+      }
+
+    printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
+           min_count, max_count, (double) total / HASH_SIZE);
+  }
+#endif
+}
+
+int
+print_insn_sparc (memaddr, info)
+     bfd_vma memaddr;
+     disassemble_info *info;
+{
+  /* It's not clear that we'll ever switch cpus in a running program.
+     It could theoretically happen in gdb so we handle it.
+     ??? There is currently a memory leak but it's not worth the trouble.  */
+  if (sparc64_p)
+    opcodes_initialized = 0;
+  sparc64_p = 0;
+  return print_insn (memaddr, info);
+}
+
+int
+print_insn_sparc64 (memaddr, info)
+     bfd_vma memaddr;
+     disassemble_info *info;
+{
+  /* It's not clear that we'll ever switch cpus in a running program.
+     It could theoretically happen in gdb so we handle it.
+     ??? There is currently a memory leak but it's not worth the trouble.  */
+  if (!sparc64_p)
+    opcodes_initialized = 0;
+  sparc64_p = 1;
+  return print_insn (memaddr, info);
+}
index 315c19deebfa6c75e3f3b43521abaa23746d4e2b..c217384af4fb70e7d81d6675de1a91f6c7e0e332 100644 (file)
@@ -1,7 +1,5 @@
-/* to sanitize this file, grep -v v9 < sparc.h > clean-sparc.h */
-
 /* Table of opcodes for the sparc.
-       Copyright 1989, 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1989, 1991, 1992, 1995 Free Software Foundation, Inc.
 
 This file is part of the BFD library.
 
@@ -17,7 +15,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with this software; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.    */
 
 /* FIXME-someday: perhaps the ,a's and such should be embedded in the
    instruction's name rather than the args.  This would make gas faster, pinsn
@@ -30,7 +29,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
 #include "ansidecl.h"
 #include "opcode/sparc.h"
 
-CONST char *architecture_pname[] = {
+const char *architecture_pname[] = {
        "v6",
        "v7",
        "v8",
@@ -128,20 +127,18 @@ struct sparc_opcode sparc_opcodes[] = {
 { "ld",        F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RS1_G0|RD(~0),"[i],F", 0, v6 },
 { "ld",        F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|SIMM13(~0)|RD(~0),"[1],F", 0, v6 }, /* ld [rs1+0],d */
 
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "ld",        F3(3, 0x30, 0), F3(~3, ~0x30, ~0),              "[1+2],D", F_ALIAS, v6 },
-{ "ld",        F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0,       "[1],D", F_ALIAS, v6 }, /* ld [rs1+%g0],d */
-{ "ld",        F3(3, 0x30, 1), F3(~3, ~0x30, ~1),              "[1+i],D", F_ALIAS, v6 },
-{ "ld",        F3(3, 0x30, 1), F3(~3, ~0x30, ~1),              "[i+1],D", F_ALIAS, v6 },
-{ "ld",        F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0,       "[i],D", F_ALIAS, v6 },
-{ "ld",        F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0),   "[1],D", F_ALIAS, v6 }, /* ld [rs1+0],d */
-{ "ld",        F3(3, 0x31, 0), F3(~3, ~0x31, ~0),              "[1+2],C", 0, v6 },
-{ "ld",        F3(3, 0x31, 0), F3(~3, ~0x31, ~0)|RS2_G0,       "[1],C", 0, v6 }, /* ld [rs1+%g0],d */
-{ "ld",        F3(3, 0x31, 1), F3(~3, ~0x31, ~1),              "[1+i],C", 0, v6 },
-{ "ld",        F3(3, 0x31, 1), F3(~3, ~0x31, ~1),              "[i+1],C", 0, v6 },
-{ "ld",        F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|RS1_G0,       "[i],C", 0, v6 },
-{ "ld",        F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|SIMM13(~0),   "[1],C", 0, v6 }, /* ld [rs1+0],d */
+{ "ld",        F3(3, 0x30, 0), F3(~3, ~0x30, ~0),              "[1+2],D", F_NOTV9, v6 },
+{ "ld",        F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0,       "[1],D", F_NOTV9, v6 }, /* ld [rs1+%g0],d */
+{ "ld",        F3(3, 0x30, 1), F3(~3, ~0x30, ~1),              "[1+i],D", F_NOTV9, v6 },
+{ "ld",        F3(3, 0x30, 1), F3(~3, ~0x30, ~1),              "[i+1],D", F_NOTV9, v6 },
+{ "ld",        F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0,       "[i],D", F_NOTV9, v6 },
+{ "ld",        F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0),   "[1],D", F_NOTV9, v6 }, /* ld [rs1+0],d */
+{ "ld",        F3(3, 0x31, 0), F3(~3, ~0x31, ~0),              "[1+2],C", F_NOTV9, v6 },
+{ "ld",        F3(3, 0x31, 0), F3(~3, ~0x31, ~0)|RS2_G0,       "[1],C", F_NOTV9, v6 }, /* ld [rs1+%g0],d */
+{ "ld",        F3(3, 0x31, 1), F3(~3, ~0x31, ~1),              "[1+i],C", F_NOTV9, v6 },
+{ "ld",        F3(3, 0x31, 1), F3(~3, ~0x31, ~1),              "[i+1],C", F_NOTV9, v6 },
+{ "ld",        F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|RS1_G0,       "[i],C", F_NOTV9, v6 },
+{ "ld",        F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|SIMM13(~0),   "[1],C", F_NOTV9, v6 }, /* ld [rs1+0],d */
 
 /* The v9 LDUW is the same as the old 'ld' opcode, it is not the same as the
    'ld' pseudo-op in v9.  */
@@ -164,14 +161,13 @@ struct sparc_opcode sparc_opcodes[] = {
 { "ldd",       F3(3, 0x23, 1), F3(~3, ~0x23, ~1),              "[i+1],H", 0, v6 },
 { "ldd",       F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|RS1_G0,       "[i],H", 0, v6 },
 { "ldd",       F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|SIMM13(~0),   "[1],H", 0, v6 }, /* ldd [rs1+0],d */
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "ldd",       F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI(~0),      "[1+2],D", F_ALIAS, v6 },
-{ "ldd",       F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI_RS2(~0),  "[1],D", F_ALIAS, v6 }, /* ldd [rs1+%g0],d */
-{ "ldd",       F3(3, 0x33, 1), F3(~3, ~0x33, ~1),              "[1+i],D", F_ALIAS, v6 },
-{ "ldd",       F3(3, 0x33, 1), F3(~3, ~0x33, ~1),              "[i+1],D", F_ALIAS, v6 },
-{ "ldd",       F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|RS1_G0,       "[i],D", F_ALIAS, v6 },
-{ "ldd",       F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|SIMM13(~0),   "[1],D", F_ALIAS, v6 }, /* ldd [rs1+0],d */
+
+{ "ldd",       F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI(~0),      "[1+2],D", F_NOTV9, v6 },
+{ "ldd",       F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI_RS2(~0),  "[1],D", F_NOTV9, v6 }, /* ldd [rs1+%g0],d */
+{ "ldd",       F3(3, 0x33, 1), F3(~3, ~0x33, ~1),              "[1+i],D", F_NOTV9, v6 },
+{ "ldd",       F3(3, 0x33, 1), F3(~3, ~0x33, ~1),              "[i+1],D", F_NOTV9, v6 },
+{ "ldd",       F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|RS1_G0,       "[i],D", F_NOTV9, v6 },
+{ "ldd",       F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|SIMM13(~0),   "[1],D", F_NOTV9, v6 }, /* ldd [rs1+0],d */
 
 { "ldq",       F3(3, 0x22, 0), F3(~3, ~0x22, ~0)|ASI(~0),      "[1+2],J", 0, v9 },
 { "ldq",       F3(3, 0x22, 0), F3(~3, ~0x22, ~0)|ASI_RS2(~0),  "[1],J", 0, v9 }, /* ldd [rs1+%g0],d */
@@ -338,20 +334,19 @@ struct sparc_opcode sparc_opcodes[] = {
 { "st",        F3(3, 0x24, 1), F3(~3, ~0x24, ~1),                      "g,[i+1]", 0, v6 },
 { "st",        F3(3, 0x24, 1), F3(~3, ~0x24, ~1)|RS1_G0,               "g,[i]", 0, v6 },
 { "st",        F3(3, 0x24, 1), F3(~3, ~0x24, ~1)|SIMM13(~0),           "g,[1]", 0, v6 }, /* st d,[rs1+0] */
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "st",        F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI(~0),              "D,[1+2]", F_ALIAS, v6 },
-{ "st",        F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI_RS2(~0),          "D,[1]", F_ALIAS, v6 }, /* st d,[rs1+%g0] */
-{ "st",        F3(3, 0x34, 1), F3(~3, ~0x34, ~1),                      "D,[1+i]", F_ALIAS, v6 },
-{ "st",        F3(3, 0x34, 1), F3(~3, ~0x34, ~1),                      "D,[i+1]", F_ALIAS, v6 },
-{ "st",        F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|RS1_G0,               "D,[i]", F_ALIAS, v6 },
-{ "st",        F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|SIMM13(~0),           "D,[1]", F_ALIAS, v6 }, /* st d,[rs1+0] */
-{ "st",        F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI(~0),              "C,[1+2]", 0, v6 },
-{ "st",        F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI_RS2(~0),          "C,[1]", 0, v6 }, /* st d,[rs1+%g0] */
-{ "st",        F3(3, 0x35, 1), F3(~3, ~0x35, ~1),                      "C,[1+i]", 0, v6 },
-{ "st",        F3(3, 0x35, 1), F3(~3, ~0x35, ~1),                      "C,[i+1]", 0, v6 },
-{ "st",        F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|RS1_G0,               "C,[i]", 0, v6 },
-{ "st",        F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|SIMM13(~0),           "C,[1]", 0, v6 }, /* st d,[rs1+0] */
+
+{ "st",        F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI(~0),              "D,[1+2]", F_NOTV9, v6 },
+{ "st",        F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI_RS2(~0),          "D,[1]", F_NOTV9, v6 }, /* st d,[rs1+%g0] */
+{ "st",        F3(3, 0x34, 1), F3(~3, ~0x34, ~1),                      "D,[1+i]", F_NOTV9, v6 },
+{ "st",        F3(3, 0x34, 1), F3(~3, ~0x34, ~1),                      "D,[i+1]", F_NOTV9, v6 },
+{ "st",        F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|RS1_G0,               "D,[i]", F_NOTV9, v6 },
+{ "st",        F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|SIMM13(~0),           "D,[1]", F_NOTV9, v6 }, /* st d,[rs1+0] */
+{ "st",        F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI(~0),              "C,[1+2]", F_NOTV9, v6 },
+{ "st",        F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI_RS2(~0),          "C,[1]", F_NOTV9, v6 }, /* st d,[rs1+%g0] */
+{ "st",        F3(3, 0x35, 1), F3(~3, ~0x35, ~1),                      "C,[1+i]", F_NOTV9, v6 },
+{ "st",        F3(3, 0x35, 1), F3(~3, ~0x35, ~1),                      "C,[i+1]", F_NOTV9, v6 },
+{ "st",        F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|RS1_G0,               "C,[i]", F_NOTV9, v6 },
+{ "st",        F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|SIMM13(~0),           "C,[1]", F_NOTV9, v6 }, /* st d,[rs1+0] */
 
 { "st",        F3(3, 0x25, 0), F3(~3, ~0x25, ~0)|RD_G0|ASI(~0),        "F,[1+2]", 0, v6 },
 { "st",        F3(3, 0x25, 0), F3(~3, ~0x25, ~0)|RD_G0|ASI_RS2(~0),    "F,[1]", 0, v6 }, /* st d,[rs1+%g0] */
@@ -408,36 +403,32 @@ struct sparc_opcode sparc_opcodes[] = {
 { "std",       F3(3, 0x07, 1), F3(~3, ~0x07, ~1),              "d,[i+1]", 0, v6 },
 { "std",       F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|RS1_G0,       "d,[i]", 0, v6 },
 { "std",       F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|SIMM13(~0),   "d,[1]", 0, v6 }, /* std d,[rs1+0] */
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "std",       F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI(~0),      "q,[1+2]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI_RS2(~0),  "q,[1]", F_ALIAS, v6 }, /* std d,[rs1+%g0] */
-{ "std",       F3(3, 0x26, 1), F3(~3, ~0x26, ~1),              "q,[1+i]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x26, 1), F3(~3, ~0x26, ~1),              "q,[i+1]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|RS1_G0,       "q,[i]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|SIMM13(~0),   "q,[1]", F_ALIAS, v6 }, /* std d,[rs1+0] */
+
+{ "std",       F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI(~0),      "q,[1+2]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI_RS2(~0),  "q,[1]", F_NOTV9, v6 }, /* std d,[rs1+%g0] */
+{ "std",       F3(3, 0x26, 1), F3(~3, ~0x26, ~1),              "q,[1+i]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x26, 1), F3(~3, ~0x26, ~1),              "q,[i+1]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|RS1_G0,       "q,[i]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|SIMM13(~0),   "q,[1]", F_NOTV9, v6 }, /* std d,[rs1+0] */
 { "std",       F3(3, 0x27, 0), F3(~3, ~0x27, ~0)|ASI(~0),      "H,[1+2]", 0, v6 },
 { "std",       F3(3, 0x27, 0), F3(~3, ~0x27, ~0)|ASI_RS2(~0),  "H,[1]", 0, v6 }, /* std d,[rs1+%g0] */
 { "std",       F3(3, 0x27, 1), F3(~3, ~0x27, ~1),              "H,[1+i]", 0, v6 },
 { "std",       F3(3, 0x27, 1), F3(~3, ~0x27, ~1),              "H,[i+1]", 0, v6 },
 { "std",       F3(3, 0x27, 1), F3(~3, ~0x27, ~1)|RS1_G0,       "H,[i]", 0, v6 },
 { "std",       F3(3, 0x27, 1), F3(~3, ~0x27, ~1)|SIMM13(~0),   "H,[1]", 0, v6 }, /* std d,[rs1+0] */
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "std",       F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI(~0),      "Q,[1+2]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI_RS2(~0),  "Q,[1]", F_ALIAS, v6 }, /* std d,[rs1+%g0] */
-{ "std",       F3(3, 0x36, 1), F3(~3, ~0x36, ~1),              "Q,[1+i]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x36, 1), F3(~3, ~0x36, ~1),              "Q,[i+1]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|RS1_G0,       "Q,[i]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|SIMM13(~0),   "Q,[1]", F_ALIAS, v6 }, /* std d,[rs1+0] */
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "std",       F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI(~0),      "D,[1+2]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI_RS2(~0),  "D,[1]", F_ALIAS, v6 }, /* std d,[rs1+%g0] */
-{ "std",       F3(3, 0x37, 1), F3(~3, ~0x37, ~1),              "D,[1+i]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x37, 1), F3(~3, ~0x37, ~1),              "D,[i+1]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0,       "D,[i]", F_ALIAS, v6 },
-{ "std",       F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0),   "D,[1]", F_ALIAS, v6 }, /* std d,[rs1+0] */
+
+{ "std",       F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI(~0),      "Q,[1+2]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI_RS2(~0),  "Q,[1]", F_NOTV9, v6 }, /* std d,[rs1+%g0] */
+{ "std",       F3(3, 0x36, 1), F3(~3, ~0x36, ~1),              "Q,[1+i]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x36, 1), F3(~3, ~0x36, ~1),              "Q,[i+1]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|RS1_G0,       "Q,[i]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|SIMM13(~0),   "Q,[1]", F_NOTV9, v6 }, /* std d,[rs1+0] */
+{ "std",       F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI(~0),      "D,[1+2]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI_RS2(~0),  "D,[1]", F_NOTV9, v6 }, /* std d,[rs1+%g0] */
+{ "std",       F3(3, 0x37, 1), F3(~3, ~0x37, ~1),              "D,[1+i]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x37, 1), F3(~3, ~0x37, ~1),              "D,[i+1]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0,       "D,[i]", F_NOTV9, v6 },
+{ "std",       F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0),   "D,[1]", F_NOTV9, v6 }, /* std d,[rs1+0] */
 
 { "stda",      F3(3, 0x17, 0), F3(~3, ~0x17, ~0),              "d,[1+2]A", 0, v6 },
 { "stda",      F3(3, 0x17, 0), F3(~3, ~0x17, ~0)|RS2(~0),      "d,[1]A", 0, v6 }, /* stda d,[rs1+%g0] */
@@ -542,11 +533,11 @@ struct sparc_opcode sparc_opcodes[] = {
 { "jmpl",      F3(2, 0x38, 1), F3(~2, ~0x38, ~1),              "1+i,d", F_JSR|F_DELAYED, v6 },
 { "jmpl",      F3(2, 0x38, 1), F3(~2, ~0x38, ~1),              "i+1,d", F_JSR|F_DELAYED, v6 },
 
-{ "done",      F3(2, 0x3e, 1)|RD(0), F3(~2, ~0x3e, ~1)|RD(~0)|RS1_G0|SIMM13(~0),       "", 0, v9 },
-{ "retry",     F3(2, 0x3e, 1)|RD(1), F3(~2, ~0x3e, ~1)|RD(~1)|RS1_G0|SIMM13(~0),       "", 0, v9 },
-{ "saved",     F3(2, 0x31, 1)|RD(0), F3(~2, ~0x31, ~1)|RD(~0)|RS1_G0|SIMM13(~0),       "", 0, v9 },
-{ "restored",  F3(2, 0x31, 1)|RD(1), F3(~2, ~0x31, ~1)|RD(~1)|RS1_G0|SIMM13(~0),       "", 0, v9 },
-{ "sir",       F3(2, 0x30, 0)|RD(0xf), F3(~2, ~0x30, ~0)|RD(~0xf)|RS1_G0|SIMM13(~0),   "", 0, v9 },
+{ "done",      F3(2, 0x3e, 0)|RD(0), F3(~2, ~0x3e, ~0)|RD(~0)|RS1_G0|SIMM13(~0),       "", 0, v9 },
+{ "retry",     F3(2, 0x3e, 0)|RD(1), F3(~2, ~0x3e, ~0)|RD(~1)|RS1_G0|SIMM13(~0),       "", 0, v9 },
+{ "saved",     F3(2, 0x31, 0)|RD(0), F3(~2, ~0x31, ~0)|RD(~0)|RS1_G0|SIMM13(~0),       "", 0, v9 },
+{ "restored",  F3(2, 0x31, 0)|RD(1), F3(~2, ~0x31, ~0)|RD(~1)|RS1_G0|SIMM13(~0),       "", 0, v9 },
+{ "sir",       F3(2, 0x30, 1)|RD(0xf), F3(~2, ~0x30, ~1)|RD(~0xf)|RS1_G0,              "i", 0, v9 },
 
 { "flush",     F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI(~0),      "1+2", 0, v8 },
 { "flush",     F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI_RS2(~0),  "1", 0, v8 }, /* flush rs1+%g0 */
@@ -572,7 +563,7 @@ struct sparc_opcode sparc_opcodes[] = {
 
 { "flushw",    F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RD_G0|RS1_G0|ASI_RS2(~0),     "", 0, v9 },
 
-{ "membar",    F3(2, 0x28, 1)|RS1(0xf), F3(~2, ~0x28, ~1)|RD_G0|RS1(~0xf)|ASI(~0), "K", 0, v9 },
+{ "membar",    F3(2, 0x28, 1)|RS1(0xf), F3(~2, ~0x28, ~1)|RD_G0|RS1(~0xf)|SIMM13(~0), "K", 0, v9 },
 { "stbar",     F3(2, 0x28, 0)|RS1(0xf), F3(~2, ~0x28, ~0)|RD_G0|RS1(~0xf)|SIMM13(~0),  "", 0, v8 },
 
 { "prefetch",  F3(3, 0x2d, 0), F3(~3, ~0x2d, ~0),              "[1+2],*", 0, v9 },
@@ -589,6 +580,7 @@ struct sparc_opcode sparc_opcodes[] = {
 { "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1)|SIMM13(~0),   "[1]o,d", 0, v9 }, /* prefetcha [rs1+0],d */
 
  /* The 1<<12 is a long story.  It is necessary.  For more info, please contact rich@cygnus.com */
+ /* FIXME: 'i' is wrong, need new letter for 5 bit unsigned constants.  */
 { "sll",       F3(2, 0x25, 0), F3(~2, ~0x25, ~0)|(1<<12)|ASI(~0),      "1,2,d", 0, v6 },
 { "sll",       F3(2, 0x25, 1), F3(~2, ~0x25, ~1)|(1<<12),              "1,i,d", 0, v6 },
 { "sra",       F3(2, 0x27, 0), F3(~2, ~0x27, ~0)|(1<<12)|ASI(~0),      "1,2,d", 0, v6 },
@@ -596,12 +588,13 @@ struct sparc_opcode sparc_opcodes[] = {
 { "srl",       F3(2, 0x26, 0), F3(~2, ~0x26, ~0)|(1<<12)|ASI(~0),      "1,2,d", 0, v6 },
 { "srl",       F3(2, 0x26, 1), F3(~2, ~0x26, ~1)|(1<<12),              "1,i,d", 0, v6 },
 
+ /* FIXME: 'j' is wrong, need new letter for 6 bit unsigned constants.  */
 { "sllx",      F3(2, 0x25, 0)|(1<<12), F3(~2, ~0x25, ~0)|(ASI(~0)^(1<<12)),    "1,2,d", 0, v9 },
-{ "sllx",      F3(2, 0x25, 1)|(1<<12), F3(~2, ~0x25, ~1),              "1,i,d", 0, v9 },
+{ "sllx",      F3(2, 0x25, 1)|(1<<12), F3(~2, ~0x25, ~1)|(0x3f<<6),            "1,j,d", 0, v9 },
 { "srax",      F3(2, 0x27, 0)|(1<<12), F3(~2, ~0x27, ~0)|(ASI(~0)^(1<<12)),    "1,2,d", 0, v9 },
-{ "srax",      F3(2, 0x27, 1)|(1<<12), F3(~2, ~0x27, ~1),              "1,i,d", 0, v9 },
+{ "srax",      F3(2, 0x27, 1)|(1<<12), F3(~2, ~0x27, ~1)|(0x3f<<6),            "1,j,d", 0, v9 },
 { "srlx",      F3(2, 0x26, 0)|(1<<12), F3(~2, ~0x26, ~0)|(ASI(~0)^(1<<12)),    "1,2,d", 0, v9 },
-{ "srlx",      F3(2, 0x26, 1)|(1<<12), F3(~2, ~0x26, ~1),              "1,i,d", 0, v9 },
+{ "srlx",      F3(2, 0x26, 1)|(1<<12), F3(~2, ~0x26, ~1)|(0x3f<<6),            "1,j,d", 0, v9 },
 
 { "mulscc",    F3(2, 0x24, 0), F3(~2, ~0x24, ~0)|ASI(~0),      "1,2,d", 0, v6 },
 { "mulscc",    F3(2, 0x24, 1), F3(~2, ~0x24, ~1),              "1,i,d", 0, v6 },
@@ -654,18 +647,16 @@ struct sparc_opcode sparc_opcodes[] = {
 { "tst",       F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|RD_G0|RS1_G0|ASI(~0), "2", 0, v6 }, /* orcc %g0, rs2, %g0 */
 { "tst",       F3(2, 0x12, 1), F3(~2, ~0x12, ~1)|RD_G0|SIMM13(~0),     "1", 0, v6 }, /* orcc rs1, 0, %g0 */
 
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
 { "wr",        F3(2, 0x30, 0),         F3(~2, ~0x30, ~0)|ASI(~0),              "1,2,m", 0, v8 }, /* wr r,r,%asrX */
 { "wr",        F3(2, 0x30, 0),         F3(~2, ~0x30, ~0)|RD_G0|ASI(~0),        "1,2,y", 0, v6 }, /* wr r,r,%y */
 { "wr",        F3(2, 0x30, 1),         F3(~2, ~0x30, ~1),                      "1,i,m", 0, v8 }, /* wr r,i,%asrX */
 { "wr",        F3(2, 0x30, 1),         F3(~2, ~0x30, ~1)|RD_G0,                "1,i,y", 0, v6 }, /* wr r,i,%y */
-{ "wr",        F3(2, 0x31, 0),         F3(~2, ~0x31, ~0)|RD_G0|ASI(~0),        "1,2,p", F_ALIAS, v6 }, /* wr r,r,%psr */
-{ "wr",        F3(2, 0x31, 1),         F3(~2, ~0x31, ~1)|RD_G0,                "1,i,p", F_ALIAS, v6 }, /* wr r,i,%psr */
-{ "wr",        F3(2, 0x32, 0),         F3(~2, ~0x32, ~0)|RD_G0|ASI(~0),        "1,2,w", F_ALIAS, v6 }, /* wr r,r,%wim */
-{ "wr",        F3(2, 0x32, 1),         F3(~2, ~0x32, ~1)|RD_G0,                "1,i,w", F_ALIAS, v6 }, /* wr r,i,%wim */
-{ "wr",        F3(2, 0x33, 0),         F3(~2, ~0x33, ~0)|RD_G0|ASI(~0),        "1,2,t", F_ALIAS, v6 }, /* wr r,r,%tbr */
-{ "wr",        F3(2, 0x33, 1),         F3(~2, ~0x33, ~1)|RD_G0,                "1,i,t", F_ALIAS, v6 }, /* wr r,i,%tbr */
+{ "wr",        F3(2, 0x31, 0),         F3(~2, ~0x31, ~0)|RD_G0|ASI(~0),        "1,2,p", F_NOTV9, v6 }, /* wr r,r,%psr */
+{ "wr",        F3(2, 0x31, 1),         F3(~2, ~0x31, ~1)|RD_G0,                "1,i,p", F_NOTV9, v6 }, /* wr r,i,%psr */
+{ "wr",        F3(2, 0x32, 0),         F3(~2, ~0x32, ~0)|RD_G0|ASI(~0),        "1,2,w", F_NOTV9, v6 }, /* wr r,r,%wim */
+{ "wr",        F3(2, 0x32, 1),         F3(~2, ~0x32, ~1)|RD_G0,                "1,i,w", F_NOTV9, v6 }, /* wr r,i,%wim */
+{ "wr",        F3(2, 0x33, 0),         F3(~2, ~0x33, ~0)|RD_G0|ASI(~0),        "1,2,t", F_NOTV9, v6 }, /* wr r,r,%tbr */
+{ "wr",        F3(2, 0x33, 1),         F3(~2, ~0x33, ~1)|RD_G0,                "1,i,t", F_NOTV9, v6 }, /* wr r,i,%tbr */
 
 { "wr", F3(2, 0x30, 0)|RD(0), F3(~2, ~0x30, ~0)|RD(~0)|ASI(~0), "1,2,y", 0, v9 }, /* wr r,r,%y */
 { "wr", F3(2, 0x30, 1)|RD(0), F3(~2, ~0x30, ~1)|RD(~0),                "1,i,y", 0, v9 }, /* wr r,i,%y */
@@ -676,19 +667,17 @@ struct sparc_opcode sparc_opcodes[] = {
 { "wr", F3(2, 0x30, 0)|RD(6), F3(~2, ~0x30, ~0)|RD(~6)|ASI(~0), "1,2,s", 0, v9 }, /* wr r,i,%fprs */
 { "wr", F3(2, 0x30, 1)|RD(6), F3(~2, ~0x30, ~1)|RD(~6),                "1,i,s", 0, v9 }, /* wr r,i,%fprs */
 
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
 { "rd",        F3(2, 0x28, 0),                 F3(~2, ~0x28, ~0)|SIMM13(~0),           "M,d", 0, v8 }, /* rd %asrX,r */
 { "rd",        F3(2, 0x28, 0),                 F3(~2, ~0x28, ~0)|RS1_G0|SIMM13(~0),    "y,d", 0, v6 }, /* rd %y,r */
-{ "rd",        F3(2, 0x29, 0),                 F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0),    "p,d", F_ALIAS, v6 }, /* rd %psr,r */
-{ "rd",        F3(2, 0x2a, 0),                 F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0),    "w,d", F_ALIAS, v6 }, /* rd %wim,r */
-{ "rd",        F3(2, 0x2b, 0),                 F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0),    "t,d", F_ALIAS, v6 }, /* rd %tbr,r */
+{ "rd",        F3(2, 0x29, 0),                 F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0),    "p,d", F_NOTV9, v6 }, /* rd %psr,r */
+{ "rd",        F3(2, 0x2a, 0),                 F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0),    "w,d", F_NOTV9, v6 }, /* rd %wim,r */
+{ "rd",        F3(2, 0x2b, 0),                 F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0),    "t,d", F_NOTV9, v6 }, /* rd %tbr,r */
 
 { "rd",        F3(2, 0x28, 0)|RS1(2),          F3(~2, ~0x28, ~0)|RS1(~2)|SIMM13(~0),   "E,d", 0, v9 }, /* rd %ccr,r */
 { "rd",        F3(2, 0x28, 0)|RS1(3),          F3(~2, ~0x28, ~0)|RS1(~3)|SIMM13(~0),   "o,d", 0, v9 }, /* rd %asi,r */
 { "rd",        F3(2, 0x28, 0)|RS1(4),          F3(~2, ~0x28, ~0)|RS1(~4)|SIMM13(~0),   "W,d", 0, v9 }, /* rd %tick,r */
 { "rd",        F3(2, 0x28, 0)|RS1(5),          F3(~2, ~0x28, ~0)|RS1(~5)|SIMM13(~0),   "P,d", 0, v9 }, /* rd %pc,r */
-{ "rd",        F3(2, 0x2b, 0)|RS1(6),          F3(~2, ~0x2b, ~0)|RS1(~6)|SIMM13(~0),   "s,d", 0, v9 }, /* rd %fprs,r */
+{ "rd",        F3(2, 0x28, 0)|RS1(6),          F3(~2, ~0x28, ~0)|RS1(~6)|SIMM13(~0),   "s,d", 0, v9 }, /* rd %fprs,r */
 
 { "rdpr",      F3(2, 0x2a, 0),         F3(~2, ~0x2a, ~0)|SIMM13(~0),   "?,d", 0, v9 },   /* rdpr %priv,r */
 { "wrpr",      F3(2, 0x32, 0),         F3(~2, ~0x32, ~0),              "1,2,!", 0, v9 }, /* wrpr r1,r2,%priv */
@@ -714,9 +703,9 @@ struct sparc_opcode sparc_opcodes[] = {
    v9: Methinks we will need some sort of F_NOTFORV9 flag.  */
 { "mov",       F3(2, 0x28, 0),          F3(~2, ~0x28, ~0)|SIMM13(~0),                  "M,d", F_ALIAS, v8 }, /* rd %asr1,r */
 { "mov",       F3(2, 0x28, 0),          F3(~2, ~0x28, ~0)|RS1_G0|SIMM13(~0),           "y,d", F_ALIAS, v6 }, /* rd %y,r */
-{ "mov",       F3(2, 0x29, 0),          F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0),           "p,d", F_ALIAS, v6 }, /* rd %psr,r */
-{ "mov",       F3(2, 0x2a, 0),          F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0),           "w,d", F_ALIAS, v6 }, /* rd %wim,r */
-{ "mov",       F3(2, 0x2b, 0),          F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0),           "t,d", F_ALIAS, v6 }, /* rd %tbr,r */
+{ "mov",       F3(2, 0x29, 0),          F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0),           "p,d", F_ALIAS|F_NOTV9, v6 }, /* rd %psr,r */
+{ "mov",       F3(2, 0x2a, 0),          F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0),           "w,d", F_ALIAS|F_NOTV9, v6 }, /* rd %wim,r */
+{ "mov",       F3(2, 0x2b, 0),          F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0),           "t,d", F_ALIAS|F_NOTV9, v6 }, /* rd %tbr,r */
 
 { "mov",       F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI_RS2(~0),  "1,y", F_ALIAS, v6 }, /* wr rs1,%g0,%y */
 { "mov",       F3(2, 0x30, 1), F3(~2, ~0x30, ~1),              "i,y", F_ALIAS, v6 },
@@ -763,17 +752,13 @@ struct sparc_opcode sparc_opcodes[] = {
 { "subcc",     F3(2, 0x14, 0), F3(~2, ~0x14, ~0)|ASI(~0),      "1,2,d", 0, v6 },
 { "subcc",     F3(2, 0x14, 1), F3(~2, ~0x14, ~1),              "1,i,d", 0, v6 },
 
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "subx",      F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0),      "1,2,d", F_ALIAS, v6 },
-{ "subx",      F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1),              "1,i,d", F_ALIAS, v6 },
+{ "subx",      F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0),      "1,2,d", F_NOTV9, v6 },
+{ "subx",      F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1),              "1,i,d", F_NOTV9, v6 },
 { "subc",      F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0),      "1,2,d", 0, v9 },
 { "subc",      F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1),              "1,i,d", 0, v9 },
 
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "subxcc",    F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0),      "1,2,d", F_ALIAS, v6 },
-{ "subxcc",    F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1),              "1,i,d", F_ALIAS, v6 },
+{ "subxcc",    F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0),      "1,2,d", F_NOTV9, v6 },
+{ "subxcc",    F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1),              "1,i,d", F_NOTV9, v6 },
 { "subccc",    F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0),      "1,2,d", 0, v9 },
 { "subccc",    F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1),              "1,i,d", 0, v9 },
 
@@ -806,19 +791,17 @@ struct sparc_opcode sparc_opcodes[] = {
 { "addcc",     F3(2, 0x10, 0), F3(~2, ~0x10, ~0)|ASI(~0),      "1,2,d", 0, v6 },
 { "addcc",     F3(2, 0x10, 1), F3(~2, ~0x10, ~1),              "1,i,d", 0, v6 },
 { "addcc",     F3(2, 0x10, 1), F3(~2, ~0x10, ~1),              "i,1,d", 0, v6 },
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "addx",      F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0),      "1,2,d", F_ALIAS, v6 },
-{ "addx",      F3(2, 0x08, 1), F3(~2, ~0x08, ~1),              "1,i,d", F_ALIAS, v6 },
-{ "addx",      F3(2, 0x08, 1), F3(~2, ~0x08, ~1),              "i,1,d", F_ALIAS, v6 },
+
+{ "addx",      F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0),      "1,2,d", F_NOTV9, v6 },
+{ "addx",      F3(2, 0x08, 1), F3(~2, ~0x08, ~1),              "1,i,d", F_NOTV9, v6 },
+{ "addx",      F3(2, 0x08, 1), F3(~2, ~0x08, ~1),              "i,1,d", F_NOTV9, v6 },
 { "addc",      F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0),      "1,2,d", 0, v9 },
 { "addc",      F3(2, 0x08, 1), F3(~2, ~0x08, ~1),              "1,i,d", 0, v9 },
 { "addc",      F3(2, 0x08, 1), F3(~2, ~0x08, ~1),              "i,1,d", 0, v9 },
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "addxcc",    F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0),      "1,2,d", F_ALIAS, v6 },
-{ "addxcc",    F3(2, 0x18, 1), F3(~2, ~0x18, ~1),              "1,i,d", F_ALIAS, v6 },
-{ "addxcc",    F3(2, 0x18, 1), F3(~2, ~0x18, ~1),              "i,1,d", F_ALIAS, v6 },
+
+{ "addxcc",    F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0),      "1,2,d", F_NOTV9, v6 },
+{ "addxcc",    F3(2, 0x18, 1), F3(~2, ~0x18, ~1),              "1,i,d", F_NOTV9, v6 },
+{ "addxcc",    F3(2, 0x18, 1), F3(~2, ~0x18, ~1),              "i,1,d", F_NOTV9, v6 },
 { "addccc",    F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0),      "1,2,d", 0, v9 },
 { "addccc",    F3(2, 0x18, 1), F3(~2, ~0x18, ~1),              "1,i,d", 0, v9 },
 { "addccc",    F3(2, 0x18, 1), F3(~2, ~0x18, ~1),              "i,1,d", 0, v9 },
@@ -1297,9 +1280,7 @@ condfc("fbule",   "cb013", 0xe, 0),
 { "tsubcctv",  F3(2, 0x23, 0), F3(~2, ~0x23, ~0)|ASI(~0),      "1,2,d", 0, v6 },
 { "tsubcctv",  F3(2, 0x23, 1), F3(~2, ~0x23, ~1),              "1,i,d", 0, v6 },
 
-/* FIXME This is marked F_ALIAS, so that it won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "unimp",     F2(0x0, 0x0), 0xffc00000, "n", F_ALIAS, v6 },
+{ "unimp",     F2(0x0, 0x0), 0xffc00000, "n", F_NOTV9, v6 },
 { "illtrap",   F2(0, 0), F2(~0, ~0)|RD_G0, "n", 0, v9 },
 
 /* This *is* a commutative instruction.  */
@@ -1412,16 +1393,59 @@ condfc("fbule", "cb013", 0xe, 0),
 { "fcmpes",    CMPFCC(2)|F3F(2, 0x35, 0x055), CMPFCC(~2)|F3F(~2, ~0x35, ~0x055),        "8,e,f", 0, v9 },
 { "fcmpes",    CMPFCC(3)|F3F(2, 0x35, 0x055), CMPFCC(~3)|F3F(~2, ~0x35, ~0x055),        "9,e,f", 0, v9 },
 
-/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9
-   insns when v9 is present.  Otherwise, the F_ALIAS flag is ignored.  */
-{ "cpop1",     F3(2, 0x36, 0), F3(~2, ~0x36, ~1), "[1+2],d", F_ALIAS, v6 },
-{ "cpop2",     F3(2, 0x37, 0), F3(~2, ~0x37, ~1), "[1+2],d", F_ALIAS, v6 },
+/* These Extended FPop (FIFO) instructions are new in the Fujitsu
+   MB86934, replacing the CPop instructions from v6 and later
+   processors.  */
+
+#define EFPOP1_2(name, op, args) { name, F3F(2, 0x36, op), F3F(~2, ~0x36, ~op)|RS1_G0, args, 0, sparclite }
+#define EFPOP1_3(name, op, args) { name, F3F(2, 0x36, op), F3F(~2, ~0x36, ~op),        args, 0, sparclite }
+#define EFPOP2_2(name, op, args) { name, F3F(2, 0x37, op), F3F(~2, ~0x37, ~op)|RD_G0,  args, 0, sparclite }
+
+EFPOP1_2 ("efitod",    0x0c8, "f,H"),
+EFPOP1_2 ("efitos",    0x0c4, "f,g"),
+EFPOP1_2 ("efdtoi",    0x0d2, "B,g"),
+EFPOP1_2 ("efstoi",    0x0d1, "f,g"),
+EFPOP1_2 ("efstod",    0x0c9, "f,H"),
+EFPOP1_2 ("efdtos",    0x0c6, "B,g"),
+EFPOP1_2 ("efmovs",    0x001, "f,g"),
+EFPOP1_2 ("efnegs",    0x005, "f,g"),
+EFPOP1_2 ("efabss",    0x009, "f,g"),
+EFPOP1_2 ("efsqrtd",   0x02a, "B,H"),
+EFPOP1_2 ("efsqrts",   0x029, "f,g"),
+EFPOP1_3 ("efaddd",    0x042, "v,B,H"),
+EFPOP1_3 ("efadds",    0x041, "e,f,g"),
+EFPOP1_3 ("efsubd",    0x046, "v,B,H"),
+EFPOP1_3 ("efsubs",    0x045, "e,f,g"),
+EFPOP1_3 ("efdivd",    0x04e, "v,B,H"),
+EFPOP1_3 ("efdivs",    0x04d, "e,f,g"),
+EFPOP1_3 ("efmuld",    0x04a, "v,B,H"),
+EFPOP1_3 ("efmuls",    0x049, "e,f,g"),
+EFPOP1_3 ("efsmuld",   0x069, "e,f,H"),
+EFPOP2_2 ("efcmpd",    0x052, "v,B"),
+EFPOP2_2 ("efcmped",   0x056, "v,B"),
+EFPOP2_2 ("efcmps",    0x051, "e,f"),
+EFPOP2_2 ("efcmpes",   0x055, "e,f"),
+
+#undef EFPOP1_2
+#undef EFPOP1_3
+#undef EFPOP2_2
+
+/* These are marked F_ALIAS, so that they won't conflict with sparclite insns
+   present.  Otherwise, the F_ALIAS flag is ignored.  */
+{ "cpop1",     F3(2, 0x36, 0), F3(~2, ~0x36, ~1), "[1+2],d", F_ALIAS|F_NOTV9, v6 },
+{ "cpop2",     F3(2, 0x37, 0), F3(~2, ~0x37, ~1), "[1+2],d", F_ALIAS|F_NOTV9, v6 },
+
+#define IMPDEP(name, code) \
+{ name,        F3(2, code, 0), F3(~2, ~code, ~0)|ASI(~0), "1,2,d", 0, v9 }, \
+{ name,        F3(2, code, 1), F3(~2, ~code, ~1),         "1,i,d", 0, v9 }, \
+{ name, F3(2, code, 0), F3(~2, ~code, ~0),         "x,1,2,d", 0, v9 }, \
+{ name, F3(2, code, 0), F3(~2, ~code, ~0),         "x,e,f,g", 0, v9 }
+
+IMPDEP ("impdep1", 0x36),
+IMPDEP ("impdep2", 0x37),
+
+#undef IMPDEP
 
-{ "impdep1",   F3(2, 0x36, 0), F3(~2, ~0x36, ~0)|ASI(~0), "1,2,d", 0, v9 },
-{ "impdep1",   F3(2, 0x36, 1), F3(~2, ~0x36, ~1),         "1,i,d", 0, v9 },
-{ "impdep2",   F3(2, 0x37, 0), F3(~2, ~0x37, ~0)|ASI(~0), "1,2,d", 0, v9 },
-{ "impdep2",   F3(2, 0x37, 1), F3(~2, ~0x37, ~1),         "1,i,d", 0, v9 },
-    
 { "casa",      F3(3, 0x3c, 0), F3(~3, ~0x3c, ~0), "[1]A,2,d", 0, v9 },
 { "casa",      F3(3, 0x3c, 1), F3(~3, ~0x3c, ~1), "[1]o,2,d", 0, v9 },
 { "casxa",     F3(3, 0x3e, 0), F3(~3, ~0x3e, ~0), "[1]A,2,d", 0, v9 },
@@ -1429,4 +1453,4 @@ condfc("fbule",   "cb013", 0xe, 0),
 
 };
 
-CONST int bfd_sparc_num_opcodes = ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0]));
+const int bfd_sparc_num_opcodes = ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0]));