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