* sparc-opc.c (asi): New static local.
authorDavid Edelsohn <dje.gcc@gmail.com>
Tue, 29 Aug 1995 22:44:00 +0000 (22:44 +0000)
committerDavid Edelsohn <dje.gcc@gmail.com>
Tue, 29 Aug 1995 22:44:00 +0000 (22:44 +0000)
(sparc_{encode,decode}_asi): New functions.
* sparc-dis.c (print_insn): Call sparc_decode_asi.

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

index cd6da005204f378fa8b27d86b19e6b7aef7b0f7d..3122600fb2858c9fe18cbe1822a4b4168c371801 100644 (file)
@@ -1,3 +1,13 @@
+Tue Aug 29 15:37:18 1995  Doug Evans  <dje@canuck.cygnus.com>
+
+       * sparc-opc.c (asi): New static local.
+       (sparc_{encode,decode}_asi): New functions.
+       * sparc-dis.c (print_insn): Call sparc_decode_asi.
+
+Sat Aug 26 21:22:48 1995  Ian Lance Taylor  <ian@cygnus.com>
+
+       * m68k-opc.c (m68k_opcode_aliases): Add br, brs, brb, brw, brl.
+
 Mon Aug 21 17:33:36 1995  Ian Lance Taylor  <ian@cygnus.com>
 
        * m68k-opc.c (m68k_opcode_aliases): Add bhib as an alias for bhis,
index 271fe416546a96e89e1d64b29e0c52b806379628..0962f9f571e5841b3661e9a99f15f5ef4e72b430 100644 (file)
@@ -175,10 +175,6 @@ is_delayed_branch (insn)
 /* Nonzero of opcode table has been initialized.  */
 static int opcodes_initialized = 0;
 
-/* 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 ();
 
@@ -191,9 +187,10 @@ static int compare_opcodes ();
    on that register.  */
 
 static int
-print_insn (memaddr, info)
+print_insn (memaddr, info, sparc64_p)
      bfd_vma memaddr;
      disassemble_info *info;
+     int sparc64_p;
 {
   FILE *stream = info->stream;
   bfd_byte buffer[4];
@@ -230,6 +227,16 @@ print_insn (memaddr, info)
     {
       CONST struct sparc_opcode *opcode = op->opcode;
 
+      /* If the current architecture isn't sparc64, skip sparc64 insns.  */
+      if (!sparc64_p
+         && opcode->architecture == v9)
+       continue;
+
+      /* If the current architecture is sparc64, skip sparc32 only insns.  */
+      if (sparc64_p
+         && (opcode->flags & F_NOTV9))
+       continue;
+
       if ((opcode->match & insn) == opcode->match
          && (opcode->lose & insn) == 0)
        {
@@ -509,8 +516,15 @@ print_insn (memaddr, info)
                    break;
 
                  case 'A':
-                   (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
-                   break;
+                   {
+                     char *name = sparc_decode_asi (X_ASI (insn));
+
+                     if (name)
+                       (*info->fprintf_func) (stream, "%s", name);
+                     else
+                       (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
+                     break;
+                   }
 
                  case 'C':
                    (*info->fprintf_func) (stream, "%%csr");
@@ -659,20 +673,6 @@ 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)
@@ -695,6 +695,10 @@ compare_opcodes (a, b)
        return x1 - x0;
     }
 
+  /* Put non-sparc64 insns ahead of sparc64 ones.  */
+  if ((op0->architecture == v9) != (op1->architecture == v9))
+    return (op0->architecture == v9) - (op1->architecture == v9);
+
   /* They are functionally equal.  So as long as the opcode table is
      valid, we can put whichever one first we want, on aesthetic grounds.  */
 
@@ -744,6 +748,15 @@ compare_opcodes (a, b)
       }
   }
 
+  /* Put 1,i before i,1.  */
+  {
+    int i0 = strncmp (op0->args, "i,1", 3) == 0;
+    int i1 = strncmp (op1->args, "i,1", 3) == 0;
+
+    if (i0 ^ i1)
+      return i0 - i1;
+  }
+
   /* They are, as far as we can tell, identical.
      Since qsort may have rearranged the table partially, there is
      no way to tell which one was first in the opcode table as
@@ -806,13 +819,7 @@ print_insn_sparc (memaddr, info)
      bfd_vma memaddr;
      disassemble_info *info;
 {
-  /* It could happen that we'll switch cpus in a running program.
-     Consider objdump or gdb.  The frequency of occurrence is expected
-     to be low enough that our clumsy approach is not a problem.  */
-  if (sparc64_p)
-    opcodes_initialized = 0;
-  sparc64_p = 0;
-  return print_insn (memaddr, info);
+  return print_insn (memaddr, info, 0);
 }
 
 int
@@ -820,11 +827,5 @@ print_insn_sparc64 (memaddr, info)
      bfd_vma memaddr;
      disassemble_info *info;
 {
-  /* It could happen that we'll switch cpus in a running program.
-     Consider objdump or gdb.  The frequency of occurrence is expected
-     to be low enough that our clumsy approach is not a problem.  */
-  if (!sparc64_p)
-    opcodes_initialized = 0;
-  sparc64_p = 1;
-  return print_insn (memaddr, info);
+  return print_insn (memaddr, info, 1);
 }
index c217384af4fb70e7d81d6675de1a91f6c7e0e332..04953437111d287478d3752e969d7ca2d600769a 100644 (file)
@@ -697,10 +697,6 @@ struct sparc_opcode sparc_opcodes[] = {
 { "mov",       F3(2, 0x33, 0),         F3(~2, ~0x33, ~0)|RD_G0|ASI(~0),        "1,2,t", F_ALIAS, v6 }, /* wr r,r,%tbr */
 { "mov",       F3(2, 0x33, 1),         F3(~2, ~0x33, ~1)|RD_G0,                "1,i,t", F_ALIAS, v6 }, /* wr r,i,%tbr */
 
-/* v9: FIXME: On disassembly, rd %wim,r still gets preferred to rdpr %tpc,r.
-   v9: This is because the former is stricter in which bits can be set and
-   v9: compare_opcodes() will prefer it, even though F_ALIAS is set.
-   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|F_NOTV9, v6 }, /* rd %psr,r */
@@ -1454,3 +1450,68 @@ IMPDEP ("impdep2", 0x37),
 };
 
 const int bfd_sparc_num_opcodes = ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0]));
+\f
+/* Handle ASI's.  */
+
+static struct asi
+{
+  int value;
+  char *name;
+} asi[] =
+{
+  { 0x10, "#ASI_AIUP" },
+  { 0x11, "#ASI_AIUS" },
+  { 0x18, "#ASI_AIUP_L" },
+  { 0x19, "#ASI_AIUS_L" },
+  { 0x80, "#ASI_P" },
+  { 0x81, "#ASI_S" },
+  { 0x82, "#ASI_PNF" },
+  { 0x83, "#ASI_SNF" },
+  { 0x88, "#ASI_P_L" },
+  { 0x89, "#ASI_S_L" },
+  { 0x8a, "#ASI_PNF_L" },
+  { 0x8b, "#ASI_SNF_L" },
+  { 0x10, "#ASI_AS_IF_USER_PRIMARY" },
+  { 0x11, "#ASI_AS_IF_USER_SECONDARY" },
+  { 0x18, "#ASI_AS_IF_USER_PRIMARY_L" },
+  { 0x19, "#ASI_AS_IF_USER_SECONDARY_L" },
+  { 0x80, "#ASI_PRIMARY" },
+  { 0x81, "#ASI_SECONDARY" },
+  { 0x82, "#ASI_PRIMARY_NOFAULT" },
+  { 0x83, "#ASI_SECONDARY_NOFAULT" },
+  { 0x88, "#ASI_PRIMARY_LITTLE" },
+  { 0x89, "#ASI_SECONDARY_LITTLE" },
+  { 0x8a, "#ASI_PRIMARY_NOFAULT_LITTLE" },
+  { 0x8b, "#ASI_SECONDARY_NOFAULT_LITTLE" },
+  { 0, 0 }
+};
+
+/* Return the value for ASI NAME, or -1 if not found.  */
+
+int
+sparc_encode_asi (name)
+     char *name;
+{
+  struct asi *p;
+
+  for (p = &asi[0]; p->name; ++p)
+    if (strcmp (name, p->name) == 0)
+      return p->value;
+
+  return -1;
+}
+
+/* Return the name for ASI value VALUE or NULL if not found.  */
+
+char *
+sparc_decode_asi (value)
+     int value;
+{
+  struct asi *p;
+
+  for (p = &asi[0]; p->name; ++p)
+    if (value == p->value)
+      return p->name;
+
+  return (char *) 0;
+}