1 // Copyright 2018 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4
5 #include "Core/DSP/Jit/x64/DSPJitTables.h"
6
7 #include <array>
8
9 #include "Common/CommonTypes.h"
10 #include "Core/DSP/DSPTables.h"
11 #include "Core/DSP/Jit/x64/DSPEmitter.h"
12
13 namespace DSP::JIT::x64
14 {
15 struct JITOpInfo
16 {
17 u16 opcode;
18 u16 opcode_mask;
19 JITFunction function;
20 };
21
22 // clang-format off
23 const std::array<JITOpInfo, 214> s_opcodes =
24 {{
25 {0x0000, 0xfffc, &DSPEmitter::nop},
26
27 {0x0004, 0xfffc, &DSPEmitter::dar},
28 {0x0008, 0xfffc, &DSPEmitter::iar},
29 {0x000c, 0xfffc, &DSPEmitter::subarn},
30 {0x0010, 0xfff0, &DSPEmitter::addarn},
31
32 {0x0021, 0xffff, &DSPEmitter::halt},
33
34 {0x02d0, 0xffff, &DSPEmitter::ret},
35 {0x02d1, 0xffff, &DSPEmitter::ret},
36 {0x02d2, 0xffff, &DSPEmitter::ret},
37 {0x02d3, 0xffff, &DSPEmitter::ret},
38 {0x02d4, 0xffff, &DSPEmitter::ret},
39 {0x02d5, 0xffff, &DSPEmitter::ret},
40 {0x02d6, 0xffff, &DSPEmitter::ret},
41 {0x02d7, 0xffff, &DSPEmitter::ret},
42 {0x02d8, 0xffff, &DSPEmitter::ret},
43 {0x02d9, 0xffff, &DSPEmitter::ret},
44 {0x02da, 0xffff, &DSPEmitter::ret},
45 {0x02db, 0xffff, &DSPEmitter::ret},
46 {0x02dc, 0xffff, &DSPEmitter::ret},
47 {0x02dd, 0xffff, &DSPEmitter::ret},
48 {0x02de, 0xffff, &DSPEmitter::ret},
49 {0x02df, 0xffff, &DSPEmitter::ret},
50
51 {0x02ff, 0xffff, &DSPEmitter::rti},
52
53 {0x02b0, 0xffff, &DSPEmitter::call},
54 {0x02b1, 0xffff, &DSPEmitter::call},
55 {0x02b2, 0xffff, &DSPEmitter::call},
56 {0x02b3, 0xffff, &DSPEmitter::call},
57 {0x02b4, 0xffff, &DSPEmitter::call},
58 {0x02b5, 0xffff, &DSPEmitter::call},
59 {0x02b6, 0xffff, &DSPEmitter::call},
60 {0x02b7, 0xffff, &DSPEmitter::call},
61 {0x02b8, 0xffff, &DSPEmitter::call},
62 {0x02b9, 0xffff, &DSPEmitter::call},
63 {0x02ba, 0xffff, &DSPEmitter::call},
64 {0x02bb, 0xffff, &DSPEmitter::call},
65 {0x02bc, 0xffff, &DSPEmitter::call},
66 {0x02bd, 0xffff, &DSPEmitter::call},
67 {0x02be, 0xffff, &DSPEmitter::call},
68 {0x02bf, 0xffff, &DSPEmitter::call},
69
70 {0x0270, 0xffff, &DSPEmitter::ifcc},
71 {0x0271, 0xffff, &DSPEmitter::ifcc},
72 {0x0272, 0xffff, &DSPEmitter::ifcc},
73 {0x0273, 0xffff, &DSPEmitter::ifcc},
74 {0x0274, 0xffff, &DSPEmitter::ifcc},
75 {0x0275, 0xffff, &DSPEmitter::ifcc},
76 {0x0276, 0xffff, &DSPEmitter::ifcc},
77 {0x0277, 0xffff, &DSPEmitter::ifcc},
78 {0x0278, 0xffff, &DSPEmitter::ifcc},
79 {0x0279, 0xffff, &DSPEmitter::ifcc},
80 {0x027a, 0xffff, &DSPEmitter::ifcc},
81 {0x027b, 0xffff, &DSPEmitter::ifcc},
82 {0x027c, 0xffff, &DSPEmitter::ifcc},
83 {0x027d, 0xffff, &DSPEmitter::ifcc},
84 {0x027e, 0xffff, &DSPEmitter::ifcc},
85 {0x027f, 0xffff, &DSPEmitter::ifcc},
86
87 {0x0290, 0xffff, &DSPEmitter::jcc},
88 {0x0291, 0xffff, &DSPEmitter::jcc},
89 {0x0292, 0xffff, &DSPEmitter::jcc},
90 {0x0293, 0xffff, &DSPEmitter::jcc},
91 {0x0294, 0xffff, &DSPEmitter::jcc},
92 {0x0295, 0xffff, &DSPEmitter::jcc},
93 {0x0296, 0xffff, &DSPEmitter::jcc},
94 {0x0297, 0xffff, &DSPEmitter::jcc},
95 {0x0298, 0xffff, &DSPEmitter::jcc},
96 {0x0299, 0xffff, &DSPEmitter::jcc},
97 {0x029a, 0xffff, &DSPEmitter::jcc},
98 {0x029b, 0xffff, &DSPEmitter::jcc},
99 {0x029c, 0xffff, &DSPEmitter::jcc},
100 {0x029d, 0xffff, &DSPEmitter::jcc},
101 {0x029e, 0xffff, &DSPEmitter::jcc},
102 {0x029f, 0xffff, &DSPEmitter::jcc},
103
104 {0x1700, 0xff1f, &DSPEmitter::jmprcc},
105 {0x1701, 0xff1f, &DSPEmitter::jmprcc},
106 {0x1702, 0xff1f, &DSPEmitter::jmprcc},
107 {0x1703, 0xff1f, &DSPEmitter::jmprcc},
108 {0x1704, 0xff1f, &DSPEmitter::jmprcc},
109 {0x1705, 0xff1f, &DSPEmitter::jmprcc},
110 {0x1706, 0xff1f, &DSPEmitter::jmprcc},
111 {0x1707, 0xff1f, &DSPEmitter::jmprcc},
112 {0x1708, 0xff1f, &DSPEmitter::jmprcc},
113 {0x1709, 0xff1f, &DSPEmitter::jmprcc},
114 {0x170a, 0xff1f, &DSPEmitter::jmprcc},
115 {0x170b, 0xff1f, &DSPEmitter::jmprcc},
116 {0x170c, 0xff1f, &DSPEmitter::jmprcc},
117 {0x170d, 0xff1f, &DSPEmitter::jmprcc},
118 {0x170e, 0xff1f, &DSPEmitter::jmprcc},
119 {0x170f, 0xff1f, &DSPEmitter::jmprcc},
120
121 {0x1710, 0xff1f, &DSPEmitter::callr},
122 {0x1711, 0xff1f, &DSPEmitter::callr},
123 {0x1712, 0xff1f, &DSPEmitter::callr},
124 {0x1713, 0xff1f, &DSPEmitter::callr},
125 {0x1714, 0xff1f, &DSPEmitter::callr},
126 {0x1715, 0xff1f, &DSPEmitter::callr},
127 {0x1716, 0xff1f, &DSPEmitter::callr},
128 {0x1717, 0xff1f, &DSPEmitter::callr},
129 {0x1718, 0xff1f, &DSPEmitter::callr},
130 {0x1719, 0xff1f, &DSPEmitter::callr},
131 {0x171a, 0xff1f, &DSPEmitter::callr},
132 {0x171b, 0xff1f, &DSPEmitter::callr},
133 {0x171c, 0xff1f, &DSPEmitter::callr},
134 {0x171d, 0xff1f, &DSPEmitter::callr},
135 {0x171e, 0xff1f, &DSPEmitter::callr},
136 {0x171f, 0xff1f, &DSPEmitter::callr},
137
138 {0x1200, 0xff00, &DSPEmitter::sbclr},
139 {0x1300, 0xff00, &DSPEmitter::sbset},
140
141 {0x1400, 0xfec0, &DSPEmitter::lsl},
142 {0x1440, 0xfec0, &DSPEmitter::lsr},
143 {0x1480, 0xfec0, &DSPEmitter::asl},
144 {0x14c0, 0xfec0, &DSPEmitter::asr},
145
146 // These two were discovered by ector
147 {0x02ca, 0xffff, &DSPEmitter::lsrn},
148 {0x02cb, 0xffff, &DSPEmitter::asrn},
149
150 {0x0080, 0xffe0, &DSPEmitter::lri},
151 {0x00c0, 0xffe0, &DSPEmitter::lr},
152 {0x00e0, 0xffe0, &DSPEmitter::sr},
153
154 {0x1c00, 0xfc00, &DSPEmitter::mrr},
155
156 {0x1600, 0xff00, &DSPEmitter::si},
157
158 {0x0400, 0xfe00, &DSPEmitter::addis},
159 {0x0600, 0xfe00, &DSPEmitter::cmpis},
160 {0x0800, 0xf800, &DSPEmitter::lris},
161
162 {0x0200, 0xfeff, &DSPEmitter::addi},
163 {0x0220, 0xfeff, &DSPEmitter::xori},
164 {0x0240, 0xfeff, &DSPEmitter::andi},
165 {0x0260, 0xfeff, &DSPEmitter::ori},
166 {0x0280, 0xfeff, &DSPEmitter::cmpi},
167
168 {0x02a0, 0xfeff, &DSPEmitter::andf},
169 {0x02c0, 0xfeff, &DSPEmitter::andcf},
170
171 {0x0210, 0xfefc, &DSPEmitter::ilrr},
172 {0x0214, 0xfefc, &DSPEmitter::ilrrd},
173 {0x0218, 0xfefc, &DSPEmitter::ilrri},
174 {0x021c, 0xfefc, &DSPEmitter::ilrrn},
175
176 // LOOPS
177 {0x0040, 0xffe0, &DSPEmitter::loop},
178 {0x0060, 0xffe0, &DSPEmitter::bloop},
179 {0x1000, 0xff00, &DSPEmitter::loopi},
180 {0x1100, 0xff00, &DSPEmitter::bloopi},
181
182 // Load and store value pointed by indexing reg and increment; LRR/SRR variants
183 {0x1800, 0xff80, &DSPEmitter::lrr},
184 {0x1880, 0xff80, &DSPEmitter::lrrd},
185 {0x1900, 0xff80, &DSPEmitter::lrri},
186 {0x1980, 0xff80, &DSPEmitter::lrrn},
187
188 {0x1a00, 0xff80, &DSPEmitter::srr},
189 {0x1a80, 0xff80, &DSPEmitter::srrd},
190 {0x1b00, 0xff80, &DSPEmitter::srri},
191 {0x1b80, 0xff80, &DSPEmitter::srrn},
192
193 // 2
194 {0x2000, 0xf800, &DSPEmitter::lrs},
195 {0x2800, 0xf800, &DSPEmitter::srs},
196
197 // opcodes that can be extended
198
199 // 3 - main opcode defined by 9 bits, extension defined by last 7 bits!!
200 {0x3000, 0xfc80, &DSPEmitter::xorr},
201 {0x3400, 0xfc80, &DSPEmitter::andr},
202 {0x3800, 0xfc80, &DSPEmitter::orr},
203 {0x3c00, 0xfe80, &DSPEmitter::andc},
204 {0x3e00, 0xfe80, &DSPEmitter::orc},
205 {0x3080, 0xfe80, &DSPEmitter::xorc},
206 {0x3280, 0xfe80, &DSPEmitter::notc},
207 {0x3480, 0xfc80, &DSPEmitter::lsrnrx},
208 {0x3880, 0xfc80, &DSPEmitter::asrnrx},
209 {0x3c80, 0xfe80, &DSPEmitter::lsrnr},
210 {0x3e80, 0xfe80, &DSPEmitter::asrnr},
211
212 // 4
213 {0x4000, 0xf800, &DSPEmitter::addr},
214 {0x4800, 0xfc00, &DSPEmitter::addax},
215 {0x4c00, 0xfe00, &DSPEmitter::add},
216 {0x4e00, 0xfe00, &DSPEmitter::addp},
217
218 // 5
219 {0x5000, 0xf800, &DSPEmitter::subr},
220 {0x5800, 0xfc00, &DSPEmitter::subax},
221 {0x5c00, 0xfe00, &DSPEmitter::sub},
222 {0x5e00, 0xfe00, &DSPEmitter::subp},
223
224 // 6
225 {0x6000, 0xf800, &DSPEmitter::movr},
226 {0x6800, 0xfc00, &DSPEmitter::movax},
227 {0x6c00, 0xfe00, &DSPEmitter::mov},
228 {0x6e00, 0xfe00, &DSPEmitter::movp},
229
230 // 7
231 {0x7000, 0xfc00, &DSPEmitter::addaxl},
232 {0x7400, 0xfe00, &DSPEmitter::incm},
233 {0x7600, 0xfe00, &DSPEmitter::inc},
234 {0x7800, 0xfe00, &DSPEmitter::decm},
235 {0x7a00, 0xfe00, &DSPEmitter::dec},
236 {0x7c00, 0xfe00, &DSPEmitter::neg},
237 {0x7e00, 0xfe00, &DSPEmitter::movnp},
238
239 // 8
240 {0x8000, 0xf700, &DSPEmitter::nx},
241 {0x8100, 0xf700, &DSPEmitter::clr},
242 {0x8200, 0xff00, &DSPEmitter::cmp},
243 {0x8300, 0xff00, &DSPEmitter::mulaxh},
244 {0x8400, 0xff00, &DSPEmitter::clrp},
245 {0x8500, 0xff00, &DSPEmitter::tstprod},
246 {0x8600, 0xfe00, &DSPEmitter::tstaxh},
247 {0x8a00, 0xff00, &DSPEmitter::srbith},
248 {0x8b00, 0xff00, &DSPEmitter::srbith},
249 {0x8c00, 0xff00, &DSPEmitter::srbith},
250 {0x8d00, 0xff00, &DSPEmitter::srbith},
251 {0x8e00, 0xff00, &DSPEmitter::srbith},
252 {0x8f00, 0xff00, &DSPEmitter::srbith},
253
254 // 9
255 {0x9000, 0xf700, &DSPEmitter::mul},
256 {0x9100, 0xf700, &DSPEmitter::asr16},
257 {0x9200, 0xf600, &DSPEmitter::mulmvz},
258 {0x9400, 0xf600, &DSPEmitter::mulac},
259 {0x9600, 0xf600, &DSPEmitter::mulmv},
260
261 // A-B
262 {0xa000, 0xe700, &DSPEmitter::mulx},
263 {0xa100, 0xf700, &DSPEmitter::abs},
264 {0xa200, 0xe600, &DSPEmitter::mulxmvz},
265 {0xa400, 0xe600, &DSPEmitter::mulxac},
266 {0xa600, 0xe600, &DSPEmitter::mulxmv},
267 {0xb100, 0xf700, &DSPEmitter::tst},
268
269 // C-D
270 {0xc000, 0xe700, &DSPEmitter::mulc},
271 {0xc100, 0xe700, &DSPEmitter::cmpar},
272 {0xc200, 0xe600, &DSPEmitter::mulcmvz},
273 {0xc400, 0xe600, &DSPEmitter::mulcac},
274 {0xc600, 0xe600, &DSPEmitter::mulcmv},
275
276 // E
277 {0xe000, 0xfc00, &DSPEmitter::maddx},
278 {0xe400, 0xfc00, &DSPEmitter::msubx},
279 {0xe800, 0xfc00, &DSPEmitter::maddc},
280 {0xec00, 0xfc00, &DSPEmitter::msubc},
281
282 // F
283 {0xf000, 0xfe00, &DSPEmitter::lsl16},
284 {0xf200, 0xfe00, &DSPEmitter::madd},
285 {0xf400, 0xfe00, &DSPEmitter::lsr16},
286 {0xf600, 0xfe00, &DSPEmitter::msub},
287 {0xf800, 0xfc00, &DSPEmitter::addpaxz},
288 {0xfc00, 0xfe00, &DSPEmitter::clrl},
289 {0xfe00, 0xfe00, &DSPEmitter::movpz},
290 }};
291
292 constexpr std::array<JITOpInfo, 25> s_opcodes_ext
293 {{
294 {0x0000, 0x00fc, &DSPEmitter::nop},
295
296 {0x0004, 0x00fc, &DSPEmitter::dr},
297 {0x0008, 0x00fc, &DSPEmitter::ir},
298 {0x000c, 0x00fc, &DSPEmitter::nr},
299 {0x0010, 0x00f0, &DSPEmitter::mv},
300
301 {0x0020, 0x00e4, &DSPEmitter::s},
302 {0x0024, 0x00e4, &DSPEmitter::sn},
303
304 {0x0040, 0x00c4, &DSPEmitter::l},
305 {0x0044, 0x00c4, &DSPEmitter::ln},
306
307 {0x0080, 0x00ce, &DSPEmitter::ls},
308 {0x0082, 0x00ce, &DSPEmitter::sl},
309 {0x0084, 0x00ce, &DSPEmitter::lsn},
310 {0x0086, 0x00ce, &DSPEmitter::sln},
311 {0x0088, 0x00ce, &DSPEmitter::lsm},
312 {0x008a, 0x00ce, &DSPEmitter::slm},
313 {0x008c, 0x00ce, &DSPEmitter::lsnm},
314 {0x008e, 0x00ce, &DSPEmitter::slnm},
315
316 {0x00c3, 0x00cf, &DSPEmitter::ldax},
317 {0x00c7, 0x00cf, &DSPEmitter::ldaxn},
318 {0x00cb, 0x00cf, &DSPEmitter::ldaxm},
319 {0x00cf, 0x00cf, &DSPEmitter::ldaxnm},
320
321 {0x00c0, 0x00cc, &DSPEmitter::ld},
322 {0x00c4, 0x00cc, &DSPEmitter::ldn},
323 {0x00c8, 0x00cc, &DSPEmitter::ldm},
324 {0x00cc, 0x00cc, &DSPEmitter::ldnm},
325 }};
326 // clang-format on
327
328 namespace
329 {
330 std::array<JITFunction, 65536> s_op_table;
331 std::array<JITFunction, 256> s_ext_op_table;
332 bool s_tables_initialized = false;
333 } // Anonymous namespace
334
GetOp(UDSPInstruction inst)335 JITFunction GetOp(UDSPInstruction inst)
336 {
337 return s_op_table[inst];
338 }
339
GetExtOp(UDSPInstruction inst)340 JITFunction GetExtOp(UDSPInstruction inst)
341 {
342 const bool has_seven_bit_extension = (inst >> 12) == 0x3;
343
344 if (has_seven_bit_extension)
345 return s_ext_op_table[inst & 0x7F];
346
347 return s_ext_op_table[inst & 0xFF];
348 }
349
InitInstructionTables()350 void InitInstructionTables()
351 {
352 if (s_tables_initialized)
353 return;
354
355 // ext op table
356 for (size_t i = 0; i < s_ext_op_table.size(); i++)
357 {
358 s_ext_op_table[i] = nullptr;
359
360 const auto iter = FindByOpcode(static_cast<UDSPInstruction>(i), s_opcodes_ext);
361 if (iter == s_opcodes_ext.cend())
362 continue;
363
364 s_ext_op_table[i] = iter->function;
365 }
366
367 // op table
368 for (size_t i = 0; i < s_op_table.size(); i++)
369 {
370 s_op_table[i] = nullptr;
371
372 const auto iter = FindByOpcode(static_cast<UDSPInstruction>(i), s_opcodes);
373 if (iter == s_opcodes.cend())
374 continue;
375
376 s_op_table[i] = iter->function;
377 }
378
379 s_tables_initialized = true;
380 }
381 } // namespace DSP::JIT::x64
382