From: David Edelsohn Date: Wed, 2 Aug 1995 16:06:17 +0000 (+0000) Subject: * sparc-dis.c (HASH_SIZE, HASH_INSN): Define. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f069afb4eb539bd89f9a163f82bd8e30ba6132f3;p=binutils-gdb.git * sparc-dis.c (HASH_SIZE, HASH_INSN): Define. (opcode_bits, opcode_hash_table, sparc64_p): New variables. (opcodes_initialized): Renamed from opcodes_sorted. (build_hash_table): New function. (is_delayed_branch): Use hash table. (print_insn): Renamed from print_insn_sparc, made static. Build and use hash table. (print_insn_sparc, print_insn_sparc64): New functions. (compare_opcodes): If !sparc64, move sparc64 opcodes to end, and vice-versa if sparc64. * sparc-opc.c (all non-v9 insns): Use flag F_NOTV9 instead of F_ALIAS. --- diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 393e457a86b..a5188c29842 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,42 @@ +Wed Aug 2 08:23:38 1995 Doug Evans + + * sparc-dis.c (HASH_SIZE, HASH_INSN): Define. + (opcode_bits, opcode_hash_table, sparc64_p): New variables. + (opcodes_initialized): Renamed from opcodes_sorted. + (build_hash_table): New function. + (is_delayed_branch): Use hash table. + (print_insn): Renamed from print_insn_sparc, made static. + Build and use hash table. + (print_insn_sparc, print_insn_sparc64): New functions. + (compare_opcodes): If !sparc64, move sparc64 opcodes to end, + and vice-versa if sparc64. + * sparc-opc.c (all non-v9 insns): Use flag F_NOTV9 instead of F_ALIAS. + +Tue Aug 1 00:12:49 1995 Ian Lance Taylor + + * sh-dis.c (print_insn_shx): Remove unused local dslot. Use + print_address_func for A_BDISP12 and A_BDISP8. Correct test which + avoids printing a delay slot in a delay slot. + * sh-opc.h (sh_table): Fully bracket last entry. + +Mon Jul 31 12:04:47 1995 Doug Evans + + * sparc-opc.c (sllx, srax, srlx): Fix disassembly. + +Wed Jul 12 00:59:34 1995 Ken Raeburn + + * configure.in: Get host_makefile_frag from ${srcdir}. + + * configure.in: Autoconfiscated. Check for string[s].h. Create + config.h from config.in. Don't set up sysdep.h link. + * sysdep.h: New file. + * configure, config.in: New files, generated from configure.in. + * Makefile.in: Updated to be processed autoconf-style. + (distclean): Keep sysdep.h. Remove config.log and config.cache. + (Makefile): Depend on config.status. + (config.status): New rule. + * configure.bat: Update Makefile substitutions. + Tue Jul 11 14:23:37 1995 Jeff Spiegel * mips-opc.c (L1): Define. diff --git a/opcodes/sparc-dis.c b/opcodes/sparc-dis.c index a3d59b8be83..532fb94c228 100644 --- a/opcodes/sparc-dis.c +++ b/opcodes/sparc-dis.c @@ -1,5 +1,5 @@ /* Print SPARC instructions. - Copyright 1989, 1991, 1992, 1993 Free Software Foundation, Inc. + Copyright 1989, 1991, 1992, 1993, 1995 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,14 +13,38 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "ansidecl.h" #include "opcode/sparc.h" #include "dis-asm.h" +#include "libiberty.h" #include +/* For faster lookup, after insns are sorted they are hashed. */ +/* ??? I think there is room for even more improvement. */ + +#define HASH_SIZE 256 +/* It is important that we only look at insn code bits as that is how the + opcode table is hashed. OPCODE_BITS is a table of valid bits for each + of the main types (0,1,2,3). */ +static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 }; +#define HASH_INSN(INSN) \ + ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19)) +struct opcode_hash { + struct opcode_hash *next; + struct sparc_opcode *opcode; +}; +static struct opcode_hash *opcode_hash_table[HASH_SIZE]; +static void build_hash_table (); + +/* Sign-extend a value which is N bits long. */ +#define SEX(value, bits) \ + ((((int)(value)) << ((8 * sizeof (int)) - bits)) \ + >> ((8 * sizeof (int)) - bits) ) + static char *reg_names[] = - { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", +{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", @@ -28,123 +52,166 @@ static char *reg_names[] = "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" }; +#ifndef NO_V9 + "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39", + "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", + "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55", + "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63", +/* psr, wim, tbr, fpsr, cpsr are v8 only. */ +#endif + "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" +}; #define freg_names (®_names[4 * 8]) -/* FIXME--need to deal with byte order (probably using masking and - shifting rather than bitfields is easiest). */ +#ifndef NO_V9 +/* These are ordered according to there register number in + rdpr and wrpr insns. */ +static char *v9_priv_reg_names[] = +{ + "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl", + "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin", + "wstate", "fq" + /* "ver" - special cased */ +}; +#endif + +/* Macros used to extract instruction fields. Not all fields have + macros defined here, only those which are actually used. */ + +#define X_RD(i) (((i) >> 25) & 0x1f) +#define X_RS1(i) (((i) >> 14) & 0x1f) +#define X_LDST_I(i) (((i) >> 13) & 1) +#define X_ASI(i) (((i) >> 5) & 0xff) +#define X_RS2(i) (((i) >> 0) & 0x1f) +#define X_IMM13(i) (((i) >> 0) & 0x1fff) +#define X_DISP22(i) (((i) >> 0) & 0x3fffff) +#define X_IMM22(i) X_DISP22 (i) +#define X_DISP30(i) (((i) >> 0) & 0x3fffffff) -union sparc_insn - { - unsigned long int code; - struct - { - unsigned int anop:2; -#define op ldst.anop - unsigned int anrd:5; -#define rd ldst.anrd - unsigned int op3:6; - unsigned int anrs1:5; -#define rs1 ldst.anrs1 - unsigned int i:1; - unsigned int anasi:8; -#define asi ldst.anasi - unsigned int anrs2:5; -#define rs2 ldst.anrs2 -#define shcnt rs2 - } ldst; - struct - { - unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1; - unsigned int IMM13:13; -#define imm13 IMM13.IMM13 - } IMM13; - struct - { - unsigned int anop:2; - unsigned int a:1; - unsigned int cond:4; - unsigned int op2:3; - unsigned int DISP22:22; -#define disp22 branch.DISP22 - } branch; #ifndef NO_V9 - struct - { - unsigned int _OP:2, _RD:5, op3:6, _RS1:5; - unsigned int DISP14:14; -#define disp14 DISP14.DISP14 - } DISP14; - struct - { - unsigned int _OP:2; - unsigned int a:1; - unsigned int cond:4; - unsigned int op2:3; - unsigned int p:1; - unsigned int DISP21:21; -#define disp21 branch2.DISP21 - } branch2; -#endif /* NO_V9 */ - -#define imm22 disp22 - struct - { - unsigned int anop:2; - unsigned int adisp30:30; -#define disp30 call.adisp30 - } call; - }; +#define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff)) +#endif + +/* Here is the union which was used to extract instruction fields + before the shift and mask macros were written. + + union sparc_insn + { + unsigned long int code; + struct + { + unsigned int anop:2; + #define op ldst.anop + unsigned int anrd:5; + #define rd ldst.anrd + unsigned int op3:6; + unsigned int anrs1:5; + #define rs1 ldst.anrs1 + unsigned int i:1; + unsigned int anasi:8; + #define asi ldst.anasi + unsigned int anrs2:5; + #define rs2 ldst.anrs2 + #define shcnt rs2 + } ldst; + struct + { + unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1; + unsigned int IMM13:13; + #define imm13 IMM13.IMM13 + } IMM13; + struct + { + unsigned int anop:2; + unsigned int a:1; + unsigned int cond:4; + unsigned int op2:3; + unsigned int DISP22:22; + #define disp22 branch.DISP22 + #define imm22 disp22 + } branch; + #ifndef NO_V9 + struct + { + unsigned int anop:2; + unsigned int a:1; + unsigned int z:1; + unsigned int rcond:3; + unsigned int op2:3; + unsigned int DISP16HI:2; + unsigned int p:1; + unsigned int _rs1:5; + unsigned int DISP16LO:14; + } branch16; + #endif + struct + { + unsigned int anop:2; + unsigned int adisp30:30; + #define disp30 call.adisp30 + } call; + }; + + */ /* Nonzero if INSN is the opcode for a delayed branch. */ static int is_delayed_branch (insn) - union sparc_insn insn; + unsigned long insn; { - unsigned int i; + struct opcode_hash *op; - for (i = 0; i < NUMOPCODES; ++i) + for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next) { - const struct sparc_opcode *opcode = &sparc_opcodes[i]; - if ((opcode->match & insn.code) == opcode->match - && (opcode->lose & insn.code) == 0) + CONST struct sparc_opcode *opcode = op->opcode; + if ((opcode->match & insn) == opcode->match + && (opcode->lose & insn) == 0) return (opcode->flags & F_DELAYED); } return 0; } -static int opcodes_sorted = 0; -extern void qsort (); +/* Nonzero of opcode table has been initialized. */ +static int opcodes_initialized = 0; -/* Print one instruction from MEMADDR on STREAM. +/* 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 (); + +/* Print one instruction from MEMADDR on INFO->STREAM. We suffix the instruction with a comment that gives the absolute address involved, as well as its symbolic form, if the instruction is preceded by a findable `sethi' and it either adds an immediate displacement to that register, or it is an `add' or `or' instruction on that register. */ -int -print_insn_sparc (memaddr, info) + +static int +print_insn (memaddr, info) bfd_vma memaddr; disassemble_info *info; { FILE *stream = info->stream; - union sparc_insn insn; - + bfd_byte buffer[4]; + unsigned long insn; register unsigned int i; + register struct opcode_hash *op; - if (!opcodes_sorted) + if (!opcodes_initialized) { - static int compare_opcodes (); qsort ((char *) sparc_opcodes, NUMOPCODES, sizeof (sparc_opcodes[0]), compare_opcodes); - opcodes_sorted = 1; + build_hash_table (sparc_opcodes, opcode_hash_table, NUMOPCODES); + opcodes_initialized = 1; } { int status = - (*info->read_memory_func) (memaddr, (char *) &insn, sizeof (insn), info); + (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); @@ -152,11 +219,19 @@ print_insn_sparc (memaddr, info) } } - for (i = 0; i < NUMOPCODES; ++i) + insn = bfd_getb32 (buffer); + + info->insn_info_valid = 1; /* We do return this info */ + info->insn_type = dis_nonbranch; /* Assume non branch insn */ + info->branch_delay_insns = 0; /* Assume no delay */ + info->target = 0; /* Assume no target known */ + + for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next) { - const struct sparc_opcode *opcode = &sparc_opcodes[i]; - if ((opcode->match & insn.code) == opcode->match - && (opcode->lose & insn.code) == 0) + CONST struct sparc_opcode *opcode = op->opcode; + + if ((opcode->match & insn) == opcode->match + && (opcode->lose & insn) == 0) { /* Nonzero means that we have found an instruction which has the effect of adding or or'ing the imm13 field to rs1. */ @@ -166,14 +241,17 @@ print_insn_sparc (memaddr, info) field of the opcode table. */ int found_plus = 0; + /* Nonzero means we have an annulled branch. */ + int is_annulled = 0; + /* Do we have an `add' or `or' instruction where rs1 is the same as rsd, and which has the i bit set? */ if ((opcode->match == 0x80102000 || opcode->match == 0x80002000) /* (or) (add) */ - && insn.rs1 == insn.rd) + && X_RS1 (insn) == X_RD (insn)) imm_added_to_rs1 = 1; - if (insn.rs1 != insn.rd + if (X_RS1 (insn) != X_RD (insn) && strchr (opcode->args, 'r') != 0) /* Can't do simple format if source and dest are different. */ continue; @@ -181,7 +259,7 @@ print_insn_sparc (memaddr, info) (*info->fprintf_func) (stream, opcode->name); { - register const char *s; + register CONST char *s; if (opcode->args[0] != ',') (*info->fprintf_func) (stream, " "); @@ -194,6 +272,7 @@ print_insn_sparc (memaddr, info) switch (*s) { case 'a': (*info->fprintf_func) (stream, "a"); + is_annulled = 1; ++s; continue; #ifndef NO_V9 @@ -206,7 +285,7 @@ print_insn_sparc (memaddr, info) (*info->fprintf_func) (stream, "pt"); ++s; continue; -#endif /* NO_V9 */ +#endif /* NO_V9 */ default: break; @@ -232,62 +311,69 @@ print_insn_sparc (memaddr, info) #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n]) case '1': case 'r': - reg (insn.rs1); + reg (X_RS1 (insn)); break; case '2': - reg (insn.rs2); + reg (X_RS2 (insn)); break; case 'd': - reg (insn.rd); + reg (X_RD (insn)); break; #undef reg -#define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n]) +#define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n]) +#define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)]) case 'e': + freg (X_RS1 (insn)); + break; case 'v': /* double/even */ case 'V': /* quad/multiple of 4 */ - freg (insn.rs1); + fregx (X_RS1 (insn)); break; case 'f': + freg (X_RS2 (insn)); + break; case 'B': /* double/even */ case 'R': /* quad/multiple of 4 */ - freg (insn.rs2); + fregx (X_RS2 (insn)); break; case 'g': + freg (X_RD (insn)); + break; case 'H': /* double/even */ case 'J': /* quad/multiple of 4 */ - freg (insn.rd); + fregx (X_RD (insn)); break; #undef freg +#undef fregx #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n)) case 'b': - creg (insn.rs1); + creg (X_RS1 (insn)); break; case 'c': - creg (insn.rs2); + creg (X_RS2 (insn)); break; case 'D': - creg (insn.rd); + creg (X_RD (insn)); break; #undef creg case 'h': (*info->fprintf_func) (stream, "%%hi(%#x)", - (int) insn.imm22 << 10); + (0xFFFFFFFF + & ((int) X_IMM22 (insn) << 10))); break; case 'i': { - /* We cannot trust the compiler to sign-extend - when extracting the bitfield, hence the shifts. */ - int imm = ((int) insn.imm13 << 19) >> 19; + int imm = SEX (X_IMM13 (insn), 13); /* Check to see whether we have a 1+i, and take note of that fact. @@ -310,14 +396,12 @@ print_insn_sparc (memaddr, info) case 'I': /* 11 bit immediate. */ case 'j': /* 10 bit immediate. */ { - /* We cannot trust the compiler to sign-extend - when extracting the bitfield, hence the shifts. */ int imm; if (*s == 'I') - imm = ((int) insn.imm13 << 21) >> 21; + imm = SEX (X_IMM13 (insn), 11); else - imm = ((int) insn.imm13 << 22) >> 22; + imm = SEX (X_IMM13 (insn), 10); /* Check to see whether we have a 1+i, and take note of that fact. @@ -336,37 +420,29 @@ print_insn_sparc (memaddr, info) } break; - - - case 'k': - (*info->print_address_func) - ((bfd_vma) (memaddr - + (((int) insn.disp14 << 18) >> 18) * 4), - info); + info->target = memaddr + (SEX (X_DISP16 (insn), 16)) * 4; + (*info->print_address_func) (info->target, info); break; case 'G': - (*info->print_address_func) - ((bfd_vma) (memaddr - /* We use only 19 of the 21 bits. */ - + (((int) insn.disp21 << 13) >> 13) * 4), - info); + info->target = memaddr + (SEX (X_DISP22 (insn), 19)) * 4; + (*info->print_address_func) (info->target, info); break; case '6': case '7': case '8': case '9': - (*info->fprintf_func) (stream, "fcc%c", *s - '6' + '0'); + (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0'); break; case 'z': - (*info->fprintf_func) (stream, "icc"); + (*info->fprintf_func) (stream, "%%icc"); break; case 'Z': - (*info->fprintf_func) (stream, "xcc"); + (*info->fprintf_func) (stream, "%%xcc"); break; case 'E': @@ -376,40 +452,64 @@ print_insn_sparc (memaddr, info) case 's': (*info->fprintf_func) (stream, "%%fprs"); break; -#endif /* NO_V9 */ + + case 'o': + (*info->fprintf_func) (stream, "%%asi"); + break; + + case 'W': + (*info->fprintf_func) (stream, "%%tick"); + break; + + case 'P': + (*info->fprintf_func) (stream, "%%pc"); + break; + + case '?': + if (X_RS1 (insn) == 31) + (*info->fprintf_func) (stream, "%%ver"); + else if ((unsigned) X_RS1 (insn) < 16) + (*info->fprintf_func) (stream, "%%%s", + v9_priv_reg_names[X_RS1 (insn)]); + else + (*info->fprintf_func) (stream, "%%reserved"); + break; + + case '!': + if ((unsigned) X_RD (insn) < 15) + (*info->fprintf_func) (stream, "%%%s", + v9_priv_reg_names[X_RD (insn)]); + else + (*info->fprintf_func) (stream, "%%reserved"); + break; + break; +#endif /* NO_V9 */ case 'M': - (*info->fprintf_func) (stream, "%%asr%d", insn.rs1); + (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn)); break; case 'm': - (*info->fprintf_func) (stream, "%%asr%d", insn.rd); + (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn)); break; case 'L': - (*info->print_address_func) - ((bfd_vma) memaddr + insn.disp30 * 4, - info); + info->target = memaddr + X_DISP30 (insn) * 4; + (*info->print_address_func) (info->target, info); + break; + + case 'n': + (*info->fprintf_func) + (stream, "%#x", (SEX (X_DISP22 (insn), 22))); break; case 'l': - if ((insn.code >> 22) == 0) - /* Special case for `unimp'. Don't try to turn - it's operand into a function offset. */ - (*info->fprintf_func) - (stream, "%#x", - (int) (((int) insn.disp22 << 10) >> 10)); - else - /* We cannot trust the compiler to sign-extend - when extracting the bitfield, hence the shifts. */ - (*info->print_address_func) - ((bfd_vma) (memaddr - + (((int) insn.disp22 << 10) >> 10) * 4), - info); + info->target = memaddr + (SEX (X_DISP22 (insn), 22)) * 4; + (*info->print_address_func) (info->target, info); break; case 'A': - (*info->fprintf_func) (stream, "(%d)", (int) insn.asi); + (*info->fprintf_func) (stream, "(%d)", X_ASI (insn)); break; case 'C': @@ -440,6 +540,12 @@ print_insn_sparc (memaddr, info) (*info->fprintf_func) (stream, "%%wim"); break; + case 'x': + (*info->fprintf_func) (stream, "%d", + ((X_LDST_I (insn) << 8) + + X_ASI (insn))); + break; + case 'y': (*info->fprintf_func) (stream, "%%y"); break; @@ -455,13 +561,13 @@ print_insn_sparc (memaddr, info) and its symbolic value. */ if (imm_added_to_rs1) { - union sparc_insn prev_insn; + unsigned long prev_insn; int errcode; errcode = (*info->read_memory_func) - (memaddr - 4, - (char *)&prev_insn, sizeof (prev_insn), info); + (memaddr - 4, buffer, sizeof (buffer), info); + prev_insn = bfd_getb32 (buffer); if (errcode == 0) { @@ -475,9 +581,11 @@ print_insn_sparc (memaddr, info) */ if (is_delayed_branch (prev_insn)) - errcode = (*info->read_memory_func) - (memaddr - 8, (char *)&prev_insn, sizeof (prev_insn), - info); + { + errcode = (*info->read_memory_func) + (memaddr - 8, buffer, sizeof (buffer), info); + prev_insn = bfd_getb32 (buffer); + } } /* If there was a problem reading memory, then assume @@ -485,26 +593,40 @@ print_insn_sparc (memaddr, info) if (errcode == 0) { /* Is it sethi to the same register? */ - if ((prev_insn.code & 0xc1c00000) == 0x01000000 - && prev_insn.rd == insn.rs1) + if ((prev_insn & 0xc1c00000) == 0x01000000 + && X_RD (prev_insn) == X_RS1 (insn)) { (*info->fprintf_func) (stream, "\t! "); - /* We cannot trust the compiler to sign-extend - when extracting the bitfield, hence the shifts. */ - (*info->print_address_func) - (((int) prev_insn.imm22 << 10) - | (insn.imm13 << 19) >> 19, - info); + info->target = + (0xFFFFFFFF & (int) X_IMM22 (prev_insn) << 10) + | SEX (X_IMM13 (insn), 13); + (*info->print_address_func) (info->target, info); + info->insn_type = dis_dref; + info->data_size = 4; /* FIXME!!! */ } } } - return sizeof (insn); + if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR)) + { + /* FIXME -- check is_annulled flag */ + if (opcode->flags & F_UNBR) + info->insn_type = dis_branch; + if (opcode->flags & F_CONDBR) + info->insn_type = dis_condbranch; + if (opcode->flags & F_JSR) + info->insn_type = dis_jsr; + if (opcode->flags & F_DELAYED) + info->branch_delay_insns = 1; + } + + return sizeof (buffer); } } - (*info->fprintf_func) (stream, "%#8x", insn.code); - return sizeof (insn); + info->insn_type = dis_noninsn; /* Mark as non-valid instruction */ + (*info->fprintf_func) (stream, "%#8x", insn); + return sizeof (buffer); } /* Compare opcodes A and B. */ @@ -537,6 +659,20 @@ 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) @@ -614,3 +750,78 @@ compare_opcodes (a, b) written, so just say there are equal. */ return 0; } + +/* Build a hash table from the opcode table. */ + +static void +build_hash_table (table, hash_table, num_opcodes) + struct sparc_opcode *table; + struct opcode_hash **hash_table; + int num_opcodes; +{ + int i; + int hash_count[HASH_SIZE]; + + /* Start at the end of the table and work backwards so that each + chain is sorted. */ + /* ??? Do we really need to sort them now? */ + + memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0])); + memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0])); + for (i = num_opcodes - 1; i >= 0; --i) + { + int hash = HASH_INSN (sparc_opcodes[i].match); + struct opcode_hash *h = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash)); + h->next = hash_table[hash]; + h->opcode = &sparc_opcodes[i]; + hash_table[hash] = h; + ++hash_count[hash]; + } + +#if 0 /* for debugging */ + { + int min_count = num_opcodes, max_count = 0; + int total; + + for (i = 0; i < HASH_SIZE; ++i) + { + if (hash_count[i] < min_count) + min_count = hash_count[i]; + if (hash_count[i] > max_count) + max_count = hash_count[i]; + total += hash_count[i]; + } + + printf ("Opcode hash table stats: min %d, max %d, ave %f\n", + min_count, max_count, (double) total / HASH_SIZE); + } +#endif +} + +int +print_insn_sparc (memaddr, info) + bfd_vma memaddr; + disassemble_info *info; +{ + /* It's not clear that we'll ever switch cpus in a running program. + It could theoretically happen in gdb so we handle it. + ??? There is currently a memory leak but it's not worth the trouble. */ + if (sparc64_p) + opcodes_initialized = 0; + sparc64_p = 0; + return print_insn (memaddr, info); +} + +int +print_insn_sparc64 (memaddr, info) + bfd_vma memaddr; + disassemble_info *info; +{ + /* It's not clear that we'll ever switch cpus in a running program. + It could theoretically happen in gdb so we handle it. + ??? There is currently a memory leak but it's not worth the trouble. */ + if (!sparc64_p) + opcodes_initialized = 0; + sparc64_p = 1; + return print_insn (memaddr, info); +} diff --git a/opcodes/sparc-opc.c b/opcodes/sparc-opc.c index 315c19deebf..c217384af4f 100644 --- a/opcodes/sparc-opc.c +++ b/opcodes/sparc-opc.c @@ -1,7 +1,5 @@ -/* to sanitize this file, grep -v v9 < sparc.h > clean-sparc.h */ - /* Table of opcodes for the sparc. - Copyright 1989, 1991, 1992 Free Software Foundation, Inc. + Copyright 1989, 1991, 1992, 1995 Free Software Foundation, Inc. This file is part of the BFD library. @@ -17,7 +15,8 @@ for more details. You should have received a copy of the GNU General Public License along with this software; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* FIXME-someday: perhaps the ,a's and such should be embedded in the instruction's name rather than the args. This would make gas faster, pinsn @@ -30,7 +29,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ansidecl.h" #include "opcode/sparc.h" -CONST char *architecture_pname[] = { +const char *architecture_pname[] = { "v6", "v7", "v8", @@ -128,20 +127,18 @@ struct sparc_opcode sparc_opcodes[] = { { "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RS1_G0|RD(~0),"[i],F", 0, v6 }, { "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|SIMM13(~0)|RD(~0),"[1],F", 0, v6 }, /* ld [rs1+0],d */ -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0), "[1+2],D", F_ALIAS, v6 }, -{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0, "[1],D", F_ALIAS, v6 }, /* ld [rs1+%g0],d */ -{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[1+i],D", F_ALIAS, v6 }, -{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[i+1],D", F_ALIAS, v6 }, -{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0, "[i],D", F_ALIAS, v6 }, -{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0), "[1],D", F_ALIAS, v6 }, /* ld [rs1+0],d */ -{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0), "[1+2],C", 0, v6 }, -{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0)|RS2_G0, "[1],C", 0, v6 }, /* ld [rs1+%g0],d */ -{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1), "[1+i],C", 0, v6 }, -{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1), "[i+1],C", 0, v6 }, -{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|RS1_G0, "[i],C", 0, v6 }, -{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|SIMM13(~0), "[1],C", 0, v6 }, /* ld [rs1+0],d */ +{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0), "[1+2],D", F_NOTV9, v6 }, +{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0, "[1],D", F_NOTV9, v6 }, /* ld [rs1+%g0],d */ +{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[1+i],D", F_NOTV9, v6 }, +{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[i+1],D", F_NOTV9, v6 }, +{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0, "[i],D", F_NOTV9, v6 }, +{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0), "[1],D", F_NOTV9, v6 }, /* ld [rs1+0],d */ +{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0), "[1+2],C", F_NOTV9, v6 }, +{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0)|RS2_G0, "[1],C", F_NOTV9, v6 }, /* ld [rs1+%g0],d */ +{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1), "[1+i],C", F_NOTV9, v6 }, +{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1), "[i+1],C", F_NOTV9, v6 }, +{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|RS1_G0, "[i],C", F_NOTV9, v6 }, +{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|SIMM13(~0), "[1],C", F_NOTV9, v6 }, /* ld [rs1+0],d */ /* The v9 LDUW is the same as the old 'ld' opcode, it is not the same as the 'ld' pseudo-op in v9. */ @@ -164,14 +161,13 @@ struct sparc_opcode sparc_opcodes[] = { { "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1), "[i+1],H", 0, v6 }, { "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|RS1_G0, "[i],H", 0, v6 }, { "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|SIMM13(~0), "[1],H", 0, v6 }, /* ldd [rs1+0],d */ -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "ldd", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI(~0), "[1+2],D", F_ALIAS, v6 }, -{ "ldd", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI_RS2(~0), "[1],D", F_ALIAS, v6 }, /* ldd [rs1+%g0],d */ -{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[1+i],D", F_ALIAS, v6 }, -{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[i+1],D", F_ALIAS, v6 }, -{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|RS1_G0, "[i],D", F_ALIAS, v6 }, -{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|SIMM13(~0), "[1],D", F_ALIAS, v6 }, /* ldd [rs1+0],d */ + +{ "ldd", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI(~0), "[1+2],D", F_NOTV9, v6 }, +{ "ldd", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI_RS2(~0), "[1],D", F_NOTV9, v6 }, /* ldd [rs1+%g0],d */ +{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[1+i],D", F_NOTV9, v6 }, +{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[i+1],D", F_NOTV9, v6 }, +{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|RS1_G0, "[i],D", F_NOTV9, v6 }, +{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|SIMM13(~0), "[1],D", F_NOTV9, v6 }, /* ldd [rs1+0],d */ { "ldq", F3(3, 0x22, 0), F3(~3, ~0x22, ~0)|ASI(~0), "[1+2],J", 0, v9 }, { "ldq", F3(3, 0x22, 0), F3(~3, ~0x22, ~0)|ASI_RS2(~0), "[1],J", 0, v9 }, /* ldd [rs1+%g0],d */ @@ -338,20 +334,19 @@ struct sparc_opcode sparc_opcodes[] = { { "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1), "g,[i+1]", 0, v6 }, { "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1)|RS1_G0, "g,[i]", 0, v6 }, { "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1)|SIMM13(~0), "g,[1]", 0, v6 }, /* st d,[rs1+0] */ -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "st", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI(~0), "D,[1+2]", F_ALIAS, v6 }, -{ "st", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI_RS2(~0), "D,[1]", F_ALIAS, v6 }, /* st d,[rs1+%g0] */ -{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "D,[1+i]", F_ALIAS, v6 }, -{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "D,[i+1]", F_ALIAS, v6 }, -{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|RS1_G0, "D,[i]", F_ALIAS, v6 }, -{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|SIMM13(~0), "D,[1]", F_ALIAS, v6 }, /* st d,[rs1+0] */ -{ "st", F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI(~0), "C,[1+2]", 0, v6 }, -{ "st", F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI_RS2(~0), "C,[1]", 0, v6 }, /* st d,[rs1+%g0] */ -{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1), "C,[1+i]", 0, v6 }, -{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1), "C,[i+1]", 0, v6 }, -{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|RS1_G0, "C,[i]", 0, v6 }, -{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|SIMM13(~0), "C,[1]", 0, v6 }, /* st d,[rs1+0] */ + +{ "st", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI(~0), "D,[1+2]", F_NOTV9, v6 }, +{ "st", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI_RS2(~0), "D,[1]", F_NOTV9, v6 }, /* st d,[rs1+%g0] */ +{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "D,[1+i]", F_NOTV9, v6 }, +{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "D,[i+1]", F_NOTV9, v6 }, +{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|RS1_G0, "D,[i]", F_NOTV9, v6 }, +{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|SIMM13(~0), "D,[1]", F_NOTV9, v6 }, /* st d,[rs1+0] */ +{ "st", F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI(~0), "C,[1+2]", F_NOTV9, v6 }, +{ "st", F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI_RS2(~0), "C,[1]", F_NOTV9, v6 }, /* st d,[rs1+%g0] */ +{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1), "C,[1+i]", F_NOTV9, v6 }, +{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1), "C,[i+1]", F_NOTV9, v6 }, +{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|RS1_G0, "C,[i]", F_NOTV9, v6 }, +{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|SIMM13(~0), "C,[1]", F_NOTV9, v6 }, /* st d,[rs1+0] */ { "st", F3(3, 0x25, 0), F3(~3, ~0x25, ~0)|RD_G0|ASI(~0), "F,[1+2]", 0, v6 }, { "st", F3(3, 0x25, 0), F3(~3, ~0x25, ~0)|RD_G0|ASI_RS2(~0), "F,[1]", 0, v6 }, /* st d,[rs1+%g0] */ @@ -408,36 +403,32 @@ struct sparc_opcode sparc_opcodes[] = { { "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[i+1]", 0, v6 }, { "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|RS1_G0, "d,[i]", 0, v6 }, { "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* std d,[rs1+0] */ -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "std", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI(~0), "q,[1+2]", F_ALIAS, v6 }, -{ "std", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI_RS2(~0), "q,[1]", F_ALIAS, v6 }, /* std d,[rs1+%g0] */ -{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "q,[1+i]", F_ALIAS, v6 }, -{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "q,[i+1]", F_ALIAS, v6 }, -{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|RS1_G0, "q,[i]", F_ALIAS, v6 }, -{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|SIMM13(~0), "q,[1]", F_ALIAS, v6 }, /* std d,[rs1+0] */ + +{ "std", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI(~0), "q,[1+2]", F_NOTV9, v6 }, +{ "std", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI_RS2(~0), "q,[1]", F_NOTV9, v6 }, /* std d,[rs1+%g0] */ +{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "q,[1+i]", F_NOTV9, v6 }, +{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "q,[i+1]", F_NOTV9, v6 }, +{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|RS1_G0, "q,[i]", F_NOTV9, v6 }, +{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|SIMM13(~0), "q,[1]", F_NOTV9, v6 }, /* std d,[rs1+0] */ { "std", F3(3, 0x27, 0), F3(~3, ~0x27, ~0)|ASI(~0), "H,[1+2]", 0, v6 }, { "std", F3(3, 0x27, 0), F3(~3, ~0x27, ~0)|ASI_RS2(~0), "H,[1]", 0, v6 }, /* std d,[rs1+%g0] */ { "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1), "H,[1+i]", 0, v6 }, { "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1), "H,[i+1]", 0, v6 }, { "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1)|RS1_G0, "H,[i]", 0, v6 }, { "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1)|SIMM13(~0), "H,[1]", 0, v6 }, /* std d,[rs1+0] */ -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "std", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI(~0), "Q,[1+2]", F_ALIAS, v6 }, -{ "std", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI_RS2(~0), "Q,[1]", F_ALIAS, v6 }, /* std d,[rs1+%g0] */ -{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "Q,[1+i]", F_ALIAS, v6 }, -{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "Q,[i+1]", F_ALIAS, v6 }, -{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|RS1_G0, "Q,[i]", F_ALIAS, v6 }, -{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|SIMM13(~0), "Q,[1]", F_ALIAS, v6 }, /* std d,[rs1+0] */ -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "std", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI(~0), "D,[1+2]", F_ALIAS, v6 }, -{ "std", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI_RS2(~0), "D,[1]", F_ALIAS, v6 }, /* std d,[rs1+%g0] */ -{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "D,[1+i]", F_ALIAS, v6 }, -{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "D,[i+1]", F_ALIAS, v6 }, -{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0, "D,[i]", F_ALIAS, v6 }, -{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0), "D,[1]", F_ALIAS, v6 }, /* std d,[rs1+0] */ + +{ "std", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI(~0), "Q,[1+2]", F_NOTV9, v6 }, +{ "std", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI_RS2(~0), "Q,[1]", F_NOTV9, v6 }, /* std d,[rs1+%g0] */ +{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "Q,[1+i]", F_NOTV9, v6 }, +{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "Q,[i+1]", F_NOTV9, v6 }, +{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|RS1_G0, "Q,[i]", F_NOTV9, v6 }, +{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|SIMM13(~0), "Q,[1]", F_NOTV9, v6 }, /* std d,[rs1+0] */ +{ "std", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI(~0), "D,[1+2]", F_NOTV9, v6 }, +{ "std", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI_RS2(~0), "D,[1]", F_NOTV9, v6 }, /* std d,[rs1+%g0] */ +{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "D,[1+i]", F_NOTV9, v6 }, +{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "D,[i+1]", F_NOTV9, v6 }, +{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0, "D,[i]", F_NOTV9, v6 }, +{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0), "D,[1]", F_NOTV9, v6 }, /* std d,[rs1+0] */ { "stda", F3(3, 0x17, 0), F3(~3, ~0x17, ~0), "d,[1+2]A", 0, v6 }, { "stda", F3(3, 0x17, 0), F3(~3, ~0x17, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* stda d,[rs1+%g0] */ @@ -542,11 +533,11 @@ struct sparc_opcode sparc_opcodes[] = { { "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1), "1+i,d", F_JSR|F_DELAYED, v6 }, { "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1), "i+1,d", F_JSR|F_DELAYED, v6 }, -{ "done", F3(2, 0x3e, 1)|RD(0), F3(~2, ~0x3e, ~1)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 }, -{ "retry", F3(2, 0x3e, 1)|RD(1), F3(~2, ~0x3e, ~1)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 }, -{ "saved", F3(2, 0x31, 1)|RD(0), F3(~2, ~0x31, ~1)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 }, -{ "restored", F3(2, 0x31, 1)|RD(1), F3(~2, ~0x31, ~1)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 }, -{ "sir", F3(2, 0x30, 0)|RD(0xf), F3(~2, ~0x30, ~0)|RD(~0xf)|RS1_G0|SIMM13(~0), "", 0, v9 }, +{ "done", F3(2, 0x3e, 0)|RD(0), F3(~2, ~0x3e, ~0)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 }, +{ "retry", F3(2, 0x3e, 0)|RD(1), F3(~2, ~0x3e, ~0)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 }, +{ "saved", F3(2, 0x31, 0)|RD(0), F3(~2, ~0x31, ~0)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 }, +{ "restored", F3(2, 0x31, 0)|RD(1), F3(~2, ~0x31, ~0)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 }, +{ "sir", F3(2, 0x30, 1)|RD(0xf), F3(~2, ~0x30, ~1)|RD(~0xf)|RS1_G0, "i", 0, v9 }, { "flush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI(~0), "1+2", 0, v8 }, { "flush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI_RS2(~0), "1", 0, v8 }, /* flush rs1+%g0 */ @@ -572,7 +563,7 @@ struct sparc_opcode sparc_opcodes[] = { { "flushw", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RD_G0|RS1_G0|ASI_RS2(~0), "", 0, v9 }, -{ "membar", F3(2, 0x28, 1)|RS1(0xf), F3(~2, ~0x28, ~1)|RD_G0|RS1(~0xf)|ASI(~0), "K", 0, v9 }, +{ "membar", F3(2, 0x28, 1)|RS1(0xf), F3(~2, ~0x28, ~1)|RD_G0|RS1(~0xf)|SIMM13(~0), "K", 0, v9 }, { "stbar", F3(2, 0x28, 0)|RS1(0xf), F3(~2, ~0x28, ~0)|RD_G0|RS1(~0xf)|SIMM13(~0), "", 0, v8 }, { "prefetch", F3(3, 0x2d, 0), F3(~3, ~0x2d, ~0), "[1+2],*", 0, v9 }, @@ -589,6 +580,7 @@ struct sparc_opcode sparc_opcodes[] = { { "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* prefetcha [rs1+0],d */ /* The 1<<12 is a long story. It is necessary. For more info, please contact rich@cygnus.com */ + /* FIXME: 'i' is wrong, need new letter for 5 bit unsigned constants. */ { "sll", F3(2, 0x25, 0), F3(~2, ~0x25, ~0)|(1<<12)|ASI(~0), "1,2,d", 0, v6 }, { "sll", F3(2, 0x25, 1), F3(~2, ~0x25, ~1)|(1<<12), "1,i,d", 0, v6 }, { "sra", F3(2, 0x27, 0), F3(~2, ~0x27, ~0)|(1<<12)|ASI(~0), "1,2,d", 0, v6 }, @@ -596,12 +588,13 @@ struct sparc_opcode sparc_opcodes[] = { { "srl", F3(2, 0x26, 0), F3(~2, ~0x26, ~0)|(1<<12)|ASI(~0), "1,2,d", 0, v6 }, { "srl", F3(2, 0x26, 1), F3(~2, ~0x26, ~1)|(1<<12), "1,i,d", 0, v6 }, + /* FIXME: 'j' is wrong, need new letter for 6 bit unsigned constants. */ { "sllx", F3(2, 0x25, 0)|(1<<12), F3(~2, ~0x25, ~0)|(ASI(~0)^(1<<12)), "1,2,d", 0, v9 }, -{ "sllx", F3(2, 0x25, 1)|(1<<12), F3(~2, ~0x25, ~1), "1,i,d", 0, v9 }, +{ "sllx", F3(2, 0x25, 1)|(1<<12), F3(~2, ~0x25, ~1)|(0x3f<<6), "1,j,d", 0, v9 }, { "srax", F3(2, 0x27, 0)|(1<<12), F3(~2, ~0x27, ~0)|(ASI(~0)^(1<<12)), "1,2,d", 0, v9 }, -{ "srax", F3(2, 0x27, 1)|(1<<12), F3(~2, ~0x27, ~1), "1,i,d", 0, v9 }, +{ "srax", F3(2, 0x27, 1)|(1<<12), F3(~2, ~0x27, ~1)|(0x3f<<6), "1,j,d", 0, v9 }, { "srlx", F3(2, 0x26, 0)|(1<<12), F3(~2, ~0x26, ~0)|(ASI(~0)^(1<<12)), "1,2,d", 0, v9 }, -{ "srlx", F3(2, 0x26, 1)|(1<<12), F3(~2, ~0x26, ~1), "1,i,d", 0, v9 }, +{ "srlx", F3(2, 0x26, 1)|(1<<12), F3(~2, ~0x26, ~1)|(0x3f<<6), "1,j,d", 0, v9 }, { "mulscc", F3(2, 0x24, 0), F3(~2, ~0x24, ~0)|ASI(~0), "1,2,d", 0, v6 }, { "mulscc", F3(2, 0x24, 1), F3(~2, ~0x24, ~1), "1,i,d", 0, v6 }, @@ -654,18 +647,16 @@ struct sparc_opcode sparc_opcodes[] = { { "tst", F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|RD_G0|RS1_G0|ASI(~0), "2", 0, v6 }, /* orcc %g0, rs2, %g0 */ { "tst", F3(2, 0x12, 1), F3(~2, ~0x12, ~1)|RD_G0|SIMM13(~0), "1", 0, v6 }, /* orcc rs1, 0, %g0 */ -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ { "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI(~0), "1,2,m", 0, v8 }, /* wr r,r,%asrX */ { "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI(~0), "1,2,y", 0, v6 }, /* wr r,r,%y */ { "wr", F3(2, 0x30, 1), F3(~2, ~0x30, ~1), "1,i,m", 0, v8 }, /* wr r,i,%asrX */ { "wr", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0, "1,i,y", 0, v6 }, /* wr r,i,%y */ -{ "wr", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI(~0), "1,2,p", F_ALIAS, v6 }, /* wr r,r,%psr */ -{ "wr", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0, "1,i,p", F_ALIAS, v6 }, /* wr r,i,%psr */ -{ "wr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI(~0), "1,2,w", F_ALIAS, v6 }, /* wr r,r,%wim */ -{ "wr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0, "1,i,w", F_ALIAS, v6 }, /* wr r,i,%wim */ -{ "wr", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI(~0), "1,2,t", F_ALIAS, v6 }, /* wr r,r,%tbr */ -{ "wr", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0, "1,i,t", F_ALIAS, v6 }, /* wr r,i,%tbr */ +{ "wr", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI(~0), "1,2,p", F_NOTV9, v6 }, /* wr r,r,%psr */ +{ "wr", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0, "1,i,p", F_NOTV9, v6 }, /* wr r,i,%psr */ +{ "wr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI(~0), "1,2,w", F_NOTV9, v6 }, /* wr r,r,%wim */ +{ "wr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0, "1,i,w", F_NOTV9, v6 }, /* wr r,i,%wim */ +{ "wr", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI(~0), "1,2,t", F_NOTV9, v6 }, /* wr r,r,%tbr */ +{ "wr", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0, "1,i,t", F_NOTV9, v6 }, /* wr r,i,%tbr */ { "wr", F3(2, 0x30, 0)|RD(0), F3(~2, ~0x30, ~0)|RD(~0)|ASI(~0), "1,2,y", 0, v9 }, /* wr r,r,%y */ { "wr", F3(2, 0x30, 1)|RD(0), F3(~2, ~0x30, ~1)|RD(~0), "1,i,y", 0, v9 }, /* wr r,i,%y */ @@ -676,19 +667,17 @@ struct sparc_opcode sparc_opcodes[] = { { "wr", F3(2, 0x30, 0)|RD(6), F3(~2, ~0x30, ~0)|RD(~6)|ASI(~0), "1,2,s", 0, v9 }, /* wr r,i,%fprs */ { "wr", F3(2, 0x30, 1)|RD(6), F3(~2, ~0x30, ~1)|RD(~6), "1,i,s", 0, v9 }, /* wr r,i,%fprs */ -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ { "rd", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|SIMM13(~0), "M,d", 0, v8 }, /* rd %asrX,r */ { "rd", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|RS1_G0|SIMM13(~0), "y,d", 0, v6 }, /* rd %y,r */ -{ "rd", F3(2, 0x29, 0), F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0), "p,d", F_ALIAS, v6 }, /* rd %psr,r */ -{ "rd", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0), "w,d", F_ALIAS, v6 }, /* rd %wim,r */ -{ "rd", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0), "t,d", F_ALIAS, v6 }, /* rd %tbr,r */ +{ "rd", F3(2, 0x29, 0), F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0), "p,d", F_NOTV9, v6 }, /* rd %psr,r */ +{ "rd", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0), "w,d", F_NOTV9, v6 }, /* rd %wim,r */ +{ "rd", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0), "t,d", F_NOTV9, v6 }, /* rd %tbr,r */ { "rd", F3(2, 0x28, 0)|RS1(2), F3(~2, ~0x28, ~0)|RS1(~2)|SIMM13(~0), "E,d", 0, v9 }, /* rd %ccr,r */ { "rd", F3(2, 0x28, 0)|RS1(3), F3(~2, ~0x28, ~0)|RS1(~3)|SIMM13(~0), "o,d", 0, v9 }, /* rd %asi,r */ { "rd", F3(2, 0x28, 0)|RS1(4), F3(~2, ~0x28, ~0)|RS1(~4)|SIMM13(~0), "W,d", 0, v9 }, /* rd %tick,r */ { "rd", F3(2, 0x28, 0)|RS1(5), F3(~2, ~0x28, ~0)|RS1(~5)|SIMM13(~0), "P,d", 0, v9 }, /* rd %pc,r */ -{ "rd", F3(2, 0x2b, 0)|RS1(6), F3(~2, ~0x2b, ~0)|RS1(~6)|SIMM13(~0), "s,d", 0, v9 }, /* rd %fprs,r */ +{ "rd", F3(2, 0x28, 0)|RS1(6), F3(~2, ~0x28, ~0)|RS1(~6)|SIMM13(~0), "s,d", 0, v9 }, /* rd %fprs,r */ { "rdpr", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|SIMM13(~0), "?,d", 0, v9 }, /* rdpr %priv,r */ { "wrpr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0), "1,2,!", 0, v9 }, /* wrpr r1,r2,%priv */ @@ -714,9 +703,9 @@ struct sparc_opcode sparc_opcodes[] = { 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, v6 }, /* rd %psr,r */ -{ "mov", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0), "w,d", F_ALIAS, v6 }, /* rd %wim,r */ -{ "mov", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0), "t,d", F_ALIAS, v6 }, /* rd %tbr,r */ +{ "mov", F3(2, 0x29, 0), F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0), "p,d", F_ALIAS|F_NOTV9, v6 }, /* rd %psr,r */ +{ "mov", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0), "w,d", F_ALIAS|F_NOTV9, v6 }, /* rd %wim,r */ +{ "mov", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0), "t,d", F_ALIAS|F_NOTV9, v6 }, /* rd %tbr,r */ { "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI_RS2(~0), "1,y", F_ALIAS, v6 }, /* wr rs1,%g0,%y */ { "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1), "i,y", F_ALIAS, v6 }, @@ -763,17 +752,13 @@ struct sparc_opcode sparc_opcodes[] = { { "subcc", F3(2, 0x14, 0), F3(~2, ~0x14, ~0)|ASI(~0), "1,2,d", 0, v6 }, { "subcc", F3(2, 0x14, 1), F3(~2, ~0x14, ~1), "1,i,d", 0, v6 }, -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "subx", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", F_ALIAS, v6 }, -{ "subx", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", F_ALIAS, v6 }, +{ "subx", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", F_NOTV9, v6 }, +{ "subx", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", F_NOTV9, v6 }, { "subc", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v9 }, { "subc", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v9 }, -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "subxcc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", F_ALIAS, v6 }, -{ "subxcc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", F_ALIAS, v6 }, +{ "subxcc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", F_NOTV9, v6 }, +{ "subxcc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", F_NOTV9, v6 }, { "subccc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v9 }, { "subccc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v9 }, @@ -806,19 +791,17 @@ struct sparc_opcode sparc_opcodes[] = { { "addcc", F3(2, 0x10, 0), F3(~2, ~0x10, ~0)|ASI(~0), "1,2,d", 0, v6 }, { "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "1,i,d", 0, v6 }, { "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "i,1,d", 0, v6 }, -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "addx", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", F_ALIAS, v6 }, -{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", F_ALIAS, v6 }, -{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", F_ALIAS, v6 }, + +{ "addx", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", F_NOTV9, v6 }, +{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", F_NOTV9, v6 }, +{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", F_NOTV9, v6 }, { "addc", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v9 }, { "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v9 }, { "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v9 }, -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "addxcc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", F_ALIAS, v6 }, -{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", F_ALIAS, v6 }, -{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", F_ALIAS, v6 }, + +{ "addxcc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", F_NOTV9, v6 }, +{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", F_NOTV9, v6 }, +{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", F_NOTV9, v6 }, { "addccc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v9 }, { "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v9 }, { "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v9 }, @@ -1297,9 +1280,7 @@ condfc("fbule", "cb013", 0xe, 0), { "tsubcctv", F3(2, 0x23, 0), F3(~2, ~0x23, ~0)|ASI(~0), "1,2,d", 0, v6 }, { "tsubcctv", F3(2, 0x23, 1), F3(~2, ~0x23, ~1), "1,i,d", 0, v6 }, -/* FIXME This is marked F_ALIAS, so that it won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "unimp", F2(0x0, 0x0), 0xffc00000, "n", F_ALIAS, v6 }, +{ "unimp", F2(0x0, 0x0), 0xffc00000, "n", F_NOTV9, v6 }, { "illtrap", F2(0, 0), F2(~0, ~0)|RD_G0, "n", 0, v9 }, /* This *is* a commutative instruction. */ @@ -1412,16 +1393,59 @@ condfc("fbule", "cb013", 0xe, 0), { "fcmpes", CMPFCC(2)|F3F(2, 0x35, 0x055), CMPFCC(~2)|F3F(~2, ~0x35, ~0x055), "8,e,f", 0, v9 }, { "fcmpes", CMPFCC(3)|F3F(2, 0x35, 0x055), CMPFCC(~3)|F3F(~2, ~0x35, ~0x055), "9,e,f", 0, v9 }, -/* FIXME These are marked F_ALIAS, so that they won't conflict with new v9 - insns when v9 is present. Otherwise, the F_ALIAS flag is ignored. */ -{ "cpop1", F3(2, 0x36, 0), F3(~2, ~0x36, ~1), "[1+2],d", F_ALIAS, v6 }, -{ "cpop2", F3(2, 0x37, 0), F3(~2, ~0x37, ~1), "[1+2],d", F_ALIAS, v6 }, +/* These Extended FPop (FIFO) instructions are new in the Fujitsu + MB86934, replacing the CPop instructions from v6 and later + processors. */ + +#define EFPOP1_2(name, op, args) { name, F3F(2, 0x36, op), F3F(~2, ~0x36, ~op)|RS1_G0, args, 0, sparclite } +#define EFPOP1_3(name, op, args) { name, F3F(2, 0x36, op), F3F(~2, ~0x36, ~op), args, 0, sparclite } +#define EFPOP2_2(name, op, args) { name, F3F(2, 0x37, op), F3F(~2, ~0x37, ~op)|RD_G0, args, 0, sparclite } + +EFPOP1_2 ("efitod", 0x0c8, "f,H"), +EFPOP1_2 ("efitos", 0x0c4, "f,g"), +EFPOP1_2 ("efdtoi", 0x0d2, "B,g"), +EFPOP1_2 ("efstoi", 0x0d1, "f,g"), +EFPOP1_2 ("efstod", 0x0c9, "f,H"), +EFPOP1_2 ("efdtos", 0x0c6, "B,g"), +EFPOP1_2 ("efmovs", 0x001, "f,g"), +EFPOP1_2 ("efnegs", 0x005, "f,g"), +EFPOP1_2 ("efabss", 0x009, "f,g"), +EFPOP1_2 ("efsqrtd", 0x02a, "B,H"), +EFPOP1_2 ("efsqrts", 0x029, "f,g"), +EFPOP1_3 ("efaddd", 0x042, "v,B,H"), +EFPOP1_3 ("efadds", 0x041, "e,f,g"), +EFPOP1_3 ("efsubd", 0x046, "v,B,H"), +EFPOP1_3 ("efsubs", 0x045, "e,f,g"), +EFPOP1_3 ("efdivd", 0x04e, "v,B,H"), +EFPOP1_3 ("efdivs", 0x04d, "e,f,g"), +EFPOP1_3 ("efmuld", 0x04a, "v,B,H"), +EFPOP1_3 ("efmuls", 0x049, "e,f,g"), +EFPOP1_3 ("efsmuld", 0x069, "e,f,H"), +EFPOP2_2 ("efcmpd", 0x052, "v,B"), +EFPOP2_2 ("efcmped", 0x056, "v,B"), +EFPOP2_2 ("efcmps", 0x051, "e,f"), +EFPOP2_2 ("efcmpes", 0x055, "e,f"), + +#undef EFPOP1_2 +#undef EFPOP1_3 +#undef EFPOP2_2 + +/* These are marked F_ALIAS, so that they won't conflict with sparclite insns + present. Otherwise, the F_ALIAS flag is ignored. */ +{ "cpop1", F3(2, 0x36, 0), F3(~2, ~0x36, ~1), "[1+2],d", F_ALIAS|F_NOTV9, v6 }, +{ "cpop2", F3(2, 0x37, 0), F3(~2, ~0x37, ~1), "[1+2],d", F_ALIAS|F_NOTV9, v6 }, + +#define IMPDEP(name, code) \ +{ name, F3(2, code, 0), F3(~2, ~code, ~0)|ASI(~0), "1,2,d", 0, v9 }, \ +{ name, F3(2, code, 1), F3(~2, ~code, ~1), "1,i,d", 0, v9 }, \ +{ name, F3(2, code, 0), F3(~2, ~code, ~0), "x,1,2,d", 0, v9 }, \ +{ name, F3(2, code, 0), F3(~2, ~code, ~0), "x,e,f,g", 0, v9 } + +IMPDEP ("impdep1", 0x36), +IMPDEP ("impdep2", 0x37), + +#undef IMPDEP -{ "impdep1", F3(2, 0x36, 0), F3(~2, ~0x36, ~0)|ASI(~0), "1,2,d", 0, v9 }, -{ "impdep1", F3(2, 0x36, 1), F3(~2, ~0x36, ~1), "1,i,d", 0, v9 }, -{ "impdep2", F3(2, 0x37, 0), F3(~2, ~0x37, ~0)|ASI(~0), "1,2,d", 0, v9 }, -{ "impdep2", F3(2, 0x37, 1), F3(~2, ~0x37, ~1), "1,i,d", 0, v9 }, - { "casa", F3(3, 0x3c, 0), F3(~3, ~0x3c, ~0), "[1]A,2,d", 0, v9 }, { "casa", F3(3, 0x3c, 1), F3(~3, ~0x3c, ~1), "[1]o,2,d", 0, v9 }, { "casxa", F3(3, 0x3e, 0), F3(~3, ~0x3e, ~0), "[1]A,2,d", 0, v9 }, @@ -1429,4 +1453,4 @@ condfc("fbule", "cb013", 0xe, 0), }; -CONST int bfd_sparc_num_opcodes = ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0])); +const int bfd_sparc_num_opcodes = ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0]));