1 // Copyright (c) 2012- PPSSPP Project.
2 
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0 or later versions.
6 
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 // GNU General Public License 2.0 for more details.
11 
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
14 
15 // Official git repository and contact information can be found at
16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17 
18 #include "Core/Core.h"
19 #include "Core/System.h"
20 #include "Core/MemMap.h"
21 #include "Core/MIPS/MIPS.h"
22 #include "Core/MIPS/MIPSDis.h"
23 #include "Core/MIPS/MIPSDisVFPU.h"
24 #include "Core/MIPS/MIPSInt.h"
25 #include "Core/MIPS/MIPSIntVFPU.h"
26 #include "Core/MIPS/MIPSCodeUtils.h"
27 #include "Core/MIPS/MIPSTables.h"
28 #include "Core/CoreTiming.h"
29 #include "Core/Reporting.h"
30 #include "Core/Debugger/Breakpoints.h"
31 
32 #include "JitCommon/JitCommon.h"
33 
34 enum MipsEncoding {
35 	Imme,
36 	Spec,
37 	Spe2,
38 	Spe3,
39 	RegI,
40 	Cop0,
41 	Cop0CO,
42 	Cop1,
43 	Cop1BC,
44 	Cop1S,
45 	Cop1W,
46 	Cop2,
47 	Cop2BC2,
48 	Cop2Rese,
49 	VFPU0,
50 	VFPU1,
51 	VFPU3,
52 	VFPU4Jump,
53 	VFPU7,
54 	VFPU4,
55 	VFPU5,
56 	VFPU6,
57 	VFPUMatrix1,
58 	VFPU9,
59 	ALLEGREX0,
60 	Emu,
61 	Rese,
62 	NumEncodings,
63 
64 	Instruc = -1,
65 	Inval = -2,
66 };
67 
68 struct MIPSInstruction {
69 	MipsEncoding altEncoding;
70 	const char *name;
71 	MIPSComp::MIPSCompileFunc compile;
72 	MIPSDisFunc disasm;
73 	MIPSInterpretFunc interpret;
74 	//MIPSInstructionInfo information;
75 	MIPSInfo flags;
76 };
77 
78 #define INVALID {Inval}
79 #define INVALID_X_8 INVALID,INVALID,INVALID,INVALID,INVALID,INVALID,INVALID,INVALID
80 
81 #define ENCODING(a) {a}
82 #define INSTR(name, comp, dis, inter, flags) {Instruc, name, comp, dis, inter, MIPSInfo(flags)}
83 
84 #define JITFUNC(f) (&MIPSFrontendInterface::f)
85 
86 using namespace MIPSDis;
87 using namespace MIPSInt;
88 using namespace MIPSComp;
89 
90 // %s/&Jit::\(.\{-}\),/JITFUNC(\1),/g
91 
92 // regregreg instructions
93 const MIPSInstruction tableImmediate[64] = // xxxxxx ..... ..... ................
94 {
95 	//0
96 	ENCODING(Spec),
97 	ENCODING(RegI),
98 	INSTR("j",    JITFUNC(Comp_Jump), Dis_JumpType, Int_JumpType, IS_JUMP|IN_IMM26|DELAYSLOT),
99 	INSTR("jal",  JITFUNC(Comp_Jump), Dis_JumpType, Int_JumpType, IS_JUMP|IN_IMM26|OUT_RA|DELAYSLOT),
100 	INSTR("beq",  JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|CONDTYPE_EQ),
101 	INSTR("bne",  JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|CONDTYPE_NE),
102 	INSTR("blez", JITFUNC(Comp_RelBranch), Dis_RelBranch,  Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_LEZ),
103 	INSTR("bgtz", JITFUNC(Comp_RelBranch), Dis_RelBranch,  Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_GTZ),
104 	//8
105 	INSTR("addi",  JITFUNC(Comp_IType), Dis_addi,   Int_IType, IN_RS|IN_IMM16|OUT_RT),
106 	INSTR("addiu", JITFUNC(Comp_IType), Dis_addi,   Int_IType, IN_RS|IN_IMM16|OUT_RT),
107 	INSTR("slti",  JITFUNC(Comp_IType), Dis_IType,  Int_IType, IN_RS|IN_IMM16|OUT_RT),
108 	INSTR("sltiu", JITFUNC(Comp_IType), Dis_IType,  Int_IType, IN_RS|IN_IMM16|OUT_RT),
109 	INSTR("andi",  JITFUNC(Comp_IType), Dis_IType,  Int_IType, IN_RS|IN_IMM16|OUT_RT),
110 	INSTR("ori",   JITFUNC(Comp_IType), Dis_ori,    Int_IType, IN_RS|IN_IMM16|OUT_RT),
111 	INSTR("xori",  JITFUNC(Comp_IType), Dis_IType,  Int_IType, IN_RS|IN_IMM16|OUT_RT),
112 	INSTR("lui",   JITFUNC(Comp_IType), Dis_IType1, Int_IType, IN_IMM16|OUT_RT),
113 	//16
114 	ENCODING(Cop0), //cop0
115 	ENCODING(Cop1), //cop1
116 	ENCODING(Cop2), //cop2
117 	INVALID, //copU
118 
119 	INSTR("beql",  JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|LIKELY|CONDTYPE_EQ), //L = likely
120 	INSTR("bnel",  JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|LIKELY|CONDTYPE_NE),
121 	INSTR("blezl", JITFUNC(Comp_RelBranch), Dis_RelBranch,  Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_LEZ),
122 	INSTR("bgtzl", JITFUNC(Comp_RelBranch), Dis_RelBranch,  Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_GTZ),
123 	//24
124 	ENCODING(VFPU0),
125 	ENCODING(VFPU1),
126 	ENCODING(Emu),
127 	ENCODING(VFPU3),
128 	ENCODING(Spe2), //special2
129 	INVALID,
130 	INVALID,
131 	ENCODING(Spe3), //special3
132 	//32
133 	INSTR("lb",  JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_BYTE),
134 	INSTR("lh",  JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_HWORD),
135 	INSTR("lwl", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|IN_RT|OUT_RT|MEMTYPE_WORD),
136 	INSTR("lw",  JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_WORD),
137 	INSTR("lbu", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_BYTE),
138 	INSTR("lhu", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_HWORD),
139 	INSTR("lwr", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|IN_RT|OUT_RT|MEMTYPE_WORD),
140 	INVALID,
141 	//40
142 	INSTR("sb",  JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_BYTE),
143 	INSTR("sh",  JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_HWORD),
144 	INSTR("swl", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),
145 	INSTR("sw",  JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),
146 	INVALID,
147 	INVALID,
148 	INSTR("swr", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),
149 	INSTR("cache", JITFUNC(Comp_Cache), Dis_Cache, Int_Cache, IN_MEM|IN_IMM16|IN_RS_ADDR),
150 	//48
151 	INSTR("ll", JITFUNC(Comp_Generic), Dis_Generic, Int_StoreSync, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|OUT_OTHER|MEMTYPE_WORD),
152 	INSTR("lwc1", JITFUNC(Comp_FPULS), Dis_FPULS, Int_FPULS, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_FT|MEMTYPE_FLOAT|IS_FPU),
153 	INSTR("lv.s", JITFUNC(Comp_SV), Dis_SV, Int_SV, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_OTHER|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_FLOAT),
154 	INVALID,
155 	ENCODING(VFPU4Jump),
156 	INSTR("lv", JITFUNC(Comp_SVQ), Dis_SVLRQ, Int_SVQ, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_OTHER|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_VQUAD),
157 	INSTR("lv.q", JITFUNC(Comp_SVQ), Dis_SVQ, Int_SVQ, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_OTHER|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_VQUAD), //copU
158 	ENCODING(VFPU5),
159 	//56
160 	INSTR("sc", JITFUNC(Comp_Generic), Dis_Generic, Int_StoreSync, IN_IMM16|IN_RS_ADDR|IN_OTHER|IN_RT|OUT_RT|OUT_MEM|MEMTYPE_WORD),
161 	INSTR("swc1", JITFUNC(Comp_FPULS), Dis_FPULS, Int_FPULS, IN_IMM16|IN_RS_ADDR|IN_FT|OUT_MEM|MEMTYPE_FLOAT|IS_FPU), //copU
162 	INSTR("sv.s", JITFUNC(Comp_SV), Dis_SV, Int_SV, IN_IMM16|IN_RS_ADDR|IN_OTHER|OUT_MEM|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_FLOAT),
163 	INVALID,
164 	//60
165 	ENCODING(VFPU6),
166 	INSTR("sv", JITFUNC(Comp_SVQ), Dis_SVLRQ, Int_SVQ, IN_IMM16|IN_RS_ADDR|IN_OTHER|OUT_MEM|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_VQUAD), //copU
167 	INSTR("sv.q", JITFUNC(Comp_SVQ), Dis_SVQ, Int_SVQ, IN_IMM16|IN_RS_ADDR|IN_OTHER|OUT_MEM|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_VQUAD),
168 	// Some call this VFPU7 (vflush/vnop/vsync), but it's not super important.
169 	INSTR("vflush", JITFUNC(Comp_DoNothing), Dis_Vflush, Int_Vflush, IS_VFPU|VFPU_NO_PREFIX),
170 };
171 
172 const MIPSInstruction tableSpecial[64] = // 000000 ..... ..... ..... ..... xxxxxx
173 {
174 	INSTR("sll",   JITFUNC(Comp_ShiftType), Dis_ShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_SA),
175 	INVALID,  // copu
176 
177 	INSTR("srl",   JITFUNC(Comp_ShiftType), Dis_ShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_SA),
178 	INSTR("sra",   JITFUNC(Comp_ShiftType), Dis_ShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_SA),
179 	INSTR("sllv",  JITFUNC(Comp_ShiftType), Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),
180 	INVALID,
181 	INSTR("srlv",  JITFUNC(Comp_ShiftType), Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),
182 	INSTR("srav",  JITFUNC(Comp_ShiftType), Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),
183 
184 	//8
185 	INSTR("jr",    JITFUNC(Comp_JumpReg), Dis_JumpRegType, Int_JumpRegType, IS_JUMP|IN_RS|DELAYSLOT),
186 	INSTR("jalr",  JITFUNC(Comp_JumpReg), Dis_JumpRegType, Int_JumpRegType, IS_JUMP|IN_RS|OUT_RD|DELAYSLOT),
187 	INSTR("movz",  JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT|IS_CONDMOVE|CONDTYPE_EQ),
188 	INSTR("movn",  JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT|IS_CONDMOVE|CONDTYPE_NE),
189 	INSTR("syscall", JITFUNC(Comp_Syscall), Dis_Syscall, Int_Syscall, IN_MEM|IN_OTHER|OUT_MEM|OUT_OTHER),
190 	INSTR("break", JITFUNC(Comp_Break), Dis_Generic, Int_Break, 0),
191 	INVALID,
192 	INSTR("sync",  JITFUNC(Comp_DoNothing), Dis_Generic, Int_Sync, 0),
193 
194 	//16
195 	INSTR("mfhi",  JITFUNC(Comp_MulDivType), Dis_FromHiloTransfer, Int_MulDivType, OUT_RD|IN_HI),
196 	INSTR("mthi",  JITFUNC(Comp_MulDivType), Dis_ToHiloTransfer,   Int_MulDivType, IN_RS|OUT_HI),
197 	INSTR("mflo",  JITFUNC(Comp_MulDivType), Dis_FromHiloTransfer, Int_MulDivType, OUT_RD|IN_LO),
198 	INSTR("mtlo",  JITFUNC(Comp_MulDivType), Dis_ToHiloTransfer,   Int_MulDivType, IN_RS|OUT_LO),
199 	INVALID,
200 	INVALID,
201 	INSTR("clz",   JITFUNC(Comp_RType2), Dis_RType2, Int_RType2, OUT_RD|IN_RS),
202 	INSTR("clo",   JITFUNC(Comp_RType2), Dis_RType2, Int_RType2, OUT_RD|IN_RS),
203 
204 	//24
205 	INSTR("mult",  JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),
206 	INSTR("multu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),
207 	INSTR("div",   JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),
208 	INSTR("divu",  JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),
209 	INSTR("madd",  JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),
210 	INSTR("maddu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),
211 	INVALID,
212 	INVALID,
213 
214 	//32
215 	INSTR("add",  JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
216 	INSTR("addu", JITFUNC(Comp_RType3), Dis_addu,   Int_RType3, IN_RS|IN_RT|OUT_RD),
217 	INSTR("sub",  JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
218 	INSTR("subu", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
219 	INSTR("and",  JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
220 	INSTR("or",   JITFUNC(Comp_RType3), Dis_addu,   Int_RType3, IN_RS|IN_RT|OUT_RD),
221 	INSTR("xor",  JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
222 	INSTR("nor",  JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
223 
224 	//40
225 	INVALID,
226 	INVALID,
227 	INSTR("slt",  JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
228 	INSTR("sltu", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
229 	INSTR("max",  JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
230 	INSTR("min",  JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
231 	INSTR("msub",  JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),
232 	INSTR("msubu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),
233 
234 	//48
235 	INSTR("tge",  JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
236 	INSTR("tgeu", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
237 	INSTR("tlt",  JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
238 	INSTR("tltu", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
239 	INSTR("teq",  JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
240 	INVALID,
241 	INSTR("tne",  JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
242 	INVALID,
243 
244 	//56
245 	INVALID_X_8,
246 };
247 
248 // Theoretically should not hit these.
249 const MIPSInstruction tableSpecial2[64] = // 011100 ..... ..... ..... ..... xxxxxx
250 {
251 	INSTR("halt", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
252 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
253 	//8
254 	INVALID_X_8,
255 	INVALID_X_8,
256 	INVALID_X_8,
257 	//32
258 	INVALID, INVALID, INVALID, INVALID,
259 	INSTR("mfic", JITFUNC(Comp_Generic), Dis_Generic, Int_Special2, OUT_OTHER),
260 	INVALID,
261 	INSTR("mtic", JITFUNC(Comp_Generic), Dis_Generic, Int_Special2, OUT_OTHER),
262 	INVALID,
263 	//40
264 	INVALID_X_8,
265 	INVALID_X_8,
266 	INVALID_X_8,
267 };
268 
269 const MIPSInstruction tableSpecial3[64] = // 011111 ..... ..... ..... ..... xxxxxx
270 {
271 	INSTR("ext", JITFUNC(Comp_Special3), Dis_Special3, Int_Special3, IN_RS|OUT_RT),
272 	INVALID,
273 	INVALID,
274 	INVALID,
275 	INSTR("ins", JITFUNC(Comp_Special3), Dis_Special3, Int_Special3, IN_RS|IN_RT|OUT_RT),
276 	INVALID,
277 	INVALID,
278 	INVALID,
279 	//8
280 	INVALID_X_8,
281 	//16
282 	INVALID_X_8,
283 	//24
284 	// TODO: Is this right?  Or should it only be 32?  Comment above (24) was mistakenly 32 before.
285 	ENCODING(ALLEGREX0),
286 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
287 	//32
288 	ENCODING(ALLEGREX0),
289 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
290 	//40
291 	INVALID_X_8,
292 	INVALID_X_8,
293 	//56
294 	INVALID, INVALID, INVALID,
295 	INSTR("rdhwr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
296 	INVALID, INVALID, INVALID, INVALID,
297 };
298 
299 const MIPSInstruction tableRegImm[32] = // 000001 ..... xxxxx ................
300 {
301 	INSTR("bltz",  JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_LTZ),
302 	INSTR("bgez",  JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_GEZ),
303 	INSTR("bltzl", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_LTZ),
304 	INSTR("bgezl", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_GEZ),
305 	INVALID,
306 	INVALID,
307 	INVALID,
308 	INVALID,
309 	//8
310 	INSTR("tgei",  JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
311 	INSTR("tgeiu", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
312 	INSTR("tlti",  JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
313 	INSTR("tltiu", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
314 	INSTR("teqi",  JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
315 	INVALID,
316 	INSTR("tnei",  JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
317 	INVALID,
318 	//16
319 	INSTR("bltzal",  JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|CONDTYPE_LTZ),
320 	INSTR("bgezal",  JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|CONDTYPE_GEZ),
321 	INSTR("bltzall", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|LIKELY|CONDTYPE_LTZ), //L = likely
322 	INSTR("bgezall", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|LIKELY|CONDTYPE_GEZ),
323 	INVALID,
324 	INVALID,
325 	INVALID,
326 	INVALID,
327 	//24
328 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
329 	INSTR("synci", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
330 };
331 
332 const MIPSInstruction tableCop2[32] = // 010010 xxxxx ..... ................
333 {
334 	INSTR("mfc2", JITFUNC(Comp_Generic), Dis_Generic, 0, OUT_RT),
335 	INVALID,
336 	INSTR("cfc2", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
337 	INSTR("mfv", JITFUNC(Comp_Mftv), Dis_Mftv, Int_Mftv, IN_OTHER|IN_VFPU_CC|OUT_RT|IS_VFPU),
338 	INSTR("mtc2", JITFUNC(Comp_Generic), Dis_Generic, 0, IN_RT),
339 	INVALID,
340 	INSTR("ctc2", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
341 	INSTR("mtv", JITFUNC(Comp_Mftv), Dis_Mftv, Int_Mftv, IN_RT|OUT_VFPU_CC|OUT_OTHER|IS_VFPU),
342 	//8
343 	ENCODING(Cop2BC2),
344 	INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
345 	INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
346 	INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
347 	INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
348 	INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
349 	INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
350 	INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
351 	//16
352 	INVALID_X_8,
353 	INVALID_X_8,
354 };
355 
356 const MIPSInstruction tableCop2BC2[4] = // 010010 01000 ...xx ................
357 {
358 	INSTR("bvf", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|IS_VFPU),
359 	INSTR("bvt", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|IS_VFPU),
360 	INSTR("bvfl", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|LIKELY|IS_VFPU),
361 	INSTR("bvtl", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|LIKELY|IS_VFPU),
362 };
363 
364 const MIPSInstruction tableCop0[32] = // 010000 xxxxx ..... ................
365 {
366 	INSTR("mfc0", JITFUNC(Comp_Generic), Dis_Generic, 0, OUT_RT),  // unused
367 	INVALID,
368 	INVALID,
369 	INVALID,
370 	INSTR("mtc0", JITFUNC(Comp_Generic), Dis_Generic, 0, IN_RT),  // unused
371 	INVALID,
372 	INVALID,
373 	INVALID,
374 	//8
375 	INVALID,
376 	INVALID,
377 	INSTR("rdpgpr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
378 	INSTR("mfmc0", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
379 
380 	INVALID,
381 	INVALID,
382 	INSTR("wrpgpr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
383 	INVALID,
384 	//16
385 	ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO),
386 	ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO),
387 };
388 
389 // we won't encounter these since we only do user mode emulation
390 const MIPSInstruction tableCop0CO[64] = // 010000 1.... ..... ..... ..... xxxxxx
391 {
392 	INVALID,
393 	INSTR("tlbr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
394 	INSTR("tlbwi", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
395 	INVALID,
396 	INVALID,
397 	INVALID,
398 	INSTR("tlbwr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
399 	INVALID,
400 	//8
401 	INSTR("tlbp", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
402 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
403 	INVALID_X_8,
404 	//24
405 	INSTR("eret", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
406 	INSTR("iack", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
407 	INVALID, INVALID, INVALID, INVALID, INVALID,
408 	INSTR("deret", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
409 	//32
410 	INSTR("wait", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
411 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
412 	//40
413 	INVALID_X_8,
414 	INVALID_X_8,
415 	INVALID_X_8,
416 };
417 
418 const MIPSInstruction tableCop1[32] = // 010001 xxxxx ..... ..... ...........
419 {
420 	INSTR("mfc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_FS|OUT_RT|IS_FPU),
421 	INVALID,
422 	INSTR("cfc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_OTHER|IN_FPUFLAG|OUT_RT|IS_FPU),
423 	INVALID,
424 	INSTR("mtc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_RT|OUT_FS|IS_FPU),
425 	INVALID,
426 	INSTR("ctc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_RT|OUT_FPUFLAG|OUT_OTHER|IS_FPU),
427 	INVALID,
428 	//8
429 	ENCODING(Cop1BC), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
430 	//16
431 	ENCODING(Cop1S), INVALID, INVALID, INVALID,
432 	ENCODING(Cop1W), INVALID, INVALID, INVALID,
433 	//24
434 	INVALID_X_8,
435 };
436 
437 const MIPSInstruction tableCop1BC[32] = // 010001 01000 xxxxx ................
438 {
439 	INSTR("bc1f",  JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|CONDTYPE_FPUFALSE|IS_FPU),
440 	INSTR("bc1t",  JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|CONDTYPE_FPUTRUE|IS_FPU),
441 	INSTR("bc1fl", JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|LIKELY|CONDTYPE_FPUFALSE|IS_FPU),
442 	INSTR("bc1tl", JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|LIKELY|CONDTYPE_FPUTRUE|IS_FPU),
443 	INVALID, INVALID, INVALID, INVALID,
444 	//8
445 	INVALID_X_8,
446 	INVALID_X_8,
447 	INVALID_X_8,
448 };
449 
450 const MIPSInstruction tableCop1S[64] = // 010001 10000 ..... ..... ..... xxxxxx
451 {
452 	INSTR("add.s",  JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),
453 	INSTR("sub.s",  JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),
454 	INSTR("mul.s",  JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),
455 	INSTR("div.s",  JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, MIPSInfo(OUT_FD|IN_FS|IN_FT|IS_FPU, 29)),
456 	INSTR("sqrt.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
457 	INSTR("abs.s",  JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
458 	INSTR("mov.s",  JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
459 	INSTR("neg.s",  JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
460 	//8
461 	INVALID, INVALID, INVALID, INVALID,
462 	INSTR("round.w.s",  JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
463 	INSTR("trunc.w.s",  JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
464 	INSTR("ceil.w.s",   JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
465 	INSTR("floor.w.s",  JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
466 	//16
467 	INVALID_X_8,
468 	//24
469 	INVALID_X_8,
470 	//32
471 	INVALID, INVALID, INVALID, INVALID,
472 	//36
473 	INSTR("cvt.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
474 	INVALID,
475 	INSTR("dis.int", JITFUNC(Comp_Generic), Dis_Generic, Int_Interrupt, 0),
476 	INVALID,
477 	//40
478 	INVALID_X_8,
479 	//48 - 010001 10000 ..... ..... ..... 11xxxx
480 	INSTR("c.f",   JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU),
481 	INSTR("c.un",  JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
482 	INSTR("c.eq",  JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
483 	INSTR("c.ueq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
484 	INSTR("c.olt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
485 	INSTR("c.ult", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
486 	INSTR("c.ole", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
487 	INSTR("c.ule", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
488 	INSTR("c.sf",  JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU),
489 	INSTR("c.ngle",JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
490 	INSTR("c.seq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
491 	INSTR("c.ngl", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
492 	INSTR("c.lt",  JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
493 	INSTR("c.nge", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
494 	INSTR("c.le",  JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
495 	INSTR("c.ngt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
496 };
497 
498 const MIPSInstruction tableCop1W[64] = // 010001 10100 ..... ..... ..... xxxxxx
499 {
500 	INVALID_X_8,
501 	//8
502 	INVALID_X_8,
503 	//16
504 	INVALID_X_8,
505 	//24
506 	INVALID_X_8,
507 	//32
508 	INSTR("cvt.s.w", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
509 	INVALID, INVALID, INVALID,
510 	//36
511 	INVALID,
512 	INVALID,
513 	INVALID,
514 	INVALID,
515 	//40
516 	INVALID_X_8,
517 	//48
518 	INVALID_X_8,
519 	INVALID_X_8,
520 };
521 
522 const MIPSInstruction tableVFPU0[8] = // 011000 xxx ....... . ....... . .......
523 {
524 	INSTR("vadd", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, MIPSInfo(IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX, 2)),
525 	INSTR("vsub", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, MIPSInfo(IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX, 2)),
526 	// TODO: Disasm is wrong.
527 	INSTR("vsbn", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vsbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
528 	INVALID, INVALID, INVALID, INVALID,
529 
530 	INSTR("vdiv", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
531 };
532 
533 const MIPSInstruction tableVFPU1[8] = // 011001 xxx ....... . ....... . .......
534 {
535 	INSTR("vmul", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
536 	INSTR("vdot", JITFUNC(Comp_VDot), Dis_VectorDot, Int_VDot, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
537 	INSTR("vscl", JITFUNC(Comp_VScl), Dis_VScl, Int_VScl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
538 	INVALID,
539 	INSTR("vhdp", JITFUNC(Comp_VHdp), Dis_VectorDot, Int_VHdp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
540 	INSTR("vcrs", JITFUNC(Comp_VCrs), Dis_Vcrs, Int_Vcrs, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
541 	INSTR("vdet", JITFUNC(Comp_VDet), Dis_VectorDot, Int_Vdet, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
542 	INVALID,
543 };
544 
545 const MIPSInstruction tableVFPU3[8] = // 011011 xxx ....... . ....... . .......
546 {
547 	INSTR("vcmp", JITFUNC(Comp_Vcmp), Dis_Vcmp, Int_Vcmp, IN_OTHER|OUT_VFPU_CC|IS_VFPU|OUT_EAT_PREFIX),
548 	INVALID,
549 	INSTR("vmin", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vminmax, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
550 	INSTR("vmax", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vminmax, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
551 	INVALID,
552 	INSTR("vscmp", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vscmp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
553 	INSTR("vsge", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vsge, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
554 	INSTR("vslt", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vslt, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
555 };
556 
557 const MIPSInstruction tableVFPU4Jump[32] = // 110100 xxxxx ..... . ....... . .......
558 {
559 	ENCODING(VFPU4),
560 	ENCODING(VFPU7),
561 	ENCODING(VFPU9),
562 	INSTR("vcst", JITFUNC(Comp_Vcst), Dis_Vcst, Int_Vcst, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
563 	INVALID, INVALID, INVALID, INVALID,
564 
565 	//8
566 	INVALID_X_8,
567 
568 	//16
569 	INSTR("vf2in", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
570 	INSTR("vf2iz", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
571 	INSTR("vf2iu", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
572 	INSTR("vf2id", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
573 	//20
574 	INSTR("vi2f", JITFUNC(Comp_Vi2f), Dis_Vf2i, Int_Vi2f, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
575 	INSTR("vcmov", JITFUNC(Comp_Vcmov), Dis_Vcmov, Int_Vcmov, IN_OTHER|IN_VFPU_CC|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
576 	INVALID,
577 	INVALID,
578 	//24 - 110100 11 ........ . ....... . .......
579 	INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
580 	INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
581 	INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
582 	INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
583 	INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
584 	INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
585 	INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
586 	INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
587 };
588 
589 const MIPSInstruction tableVFPU7[32] = // 110100 00001 xxxxx . ....... . .......
590 {
591 	INSTR("vrnds", JITFUNC(Comp_Generic), Dis_Vrnds, Int_Vrnds, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
592 	INSTR("vrndi", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
593 	INSTR("vrndf1", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
594 	INSTR("vrndf2", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
595 
596 	INVALID, INVALID, INVALID, INVALID,
597 	//8
598 	INVALID, INVALID, INVALID, INVALID,
599 	INVALID, INVALID, INVALID, INVALID,
600 	//16
601 	INVALID,
602 	INVALID,
603 	INSTR("vf2h", JITFUNC(Comp_Generic), Dis_Vf2h, Int_Vf2h, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
604 	INSTR("vh2f", JITFUNC(Comp_Vh2f), Dis_Vh2f, Int_Vh2f, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
605 
606 	INVALID,
607 	INVALID,
608 	INSTR("vsbz", JITFUNC(Comp_Generic), Dis_Generic, Int_Vsbz, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
609 	INSTR("vlgb", JITFUNC(Comp_Generic), Dis_Generic, Int_Vlgb, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
610 	//24
611 	INSTR("vuc2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),  // Seen in BraveStory, initialization  110100 00001110000 000 0001 0000 0000
612 	INSTR("vc2i",  JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
613 	INSTR("vus2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
614 	INSTR("vs2i",  JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
615 
616 	INSTR("vi2uc", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
617 	INSTR("vi2c",  JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
618 	INSTR("vi2us", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
619 	INSTR("vi2s",  JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
620 };
621 
622 // 110100 00000 10100 0000000000000000
623 // 110100 00000 10111 0000000000000000
624 const MIPSInstruction tableVFPU4[32] = // 110100 00000 xxxxx . ....... . .......
625 {
626 	INSTR("vmov", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
627 	INSTR("vabs", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
628 	INSTR("vneg", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
629 	INSTR("vidt", JITFUNC(Comp_VIdt), Dis_VectorSet1, Int_Vidt, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
630 	INSTR("vsat0", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
631 	INSTR("vsat1", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
632 	INSTR("vzero", JITFUNC(Comp_VVectorInit), Dis_VectorSet1, Int_VVectorInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
633 	INSTR("vone",  JITFUNC(Comp_VVectorInit), Dis_VectorSet1, Int_VVectorInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
634 	//8
635 	INVALID_X_8,
636 	//16
637 	INSTR("vrcp", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
638 	INSTR("vrsq", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
639 	INSTR("vsin", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
640 	INSTR("vcos", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
641 	INSTR("vexp2", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
642 	INSTR("vlog2", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
643 	INSTR("vsqrt", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
644 	INSTR("vasin", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
645 	//24
646 	INSTR("vnrcp", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
647 	INVALID,
648 	INSTR("vnsin", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
649 	INVALID,
650 	INSTR("vrexp2", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
651 	INVALID, INVALID, INVALID,
652 };
653 
654 MIPSInstruction tableVFPU5[8] = // 110111 xxx ....... ................
655 {
656 	INSTR("vpfxs", JITFUNC(Comp_VPFX), Dis_VPFXST, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),
657 	INSTR("vpfxs", JITFUNC(Comp_VPFX), Dis_VPFXST, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),
658 	INSTR("vpfxt", JITFUNC(Comp_VPFX), Dis_VPFXST, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),
659 	INSTR("vpfxt", JITFUNC(Comp_VPFX), Dis_VPFXST, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),
660 	INSTR("vpfxd", JITFUNC(Comp_VPFX), Dis_VPFXD,  Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),
661 	INSTR("vpfxd", JITFUNC(Comp_VPFX), Dis_VPFXD,  Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),
662 	INSTR("viim.s", JITFUNC(Comp_Viim), Dis_Viim, Int_Viim, IN_IMM16|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
663 	INSTR("vfim.s", JITFUNC(Comp_Vfim), Dis_Viim, Int_Viim, IN_IMM16|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
664 };
665 
666 const MIPSInstruction tableVFPU6[32] = // 111100 xxxxx ..... . ....... . .......
667 {
668 	//0
669 	INSTR("vmmul", JITFUNC(Comp_Vmmul), Dis_MatrixMult, Int_Vmmul, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
670 	INSTR("vmmul", JITFUNC(Comp_Vmmul), Dis_MatrixMult, Int_Vmmul, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
671 	INSTR("vmmul", JITFUNC(Comp_Vmmul), Dis_MatrixMult, Int_Vmmul, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
672 	INSTR("vmmul", JITFUNC(Comp_Vmmul), Dis_MatrixMult, Int_Vmmul, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
673 
674 	INSTR("v(h)tfm2", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
675 	INSTR("v(h)tfm2", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
676 	INSTR("v(h)tfm2", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
677 	INSTR("v(h)tfm2", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
678 	//8
679 	INSTR("v(h)tfm3", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
680 	INSTR("v(h)tfm3", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
681 	INSTR("v(h)tfm3", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
682 	INSTR("v(h)tfm3", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
683 
684 	INSTR("v(h)tfm4", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
685 	INSTR("v(h)tfm4", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
686 	INSTR("v(h)tfm4", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
687 	INSTR("v(h)tfm4", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
688 	//16
689 	INSTR("vmscl", JITFUNC(Comp_Vmscl), Dis_Vmscl, Int_Vmscl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
690 	INSTR("vmscl", JITFUNC(Comp_Vmscl), Dis_Vmscl, Int_Vmscl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
691 	INSTR("vmscl", JITFUNC(Comp_Vmscl), Dis_Vmscl, Int_Vmscl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
692 	INSTR("vmscl", JITFUNC(Comp_Vmscl), Dis_Vmscl, Int_Vmscl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
693 
694 	INSTR("vcrsp.t/vqmul.q", JITFUNC(Comp_VCrossQuat), Dis_CrossQuat, Int_CrossQuat, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
695 	INSTR("vcrsp.t/vqmul.q", JITFUNC(Comp_VCrossQuat), Dis_CrossQuat, Int_CrossQuat, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
696 	INSTR("vcrsp.t/vqmul.q", JITFUNC(Comp_VCrossQuat), Dis_CrossQuat, Int_CrossQuat, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
697 	INSTR("vcrsp.t/vqmul.q", JITFUNC(Comp_VCrossQuat), Dis_CrossQuat, Int_CrossQuat, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
698 	//24
699 	INVALID,
700 	INVALID,
701 	INVALID,
702 	INVALID,
703 	//28
704 	ENCODING(VFPUMatrix1),
705 	INSTR("vrot", JITFUNC(Comp_VRot), Dis_VRot, Int_Vrot, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
706 	INVALID,
707 	INVALID,
708 };
709 
710 // TODO: Should this only be when bit 20 is 0?
711 const MIPSInstruction tableVFPUMatrixSet1[16] = // 111100 11100 .xxxx . ....... . .......  (rm x is 16)
712 {
713 	INSTR("vmmov", JITFUNC(Comp_Vmmov), Dis_MatrixSet2, Int_Vmmov, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
714 	INVALID,
715 	INVALID,
716 	INSTR("vmidt", JITFUNC(Comp_VMatrixInit), Dis_MatrixSet1, Int_VMatrixInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
717 
718 	INVALID,
719 	INVALID,
720 	INSTR("vmzero", JITFUNC(Comp_VMatrixInit), Dis_MatrixSet1, Int_VMatrixInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
721 	INSTR("vmone",  JITFUNC(Comp_VMatrixInit), Dis_MatrixSet1, Int_VMatrixInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
722 
723 	INVALID_X_8,
724 };
725 
726 const MIPSInstruction tableVFPU9[32] = // 110100 00010 xxxxx . ....... . .......
727 {
728 	INSTR("vsrt1", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt1, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
729 	INSTR("vsrt2", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt2, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
730 	INSTR("vbfy1", JITFUNC(Comp_Vbfy), Dis_Vbfy, Int_Vbfy, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
731 	INSTR("vbfy2", JITFUNC(Comp_Vbfy), Dis_Vbfy, Int_Vbfy, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
732 	//4
733 	INSTR("vocp", JITFUNC(Comp_Vocp), Dis_Vbfy, Int_Vocp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),  // one's complement
734 	INSTR("vsocp", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsocp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
735 	INSTR("vfad", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vfad, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
736 	INSTR("vavg", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vavg, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
737 	//8
738 	INSTR("vsrt3", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
739 	INSTR("vsrt4", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt4, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
740 	INSTR("vsgn", JITFUNC(Comp_Vsgn), Dis_Vbfy, Int_Vsgn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
741 	INVALID,
742 	//12
743 	INVALID,
744 	INVALID,
745 	INVALID,
746 	INVALID,
747 
748 	//16
749 	INSTR("vmfvc", JITFUNC(Comp_Vmfvc), Dis_Vmfvc, Int_Vmfvc, IN_OTHER|IN_VFPU_CC|OUT_OTHER|IS_VFPU),
750 	INSTR("vmtvc", JITFUNC(Comp_Vmtvc), Dis_Vmtvc, Int_Vmtvc, IN_OTHER|OUT_VFPU_CC|OUT_OTHER|IS_VFPU),
751 	INVALID,
752 	INVALID,
753 
754 	//20
755 	INVALID, INVALID, INVALID, INVALID,
756 	//24
757 	INVALID,
758 	INSTR("vt4444", JITFUNC(Comp_ColorConv), Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
759 	INSTR("vt5551", JITFUNC(Comp_ColorConv), Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
760 	INSTR("vt5650", JITFUNC(Comp_ColorConv), Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
761 
762 	//28
763 	INVALID, INVALID, INVALID, INVALID,
764 };
765 
766 const MIPSInstruction tableALLEGREX0[32] =  // 011111 ..... ..... ..... xxxxx 100000 - or ending with 011000?
767 {
768 	INVALID,
769 	INVALID,
770 	INSTR("wsbh", JITFUNC(Comp_Allegrex2), Dis_Allegrex2, Int_Allegrex2, IN_RT|OUT_RD),
771 	INSTR("wsbw", JITFUNC(Comp_Allegrex2), Dis_Allegrex2, Int_Allegrex2, IN_RT|OUT_RD),
772 	INVALID, INVALID, INVALID, INVALID,
773 //8
774 	INVALID_X_8,
775 //16
776 	INSTR("seb", JITFUNC(Comp_Allegrex), Dis_Allegrex,Int_Allegrex, IN_RT|OUT_RD),
777 	INVALID,
778 	INVALID,
779 	INVALID,
780 //20
781 	INSTR("bitrev", JITFUNC(Comp_Allegrex), Dis_Allegrex,Int_Allegrex, IN_RT|OUT_RD),
782 	INVALID,
783 	INVALID,
784 	INVALID,
785 //24
786 	INSTR("seh", JITFUNC(Comp_Allegrex), Dis_Allegrex,Int_Allegrex, IN_RT|OUT_RD),
787 	INVALID,
788 	INVALID,
789 	INVALID,
790 //28
791 	INVALID,
792 	INVALID,
793 	INVALID,
794 	INVALID,
795 };
796 
797 
798 const MIPSInstruction tableEMU[4] = {
799 	INSTR("RUNBLOCK", JITFUNC(Comp_RunBlock), Dis_Emuhack, Int_Emuhack, 0xFFFFFFFF),
800 	INSTR("RetKrnl", 0, Dis_Emuhack, Int_Emuhack, 0),
801 	INSTR("CallRepl", JITFUNC(Comp_ReplacementFunc), Dis_Emuhack, Int_Emuhack, 0),
802 	INVALID,
803 };
804 
805 struct EncodingBitsInfo {
EncodingBitsInfoEncodingBitsInfo806 	EncodingBitsInfo(u8 shift_, u8 maskBits_) : shift(shift_) {
807 		mask = (1 << maskBits_) - 1;
808 	}
809 	u8 shift;
810 	u32 mask;
811 };
812 
813 const EncodingBitsInfo encodingBits[NumEncodings] = {
814 	EncodingBitsInfo(26, 6), //IMME
815 	EncodingBitsInfo(0,  6), //Special
816 	EncodingBitsInfo(0,  6), //special2
817 	EncodingBitsInfo(0,  6), //special3
818 	EncodingBitsInfo(16, 5), //RegImm
819 	EncodingBitsInfo(21, 5), //Cop0
820 	EncodingBitsInfo(0,  6), //Cop0CO
821 	EncodingBitsInfo(21, 5), //Cop1
822 	EncodingBitsInfo(16, 5), //Cop1BC
823 	EncodingBitsInfo(0,  6), //Cop1S
824 	EncodingBitsInfo(0,  6), //Cop1W
825 	EncodingBitsInfo(21, 5), //Cop2
826 	EncodingBitsInfo(16, 2), //Cop2BC2
827 	EncodingBitsInfo(0,  0), //Cop2Rese
828 	EncodingBitsInfo(23, 3), //VFPU0
829 	EncodingBitsInfo(23, 3), //VFPU1
830 	EncodingBitsInfo(23, 3), //VFPU3
831 	EncodingBitsInfo(21, 5), //VFPU4Jump
832 	EncodingBitsInfo(16, 5), //VFPU7
833 	EncodingBitsInfo(16, 5), //VFPU4
834 	EncodingBitsInfo(23, 3), //VFPU5
835 	EncodingBitsInfo(21, 5), //VFPU6
836 	EncodingBitsInfo(16, 4), //VFPUMatrix1
837 	EncodingBitsInfo(16, 5), //VFPU9
838 	EncodingBitsInfo(6,  5), //ALLEGREX0
839 	EncodingBitsInfo(24, 2), //EMUHACK
840 	EncodingBitsInfo(0,  0), //Rese
841 };
842 
843 const MIPSInstruction *mipsTables[NumEncodings] = {
844 	tableImmediate,
845 	tableSpecial,
846 	tableSpecial2,
847 	tableSpecial3,
848 	tableRegImm,
849 	tableCop0,
850 	tableCop0CO,
851 	tableCop1,
852 	tableCop1BC,
853 	tableCop1S,
854 	tableCop1W,
855 	tableCop2,
856 	tableCop2BC2,
857 	0,
858 	tableVFPU0, //vfpu0
859 	tableVFPU1, //vfpu1
860 	tableVFPU3, //vfpu3
861 	tableVFPU4Jump,
862 	tableVFPU7, //vfpu4     110100 00001
863 	tableVFPU4, //vfpu4     110100 00000
864 	tableVFPU5, //vfpu5     110111
865 	tableVFPU6, //vfpu6     111100
866 	tableVFPUMatrixSet1,
867 	tableVFPU9,
868 	tableALLEGREX0,
869 	tableEMU,
870 	0,
871 };
872 
873 //arm encoding table
874 //const MIPSInstruction mipsinstructions[] =
875 //{
876 //{Comp_Unimpl,Dis_Unimpl, Info_NN,    0, 0x601,       0x1FE,0}, //could be used for drec hook :) bits 5-24 plus 0-3 are available, 19 bits are more than enough
877 // DATA PROCESSING INSTRUCTIONS
878 //                        S
879 //	{Comp_AND,   Dis_AND,    Info_DP,    0, DATAP(0, 0), 0x20F, {0}},
880 //};
881 
882 // TODO : generate smart dispatcher functions from above tables
883 // instead of this slow method.
MIPSGetInstruction(MIPSOpcode op)884 const MIPSInstruction *MIPSGetInstruction(MIPSOpcode op) {
885 	MipsEncoding encoding = Imme;
886 	const MIPSInstruction *instr = &tableImmediate[op.encoding >> 26];
887 	while (instr->altEncoding != Instruc) {
888 		if (instr->altEncoding == Inval) {
889 			//ERROR_LOG(CPU, "Invalid instruction %08x in table %i, entry %i", op, (int)encoding, subop);
890 			return 0; //invalid instruction
891 		}
892 		encoding = instr->altEncoding;
893 
894 		const MIPSInstruction *table = mipsTables[encoding];
895 		const u32 subop = (op.encoding >> encodingBits[encoding].shift) & encodingBits[encoding].mask;
896 		instr = &table[subop];
897 	}
898 	//alright, we have a valid MIPS instruction!
899 	return instr;
900 }
901 
MIPSCompileOp(MIPSOpcode op,MIPSComp::MIPSFrontendInterface * jit)902 void MIPSCompileOp(MIPSOpcode op, MIPSComp::MIPSFrontendInterface *jit) {
903 	if (op == 0)
904 		return;
905 	const MIPSInstruction *instr = MIPSGetInstruction(op);
906 	const MIPSInfo info = MIPSGetInfo(op);
907 	if (instr) {
908 		if (instr->compile) {
909 			(jit->*(instr->compile))(op);
910 		} else {
911 			ERROR_LOG_REPORT(CPU,"MIPSCompileOp %08x failed",op.encoding);
912 		}
913 		if (info & OUT_EAT_PREFIX)
914 			jit->EatPrefix();
915 	} else {
916 		ERROR_LOG_REPORT(CPU, "MIPSCompileOp: Invalid instruction %08x", op.encoding);
917 	}
918 }
919 
MIPSDisAsm(MIPSOpcode op,u32 pc,char * out,bool tabsToSpaces)920 void MIPSDisAsm(MIPSOpcode op, u32 pc, char *out, bool tabsToSpaces) {
921 	if (op == 0) {
922 		sprintf(out,"nop");
923 	} else {
924 		disPC = pc;
925 		const MIPSInstruction *instr = MIPSGetInstruction(op);
926 		if (instr && instr->disasm) {
927 			instr->disasm(op, out);
928 			if (tabsToSpaces) {
929 				while (*out) {
930 					if (*out == '\t')
931 						*out = ' ';
932 					out++;
933 				}
934 			}
935 		} else {
936 			strcpy(out, "no instruction :(");
937 		}
938 	}
939 }
940 
MIPSInterpret(MIPSOpcode op)941 void MIPSInterpret(MIPSOpcode op) {
942 	const MIPSInstruction *instr = MIPSGetInstruction(op);
943 	if (instr && instr->interpret) {
944 		instr->interpret(op);
945 	} else {
946 		ERROR_LOG_REPORT(CPU, "Unknown instruction %08x at %08x", op.encoding, currentMIPS->pc);
947 		// Try to disassemble it
948 		char disasm[256];
949 		MIPSDisAsm(op, currentMIPS->pc, disasm);
950 		_dbg_assert_msg_( 0, "%s", disasm);
951 		currentMIPS->pc += 4;
952 	}
953 }
954 
955 #define _RS   ((op>>21) & 0x1F)
956 #define _RT   ((op>>16) & 0x1F)
957 #define _RD   ((op>>11) & 0x1F)
958 #define R(i)   (curMips->r[i])
959 
960 
MIPSInterpret_RunUntil(u64 globalTicks)961 int MIPSInterpret_RunUntil(u64 globalTicks)
962 {
963 	MIPSState *curMips = currentMIPS;
964 	while (coreState == CORE_RUNNING)
965 	{
966 		CoreTiming::Advance();
967 
968 		// NEVER stop in a delay slot!
969 		while (curMips->downcount >= 0 && coreState == CORE_RUNNING)
970 		{
971 			// int cycles = 0;
972 			{
973 				again:
974 				MIPSOpcode op = MIPSOpcode(Memory::Read_U32(curMips->pc));
975 				//MIPSOpcode op = Memory::Read_Opcode_JIT(mipsr4k.pc);
976 
977 		//2: check for breakpoint (VERY SLOW)
978 #if defined(_DEBUG)
979 				if (CBreakPoints::IsAddressBreakPoint(curMips->pc))
980 				{
981 					auto cond = CBreakPoints::GetBreakPointCondition(currentMIPS->pc);
982 					if (!cond || cond->Evaluate())
983 					{
984 						Core_EnableStepping(true);
985 						if (CBreakPoints::IsTempBreakPoint(curMips->pc))
986 							CBreakPoints::RemoveBreakPoint(curMips->pc);
987 						break;
988 					}
989 				}
990 #endif
991 
992 				bool wasInDelaySlot = curMips->inDelaySlot;
993 				MIPSInterpret(op);
994 				curMips->downcount -= MIPSGetInstructionCycleEstimate(op);
995 
996 				if (curMips->inDelaySlot)
997 				{
998 					// The reason we have to check this is the delay slot hack in Int_Syscall.
999 					if (wasInDelaySlot)
1000 					{
1001 						curMips->pc = curMips->nextPC;
1002 						curMips->inDelaySlot = false;
1003 						continue;
1004 					}
1005 					goto again;
1006 				}
1007 			}
1008 
1009 			if (CoreTiming::GetTicks() > globalTicks)
1010 			{
1011 				// DEBUG_LOG(CPU, "Hit the max ticks, bailing 1 : %llu, %llu", globalTicks, CoreTiming::GetTicks());
1012 				return 1;
1013 			}
1014 		}
1015 	}
1016 
1017 	return 1;
1018 }
1019 
MIPSGetName(MIPSOpcode op)1020 const char *MIPSGetName(MIPSOpcode op)
1021 {
1022 	static const char *noname = "unk";
1023 	const MIPSInstruction *instr = MIPSGetInstruction(op);
1024 	if (!instr)
1025 		return noname;
1026 	else
1027 		return instr->name;
1028 }
1029 
MIPSGetInfo(MIPSOpcode op)1030 MIPSInfo MIPSGetInfo(MIPSOpcode op)
1031 {
1032 	//	int crunch = CRUNCH_MIPS_OP(op);
1033 	const MIPSInstruction *instr = MIPSGetInstruction(op);
1034 	if (instr)
1035 		return instr->flags;
1036 	else
1037 		return MIPSInfo(BAD_INSTRUCTION);
1038 }
1039 
MIPSGetInterpretFunc(MIPSOpcode op)1040 MIPSInterpretFunc MIPSGetInterpretFunc(MIPSOpcode op)
1041 {
1042 	const MIPSInstruction *instr = MIPSGetInstruction(op);
1043 	if (instr->interpret)
1044 		return instr->interpret;
1045 	else
1046 		return 0;
1047 }
1048 
1049 // TODO: Do something that makes sense here.
MIPSGetInstructionCycleEstimate(MIPSOpcode op)1050 int MIPSGetInstructionCycleEstimate(MIPSOpcode op)
1051 {
1052 	MIPSInfo info = MIPSGetInfo(op);
1053 	return info.cycles;
1054 }
1055 
MIPSDisasmAt(u32 compilerPC)1056 const char *MIPSDisasmAt(u32 compilerPC) {
1057 	static char temp[256];
1058 	MIPSDisAsm(Memory::Read_Instruction(compilerPC), 0, temp);
1059 	return temp;
1060 }
1061