Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/MIPS/MIPSTables.cpp
3186 views
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 "Common/StringUtils.h"
19
20
#include "Core/Core.h"
21
#include "Core/MemMap.h"
22
#include "Core/MIPS/MIPS.h"
23
#include "Core/MIPS/MIPSDis.h"
24
#include "Core/MIPS/MIPSDisVFPU.h"
25
#include "Core/MIPS/MIPSInt.h"
26
#include "Core/MIPS/MIPSIntVFPU.h"
27
#include "Core/MIPS/MIPSCodeUtils.h"
28
#include "Core/MIPS/MIPSTables.h"
29
#include "Core/CoreTiming.h"
30
#include "Core/Reporting.h"
31
#include "Core/Debugger/Breakpoints.h"
32
33
#include "JitCommon/JitCommon.h"
34
35
enum MipsEncoding {
36
Imme,
37
Spec,
38
Spe2,
39
Spe3,
40
RegI,
41
Cop0,
42
Cop0CO,
43
Cop1,
44
Cop1BC,
45
Cop1S,
46
Cop1W,
47
Cop2,
48
Cop2BC2,
49
Cop2Rese,
50
VFPU0,
51
VFPU1,
52
VFPU3,
53
VFPU4Jump,
54
VFPU7,
55
VFPU4,
56
VFPU5,
57
VFPU6,
58
VFPUMatrix1,
59
VFPU9,
60
ALLEGREX0,
61
Emu,
62
Rese,
63
NumEncodings,
64
65
Instruc = -1,
66
Inval = -2,
67
};
68
69
struct MIPSInstruction {
70
MipsEncoding altEncoding;
71
const char *name;
72
MIPSComp::MIPSCompileFunc compile;
73
MIPSDisFunc disasm;
74
MIPSInterpretFunc interpret;
75
//MIPSInstructionInfo information;
76
MIPSInfo flags;
77
};
78
79
#define INVALID {Inval}
80
#define INVALID_X_8 INVALID,INVALID,INVALID,INVALID,INVALID,INVALID,INVALID,INVALID
81
82
#define ENCODING(a) {a}
83
#define INSTR(name, comp, dis, inter, flags) {Instruc, name, comp, dis, inter, MIPSInfo(flags)}
84
85
#define JITFUNC(f) (&MIPSFrontendInterface::f)
86
87
using namespace MIPSDis;
88
using namespace MIPSInt;
89
using namespace MIPSComp;
90
91
// %s/&Jit::\(.\{-}\),/JITFUNC(\1),/g
92
93
// regregreg instructions
94
static const MIPSInstruction tableImmediate[64] = // xxxxxx ..... ..... ................
95
{
96
//0
97
ENCODING(Spec),
98
ENCODING(RegI),
99
INSTR("j", JITFUNC(Comp_Jump), Dis_JumpType, Int_JumpType, IS_JUMP|IN_IMM26|DELAYSLOT),
100
INSTR("jal", JITFUNC(Comp_Jump), Dis_JumpType, Int_JumpType, IS_JUMP|IN_IMM26|OUT_RA|DELAYSLOT),
101
INSTR("beq", JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|CONDTYPE_EQ),
102
INSTR("bne", JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|CONDTYPE_NE),
103
INSTR("blez", JITFUNC(Comp_RelBranch), Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_LEZ),
104
INSTR("bgtz", JITFUNC(Comp_RelBranch), Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_GTZ),
105
//8
106
INSTR("addi", JITFUNC(Comp_IType), Dis_addi, Int_IType, IN_RS|IN_IMM16|OUT_RT),
107
INSTR("addiu", JITFUNC(Comp_IType), Dis_addi, Int_IType, IN_RS|IN_IMM16|OUT_RT),
108
INSTR("slti", JITFUNC(Comp_IType), Dis_IType, Int_IType, IN_RS|IN_IMM16|OUT_RT),
109
INSTR("sltiu", JITFUNC(Comp_IType), Dis_IType, Int_IType, IN_RS|IN_IMM16|OUT_RT),
110
INSTR("andi", JITFUNC(Comp_IType), Dis_IType, Int_IType, IN_RS|IN_IMM16|OUT_RT),
111
INSTR("ori", JITFUNC(Comp_IType), Dis_ori, Int_IType, IN_RS|IN_IMM16|OUT_RT),
112
INSTR("xori", JITFUNC(Comp_IType), Dis_IType, Int_IType, IN_RS|IN_IMM16|OUT_RT),
113
INSTR("lui", JITFUNC(Comp_IType), Dis_IType1, Int_IType, IN_IMM16|OUT_RT),
114
//16
115
ENCODING(Cop0), //cop0
116
ENCODING(Cop1), //cop1
117
ENCODING(Cop2), //cop2
118
INVALID, //copU
119
120
INSTR("beql", JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|LIKELY|CONDTYPE_EQ), //L = likely
121
INSTR("bnel", JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|LIKELY|CONDTYPE_NE),
122
INSTR("blezl", JITFUNC(Comp_RelBranch), Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_LEZ),
123
INSTR("bgtzl", JITFUNC(Comp_RelBranch), Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_GTZ),
124
//24
125
ENCODING(VFPU0),
126
ENCODING(VFPU1),
127
ENCODING(Emu),
128
ENCODING(VFPU3),
129
ENCODING(Spe2), //special2
130
INVALID,
131
INVALID,
132
ENCODING(Spe3), //special3
133
//32
134
INSTR("lb", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_BYTE),
135
INSTR("lh", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_HWORD),
136
INSTR("lwl", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|IN_RT|OUT_RT|MEMTYPE_WORD),
137
INSTR("lw", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_WORD),
138
INSTR("lbu", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_BYTE),
139
INSTR("lhu", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_HWORD),
140
INSTR("lwr", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|IN_RT|OUT_RT|MEMTYPE_WORD),
141
INVALID,
142
//40
143
INSTR("sb", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_BYTE),
144
INSTR("sh", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_HWORD),
145
INSTR("swl", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),
146
INSTR("sw", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),
147
INVALID,
148
INVALID,
149
INSTR("swr", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),
150
INSTR("cache", JITFUNC(Comp_Cache), Dis_Cache, Int_Cache, IN_MEM|IN_IMM16|IN_RS_ADDR),
151
//48
152
INSTR("ll", JITFUNC(Comp_StoreSync), Dis_ITypeMem, Int_StoreSync, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|OUT_OTHER|MEMTYPE_WORD),
153
INSTR("lwc1", JITFUNC(Comp_FPULS), Dis_FPULS, Int_FPULS, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_FT|MEMTYPE_FLOAT|IS_FPU),
154
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),
155
INVALID,
156
ENCODING(VFPU4Jump),
157
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),
158
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
159
ENCODING(VFPU5),
160
//56
161
INSTR("sc", JITFUNC(Comp_StoreSync), Dis_ITypeMem, Int_StoreSync, IN_IMM16|IN_RS_ADDR|IN_OTHER|IN_RT|OUT_RT|OUT_MEM|MEMTYPE_WORD),
162
INSTR("swc1", JITFUNC(Comp_FPULS), Dis_FPULS, Int_FPULS, IN_IMM16|IN_RS_ADDR|IN_FT|OUT_MEM|MEMTYPE_FLOAT|IS_FPU), //copU
163
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),
164
INVALID,
165
//60
166
ENCODING(VFPU6),
167
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
168
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),
169
// Some call this VFPU7 (vflush/vnop/vsync), but it's not super important.
170
INSTR("vflush", JITFUNC(Comp_DoNothing), Dis_Vflush, Int_Vflush, IS_VFPU|VFPU_NO_PREFIX),
171
};
172
173
static const MIPSInstruction tableSpecial[64] = // 000000 ..... ..... ..... ..... xxxxxx
174
{
175
INSTR("sll", JITFUNC(Comp_ShiftType), Dis_ShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_SA),
176
INVALID, // copu
177
178
INSTR("srl", JITFUNC(Comp_ShiftType), Dis_ShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_SA),
179
INSTR("sra", JITFUNC(Comp_ShiftType), Dis_ShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_SA),
180
INSTR("sllv", JITFUNC(Comp_ShiftType), Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),
181
INVALID,
182
INSTR("srlv", JITFUNC(Comp_ShiftType), Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),
183
INSTR("srav", JITFUNC(Comp_ShiftType), Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),
184
185
//8
186
INSTR("jr", JITFUNC(Comp_JumpReg), Dis_JumpRegType, Int_JumpRegType, IS_JUMP|IN_RS|DELAYSLOT),
187
INSTR("jalr", JITFUNC(Comp_JumpReg), Dis_JumpRegType, Int_JumpRegType, IS_JUMP|IN_RS|OUT_RD|DELAYSLOT),
188
INSTR("movz", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT|IS_CONDMOVE|CONDTYPE_EQ),
189
INSTR("movn", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT|IS_CONDMOVE|CONDTYPE_NE),
190
INSTR("syscall", JITFUNC(Comp_Syscall), Dis_Syscall, Int_Syscall, IN_MEM|IN_OTHER|OUT_MEM|OUT_OTHER|IS_SYSCALL),
191
INSTR("break", JITFUNC(Comp_Break), Dis_Generic, Int_Break, 0),
192
INVALID,
193
INSTR("sync", JITFUNC(Comp_DoNothing), Dis_Generic, Int_Sync, 0),
194
195
//16
196
INSTR("mfhi", JITFUNC(Comp_MulDivType), Dis_FromHiloTransfer, Int_MulDivType, OUT_RD|IN_HI),
197
INSTR("mthi", JITFUNC(Comp_MulDivType), Dis_ToHiloTransfer, Int_MulDivType, IN_RS|OUT_HI),
198
INSTR("mflo", JITFUNC(Comp_MulDivType), Dis_FromHiloTransfer, Int_MulDivType, OUT_RD|IN_LO),
199
INSTR("mtlo", JITFUNC(Comp_MulDivType), Dis_ToHiloTransfer, Int_MulDivType, IN_RS|OUT_LO),
200
INVALID,
201
INVALID,
202
INSTR("clz", JITFUNC(Comp_RType2), Dis_RType2, Int_RType2, OUT_RD|IN_RS),
203
INSTR("clo", JITFUNC(Comp_RType2), Dis_RType2, Int_RType2, OUT_RD|IN_RS),
204
205
//24
206
INSTR("mult", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),
207
INSTR("multu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),
208
INSTR("div", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),
209
INSTR("divu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),
210
INSTR("madd", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),
211
INSTR("maddu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),
212
INVALID,
213
INVALID,
214
215
//32
216
INSTR("add", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
217
INSTR("addu", JITFUNC(Comp_RType3), Dis_addu, Int_RType3, IN_RS|IN_RT|OUT_RD),
218
INSTR("sub", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
219
INSTR("subu", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
220
INSTR("and", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
221
INSTR("or", JITFUNC(Comp_RType3), Dis_addu, Int_RType3, IN_RS|IN_RT|OUT_RD),
222
INSTR("xor", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
223
INSTR("nor", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
224
225
//40
226
INVALID,
227
INVALID,
228
INSTR("slt", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
229
INSTR("sltu", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
230
INSTR("max", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
231
INSTR("min", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),
232
INSTR("msub", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),
233
INSTR("msubu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),
234
235
//48
236
INSTR("tge", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
237
INSTR("tgeu", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
238
INSTR("tlt", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
239
INSTR("tltu", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
240
INSTR("teq", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
241
INVALID,
242
INSTR("tne", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),
243
INVALID,
244
245
//56
246
INVALID_X_8,
247
};
248
249
// Theoretically should not hit these.
250
static const MIPSInstruction tableSpecial2[64] = // 011100 ..... ..... ..... ..... xxxxxx
251
{
252
INSTR("halt", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
253
INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
254
//8
255
INVALID_X_8,
256
INVALID_X_8,
257
INVALID_X_8,
258
//32
259
INVALID, INVALID, INVALID, INVALID,
260
INSTR("mfic", JITFUNC(Comp_Generic), Dis_Generic, Int_Special2, OUT_OTHER),
261
INVALID,
262
INSTR("mtic", JITFUNC(Comp_Generic), Dis_Generic, Int_Special2, OUT_OTHER),
263
INVALID,
264
//40
265
INVALID_X_8,
266
INVALID_X_8,
267
INVALID_X_8,
268
};
269
270
static const MIPSInstruction tableSpecial3[64] = // 011111 ..... ..... ..... ..... xxxxxx
271
{
272
INSTR("ext", JITFUNC(Comp_Special3), Dis_Special3, Int_Special3, IN_RS|OUT_RT),
273
INVALID,
274
INVALID,
275
INVALID,
276
INSTR("ins", JITFUNC(Comp_Special3), Dis_Special3, Int_Special3, IN_RS|IN_RT|OUT_RT),
277
INVALID,
278
INVALID,
279
INVALID,
280
//8
281
INVALID_X_8,
282
//16
283
INVALID_X_8,
284
//24
285
// TODO: Is this right? Or should it only be 32? Comment above (24) was mistakenly 32 before.
286
ENCODING(ALLEGREX0),
287
INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
288
//32
289
ENCODING(ALLEGREX0),
290
INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
291
//40
292
INVALID_X_8,
293
INVALID_X_8,
294
//56
295
INVALID, INVALID, INVALID,
296
INSTR("rdhwr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
297
INVALID, INVALID, INVALID, INVALID,
298
};
299
300
static const MIPSInstruction tableRegImm[32] = // 000001 ..... xxxxx ................
301
{
302
INSTR("bltz", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_LTZ),
303
INSTR("bgez", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_GEZ),
304
INSTR("bltzl", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_LTZ),
305
INSTR("bgezl", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_GEZ),
306
INVALID,
307
INVALID,
308
INVALID,
309
INVALID,
310
//8
311
INSTR("tgei", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
312
INSTR("tgeiu", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
313
INSTR("tlti", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
314
INSTR("tltiu", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
315
INSTR("teqi", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
316
INVALID,
317
INSTR("tnei", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
318
INVALID,
319
//16
320
INSTR("bltzal", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|CONDTYPE_LTZ),
321
INSTR("bgezal", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|CONDTYPE_GEZ),
322
INSTR("bltzall", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|LIKELY|CONDTYPE_LTZ), //L = likely
323
INSTR("bgezall", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|LIKELY|CONDTYPE_GEZ),
324
INVALID,
325
INVALID,
326
INVALID,
327
INVALID,
328
//24
329
INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
330
INSTR("synci", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
331
};
332
333
static const MIPSInstruction tableCop2[32] = // 010010 xxxxx ..... ................
334
{
335
INSTR("mfc2", JITFUNC(Comp_Generic), Dis_Generic, 0, OUT_RT),
336
INVALID,
337
INSTR("cfc2", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
338
INSTR("mfv", JITFUNC(Comp_Mftv), Dis_Mftv, Int_Mftv, IN_OTHER|IN_VFPU_CC|OUT_RT|IS_VFPU),
339
INSTR("mtc2", JITFUNC(Comp_Generic), Dis_Generic, 0, IN_RT),
340
INVALID,
341
INSTR("ctc2", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
342
INSTR("mtv", JITFUNC(Comp_Mftv), Dis_Mftv, Int_Mftv, IN_RT|OUT_VFPU_CC|OUT_OTHER|IS_VFPU|OUT_VFPU_PREFIX),
343
//8
344
ENCODING(Cop2BC2),
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
INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
352
//16
353
INVALID_X_8,
354
INVALID_X_8,
355
};
356
357
static const MIPSInstruction tableCop2BC2[4] = // 010010 01000 ...xx ................
358
{
359
INSTR("bvf", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|IS_VFPU),
360
INSTR("bvt", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|IS_VFPU),
361
INSTR("bvfl", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|LIKELY|IS_VFPU),
362
INSTR("bvtl", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|LIKELY|IS_VFPU),
363
};
364
365
static const MIPSInstruction tableCop0[32] = // 010000 xxxxx ..... ................
366
{
367
INSTR("mfc0", JITFUNC(Comp_Generic), Dis_Generic, 0, OUT_RT), // unused
368
INVALID,
369
INVALID,
370
INVALID,
371
INSTR("mtc0", JITFUNC(Comp_Generic), Dis_Generic, 0, IN_RT), // unused
372
INVALID,
373
INVALID,
374
INVALID,
375
//8
376
INVALID,
377
INVALID,
378
INSTR("rdpgpr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
379
INSTR("mfmc0", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
380
381
INVALID,
382
INVALID,
383
INSTR("wrpgpr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
384
INVALID,
385
//16
386
ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO),
387
ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO),
388
};
389
390
// we won't encounter these since we only do user mode emulation
391
static const MIPSInstruction tableCop0CO[64] = // 010000 1.... ..... ..... ..... xxxxxx
392
{
393
INVALID,
394
INSTR("tlbr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
395
INSTR("tlbwi", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
396
INVALID,
397
INVALID,
398
INVALID,
399
INSTR("tlbwr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
400
INVALID,
401
//8
402
INSTR("tlbp", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
403
INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
404
INVALID_X_8,
405
//24
406
INSTR("eret", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
407
INSTR("iack", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
408
INVALID, INVALID, INVALID, INVALID, INVALID,
409
INSTR("deret", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
410
//32
411
INSTR("wait", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
412
INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
413
//40
414
INVALID_X_8,
415
INVALID_X_8,
416
INVALID_X_8,
417
};
418
419
static const MIPSInstruction tableCop1[32] = // 010001 xxxxx ..... ..... ...........
420
{
421
INSTR("mfc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_FS|OUT_RT|IS_FPU),
422
INVALID,
423
INSTR("cfc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_OTHER|IN_FPUFLAG|OUT_RT|IS_FPU),
424
INVALID,
425
INSTR("mtc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_RT|OUT_FS|IS_FPU),
426
INVALID,
427
INSTR("ctc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_RT|OUT_FPUFLAG|OUT_OTHER|IS_FPU),
428
INVALID,
429
//8
430
ENCODING(Cop1BC), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
431
//16
432
ENCODING(Cop1S), INVALID, INVALID, INVALID,
433
ENCODING(Cop1W), INVALID, INVALID, INVALID,
434
//24
435
INVALID_X_8,
436
};
437
438
static const MIPSInstruction tableCop1BC[32] = // 010001 01000 xxxxx ................
439
{
440
INSTR("bc1f", JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|CONDTYPE_FPUFALSE|IS_FPU),
441
INSTR("bc1t", JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|CONDTYPE_FPUTRUE|IS_FPU),
442
INSTR("bc1fl", JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|LIKELY|CONDTYPE_FPUFALSE|IS_FPU),
443
INSTR("bc1tl", JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|LIKELY|CONDTYPE_FPUTRUE|IS_FPU),
444
INVALID, INVALID, INVALID, INVALID,
445
//8
446
INVALID_X_8,
447
INVALID_X_8,
448
INVALID_X_8,
449
};
450
451
static const MIPSInstruction tableCop1S[64] = // 010001 10000 ..... ..... ..... xxxxxx
452
{
453
INSTR("add.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),
454
INSTR("sub.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),
455
INSTR("mul.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),
456
INSTR("div.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, MIPSInfo(OUT_FD|IN_FS|IN_FT|IS_FPU, 29)),
457
INSTR("sqrt.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
458
INSTR("abs.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
459
INSTR("mov.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
460
INSTR("neg.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
461
//8
462
INVALID, INVALID, INVALID, INVALID,
463
INSTR("round.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
464
INSTR("trunc.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
465
INSTR("ceil.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
466
INSTR("floor.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
467
//16
468
INVALID_X_8,
469
//24
470
INVALID_X_8,
471
//32
472
INVALID, INVALID, INVALID, INVALID,
473
//36
474
INSTR("cvt.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
475
INVALID,
476
INSTR("dis.int", JITFUNC(Comp_Generic), Dis_Generic, Int_Interrupt, 0),
477
INVALID,
478
//40
479
INVALID_X_8,
480
//48 - 010001 10000 ..... ..... ..... 11xxxx
481
INSTR("c.f", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU),
482
INSTR("c.un", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
483
INSTR("c.eq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
484
INSTR("c.ueq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
485
INSTR("c.olt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
486
INSTR("c.ult", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
487
INSTR("c.ole", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
488
INSTR("c.ule", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
489
INSTR("c.sf", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU),
490
INSTR("c.ngle",JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
491
INSTR("c.seq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
492
INSTR("c.ngl", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
493
INSTR("c.lt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
494
INSTR("c.nge", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
495
INSTR("c.le", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
496
INSTR("c.ngt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),
497
};
498
499
static const MIPSInstruction tableCop1W[64] = // 010001 10100 ..... ..... ..... xxxxxx
500
{
501
INVALID_X_8,
502
//8
503
INVALID_X_8,
504
//16
505
INVALID_X_8,
506
//24
507
INVALID_X_8,
508
//32
509
INSTR("cvt.s.w", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
510
INVALID, INVALID, INVALID,
511
//36
512
INVALID,
513
INVALID,
514
INVALID,
515
INVALID,
516
//40
517
INVALID_X_8,
518
//48
519
INVALID_X_8,
520
INVALID_X_8,
521
};
522
523
static const MIPSInstruction tableVFPU0[8] = // 011000 xxx ....... . ....... . .......
524
{
525
INSTR("vadd", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, MIPSInfo(IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX, 2)),
526
INSTR("vsub", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, MIPSInfo(IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX, 2)),
527
// TODO: Disasm is wrong.
528
INSTR("vsbn", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vsbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
529
INVALID, INVALID, INVALID, INVALID,
530
531
INSTR("vdiv", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
532
};
533
534
static const MIPSInstruction tableVFPU1[8] = // 011001 xxx ....... . ....... . .......
535
{
536
INSTR("vmul", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
537
INSTR("vdot", JITFUNC(Comp_VDot), Dis_VectorDot, Int_VDot, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
538
INSTR("vscl", JITFUNC(Comp_VScl), Dis_VScl, Int_VScl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
539
INVALID,
540
INSTR("vhdp", JITFUNC(Comp_VHdp), Dis_VectorDot, Int_VHdp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
541
INSTR("vcrs", JITFUNC(Comp_VCrs), Dis_Vcrs, Int_Vcrs, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
542
INSTR("vdet", JITFUNC(Comp_VDet), Dis_VectorDot, Int_Vdet, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
543
INVALID,
544
};
545
546
static const MIPSInstruction tableVFPU3[8] = // 011011 xxx ....... . ....... . .......
547
{
548
INSTR("vcmp", JITFUNC(Comp_Vcmp), Dis_Vcmp, Int_Vcmp, IN_OTHER|OUT_VFPU_CC|IS_VFPU|OUT_EAT_PREFIX),
549
INVALID,
550
INSTR("vmin", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vminmax, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
551
INSTR("vmax", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vminmax, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
552
INVALID,
553
INSTR("vscmp", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vscmp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
554
INSTR("vsge", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vsge, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
555
INSTR("vslt", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vslt, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
556
};
557
558
static const MIPSInstruction tableVFPU4Jump[32] = // 110100 xxxxx ..... . ....... . .......
559
{
560
ENCODING(VFPU4),
561
ENCODING(VFPU7),
562
ENCODING(VFPU9),
563
INSTR("vcst", JITFUNC(Comp_Vcst), Dis_Vcst, Int_Vcst, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
564
INVALID, INVALID, INVALID, INVALID,
565
566
//8
567
INVALID_X_8,
568
569
//16
570
INSTR("vf2in", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
571
INSTR("vf2iz", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
572
INSTR("vf2iu", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
573
INSTR("vf2id", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
574
//20
575
INSTR("vi2f", JITFUNC(Comp_Vi2f), Dis_Vf2i, Int_Vi2f, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
576
INSTR("vcmov", JITFUNC(Comp_Vcmov), Dis_Vcmov, Int_Vcmov, IN_OTHER|IN_VFPU_CC|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
577
INVALID,
578
INVALID,
579
//24 - 110100 11 ........ . ....... . .......
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
INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
588
};
589
590
static const MIPSInstruction tableVFPU7[32] = // 110100 00001 xxxxx . ....... . .......
591
{
592
INSTR("vrnds", JITFUNC(Comp_Generic), Dis_Vrnds, Int_Vrnds, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
593
INSTR("vrndi", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
594
INSTR("vrndf1", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
595
INSTR("vrndf2", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
596
597
INVALID, INVALID, INVALID, INVALID,
598
//8
599
INVALID, INVALID, INVALID, INVALID,
600
INVALID, INVALID, INVALID, INVALID,
601
//16
602
INVALID,
603
INVALID,
604
INSTR("vf2h", JITFUNC(Comp_Generic), Dis_Vf2h, Int_Vf2h, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
605
INSTR("vh2f", JITFUNC(Comp_Vh2f), Dis_Vh2f, Int_Vh2f, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
606
607
INVALID,
608
INVALID,
609
INSTR("vsbz", JITFUNC(Comp_Generic), Dis_Generic, Int_Vsbz, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
610
INSTR("vlgb", JITFUNC(Comp_Generic), Dis_Generic, Int_Vlgb, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
611
//24
612
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
613
INSTR("vc2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
614
INSTR("vus2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
615
INSTR("vs2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
616
617
INSTR("vi2uc", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
618
INSTR("vi2c", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
619
INSTR("vi2us", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
620
INSTR("vi2s", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
621
};
622
623
// 110100 00000 10100 0000000000000000
624
// 110100 00000 10111 0000000000000000
625
static const MIPSInstruction tableVFPU4[32] = // 110100 00000 xxxxx . ....... . .......
626
{
627
INSTR("vmov", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
628
INSTR("vabs", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
629
INSTR("vneg", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
630
INSTR("vidt", JITFUNC(Comp_VIdt), Dis_VectorSet1, Int_Vidt, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
631
INSTR("vsat0", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
632
INSTR("vsat1", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
633
INSTR("vzero", JITFUNC(Comp_VVectorInit), Dis_VectorSet1, Int_VVectorInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
634
INSTR("vone", JITFUNC(Comp_VVectorInit), Dis_VectorSet1, Int_VVectorInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
635
//8
636
INVALID_X_8,
637
//16
638
INSTR("vrcp", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
639
INSTR("vrsq", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
640
INSTR("vsin", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
641
INSTR("vcos", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
642
INSTR("vexp2", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
643
INSTR("vlog2", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
644
INSTR("vsqrt", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
645
INSTR("vasin", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
646
//24
647
INSTR("vnrcp", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
648
INVALID,
649
INSTR("vnsin", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
650
INVALID,
651
INSTR("vrexp2", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
652
INVALID, INVALID, INVALID,
653
};
654
655
static const MIPSInstruction tableVFPU5[8] = // 110111 xxx ....... ................
656
{
657
INSTR("vpfxs", JITFUNC(Comp_VPFX), Dis_VPFXST, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),
658
INSTR("vpfxs", 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("vpfxt", JITFUNC(Comp_VPFX), Dis_VPFXST, 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("vpfxd", JITFUNC(Comp_VPFX), Dis_VPFXD, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),
663
INSTR("viim.s", JITFUNC(Comp_Viim), Dis_Viim, Int_Viim, IN_IMM16|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
664
INSTR("vfim.s", JITFUNC(Comp_Vfim), Dis_Viim, Int_Viim, IN_IMM16|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
665
};
666
667
static const MIPSInstruction tableVFPU6[32] = // 111100 xxxxx ..... . ....... . .......
668
{
669
//0
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
INSTR("vmmul", JITFUNC(Comp_Vmmul), Dis_MatrixMult, Int_Vmmul, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
674
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
INSTR("v(h)tfm2", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
679
//8
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
INSTR("v(h)tfm3", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
684
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
INSTR("v(h)tfm4", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
689
//16
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
INSTR("vmscl", JITFUNC(Comp_Vmscl), Dis_Vmscl, Int_Vmscl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
694
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
INSTR("vcrsp.t/vqmul.q", JITFUNC(Comp_VCrossQuat), Dis_CrossQuat, Int_CrossQuat, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
699
//24
700
INVALID,
701
INVALID,
702
INVALID,
703
INVALID,
704
//28
705
ENCODING(VFPUMatrix1),
706
INSTR("vrot", JITFUNC(Comp_VRot), Dis_VRot, Int_Vrot, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
707
INVALID,
708
INVALID,
709
};
710
711
// TODO: Should this only be when bit 20 is 0?
712
static const MIPSInstruction tableVFPUMatrixSet1[16] = // 111100 11100 .xxxx . ....... . ....... (rm x is 16)
713
{
714
INSTR("vmmov", JITFUNC(Comp_Vmmov), Dis_MatrixSet2, Int_Vmmov, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
715
INVALID,
716
INVALID,
717
INSTR("vmidt", JITFUNC(Comp_VMatrixInit), Dis_MatrixSet1, Int_VMatrixInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
718
719
INVALID,
720
INVALID,
721
INSTR("vmzero", JITFUNC(Comp_VMatrixInit), Dis_MatrixSet1, Int_VMatrixInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
722
INSTR("vmone", JITFUNC(Comp_VMatrixInit), Dis_MatrixSet1, Int_VMatrixInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
723
724
INVALID_X_8,
725
};
726
727
static const MIPSInstruction tableVFPU9[32] = // 110100 00010 xxxxx . ....... . .......
728
{
729
INSTR("vsrt1", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt1, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
730
INSTR("vsrt2", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt2, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
731
INSTR("vbfy1", JITFUNC(Comp_Vbfy), Dis_Vbfy, Int_Vbfy, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
732
INSTR("vbfy2", JITFUNC(Comp_Vbfy), Dis_Vbfy, Int_Vbfy, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
733
//4
734
INSTR("vocp", JITFUNC(Comp_Vocp), Dis_Vbfy, Int_Vocp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), // one's complement
735
INSTR("vsocp", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsocp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
736
INSTR("vfad", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vfad, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
737
INSTR("vavg", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vavg, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
738
//8
739
INSTR("vsrt3", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
740
INSTR("vsrt4", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt4, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
741
INSTR("vsgn", JITFUNC(Comp_Vsgn), Dis_Vbfy, Int_Vsgn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
742
INVALID,
743
//12
744
INVALID,
745
INVALID,
746
INVALID,
747
INVALID,
748
749
//16
750
INSTR("vmfvc", JITFUNC(Comp_Vmfvc), Dis_Vmfvc, Int_Vmfvc, IN_OTHER|IN_VFPU_CC|OUT_OTHER|IS_VFPU),
751
INSTR("vmtvc", JITFUNC(Comp_Vmtvc), Dis_Vmtvc, Int_Vmtvc, IN_OTHER|OUT_VFPU_CC|OUT_OTHER|IS_VFPU|OUT_VFPU_PREFIX),
752
INVALID,
753
INVALID,
754
755
//20
756
INVALID, INVALID, INVALID, INVALID,
757
//24
758
INVALID,
759
INSTR("vt4444", JITFUNC(Comp_ColorConv), Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
760
INSTR("vt5551", JITFUNC(Comp_ColorConv), Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
761
INSTR("vt5650", JITFUNC(Comp_ColorConv), Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
762
763
//28
764
INVALID, INVALID, INVALID, INVALID,
765
};
766
767
static const MIPSInstruction tableALLEGREX0[32] = // 011111 ..... ..... ..... xxxxx 100000 - or ending with 011000?
768
{
769
INVALID,
770
INVALID,
771
INSTR("wsbh", JITFUNC(Comp_Allegrex2), Dis_Allegrex2, Int_Allegrex2, IN_RT|OUT_RD),
772
INSTR("wsbw", JITFUNC(Comp_Allegrex2), Dis_Allegrex2, Int_Allegrex2, IN_RT|OUT_RD),
773
INVALID, INVALID, INVALID, INVALID,
774
//8
775
INVALID_X_8,
776
//16
777
INSTR("seb", JITFUNC(Comp_Allegrex), Dis_Allegrex,Int_Allegrex, IN_RT|OUT_RD),
778
INVALID,
779
INVALID,
780
INVALID,
781
//20
782
INSTR("bitrev", JITFUNC(Comp_Allegrex), Dis_Allegrex,Int_Allegrex, IN_RT|OUT_RD),
783
INVALID,
784
INVALID,
785
INVALID,
786
//24
787
INSTR("seh", JITFUNC(Comp_Allegrex), Dis_Allegrex,Int_Allegrex, IN_RT|OUT_RD),
788
INVALID,
789
INVALID,
790
INVALID,
791
//28
792
INVALID,
793
INVALID,
794
INVALID,
795
INVALID,
796
};
797
798
static 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 {
806
EncodingBitsInfo(u8 shift_, u8 maskBits_) : shift(shift_) {
807
mask = (1 << maskBits_) - 1;
808
}
809
u8 shift;
810
u32 mask;
811
};
812
813
static 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
static 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.
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(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
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(Log::CPU,"MIPSCompileOp %08x failed",op.encoding);
912
}
913
if (info & OUT_EAT_PREFIX)
914
jit->EatPrefix();
915
} else {
916
// Used to _REPORT this, but I'm confident we have all instructions now, any caught here
917
// are due to games crashing, due to cheats or bugs.
918
ERROR_LOG(Log::CPU, "MIPSCompileOp: Invalid instruction %08x", op.encoding);
919
}
920
}
921
922
void MIPSDisAsm(MIPSOpcode op, u32 pc, char *out, size_t outSize, bool tabsToSpaces) {
923
if (op == 0) {
924
truncate_cpy(out, outSize, "nop");
925
} else {
926
const MIPSInstruction *instr = MIPSGetInstruction(op);
927
if (instr && instr->disasm) {
928
instr->disasm(op, pc, out, outSize);
929
if (tabsToSpaces) {
930
while (*out) {
931
if (*out == '\t')
932
*out = ' ';
933
out++;
934
}
935
}
936
} else {
937
truncate_cpy(out, outSize, "no instruction :(");
938
}
939
}
940
}
941
942
static inline void Interpret(const MIPSInstruction *instr, MIPSOpcode op) {
943
if (instr && instr->interpret) {
944
instr->interpret(op);
945
} else {
946
ERROR_LOG_REPORT(Log::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, sizeof(disasm));
950
_dbg_assert_msg_(0, "%s", disasm);
951
currentMIPS->pc += 4;
952
}
953
}
954
955
inline int GetInstructionCycleEstimate(const MIPSInstruction *instr) {
956
if (instr)
957
return instr->flags.cycles;
958
return 1;
959
}
960
961
void MIPSInterpret(MIPSOpcode op) {
962
const MIPSInstruction *instr = MIPSGetInstruction(op);
963
Interpret(instr, op);
964
}
965
966
#define _RS ((op>>21) & 0x1F)
967
#define _RT ((op>>16) & 0x1F)
968
#define _RD ((op>>11) & 0x1F)
969
#define R(i) (curMips->r[i])
970
971
static inline void RunUntilFast() {
972
MIPSState *curMips = currentMIPS;
973
// NEVER stop in a delay slot!
974
while (curMips->downcount >= 0 && coreState == CORE_RUNNING_CPU) {
975
do {
976
// Replacements and similar are processed here, intentionally.
977
MIPSOpcode op = MIPSOpcode(Memory::Read_U32(curMips->pc));
978
979
bool wasInDelaySlot = curMips->inDelaySlot;
980
const MIPSInstruction *instr = MIPSGetInstruction(op);
981
Interpret(instr, op);
982
curMips->downcount -= GetInstructionCycleEstimate(instr);
983
984
// The reason we have to check this is the delay slot hack in Int_Syscall.
985
if (curMips->inDelaySlot && wasInDelaySlot) {
986
curMips->pc = curMips->nextPC;
987
curMips->inDelaySlot = false;
988
}
989
} while (curMips->inDelaySlot);
990
}
991
}
992
993
static void RunUntilWithChecks(u64 globalTicks) {
994
MIPSState *curMips = currentMIPS;
995
// NEVER stop in a delay slot!
996
bool hasBPs = g_breakpoints.HasBreakPoints();
997
bool hasMCs = g_breakpoints.HasMemChecks();
998
while (curMips->downcount >= 0 && coreState == CORE_RUNNING_CPU) {
999
do {
1000
// Replacements and similar are processed here, intentionally.
1001
MIPSOpcode op = MIPSOpcode(Memory::Read_U32(curMips->pc));
1002
const MIPSInstruction *instr = MIPSGetInstruction(op);
1003
1004
// Check for breakpoint
1005
if (hasBPs && g_breakpoints.IsAddressBreakPoint(curMips->pc) && g_breakpoints.CheckSkipFirst() != curMips->pc) {
1006
auto cond = g_breakpoints.GetBreakPointCondition(currentMIPS->pc);
1007
if (!cond || cond->Evaluate()) {
1008
Core_Break(BreakReason::CpuBreakpoint, curMips->pc);
1009
if (g_breakpoints.IsTempBreakPoint(curMips->pc))
1010
g_breakpoints.RemoveBreakPoint(curMips->pc);
1011
break;
1012
}
1013
}
1014
if (hasMCs && (instr->flags & (IN_MEM | OUT_MEM)) != 0 && g_breakpoints.CheckSkipFirst() != curMips->pc && instr->interpret != &Int_Syscall) {
1015
// This is common for all IN_MEM/OUT_MEM funcs.
1016
int offset = (instr->flags & IS_VFPU) != 0 ? SignExtend16ToS32(op & 0xFFFC) : SignExtend16ToS32(op);
1017
u32 addr = (R(_RS) + offset) & 0xFFFFFFFC;
1018
int sz = MIPSGetMemoryAccessSize(op);
1019
1020
if ((instr->flags & IN_MEM) != 0)
1021
g_breakpoints.ExecMemCheck(addr, false, sz, curMips->pc, "interpret");
1022
if ((instr->flags & OUT_MEM) != 0)
1023
g_breakpoints.ExecMemCheck(addr, true, sz, curMips->pc, "interpret");
1024
1025
// If it tripped, bail without running.
1026
if (coreState == CORE_STEPPING_CPU)
1027
break;
1028
}
1029
1030
bool wasInDelaySlot = curMips->inDelaySlot;
1031
Interpret(instr, op);
1032
curMips->downcount -= GetInstructionCycleEstimate(instr);
1033
1034
// The reason we have to check this is the delay slot hack in Int_Syscall.
1035
if (curMips->inDelaySlot && wasInDelaySlot) {
1036
curMips->pc = curMips->nextPC;
1037
curMips->inDelaySlot = false;
1038
}
1039
} while (curMips->inDelaySlot);
1040
1041
if (CoreTiming::GetTicks() > globalTicks)
1042
return;
1043
}
1044
}
1045
1046
int MIPSInterpret_RunUntil(u64 globalTicks) {
1047
MIPSState *curMips = currentMIPS;
1048
while (coreState == CORE_RUNNING_CPU) {
1049
CoreTiming::Advance();
1050
1051
uint64_t ticksLeft = globalTicks - CoreTiming::GetTicks();
1052
if (g_breakpoints.HasBreakPoints() || g_breakpoints.HasMemChecks() || ticksLeft <= curMips->downcount)
1053
RunUntilWithChecks(globalTicks);
1054
else
1055
RunUntilFast();
1056
1057
if (CoreTiming::GetTicks() > globalTicks) {
1058
// DEBUG_LOG(Log::CPU, "Hit the max ticks, bailing 1 : %llu, %llu", globalTicks, CoreTiming::GetTicks());
1059
return 1;
1060
}
1061
}
1062
1063
return 1;
1064
}
1065
1066
const char *MIPSGetName(MIPSOpcode op)
1067
{
1068
static const char * const noname = "unk";
1069
const MIPSInstruction *instr = MIPSGetInstruction(op);
1070
if (!instr)
1071
return noname;
1072
else
1073
return instr->name;
1074
}
1075
1076
MIPSInfo MIPSGetInfo(MIPSOpcode op)
1077
{
1078
// int crunch = CRUNCH_MIPS_OP(op);
1079
const MIPSInstruction *instr = MIPSGetInstruction(op);
1080
if (instr)
1081
return instr->flags;
1082
else
1083
return MIPSInfo(BAD_INSTRUCTION);
1084
}
1085
1086
MIPSInterpretFunc MIPSGetInterpretFunc(MIPSOpcode op)
1087
{
1088
const MIPSInstruction *instr = MIPSGetInstruction(op);
1089
if (instr->interpret)
1090
return instr->interpret;
1091
else
1092
return 0;
1093
}
1094
1095
// TODO: Do something that makes sense here.
1096
int MIPSGetInstructionCycleEstimate(MIPSOpcode op)
1097
{
1098
const MIPSInstruction *instr = MIPSGetInstruction(op);
1099
return GetInstructionCycleEstimate(instr);
1100
}
1101
1102
int MIPSGetMemoryAccessSize(MIPSOpcode op) {
1103
MIPSInfo info = MIPSGetInfo(op);
1104
if ((info & (IN_MEM | OUT_MEM)) == 0) {
1105
return 0;
1106
}
1107
1108
switch (info & MEMTYPE_MASK) {
1109
case MEMTYPE_BYTE:
1110
return 1;
1111
case MEMTYPE_HWORD:
1112
return 2;
1113
case MEMTYPE_WORD:
1114
case MEMTYPE_FLOAT:
1115
return 4;
1116
case MEMTYPE_VQUAD:
1117
return 16;
1118
}
1119
1120
return 0;
1121
}
1122
1123
std::string MIPSDisasmAt(u32 compilerPC) {
1124
char temp[512];
1125
MIPSDisAsm(Memory::Read_Instruction(compilerPC), 0, temp, sizeof(temp));
1126
return temp;
1127
}
1128
1129