Sparc disassembler from David Miller.
Heavily munged by me to: - reduce table size significantly. - follow various opcode tables in the Sparc Architecture Manual (V9) more closely. - recognise V8 priviliged instructions. - fit the DDB interface. - fix many typos. Todo: - get a number of FP ops right (unimportant until V9 is here). - opcode aliases (`mov',`cmp',`set') for simple instructions. - better template matching; current method is sloppy and is prone to spurious matches.
This commit is contained in:
parent
03dc23c91c
commit
c4a9be4024
@ -1,7 +1,8 @@
|
||||
/* $NetBSD: db_disasm.c,v 1.2 1994/11/20 20:54:11 deraadt Exp $ */
|
||||
/* $NetBSD: db_disasm.c,v 1.3 1995/01/05 21:33:31 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Theo de Raadt
|
||||
* Copyright (c) 1994 David S. Miller, davem@nadzieja.rutgers.edu
|
||||
* Copyright (c) 1995 Paul Kranenburg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -14,7 +15,7 @@
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Theo de Raadt.
|
||||
* This product includes software developed by David Miller.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
@ -33,11 +34,971 @@
|
||||
#include <sys/param.h>
|
||||
#include <machine/db_machdep.h>
|
||||
#include <ddb/db_sym.h>
|
||||
#include <machine/instr.h>
|
||||
|
||||
/*
|
||||
* All Sparc instructions are 32-bits, with the one exception being
|
||||
* the set instruction which is actually a macro which expands into
|
||||
* two instructions...
|
||||
*
|
||||
* There are 5 different fields that can be used to identify which
|
||||
* operation is encoded into a particular 32-bit insn. There are 3
|
||||
* formats for instuctions, which one being used is determined by
|
||||
* bits 30-31 of the insn. Here are the bit fields and their names:
|
||||
*
|
||||
* 1100 0000 0000 0000 0000 0000 0000 0000 op field, determines format
|
||||
* 0000 0001 1100 0000 0000 0000 0000 0000 op2 field, format 2 only
|
||||
* 0000 0001 1111 1000 0000 0000 0000 0000 op3 field, format 3 only
|
||||
* 0000 0000 0000 0000 0010 0000 0000 0000 f3i bit, format 3 only
|
||||
*/
|
||||
|
||||
#define OP(x) ((x & 0x3) << 30)
|
||||
#define OP2(x) ((x & 0x7) << 22)
|
||||
#define OP3(x) ((x & 0x3f) << 19)
|
||||
#define OPF(x) ((x & 0x1ff) << 5)
|
||||
#define F3I(x) ((x & 0x1) << 13)
|
||||
|
||||
/* various other fields */
|
||||
|
||||
#define A(x) ((x & 0x1) << 29)
|
||||
#define P(x) ((x & 0x1) << 19)
|
||||
#define X(x) ((x & 0x1) << 12)
|
||||
#define FCN(x) ((x & 0x1f) << 25)
|
||||
#define OPF(x) ((x & 0x1ff) << 5)
|
||||
#define RCOND2(x) ((x & 0x7) << 25)
|
||||
#define RCOND34(x) ((x & 0x7) << 10)
|
||||
#define COND(x) ((x & 0xf) << 25)
|
||||
#define SW_TRAP(x) (x & 0x7f)
|
||||
#define SHCNT32(x) (x & 0x1f)
|
||||
#define SHCNT64(x) (x & 0x3f)
|
||||
#define IMM11(x) (x & 0x7ff)
|
||||
#define IMM22(x) (x & 0x3fffff)
|
||||
#define DISP19(x) (x & 0x7ffff)
|
||||
#define DISP22(x) (x & 0x3fffff)
|
||||
#define DISP30(x) (x & 0x3fffffff)
|
||||
|
||||
/* Register Operand Fields */
|
||||
#define RS1(x) ((x & 0x1f) << 14)
|
||||
#define RS2(x) (x & 0x1f)
|
||||
#define RD(x) ((x & 0x1f) << 25)
|
||||
|
||||
/* FORMAT macros used in sparc_i table to decode each opcode */
|
||||
#define FORMAT1(a) (OP(a))
|
||||
#define FORMAT2(a,b) (OP(a) | OP2(b))
|
||||
#define FORMAT3(a,b,c) (OP(a) | OP3(b) | F3I(c))
|
||||
#define FORMAT3F(a,b,c) (OP(a) | OP3(b) | OPF(c))
|
||||
|
||||
/* Helper macros to construct OP3 & OPF */
|
||||
#define OP3_X(x,y) ((((x) & 3) << 4) | ((y) & 0xf))
|
||||
#define OPF_X(x,y) ((((x) & 0x1f) << 4) | ((y) & 0xf))
|
||||
|
||||
/* COND condition codes field... */
|
||||
#define COND2(x) ((x & 0xf) << 14)
|
||||
|
||||
struct sparc_insn {
|
||||
unsigned long int match;
|
||||
char* name;
|
||||
char* format;
|
||||
};
|
||||
|
||||
char* regs[] = {
|
||||
"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"
|
||||
};
|
||||
|
||||
char* priv_regs[] = {
|
||||
"tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
|
||||
"pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
|
||||
"wstate", "fq",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", ""
|
||||
};
|
||||
|
||||
char* state_regs[] = {
|
||||
"y", "", "ccr", "asi", "tick", "pc", "fprs", "asr",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"illegal", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", ""
|
||||
};
|
||||
|
||||
char* ccodes[] = {
|
||||
"fcc0", "fcc1", "fcc2", "fcc3", "icc", "", "xcc", ""
|
||||
};
|
||||
|
||||
char* prefetch[] = {
|
||||
"n_reads", "one_read", "n_writes", "one_write", "page"
|
||||
};
|
||||
|
||||
|
||||
/* The sparc instruction table has a format field which tells what
|
||||
the operand structure for this instruction is. Here are the codes:
|
||||
|
||||
Modifiers (nust be first):
|
||||
a -- opcode has annul bit
|
||||
p -- opcode has branch prediction bit
|
||||
|
||||
Codes:
|
||||
1 -- source register operand stored in rs1
|
||||
2 -- source register operand stored in rs2
|
||||
d -- destination register operand stored in rd
|
||||
3 -- floating source register in rs1
|
||||
4 -- floating source register in rs2
|
||||
e -- floating destination register in rd
|
||||
i -- 13-bit immediate value stored in simm13
|
||||
j -- 11-bit immediate value stored in simm11
|
||||
l -- displacement using d16lo and d16hi
|
||||
m -- 22-bit fcc displacement value
|
||||
n -- 30-bit displacement used in call insns
|
||||
o -- %fcc number specified in cc1 and cc0 fields
|
||||
p -- address computed by the contents of rs1+rs2
|
||||
q -- address computed by the contents of rs1+simm13
|
||||
r -- prefetch
|
||||
s -- %asi is implicit in the insn, rs1 value not used
|
||||
t -- immediate 8-bit asi value
|
||||
u -- 19-bit fcc displacement value
|
||||
5 -- hard register, %fsr lower-half
|
||||
6 -- hard register, %fsr all
|
||||
7 -- [reg_addr rs1+rs2] imm_asi
|
||||
8 -- [reg_addr rs1+simm13] %asi
|
||||
9 -- logical or of the cmask and mmask fields (membar insn)
|
||||
0 -- icc or xcc condition codes register
|
||||
r -- prefection function stored in fcn field
|
||||
A -- privileged register encoded in rs1
|
||||
B -- state register encoded in rs1
|
||||
C -- %hi(value) where value is stored in imm22 field
|
||||
D -- 32-bit shift count in shcnt32
|
||||
E -- 64-bit shift count in shcnt64
|
||||
F -- software trap number stored in sw_trap
|
||||
G -- privileged register encoded in rd
|
||||
H -- state register encoded in rd
|
||||
|
||||
V8 only:
|
||||
Y -- write y register
|
||||
P -- write psr register
|
||||
T -- write tbr register
|
||||
W -- write wim register
|
||||
*/
|
||||
|
||||
|
||||
struct sparc_insn sparc_i[] = {
|
||||
|
||||
/*
|
||||
* Format 1: Call
|
||||
*/
|
||||
{(FORMAT1(1)), "call", "n"},
|
||||
|
||||
/*
|
||||
* Format 0: Sethi & Branches
|
||||
*/
|
||||
/* Illegal Instruction Trap */
|
||||
{(FORMAT2(0, 0)), "illtrap", "m"},
|
||||
|
||||
/* Note: if imm22 is zero then this is actually a "nop" grrr... */
|
||||
{(FORMAT2(0, 0x4)), "sethi", "Cd"},
|
||||
|
||||
/* Branch on Integer Condition Codes "Bicc" */
|
||||
{(FORMAT2(0, 2) | COND(8)), "ba", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(0)), "bn", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(9)), "bne", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(1)), "be", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(10)), "bg", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(2)), "ble", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(11)), "bge", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(3)), "bl", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(12)), "bgu", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(4)), "bleu", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(13)), "bcc", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(5)), "bcs", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(14)), "bpos", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(6)), "bneg", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(15)), "bvc", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(7)), "bvs", "a,m"},
|
||||
|
||||
/* Branch on Integer Condition Codes with Prediction "BPcc" */
|
||||
{(FORMAT2(0, 1) | COND(8)), "ba", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(0)), "bn", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(9)), "bne", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(1)), "be", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(10)), "bg", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(2)), "ble", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(11)), "bge", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(3)), "bl", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(12)), "bgu", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(4)), "bleu", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(13)), "bcc", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(5)), "bcs", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(14)), "bpos", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(6)), "bneg", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(15)), "bvc", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(7)), "bvs", "ap,u"},
|
||||
|
||||
/* Branch on Integer Register with Prediction "BPr" */
|
||||
{(FORMAT2(0, 3) | RCOND2(1)), "brz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | A(1) | P(1) | RCOND2(2)), "brlex", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | RCOND2(3)), "brlz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | RCOND2(5)), "brnz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | RCOND2(6)), "brgz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | RCOND2(7)), "brgez", "ap,1l"},
|
||||
|
||||
/* Branch on Floating-Point Condition Codes with Prediction "FBPfcc" */
|
||||
{(FORMAT2(0, 5) | COND(8)), "fba", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(0)), "fbn", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(7)), "fbu", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(6)), "fbg", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(5)), "fbug", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(4)), "fbl", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(3)), "fbul", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(2)), "fblg", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(1)), "fbne", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(9)), "fbe", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(10)), "fbue", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(11)), "fbge", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(12)), "fbuge", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(13)), "fble", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(14)), "fbule", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(15)), "fbo", "ap,m"},
|
||||
|
||||
/* Branch on Floating-Point Condition Codes "FBfcc" */
|
||||
{(FORMAT2(0, 6) | COND(8)), "fba", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(0)), "fbn", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(7)), "fbu", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(6)), "fbg", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(5)), "fbug", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(4)), "fbl", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(3)), "fbul", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(2)), "fblg", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(1)), "fbne", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(9)), "fbe", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(10)), "fbue", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(11)), "fbge", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(12)), "fbuge", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(13)), "fble", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(14)), "fbule", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(15)), "fbo", "a,m"},
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Format 3/2: Arithmetic & misc (table 32, appendix E)
|
||||
*/
|
||||
{FORMAT3(2, OP3_X(0,0), 0), "add", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,0), 1), "add", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,0), 0), "addcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,0), 1), "addcc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,0), 0), "taddcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,0), 1), "taddcc", "1id"},
|
||||
#ifdef V9
|
||||
{(FORMAT3(2, 0x30, 1) | RD(0xf)), "sir", "i"},
|
||||
{FORMAT3(2, OP3_X(3,0), 0), "wr", "12H"},
|
||||
{FORMAT3(2, OP3_X(3,0), 1), "wr", "1iH"},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(3,0), 0), "wr", "12Y"}, /* wr 1, 2, %y */
|
||||
{FORMAT3(2, OP3_X(3,0), 1), "wr", "1iY"}, /* wr 1, i, %y */
|
||||
#endif
|
||||
|
||||
{FORMAT3(2, OP3_X(0,1), 0), "and", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,1), 1), "and", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,1), 0), "andcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,1), 1), "andcc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,1), 0), "tsubcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,1), 1), "tsubcc", "1id"},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(3,1), 0), "saved", ""},
|
||||
{FORMAT3(2, OP3_X(3,1), 0)|FCN(1), "restored", ""},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(3,1), 0), "wr", "12P"}, /* wr 1, 2, %psr */
|
||||
{FORMAT3(2, OP3_X(3,1), 1), "wr", "1iP"}, /* wr 1, i, %psr */
|
||||
#endif
|
||||
|
||||
{FORMAT3(2, OP3_X(0,2), 0), "or", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,2), 1), "or", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,2), 0), "orcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,2), 1), "orcc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,2), 0), "taddcctv", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,2), 1), "taddcctv", "1id"},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(3,2), 0), "wrpr", "12G"},
|
||||
{FORMAT3(2, OP3_X(3,2), 1), "wrpr", "1iG"},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(3,2), 0), "wr", "12W"}, /* wr 1, 2, %wim */
|
||||
{FORMAT3(2, OP3_X(3,2), 1), "wr", "1iW"}, /* wr 1, i, %wim */
|
||||
#endif
|
||||
|
||||
{FORMAT3(2, OP3_X(0,3), 0), "xor", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,3), 1), "xor", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,3), 0), "xorcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,3), 1), "xorcc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,3), 0), "tsubcctv", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,3), 1), "tsubcctv", "1id"},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(3,3), 0), "UNDEFINED", ""},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(3,3), 0), "wr", "12T"}, /* wr 1, 2, %tbr */
|
||||
{FORMAT3(2, OP3_X(3,3), 1), "wr", "1iT"}, /* wr 1, i, %tbr */
|
||||
#endif
|
||||
|
||||
{FORMAT3(2, OP3_X(0,4), 0), "sub", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,4), 1), "sub", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,4), 0), "subcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,4), 1), "subcc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,4), 0), "mulscc", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,4), 1), "mulscc", "1id"},
|
||||
{FORMAT3(2, OP3_X(3,4), 1), "FPop1", ""}, /* see below */
|
||||
|
||||
{FORMAT3(2, OP3_X(0,5), 0), "andn", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,5), 1), "andn", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,5), 0), "andncc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,5), 1), "andncc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,5), 0), "sll", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,5), 1), "sll", "1Dd"},
|
||||
{FORMAT3(2, OP3_X(2,5)|X(1), 0), "sllx", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,5)|X(1), 1), "sllx", "1Ed"},
|
||||
{FORMAT3(2, OP3_X(3,5), 1), "FPop2", ""}, /* see below */
|
||||
|
||||
{FORMAT3(2, OP3_X(0,6), 0), "orn", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,6), 1), "orn", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,6), 0), "orncc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,6), 1), "orncc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,6), 0), "srl", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,6), 1), "srl", "1Dd"},
|
||||
{FORMAT3(2, OP3_X(2,6)|X(1), 0), "srlx", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,6)|X(1), 1), "srlx", "1Ed"},
|
||||
{FORMAT3(2, OP3_X(3,6), 1), "impdep1", ""},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,7), 0), "xorn", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,7), 1), "xorn", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,7), 0), "xorncc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,7), 1), "xorncc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,7), 0), "sra", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,7), 1), "sra", "1Dd"},
|
||||
{FORMAT3(2, OP3_X(2,7)|X(1), 0), "srax", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,7)|X(1), 1), "srax", "1Ed"},
|
||||
{FORMAT3(2, OP3_X(3,7), 1), "impdep2", ""},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,8), 0), "addc", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,8), 1), "addc", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,8), 0), "addccc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,8), 1), "addccc", "1id"},
|
||||
#ifdef V9
|
||||
{(FORMAT3(2, 0x28, 1) | RS1(15)), "membar", "9"},
|
||||
{(FORMAT3(2, 0x28, 0) | RS1(15)), "stbar", ""},
|
||||
{FORMAT3(2, OP3_X(2,8), 0), "rd", "Bd"},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(2,8), 0), "rd", "Yd"},
|
||||
#endif
|
||||
|
||||
{FORMAT3(2, OP3_X(3,8), 0), "jmpl", "pd"},
|
||||
{FORMAT3(2, OP3_X(3,8), 1), "jmpl", "qd"},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,9), 0), "mulx", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,9), 1), "mulx", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,9), 0), "UNDEFINED", ""},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(2,9), 0), "UNDEFINED", ""},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(2,9), 0), "rd", "Pd"},
|
||||
#endif
|
||||
{FORMAT3(2, OP3_X(3,9), 0), "return", "p"},
|
||||
{FORMAT3(2, OP3_X(3,9), 1), "return", "q"},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,10), 0), "umul", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,10), 1), "umul", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,10), 0), "umulcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,10), 1), "umulcc", "1id"},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(2,10), 0), "rdpr", "Ad"},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(2,10), 0), "rd", "Wd"},
|
||||
#endif
|
||||
/*
|
||||
* OP3 = (3,10): TCC: Trap on Integer Condition Codes
|
||||
*/
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x8)), "ta", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x8)), "ta", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x0)), "tn", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x0)), "tn", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x9)), "tne", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x9)), "tne", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x1)), "te", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x1)), "te", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xa)), "tg", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xa)), "tg", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x2)), "tle", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x2)), "tle", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xb)), "tge", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xb)), "tge", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x3)), "tl", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x3)), "tl", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xc)), "tgu", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xc)), "tgu", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x4)), "tleu", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x4)), "tleu", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xd)), "tcc", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xd)), "tcc", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x5)), "tcs", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x5)), "tcs", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xe)), "tpos", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xe)), "tpos", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x6)), "tneg", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x6)), "tneg", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xf)), "tvc", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xf)), "tvc", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x7)), "tvs", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x7)), "tvs", "0F"},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,11), 0), "smul", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,11), 1), "smul", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,11), 0), "smulcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,11), 1), "smulcc", "1id"},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(2,11), 0), "flushw", ""},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(2,11), 0), "rd", "Td"},
|
||||
#endif
|
||||
{FORMAT3(2, OP3_X(3,11), 0), "flush", "p"},
|
||||
{FORMAT3(2, OP3_X(3,11), 1), "flush", "q"},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,12), 0), "subc", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,12), 1), "subc", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,12), 0), "subccc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,12), 1), "subccc", "1id"},
|
||||
/*
|
||||
* OP3 = (2,12): MOVcc, Move Integer Register on Condition
|
||||
*/
|
||||
/* For Integer Condition Codes */
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(8)), "mova", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(0)), "movn", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(9)), "movne", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(1)), "move", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(10)), "movg", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(2)), "movle", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(11)), "movge", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(3)), "movl", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(12)), "movgu", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(4)), "movleu", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(13)), "movcc", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(5)), "movcs", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(14)), "movpos", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(6)), "movneg", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(15)), "movvc", "0jd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(7)), "movvs", "0jd"},
|
||||
|
||||
/* For Floating-Point Condition Codes */
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(8)), "mova", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(0)), "movn", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(7)), "movu", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(6)), "movg", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(5)), "movug", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(4)), "movl", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(3)), "movul", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(2)), "movlg", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(1)), "movne", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(9)), "move", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(10)), "movue", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(11)), "movge", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(12)), "movuge", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(13)), "movle", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(14)), "movule", "ojd"},
|
||||
{(FORMAT3(2, OP3_X(2,12), 1) | COND(15)), "movo", "ojd"},
|
||||
|
||||
{FORMAT3(2, OP3_X(3,12), 0), "save", "12d"},
|
||||
{FORMAT3(2, OP3_X(3,12), 1), "save", "1id"},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,13), 0), "udivx", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,13), 1), "udivx", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,13), 0), "UNDEFINED", ""},
|
||||
{FORMAT3(2, OP3_X(2,13), 0), "sdivx", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,13), 1), "sdivx", "1id"},
|
||||
{FORMAT3(2, OP3_X(3,13), 0), "restore", "12d"},
|
||||
{FORMAT3(2, OP3_X(3,13), 1), "restore", "1id"},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,14), 0), "udiv", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,14), 1), "udiv", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,14), 0), "udivcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,14), 1), "udivcc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,14), 0), "popc", "2d"},
|
||||
{FORMAT3(2, OP3_X(2,14), 1), "popc", "id"},
|
||||
|
||||
{FORMAT3(2, OP3_X(3,14), 0), "done", ""},
|
||||
{FORMAT3(2, OP3_X(3,14)|FCN(1), 1), "retry", ""},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,15), 0), "sdiv", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,15), 1), "sdiv", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,15), 0), "sdivcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,15), 1), "sdivcc", "1id"},
|
||||
/*
|
||||
* OP3 = (2,15): MOVr:
|
||||
* Move Integer Register on Register Condition
|
||||
*/
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(1)), "movrz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(1)), "movrz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(2)), "movrlez", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(2)), "movrlez", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(3)), "movrlz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(3)), "movrlz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(5)), "movrnz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(5)), "movrnz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(6)), "movrgz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(6)), "movrgz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(7)), "movrgez", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(7)), "movrgez", "12d"},
|
||||
|
||||
{FORMAT3(2, OP3_X(3,15), 0), "UNDEFINED", ""},
|
||||
|
||||
|
||||
/*
|
||||
* Format 3/3: Load and store (appendix E, table 33)
|
||||
*/
|
||||
|
||||
/* Loads */
|
||||
{(FORMAT3(3, OP3_X(0,0), 0)), "ld", "pd"}, /* officially: lduw */
|
||||
{(FORMAT3(3, OP3_X(0,0), 1)), "ld", "qd"},
|
||||
{(FORMAT3(3, OP3_X(1,0), 0)), "lda", "7d"}, /* officially: lduwa */
|
||||
{(FORMAT3(3, OP3_X(1,0), 1)), "lda", "8d"},
|
||||
{(FORMAT3(3, OP3_X(2,0), 0)), "ldf", "pe"},
|
||||
{(FORMAT3(3, OP3_X(2,0), 1)), "ldf", "qe"},
|
||||
{(FORMAT3(3, OP3_X(3,0), 0)), "ldfa", "7e"},
|
||||
{(FORMAT3(3, OP3_X(3,0), 1)), "ldfa", "8e"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,1), 0)), "ldub", "pd"},
|
||||
{(FORMAT3(3, OP3_X(0,1), 1)), "ldub", "qd"},
|
||||
{(FORMAT3(3, OP3_X(1,1), 0)), "lduba", "7d"},
|
||||
{(FORMAT3(3, OP3_X(1,1), 1)), "lduba", "8d"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 0) | RD(0)), "ld", "p5"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 1) | RD(0)), "ld", "q5"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 0) | RD(1)), "ldx", "p6"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 1) | RD(1)), "ldx", "q6"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,2), 0)), "lduh", "pd"},
|
||||
{(FORMAT3(3, OP3_X(0,2), 1)), "lduh", "qd"},
|
||||
{(FORMAT3(3, OP3_X(1,2), 0)), "lduha", "7d"},
|
||||
{(FORMAT3(3, OP3_X(1,2), 1)), "lduha", "8d"},
|
||||
{(FORMAT3(3, OP3_X(2,2), 0)), "ldq", "pe"},
|
||||
{(FORMAT3(3, OP3_X(2,2), 1)), "ldq", "qe"},
|
||||
{(FORMAT3(3, OP3_X(3,2), 0)), "ldqa", "7e"},
|
||||
{(FORMAT3(3, OP3_X(3,2), 1)), "ldqa", "8e"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,3), 0)), "ldd", "pd"},
|
||||
{(FORMAT3(3, OP3_X(0,3), 1)), "ldd", "qd"},
|
||||
{(FORMAT3(3, OP3_X(1,3), 0)), "ldda", "7d"},
|
||||
{(FORMAT3(3, OP3_X(1,3), 1)), "ldda", "8d"},
|
||||
{(FORMAT3(3, OP3_X(2,3), 0)), "ldd", "pe"},
|
||||
{(FORMAT3(3, OP3_X(2,3), 1)), "ldd", "qe"},
|
||||
{(FORMAT3(3, OP3_X(3,3), 0)), "ldda", "7e"},
|
||||
{(FORMAT3(3, OP3_X(3,3), 1)), "ldda", "8e"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,4), 0)), "st", "dp"}, /* officially: stw */
|
||||
{(FORMAT3(3, OP3_X(0,4), 1)), "st", "dq"},
|
||||
{(FORMAT3(3, OP3_X(1,4), 0)), "sta", "d7"}, /* officially: stwa */
|
||||
{(FORMAT3(3, OP3_X(1,4), 1)), "sta", "d8"},
|
||||
{(FORMAT3(3, OP3_X(2,4), 0)), "st", "ep"},
|
||||
{(FORMAT3(3, OP3_X(2,4), 1)), "st", "eq"},
|
||||
{(FORMAT3(3, OP3_X(3,4), 0)), "sta", "e7"},
|
||||
{(FORMAT3(3, OP3_X(3,4), 1)), "sta", "e8"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,5), 0)), "stb", "dp"},
|
||||
{(FORMAT3(3, OP3_X(0,5), 1)), "stb", "dq"},
|
||||
{(FORMAT3(3, OP3_X(1,5), 0)), "stba", "d7"},
|
||||
{(FORMAT3(3, OP3_X(1,5), 1)), "stba", "d8"},
|
||||
{(FORMAT3(3, OP3_X(2,5), 0)), "st", "5p"},
|
||||
{(FORMAT3(3, OP3_X(2,5), 1)), "st", "5q"},
|
||||
{(FORMAT3(3, OP3_X(2,5), 0)|RD(1)), "stx", "6p"},
|
||||
{(FORMAT3(3, OP3_X(2,5), 1)|RD(1)), "stx", "6q"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,6), 0)), "sth", "dp"},
|
||||
{(FORMAT3(3, OP3_X(0,6), 1)), "sth", "dq"},
|
||||
{(FORMAT3(3, OP3_X(1,6), 0)), "stha", "d7"},
|
||||
{(FORMAT3(3, OP3_X(1,6), 1)), "stha", "d8"},
|
||||
{(FORMAT3(3, OP3_X(2,6), 0)), "stq", "ep"},
|
||||
{(FORMAT3(3, OP3_X(2,6), 1)), "stq", "eq"},
|
||||
{(FORMAT3(3, OP3_X(3,6), 0)), "stqa", "e7"},
|
||||
{(FORMAT3(3, OP3_X(3,6), 1)), "stqa", "e8"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,7), 0)), "std", "dp"},
|
||||
{(FORMAT3(3, OP3_X(0,7), 1)), "std", "dq"},
|
||||
{(FORMAT3(3, OP3_X(1,7), 0)), "stda", "d7"},
|
||||
{(FORMAT3(3, OP3_X(1,7), 1)), "stda", "d8"},
|
||||
{(FORMAT3(3, OP3_X(2,7), 0)), "std", "ep"},
|
||||
{(FORMAT3(3, OP3_X(2,7), 1)), "std", "eq"},
|
||||
{(FORMAT3(3, OP3_X(3,7), 0)), "stda", "e7"},
|
||||
{(FORMAT3(3, OP3_X(3,7), 1)), "stda", "e8"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,8), 0)), "ldsw", "pd"},
|
||||
{(FORMAT3(3, OP3_X(0,8), 1)), "ldsw", "qd"},
|
||||
{(FORMAT3(3, OP3_X(1,8), 0)), "ldswa", "7d"},
|
||||
{(FORMAT3(3, OP3_X(1,8), 1)), "ldswa", "8d"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,9), 0)), "ldsb", "pd"},
|
||||
{(FORMAT3(3, OP3_X(0,9), 1)), "ldsb", "qd"},
|
||||
{(FORMAT3(3, OP3_X(1,9), 0)), "ldsba", "7d"},
|
||||
{(FORMAT3(3, OP3_X(1,9), 1)), "ldsba", "8d"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,10), 0)), "ldsh", "pd"},
|
||||
{(FORMAT3(3, OP3_X(0,10), 1)), "ldsh", "qd"},
|
||||
{(FORMAT3(3, OP3_X(1,10), 0)), "ldsha", "7d"},
|
||||
{(FORMAT3(3, OP3_X(1,10), 1)), "ldsha", "8d"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,11), 0)), "ldx", "pd"},
|
||||
{(FORMAT3(3, OP3_X(0,11), 1)), "ldx", "qd"},
|
||||
{(FORMAT3(3, OP3_X(1,11), 0)), "ldxa", "7d"},
|
||||
{(FORMAT3(3, OP3_X(1,11), 1)), "ldxa", "8d"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(3,12), 1)), "casa", "s2d"},
|
||||
{(FORMAT3(3, OP3_X(3,12), 0)), "casa", "t2d"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,13), 0)), "ldstub", "7d"},
|
||||
{(FORMAT3(3, OP3_X(0,13), 1)), "ldstub", "8d"},
|
||||
{(FORMAT3(3, OP3_X(1,13), 0)), "ldstuba", "pd"},
|
||||
{(FORMAT3(3, OP3_X(1,13), 1)), "ldstuba", "qd"},
|
||||
{(FORMAT3(3, OP3_X(2,13), 0)), "prefetch", "pr"},
|
||||
{(FORMAT3(3, OP3_X(2,13), 1)), "prefetch", "qr"},
|
||||
{(FORMAT3(3, OP3_X(3,13), 0)), "prefetcha", "7r"},
|
||||
{(FORMAT3(3, OP3_X(3,13), 1)), "prefetcha", "8r"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,14), 0)), "stx", "dp"},
|
||||
{(FORMAT3(3, OP3_X(0,14), 1)), "stx", "dq"},
|
||||
{(FORMAT3(3, OP3_X(1,14), 0)), "stwa", "d7"},
|
||||
{(FORMAT3(3, OP3_X(1,14), 1)), "stwa", "d8"},
|
||||
{(FORMAT3(3, OP3_X(3,14), 0)), "casxa", "t2d"},
|
||||
{(FORMAT3(3, OP3_X(3,14), 1)), "casxa", "s2d"},
|
||||
|
||||
/* Swap Register */
|
||||
{(FORMAT3(3, OP3_X(0,15), 0)), "swap", "pd"},
|
||||
{(FORMAT3(3, OP3_X(0,15), 1)), "swap", "qd"},
|
||||
{(FORMAT3(3, OP3_X(1,15), 0)), "swapa", "7d"},
|
||||
{(FORMAT3(3, OP3_X(1,15), 1)), "swapa", "8d"},
|
||||
|
||||
|
||||
/*
|
||||
* OP3 = (3,4): FPop1 (table 34)
|
||||
*/
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,1))), "fmovs", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,2))), "fmovd", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,3))), "fmovq", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,5))), "fnegs", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,6))), "fnegd", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,7))), "fnegq", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,9))), "fabss", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,10))), "fabsd", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,11))), "fabsq", "4e"},
|
||||
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(2,9))), "fsqrts", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(2,10))), "fsqrtd", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(2,11))), "fsqrtq", "4e"},
|
||||
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,1))), "fadds", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,2))), "faddd", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,3))), "faddq", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,5))), "fsubs", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,6))), "fsubd", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,7))), "fsubq", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,9))), "fmuls", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,10))), "fmuld", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,11))), "fmulq", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,13))), "fdivs", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,14))), "fdivd", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,15))), "fdivq", "34e"},
|
||||
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(6,9))), "fsmuld", "34e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(6,14))), "fdmulq", "34e"},
|
||||
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,1))), "fstox", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,2))), "fdtox", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,3))), "fqtox", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,4))), "fxtos", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,8))), "fxtod", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,12))), "fxtoq", "4e"},
|
||||
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,4))), "fitos", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,6))), "fdtos", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,7))), "fqtos", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,8))), "fitod", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,9))), "fstod", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,11))), "fqtod", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,12))), "fitoq", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,13))), "fstoq", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,14))), "fdtoq", "4e"},
|
||||
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(13,1))), "fstoi", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(13,2))), "fdtoi", "4e"},
|
||||
{(FORMAT3F(2, OP3_X(3,4), OPF_X(13,3))), "fqtoi", "4e"},
|
||||
|
||||
|
||||
#ifdef xxx
|
||||
/*
|
||||
* OP3 =(3,5): FPop2 (table 35)
|
||||
*/
|
||||
{(FORMAT3F(2, OP3_X(3,5), 81)), "fcmps", "o34"},
|
||||
{(FORMAT3F(2, OP3_X(3,5), 82)), "fcmpd", "o34"},
|
||||
{(FORMAT3F(2, OP3_X(3,5), 83)), "fcmpq", "o34"},
|
||||
{(FORMAT3F(2, OP3_X(3,5), 85)), "fcmpes", "o34"},
|
||||
{(FORMAT3F(2, OP3_X(3,5), 86)), "fcmped", "o34"},
|
||||
{(FORMAT3F(2, OP3_X(3,5), 87)), "fcmpeq", "o34"},
|
||||
|
||||
/* Move Floating-Point Register on Condition "FMOVcc" */
|
||||
/* FIXME should check for single, double, and quad movements */
|
||||
/* Integer Condition Codes */
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(8)), "fmova", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0)), "fmovn", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(9)), "fmovne", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(1)), "fmove", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(10)), "fmovg", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(2)), "fmovle", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(11)), "fmovge", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(3)), "fmovl", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(12)), "fmovgu", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(4)), "fmovleu", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(13)), "fmovcc", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(5)), "fmovcs", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(14)), "fmovpos", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(6)), "fmovneg", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(15)), "fmovvc", "04e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(7)), "fmovvs", "04e"},
|
||||
|
||||
/* Floating-Point Condition Codes */
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(8)), "fmova", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0)), "fmovn", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(7)), "fmovu", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(6)), "fmovg", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(5)), "fmovug", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(4)), "fmovk", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(3)), "fmovul", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(2)), "fmovlg", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(1)), "fmovne", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(9)), "fmove", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(10)), "fmovue", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(11)), "fmovge", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(12)), "fmovuge", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(13)), "fmovle", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(14)), "fmovule", "o4e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | COND2(15)), "fmovo", "o4e"},
|
||||
|
||||
/* Move F-P Register on Integer Register Condition "FMOVr" */
|
||||
/* FIXME: check for short, double, and quad's */
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(1)), "fmovre", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(2)), "fmovrlez", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(3)), "fmovrlz", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(5)), "fmovrne", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(6)), "fmovrgz", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(7)), "fmovrgez", "14e"},
|
||||
#endif
|
||||
|
||||
/* grrrr.... */
|
||||
{0, 0, 0}
|
||||
|
||||
};
|
||||
|
||||
vm_offset_t
|
||||
db_disasm(loc, altfmt)
|
||||
vm_offset_t loc;
|
||||
boolean_t altfmt;
|
||||
{
|
||||
struct sparc_insn* i_ptr = (struct sparc_insn *)&sparc_i;
|
||||
|
||||
unsigned long int insn, you_lose, bitmask;
|
||||
int matchp;
|
||||
char* f_ptr, *cp;
|
||||
|
||||
you_lose = 0;
|
||||
matchp = 0;
|
||||
insn = db_get_value(loc, 4, 0);
|
||||
|
||||
if (insn == 0x01000000) {
|
||||
db_printf("nop\n");
|
||||
return loc + 4;
|
||||
}
|
||||
|
||||
while (i_ptr->name) {
|
||||
/* calculate YOU_LOSE value */
|
||||
bitmask= (i_ptr->match);
|
||||
you_lose = (~bitmask);
|
||||
|
||||
if (((bitmask>>30) & 0x3) == 0x1) {
|
||||
/* Call */
|
||||
you_lose = ((~0x1)<<30);
|
||||
} else if (((bitmask>>30) & 0x3) == 0x0) {
|
||||
if (((bitmask>>22) & 0x7) == 0x4) {
|
||||
/* Sethi */
|
||||
you_lose &= (FORMAT2(0x3,0x7));
|
||||
} else {
|
||||
/* Branches */
|
||||
you_lose &= (FORMAT2(0x3,0x7)|COND(0xf));
|
||||
}
|
||||
} else if (((bitmask>>30) & 0x3) == 0x2 &&
|
||||
((bitmask>>19) & 0x3f) == 0x34) /* XXX */ {
|
||||
/* FPop1 */
|
||||
you_lose &= (FORMAT3(0x3,0x3f,0x1) | OPF(0x1ff));
|
||||
} else {
|
||||
you_lose &= (FORMAT3(0x3,0x3f,0x1));
|
||||
}
|
||||
|
||||
if (((bitmask & insn) == bitmask) && ((you_lose & insn) == 0)) {
|
||||
matchp = 1;
|
||||
break;
|
||||
}
|
||||
i_ptr++;
|
||||
};
|
||||
|
||||
if (!matchp) {
|
||||
db_printf("undefined\n");
|
||||
return loc + 4;
|
||||
}
|
||||
|
||||
db_printf("%s", i_ptr->name);
|
||||
|
||||
f_ptr = i_ptr->format;
|
||||
|
||||
for (cp = f_ptr; *cp; cp++) {
|
||||
if (*cp == ',') {
|
||||
for (;f_ptr < cp; f_ptr++)
|
||||
switch (*f_ptr) {
|
||||
case 'a':
|
||||
if (insn & A(1))
|
||||
db_printf(",a");
|
||||
break;
|
||||
case 'p':
|
||||
if (insn & P(1))
|
||||
db_printf(",pt");
|
||||
else
|
||||
db_printf(",pn");
|
||||
break;
|
||||
}
|
||||
f_ptr++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
db_printf(" \t");
|
||||
|
||||
while (*f_ptr) {
|
||||
switch (*f_ptr) {
|
||||
case '1':
|
||||
db_printf("%%%s", regs[((insn >> 14) & 0x1f)]);
|
||||
break;
|
||||
case '2':
|
||||
db_printf("%%%s", regs[(insn & 0x1f)]);
|
||||
break;
|
||||
case 'd':
|
||||
db_printf("%%%s", regs[((insn >> 25) & 0x1f)]);
|
||||
break;
|
||||
case '3':
|
||||
db_printf("%%f%d", ((insn >> 14) & 0x1f));
|
||||
break;
|
||||
case '4':
|
||||
db_printf("%%f%d", (insn & 0x1f));
|
||||
break;
|
||||
case 'e':
|
||||
db_printf("%%f%d", ((insn >> 25) & 0x1f));
|
||||
break;
|
||||
case 'i':
|
||||
db_printf("0x%lx", (insn & 0x1fff));
|
||||
break;
|
||||
case 'j':
|
||||
db_printf("0x%lx", (insn & 0x7ff));
|
||||
break;
|
||||
case 'l':
|
||||
db_printf("0x%lx", ((insn & 0x1fff) |
|
||||
((insn >> 20) & 0x3)));
|
||||
break;
|
||||
case 'm':
|
||||
db_printf("0x%lx", (loc + (4 * (insn & 0x3fffff))));
|
||||
break;
|
||||
case 'u':
|
||||
db_printf("0x%lx", (loc + (4 * (insn & 0x7ffff))));
|
||||
break;
|
||||
case 'n':
|
||||
db_printf("0x%lx", (insn & 0x3fffffff));
|
||||
break;
|
||||
case 's':
|
||||
db_printf("%%asi");
|
||||
break;
|
||||
case 't':
|
||||
db_printf("0x%-2.2lx", ((insn >> 5) & 0xff));
|
||||
break;
|
||||
case 'o':
|
||||
db_printf("%%fcc%d", ((insn >> 25) & 0x3));
|
||||
break;
|
||||
case 'p':
|
||||
case '7':
|
||||
db_printf("[%%%s + %%%s]",
|
||||
regs[((insn >> 14) & 0x1f)],
|
||||
regs[(insn & 0x1f)]);
|
||||
if (*f_ptr == '7')
|
||||
db_printf(" %d", ((insn >> 5) & 0xff));
|
||||
break;
|
||||
case 'q':
|
||||
case '8':
|
||||
db_printf("[%%%s + 0x%lx]",
|
||||
regs[((insn >> 14) & 0x1f)],
|
||||
(insn & 0x1fff));
|
||||
if (*f_ptr == '8')
|
||||
db_printf(" %%asi");
|
||||
break;
|
||||
case '5':
|
||||
db_printf("%%fsr");
|
||||
break;
|
||||
case '6':
|
||||
db_printf("%%fsr");
|
||||
break;
|
||||
case '9':
|
||||
db_printf("0x%xl",
|
||||
((insn & 0xf) | ((insn >> 4) & 0x7)));
|
||||
break;
|
||||
case '0':
|
||||
db_printf("%%%s", ccodes[((insn >> 11) & 0x7)]);
|
||||
break;
|
||||
case 'r':
|
||||
db_printf("#%s", prefetch[((insn >> 25) & 0x1f)]);
|
||||
break;
|
||||
case 'A':
|
||||
db_printf("%%%s", priv_regs[((insn >> 14) & 0x1f)]);
|
||||
break;
|
||||
case 'B':
|
||||
db_printf("%%%s", state_regs[((insn >> 14) & 0x1f)]);
|
||||
break;
|
||||
case 'C':
|
||||
db_printf("%%hi(0x%lx)", ((insn & 0x3fffff) << 10));
|
||||
break;
|
||||
case 'D':
|
||||
db_printf("0x%lx", (insn & 0x1f));
|
||||
break;
|
||||
case 'E':
|
||||
db_printf("0x%lx", (insn & 0x3f));
|
||||
break;
|
||||
case 'F':
|
||||
db_printf("0x%lx", (insn & 0x3f));
|
||||
break;
|
||||
case 'G':
|
||||
db_printf("%%%s", priv_regs[((insn >> 25) & 0x1f)]);
|
||||
break;
|
||||
case 'H':
|
||||
db_printf("%%%s", state_regs[((insn >> 25) & 0x1f)]);
|
||||
break;
|
||||
#ifndef V9
|
||||
case 'P':
|
||||
db_printf("%%psr");
|
||||
break;
|
||||
case 'T':
|
||||
db_printf("%%tbr");
|
||||
break;
|
||||
case 'W':
|
||||
db_printf("%%wim");
|
||||
break;
|
||||
case 'Y':
|
||||
db_printf("%%y");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
db_printf("(UNKNOWN)");
|
||||
break;
|
||||
}
|
||||
if (*(++f_ptr))
|
||||
db_printf(", ");
|
||||
};
|
||||
|
||||
db_printf("\n");
|
||||
|
||||
return (loc + 4);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user