* sparc-opc.c (asi): New static local.
(sparc_{encode,decode}_asi): New functions. * sparc-dis.c (print_insn): Call sparc_decode_asi.
This commit is contained in:
parent
44292d2e1e
commit
7ec658304a
3 changed files with 111 additions and 39 deletions
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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]));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue