2 * Author: Humberto Naves (hsnaves@gmail.com)
3 * Special thanks to Tyranid for the prxtool "disasm.C"
14 * %i - 16bit signed immediate
15 * %I - 16bit unsigned immediate (always printed in hex)
16 * %o - 16bit signed offset (rs base)
17 * %O - 16bit signed offset (PC relative)
18 * %j - 26bit absolute offset
23 * %2? - Cop2 register (? is (s, d))
24 * %p - General cop (i.e. numbered) register
25 * %n? - ins/ext size, ? (e, i)
31 * %x? - Vt (? is (s/scalar, p/pair, t/triple, q/quad, m/matrix pair, n/matrix triple, o/matrix quad)
34 * %X? - Vo (? is (s, q))
36 * %Z? - VFPU condition code/name (? is (c, n))
37 * %v? - VFPU immediate, ? (3, 5, 8, k, i, h, r, p? (? is (0, 1, 2, 3, 4, 5, 6, 7)))
38 * %c - code (for break/dbreak/syscall)
39 * %? - Indicates vmmul special exception
42 #define RT(op) ((op >> 16) & 0x1F)
43 #define RS(op) ((op >> 21) & 0x1F)
44 #define RD(op) ((op >> 11) & 0x1F)
45 #define FT(op) ((op >> 16) & 0x1F)
46 #define FS(op) ((op >> 11) & 0x1F)
47 #define FD(op) ((op >> 6) & 0x1F)
48 #define SA(op) ((op >> 6) & 0x1F)
49 #define IMM(op) ((signed short) (op & 0xFFFF))
50 #define IMMU(op) ((unsigned short) (op & 0xFFFF))
51 #define JUMP(op, pc) ((pc & 0xF0000000) | ((op & 0x3FFFFFF) << 2))
52 #define CODE(op) ((op >> 6) & 0xFFFFF)
53 #define SIZE(op) ((op >> 11) & 0x1F)
54 #define POS(op) ((op >> 6) & 0x1F)
55 #define VO(op) (((op & 3) << 5) | ((op >> 16) & 0x1F))
56 #define VCC(op) ((op >> 18) & 7)
57 #define VD(op) (op & 0x7F)
58 #define VS(op) ((op >> 8) & 0x7F)
59 #define VT(op) ((op >> 16) & 0x7F)
61 /* [hlide] new #defines */
62 #define VED(op) (op & 0xFF)
63 #define VES(op) ((op >> 8) & 0xFF)
64 #define VCN(op) (op & 0x0F)
65 #define VI3(op) ((op >> 16) & 0x07)
66 #define VI5(op) ((op >> 16) & 0x1F)
67 #define VI8(op) ((op >> 16) & 0xFF)
69 /* VFPU 16-bit floating-point format. */
70 #define VFPU_FLOAT16_EXP_MAX 0x1f
71 #define VFPU_SH_FLOAT16_SIGN 15
72 #define VFPU_MASK_FLOAT16_SIGN 0x1
73 #define VFPU_SH_FLOAT16_EXP 10
74 #define VFPU_MASK_FLOAT16_EXP 0x1f
75 #define VFPU_SH_FLOAT16_FRAC 0
76 #define VFPU_MASK_FLOAT16_FRAC 0x3ff
78 /* VFPU prefix instruction operands. The *_SH_* values really specify where
79 the bitfield begins, as VFPU prefix instructions have four operands
80 encoded within the immediate field. */
81 #define VFPU_SH_PFX_NEG 16
82 #define VFPU_MASK_PFX_NEG 0x1 /* Negation. */
83 #define VFPU_SH_PFX_CST 12
84 #define VFPU_MASK_PFX_CST 0x1 /* Constant. */
85 #define VFPU_SH_PFX_ABS_CSTHI 8
86 #define VFPU_MASK_PFX_ABS_CSTHI 0x1 /* Abs/Constant (bit 2). */
87 #define VFPU_SH_PFX_SWZ_CSTLO 0
88 #define VFPU_MASK_PFX_SWZ_CSTLO 0x3 /* Swizzle/Constant (bits 0-1). */
89 #define VFPU_SH_PFX_MASK 8
90 #define VFPU_MASK_PFX_MASK 0x1 /* Mask. */
91 #define VFPU_SH_PFX_SAT 0
92 #define VFPU_MASK_PFX_SAT 0x3 /* Saturation. */
94 /* Special handling of the vrot instructions. */
95 #define VFPU_MASK_OP_SIZE 0x8080 /* Masks the operand size (pair, triple, quad). */
96 #define VFPU_OP_SIZE_PAIR 0x80
97 #define VFPU_OP_SIZE_TRIPLE 0x8000
98 #define VFPU_OP_SIZE_QUAD 0x8080
99 /* Note that these are within the rotators field, and not the full opcode. */
100 #define VFPU_SH_ROT_HI 2
101 #define VFPU_MASK_ROT_HI 0x3
102 #define VFPU_SH_ROT_LO 0
103 #define VFPU_MASK_ROT_LO 0x3
104 #define VFPU_SH_ROT_NEG 4 /* Negation. */
105 #define VFPU_MASK_ROT_NEG 0x1
107 /* Alias (shorter version) */
108 #define _AL INSN_ALIAS
109 #define _RS INSN_READ_GPR_S
110 #define _RT INSN_READ_GPR_T
111 #define _RD INSN_READ_GPR_D
112 #define _Rs INSN_READ_FPR_S
113 #define _Rt INSN_READ_FPR_T
114 #define _RC INSN_READ_COND_CODE
115 #define _RH INSN_READ_HI
116 #define _RL INSN_READ_LO
117 #define _WD INSN_WRITE_GPR_D
118 #define _WT INSN_WRITE_GPR_T
119 #define _Wd INSN_WRITE_FPR_D
120 #define _Wt INSN_WRITE_FPR_T
121 #define _WC INSN_WRITE_COND_CODE
122 #define _WH INSN_WRITE_HI
123 #define _WL INSN_WRITE_LO
124 #define _JP INSN_JUMP
125 #define _BR INSN_BRANCH
126 #define _BL INSN_BRANCHLIKELY
127 #define _LK INSN_LINK
128 #define _LD INSN_LOAD
129 #define _ST INSN_STORE
131 #define _SP INSN_SPECIAL
132 #define _DB INSN_DEBUG
133 #define _C0 INSN_COP0
135 #define _C2 INSN_VFPU
137 #define COMMAND_INDEX 1
138 #define COMMAND_BSEARCH 2
139 #define COMMAND_TEST 3
140 #define COMMAND_END 4
142 struct disasm_command
{
149 struct bsearch_index
{
155 static const struct allegrex_instruction instructions
[] =
157 /* MIPS instructions */
158 { I_ADD
, "add", 0x00000020, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
159 { I_ADDI
, "addi", 0x20000000, 0xFC000000, "%t, %s, %i", _RS
|_WT
},
160 { I_ADDIU
, "li", 0x24000000, 0xFFE00000, "%t, %i", _AL
|_WT
},
161 { I_ADDIU
, "addiu", 0x24000000, 0xFC000000, "%t, %s, %i", _RS
|_WT
},
162 { I_ADDU
, "move", 0x00000021, 0xFC1F07FF, "%d, %s", _AL
|_RS
|_WD
},
163 { I_ADDU
, "addu", 0x00000021, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
164 { I_AND
, "and", 0x00000024, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
165 { I_ANDI
, "andi", 0x30000000, 0xFC000000, "%t, %s, %I", _RS
|_WT
},
166 { I_BEQ
, "b", 0x10000000, 0xFFFF0000, "%O", _AL
|_BR
},
167 { I_BEQ
, "beqz", 0x10000000, 0xFC1F0000, "%s, %O", _AL
|_RS
|_BR
},
168 { I_BEQ
, "beq", 0x10000000, 0xFC000000, "%s, %t, %O", _RS
|_RT
|_BR
},
169 { I_BEQL
, "beqzl", 0x50000000, 0xFC1F0000, "%s, %O", _AL
|_RS
|_BR
|_BL
},
170 { I_BEQL
, "beql", 0x50000000, 0xFC000000, "%s, %t, %O", _RS
|_RT
|_BR
|_BL
},
171 { I_BGEZ
, "b", 0x04010000, 0xFFFF0000, "%O", _AL
|_BR
},
172 { I_BGEZ
, "bgez", 0x04010000, 0xFC1F0000, "%s, %O", _RS
|_BR
},
173 { I_BGEZAL
, "bal", 0x04110000, 0xFFFF0000, "%O", _AL
|_BR
|_LK
},
174 { I_BGEZAL
, "bgezal", 0x04110000, 0xFC1F0000, "%s, %O", _RS
|_BR
|_LK
},
175 { I_BGEZL
, "bgezl", 0x04030000, 0xFC1F0000, "%s, %O", _RS
|_BR
|_BL
},
176 { I_BGTZ
, "bgtz", 0x1C000000, 0xFC1F0000, "%s, %O", _RS
|_BR
},
177 { I_BGTZL
, "bgtzl", 0x5C000000, 0xFC1F0000, "%s, %O", _RS
|_BR
|_BL
},
178 { I_BITREV
, "bitrev", 0x7C000520, 0xFFE007FF, "%d, %t", _RT
|_WD
},
179 { I_BLEZ
, "blez", 0x18000000, 0xFC1F0000, "%s, %O", _RS
|_BR
},
180 { I_BLEZL
, "blezl", 0x58000000, 0xFC1F0000, "%s, %O", _RS
|_BR
|_BL
},
181 { I_BLTZ
, "bltz", 0x04000000, 0xFC1F0000, "%s, %O", _RS
|_BR
},
182 { I_BLTZL
, "bltzl", 0x04020000, 0xFC1F0000, "%s, %O", _RS
|_BR
|_BL
},
183 { I_BLTZAL
, "bltzal", 0x04100000, 0xFC1F0000, "%s, %O", _RS
|_BR
|_LK
},
184 { I_BLTZALL
, "bltzall", 0x04120000, 0xFC1F0000, "%s, %O", _RS
|_BR
|_BL
|_LK
},
185 { I_BNE
, "bnez", 0x14000000, 0xFC1F0000, "%s, %O", _AL
|_RS
|_BR
},
186 { I_BNE
, "bne", 0x14000000, 0xFC000000, "%s, %t, %O", _RS
|_RT
|_BR
},
187 { I_BNEL
, "bnezl", 0x54000000, 0xFC1F0000, "%s, %O", _AL
|_RS
|_BR
|_BL
},
188 { I_BNEL
, "bnel", 0x54000000, 0xFC000000, "%s, %t, %O", _RS
|_RT
|_BR
|_BL
},
189 { I_BREAK
, "break", 0x0000000D, 0xFC00003F, "%c", _SP
},
190 { I_CACHE
, "cache", 0xBC000000, 0xFC000000, "%k, %o", _RS
|_C0
},
191 { I_CFC0
, "cfc0", 0x40400000, 0xFFE007FF, "%t, %p", _WT
|_C0
},
192 { I_CLO
, "clo", 0x00000017, 0xFC1F07FF, "%d, %s", _RS
|_WD
},
193 { I_CLZ
, "clz", 0x00000016, 0xFC1F07FF, "%d, %s", _RS
|_WD
},
194 { I_CTC0
, "ctc0", 0x40C00000, 0xFFE007FF, "%t, %p", _RT
|_C0
},
195 { I_MAX
, "max", 0x0000002C, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
196 { I_MIN
, "min", 0x0000002D, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
197 { I_DBREAK
, "dbreak", 0x7000003F, 0xFC00003F, "%c", _DB
},
198 { I_DIV
, "div", 0x0000001A, 0xFC00FFFF, "%s, %t", _RS
|_RT
|_WH
|_WL
},
199 { I_DIVU
, "divu", 0x0000001B, 0xFC00FFFF, "%s, %t", _RS
|_RT
|_WH
|_WL
},
200 { I_DRET
, "dret", 0x7000003E, 0xFFFFFFFF, "", _JP
|_DB
},
201 { I_ERET
, "eret", 0x42000018, 0xFFFFFFFF, "", _JP
|_C0
},
202 { I_EXT
, "ext", 0x7C000000, 0xFC00003F, "%t, %s, %a, %ne", _RS
|_WT
},
203 { I_INS
, "ins", 0x7C000004, 0xFC00003F, "%t, %s, %a, %ni", _RS
|_RT
|_WT
},
204 { I_J
, "j", 0x08000000, 0xFC000000, "%j", _JP
},
205 { I_JR
, "jr", 0x00000008, 0xFC1FFFFF, "%J", _RS
|_JP
},
206 { I_JALR
, "jalr", 0x0000F809, 0xFC1FFFFF, "%J", _AL
|_RS
|_WD
|_JP
},
207 { I_JALR
, "jalr", 0x00000009, 0xFC1F07FF, "%J, %d", _RS
|_WD
|_JP
},
208 { I_JAL
, "jal", 0x0C000000, 0xFC000000, "%j", _JP
|_LK
},
209 { I_LB
, "lb", 0x80000000, 0xFC000000, "%t, %o", _RS
|_WT
|_LD
},
210 { I_LBU
, "lbu", 0x90000000, 0xFC000000, "%t, %o", _RS
|_WT
|_LD
},
211 { I_LH
, "lh", 0x84000000, 0xFC000000, "%t, %o", _RS
|_WT
|_LD
},
212 { I_LHU
, "lhu", 0x94000000, 0xFC000000, "%t, %o", _RS
|_WT
|_LD
},
213 { I_LL
, "ll", 0xC0000000, 0xFC000000, "%t, %o", _RS
|_WT
|_LD
},
214 { I_LUI
, "lui", 0x3C000000, 0xFFE00000, "%t, %I", _WT
},
215 { I_LW
, "lw", 0x8C000000, 0xFC000000, "%t, %o", _RS
|_WT
|_LD
},
216 { I_LWL
, "lwl", 0x88000000, 0xFC000000, "%t, %o", _RS
|_RT
|_WT
|_LD
},
217 { I_LWR
, "lwr", 0x98000000, 0xFC000000, "%t, %o", _RS
|_RT
|_WT
|_LD
},
218 { I_MADD
, "madd", 0x0000001C, 0xFC00FFFF, "%s, %t", _RS
|_RT
|_RL
|_RH
|_WL
|_WH
},
219 { I_MADDU
, "maddu", 0x0000001D, 0xFC00FFFF, "%s, %t", _RS
|_RT
|_RL
|_RH
|_WL
|_WH
},
220 { I_MFC0
, "mfc0", 0x40000000, 0xFFE007FF, "%t, %0", _WT
|_C0
},
221 { I_MFDR
, "mfdr", 0x7000003D, 0xFFE007FF, "%t, %r", _WT
|_DB
},
222 { I_MFHI
, "mfhi", 0x00000010, 0xFFFF07FF, "%d", _WD
|_RH
},
223 { I_MFIC
, "mfic", 0x70000024, 0xFFE007FF, "%t, %p", _WT
|_DB
},
224 { I_MFLO
, "mflo", 0x00000012, 0xFFFF07FF, "%d", _WD
|_RL
},
225 { I_MOVN
, "movn", 0x0000000B, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_RD
|_WD
},
226 { I_MOVZ
, "movz", 0x0000000A, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_RD
|_WD
},
227 { I_MSUB
, "msub", 0x0000002e, 0xfc00ffff, "%d, %t", _RS
|_RT
|_RL
|_RH
|_WL
|_WH
},
228 { I_MSUBU
, "msubu", 0x0000002f, 0xfc00ffff, "%d, %t", _RS
|_RT
|_RL
|_RH
|_WL
|_WH
},
229 { I_MTC0
, "mtc0", 0x40800000, 0xFFE007FF, "%t, %0", _RT
|_C0
},
230 { I_MTDR
, "mtdr", 0x7080003D, 0xFFE007FF, "%t, %r", _RT
|_DB
},
231 { I_MTIC
, "mtic", 0x70000026, 0xFFE007FF, "%t, %p", _RT
|_DB
},
232 { I_HALT
, "halt", 0x70000000, 0xFFFFFFFF, "", _DB
},
233 { I_MTHI
, "mthi", 0x00000011, 0xFC1FFFFF, "%s", _RS
|_WH
},
234 { I_MTLO
, "mtlo", 0x00000013, 0xFC1FFFFF, "%s", _RS
|_WL
},
235 { I_MULT
, "mult", 0x00000018, 0xFC00FFFF, "%s, %t", _RS
|_RT
|_WL
|_WH
},
236 { I_MULTU
, "multu", 0x00000019, 0xFC0007FF, "%s, %t", _RS
|_RT
|_WL
|_WH
},
237 { I_NOR
, "not", 0x00000027, 0xFC1F07FF, "%d, %s", _AL
|_RS
|_WD
},
238 { I_NOR
, "nor", 0x00000027, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
239 { I_OR
, "move", 0x00000025, 0xFC1F07FF, "%d, %s", _AL
|_RS
|_WD
},
240 { I_OR
, "or", 0x00000025, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
241 { I_ORI
, "li", 0x34000000, 0xFFE00000, "%t, %I", _AL
|_WT
},
242 { I_ORI
, "ori", 0x34000000, 0xFC000000, "%t, %s, %I", _RS
|_WT
},
243 { I_ROTR
, "rotr", 0x00200002, 0xFFE0003F, "%d, %t, %a", _RT
|_WD
},
244 { I_ROTV
, "rotv", 0x00000046, 0xFC0007FF, "%d, %t, %s", _RS
|_RT
|_WD
},
245 { I_SEB
, "seb", 0x7C000420, 0xFFE007FF, "%d, %t", _RT
|_WD
},
246 { I_SEH
, "seh", 0x7C000620, 0xFFE007FF, "%d, %t", _RT
|_WD
},
247 { I_SB
, "sb", 0xA0000000, 0xFC000000, "%t, %o", _RS
|_RT
|_ST
},
248 { I_SC
, "sc", 0xE0000000, 0xFC000000, "%t, %o", _RS
|_RT
|_ST
},
249 { I_SH
, "sh", 0xA4000000, 0xFC000000, "%t, %o", _RS
|_RT
|_ST
},
250 { I_SLLV
, "sllv", 0x00000004, 0xFC0007FF, "%d, %t, %s", _RS
|_RT
|_WD
},
251 { I_SLL
, "nop", 0x00000000, 0xFFFFFFFF, "", _AL
},
252 { I_SLL
, "sll", 0x00000000, 0xFFE0003F, "%d, %t, %a", _RT
|_WD
},
253 { I_SLT
, "slt", 0x0000002A, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
254 { I_SLTI
, "slti", 0x28000000, 0xFC000000, "%t, %s, %i", _RS
|_WT
},
255 { I_SLTIU
, "sltiu", 0x2C000000, 0xFC000000, "%t, %s, %i", _RS
|_WT
},
256 { I_SLTU
, "sltu", 0x0000002B, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
257 { I_SRA
, "sra", 0x00000003, 0xFFE0003F, "%d, %t, %a", _RT
|_WD
},
258 { I_SRAV
, "srav", 0x00000007, 0xFC0007FF, "%d, %t, %s", _RS
|_RT
|_WD
},
259 { I_SRLV
, "srlv", 0x00000006, 0xFC0007FF, "%d, %t, %s", _RS
|_RT
|_WD
},
260 { I_SRL
, "srl", 0x00000002, 0xFFE0003F, "%d, %t, %a", _RT
|_WD
},
261 { I_SW
, "sw", 0xAC000000, 0xFC000000, "%t, %o", _RS
|_RT
|_ST
},
262 { I_SWL
, "swl", 0xA8000000, 0xFC000000, "%t, %o", _RS
|_RT
|_ST
},
263 { I_SWR
, "swr", 0xB8000000, 0xFC000000, "%t, %o", _RS
|_RT
|_ST
},
264 { I_SUB
, "neg", 0x00000022, 0xFFE007FF, "%d, %t", _AL
|_RT
|_WD
},
265 { I_SUB
, "sub", 0x00000022, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
266 { I_SUBU
, "negu", 0x00000023, 0xFFE007FF, "%d, %t", _AL
|_RT
|_WD
},
267 { I_SUBU
, "subu", 0x00000023, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
268 { I_SYNC
, "sync", 0x0000000F, 0xFFFFFFFF, "", _SP
},
269 { I_SYSCALL
, "syscall", 0x0000000C, 0xFC00003F, "%c", _SP
},
270 { I_XOR
, "xor", 0x00000026, 0xFC0007FF, "%d, %s, %t", _RS
|_RT
|_WD
},
271 { I_XORI
, "xori", 0x38000000, 0xFC000000, "%t, %s, %I", _RS
|_WT
},
272 { I_WSBH
, "wsbh", 0x7C0000A0, 0xFFE007FF, "%d, %t", _RT
|_WD
},
273 { I_WSBW
, "wsbw", 0x7C0000E0, 0xFFE007FF, "%d, %t", _RT
|_WD
},
275 /* FPU instructions */
276 { I_ABS_S
, "abs.s", 0x46000005, 0xFFFF003F, "%D, %S", _Rs
|_Wd
|_C1
},
277 { I_ADD_S
, "add.s", 0x46000000, 0xFFE0003F, "%D, %S, %T", _Rs
|_Rt
|_Wd
|_C1
},
278 { I_BC1F
, "bc1f", 0x45000000, 0xFFFF0000, "%O", _RC
|_BR
|_C1
},
279 { I_BC1FL
, "bc1fl", 0x45020000, 0xFFFF0000, "%O", _RC
|_BR
|_BL
|_C1
},
280 { I_BC1T
, "bc1t", 0x45010000, 0xFFFF0000, "%O", _RC
|_BR
|_C1
},
281 { I_BC1TL
, "bc1tl", 0x45030000, 0xFFFF0000, "%O", _RC
|_BR
|_BL
|_C1
},
282 { I_C_F_S
, "c.f.s", 0x46000030, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
283 { I_C_UN_S
, "c.un.s", 0x46000031, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
284 { I_C_EQ_S
, "c.eq.s", 0x46000032, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
285 { I_C_UEQ_S
, "c.ueq.s", 0x46000033, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
286 { I_C_OLT_S
, "c.olt.s", 0x46000034, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
287 { I_C_ULT_S
, "c.ult.s", 0x46000035, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
288 { I_C_OLE_S
, "c.ole.s", 0x46000036, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
289 { I_C_ULE_S
, "c.ule.s", 0x46000037, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
290 { I_C_SF_S
, "c.sf.s", 0x46000038, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
291 { I_C_NGLE_S
, "c.ngle.s", 0x46000039, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
292 { I_C_SEQ_S
, "c.seq.s", 0x4600003A, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
293 { I_C_NGL_S
, "c.ngl.s", 0x4600003B, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
294 { I_C_LT_S
, "c.lt.s", 0x4600003C, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
295 { I_C_NGE_S
, "c.nge.s", 0x4600003D, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
296 { I_C_LE_S
, "c.le.s", 0x4600003E, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
297 { I_C_NGT_S
, "c.ngt.s", 0x4600003F, 0xFFE007FF, "%S, %T", _Rs
|_Rt
|_WC
|_C1
},
298 { I_CEIL_W_S
, "ceil.w.s", 0x4600000E, 0xFFFF003F, "%D, %S", _Rs
|_Wd
|_C1
},
299 { I_CFC1
, "cfc1", 0x44400000, 0xFFE007FF, "%t, %p", _WT
|_C1
},
300 { I_CTC1
, "ctc1", 0x44c00000, 0xFFE007FF, "%t, %p", _RT
|_C1
},
301 { I_CVT_S_W
, "cvt.s.w", 0x46800020, 0xFFFF003F, "%D, %S", _Rs
|_Wd
|_C1
},
302 { I_CVT_W_S
, "cvt.w.s", 0x46000024, 0xFFFF003F, "%D, %S", _Rs
|_Wd
|_C1
},
303 { I_DIV_S
, "div.s", 0x46000003, 0xFFE0003F, "%D, %S, %T", _Rs
|_Rt
|_Wd
|_C1
},
304 { I_FLOOR_W_S
, "floor.w.s", 0x4600000F, 0xFFFF003F, "%D, %S", _Rs
|_Wd
|_C1
},
305 { I_LWC1
, "lwc1", 0xc4000000, 0xFC000000, "%T, %o", _Rs
|_Wt
|_LD
|_C1
},
306 { I_MFC1
, "mfc1", 0x44000000, 0xFFE007FF, "%t, %1", _WT
|_C1
},
307 { I_MOV_S
, "mov.s", 0x46000006, 0xFFFF003F, "%D, %S", _Rs
|_Wd
|_C1
},
308 { I_MTC1
, "mtc1", 0x44800000, 0xFFE007FF, "%t, %1", _RT
|_C1
},
309 { I_MUL_S
, "mul.s", 0x46000002, 0xFFE0003F, "%D, %S, %T", _Rs
|_Rt
|_Wd
|_C1
},
310 { I_NEG_S
, "neg.s", 0x46000007, 0xFFFF003F, "%D, %S", _Rs
|_Wd
|_C1
},
311 { I_ROUND_W_S
, "round.w.s", 0x4600000C, 0xFFFF003F, "%D, %S", _Rs
|_Wd
|_C1
},
312 { I_SQRT_S
, "sqrt.s", 0x46000004, 0xFFFF003F, "%D, %S", _Rs
|_Wd
|_C1
},
313 { I_SUB_S
, "sub.s", 0x46000001, 0xFFE0003F, "%D, %S, %T", _Rs
|_Rt
|_Wd
|_C1
},
314 { I_SWC1
, "swc1", 0xe4000000, 0xFC000000, "%T, %o", _RS
|_Rt
|_ST
|_C1
},
315 { I_TRUNC_W_S
, "trunc.w.s", 0x4600000D, 0xFFFF003F, "%D, %S", _Rs
|_Wd
|_C1
},
317 /* VPU instructions */
318 { I_BVF
, "bvf", 0x49000000, 0xFFE30000, "%Zc, %O", _RC
|_BR
|_C2
}, /* [hlide] %Z -> %Zc */
319 { I_BVFL
, "bvfl", 0x49020000, 0xFFE30000, "%Zc, %O", _RC
|_BR
|_BL
|_C2
}, /* [hlide] %Z -> %Zc */
320 { I_BVT
, "bvt", 0x49010000, 0xFFE30000, "%Zc, %O", _RC
|_BR
|_C2
}, /* [hlide] %Z -> %Zc */
321 { I_BVTL
, "bvtl", 0x49030000, 0xFFE30000, "%Zc, %O", _RC
|_BR
|_BL
|_C2
}, /* [hlide] %Z -> %Zc */
322 { I_LV_Q
, "lv.q", 0xD8000000, 0xFC000002, "%Xq, %Y", _RS
|_LD
|_C2
},
323 { I_LV_S
, "lv.s", 0xC8000000, 0xFC000000, "%Xs, %Y", _RS
|_LD
|_C2
},
324 { I_LVL_Q
, "lvl.q", 0xD4000000, 0xFC000002, "%Xq, %Y", _RS
|_LD
|_C2
},
325 { I_LVR_Q
, "lvr.q", 0xD4000002, 0xFC000002, "%Xq, %Y", _RS
|_LD
|_C2
},
326 { I_MFV
, "mfv", 0x48600000, 0xFFE0FF80, "%t, %zs", _WT
|_C2
}, /* [hlide] added "%t, %zs" */
327 { I_MFVC
, "mfvc", 0x48600000, 0xFFE0FF00, "%t, %2d", _WT
|_C2
}, /* [hlide] added "%t, %2d" */
328 { I_MTV
, "mtv", 0x48E00000, 0xFFE0FF80, "%t, %zs", _RT
|_C2
}, /* [hlide] added "%t, %zs" */
329 { I_MTVC
, "mtvc", 0x48E00000, 0xFFE0FF00, "%t, %2d", _RT
|_C2
}, /* [hlide] added "%t, %2d" */
330 { I_SV_Q
, "sv.q", 0xF8000000, 0xFC000002, "%Xq, %Y", _RS
|_ST
|_C2
},
331 { I_SV_S
, "sv.s", 0xE8000000, 0xFC000000, "%Xs, %Y", _RS
|_ST
|_C2
},
332 { I_SVL_Q
, "svl.q", 0xF4000000, 0xFC000002, "%Xq, %Y", _RS
|_ST
|_C2
},
333 { I_SVR_Q
, "svr.q", 0xF4000002, 0xFC000002, "%Xq, %Y", _RS
|_ST
|_C2
},
334 { I_VABS_P
, "vabs.p", 0xD0010080, 0xFFFF8080, "%zp, %yp", _C2
},
335 { I_VABS_Q
, "vabs.q", 0xD0018080, 0xFFFF8080, "%zq, %yq", _C2
},
336 { I_VABS_S
, "vabs.s", 0xD0010000, 0xFFFF8080, "%zs, %ys", _C2
},
337 { I_VABS_T
, "vabs.t", 0xD0018000, 0xFFFF8080, "%zt, %yt", _C2
},
338 { I_VADD_P
, "vadd.p", 0x60000080, 0xFF808080, "%zp, %yp, %xp", _C2
},
339 { I_VADD_Q
, "vadd.q", 0x60008080, 0xFF808080, "%zq, %yq, %xq", _C2
},
340 { I_VADD_S
, "vadd.s", 0x60000000, 0xFF808080, "%zs, %ys, %xs", _C2
}, /* [hlide] %yz -> %ys */
341 { I_VADD_T
, "vadd.t", 0x60008000, 0xFF808080, "%zt, %yt, %xt", _C2
},
342 { I_VASIN_P
, "vasin.p", 0xD0170080, 0xFFFF8080, "%zp, %yp", _C2
},
343 { I_VASIN_Q
, "vasin.q", 0xD0178080, 0xFFFF8080, "%zq, %yq", _C2
},
344 { I_VASIN_S
, "vasin.s", 0xD0170000, 0xFFFF8080, "%zs, %ys", _C2
},
345 { I_VASIN_T
, "vasin.t", 0xD0178000, 0xFFFF8080, "%zt, %yt", _C2
},
346 { I_VAVG_P
, "vavg.p", 0xD0470080, 0xFFFF8080, "%zp, %yp", _C2
},
347 { I_VAVG_Q
, "vavg.q", 0xD0478080, 0xFFFF8080, "%zq, %yq", _C2
},
348 { I_VAVG_T
, "vavg.t", 0xD0478000, 0xFFFF8080, "%zt, %yt", _C2
},
349 { I_VBFY1_P
, "vbfy1.p", 0xD0420080, 0xFFFF8080, "%zp, %yp", _C2
},
350 { I_VBFY1_Q
, "vbfy1.q", 0xD0428080, 0xFFFF8080, "%zq, %yq", _C2
},
351 { I_VBFY2_Q
, "vbfy2.q", 0xD0438080, 0xFFFF8080, "%zq, %yq", _C2
},
352 { I_VCMOVF_P
, "vcmovf.p", 0xD2A80080, 0xFFF88080, "%zp, %yp, %v3", _RC
|_C2
}, /* [hlide] added "%zp, %yp, %v3" */
353 { I_VCMOVF_Q
, "vcmovf.q", 0xD2A88080, 0xFFF88080, "%zq, %yq, %v3", _RC
|_C2
}, /* [hlide] added "%zq, %yq, %v3" */
354 { I_VCMOVF_S
, "vcmovf.s", 0xD2A80000, 0xFFF88080, "%zs, %ys, %v3", _RC
|_C2
}, /* [hlide] added "%zs, %ys, %v3" */
355 { I_VCMOVF_T
, "vcmovf.t", 0xD2A88000, 0xFFF88080, "%zt, %yt, %v3", _RC
|_C2
}, /* [hlide] added "%zt, %yt, %v3" */
356 { I_VCMOVT_P
, "vcmovt.p", 0xD2A00080, 0xFFF88080, "%zp, %yp, %v3", _RC
|_C2
}, /* [hlide] added "%zp, %yp, %v3" */
357 { I_VCMOVT_Q
, "vcmovt.q", 0xD2A08080, 0xFFF88080, "%zq, %yq, %v3", _RC
|_C2
}, /* [hlide] added "%zq, %yq, %v3" */
358 { I_VCMOVT_S
, "vcmovt.s", 0xD2A00000, 0xFFF88080, "%zs, %ys, %v3", _RC
|_C2
}, /* [hlide] added "%zs, %ys, %v3" */
359 { I_VCMOVT_T
, "vcmovt.t", 0xD2A08000, 0xFFF88080, "%zt, %yt, %v3", _RC
|_C2
}, /* [hlide] added "%zt, %yt, %v3" */
360 { I_VCMP_P
, "vcmp.p", 0x6C000080, 0xFFFFFFF0, "%Zn", _AL
|_WC
|_C2
}, /* [hlide] added "%Zn" */
361 { I_VCMP_P
, "vcmp.p", 0x6C000080, 0xFFFF80F0, "%Zn, %yp", _AL
|_WC
|_C2
}, /* [hlide] added "%Zn, %xp" */
362 { I_VCMP_P
, "vcmp.p", 0x6C000080, 0xFF8080F0, "%Zn, %yp, %xp", _WC
|_C2
}, /* [hlide] added "%Zn, %zp, %xp" */
363 { I_VCMP_Q
, "vcmp.q", 0x6C008080, 0xFFFFFFF0, "%Zn", _AL
|_WC
|_C2
}, /* [hlide] added "%Zn" */
364 { I_VCMP_Q
, "vcmp.q", 0x6C008080, 0xFFFF80F0, "%Zn, %yq", _AL
|_WC
|_C2
}, /* [hlide] added "%Zn, %yq" */
365 { I_VCMP_Q
, "vcmp.q", 0x6C008080, 0xFF8080F0, "%Zn, %yq, %xq", _WC
|_C2
}, /* [hlide] added "%Zn, %yq, %xq" */
366 { I_VCMP_S
, "vcmp.s", 0x6C000000, 0xFFFFFFF0, "%Zn", _AL
|_WC
|_C2
}, /* [hlide] added "%Zn" */
367 { I_VCMP_S
, "vcmp.s", 0x6C000000, 0xFFFF80F0, "%Zn, %ys", _AL
|_WC
|_C2
}, /* [hlide] added "%Zn, %ys" */
368 { I_VCMP_S
, "vcmp.s", 0x6C000000, 0xFF8080F0, "%Zn, %ys, %xs", _WC
|_C2
}, /* [hlide] added "%Zn, %ys, %xs" */
369 { I_VCMP_T
, "vcmp.t", 0x6C008000, 0xFFFFFFF0, "%Zn", _AL
|_WC
|_C2
}, /* [hlide] added "%zp" */
370 { I_VCMP_T
, "vcmp.t", 0x6C008000, 0xFFFF80F0, "%Zn, %yt", _AL
|_WC
|_C2
}, /* [hlide] added "%Zn, %yt" */
371 { I_VCMP_T
, "vcmp.t", 0x6C008000, 0xFF8080F0, "%Zn, %yt, %xt", _WC
|_C2
}, /* [hlide] added "%Zn, %yt, %xt" */
372 { I_VCOS_P
, "vcos.p", 0xD0130080, 0xFFFF8080, "%zp, %yp", _C2
},
373 { I_VCOS_Q
, "vcos.q", 0xD0138080, 0xFFFF8080, "%zq, %yq", _C2
},
374 { I_VCOS_S
, "vcos.s", 0xD0130000, 0xFFFF8080, "%zs, %ys", _C2
},
375 { I_VCOS_T
, "vcos.t", 0xD0138000, 0xFFFF8080, "%zt, %yt", _C2
},
376 { I_VCRS_T
, "vcrs.t", 0x66808000, 0xFF808080, "%zt, %yt, %xt", _C2
},
377 { I_VCRSP_T
, "vcrsp.t", 0xF2808000, 0xFF808080, "%zt, %yt, %xt", _C2
},
378 { I_VCST_P
, "vcst.p", 0xD0600080, 0xFFE0FF80, "%zp, %vk", }, /* [hlide] "%zp, %yp, %xp", -> "%zp, %vk" */
379 { I_VCST_Q
, "vcst.q", 0xD0608080, 0xFFE0FF80, "%zq, %vk", _C2
}, /* [hlide] "%zq, %yq, %xq", -> "%zq, %vk" */
380 { I_VCST_S
, "vcst.s", 0xD0600000, 0xFFE0FF80, "%zs, %vk", _C2
}, /* [hlide] "%zs, %ys, %xs", -> "%zs, %vk" */
381 { I_VCST_T
, "vcst.t", 0xD0608000, 0xFFE0FF80, "%zt, %vk", _C2
}, /* [hlide] "%zt, %yt, %xt", -> "%zt, %vk" */
382 { I_VDET_P
, "vdet.p", 0x67000080, 0xFF808080, "%zs, %yp, %xp", _C2
},
383 { I_VDIV_P
, "vdiv.p", 0x63800080, 0xFF808080, "%zp, %yp, %xp", _C2
},
384 { I_VDIV_Q
, "vdiv.q", 0x63808080, 0xFF808080, "%zq, %yq, %xq", _C2
},
385 { I_VDIV_S
, "vdiv.s", 0x63800000, 0xFF808080, "%zs, %ys, %xs", _C2
}, /* [hlide] %yz -> %ys */
386 { I_VDIV_T
, "vdiv.t", 0x63808000, 0xFF808080, "%zt, %yt, %xt", _C2
},
387 { I_VDOT_P
, "vdot.p", 0x64800080, 0xFF808080, "%zs, %yp, %xp", _C2
},
388 { I_VDOT_Q
, "vdot.q", 0x64808080, 0xFF808080, "%zs, %yq, %xq", _C2
},
389 { I_VDOT_T
, "vdot.t", 0x64808000, 0xFF808080, "%zs, %yt, %xt", _C2
},
390 { I_VEXP2_P
, "vexp2.p", 0xD0140080, 0xFFFF8080, "%zp, %yp", _C2
},
391 { I_VEXP2_Q
, "vexp2.q", 0xD0148080, 0xFFFF8080, "%zq, %yq", _C2
},
392 { I_VEXP2_S
, "vexp2.s", 0xD0140000, 0xFFFF8080, "%zs, %ys", _C2
},
393 { I_VEXP2_T
, "vexp2.t", 0xD0148000, 0xFFFF8080, "%zt, %yt", _C2
},
394 { I_VF2H_P
, "vf2h.p", 0xD0320080, 0xFFFF8080, "%zs, %yp", _C2
}, /* [hlide] %zp -> %zs */
395 { I_VF2H_Q
, "vf2h.q", 0xD0328080, 0xFFFF8080, "%zp, %yq", _C2
}, /* [hlide] %zq -> %zp */
396 { I_VF2ID_P
, "vf2id.p", 0xD2600080, 0xFFE08080, "%zp, %yp, %v5", _C2
}, /* [hlide] added "%zp, %yp, %v5" */
397 { I_VF2ID_Q
, "vf2id.q", 0xD2608080, 0xFFE08080, "%zq, %yq, %v5", _C2
}, /* [hlide] added "%zq, %yq, %v5" */
398 { I_VF2ID_S
, "vf2id.s", 0xD2600000, 0xFFE08080, "%zs, %ys, %v5", _C2
}, /* [hlide] added "%zs, %ys, %v5" */
399 { I_VF2ID_T
, "vf2id.t", 0xD2608000, 0xFFE08080, "%zt, %yt, %v5", _C2
}, /* [hlide] added "%zt, %yt, %v5" */
400 { I_VF2IN_P
, "vf2in.p", 0xD2000080, 0xFFE08080, "%zp, %yp, %v5", _C2
}, /* [hlide] added "%zp, %yp, %v5" */
401 { I_VF2IN_Q
, "vf2in.q", 0xD2008080, 0xFFE08080, "%zq, %yq, %v5", _C2
}, /* [hlide] added "%zq, %yq, %v5" */
402 { I_VF2IN_S
, "vf2in.s", 0xD2000000, 0xFFE08080, "%zs, %ys, %v5", _C2
}, /* [hlide] added "%zs, %ys, %v5" */
403 { I_VF2IN_T
, "vf2in.t", 0xD2008000, 0xFFE08080, "%zt, %yt, %v5", _C2
}, /* [hlide] added "%zt, %yt, %v5" */
404 { I_VF2IU_P
, "vf2iu.p", 0xD2400080, 0xFFE08080, "%zp, %yp, %v5", _C2
}, /* [hlide] added "%zp, %yp, %v5" */
405 { I_VF2IU_Q
, "vf2iu.q", 0xD2408080, 0xFFE08080, "%zq, %yq, %v5", _C2
}, /* [hlide] added "%zq, %yq, %v5" */
406 { I_VF2IU_S
, "vf2iu.s", 0xD2400000, 0xFFE08080, "%zs, %ys, %v5", _C2
}, /* [hlide] added "%zs, %ys, %v5" */
407 { I_VF2IU_T
, "vf2iu.t", 0xD2408000, 0xFFE08080, "%zt, %yt, %v5", _C2
}, /* [hlide] added "%zt, %yt, %v5" */
408 { I_VF2IZ_P
, "vf2iz.p", 0xD2200080, 0xFFE08080, "%zp, %yp, %v5", _C2
}, /* [hlide] added "%zp, %yp, %v5" */
409 { I_VF2IZ_Q
, "vf2iz.q", 0xD2208080, 0xFFE08080, "%zq, %yq, %v5", _C2
}, /* [hlide] added "%zq, %yq, %v5" */
410 { I_VF2IZ_S
, "vf2iz.s", 0xD2200000, 0xFFE08080, "%zs, %ys, %v5", _C2
}, /* [hlide] added "%zs, %ys, %v5" */
411 { I_VF2IZ_T
, "vf2iz.t", 0xD2208000, 0xFFE08080, "%zt, %yt, %v5", _C2
}, /* [hlide] added "%zt, %yt, %v5" */
412 { I_VFAD_P
, "vfad.p", 0xD0460080, 0xFFFF8080, "%zp, %yp", _C2
},
413 { I_VFAD_Q
, "vfad.q", 0xD0468080, 0xFFFF8080, "%zq, %yq", _C2
},
414 { I_VFAD_T
, "vfad.t", 0xD0468000, 0xFFFF8080, "%zt, %yt", _C2
},
415 { I_VFIM_S
, "vfim.s", 0xDF800000, 0xFF800000, "%xs, %vh", _C2
}, /* [hlide] added "%xs, %vh" */
416 { I_VFLUSH
, "vflush", 0xFFFF040D, 0xFFFFFFFF, "", _C2
},
417 { I_VH2F_P
, "vh2f.p", 0xD0330080, 0xFFFF8080, "%zq, %yp", _C2
}, /* [hlide] %zp -> %zq */
418 { I_VH2F_S
, "vh2f.s", 0xD0330000, 0xFFFF8080, "%zp, %ys", _C2
}, /* [hlide] %zs -> %zp */
419 { I_VHDP_P
, "vhdp.p", 0x66000080, 0xFF808080, "%zs, %yp, %xp", _C2
}, /* [hlide] added "%zs, %yp, %xp" */
420 { I_VHDP_Q
, "vhdp.q", 0x66008080, 0xFF808080, "%zs, %yq, %xq", _C2
}, /* [hlide] added "%zs, %yq, %xq" */
421 { I_VHDP_T
, "vhdp.t", 0x66008000, 0xFF808080, "%zs, %yt, %xt", _C2
}, /* [hlide] added "%zs, %yt, %xt" */
422 { I_VHTFM2_P
, "vhtfm2.p", 0xF0800000, 0xFF808080, "%zp, %ym, %xp", _C2
}, /* [hlide] added "%zp, %ym, %xp" */
423 { I_VHTFM3_T
, "vhtfm3.t", 0xF1000080, 0xFF808080, "%zt, %yn, %xt", _C2
}, /* [hlide] added "%zt, %yn, %xt" */
424 { I_VHTFM4_Q
, "vhtfm4.q", 0xF1808000, 0xFF808080, "%zq, %yo, %xq", _C2
}, /* [hlide] added "%zq, %yo, %xq" */
425 { I_VI2C_Q
, "vi2c.q", 0xD03D8080, 0xFFFF8080, "%zs, %yq", _C2
}, /* [hlide] added "%zs, %yq" */
426 { I_VI2F_P
, "vi2f.p", 0xD2800080, 0xFFE08080, "%zp, %yp, %v5", _C2
}, /* [hlide] added "%zp, %yp, %v5" */
427 { I_VI2F_Q
, "vi2f.q", 0xD2808080, 0xFFE08080, "%zq, %yq, %v5", _C2
}, /* [hlide] added "%zq, %yq, %v5" */
428 { I_VI2F_S
, "vi2f.s", 0xD2800000, 0xFFE08080, "%zs, %ys, %v5", _C2
}, /* [hlide] added "%zs, %ys, %v5" */
429 { I_VI2F_T
, "vi2f.t", 0xD2808000, 0xFFE08080, "%zt, %yt, %v5", _C2
}, /* [hlide] added "%zt, %yt, %v5" */
430 { I_VI2S_P
, "vi2s.p", 0xD03F0080, 0xFFFF8080, "%zs, %yp", _C2
}, /* [hlide] added "%zs, %yp" */
431 { I_VI2S_Q
, "vi2s.q", 0xD03F8080, 0xFFFF8080, "%zp, %yq", _C2
}, /* [hlide] added "%zp, %yq" */
432 { I_VI2UC_Q
, "vi2uc.q", 0xD03C8080, 0xFFFF8080, "%zq, %yq", _C2
}, /* [hlide] %zp -> %zq */
433 { I_VI2US_P
, "vi2us.p", 0xD03E0080, 0xFFFF8080, "%zq, %yq", _C2
}, /* [hlide] %zp -> %zq */
434 { I_VI2US_Q
, "vi2us.q", 0xD03E8080, 0xFFFF8080, "%zq, %yq", _C2
}, /* [hlide] %zp -> %zq */
435 { I_VIDT_P
, "vidt.p", 0xD0030080, 0xFFFFFF80, "%zp", _C2
},
436 { I_VIDT_Q
, "vidt.q", 0xD0038080, 0xFFFFFF80, "%zq", _C2
},
437 { I_VIIM_S
, "viim.s", 0xDF000000, 0xFF800000, "%xs, %vi", _C2
}, /* [hlide] added "%xs, %vi" */
438 { I_VLGB_S
, "vlgb.s", 0xD0370000, 0xFFFF8080, "%zs, %ys", _C2
},
439 { I_VLOG2_P
, "vlog2.p", 0xD0150080, 0xFFFF8080, "%zp, %yp", _C2
},
440 { I_VLOG2_Q
, "vlog2.q", 0xD0158080, 0xFFFF8080, "%zq, %yq", _C2
},
441 { I_VLOG2_S
, "vlog2.s", 0xD0150000, 0xFFFF8080, "%zs, %ys", _C2
},
442 { I_VLOG2_T
, "vlog2.t", 0xD0158000, 0xFFFF8080, "%zt, %yt", _C2
},
443 { I_VMAX_P
, "vmax.p", 0x6D800080, 0xFF808080, "%zp, %yp, %xp", _C2
},
444 { I_VMAX_Q
, "vmax.q", 0x6D808080, 0xFF808080, "%zq, %yq, %xq", _C2
},
445 { I_VMAX_S
, "vmax.s", 0x6D800000, 0xFF808080, "%zs, %ys, %xs", _C2
},
446 { I_VMAX_T
, "vmax.t", 0x6D808000, 0xFF808080, "%zt, %yt, %xt", _C2
},
447 { I_VMFVC
, "vmfvc", 0xD0500000, 0xFFFF0080, "%zs, %2s", _C2
}, /* [hlide] added "%zs, %2s" */
448 { I_VMIDT_P
, "vmidt.p", 0xF3830080, 0xFFFFFF80, "%zm", _C2
}, /* [hlide] %zp -> %zm */
449 { I_VMIDT_Q
, "vmidt.q", 0xF3838080, 0xFFFFFF80, "%zo", _C2
}, /* [hlide] %zq -> %zo */
450 { I_VMIDT_T
, "vmidt.t", 0xF3838000, 0xFFFFFF80, "%zn", _C2
}, /* [hlide] %zt -> %zn */
451 { I_VMIN_P
, "vmin.p", 0x6D000080, 0xFF808080, "%zp, %yp, %xp", _C2
},
452 { I_VMIN_Q
, "vmin.q", 0x6D008080, 0xFF808080, "%zq, %yq, %xq", _C2
},
453 { I_VMIN_S
, "vmin.s", 0x6D000000, 0xFF808080, "%zs, %ys, %xs", _C2
},
454 { I_VMIN_T
, "vmin.t", 0x6D008000, 0xFF808080, "%zt, %yt, %xt", _C2
},
455 { I_VMMOV_P
, "vmmov.p", 0xF3800080, 0xFFFF8080, "%zm, %ym", _C2
}, /* [hlide] added "%zm, %ym" */
456 { I_VMMOV_Q
, "vmmov.q", 0xF3808080, 0xFFFF8080, "%zo, %yo", _C2
},
457 { I_VMMOV_T
, "vmmov.t", 0xF3808000, 0xFFFF8080, "%zn, %yn", _C2
}, /* [hlide] added "%zn, %yn" */
458 { I_VMMUL_P
, "vmmul.p", 0xF0000080, 0xFF808080, "%?%zm, %ym, %xm",_C2
}, /* [hlide] added "%?%zm, %ym, %xm" */
459 { I_VMMUL_Q
, "vmmul.q", 0xF0008080, 0xFF808080, "%?%zo, %yo, %xo",_C2
},
460 { I_VMMUL_T
, "vmmul.t", 0xF0008000, 0xFF808080, "%?%zn, %yn, %xn",_C2
}, /* [hlide] added "%?%zn, %yn, %xn" */
461 { I_VMONE_P
, "vmone.p", 0xF3870080, 0xFFFFFF80, "%zp", _C2
},
462 { I_VMONE_Q
, "vmone.q", 0xF3878080, 0xFFFFFF80, "%zq", _C2
},
463 { I_VMONE_T
, "vmone.t", 0xF3878000, 0xFFFFFF80, "%zt", _C2
},
464 { I_VMOV_P
, "vmov.p", 0xD0000080, 0xFFFF8080, "%zp, %yp", _C2
},
465 { I_VMOV_Q
, "vmov.q", 0xD0008080, 0xFFFF8080, "%zq, %yq", _C2
},
466 { I_VMOV_S
, "vmov.s", 0xD0000000, 0xFFFF8080, "%zs, %ys", _C2
},
467 { I_VMOV_T
, "vmov.t", 0xD0008000, 0xFFFF8080, "%zt, %yt", _C2
},
468 { I_VMSCL_P
, "vmscl.p", 0xF2000080, 0xFF808080, "%zm, %ym, %xs", _C2
}, /* [hlide] %zp, %yp, %xp -> %zm, %ym, %xs */
469 { I_VMSCL_Q
, "vmscl.q", 0xF2008080, 0xFF808080, "%zo, %yo, %xs", _C2
}, /* [hlide] %zq, %yq, %xp -> %zo, %yo, %xs */
470 { I_VMSCL_T
, "vmscl.t", 0xF2008000, 0xFF808080, "%zn, %yn, %xs", _C2
}, /* [hlide] %zt, %yt, %xp -> %zn, %yn, %xs */
471 { I_VMTVC
, "vmtvc", 0xD0510000, 0xFFFF8000, "%2d, %ys", _C2
}, /* [hlide] added "%2d, %ys" */
472 { I_VMUL_P
, "vmul.p", 0x64000080, 0xFF808080, "%zp, %yp, %xp", _C2
},
473 { I_VMUL_Q
, "vmul.q", 0x64008080, 0xFF808080, "%zq, %yq, %xq", _C2
},
474 { I_VMUL_S
, "vmul.s", 0x64000000, 0xFF808080, "%zs, %ys, %xs", _C2
},
475 { I_VMUL_T
, "vmul.t", 0x64008000, 0xFF808080, "%zt, %yt, %xt", _C2
},
476 { I_VMZERO_P
, "vmzero.p", 0xF3860080, 0xFFFFFF80, "%zm", _C2
}, /* [hlide] %zp -> %zm */
477 { I_VMZERO_Q
, "vmzero.q", 0xF3868080, 0xFFFFFF80, "%zo", _C2
}, /* [hlide] %zq -> %zo */
478 { I_VMZERO_T
, "vmzero.t", 0xF3868000, 0xFFFFFF80, "%zn", _C2
}, /* [hlide] %zt -> %zn */
479 { I_VNEG_P
, "vneg.p", 0xD0020080, 0xFFFF8080, "%zp, %yp", _C2
},
480 { I_VNEG_Q
, "vneg.q", 0xD0028080, 0xFFFF8080, "%zq, %yq", _C2
},
481 { I_VNEG_S
, "vneg.s", 0xD0020000, 0xFFFF8080, "%zs, %ys", _C2
},
482 { I_VNEG_T
, "vneg.t", 0xD0028000, 0xFFFF8080, "%zt, %yt", _C2
},
483 { I_VNOP
, "vnop", 0xFFFF0000, 0xFFFFFFFF, "", _C2
},
484 { I_VNRCP_P
, "vnrcp.p", 0xD0180080, 0xFFFF8080, "%zp, %yp", _C2
},
485 { I_VNRCP_Q
, "vnrcp.q", 0xD0188080, 0xFFFF8080, "%zq, %yq", _C2
},
486 { I_VNRCP_S
, "vnrcp.s", 0xD0180000, 0xFFFF8080, "%zs, %ys", _C2
},
487 { I_VNRCP_T
, "vnrcp.t", 0xD0188000, 0xFFFF8080, "%zt, %yt", _C2
},
488 { I_VNSIN_P
, "vnsin.p", 0xD01A0080, 0xFFFF8080, "%zp, %yp", _C2
},
489 { I_VNSIN_Q
, "vnsin.q", 0xD01A8080, 0xFFFF8080, "%zq, %yq", _C2
},
490 { I_VNSIN_S
, "vnsin.s", 0xD01A0000, 0xFFFF8080, "%zs, %ys", _C2
},
491 { I_VNSIN_T
, "vnsin.t", 0xD01A8000, 0xFFFF8080, "%zt, %yt", _C2
},
492 { I_VOCP_P
, "vocp.p", 0xD0440080, 0xFFFF8080, "%zp, %yp", _C2
},
493 { I_VOCP_Q
, "vocp.q", 0xD0448080, 0xFFFF8080, "%zq, %yq", _C2
},
494 { I_VOCP_S
, "vocp.s", 0xD0440000, 0xFFFF8080, "%zs, %ys", _C2
},
495 { I_VOCP_T
, "vocp.t", 0xD0448000, 0xFFFF8080, "%zt, %yt", _C2
},
496 { I_VONE_P
, "vone.p", 0xD0070080, 0xFFFFFF80, "%zp", _C2
},
497 { I_VONE_Q
, "vone.q", 0xD0078080, 0xFFFFFF80, "%zq", _C2
},
498 { I_VONE_S
, "vone.s", 0xD0070000, 0xFFFFFF80, "%zs", _C2
},
499 { I_VONE_T
, "vone.t", 0xD0078000, 0xFFFFFF80, "%zt", _C2
},
500 { I_VPFXD
, "vpfxd", 0xDE000000, 0xFF000000, "[%vp4, %vp5, %vp6, %vp7]",_C2
}, /* [hlide] added "[%vp4, %vp5, %vp6, %vp7]" */
501 { I_VPFXS
, "vpfxs", 0xDC000000, 0xFF000000, "[%vp0, %vp1, %vp2, %vp3]",_C2
}, /* [hlide] added "[%vp0, %vp1, %vp2, %vp3]" */
502 { I_VPFXT
, "vpfxt", 0xDD000000, 0xFF000000, "[%vp0, %vp1, %vp2, %vp3]",_C2
}, /* [hlide] added "[%vp0, %vp1, %vp2, %vp3]" */
503 { I_VQMUL_Q
, "vqmul.q", 0xF2808080, 0xFF808080, "%zq, %yq, %xq", _C2
}, /* [hlide] added "%zq, %yq, %xq" */
504 { I_VRCP_P
, "vrcp.p", 0xD0100080, 0xFFFF8080, "%zp, %yp", _C2
},
505 { I_VRCP_Q
, "vrcp.q", 0xD0108080, 0xFFFF8080, "%zq, %yq", _C2
},
506 { I_VRCP_S
, "vrcp.s", 0xD0100000, 0xFFFF8080, "%zs, %ys", _C2
},
507 { I_VRCP_T
, "vrcp.t", 0xD0108000, 0xFFFF8080, "%zt, %yt", _C2
},
508 { I_VREXP2_P
, "vrexp2.p", 0xD01C0080, 0xFFFF8080, "%zp, %yp", _C2
},
509 { I_VREXP2_Q
, "vrexp2.q", 0xD01C8080, 0xFFFF8080, "%zq, %yq", _C2
},
510 { I_VREXP2_S
, "vrexp2.s", 0xD01C0000, 0xFFFF8080, "%zs, %ys", _C2
},
511 { I_VREXP2_T
, "vrexp2.t", 0xD01C8000, 0xFFFF8080, "%zt, %yt", _C2
},
512 { I_VRNDF1_P
, "vrndf1.p", 0xD0220080, 0xFFFFFF80, "%zp", _C2
},
513 { I_VRNDF1_Q
, "vrndf1.q", 0xD0228080, 0xFFFFFF80, "%zq", _C2
},
514 { I_VRNDF1_S
, "vrndf1.s", 0xD0220000, 0xFFFFFF80, "%zs", _C2
},
515 { I_VRNDF1_T
, "vrndf1.t", 0xD0228000, 0xFFFFFF80, "%zt", _C2
},
516 { I_VRNDF2_P
, "vrndf2.p", 0xD0230080, 0xFFFFFF80, "%zp", _C2
},
517 { I_VRNDF2_Q
, "vrndf2.q", 0xD0238080, 0xFFFFFF80, "%zq", _C2
},
518 { I_VRNDF2_S
, "vrndf2.s", 0xD0230000, 0xFFFFFF80, "%zs", _C2
},
519 { I_VRNDF2_T
, "vrndf2.t", 0xD0238000, 0xFFFFFF80, "%zt", _C2
},
520 { I_VRNDI_P
, "vrndi.p", 0xD0210080, 0xFFFFFF80, "%zp", _C2
},
521 { I_VRNDI_Q
, "vrndi.q", 0xD0218080, 0xFFFFFF80, "%zq", _C2
},
522 { I_VRNDI_S
, "vrndi.s", 0xD0210000, 0xFFFFFF80, "%zs", _C2
},
523 { I_VRNDI_T
, "vrndi.t", 0xD0218000, 0xFFFFFF80, "%zt", _C2
},
524 { I_VRNDS_S
, "vrnds.s", 0xD0200000, 0xFFFF80FF, "%ys", _C2
},
525 { I_VROT_P
, "vrot.p", 0xF3A00080, 0xFFE08080, "%zp, %ys, %vr", _C2
}, /* [hlide] added "%zp, %ys, %vr" */
526 { I_VROT_Q
, "vrot.q", 0xF3A08080, 0xFFE08080, "%zq, %ys, %vr", _C2
}, /* [hlide] added "%zq, %ys, %vr" */
527 { I_VROT_T
, "vrot.t", 0xF3A08000, 0xFFE08080, "%zt, %ys, %vr", _C2
}, /* [hlide] added "%zt, %ys, %vr" */
528 { I_VRSQ_P
, "vrsq.p", 0xD0110080, 0xFFFF8080, "%zp, %yp", _C2
},
529 { I_VRSQ_Q
, "vrsq.q", 0xD0118080, 0xFFFF8080, "%zq, %yq", _C2
},
530 { I_VRSQ_S
, "vrsq.s", 0xD0110000, 0xFFFF8080, "%zs, %ys", _C2
},
531 { I_VRSQ_T
, "vrsq.t", 0xD0118000, 0xFFFF8080, "%zt, %yt", _C2
},
532 { I_VS2I_P
, "vs2i.p", 0xD03B0080, 0xFFFF8080, "%zq, %yp", _C2
}, /* [hlide] %zp -> %zq */
533 { I_VS2I_S
, "vs2i.s", 0xD03B0000, 0xFFFF8080, "%zp, %ys", _C2
}, /* [hlide] %zs -> %zp */
534 { I_VSAT0_P
, "vsat0.p", 0xD0040080, 0xFFFF8080, "%zp, %yp", _C2
},
535 { I_VSAT0_Q
, "vsat0.q", 0xD0048080, 0xFFFF8080, "%zq, %yq", _C2
},
536 { I_VSAT0_S
, "vsat0.s", 0xD0040000, 0xFFFF8080, "%zs, %ys", _C2
},
537 { I_VSAT0_T
, "vsat0.t", 0xD0048000, 0xFFFF8080, "%zt, %yt", _C2
},
538 { I_VSAT1_P
, "vsat1.p", 0xD0050080, 0xFFFF8080, "%zp, %yp", _C2
},
539 { I_VSAT1_Q
, "vsat1.q", 0xD0058080, 0xFFFF8080, "%zq, %yq", _C2
},
540 { I_VSAT1_S
, "vsat1.s", 0xD0050000, 0xFFFF8080, "%zs, %ys", _C2
},
541 { I_VSAT1_T
, "vsat1.t", 0xD0058000, 0xFFFF8080, "%zt, %yt", _C2
},
542 { I_VSBN_S
, "vsbn.s", 0x61000000, 0xFF808080, "%zs, %ys, %xs", _C2
},
543 { I_VSBZ_S
, "vsbz.s", 0xD0360000, 0xFFFF8080, "%zs, %ys", _C2
},
544 { I_VSCL_P
, "vscl.p", 0x65000080, 0xFF808080, "%zp, %yp, %xs", _C2
}, /* [hlide] %xp -> %xs */
545 { I_VSCL_Q
, "vscl.q", 0x65008080, 0xFF808080, "%zq, %yq, %xs", _C2
}, /* [hlide] %xq -> %xs */
546 { I_VSCL_T
, "vscl.t", 0x65008000, 0xFF808080, "%zt, %yt, %xs", _C2
}, /* [hlide] %xt -> %xs */
547 { I_VSCMP_P
, "vscmp.p", 0x6E800080, 0xFF808080, "%zp, %yp, %xp", _C2
},
548 { I_VSCMP_Q
, "vscmp.q", 0x6E808080, 0xFF808080, "%zq, %yq, %xq", _C2
},
549 { I_VSCMP_S
, "vscmp.s", 0x6E800000, 0xFF808080, "%zs, %ys, %xs", _C2
},
550 { I_VSCMP_T
, "vscmp.t", 0x6E808000, 0xFF808080, "%zt, %yt, %xt", _C2
},
551 { I_VSGE_P
, "vsge.p", 0x6F000080, 0xFF808080, "%zp, %yp, %xp", _C2
},
552 { I_VSGE_Q
, "vsge.q", 0x6F008080, 0xFF808080, "%zq, %yq, %xq", _C2
},
553 { I_VSGE_S
, "vsge.s", 0x6F000000, 0xFF808080, "%zs, %ys, %xs", _C2
},
554 { I_VSGE_T
, "vsge.t", 0x6F008000, 0xFF808080, "%zt, %yt, %xt", _C2
},
555 { I_VSGN_P
, "vsgn.p", 0xD04A0080, 0xFFFF8080, "%zp, %yp", _C2
},
556 { I_VSGN_Q
, "vsgn.q", 0xD04A8080, 0xFFFF8080, "%zq, %yq", _C2
},
557 { I_VSGN_S
, "vsgn.s", 0xD04A0000, 0xFFFF8080, "%zs, %ys", _C2
},
558 { I_VSGN_T
, "vsgn.t", 0xD04A8000, 0xFFFF8080, "%zt, %yt", _C2
},
559 { I_VSIN_P
, "vsin.p", 0xD0120080, 0xFFFF8080, "%zp, %yp", _C2
},
560 { I_VSIN_Q
, "vsin.q", 0xD0128080, 0xFFFF8080, "%zq, %yq", _C2
},
561 { I_VSIN_S
, "vsin.s", 0xD0120000, 0xFFFF8080, "%zs, %ys", _C2
},
562 { I_VSIN_T
, "vsin.t", 0xD0128000, 0xFFFF8080, "%zt, %yt", _C2
},
563 { I_VSLT_P
, "vslt.p", 0x6F800080, 0xFF808080, "%zp, %yp, %xp", _C2
},
564 { I_VSLT_Q
, "vslt.q", 0x6F808080, 0xFF808080, "%zq, %yq, %xq", _C2
},
565 { I_VSLT_S
, "vslt.s", 0x6F800000, 0xFF808080, "%zs, %ys, %xs", _C2
},
566 { I_VSLT_T
, "vslt.t", 0x6F808000, 0xFF808080, "%zt, %yt, %xt", _C2
},
567 { I_VSOCP_P
, "vsocp.p", 0xD0450080, 0xFFFF8080, "%zq, %yp", _C2
}, /* [hlide] %zp -> %zq */
568 { I_VSOCP_S
, "vsocp.s", 0xD0450000, 0xFFFF8080, "%zp, %ys", _C2
}, /* [hlide] %zs -> %zp */
569 { I_VSQRT_P
, "vsqrt.p", 0xD0160080, 0xFFFF8080, "%zp, %yp", _C2
},
570 { I_VSQRT_Q
, "vsqrt.q", 0xD0168080, 0xFFFF8080, "%zq, %yq", _C2
},
571 { I_VSQRT_S
, "vsqrt.s", 0xD0160000, 0xFFFF8080, "%zs, %ys", _C2
},
572 { I_VSQRT_T
, "vsqrt.t", 0xD0168000, 0xFFFF8080, "%zt, %yt", _C2
},
573 { I_VSRT1_Q
, "vsrt1.q", 0xD0408080, 0xFFFF8080, "%zq, %yq", _C2
},
574 { I_VSRT2_Q
, "vsrt2.q", 0xD0418080, 0xFFFF8080, "%zq, %yq", _C2
},
575 { I_VSRT3_Q
, "vsrt3.q", 0xD0488080, 0xFFFF8080, "%zq, %yq", _C2
},
576 { I_VSRT4_Q
, "vsrt4.q", 0xD0498080, 0xFFFF8080, "%zq, %yq", _C2
},
577 { I_VSUB_P
, "vsub.p", 0x60800080, 0xFF808080, "%zp, %yp, %xp", _C2
},
578 { I_VSUB_Q
, "vsub.q", 0x60808080, 0xFF808080, "%zq, %yq, %xq", _C2
},
579 { I_VSUB_S
, "vsub.s", 0x60800000, 0xFF808080, "%zs, %ys, %xs", _C2
},
580 { I_VSUB_T
, "vsub.t", 0x60808000, 0xFF808080, "%zt, %yt, %xt", _C2
},
581 { I_VSYNC
, "vsync", 0xFFFF0320, 0xFFFFFFFF, "", _AL
|_C2
},
582 { I_VSYNC
, "vsync", 0xFFFF0000, 0xFFFF0000, "%I", _C2
},
583 { I_VT4444_Q
, "vt4444.q", 0xD0598080, 0xFFFF8080, "%zq, %yq", _C2
}, /* [hlide] %zq -> %zp */
584 { I_VT5551_Q
, "vt5551.q", 0xD05A8080, 0xFFFF8080, "%zq, %yq", _C2
}, /* [hlide] %zq -> %zp */
585 { I_VT5650_Q
, "vt5650.q", 0xD05B8080, 0xFFFF8080, "%zq, %yq", _C2
}, /* [hlide] %zq -> %zp */
586 { I_VTFM2_P
, "vtfm2.p", 0xF0800080, 0xFF808080, "%zp, %ym, %xp", _C2
}, /* [hlide] added "%zp, %ym, %xp" */
587 { I_VTFM3_T
, "vtfm3.t", 0xF1008000, 0xFF808080, "%zt, %yn, %xt", _C2
}, /* [hlide] added "%zt, %yn, %xt" */
588 { I_VTFM4_Q
, "vtfm4.q", 0xF1808080, 0xFF808080, "%zq, %yo, %xq", _C2
}, /* [hlide] added "%zq, %yo, %xq" */
589 { I_VUS2I_P
, "vus2i.p", 0xD03A0080, 0xFFFF8080, "%zq, %yp", _C2
}, /* [hlide] added "%zq, %yp" */
590 { I_VUS2I_S
, "vus2i.s", 0xD03A0000, 0xFFFF8080, "%zp, %ys", _C2
}, /* [hlide] added "%zp, %ys" */
591 { I_VWB_Q
, "vwb.q", 0xF8000002, 0xFC000002, "%Xq, %Y", _RS
|_ST
|_C2
},
592 { I_VWBN_S
, "vwbn.s", 0xD3000000, 0xFF008080, "%zs, %xs, %I", _C2
},
593 { I_VZERO_P
, "vzero.p", 0xD0060080, 0xFFFFFF80, "%zp", _C2
},
594 { I_VZERO_Q
, "vzero.q", 0xD0068080, 0xFFFFFF80, "%zq", _C2
},
595 { I_VZERO_S
, "vzero.s", 0xD0060000, 0xFFFFFF80, "%zs", _C2
},
596 { I_VZERO_T
, "vzero.t", 0xD0068000, 0xFFFFFF80, "%zt", _C2
},
597 { I_MFVME
, "mfvme", 0x68000000, 0xFC000000, "%t, %i", _WT
|_C2
},
598 { I_MTVME
, "mtvme", 0xb0000000, 0xFC000000, "%t, %i", _RT
|_C2
},
601 #define NUM_INSTRUCTIONS (sizeof (instructions) / sizeof (struct allegrex_instruction))
603 static char buffer
[1024];
604 const char *gpr_names
[] =
606 "zr", "at", "v0", "v1", "a0", "a1", "a2", "a3",
607 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
608 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
609 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
612 static const char *cop0_regs
[] =
614 "COP0_0", "COP0_1", "COP0_2", "COP0_3", "COP0_4", "COP0_5", "COP0_6", "COP0_7",
615 "BadVaddr", "Count", "COP0_10", "Compare", "Status", "Cause", "EPC", "PrID",
616 "Config", "COP0_17", "COP0_18", "COP0_19", "COP0_20", "COP0_21", "COP0_22", "COP0_23",
617 "COP0_24", "EBase", "COP0_26", "COP0_27", "TagLo", "TagHi", "ErrorPC", "COP0_31"
621 static const char *debug_regs
[] =
623 "DRCNTL", "DEPC", "DDATA0", "DDATA1", "IBC", "DBC", "Debug06", "Debug07",
624 "IBA", "IBAM", "Debug10", "Debug11", "DBA", "DBAM", "DBD", "DBDM",
625 "Debug16", "Debug17", "Debug18", "Debug19", "Debug20", "Debug21", "Debug22", "Debug23",
626 "Debug24", "Debug25", "Debug26", "Debug27", "Debug28", "Debug29", "Debug30", "Debug31"
629 static const char *vfpu_cond_names
[] =
631 "FL", "EQ", "LT", "LE",
632 "TR", "NE", "GE", "GT",
633 "EZ", "EN", "EI", "ES",
634 "NZ", "NN", "NI", "NS"
637 static const char *vfpu_constants
[] = {
672 static const char *pfx_cst_names
[] =
674 "0", "1", "2", "1/2", "3", "1/3", "1/4", "1/6"
677 static const char *pfx_swz_names
[] =
682 static const char *pfx_sat_names
[] =
684 "", "[0:1]", "", "[-1:1]"
687 /* [hlide] added vfpu_extra_regs */
688 static const char *vfpu_extra_regs
[] =
709 int print_vfpu_single (int reg
, char *output
)
711 return sprintf (output
, "S%d%d%d", (reg
>> 2) & 7, reg
& 3, (reg
>> 5) & 3);
715 int print_vfpu_reg (int reg
, int offset
, char one
, char two
, char *output
)
717 if ((reg
>> 5) & 1) {
718 return sprintf (output
, "%c%d%d%d", two
, (reg
>> 2) & 7, offset
, reg
& 3);
720 return sprintf (output
, "%c%d%d%d", one
, (reg
>> 2) & 7, reg
& 3, offset
);
725 int print_vfpu_quad (int reg
, char *output
)
727 return print_vfpu_reg (reg
, 0, 'C', 'R', output
);
731 int print_vfpu_pair (int reg
, char *output
)
733 if ((reg
>> 6) & 1) {
734 return print_vfpu_reg (reg
, 2, 'C', 'R', output
);
736 return print_vfpu_reg (reg
, 0, 'C', 'R', output
);
741 int print_vfpu_triple (int reg
, char *output
)
743 if ((reg
>> 6) & 1) {
744 return print_vfpu_reg (reg
, 1, 'C', 'R', output
);
746 return print_vfpu_reg (reg
, 0, 'C', 'R', output
);
751 int print_vfpu_mpair (int reg
, char *output
)
753 if ((reg
>> 6) & 1) {
754 return print_vfpu_reg (reg
, 2, 'M', 'E', output
);
756 return print_vfpu_reg (reg
, 0, 'M', 'E', output
);
761 int print_vfpu_mtriple (int reg
, char *output
)
763 if ((reg
>> 6) & 1) {
764 return print_vfpu_reg (reg
, 1, 'M', 'E', output
);
766 return print_vfpu_reg (reg
, 0, 'M', 'E', output
);
771 int print_vfpu_matrix (int reg
, char *output
)
773 return print_vfpu_reg (reg
, 0, 'M', 'E', output
);
777 int print_vfpu_register (int reg
, char type
, char *output
)
780 case 's': return print_vfpu_single (reg
, output
);
781 case 'q': return print_vfpu_quad (reg
, output
);
782 case 'p': return print_vfpu_pair (reg
, output
);
783 case 't': return print_vfpu_triple (reg
, output
);
784 case 'm': return print_vfpu_mpair (reg
, output
);
785 case 'n': return print_vfpu_mtriple (reg
, output
);
786 case 'o': return print_vfpu_matrix (reg
, output
);
793 int print_vfpu_halffloat (int l
, char *output
)
795 unsigned short float16
= l
& 0xFFFF;
796 unsigned int sign
= (float16
>> VFPU_SH_FLOAT16_SIGN
) & VFPU_MASK_FLOAT16_SIGN
;
797 int exponent
= (float16
>> VFPU_SH_FLOAT16_EXP
) & VFPU_MASK_FLOAT16_EXP
;
798 unsigned int fraction
= float16
& VFPU_MASK_FLOAT16_FRAC
;
799 char signchar
= '+' + ((sign
== 1) * 2);
801 /* Convert a VFPU 16-bit floating-point number to IEEE754. */
808 if (exponent
== VFPU_FLOAT16_EXP_MAX
) {
810 len
= sprintf (output
, "%cInf", signchar
);
812 len
= sprintf (output
, "%cNaN", signchar
);
813 } else if (exponent
== 0 && fraction
== 0) {
814 len
= sprintf (output
, "%c0", signchar
);
820 } while (!(fraction
& (VFPU_MASK_FLOAT16_FRAC
+ 1)));
822 fraction
&= VFPU_MASK_FLOAT16_FRAC
;
825 /* Convert to 32-bit single-precision IEEE754. */
826 float2int
.i
= sign
<< 31;
827 float2int
.i
|= (exponent
+ 112) << 23;
828 float2int
.i
|= fraction
<< 13;
829 len
= sprintf (output
, "%g", float2int
.f
);
835 /* [hlide] added print_vfpu_prefix */
837 int print_vfpu_prefix (int l
, unsigned int pos
, char *output
)
848 unsigned int base
= '0';
849 unsigned int negation
= (l
>> (pos
- (base
- VFPU_SH_PFX_NEG
))) & VFPU_MASK_PFX_NEG
;
850 unsigned int constant
= (l
>> (pos
- (base
- VFPU_SH_PFX_CST
))) & VFPU_MASK_PFX_CST
;
851 unsigned int abs_consthi
= (l
>> (pos
- (base
- VFPU_SH_PFX_ABS_CSTHI
))) & VFPU_MASK_PFX_ABS_CSTHI
;
852 unsigned int swz_constlo
= (l
>> ((pos
- base
) * 2)) & VFPU_MASK_PFX_SWZ_CSTLO
;
855 len
= sprintf (output
, "-");
857 len
+= sprintf (output
+ len
, "%s", pfx_cst_names
[(abs_consthi
<< 2) | swz_constlo
]);
860 len
+= sprintf (output
+ len
, "|%s|", pfx_swz_names
[swz_constlo
]);
862 len
+= sprintf (output
+ len
, "%s", pfx_swz_names
[swz_constlo
]);
872 unsigned int base
= '4';
873 unsigned int mask
= (l
>> (pos
- (base
- VFPU_SH_PFX_MASK
))) & VFPU_MASK_PFX_MASK
;
874 unsigned int saturation
= (l
>> ((pos
- base
) * 2)) & VFPU_MASK_PFX_SAT
;
877 len
+= sprintf (output
, "m");
879 len
+= sprintf (output
, "%s", pfx_sat_names
[saturation
]);
889 int print_vfpu_rotator (int l
, char *output
)
893 const char *elements
[4];
895 unsigned int opcode
= l
& VFPU_MASK_OP_SIZE
;
896 unsigned int rotators
= (l
>> 16) & 0x1f;
897 unsigned int opsize
, rothi
, rotlo
, negation
, i
;
899 /* Determine the operand size so we'll know how many elements to output. */
900 if (opcode
== VFPU_OP_SIZE_PAIR
)
902 else if (opcode
== VFPU_OP_SIZE_TRIPLE
)
905 opsize
= (opcode
== VFPU_OP_SIZE_QUAD
) * 4; /* Sanity check. */
907 rothi
= (rotators
>> VFPU_SH_ROT_HI
) & VFPU_MASK_ROT_HI
;
908 rotlo
= (rotators
>> VFPU_SH_ROT_LO
) & VFPU_MASK_ROT_LO
;
909 negation
= (rotators
>> VFPU_SH_ROT_NEG
) & VFPU_MASK_ROT_NEG
;
911 if (rothi
== rotlo
) {
930 elements
[rothi
] = "-s";
932 elements
[rothi
] = "s";
933 elements
[rotlo
] = "c";
935 len
= sprintf (output
, "[");
937 len
+= sprintf (output
+ len
, "%s", elements
[i
++]);
940 sprintf (output
+ len
, " ,");
943 len
+= sprintf (output
+ len
, "]");
948 /* [hlide] added print_cop2 */
950 int print_cop2 (int reg
, char *output
)
954 if ((reg
>= 128) && (reg
< 128+16) && (vfpu_extra_regs
[reg
- 128])) {
955 len
= sprintf (output
, "%s", vfpu_extra_regs
[reg
- 128]);
957 len
= sprintf (output
, "VFPU_COP2_%d", reg
);
965 void print_instruction (const struct allegrex_instruction
*insn
, unsigned int opcode
, unsigned int PC
, int prtall
)
967 int i
= 0, len
= 0, vmmul
= 0;
968 unsigned int data
= opcode
;
971 len
+= sprintf (buffer
, "0x%08X: 0x%08X '", PC
, opcode
);
972 for (i
= 0; i
< 4; i
++) {
973 char c
= (char) (data
& 0xFF);
974 if (isprint (c
)) { len
+= sprintf (&buffer
[len
], "%c", c
); }
975 else { len
+= sprintf (&buffer
[len
], "."); }
978 len
+= sprintf (&buffer
[len
], "' - ");
981 sprintf (&buffer
[len
], "Invalid");
984 len
+= sprintf (&buffer
[len
], "%-10s ", insn
->name
);
988 char c
= insn
->fmt
[i
++];
989 if (c
== '\0') break;
994 len
+= sprintf (&buffer
[len
], "$%s", gpr_names
[RD (opcode
)]);
997 len
+= sprintf (&buffer
[len
], "$fpr%02d", FD (opcode
));
1000 len
+= sprintf (&buffer
[len
], "$%s", gpr_names
[RT (opcode
)]);
1003 len
+= sprintf (&buffer
[len
], "$fpr%02d", FT (opcode
));
1006 len
+= sprintf (&buffer
[len
], "$%s", gpr_names
[RS (opcode
)]);
1009 len
+= sprintf (&buffer
[len
], "$fpr%02d", FS (opcode
));
1012 len
+= sprintf (&buffer
[len
], "$%s", gpr_names
[RS (opcode
)]);
1015 len
+= sprintf (&buffer
[len
], "%d", IMM (opcode
));
1018 len
+= sprintf (&buffer
[len
], "0x%04X", IMMU (opcode
));
1021 len
+= sprintf (&buffer
[len
], "0x%08X", JUMP (opcode
, PC
));
1024 len
+= sprintf (&buffer
[len
], "0x%08X", PC
+ 4 + 4 * ((int) IMM (opcode
)));
1027 len
+= sprintf (&buffer
[len
], "%d($%s)", IMM (opcode
), gpr_names
[RS (opcode
)]);
1030 if (CODE(opcode
) != 0)
1031 len
+= sprintf (&buffer
[len
], "0x%05X", CODE (opcode
));
1034 len
+= sprintf (&buffer
[len
], "0x%X", RT (opcode
));
1037 len
+= sprintf (&buffer
[len
], "$%d", RD (opcode
));
1040 len
+= sprintf (&buffer
[len
], "%d", SA (opcode
));
1043 len
+= sprintf (&buffer
[len
], "%s", debug_regs
[RD (opcode
)]);
1046 len
+= sprintf (&buffer
[len
], "%s", cop0_regs
[RD (opcode
)]);
1049 len
+= sprintf (&buffer
[len
], "$fpr%d", RD (opcode
));
1054 len
+= print_cop2 (VED (opcode
), &buffer
[len
]);
1056 len
+= print_cop2 (VES (opcode
), &buffer
[len
]);
1061 len
+= print_vfpu_register (VD (opcode
), c
, &buffer
[len
]);
1066 len
+= sprintf (&buffer
[len
], "%d", VCC (opcode
));
1068 len
+= sprintf (&buffer
[len
], "%s", vfpu_cond_names
[VCN (opcode
)]);
1074 len
+= sprintf (&buffer
[len
], "%d", RD (opcode
) + 1);
1076 len
+= sprintf (&buffer
[len
], "%d", RD (opcode
) - SA (opcode
) + 1);
1081 len
+= print_vfpu_register (VO (opcode
), c
, &buffer
[len
]);
1085 len
+= print_vfpu_register (VT (opcode
), c
, &buffer
[len
]);
1088 len
+= sprintf (&buffer
[len
], "%d($%s)", IMM (opcode
) & ~3, gpr_names
[RS (opcode
)]);
1092 int reg
= VS (opcode
);
1093 if (vmmul
) { if (reg
& 0x20) { reg
&= 0x5F; } else { reg
|= 0x20; } }
1095 len
+= print_vfpu_register (reg
, c
, &buffer
[len
]);
1101 case '3' : len
+= sprintf (&buffer
[len
], "%d", VI3 (opcode
)); break;
1102 case '5' : len
+= sprintf (&buffer
[len
], "%d", VI5 (opcode
)); break;
1103 case '8' : len
+= sprintf (&buffer
[len
], "%d", VI8 (opcode
)); break;
1104 case 'k' : len
+= sprintf (&buffer
[len
], "%s", vfpu_constants
[VI5 (opcode
)]); break;
1105 case 'i' : len
+= sprintf (&buffer
[len
], "%d", IMM (opcode
)); break;
1106 case 'h' : len
+= print_vfpu_halffloat (opcode
, &buffer
[len
]); break;
1107 case 'r' : len
+= print_vfpu_rotator (opcode
, &buffer
[len
]); break;
1108 case 'p' : c
= insn
->fmt
[i
++]; len
+= print_vfpu_prefix (opcode
, c
, &buffer
[len
]); break;
1116 len
+= sprintf (&buffer
[len
], "%c", c
);
1119 while (buffer
[len
-1] == ' ' && len
> 0) len
--;
1124 const struct allegrex_instruction
*allegrex_decode (unsigned int opcode
, int allowalias
)
1128 for (i
= 0; i
< sizeof (instructions
) / sizeof (struct allegrex_instruction
); i
++) {
1129 printf ("Scanning %s 0x%08X 0x%08X\n", instructions
[i
].name
, instructions
[i
].mask
& opcode
, instructions
[i
].opcode
);
1130 if ((instructions
[i
].mask
& opcode
) == instructions
[i
].opcode
) {
1131 if (allowalias
|| !(instructions
[i
].flags
& INSN_ALIAS
))
1132 return &instructions
[i
];
1138 #else /* !SLOW_VERSION */
1140 #include "allefast.c"
1142 const struct allegrex_instruction
*allegrex_decode (unsigned int opcode
, int allowalias
)
1149 struct disasm_command
*cmd
= &command
[cmdpos
];
1150 switch (cmd
->type
) {
1153 if ((cmd
->param2
& opcode
) == cmd
->param1
) {
1154 if (allowalias
|| !(instructions
[cmd
->param3
].flags
& INSN_ALIAS
))
1155 return &instructions
[cmd
->param3
];
1157 if (cmd
->type
== COMMAND_TEST
) {
1165 temp
= (opcode
>> cmd
->param1
) & cmd
->param2
;
1166 cmdpos
= arrayidx
[cmd
->param3
+ temp
];
1167 if (cmdpos
== -1) return NULL
;
1169 case COMMAND_BSEARCH
:
1172 temp
= opcode
& cmd
->param3
;
1173 while (high
>= low
) {
1174 pos
= (low
+ high
) / 2;
1175 if (bsidx
[pos
].opcode
== temp
) {
1176 cmdpos
= bsidx
[pos
].index
;
1178 } else if (bsidx
[pos
].opcode
> temp
) {
1184 if (high
< low
) return NULL
;
1190 #endif /* !SLOW_VERSION */
1192 char *allegrex_disassemble (unsigned int opcode
, unsigned int PC
, int prtall
)
1194 const struct allegrex_instruction
*insn
= allegrex_decode (opcode
, 1);
1195 print_instruction (insn
, opcode
, PC
, prtall
);
1196 return (char *) buffer
;
1199 #ifdef TEST_DISASSEMBLE
1203 int main (int argc
, char **argv
)
1207 for (i
= 0; i
< NUM_INSTRUCTIONS
; i
++) {
1208 unsigned int opcode
= rand ();
1209 opcode
= (opcode
& (~instructions
[i
].mask
)) | instructions
[i
].opcode
;
1210 printf ("%s\n", allegrex_disassemble (opcode
, 4 * i
, 1));
1216 #endif /* TEST_DISASSEMBLE */
1222 static unsigned int cmp_mask
;
1223 static struct allegrex_instruction _instructions
[NUM_INSTRUCTIONS
];
1224 static int _arrayidx_pos
, _bsidx_pos
, _command_pos
;
1225 static struct disasm_command _command
[1024];
1226 static struct bsearch_index _bsidx
[1024];
1227 static int _arrayidx
[1024];
1228 static int max_cmd_count
;
1230 int cmp_func (const void *p1
, const void *p2
)
1232 const struct allegrex_instruction
*i1
= p1
;
1233 const struct allegrex_instruction
*i2
= p2
;
1235 if ((i1
->opcode
& cmp_mask
) > (i2
->opcode
& cmp_mask
)) return 1;
1236 if ((i1
->opcode
& cmp_mask
) < (i2
->opcode
& cmp_mask
)) return -11;
1237 if ((i1
->insn
) > (i2
->insn
)) return 1;
1238 if ((i1
->insn
) < (i2
->insn
)) return -1;
1239 if ((i1
->mask
) > (i2
->mask
)) return 1;
1240 if ((i1
->mask
) > (i2
->mask
)) return -1;
1244 void sort (int bpos
, int epos
, unsigned int oldmask
, int cmdcount
)
1246 int i
, j
, numgroups
;
1247 unsigned int temp
, mask
;
1250 for (i
= bpos
; i
< epos
; i
++) {
1251 cmp_mask
&= _instructions
[i
].mask
;
1254 qsort (&_instructions
[bpos
], epos
- bpos
, sizeof (struct allegrex_instruction
), &cmp_func
);
1257 temp
= _instructions
[bpos
].opcode
& mask
;
1258 for (i
= bpos
; i
< epos
; i
++) {
1259 if ((_instructions
[i
].opcode
& mask
) != temp
) {
1260 temp
= _instructions
[i
].opcode
& mask
;
1265 if (numgroups
== 1) {
1266 for (i
= bpos
; i
< epos
; i
++) {
1267 _command
[_command_pos
].type
= (i
== (epos
- 1)) ? COMMAND_END
: COMMAND_TEST
;
1268 _command
[_command_pos
].param1
= _instructions
[i
].opcode
;
1269 _command
[_command_pos
].param2
= _instructions
[i
].mask
;
1270 _command
[_command_pos
].param3
= _instructions
[i
].insn
;
1273 cmdcount
+= epos
- bpos
;
1275 unsigned int shift
= 0, nbits
= 0, bits
= 0;
1276 temp
= mask
^ oldmask
;
1278 while ((temp
& 0x01) == 0) {
1279 shift
++; temp
>>= 1;
1281 while ((temp
& 0x01) == 1) {
1282 nbits
++; temp
>>= 1;
1285 if (temp
== 0 && nbits
<= 6) {
1286 int arraypos
= _arrayidx_pos
;
1287 bits
= (1 << nbits
) - 1;
1288 _arrayidx_pos
+= (1 << nbits
);
1289 for (i
= arraypos
; i
< _arrayidx_pos
; i
++)
1291 _command
[_command_pos
].type
= COMMAND_INDEX
;
1292 _command
[_command_pos
].param1
= shift
;
1293 _command
[_command_pos
].param2
= bits
;
1294 _command
[_command_pos
].param3
= arraypos
;
1298 temp
= _instructions
[bpos
].opcode
& mask
;
1299 for (i
= j
= bpos
; i
< epos
; i
++) {
1300 if ((_instructions
[i
].opcode
& mask
) != temp
) {
1301 _arrayidx
[arraypos
+ ((temp
>> shift
) & bits
)] = _command_pos
;
1302 sort (j
, i
, mask
, cmdcount
);
1304 j
= i
; temp
= _instructions
[i
].opcode
& mask
;
1307 _arrayidx
[arraypos
+ ((temp
>> shift
) & bits
)] = _command_pos
;
1308 sort (j
, i
, mask
, cmdcount
);
1311 int bsearchpos
= _bsidx_pos
;
1312 _bsidx_pos
+= numgroups
;
1313 _command
[_command_pos
].type
= COMMAND_BSEARCH
;
1314 _command
[_command_pos
].param1
= bsearchpos
;
1315 _command
[_command_pos
].param2
= _bsidx_pos
- 1;
1316 _command
[_command_pos
].param3
= mask
;
1326 temp
= _instructions
[bpos
].opcode
& mask
;
1327 for (i
= j
= bpos
; i
< epos
; i
++) {
1328 if ((_instructions
[i
].opcode
& mask
) != temp
) {
1329 _bsidx
[bsearchpos
].index
= _command_pos
;
1330 _bsidx
[bsearchpos
++].opcode
= temp
;
1331 sort (j
, i
, mask
, cmdcount
);
1333 j
= i
; temp
= _instructions
[i
].opcode
& mask
;
1336 _bsidx
[bsearchpos
].index
= _command_pos
;
1337 _bsidx
[bsearchpos
++].opcode
= temp
;
1338 sort (j
, i
, mask
, cmdcount
);
1342 if (cmdcount
> max_cmd_count
)
1343 max_cmd_count
= cmdcount
;
1347 int main (int argc
, char **argv
)
1351 for (i
= 0; i
< NUM_INSTRUCTIONS
; i
++) {
1352 _instructions
[i
] = instructions
[i
];
1353 _instructions
[i
].insn
= i
;
1356 sort (0, NUM_INSTRUCTIONS
, 0, 0);
1357 fprintf (stderr
, "max_cmd_count = %d\n", max_cmd_count
);
1358 fprintf (stderr
, "_arrayidx_pos = %d, _bsidx_pos = %d, _command_pos = %d\n",
1359 _arrayidx_pos
, _bsidx_pos
, _command_pos
);
1362 printf ("static int arrayidx[] = {\n");
1363 for (i
= 0; i
< _arrayidx_pos
; i
++) {
1364 printf (" %d", _arrayidx
[i
]);
1365 if (i
!= (_arrayidx_pos
- 1)) printf (",");
1370 printf ("static struct bsearch_index bsidx[] = {\n");
1371 for (i
= 0; i
< _bsidx_pos
; i
++) {
1372 printf (" { %8d, 0x%08X }", _bsidx
[i
].index
, _bsidx
[i
].opcode
);
1373 if (i
!= (_bsidx_pos
- 1)) printf (",");
1378 printf ("static struct disasm_command command[] = {\n");
1379 for (i
= 0; i
< _command_pos
; i
++) {
1380 switch (_command
[i
].type
) {
1381 case COMMAND_BSEARCH
:
1382 printf (" { COMMAND_BSEARCH, %10d, %10d, 0x%08X }",
1383 _command
[i
].param1
, _command
[i
].param2
, _command
[i
].param3
);
1386 printf (" { COMMAND_INDEX, %10d, 0x%08X, %-10d }",
1387 _command
[i
].param1
, _command
[i
].param2
, _command
[i
].param3
);
1390 printf (" { COMMAND_TEST, 0x%08X, 0x%08X, %-10d }",
1391 _command
[i
].param1
, _command
[i
].param2
, _command
[i
].param3
);
1394 printf (" { COMMAND_END, 0x%08X, 0x%08X, %-10d }",
1395 _command
[i
].param1
, _command
[i
].param2
, _command
[i
].param3
);
1398 if (i
!= (_command_pos
- 1)) printf (",");
1407 #endif /* MAKE_INDEX */