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