* 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:
David Edelsohn 1995-08-29 22:44:00 +00:00
parent 44292d2e1e
commit 7ec658304a
3 changed files with 111 additions and 39 deletions

View 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,

View 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);
}

View 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]));
/* 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;
}