(sparc_{encode,decode}_asi): New functions.
* sparc-dis.c (print_insn): Call sparc_decode_asi.
+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,
/* 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 ();
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];
{
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)
{
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");
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)
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. */
}
}
+ /* 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
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
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);
}
{ "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 */
};
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;
+}