CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

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