From 7ec658304ad3bd40e5ae60c10c5c06cb80796a73 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Tue, 29 Aug 1995 22:44:00 +0000 Subject: [PATCH] * sparc-opc.c (asi): New static local. (sparc_{encode,decode}_asi): New functions. * sparc-dis.c (print_insn): Call sparc_decode_asi. --- opcodes/ChangeLog | 10 +++++++ opcodes/sparc-dis.c | 71 +++++++++++++++++++++++---------------------- opcodes/sparc-opc.c | 69 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 111 insertions(+), 39 deletions(-) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index cd6da005204..3122600fb28 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,13 @@ +Tue Aug 29 15:37:18 1995 Doug Evans + + * 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 + + * m68k-opc.c (m68k_opcode_aliases): Add br, brs, brb, brw, brl. + Mon Aug 21 17:33:36 1995 Ian Lance Taylor * m68k-opc.c (m68k_opcode_aliases): Add bhib as an alias for bhis, diff --git a/opcodes/sparc-dis.c b/opcodes/sparc-dis.c index 271fe416546..0962f9f571e 100644 --- a/opcodes/sparc-dis.c +++ b/opcodes/sparc-dis.c @@ -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); } diff --git a/opcodes/sparc-opc.c b/opcodes/sparc-opc.c index c217384af4f..04953437111 100644 --- a/opcodes/sparc-opc.c +++ b/opcodes/sparc-opc.c @@ -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; +} -- 2.30.2