1 // Copyright 2012 Michael Kang, 2014 Citra Emulator Project
2 // Licensed under GPLv2 or any later version
3 // Refer to the license.txt file included.
4 
5 #define CITRA_IGNORE_EXIT(x)
6 
7 #include <algorithm>
8 #include <cinttypes>
9 #include <cstdio>
10 #include "common/common_types.h"
11 #include "common/logging/log.h"
12 #include "common/microprofile.h"
13 #include "core/arm/dyncom/arm_dyncom_dec.h"
14 #include "core/arm/dyncom/arm_dyncom_interpreter.h"
15 #include "core/arm/dyncom/arm_dyncom_run.h"
16 #include "core/arm/dyncom/arm_dyncom_thumb.h"
17 #include "core/arm/dyncom/arm_dyncom_trans.h"
18 #include "core/arm/skyeye_common/armstate.h"
19 #include "core/arm/skyeye_common/armsupp.h"
20 #include "core/arm/skyeye_common/vfp/vfp.h"
21 #include "core/core.h"
22 #include "core/core_timing.h"
23 #include "core/gdbstub/gdbstub.h"
24 #include "core/hle/kernel/svc.h"
25 #include "core/memory.h"
26 
27 #define RM BITS(sht_oper, 0, 3)
28 #define RS BITS(sht_oper, 8, 11)
29 
30 #define glue(x, y) x##y
31 #define DPO(s) glue(DataProcessingOperands, s)
32 #define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i))
33 #define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i))
34 #define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
35 #define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
36 
CondPassed(const ARMul_State * cpu,unsigned int cond)37 static bool CondPassed(const ARMul_State* cpu, unsigned int cond) {
38     const bool n_flag = cpu->NFlag != 0;
39     const bool z_flag = cpu->ZFlag != 0;
40     const bool c_flag = cpu->CFlag != 0;
41     const bool v_flag = cpu->VFlag != 0;
42 
43     switch (cond) {
44     case ConditionCode::EQ:
45         return z_flag;
46     case ConditionCode::NE:
47         return !z_flag;
48     case ConditionCode::CS:
49         return c_flag;
50     case ConditionCode::CC:
51         return !c_flag;
52     case ConditionCode::MI:
53         return n_flag;
54     case ConditionCode::PL:
55         return !n_flag;
56     case ConditionCode::VS:
57         return v_flag;
58     case ConditionCode::VC:
59         return !v_flag;
60     case ConditionCode::HI:
61         return (c_flag && !z_flag);
62     case ConditionCode::LS:
63         return (!c_flag || z_flag);
64     case ConditionCode::GE:
65         return (n_flag == v_flag);
66     case ConditionCode::LT:
67         return (n_flag != v_flag);
68     case ConditionCode::GT:
69         return (!z_flag && (n_flag == v_flag));
70     case ConditionCode::LE:
71         return (z_flag || (n_flag != v_flag));
72     case ConditionCode::AL:
73     case ConditionCode::NV: // Unconditional
74         return true;
75     }
76 
77     return false;
78 }
79 
DPO(Immediate)80 static unsigned int DPO(Immediate)(ARMul_State* cpu, unsigned int sht_oper) {
81     unsigned int immed_8 = BITS(sht_oper, 0, 7);
82     unsigned int rotate_imm = BITS(sht_oper, 8, 11);
83     unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);
84     if (rotate_imm == 0)
85         cpu->shifter_carry_out = cpu->CFlag;
86     else
87         cpu->shifter_carry_out = BIT(shifter_operand, 31);
88     return shifter_operand;
89 }
90 
DPO(Register)91 static unsigned int DPO(Register)(ARMul_State* cpu, unsigned int sht_oper) {
92     unsigned int rm = CHECK_READ_REG15(cpu, RM);
93     unsigned int shifter_operand = rm;
94     cpu->shifter_carry_out = cpu->CFlag;
95     return shifter_operand;
96 }
97 
DPO(LogicalShiftLeftByImmediate)98 static unsigned int DPO(LogicalShiftLeftByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
99     int shift_imm = BITS(sht_oper, 7, 11);
100     unsigned int rm = CHECK_READ_REG15(cpu, RM);
101     unsigned int shifter_operand;
102     if (shift_imm == 0) {
103         shifter_operand = rm;
104         cpu->shifter_carry_out = cpu->CFlag;
105     } else {
106         shifter_operand = rm << shift_imm;
107         cpu->shifter_carry_out = BIT(rm, 32 - shift_imm);
108     }
109     return shifter_operand;
110 }
111 
DPO(LogicalShiftLeftByRegister)112 static unsigned int DPO(LogicalShiftLeftByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
113     int shifter_operand;
114     unsigned int rm = CHECK_READ_REG15(cpu, RM);
115     unsigned int rs = CHECK_READ_REG15(cpu, RS);
116     if (BITS(rs, 0, 7) == 0) {
117         shifter_operand = rm;
118         cpu->shifter_carry_out = cpu->CFlag;
119     } else if (BITS(rs, 0, 7) < 32) {
120         shifter_operand = rm << BITS(rs, 0, 7);
121         cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7));
122     } else if (BITS(rs, 0, 7) == 32) {
123         shifter_operand = 0;
124         cpu->shifter_carry_out = BIT(rm, 0);
125     } else {
126         shifter_operand = 0;
127         cpu->shifter_carry_out = 0;
128     }
129     return shifter_operand;
130 }
131 
DPO(LogicalShiftRightByImmediate)132 static unsigned int DPO(LogicalShiftRightByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
133     unsigned int rm = CHECK_READ_REG15(cpu, RM);
134     unsigned int shifter_operand;
135     int shift_imm = BITS(sht_oper, 7, 11);
136     if (shift_imm == 0) {
137         shifter_operand = 0;
138         cpu->shifter_carry_out = BIT(rm, 31);
139     } else {
140         shifter_operand = rm >> shift_imm;
141         cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
142     }
143     return shifter_operand;
144 }
145 
DPO(LogicalShiftRightByRegister)146 static unsigned int DPO(LogicalShiftRightByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
147     unsigned int rs = CHECK_READ_REG15(cpu, RS);
148     unsigned int rm = CHECK_READ_REG15(cpu, RM);
149     unsigned int shifter_operand;
150     if (BITS(rs, 0, 7) == 0) {
151         shifter_operand = rm;
152         cpu->shifter_carry_out = cpu->CFlag;
153     } else if (BITS(rs, 0, 7) < 32) {
154         shifter_operand = rm >> BITS(rs, 0, 7);
155         cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
156     } else if (BITS(rs, 0, 7) == 32) {
157         shifter_operand = 0;
158         cpu->shifter_carry_out = BIT(rm, 31);
159     } else {
160         shifter_operand = 0;
161         cpu->shifter_carry_out = 0;
162     }
163     return shifter_operand;
164 }
165 
DPO(ArithmeticShiftRightByImmediate)166 static unsigned int DPO(ArithmeticShiftRightByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
167     unsigned int rm = CHECK_READ_REG15(cpu, RM);
168     unsigned int shifter_operand;
169     int shift_imm = BITS(sht_oper, 7, 11);
170     if (shift_imm == 0) {
171         if (BIT(rm, 31) == 0)
172             shifter_operand = 0;
173         else
174             shifter_operand = 0xFFFFFFFF;
175         cpu->shifter_carry_out = BIT(rm, 31);
176     } else {
177         shifter_operand = static_cast<int>(rm) >> shift_imm;
178         cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
179     }
180     return shifter_operand;
181 }
182 
DPO(ArithmeticShiftRightByRegister)183 static unsigned int DPO(ArithmeticShiftRightByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
184     unsigned int rs = CHECK_READ_REG15(cpu, RS);
185     unsigned int rm = CHECK_READ_REG15(cpu, RM);
186     unsigned int shifter_operand;
187     if (BITS(rs, 0, 7) == 0) {
188         shifter_operand = rm;
189         cpu->shifter_carry_out = cpu->CFlag;
190     } else if (BITS(rs, 0, 7) < 32) {
191         shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7);
192         cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
193     } else {
194         if (BIT(rm, 31) == 0)
195             shifter_operand = 0;
196         else
197             shifter_operand = 0xffffffff;
198         cpu->shifter_carry_out = BIT(rm, 31);
199     }
200     return shifter_operand;
201 }
202 
DPO(RotateRightByImmediate)203 static unsigned int DPO(RotateRightByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
204     unsigned int shifter_operand;
205     unsigned int rm = CHECK_READ_REG15(cpu, RM);
206     int shift_imm = BITS(sht_oper, 7, 11);
207     if (shift_imm == 0) {
208         shifter_operand = (cpu->CFlag << 31) | (rm >> 1);
209         cpu->shifter_carry_out = BIT(rm, 0);
210     } else {
211         shifter_operand = ROTATE_RIGHT_32(rm, shift_imm);
212         cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
213     }
214     return shifter_operand;
215 }
216 
DPO(RotateRightByRegister)217 static unsigned int DPO(RotateRightByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
218     unsigned int rm = CHECK_READ_REG15(cpu, RM);
219     unsigned int rs = CHECK_READ_REG15(cpu, RS);
220     unsigned int shifter_operand;
221     if (BITS(rs, 0, 7) == 0) {
222         shifter_operand = rm;
223         cpu->shifter_carry_out = cpu->CFlag;
224     } else if (BITS(rs, 0, 4) == 0) {
225         shifter_operand = rm;
226         cpu->shifter_carry_out = BIT(rm, 31);
227     } else {
228         shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4));
229         cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1);
230     }
231     return shifter_operand;
232 }
233 
234 #define DEBUG_MSG                                                                                  \
235     LOG_DEBUG(Core_ARM11, "inst is {:x}", inst);                                                   \
236     CITRA_IGNORE_EXIT(0)
237 
238 #define LnSWoUB(s) glue(LnSWoUB, s)
239 #define MLnS(s) glue(MLnS, s)
240 #define LdnStM(s) glue(LdnStM, s)
241 
242 #define W_BIT BIT(inst, 21)
243 #define U_BIT BIT(inst, 23)
244 #define I_BIT BIT(inst, 25)
245 #define P_BIT BIT(inst, 24)
246 #define OFFSET_12 BITS(inst, 0, 11)
247 
LnSWoUB(ImmediateOffset)248 static void LnSWoUB(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
249     unsigned int Rn = BITS(inst, 16, 19);
250     unsigned int addr;
251 
252     if (U_BIT)
253         addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
254     else
255         addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
256 
257     virt_addr = addr;
258 }
259 
LnSWoUB(RegisterOffset)260 static void LnSWoUB(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
261     unsigned int Rn = BITS(inst, 16, 19);
262     unsigned int Rm = BITS(inst, 0, 3);
263     unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
264     unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
265     unsigned int addr;
266 
267     if (U_BIT)
268         addr = rn + rm;
269     else
270         addr = rn - rm;
271 
272     virt_addr = addr;
273 }
274 
LnSWoUB(ImmediatePostIndexed)275 static void LnSWoUB(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst,
276                                           unsigned int& virt_addr) {
277     unsigned int Rn = BITS(inst, 16, 19);
278     unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
279 
280     if (U_BIT)
281         cpu->Reg[Rn] += OFFSET_12;
282     else
283         cpu->Reg[Rn] -= OFFSET_12;
284 
285     virt_addr = addr;
286 }
287 
LnSWoUB(ImmediatePreIndexed)288 static void LnSWoUB(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst,
289                                          unsigned int& virt_addr) {
290     unsigned int Rn = BITS(inst, 16, 19);
291     unsigned int addr;
292 
293     if (U_BIT)
294         addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
295     else
296         addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
297 
298     virt_addr = addr;
299 
300     if (CondPassed(cpu, BITS(inst, 28, 31)))
301         cpu->Reg[Rn] = addr;
302 }
303 
MLnS(RegisterPreIndexed)304 static void MLnS(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
305     unsigned int addr;
306     unsigned int Rn = BITS(inst, 16, 19);
307     unsigned int Rm = BITS(inst, 0, 3);
308     unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
309     unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
310 
311     if (U_BIT)
312         addr = rn + rm;
313     else
314         addr = rn - rm;
315 
316     virt_addr = addr;
317 
318     if (CondPassed(cpu, BITS(inst, 28, 31)))
319         cpu->Reg[Rn] = addr;
320 }
321 
LnSWoUB(RegisterPreIndexed)322 static void LnSWoUB(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst,
323                                         unsigned int& virt_addr) {
324     unsigned int Rn = BITS(inst, 16, 19);
325     unsigned int Rm = BITS(inst, 0, 3);
326     unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
327     unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
328     unsigned int addr;
329 
330     if (U_BIT)
331         addr = rn + rm;
332     else
333         addr = rn - rm;
334 
335     virt_addr = addr;
336 
337     if (CondPassed(cpu, BITS(inst, 28, 31))) {
338         cpu->Reg[Rn] = addr;
339     }
340 }
341 
LnSWoUB(ScaledRegisterPreIndexed)342 static void LnSWoUB(ScaledRegisterPreIndexed)(ARMul_State* cpu, unsigned int inst,
343                                               unsigned int& virt_addr) {
344     unsigned int shift = BITS(inst, 5, 6);
345     unsigned int shift_imm = BITS(inst, 7, 11);
346     unsigned int Rn = BITS(inst, 16, 19);
347     unsigned int Rm = BITS(inst, 0, 3);
348     unsigned int index = 0;
349     unsigned int addr;
350     unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
351     unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
352 
353     switch (shift) {
354     case 0:
355         index = rm << shift_imm;
356         break;
357     case 1:
358         if (shift_imm == 0) {
359             index = 0;
360         } else {
361             index = rm >> shift_imm;
362         }
363         break;
364     case 2:
365         if (shift_imm == 0) { // ASR #32
366             if (BIT(rm, 31) == 1)
367                 index = 0xFFFFFFFF;
368             else
369                 index = 0;
370         } else {
371             index = static_cast<int>(rm) >> shift_imm;
372         }
373         break;
374     case 3:
375         if (shift_imm == 0) {
376             index = (cpu->CFlag << 31) | (rm >> 1);
377         } else {
378             index = ROTATE_RIGHT_32(rm, shift_imm);
379         }
380         break;
381     }
382 
383     if (U_BIT)
384         addr = rn + index;
385     else
386         addr = rn - index;
387 
388     virt_addr = addr;
389 
390     if (CondPassed(cpu, BITS(inst, 28, 31)))
391         cpu->Reg[Rn] = addr;
392 }
393 
LnSWoUB(ScaledRegisterPostIndexed)394 static void LnSWoUB(ScaledRegisterPostIndexed)(ARMul_State* cpu, unsigned int inst,
395                                                unsigned int& virt_addr) {
396     unsigned int shift = BITS(inst, 5, 6);
397     unsigned int shift_imm = BITS(inst, 7, 11);
398     unsigned int Rn = BITS(inst, 16, 19);
399     unsigned int Rm = BITS(inst, 0, 3);
400     unsigned int index = 0;
401     unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
402     unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
403 
404     switch (shift) {
405     case 0:
406         index = rm << shift_imm;
407         break;
408     case 1:
409         if (shift_imm == 0) {
410             index = 0;
411         } else {
412             index = rm >> shift_imm;
413         }
414         break;
415     case 2:
416         if (shift_imm == 0) { // ASR #32
417             if (BIT(rm, 31) == 1)
418                 index = 0xFFFFFFFF;
419             else
420                 index = 0;
421         } else {
422             index = static_cast<int>(rm) >> shift_imm;
423         }
424         break;
425     case 3:
426         if (shift_imm == 0) {
427             index = (cpu->CFlag << 31) | (rm >> 1);
428         } else {
429             index = ROTATE_RIGHT_32(rm, shift_imm);
430         }
431         break;
432     }
433 
434     virt_addr = addr;
435 
436     if (CondPassed(cpu, BITS(inst, 28, 31))) {
437         if (U_BIT)
438             cpu->Reg[Rn] += index;
439         else
440             cpu->Reg[Rn] -= index;
441     }
442 }
443 
LnSWoUB(RegisterPostIndexed)444 static void LnSWoUB(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst,
445                                          unsigned int& virt_addr) {
446     unsigned int Rn = BITS(inst, 16, 19);
447     unsigned int Rm = BITS(inst, 0, 3);
448     unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
449 
450     virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
451 
452     if (CondPassed(cpu, BITS(inst, 28, 31))) {
453         if (U_BIT) {
454             cpu->Reg[Rn] += rm;
455         } else {
456             cpu->Reg[Rn] -= rm;
457         }
458     }
459 }
460 
MLnS(ImmediateOffset)461 static void MLnS(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
462     unsigned int immedL = BITS(inst, 0, 3);
463     unsigned int immedH = BITS(inst, 8, 11);
464     unsigned int Rn = BITS(inst, 16, 19);
465     unsigned int addr;
466 
467     unsigned int offset_8 = (immedH << 4) | immedL;
468 
469     if (U_BIT)
470         addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8;
471     else
472         addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8;
473 
474     virt_addr = addr;
475 }
476 
MLnS(RegisterOffset)477 static void MLnS(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
478     unsigned int addr;
479     unsigned int Rn = BITS(inst, 16, 19);
480     unsigned int Rm = BITS(inst, 0, 3);
481     unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
482     unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
483 
484     if (U_BIT)
485         addr = rn + rm;
486     else
487         addr = rn - rm;
488 
489     virt_addr = addr;
490 }
491 
MLnS(ImmediatePreIndexed)492 static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst,
493                                       unsigned int& virt_addr) {
494     unsigned int Rn = BITS(inst, 16, 19);
495     unsigned int immedH = BITS(inst, 8, 11);
496     unsigned int immedL = BITS(inst, 0, 3);
497     unsigned int addr;
498     unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
499     unsigned int offset_8 = (immedH << 4) | immedL;
500 
501     if (U_BIT)
502         addr = rn + offset_8;
503     else
504         addr = rn - offset_8;
505 
506     virt_addr = addr;
507 
508     if (CondPassed(cpu, BITS(inst, 28, 31)))
509         cpu->Reg[Rn] = addr;
510 }
511 
MLnS(ImmediatePostIndexed)512 static void MLnS(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst,
513                                        unsigned int& virt_addr) {
514     unsigned int Rn = BITS(inst, 16, 19);
515     unsigned int immedH = BITS(inst, 8, 11);
516     unsigned int immedL = BITS(inst, 0, 3);
517     unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
518 
519     virt_addr = rn;
520 
521     if (CondPassed(cpu, BITS(inst, 28, 31))) {
522         unsigned int offset_8 = (immedH << 4) | immedL;
523         if (U_BIT)
524             rn += offset_8;
525         else
526             rn -= offset_8;
527 
528         cpu->Reg[Rn] = rn;
529     }
530 }
531 
MLnS(RegisterPostIndexed)532 static void MLnS(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst,
533                                       unsigned int& virt_addr) {
534     unsigned int Rn = BITS(inst, 16, 19);
535     unsigned int Rm = BITS(inst, 0, 3);
536     unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
537 
538     virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
539 
540     if (CondPassed(cpu, BITS(inst, 28, 31))) {
541         if (U_BIT)
542             cpu->Reg[Rn] += rm;
543         else
544             cpu->Reg[Rn] -= rm;
545     }
546 }
547 
LdnStM(DecrementBefore)548 static void LdnStM(DecrementBefore)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
549     unsigned int Rn = BITS(inst, 16, 19);
550     unsigned int i = BITS(inst, 0, 15);
551     int count = 0;
552 
553     while (i) {
554         if (i & 1)
555             count++;
556         i = i >> 1;
557     }
558 
559     virt_addr = CHECK_READ_REG15_WA(cpu, Rn) - count * 4;
560 
561     if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21))
562         cpu->Reg[Rn] -= count * 4;
563 }
564 
LdnStM(IncrementBefore)565 static void LdnStM(IncrementBefore)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
566     unsigned int Rn = BITS(inst, 16, 19);
567     unsigned int i = BITS(inst, 0, 15);
568     int count = 0;
569 
570     while (i) {
571         if (i & 1)
572             count++;
573         i = i >> 1;
574     }
575 
576     virt_addr = CHECK_READ_REG15_WA(cpu, Rn) + 4;
577 
578     if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21))
579         cpu->Reg[Rn] += count * 4;
580 }
581 
LdnStM(IncrementAfter)582 static void LdnStM(IncrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
583     unsigned int Rn = BITS(inst, 16, 19);
584     unsigned int i = BITS(inst, 0, 15);
585     int count = 0;
586 
587     while (i) {
588         if (i & 1)
589             count++;
590         i = i >> 1;
591     }
592 
593     virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
594 
595     if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21))
596         cpu->Reg[Rn] += count * 4;
597 }
598 
LdnStM(DecrementAfter)599 static void LdnStM(DecrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
600     unsigned int Rn = BITS(inst, 16, 19);
601     unsigned int i = BITS(inst, 0, 15);
602     int count = 0;
603     while (i) {
604         if (i & 1)
605             count++;
606         i = i >> 1;
607     }
608     unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
609     unsigned int start_addr = rn - count * 4 + 4;
610 
611     virt_addr = start_addr;
612 
613     if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
614         cpu->Reg[Rn] -= count * 4;
615     }
616 }
617 
LnSWoUB(ScaledRegisterOffset)618 static void LnSWoUB(ScaledRegisterOffset)(ARMul_State* cpu, unsigned int inst,
619                                           unsigned int& virt_addr) {
620     unsigned int shift = BITS(inst, 5, 6);
621     unsigned int shift_imm = BITS(inst, 7, 11);
622     unsigned int Rn = BITS(inst, 16, 19);
623     unsigned int Rm = BITS(inst, 0, 3);
624     unsigned int index = 0;
625     unsigned int addr;
626     unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
627     unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
628 
629     switch (shift) {
630     case 0:
631         index = rm << shift_imm;
632         break;
633     case 1:
634         if (shift_imm == 0) {
635             index = 0;
636         } else {
637             index = rm >> shift_imm;
638         }
639         break;
640     case 2:
641         if (shift_imm == 0) { // ASR #32
642             if (BIT(rm, 31) == 1)
643                 index = 0xFFFFFFFF;
644             else
645                 index = 0;
646         } else {
647             index = static_cast<int>(rm) >> shift_imm;
648         }
649         break;
650     case 3:
651         if (shift_imm == 0) {
652             index = (cpu->CFlag << 31) | (rm >> 1);
653         } else {
654             index = ROTATE_RIGHT_32(rm, shift_imm);
655         }
656         break;
657     }
658 
659     if (U_BIT) {
660         addr = rn + index;
661     } else
662         addr = rn - index;
663 
664     virt_addr = addr;
665 }
666 
GetShifterOp(unsigned int inst)667 shtop_fp_t GetShifterOp(unsigned int inst) {
668     if (BIT(inst, 25)) {
669         return DPO(Immediate);
670     } else if (BITS(inst, 4, 11) == 0) {
671         return DPO(Register);
672     } else if (BITS(inst, 4, 6) == 0) {
673         return DPO(LogicalShiftLeftByImmediate);
674     } else if (BITS(inst, 4, 7) == 1) {
675         return DPO(LogicalShiftLeftByRegister);
676     } else if (BITS(inst, 4, 6) == 2) {
677         return DPO(LogicalShiftRightByImmediate);
678     } else if (BITS(inst, 4, 7) == 3) {
679         return DPO(LogicalShiftRightByRegister);
680     } else if (BITS(inst, 4, 6) == 4) {
681         return DPO(ArithmeticShiftRightByImmediate);
682     } else if (BITS(inst, 4, 7) == 5) {
683         return DPO(ArithmeticShiftRightByRegister);
684     } else if (BITS(inst, 4, 6) == 6) {
685         return DPO(RotateRightByImmediate);
686     } else if (BITS(inst, 4, 7) == 7) {
687         return DPO(RotateRightByRegister);
688     }
689     return nullptr;
690 }
691 
GetAddressingOp(unsigned int inst)692 get_addr_fp_t GetAddressingOp(unsigned int inst) {
693     if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
694         return LnSWoUB(ImmediateOffset);
695     } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
696         return LnSWoUB(RegisterOffset);
697     } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
698         return LnSWoUB(ScaledRegisterOffset);
699     } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) {
700         return LnSWoUB(ImmediatePreIndexed);
701     } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) {
702         return LnSWoUB(RegisterPreIndexed);
703     } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) {
704         return LnSWoUB(ScaledRegisterPreIndexed);
705     } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) {
706         return LnSWoUB(ImmediatePostIndexed);
707     } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
708         return LnSWoUB(RegisterPostIndexed);
709     } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
710         return LnSWoUB(ScaledRegisterPostIndexed);
711     } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 &&
712                BIT(inst, 4) == 1) {
713         return MLnS(ImmediateOffset);
714     } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 &&
715                BIT(inst, 4) == 1) {
716         return MLnS(RegisterOffset);
717     } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 &&
718                BIT(inst, 4) == 1) {
719         return MLnS(ImmediatePreIndexed);
720     } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 &&
721                BIT(inst, 4) == 1) {
722         return MLnS(RegisterPreIndexed);
723     } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 &&
724                BIT(inst, 4) == 1) {
725         return MLnS(ImmediatePostIndexed);
726     } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 &&
727                BIT(inst, 4) == 1) {
728         return MLnS(RegisterPostIndexed);
729     } else if (BITS(inst, 23, 27) == 0x11) {
730         return LdnStM(IncrementAfter);
731     } else if (BITS(inst, 23, 27) == 0x13) {
732         return LdnStM(IncrementBefore);
733     } else if (BITS(inst, 23, 27) == 0x10) {
734         return LdnStM(DecrementAfter);
735     } else if (BITS(inst, 23, 27) == 0x12) {
736         return LdnStM(DecrementBefore);
737     }
738     return nullptr;
739 }
740 
741 // Specialized for LDRT, LDRBT, STRT, and STRBT, which have specific addressing mode requirements
GetAddressingOpLoadStoreT(unsigned int inst)742 get_addr_fp_t GetAddressingOpLoadStoreT(unsigned int inst) {
743     if (BITS(inst, 25, 27) == 2) {
744         return LnSWoUB(ImmediatePostIndexed);
745     } else if (BITS(inst, 25, 27) == 3) {
746         return LnSWoUB(ScaledRegisterPostIndexed);
747     }
748     // Reaching this would indicate the thumb version
749     // of this instruction, however the 3DS CPU doesn't
750     // support this variant (the 3DS CPU is only ARMv6K,
751     // while this variant is added in ARMv6T2).
752     // So it's sufficient for citra to not implement this.
753     return nullptr;
754 }
755 
756 enum { FETCH_SUCCESS, FETCH_FAILURE };
757 
DecodeThumbInstruction(u32 inst,u32 addr,u32 * arm_inst,u32 * inst_size,ARM_INST_PTR * ptr_inst_base)758 static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size,
759                                                 ARM_INST_PTR* ptr_inst_base) {
760     // Check if in Thumb mode
761     ThumbDecodeStatus ret = TranslateThumbInstruction(addr, inst, arm_inst, inst_size);
762     if (ret == ThumbDecodeStatus::BRANCH) {
763         int inst_index;
764         int table_length = static_cast<int>(arm_instruction_trans_len);
765         u32 tinstr = GetThumbInstruction(inst, addr);
766 
767         switch ((tinstr & 0xF800) >> 11) {
768         case 26:
769         case 27:
770             if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)) {
771                 inst_index = table_length - 4;
772                 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
773             } else {
774                 LOG_ERROR(Core_ARM11, "thumb decoder error");
775             }
776             break;
777         case 28:
778             // Branch 2, unconditional branch
779             inst_index = table_length - 5;
780             *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
781             break;
782 
783         case 8:
784         case 29:
785             // For BLX 1 thumb instruction
786             inst_index = table_length - 1;
787             *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
788             break;
789         case 30:
790             // For BL 1 thumb instruction
791             inst_index = table_length - 3;
792             *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
793             break;
794         case 31:
795             // For BL 2 thumb instruction
796             inst_index = table_length - 2;
797             *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
798             break;
799         default:
800             ret = ThumbDecodeStatus::UNDEFINED;
801             break;
802         }
803     }
804     return ret;
805 }
806 
807 enum { KEEP_GOING, FETCH_EXCEPTION };
808 
809 MICROPROFILE_DEFINE(DynCom_Decode, "DynCom", "Decode", MP_RGB(255, 64, 64));
810 
InterpreterTranslateInstruction(const ARMul_State * cpu,const u32 phys_addr,ARM_INST_PTR & inst_base)811 static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr,
812                                                     ARM_INST_PTR& inst_base) {
813     u32 inst_size = 4;
814     u32 inst = cpu->memory.Read32(phys_addr & 0xFFFFFFFC);
815 
816     // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM
817     // instruction
818     if (cpu->TFlag) {
819         u32 arm_inst;
820         ThumbDecodeStatus state =
821             DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base);
822 
823         // We have translated the Thumb branch instruction in the Thumb decoder
824         if (state == ThumbDecodeStatus::BRANCH) {
825             return inst_size;
826         }
827         inst = arm_inst;
828     }
829 
830     int idx;
831     if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) {
832         LOG_ERROR(Core_ARM11, "Decode failure.\tPC: [{:#010X}]\tInstruction: {:08X}", phys_addr,
833                   inst);
834         LOG_ERROR(Core_ARM11, "cpsr={:#X}, cpu->TFlag={}, r15={:#010X}", cpu->Cpsr, cpu->TFlag,
835                   cpu->Reg[15]);
836         CITRA_IGNORE_EXIT(-1);
837     }
838     inst_base = arm_instruction_trans[idx](inst, idx);
839 
840     return inst_size;
841 }
842 
InterpreterTranslateBlock(ARMul_State * cpu,std::size_t & bb_start,u32 addr)843 static int InterpreterTranslateBlock(ARMul_State* cpu, std::size_t& bb_start, u32 addr) {
844     MICROPROFILE_SCOPE(DynCom_Decode);
845 
846     // Decode instruction, get index
847     // Allocate memory and init InsCream
848     // Go on next, until terminal instruction
849     // Save start addr of basicblock in CreamCache
850     ARM_INST_PTR inst_base = nullptr;
851     TransExtData ret = TransExtData::NON_BRANCH;
852     int size = 0; // instruction size of basic block
853     bb_start = trans_cache_buf_top;
854 
855     u32 phys_addr = addr;
856     u32 pc_start = cpu->Reg[15];
857 
858     while (ret == TransExtData::NON_BRANCH) {
859         unsigned int inst_size = InterpreterTranslateInstruction(cpu, phys_addr, inst_base);
860 
861         size++;
862 
863         phys_addr += inst_size;
864 
865         if ((phys_addr & 0xfff) == 0) {
866             inst_base->br = TransExtData::END_OF_PAGE;
867         }
868         ret = inst_base->br;
869     };
870 
871     cpu->instruction_cache[pc_start] = bb_start;
872 
873     return KEEP_GOING;
874 }
875 
InterpreterTranslateSingle(ARMul_State * cpu,std::size_t & bb_start,u32 addr)876 static int InterpreterTranslateSingle(ARMul_State* cpu, std::size_t& bb_start, u32 addr) {
877     MICROPROFILE_SCOPE(DynCom_Decode);
878 
879     ARM_INST_PTR inst_base = nullptr;
880     bb_start = trans_cache_buf_top;
881 
882     u32 phys_addr = addr;
883     u32 pc_start = cpu->Reg[15];
884 
885     InterpreterTranslateInstruction(cpu, phys_addr, inst_base);
886 
887     if (inst_base->br == TransExtData::NON_BRANCH) {
888         inst_base->br = TransExtData::SINGLE_STEP;
889     }
890 
891     cpu->instruction_cache[pc_start] = bb_start;
892 
893     return KEEP_GOING;
894 }
895 
clz(unsigned int x)896 static int clz(unsigned int x) {
897     int n;
898     if (x == 0)
899         return (32);
900     n = 1;
901     if ((x >> 16) == 0) {
902         n = n + 16;
903         x = x << 16;
904     }
905     if ((x >> 24) == 0) {
906         n = n + 8;
907         x = x << 8;
908     }
909     if ((x >> 28) == 0) {
910         n = n + 4;
911         x = x << 4;
912     }
913     if ((x >> 30) == 0) {
914         n = n + 2;
915         x = x << 2;
916     }
917     n = n - (x >> 31);
918     return n;
919 }
920 
921 MICROPROFILE_DEFINE(DynCom_Execute, "DynCom", "Execute", MP_RGB(255, 0, 0));
922 
InterpreterMainLoop(ARMul_State * cpu)923 unsigned InterpreterMainLoop(ARMul_State* cpu) {
924     MICROPROFILE_SCOPE(DynCom_Execute);
925 
926     /// Nearest upcoming GDB code execution breakpoint, relative to the last dispatch's address.
927     GDBStub::BreakpointAddress breakpoint_data;
928     breakpoint_data.type = GDBStub::BreakpointType::None;
929 
930 #undef RM
931 #undef RS
932 
933 #define CRn inst_cream->crn
934 #define OPCODE_1 inst_cream->opcode_1
935 #define OPCODE_2 inst_cream->opcode_2
936 #define CRm inst_cream->crm
937 #define RD cpu->Reg[inst_cream->Rd]
938 #define RD2 cpu->Reg[inst_cream->Rd + 1]
939 #define RN cpu->Reg[inst_cream->Rn]
940 #define RM cpu->Reg[inst_cream->Rm]
941 #define RS cpu->Reg[inst_cream->Rs]
942 #define RDHI cpu->Reg[inst_cream->RdHi]
943 #define RDLO cpu->Reg[inst_cream->RdLo]
944 #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4)
945 #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
946 #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
947 
948 #define FETCH_INST                                                                                 \
949     if (inst_base->br != TransExtData::NON_BRANCH)                                                 \
950         goto DISPATCH;                                                                             \
951     inst_base = (arm_inst*)&trans_cache_buf[ptr]
952 
953 #define INC_PC(l) ptr += sizeof(arm_inst) + l
954 #define INC_PC_STUB ptr += sizeof(arm_inst)
955 
956 #ifdef ANDROID
957 #define GDB_BP_CHECK
958 #else
959 #define GDB_BP_CHECK                                                                               \
960     cpu->Cpsr &= ~(1 << 5);                                                                        \
961     cpu->Cpsr |= cpu->TFlag << 5;                                                                  \
962     if (GDBStub::IsServerEnabled()) {                                                              \
963         if (GDBStub::IsMemoryBreak()) {                                                            \
964             goto END;                                                                              \
965         } else if (breakpoint_data.type != GDBStub::BreakpointType::None &&                        \
966                    PC == breakpoint_data.address) {                                                \
967             cpu->RecordBreak(breakpoint_data);                                                     \
968             goto END;                                                                              \
969         }                                                                                          \
970     }
971 #endif
972 
973 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
974 // clunky switch statement.
975 #if defined __GNUC__ || defined __clang__
976 #define GOTO_NEXT_INST                                                                             \
977     GDB_BP_CHECK;                                                                                  \
978     if (num_instrs >= cpu->NumInstrsToExecute)                                                     \
979         goto END;                                                                                  \
980     num_instrs++;                                                                                  \
981     goto* InstLabel[inst_base->idx]
982 #else
983 #define GOTO_NEXT_INST                                                                             \
984     GDB_BP_CHECK;                                                                                  \
985     if (num_instrs >= cpu->NumInstrsToExecute)                                                     \
986         goto END;                                                                                  \
987     num_instrs++;                                                                                  \
988     switch (inst_base->idx) {                                                                      \
989     case 0:                                                                                        \
990         goto VMLA_INST;                                                                            \
991     case 1:                                                                                        \
992         goto VMLS_INST;                                                                            \
993     case 2:                                                                                        \
994         goto VNMLA_INST;                                                                           \
995     case 3:                                                                                        \
996         goto VNMLS_INST;                                                                           \
997     case 4:                                                                                        \
998         goto VNMUL_INST;                                                                           \
999     case 5:                                                                                        \
1000         goto VMUL_INST;                                                                            \
1001     case 6:                                                                                        \
1002         goto VADD_INST;                                                                            \
1003     case 7:                                                                                        \
1004         goto VSUB_INST;                                                                            \
1005     case 8:                                                                                        \
1006         goto VDIV_INST;                                                                            \
1007     case 9:                                                                                        \
1008         goto VMOVI_INST;                                                                           \
1009     case 10:                                                                                       \
1010         goto VMOVR_INST;                                                                           \
1011     case 11:                                                                                       \
1012         goto VABS_INST;                                                                            \
1013     case 12:                                                                                       \
1014         goto VNEG_INST;                                                                            \
1015     case 13:                                                                                       \
1016         goto VSQRT_INST;                                                                           \
1017     case 14:                                                                                       \
1018         goto VCMP_INST;                                                                            \
1019     case 15:                                                                                       \
1020         goto VCMP2_INST;                                                                           \
1021     case 16:                                                                                       \
1022         goto VCVTBDS_INST;                                                                         \
1023     case 17:                                                                                       \
1024         goto VCVTBFF_INST;                                                                         \
1025     case 18:                                                                                       \
1026         goto VCVTBFI_INST;                                                                         \
1027     case 19:                                                                                       \
1028         goto VMOVBRS_INST;                                                                         \
1029     case 20:                                                                                       \
1030         goto VMSR_INST;                                                                            \
1031     case 21:                                                                                       \
1032         goto VMOVBRC_INST;                                                                         \
1033     case 22:                                                                                       \
1034         goto VMRS_INST;                                                                            \
1035     case 23:                                                                                       \
1036         goto VMOVBCR_INST;                                                                         \
1037     case 24:                                                                                       \
1038         goto VMOVBRRSS_INST;                                                                       \
1039     case 25:                                                                                       \
1040         goto VMOVBRRD_INST;                                                                        \
1041     case 26:                                                                                       \
1042         goto VSTR_INST;                                                                            \
1043     case 27:                                                                                       \
1044         goto VPUSH_INST;                                                                           \
1045     case 28:                                                                                       \
1046         goto VSTM_INST;                                                                            \
1047     case 29:                                                                                       \
1048         goto VPOP_INST;                                                                            \
1049     case 30:                                                                                       \
1050         goto VLDR_INST;                                                                            \
1051     case 31:                                                                                       \
1052         goto VLDM_INST;                                                                            \
1053     case 32:                                                                                       \
1054         goto SRS_INST;                                                                             \
1055     case 33:                                                                                       \
1056         goto RFE_INST;                                                                             \
1057     case 34:                                                                                       \
1058         goto BKPT_INST;                                                                            \
1059     case 35:                                                                                       \
1060         goto BLX_INST;                                                                             \
1061     case 36:                                                                                       \
1062         goto CPS_INST;                                                                             \
1063     case 37:                                                                                       \
1064         goto PLD_INST;                                                                             \
1065     case 38:                                                                                       \
1066         goto SETEND_INST;                                                                          \
1067     case 39:                                                                                       \
1068         goto CLREX_INST;                                                                           \
1069     case 40:                                                                                       \
1070         goto REV16_INST;                                                                           \
1071     case 41:                                                                                       \
1072         goto USAD8_INST;                                                                           \
1073     case 42:                                                                                       \
1074         goto SXTB_INST;                                                                            \
1075     case 43:                                                                                       \
1076         goto UXTB_INST;                                                                            \
1077     case 44:                                                                                       \
1078         goto SXTH_INST;                                                                            \
1079     case 45:                                                                                       \
1080         goto SXTB16_INST;                                                                          \
1081     case 46:                                                                                       \
1082         goto UXTH_INST;                                                                            \
1083     case 47:                                                                                       \
1084         goto UXTB16_INST;                                                                          \
1085     case 48:                                                                                       \
1086         goto CPY_INST;                                                                             \
1087     case 49:                                                                                       \
1088         goto UXTAB_INST;                                                                           \
1089     case 50:                                                                                       \
1090         goto SSUB8_INST;                                                                           \
1091     case 51:                                                                                       \
1092         goto SHSUB8_INST;                                                                          \
1093     case 52:                                                                                       \
1094         goto SSUBADDX_INST;                                                                        \
1095     case 53:                                                                                       \
1096         goto STREX_INST;                                                                           \
1097     case 54:                                                                                       \
1098         goto STREXB_INST;                                                                          \
1099     case 55:                                                                                       \
1100         goto SWP_INST;                                                                             \
1101     case 56:                                                                                       \
1102         goto SWPB_INST;                                                                            \
1103     case 57:                                                                                       \
1104         goto SSUB16_INST;                                                                          \
1105     case 58:                                                                                       \
1106         goto SSAT16_INST;                                                                          \
1107     case 59:                                                                                       \
1108         goto SHSUBADDX_INST;                                                                       \
1109     case 60:                                                                                       \
1110         goto QSUBADDX_INST;                                                                        \
1111     case 61:                                                                                       \
1112         goto SHADDSUBX_INST;                                                                       \
1113     case 62:                                                                                       \
1114         goto SHADD8_INST;                                                                          \
1115     case 63:                                                                                       \
1116         goto SHADD16_INST;                                                                         \
1117     case 64:                                                                                       \
1118         goto SEL_INST;                                                                             \
1119     case 65:                                                                                       \
1120         goto SADDSUBX_INST;                                                                        \
1121     case 66:                                                                                       \
1122         goto SADD8_INST;                                                                           \
1123     case 67:                                                                                       \
1124         goto SADD16_INST;                                                                          \
1125     case 68:                                                                                       \
1126         goto SHSUB16_INST;                                                                         \
1127     case 69:                                                                                       \
1128         goto UMAAL_INST;                                                                           \
1129     case 70:                                                                                       \
1130         goto UXTAB16_INST;                                                                         \
1131     case 71:                                                                                       \
1132         goto USUBADDX_INST;                                                                        \
1133     case 72:                                                                                       \
1134         goto USUB8_INST;                                                                           \
1135     case 73:                                                                                       \
1136         goto USUB16_INST;                                                                          \
1137     case 74:                                                                                       \
1138         goto USAT16_INST;                                                                          \
1139     case 75:                                                                                       \
1140         goto USADA8_INST;                                                                          \
1141     case 76:                                                                                       \
1142         goto UQSUBADDX_INST;                                                                       \
1143     case 77:                                                                                       \
1144         goto UQSUB8_INST;                                                                          \
1145     case 78:                                                                                       \
1146         goto UQSUB16_INST;                                                                         \
1147     case 79:                                                                                       \
1148         goto UQADDSUBX_INST;                                                                       \
1149     case 80:                                                                                       \
1150         goto UQADD8_INST;                                                                          \
1151     case 81:                                                                                       \
1152         goto UQADD16_INST;                                                                         \
1153     case 82:                                                                                       \
1154         goto SXTAB_INST;                                                                           \
1155     case 83:                                                                                       \
1156         goto UHSUBADDX_INST;                                                                       \
1157     case 84:                                                                                       \
1158         goto UHSUB8_INST;                                                                          \
1159     case 85:                                                                                       \
1160         goto UHSUB16_INST;                                                                         \
1161     case 86:                                                                                       \
1162         goto UHADDSUBX_INST;                                                                       \
1163     case 87:                                                                                       \
1164         goto UHADD8_INST;                                                                          \
1165     case 88:                                                                                       \
1166         goto UHADD16_INST;                                                                         \
1167     case 89:                                                                                       \
1168         goto UADDSUBX_INST;                                                                        \
1169     case 90:                                                                                       \
1170         goto UADD8_INST;                                                                           \
1171     case 91:                                                                                       \
1172         goto UADD16_INST;                                                                          \
1173     case 92:                                                                                       \
1174         goto SXTAH_INST;                                                                           \
1175     case 93:                                                                                       \
1176         goto SXTAB16_INST;                                                                         \
1177     case 94:                                                                                       \
1178         goto QADD8_INST;                                                                           \
1179     case 95:                                                                                       \
1180         goto BXJ_INST;                                                                             \
1181     case 96:                                                                                       \
1182         goto CLZ_INST;                                                                             \
1183     case 97:                                                                                       \
1184         goto UXTAH_INST;                                                                           \
1185     case 98:                                                                                       \
1186         goto BX_INST;                                                                              \
1187     case 99:                                                                                       \
1188         goto REV_INST;                                                                             \
1189     case 100:                                                                                      \
1190         goto BLX_INST;                                                                             \
1191     case 101:                                                                                      \
1192         goto REVSH_INST;                                                                           \
1193     case 102:                                                                                      \
1194         goto QADD_INST;                                                                            \
1195     case 103:                                                                                      \
1196         goto QADD16_INST;                                                                          \
1197     case 104:                                                                                      \
1198         goto QADDSUBX_INST;                                                                        \
1199     case 105:                                                                                      \
1200         goto LDREX_INST;                                                                           \
1201     case 106:                                                                                      \
1202         goto QDADD_INST;                                                                           \
1203     case 107:                                                                                      \
1204         goto QDSUB_INST;                                                                           \
1205     case 108:                                                                                      \
1206         goto QSUB_INST;                                                                            \
1207     case 109:                                                                                      \
1208         goto LDREXB_INST;                                                                          \
1209     case 110:                                                                                      \
1210         goto QSUB8_INST;                                                                           \
1211     case 111:                                                                                      \
1212         goto QSUB16_INST;                                                                          \
1213     case 112:                                                                                      \
1214         goto SMUAD_INST;                                                                           \
1215     case 113:                                                                                      \
1216         goto SMMUL_INST;                                                                           \
1217     case 114:                                                                                      \
1218         goto SMUSD_INST;                                                                           \
1219     case 115:                                                                                      \
1220         goto SMLSD_INST;                                                                           \
1221     case 116:                                                                                      \
1222         goto SMLSLD_INST;                                                                          \
1223     case 117:                                                                                      \
1224         goto SMMLA_INST;                                                                           \
1225     case 118:                                                                                      \
1226         goto SMMLS_INST;                                                                           \
1227     case 119:                                                                                      \
1228         goto SMLALD_INST;                                                                          \
1229     case 120:                                                                                      \
1230         goto SMLAD_INST;                                                                           \
1231     case 121:                                                                                      \
1232         goto SMLAW_INST;                                                                           \
1233     case 122:                                                                                      \
1234         goto SMULW_INST;                                                                           \
1235     case 123:                                                                                      \
1236         goto PKHTB_INST;                                                                           \
1237     case 124:                                                                                      \
1238         goto PKHBT_INST;                                                                           \
1239     case 125:                                                                                      \
1240         goto SMUL_INST;                                                                            \
1241     case 126:                                                                                      \
1242         goto SMLALXY_INST;                                                                         \
1243     case 127:                                                                                      \
1244         goto SMLA_INST;                                                                            \
1245     case 128:                                                                                      \
1246         goto MCRR_INST;                                                                            \
1247     case 129:                                                                                      \
1248         goto MRRC_INST;                                                                            \
1249     case 130:                                                                                      \
1250         goto CMP_INST;                                                                             \
1251     case 131:                                                                                      \
1252         goto TST_INST;                                                                             \
1253     case 132:                                                                                      \
1254         goto TEQ_INST;                                                                             \
1255     case 133:                                                                                      \
1256         goto CMN_INST;                                                                             \
1257     case 134:                                                                                      \
1258         goto SMULL_INST;                                                                           \
1259     case 135:                                                                                      \
1260         goto UMULL_INST;                                                                           \
1261     case 136:                                                                                      \
1262         goto UMLAL_INST;                                                                           \
1263     case 137:                                                                                      \
1264         goto SMLAL_INST;                                                                           \
1265     case 138:                                                                                      \
1266         goto MUL_INST;                                                                             \
1267     case 139:                                                                                      \
1268         goto MLA_INST;                                                                             \
1269     case 140:                                                                                      \
1270         goto SSAT_INST;                                                                            \
1271     case 141:                                                                                      \
1272         goto USAT_INST;                                                                            \
1273     case 142:                                                                                      \
1274         goto MRS_INST;                                                                             \
1275     case 143:                                                                                      \
1276         goto MSR_INST;                                                                             \
1277     case 144:                                                                                      \
1278         goto AND_INST;                                                                             \
1279     case 145:                                                                                      \
1280         goto BIC_INST;                                                                             \
1281     case 146:                                                                                      \
1282         goto LDM_INST;                                                                             \
1283     case 147:                                                                                      \
1284         goto EOR_INST;                                                                             \
1285     case 148:                                                                                      \
1286         goto ADD_INST;                                                                             \
1287     case 149:                                                                                      \
1288         goto RSB_INST;                                                                             \
1289     case 150:                                                                                      \
1290         goto RSC_INST;                                                                             \
1291     case 151:                                                                                      \
1292         goto SBC_INST;                                                                             \
1293     case 152:                                                                                      \
1294         goto ADC_INST;                                                                             \
1295     case 153:                                                                                      \
1296         goto SUB_INST;                                                                             \
1297     case 154:                                                                                      \
1298         goto ORR_INST;                                                                             \
1299     case 155:                                                                                      \
1300         goto MVN_INST;                                                                             \
1301     case 156:                                                                                      \
1302         goto MOV_INST;                                                                             \
1303     case 157:                                                                                      \
1304         goto STM_INST;                                                                             \
1305     case 158:                                                                                      \
1306         goto LDM_INST;                                                                             \
1307     case 159:                                                                                      \
1308         goto LDRSH_INST;                                                                           \
1309     case 160:                                                                                      \
1310         goto STM_INST;                                                                             \
1311     case 161:                                                                                      \
1312         goto LDM_INST;                                                                             \
1313     case 162:                                                                                      \
1314         goto LDRSB_INST;                                                                           \
1315     case 163:                                                                                      \
1316         goto STRD_INST;                                                                            \
1317     case 164:                                                                                      \
1318         goto LDRH_INST;                                                                            \
1319     case 165:                                                                                      \
1320         goto STRH_INST;                                                                            \
1321     case 166:                                                                                      \
1322         goto LDRD_INST;                                                                            \
1323     case 167:                                                                                      \
1324         goto STRT_INST;                                                                            \
1325     case 168:                                                                                      \
1326         goto STRBT_INST;                                                                           \
1327     case 169:                                                                                      \
1328         goto LDRBT_INST;                                                                           \
1329     case 170:                                                                                      \
1330         goto LDRT_INST;                                                                            \
1331     case 171:                                                                                      \
1332         goto MRC_INST;                                                                             \
1333     case 172:                                                                                      \
1334         goto MCR_INST;                                                                             \
1335     case 173:                                                                                      \
1336         goto MSR_INST;                                                                             \
1337     case 174:                                                                                      \
1338         goto MSR_INST;                                                                             \
1339     case 175:                                                                                      \
1340         goto MSR_INST;                                                                             \
1341     case 176:                                                                                      \
1342         goto MSR_INST;                                                                             \
1343     case 177:                                                                                      \
1344         goto MSR_INST;                                                                             \
1345     case 178:                                                                                      \
1346         goto LDRB_INST;                                                                            \
1347     case 179:                                                                                      \
1348         goto STRB_INST;                                                                            \
1349     case 180:                                                                                      \
1350         goto LDR_INST;                                                                             \
1351     case 181:                                                                                      \
1352         goto LDRCOND_INST;                                                                         \
1353     case 182:                                                                                      \
1354         goto STR_INST;                                                                             \
1355     case 183:                                                                                      \
1356         goto CDP_INST;                                                                             \
1357     case 184:                                                                                      \
1358         goto STC_INST;                                                                             \
1359     case 185:                                                                                      \
1360         goto LDC_INST;                                                                             \
1361     case 186:                                                                                      \
1362         goto LDREXD_INST;                                                                          \
1363     case 187:                                                                                      \
1364         goto STREXD_INST;                                                                          \
1365     case 188:                                                                                      \
1366         goto LDREXH_INST;                                                                          \
1367     case 189:                                                                                      \
1368         goto STREXH_INST;                                                                          \
1369     case 190:                                                                                      \
1370         goto NOP_INST;                                                                             \
1371     case 191:                                                                                      \
1372         goto YIELD_INST;                                                                           \
1373     case 192:                                                                                      \
1374         goto WFE_INST;                                                                             \
1375     case 193:                                                                                      \
1376         goto WFI_INST;                                                                             \
1377     case 194:                                                                                      \
1378         goto SEV_INST;                                                                             \
1379     case 195:                                                                                      \
1380         goto SWI_INST;                                                                             \
1381     case 196:                                                                                      \
1382         goto BBL_INST;                                                                             \
1383     case 197:                                                                                      \
1384         goto B_2_THUMB;                                                                            \
1385     case 198:                                                                                      \
1386         goto B_COND_THUMB;                                                                         \
1387     case 199:                                                                                      \
1388         goto BL_1_THUMB;                                                                           \
1389     case 200:                                                                                      \
1390         goto BL_2_THUMB;                                                                           \
1391     case 201:                                                                                      \
1392         goto BLX_1_THUMB;                                                                          \
1393     case 202:                                                                                      \
1394         goto DISPATCH;                                                                             \
1395     case 203:                                                                                      \
1396         goto INIT_INST_LENGTH;                                                                     \
1397     case 204:                                                                                      \
1398         goto END;                                                                                  \
1399     }
1400 #endif
1401 
1402 #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
1403 #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
1404 #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out)
1405 
1406 #define SAVE_NZCVT                                                                                 \
1407     cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | (cpu->NFlag << 31) | (cpu->ZFlag << 30) |               \
1408                 (cpu->CFlag << 29) | (cpu->VFlag << 28) | (cpu->TFlag << 5)
1409 #define LOAD_NZCVT                                                                                 \
1410     cpu->NFlag = (cpu->Cpsr >> 31);                                                                \
1411     cpu->ZFlag = (cpu->Cpsr >> 30) & 1;                                                            \
1412     cpu->CFlag = (cpu->Cpsr >> 29) & 1;                                                            \
1413     cpu->VFlag = (cpu->Cpsr >> 28) & 1;                                                            \
1414     cpu->TFlag = (cpu->Cpsr >> 5) & 1;
1415 
1416 #define PC (cpu->Reg[15])
1417 
1418 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
1419 // to a clunky switch statement.
1420 #if defined __GNUC__ || defined __clang__
1421     void* InstLabel[] = {&&VMLA_INST,
1422                          &&VMLS_INST,
1423                          &&VNMLA_INST,
1424                          &&VNMLS_INST,
1425                          &&VNMUL_INST,
1426                          &&VMUL_INST,
1427                          &&VADD_INST,
1428                          &&VSUB_INST,
1429                          &&VDIV_INST,
1430                          &&VMOVI_INST,
1431                          &&VMOVR_INST,
1432                          &&VABS_INST,
1433                          &&VNEG_INST,
1434                          &&VSQRT_INST,
1435                          &&VCMP_INST,
1436                          &&VCMP2_INST,
1437                          &&VCVTBDS_INST,
1438                          &&VCVTBFF_INST,
1439                          &&VCVTBFI_INST,
1440                          &&VMOVBRS_INST,
1441                          &&VMSR_INST,
1442                          &&VMOVBRC_INST,
1443                          &&VMRS_INST,
1444                          &&VMOVBCR_INST,
1445                          &&VMOVBRRSS_INST,
1446                          &&VMOVBRRD_INST,
1447                          &&VSTR_INST,
1448                          &&VPUSH_INST,
1449                          &&VSTM_INST,
1450                          &&VPOP_INST,
1451                          &&VLDR_INST,
1452                          &&VLDM_INST,
1453 
1454                          &&SRS_INST,
1455                          &&RFE_INST,
1456                          &&BKPT_INST,
1457                          &&BLX_INST,
1458                          &&CPS_INST,
1459                          &&PLD_INST,
1460                          &&SETEND_INST,
1461                          &&CLREX_INST,
1462                          &&REV16_INST,
1463                          &&USAD8_INST,
1464                          &&SXTB_INST,
1465                          &&UXTB_INST,
1466                          &&SXTH_INST,
1467                          &&SXTB16_INST,
1468                          &&UXTH_INST,
1469                          &&UXTB16_INST,
1470                          &&CPY_INST,
1471                          &&UXTAB_INST,
1472                          &&SSUB8_INST,
1473                          &&SHSUB8_INST,
1474                          &&SSUBADDX_INST,
1475                          &&STREX_INST,
1476                          &&STREXB_INST,
1477                          &&SWP_INST,
1478                          &&SWPB_INST,
1479                          &&SSUB16_INST,
1480                          &&SSAT16_INST,
1481                          &&SHSUBADDX_INST,
1482                          &&QSUBADDX_INST,
1483                          &&SHADDSUBX_INST,
1484                          &&SHADD8_INST,
1485                          &&SHADD16_INST,
1486                          &&SEL_INST,
1487                          &&SADDSUBX_INST,
1488                          &&SADD8_INST,
1489                          &&SADD16_INST,
1490                          &&SHSUB16_INST,
1491                          &&UMAAL_INST,
1492                          &&UXTAB16_INST,
1493                          &&USUBADDX_INST,
1494                          &&USUB8_INST,
1495                          &&USUB16_INST,
1496                          &&USAT16_INST,
1497                          &&USADA8_INST,
1498                          &&UQSUBADDX_INST,
1499                          &&UQSUB8_INST,
1500                          &&UQSUB16_INST,
1501                          &&UQADDSUBX_INST,
1502                          &&UQADD8_INST,
1503                          &&UQADD16_INST,
1504                          &&SXTAB_INST,
1505                          &&UHSUBADDX_INST,
1506                          &&UHSUB8_INST,
1507                          &&UHSUB16_INST,
1508                          &&UHADDSUBX_INST,
1509                          &&UHADD8_INST,
1510                          &&UHADD16_INST,
1511                          &&UADDSUBX_INST,
1512                          &&UADD8_INST,
1513                          &&UADD16_INST,
1514                          &&SXTAH_INST,
1515                          &&SXTAB16_INST,
1516                          &&QADD8_INST,
1517                          &&BXJ_INST,
1518                          &&CLZ_INST,
1519                          &&UXTAH_INST,
1520                          &&BX_INST,
1521                          &&REV_INST,
1522                          &&BLX_INST,
1523                          &&REVSH_INST,
1524                          &&QADD_INST,
1525                          &&QADD16_INST,
1526                          &&QADDSUBX_INST,
1527                          &&LDREX_INST,
1528                          &&QDADD_INST,
1529                          &&QDSUB_INST,
1530                          &&QSUB_INST,
1531                          &&LDREXB_INST,
1532                          &&QSUB8_INST,
1533                          &&QSUB16_INST,
1534                          &&SMUAD_INST,
1535                          &&SMMUL_INST,
1536                          &&SMUSD_INST,
1537                          &&SMLSD_INST,
1538                          &&SMLSLD_INST,
1539                          &&SMMLA_INST,
1540                          &&SMMLS_INST,
1541                          &&SMLALD_INST,
1542                          &&SMLAD_INST,
1543                          &&SMLAW_INST,
1544                          &&SMULW_INST,
1545                          &&PKHTB_INST,
1546                          &&PKHBT_INST,
1547                          &&SMUL_INST,
1548                          &&SMLALXY_INST,
1549                          &&SMLA_INST,
1550                          &&MCRR_INST,
1551                          &&MRRC_INST,
1552                          &&CMP_INST,
1553                          &&TST_INST,
1554                          &&TEQ_INST,
1555                          &&CMN_INST,
1556                          &&SMULL_INST,
1557                          &&UMULL_INST,
1558                          &&UMLAL_INST,
1559                          &&SMLAL_INST,
1560                          &&MUL_INST,
1561                          &&MLA_INST,
1562                          &&SSAT_INST,
1563                          &&USAT_INST,
1564                          &&MRS_INST,
1565                          &&MSR_INST,
1566                          &&AND_INST,
1567                          &&BIC_INST,
1568                          &&LDM_INST,
1569                          &&EOR_INST,
1570                          &&ADD_INST,
1571                          &&RSB_INST,
1572                          &&RSC_INST,
1573                          &&SBC_INST,
1574                          &&ADC_INST,
1575                          &&SUB_INST,
1576                          &&ORR_INST,
1577                          &&MVN_INST,
1578                          &&MOV_INST,
1579                          &&STM_INST,
1580                          &&LDM_INST,
1581                          &&LDRSH_INST,
1582                          &&STM_INST,
1583                          &&LDM_INST,
1584                          &&LDRSB_INST,
1585                          &&STRD_INST,
1586                          &&LDRH_INST,
1587                          &&STRH_INST,
1588                          &&LDRD_INST,
1589                          &&STRT_INST,
1590                          &&STRBT_INST,
1591                          &&LDRBT_INST,
1592                          &&LDRT_INST,
1593                          &&MRC_INST,
1594                          &&MCR_INST,
1595                          &&MSR_INST,
1596                          &&MSR_INST,
1597                          &&MSR_INST,
1598                          &&MSR_INST,
1599                          &&MSR_INST,
1600                          &&LDRB_INST,
1601                          &&STRB_INST,
1602                          &&LDR_INST,
1603                          &&LDRCOND_INST,
1604                          &&STR_INST,
1605                          &&CDP_INST,
1606                          &&STC_INST,
1607                          &&LDC_INST,
1608                          &&LDREXD_INST,
1609                          &&STREXD_INST,
1610                          &&LDREXH_INST,
1611                          &&STREXH_INST,
1612                          &&NOP_INST,
1613                          &&YIELD_INST,
1614                          &&WFE_INST,
1615                          &&WFI_INST,
1616                          &&SEV_INST,
1617                          &&SWI_INST,
1618                          &&BBL_INST,
1619                          &&B_2_THUMB,
1620                          &&B_COND_THUMB,
1621                          &&BL_1_THUMB,
1622                          &&BL_2_THUMB,
1623                          &&BLX_1_THUMB,
1624                          &&DISPATCH,
1625                          &&INIT_INST_LENGTH,
1626                          &&END};
1627 #endif
1628     arm_inst* inst_base;
1629     unsigned int addr;
1630     unsigned int num_instrs = 0;
1631 
1632     std::size_t ptr;
1633 
1634     LOAD_NZCVT;
1635 DISPATCH : {
1636     if (!cpu->NirqSig) {
1637         if (!(cpu->Cpsr & 0x80)) {
1638             goto END;
1639         }
1640     }
1641 
1642     if (cpu->TFlag)
1643         cpu->Reg[15] &= 0xfffffffe;
1644     else
1645         cpu->Reg[15] &= 0xfffffffc;
1646 
1647     // Find the cached instruction cream, otherwise translate it...
1648     auto itr = cpu->instruction_cache.find(cpu->Reg[15]);
1649     if (itr != cpu->instruction_cache.end()) {
1650         ptr = itr->second;
1651     } else if (cpu->NumInstrsToExecute != 1) {
1652         if (InterpreterTranslateBlock(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
1653             goto END;
1654     } else {
1655         if (InterpreterTranslateSingle(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
1656             goto END;
1657     }
1658 
1659 #ifndef ANDROID
1660     // Find breakpoint if one exists within the block
1661     if (GDBStub::IsConnected()) {
1662         breakpoint_data =
1663             GDBStub::GetNextBreakpointFromAddress(cpu->Reg[15], GDBStub::BreakpointType::Execute);
1664     }
1665 #endif
1666 
1667     inst_base = (arm_inst*)&trans_cache_buf[ptr];
1668     GOTO_NEXT_INST;
1669 }
1670 ADC_INST : {
1671     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
1672         adc_inst* const inst_cream = (adc_inst*)inst_base->component;
1673 
1674         u32 rn_val = RN;
1675         if (inst_cream->Rn == 15)
1676             rn_val += 2 * cpu->GetInstructionSize();
1677 
1678         bool carry;
1679         bool overflow;
1680         RD = AddWithCarry(rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
1681 
1682         if (inst_cream->S && (inst_cream->Rd == 15)) {
1683             if (cpu->CurrentModeHasSPSR()) {
1684                 cpu->Cpsr = cpu->Spsr_copy;
1685                 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
1686                 LOAD_NZCVT;
1687             }
1688         } else if (inst_cream->S) {
1689             UPDATE_NFLAG(RD);
1690             UPDATE_ZFLAG(RD);
1691             cpu->CFlag = carry;
1692             cpu->VFlag = overflow;
1693         }
1694         if (inst_cream->Rd == 15) {
1695             INC_PC(sizeof(adc_inst));
1696             goto DISPATCH;
1697         }
1698     }
1699     cpu->Reg[15] += cpu->GetInstructionSize();
1700     INC_PC(sizeof(adc_inst));
1701     FETCH_INST;
1702     GOTO_NEXT_INST;
1703 }
1704 ADD_INST : {
1705     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
1706         add_inst* const inst_cream = (add_inst*)inst_base->component;
1707 
1708         u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn);
1709 
1710         bool carry;
1711         bool overflow;
1712         RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
1713 
1714         if (inst_cream->S && (inst_cream->Rd == 15)) {
1715             if (cpu->CurrentModeHasSPSR()) {
1716                 cpu->Cpsr = cpu->Spsr_copy;
1717                 cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
1718                 LOAD_NZCVT;
1719             }
1720         } else if (inst_cream->S) {
1721             UPDATE_NFLAG(RD);
1722             UPDATE_ZFLAG(RD);
1723             cpu->CFlag = carry;
1724             cpu->VFlag = overflow;
1725         }
1726         if (inst_cream->Rd == 15) {
1727             INC_PC(sizeof(add_inst));
1728             goto DISPATCH;
1729         }
1730     }
1731     cpu->Reg[15] += cpu->GetInstructionSize();
1732     INC_PC(sizeof(add_inst));
1733     FETCH_INST;
1734     GOTO_NEXT_INST;
1735 }
1736 AND_INST : {
1737     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
1738         and_inst* const inst_cream = (and_inst*)inst_base->component;
1739 
1740         u32 lop = RN;
1741         u32 rop = SHIFTER_OPERAND;
1742 
1743         if (inst_cream->Rn == 15)
1744             lop += 2 * cpu->GetInstructionSize();
1745 
1746         RD = lop & rop;
1747 
1748         if (inst_cream->S && (inst_cream->Rd == 15)) {
1749             if (cpu->CurrentModeHasSPSR()) {
1750                 cpu->Cpsr = cpu->Spsr_copy;
1751                 cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
1752                 LOAD_NZCVT;
1753             }
1754         } else if (inst_cream->S) {
1755             UPDATE_NFLAG(RD);
1756             UPDATE_ZFLAG(RD);
1757             UPDATE_CFLAG_WITH_SC;
1758         }
1759         if (inst_cream->Rd == 15) {
1760             INC_PC(sizeof(and_inst));
1761             goto DISPATCH;
1762         }
1763     }
1764     cpu->Reg[15] += cpu->GetInstructionSize();
1765     INC_PC(sizeof(and_inst));
1766     FETCH_INST;
1767     GOTO_NEXT_INST;
1768 }
1769 BBL_INST : {
1770     if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
1771         bbl_inst* inst_cream = (bbl_inst*)inst_base->component;
1772         if (inst_cream->L) {
1773             LINK_RTN_ADDR;
1774         }
1775         SET_PC;
1776         INC_PC(sizeof(bbl_inst));
1777         goto DISPATCH;
1778     }
1779     cpu->Reg[15] += cpu->GetInstructionSize();
1780     INC_PC(sizeof(bbl_inst));
1781     goto DISPATCH;
1782 }
1783 BIC_INST : {
1784     bic_inst* inst_cream = (bic_inst*)inst_base->component;
1785     if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
1786         u32 lop = RN;
1787         if (inst_cream->Rn == 15) {
1788             lop += 2 * cpu->GetInstructionSize();
1789         }
1790         u32 rop = SHIFTER_OPERAND;
1791         RD = lop & (~rop);
1792         if ((inst_cream->S) && (inst_cream->Rd == 15)) {
1793             if (cpu->CurrentModeHasSPSR()) {
1794                 cpu->Cpsr = cpu->Spsr_copy;
1795                 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
1796                 LOAD_NZCVT;
1797             }
1798         } else if (inst_cream->S) {
1799             UPDATE_NFLAG(RD);
1800             UPDATE_ZFLAG(RD);
1801             UPDATE_CFLAG_WITH_SC;
1802         }
1803         if (inst_cream->Rd == 15) {
1804             INC_PC(sizeof(bic_inst));
1805             goto DISPATCH;
1806         }
1807     }
1808     cpu->Reg[15] += cpu->GetInstructionSize();
1809     INC_PC(sizeof(bic_inst));
1810     FETCH_INST;
1811     GOTO_NEXT_INST;
1812 }
1813 BKPT_INST : {
1814     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
1815         bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
1816         LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: {:#010X}", inst_cream->imm);
1817     }
1818     cpu->Reg[15] += cpu->GetInstructionSize();
1819     INC_PC(sizeof(bkpt_inst));
1820     FETCH_INST;
1821     GOTO_NEXT_INST;
1822 }
1823 BLX_INST : {
1824     blx_inst* inst_cream = (blx_inst*)inst_base->component;
1825     if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
1826         unsigned int inst = inst_cream->inst;
1827         if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
1828             const u32 jump_address = cpu->Reg[inst_cream->val.Rm];
1829             cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
1830             if (cpu->TFlag)
1831                 cpu->Reg[14] |= 0x1;
1832             cpu->Reg[15] = jump_address & 0xfffffffe;
1833             cpu->TFlag = jump_address & 0x1;
1834         } else {
1835             cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
1836             cpu->TFlag = 0x1;
1837             int signed_int = inst_cream->val.signed_immed_24;
1838             signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int;
1839             signed_int = signed_int << 2;
1840             cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1);
1841         }
1842         INC_PC(sizeof(blx_inst));
1843         goto DISPATCH;
1844     }
1845     cpu->Reg[15] += cpu->GetInstructionSize();
1846     INC_PC(sizeof(blx_inst));
1847     goto DISPATCH;
1848 }
1849 
1850 BX_INST:
1851 BXJ_INST : {
1852     // Note that only the 'fail' case of BXJ is emulated. This is because
1853     // the facilities for Jazelle emulation are not implemented.
1854     //
1855     // According to the ARM documentation on BXJ, if setting the J bit in the APSR
1856     // fails, then BXJ functions identically like a regular BX instruction.
1857     //
1858     // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle.
1859 
1860     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
1861         bx_inst* const inst_cream = (bx_inst*)inst_base->component;
1862 
1863         u32 address = RM;
1864 
1865         if (inst_cream->Rm == 15)
1866             address += 2 * cpu->GetInstructionSize();
1867 
1868         cpu->TFlag = address & 1;
1869         cpu->Reg[15] = address & 0xfffffffe;
1870         INC_PC(sizeof(bx_inst));
1871         goto DISPATCH;
1872     }
1873 
1874     cpu->Reg[15] += cpu->GetInstructionSize();
1875     INC_PC(sizeof(bx_inst));
1876     goto DISPATCH;
1877 }
1878 
1879 CDP_INST : {
1880     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
1881         // Undefined instruction here
1882         cpu->NumInstrsToExecute = 0;
1883         return num_instrs;
1884     }
1885     cpu->Reg[15] += cpu->GetInstructionSize();
1886     INC_PC(sizeof(cdp_inst));
1887     FETCH_INST;
1888     GOTO_NEXT_INST;
1889 }
1890 
1891 CLREX_INST : {
1892     cpu->UnsetExclusiveMemoryAddress();
1893     cpu->Reg[15] += cpu->GetInstructionSize();
1894     INC_PC(sizeof(clrex_inst));
1895     FETCH_INST;
1896     GOTO_NEXT_INST;
1897 }
1898 CLZ_INST : {
1899     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
1900         clz_inst* inst_cream = (clz_inst*)inst_base->component;
1901         RD = clz(RM);
1902     }
1903     cpu->Reg[15] += cpu->GetInstructionSize();
1904     INC_PC(sizeof(clz_inst));
1905     FETCH_INST;
1906     GOTO_NEXT_INST;
1907 }
1908 CMN_INST : {
1909     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
1910         cmn_inst* const inst_cream = (cmn_inst*)inst_base->component;
1911 
1912         u32 rn_val = RN;
1913         if (inst_cream->Rn == 15)
1914             rn_val += 2 * cpu->GetInstructionSize();
1915 
1916         bool carry;
1917         bool overflow;
1918         u32 result = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
1919 
1920         UPDATE_NFLAG(result);
1921         UPDATE_ZFLAG(result);
1922         cpu->CFlag = carry;
1923         cpu->VFlag = overflow;
1924     }
1925     cpu->Reg[15] += cpu->GetInstructionSize();
1926     INC_PC(sizeof(cmn_inst));
1927     FETCH_INST;
1928     GOTO_NEXT_INST;
1929 }
1930 CMP_INST : {
1931     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
1932         cmp_inst* const inst_cream = (cmp_inst*)inst_base->component;
1933 
1934         u32 rn_val = RN;
1935         if (inst_cream->Rn == 15)
1936             rn_val += 2 * cpu->GetInstructionSize();
1937 
1938         bool carry;
1939         bool overflow;
1940         u32 result = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
1941 
1942         UPDATE_NFLAG(result);
1943         UPDATE_ZFLAG(result);
1944         cpu->CFlag = carry;
1945         cpu->VFlag = overflow;
1946     }
1947     cpu->Reg[15] += cpu->GetInstructionSize();
1948     INC_PC(sizeof(cmp_inst));
1949     FETCH_INST;
1950     GOTO_NEXT_INST;
1951 }
1952 CPS_INST : {
1953     cps_inst* inst_cream = (cps_inst*)inst_base->component;
1954     u32 aif_val = 0;
1955     u32 aif_mask = 0;
1956     if (cpu->InAPrivilegedMode()) {
1957         if (inst_cream->imod1) {
1958             if (inst_cream->A) {
1959                 aif_val |= (inst_cream->imod0 << 8);
1960                 aif_mask |= 1 << 8;
1961             }
1962             if (inst_cream->I) {
1963                 aif_val |= (inst_cream->imod0 << 7);
1964                 aif_mask |= 1 << 7;
1965             }
1966             if (inst_cream->F) {
1967                 aif_val |= (inst_cream->imod0 << 6);
1968                 aif_mask |= 1 << 6;
1969             }
1970             aif_mask = ~aif_mask;
1971             cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
1972         }
1973         if (inst_cream->mmod) {
1974             cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
1975             cpu->ChangePrivilegeMode(inst_cream->mode);
1976         }
1977     }
1978     cpu->Reg[15] += cpu->GetInstructionSize();
1979     INC_PC(sizeof(cps_inst));
1980     FETCH_INST;
1981     GOTO_NEXT_INST;
1982 }
1983 CPY_INST : {
1984     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
1985         mov_inst* inst_cream = (mov_inst*)inst_base->component;
1986 
1987         RD = SHIFTER_OPERAND;
1988         if (inst_cream->Rd == 15) {
1989             INC_PC(sizeof(mov_inst));
1990             goto DISPATCH;
1991         }
1992     }
1993     cpu->Reg[15] += cpu->GetInstructionSize();
1994     INC_PC(sizeof(mov_inst));
1995     FETCH_INST;
1996     GOTO_NEXT_INST;
1997 }
1998 EOR_INST : {
1999     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2000         eor_inst* inst_cream = (eor_inst*)inst_base->component;
2001 
2002         u32 lop = RN;
2003         if (inst_cream->Rn == 15) {
2004             lop += 2 * cpu->GetInstructionSize();
2005         }
2006         u32 rop = SHIFTER_OPERAND;
2007         RD = lop ^ rop;
2008         if (inst_cream->S && (inst_cream->Rd == 15)) {
2009             if (cpu->CurrentModeHasSPSR()) {
2010                 cpu->Cpsr = cpu->Spsr_copy;
2011                 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
2012                 LOAD_NZCVT;
2013             }
2014         } else if (inst_cream->S) {
2015             UPDATE_NFLAG(RD);
2016             UPDATE_ZFLAG(RD);
2017             UPDATE_CFLAG_WITH_SC;
2018         }
2019         if (inst_cream->Rd == 15) {
2020             INC_PC(sizeof(eor_inst));
2021             goto DISPATCH;
2022         }
2023     }
2024     cpu->Reg[15] += cpu->GetInstructionSize();
2025     INC_PC(sizeof(eor_inst));
2026     FETCH_INST;
2027     GOTO_NEXT_INST;
2028 }
2029 LDC_INST : {
2030     // Instruction not implemented
2031     // LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
2032     cpu->Reg[15] += cpu->GetInstructionSize();
2033     INC_PC(sizeof(ldc_inst));
2034     FETCH_INST;
2035     GOTO_NEXT_INST;
2036 }
2037 LDM_INST : {
2038     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2039         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
2040         inst_cream->get_addr(cpu, inst_cream->inst, addr);
2041 
2042         unsigned int inst = inst_cream->inst;
2043         if (BIT(inst, 22) && !BIT(inst, 15)) {
2044             for (int i = 0; i < 13; i++) {
2045                 if (BIT(inst, i)) {
2046                     cpu->Reg[i] = cpu->ReadMemory32(addr);
2047                     addr += 4;
2048                 }
2049             }
2050             if (BIT(inst, 13)) {
2051                 if (cpu->Mode == USER32MODE)
2052                     cpu->Reg[13] = cpu->ReadMemory32(addr);
2053                 else
2054                     cpu->Reg_usr[0] = cpu->ReadMemory32(addr);
2055 
2056                 addr += 4;
2057             }
2058             if (BIT(inst, 14)) {
2059                 if (cpu->Mode == USER32MODE)
2060                     cpu->Reg[14] = cpu->ReadMemory32(addr);
2061                 else
2062                     cpu->Reg_usr[1] = cpu->ReadMemory32(addr);
2063 
2064                 addr += 4;
2065             }
2066         } else if (!BIT(inst, 22)) {
2067             for (int i = 0; i < 16; i++) {
2068                 if (BIT(inst, i)) {
2069                     unsigned int ret = cpu->ReadMemory32(addr);
2070 
2071                     // For armv5t, should enter thumb when bits[0] is non-zero.
2072                     if (i == 15) {
2073                         cpu->TFlag = ret & 0x1;
2074                         ret &= 0xFFFFFFFE;
2075                     }
2076 
2077                     cpu->Reg[i] = ret;
2078                     addr += 4;
2079                 }
2080             }
2081         } else if (BIT(inst, 22) && BIT(inst, 15)) {
2082             for (int i = 0; i < 15; i++) {
2083                 if (BIT(inst, i)) {
2084                     cpu->Reg[i] = cpu->ReadMemory32(addr);
2085                     addr += 4;
2086                 }
2087             }
2088 
2089             if (cpu->CurrentModeHasSPSR()) {
2090                 cpu->Cpsr = cpu->Spsr_copy;
2091                 cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
2092                 LOAD_NZCVT;
2093             }
2094 
2095             cpu->Reg[15] = cpu->ReadMemory32(addr);
2096         }
2097 
2098         if (BIT(inst, 15)) {
2099             INC_PC(sizeof(ldst_inst));
2100             goto DISPATCH;
2101         }
2102     }
2103     cpu->Reg[15] += cpu->GetInstructionSize();
2104     INC_PC(sizeof(ldst_inst));
2105     FETCH_INST;
2106     GOTO_NEXT_INST;
2107 }
2108 SXTH_INST : {
2109     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2110         sxth_inst* inst_cream = (sxth_inst*)inst_base->component;
2111 
2112         unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
2113         if (BIT(operand2, 15)) {
2114             operand2 |= 0xffff0000;
2115         } else {
2116             operand2 &= 0xffff;
2117         }
2118         RD = operand2;
2119     }
2120     cpu->Reg[15] += cpu->GetInstructionSize();
2121     INC_PC(sizeof(sxth_inst));
2122     FETCH_INST;
2123     GOTO_NEXT_INST;
2124 }
2125 LDR_INST : {
2126     ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
2127     inst_cream->get_addr(cpu, inst_cream->inst, addr);
2128 
2129     unsigned int value = cpu->ReadMemory32(addr);
2130     cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
2131 
2132     if (BITS(inst_cream->inst, 12, 15) == 15) {
2133         // For armv5t, should enter thumb when bits[0] is non-zero.
2134         cpu->TFlag = value & 0x1;
2135         cpu->Reg[15] &= 0xFFFFFFFE;
2136         INC_PC(sizeof(ldst_inst));
2137         goto DISPATCH;
2138     }
2139 
2140     cpu->Reg[15] += cpu->GetInstructionSize();
2141     INC_PC(sizeof(ldst_inst));
2142     FETCH_INST;
2143     GOTO_NEXT_INST;
2144 }
2145 LDRCOND_INST : {
2146     if (CondPassed(cpu, inst_base->cond)) {
2147         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
2148         inst_cream->get_addr(cpu, inst_cream->inst, addr);
2149 
2150         unsigned int value = cpu->ReadMemory32(addr);
2151         cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
2152 
2153         if (BITS(inst_cream->inst, 12, 15) == 15) {
2154             // For armv5t, should enter thumb when bits[0] is non-zero.
2155             cpu->TFlag = value & 0x1;
2156             cpu->Reg[15] &= 0xFFFFFFFE;
2157             INC_PC(sizeof(ldst_inst));
2158             goto DISPATCH;
2159         }
2160     }
2161     cpu->Reg[15] += cpu->GetInstructionSize();
2162     INC_PC(sizeof(ldst_inst));
2163     FETCH_INST;
2164     GOTO_NEXT_INST;
2165 }
2166 UXTH_INST : {
2167     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2168         uxth_inst* inst_cream = (uxth_inst*)inst_base->component;
2169         RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
2170     }
2171     cpu->Reg[15] += cpu->GetInstructionSize();
2172     INC_PC(sizeof(uxth_inst));
2173     FETCH_INST;
2174     GOTO_NEXT_INST;
2175 }
2176 UXTAH_INST : {
2177     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2178         uxtah_inst* inst_cream = (uxtah_inst*)inst_base->component;
2179         unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
2180 
2181         RD = RN + operand2;
2182     }
2183     cpu->Reg[15] += cpu->GetInstructionSize();
2184     INC_PC(sizeof(uxtah_inst));
2185     FETCH_INST;
2186     GOTO_NEXT_INST;
2187 }
2188 LDRB_INST : {
2189     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2190         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
2191         inst_cream->get_addr(cpu, inst_cream->inst, addr);
2192 
2193         cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr);
2194     }
2195     cpu->Reg[15] += cpu->GetInstructionSize();
2196     INC_PC(sizeof(ldst_inst));
2197     FETCH_INST;
2198     GOTO_NEXT_INST;
2199 }
2200 LDRBT_INST : {
2201     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2202         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
2203         inst_cream->get_addr(cpu, inst_cream->inst, addr);
2204 
2205         const u32 dest_index = BITS(inst_cream->inst, 12, 15);
2206         const u32 previous_mode = cpu->Mode;
2207 
2208         cpu->ChangePrivilegeMode(USER32MODE);
2209         const u8 value = cpu->ReadMemory8(addr);
2210         cpu->ChangePrivilegeMode(previous_mode);
2211 
2212         cpu->Reg[dest_index] = value;
2213     }
2214     cpu->Reg[15] += cpu->GetInstructionSize();
2215     INC_PC(sizeof(ldst_inst));
2216     FETCH_INST;
2217     GOTO_NEXT_INST;
2218 }
2219 LDRD_INST : {
2220     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2221         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
2222         // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 ||
2223         // addr[2] == 0)
2224         inst_cream->get_addr(cpu, inst_cream->inst, addr);
2225 
2226         // The 3DS doesn't have LPAE (Large Physical Access Extension), so it
2227         // wouldn't do this as a single read.
2228         cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr);
2229         cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4);
2230 
2231         // No dispatch since this operation should not modify R15
2232     }
2233     cpu->Reg[15] += 4;
2234     INC_PC(sizeof(ldst_inst));
2235     FETCH_INST;
2236     GOTO_NEXT_INST;
2237 }
2238 
2239 LDREX_INST : {
2240     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2241         generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
2242         unsigned int read_addr = RN;
2243 
2244         cpu->SetExclusiveMemoryAddress(read_addr);
2245 
2246         RD = cpu->ReadMemory32(read_addr);
2247     }
2248     cpu->Reg[15] += cpu->GetInstructionSize();
2249     INC_PC(sizeof(generic_arm_inst));
2250     FETCH_INST;
2251     GOTO_NEXT_INST;
2252 }
2253 LDREXB_INST : {
2254     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2255         generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
2256         unsigned int read_addr = RN;
2257 
2258         cpu->SetExclusiveMemoryAddress(read_addr);
2259 
2260         RD = cpu->ReadMemory8(read_addr);
2261     }
2262     cpu->Reg[15] += cpu->GetInstructionSize();
2263     INC_PC(sizeof(generic_arm_inst));
2264     FETCH_INST;
2265     GOTO_NEXT_INST;
2266 }
2267 LDREXH_INST : {
2268     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2269         generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
2270         unsigned int read_addr = RN;
2271 
2272         cpu->SetExclusiveMemoryAddress(read_addr);
2273 
2274         RD = cpu->ReadMemory16(read_addr);
2275     }
2276     cpu->Reg[15] += cpu->GetInstructionSize();
2277     INC_PC(sizeof(generic_arm_inst));
2278     FETCH_INST;
2279     GOTO_NEXT_INST;
2280 }
2281 LDREXD_INST : {
2282     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2283         generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
2284         unsigned int read_addr = RN;
2285 
2286         cpu->SetExclusiveMemoryAddress(read_addr);
2287 
2288         RD = cpu->ReadMemory32(read_addr);
2289         RD2 = cpu->ReadMemory32(read_addr + 4);
2290     }
2291     cpu->Reg[15] += cpu->GetInstructionSize();
2292     INC_PC(sizeof(generic_arm_inst));
2293     FETCH_INST;
2294     GOTO_NEXT_INST;
2295 }
2296 LDRH_INST : {
2297     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2298         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
2299         inst_cream->get_addr(cpu, inst_cream->inst, addr);
2300 
2301         cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr);
2302     }
2303     cpu->Reg[15] += cpu->GetInstructionSize();
2304     INC_PC(sizeof(ldst_inst));
2305     FETCH_INST;
2306     GOTO_NEXT_INST;
2307 }
2308 LDRSB_INST : {
2309     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2310         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
2311         inst_cream->get_addr(cpu, inst_cream->inst, addr);
2312         unsigned int value = cpu->ReadMemory8(addr);
2313         if (BIT(value, 7)) {
2314             value |= 0xffffff00;
2315         }
2316         cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
2317     }
2318     cpu->Reg[15] += cpu->GetInstructionSize();
2319     INC_PC(sizeof(ldst_inst));
2320     FETCH_INST;
2321     GOTO_NEXT_INST;
2322 }
2323 LDRSH_INST : {
2324     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2325         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
2326         inst_cream->get_addr(cpu, inst_cream->inst, addr);
2327 
2328         unsigned int value = cpu->ReadMemory16(addr);
2329         if (BIT(value, 15)) {
2330             value |= 0xffff0000;
2331         }
2332         cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
2333     }
2334     cpu->Reg[15] += cpu->GetInstructionSize();
2335     INC_PC(sizeof(ldst_inst));
2336     FETCH_INST;
2337     GOTO_NEXT_INST;
2338 }
2339 LDRT_INST : {
2340     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2341         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
2342         inst_cream->get_addr(cpu, inst_cream->inst, addr);
2343 
2344         const u32 dest_index = BITS(inst_cream->inst, 12, 15);
2345         const u32 previous_mode = cpu->Mode;
2346 
2347         cpu->ChangePrivilegeMode(USER32MODE);
2348         const u32 value = cpu->ReadMemory32(addr);
2349         cpu->ChangePrivilegeMode(previous_mode);
2350 
2351         cpu->Reg[dest_index] = value;
2352     }
2353     cpu->Reg[15] += cpu->GetInstructionSize();
2354     INC_PC(sizeof(ldst_inst));
2355     FETCH_INST;
2356     GOTO_NEXT_INST;
2357 }
2358 MCR_INST : {
2359     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2360         mcr_inst* inst_cream = (mcr_inst*)inst_base->component;
2361 
2362         unsigned int inst = inst_cream->inst;
2363         if (inst_cream->Rd == 15) {
2364             DEBUG_MSG;
2365         } else {
2366             if (inst_cream->cp_num == 15)
2367                 cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2);
2368         }
2369     }
2370     cpu->Reg[15] += cpu->GetInstructionSize();
2371     INC_PC(sizeof(mcr_inst));
2372     FETCH_INST;
2373     GOTO_NEXT_INST;
2374 }
2375 
2376 MCRR_INST : {
2377     // Stubbed, as the MPCore doesn't have any registers that are accessible
2378     // through this instruction.
2379     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2380         mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
2381 
2382         LOG_ERROR(Core_ARM11, "MCRR executed | Coprocessor: {}, CRm {}, opc1: {}, Rt: {}, Rt2: {}",
2383                   inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt,
2384                   inst_cream->rt2);
2385     }
2386 
2387     cpu->Reg[15] += cpu->GetInstructionSize();
2388     INC_PC(sizeof(mcrr_inst));
2389     FETCH_INST;
2390     GOTO_NEXT_INST;
2391 }
2392 
2393 MLA_INST : {
2394     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2395         mla_inst* inst_cream = (mla_inst*)inst_base->component;
2396 
2397         u64 rm = RM;
2398         u64 rs = RS;
2399         u64 rn = RN;
2400 
2401         RD = static_cast<u32>((rm * rs + rn) & 0xffffffff);
2402         if (inst_cream->S) {
2403             UPDATE_NFLAG(RD);
2404             UPDATE_ZFLAG(RD);
2405         }
2406     }
2407     cpu->Reg[15] += cpu->GetInstructionSize();
2408     INC_PC(sizeof(mla_inst));
2409     FETCH_INST;
2410     GOTO_NEXT_INST;
2411 }
2412 MOV_INST : {
2413     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2414         mov_inst* inst_cream = (mov_inst*)inst_base->component;
2415 
2416         RD = SHIFTER_OPERAND;
2417         if (inst_cream->S && (inst_cream->Rd == 15)) {
2418             if (cpu->CurrentModeHasSPSR()) {
2419                 cpu->Cpsr = cpu->Spsr_copy;
2420                 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
2421                 LOAD_NZCVT;
2422             }
2423         } else if (inst_cream->S) {
2424             UPDATE_NFLAG(RD);
2425             UPDATE_ZFLAG(RD);
2426             UPDATE_CFLAG_WITH_SC;
2427         }
2428         if (inst_cream->Rd == 15) {
2429             INC_PC(sizeof(mov_inst));
2430             goto DISPATCH;
2431         }
2432     }
2433     cpu->Reg[15] += cpu->GetInstructionSize();
2434     INC_PC(sizeof(mov_inst));
2435     FETCH_INST;
2436     GOTO_NEXT_INST;
2437 }
2438 MRC_INST : {
2439     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2440         mrc_inst* inst_cream = (mrc_inst*)inst_base->component;
2441 
2442         if (inst_cream->cp_num == 15) {
2443             const uint32_t value = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2);
2444 
2445             if (inst_cream->Rd == 15) {
2446                 cpu->Cpsr = (cpu->Cpsr & ~0xF0000000) | (value & 0xF0000000);
2447                 LOAD_NZCVT;
2448             } else {
2449                 RD = value;
2450             }
2451         }
2452     }
2453     cpu->Reg[15] += cpu->GetInstructionSize();
2454     INC_PC(sizeof(mrc_inst));
2455     FETCH_INST;
2456     GOTO_NEXT_INST;
2457 }
2458 
2459 MRRC_INST : {
2460     // Stubbed, as the MPCore doesn't have any registers that are accessible
2461     // through this instruction.
2462     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2463         mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
2464 
2465         LOG_ERROR(Core_ARM11, "MRRC executed | Coprocessor: {}, CRm {}, opc1: {}, Rt: {}, Rt2: {}",
2466                   inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt,
2467                   inst_cream->rt2);
2468     }
2469 
2470     cpu->Reg[15] += cpu->GetInstructionSize();
2471     INC_PC(sizeof(mcrr_inst));
2472     FETCH_INST;
2473     GOTO_NEXT_INST;
2474 }
2475 
2476 MRS_INST : {
2477     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2478         mrs_inst* inst_cream = (mrs_inst*)inst_base->component;
2479 
2480         if (inst_cream->R) {
2481             RD = cpu->Spsr_copy;
2482         } else {
2483             SAVE_NZCVT;
2484             RD = cpu->Cpsr;
2485         }
2486     }
2487     cpu->Reg[15] += cpu->GetInstructionSize();
2488     INC_PC(sizeof(mrs_inst));
2489     FETCH_INST;
2490     GOTO_NEXT_INST;
2491 }
2492 MSR_INST : {
2493     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2494         msr_inst* inst_cream = (msr_inst*)inst_base->component;
2495         const u32 UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
2496         unsigned int inst = inst_cream->inst;
2497         unsigned int operand;
2498 
2499         if (BIT(inst, 25)) {
2500             int rot_imm = BITS(inst, 8, 11) * 2;
2501             operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
2502         } else {
2503             operand = cpu->Reg[BITS(inst, 0, 3)];
2504         }
2505         u32 byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) |
2506                         (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
2507         u32 mask = 0;
2508         if (!inst_cream->R) {
2509             if (cpu->InAPrivilegedMode()) {
2510                 if ((operand & StateMask) != 0) {
2511                     /// UNPREDICTABLE
2512                     DEBUG_MSG;
2513                 } else
2514                     mask = byte_mask & (UserMask | PrivMask);
2515             } else {
2516                 mask = byte_mask & UserMask;
2517             }
2518             SAVE_NZCVT;
2519 
2520             cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
2521             cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
2522             LOAD_NZCVT;
2523         } else {
2524             if (cpu->CurrentModeHasSPSR()) {
2525                 mask = byte_mask & (UserMask | PrivMask | StateMask);
2526                 cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
2527             }
2528         }
2529     }
2530     cpu->Reg[15] += cpu->GetInstructionSize();
2531     INC_PC(sizeof(msr_inst));
2532     FETCH_INST;
2533     GOTO_NEXT_INST;
2534 }
2535 MUL_INST : {
2536     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2537         mul_inst* inst_cream = (mul_inst*)inst_base->component;
2538 
2539         u64 rm = RM;
2540         u64 rs = RS;
2541         RD = static_cast<u32>((rm * rs) & 0xffffffff);
2542         if (inst_cream->S) {
2543             UPDATE_NFLAG(RD);
2544             UPDATE_ZFLAG(RD);
2545         }
2546     }
2547     cpu->Reg[15] += cpu->GetInstructionSize();
2548     INC_PC(sizeof(mul_inst));
2549     FETCH_INST;
2550     GOTO_NEXT_INST;
2551 }
2552 MVN_INST : {
2553     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2554         mvn_inst* const inst_cream = (mvn_inst*)inst_base->component;
2555 
2556         RD = ~SHIFTER_OPERAND;
2557 
2558         if (inst_cream->S && (inst_cream->Rd == 15)) {
2559             if (cpu->CurrentModeHasSPSR()) {
2560                 cpu->Cpsr = cpu->Spsr_copy;
2561                 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
2562                 LOAD_NZCVT;
2563             }
2564         } else if (inst_cream->S) {
2565             UPDATE_NFLAG(RD);
2566             UPDATE_ZFLAG(RD);
2567             UPDATE_CFLAG_WITH_SC;
2568         }
2569         if (inst_cream->Rd == 15) {
2570             INC_PC(sizeof(mvn_inst));
2571             goto DISPATCH;
2572         }
2573     }
2574     cpu->Reg[15] += cpu->GetInstructionSize();
2575     INC_PC(sizeof(mvn_inst));
2576     FETCH_INST;
2577     GOTO_NEXT_INST;
2578 }
2579 ORR_INST : {
2580     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2581         orr_inst* const inst_cream = (orr_inst*)inst_base->component;
2582 
2583         u32 lop = RN;
2584         u32 rop = SHIFTER_OPERAND;
2585 
2586         if (inst_cream->Rn == 15)
2587             lop += 2 * cpu->GetInstructionSize();
2588 
2589         RD = lop | rop;
2590 
2591         if (inst_cream->S && (inst_cream->Rd == 15)) {
2592             if (cpu->CurrentModeHasSPSR()) {
2593                 cpu->Cpsr = cpu->Spsr_copy;
2594                 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
2595                 LOAD_NZCVT;
2596             }
2597         } else if (inst_cream->S) {
2598             UPDATE_NFLAG(RD);
2599             UPDATE_ZFLAG(RD);
2600             UPDATE_CFLAG_WITH_SC;
2601         }
2602         if (inst_cream->Rd == 15) {
2603             INC_PC(sizeof(orr_inst));
2604             goto DISPATCH;
2605         }
2606     }
2607     cpu->Reg[15] += cpu->GetInstructionSize();
2608     INC_PC(sizeof(orr_inst));
2609     FETCH_INST;
2610     GOTO_NEXT_INST;
2611 }
2612 
2613 NOP_INST : {
2614     cpu->Reg[15] += cpu->GetInstructionSize();
2615     INC_PC_STUB;
2616     FETCH_INST;
2617     GOTO_NEXT_INST;
2618 }
2619 
2620 PKHBT_INST : {
2621     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2622         pkh_inst* inst_cream = (pkh_inst*)inst_base->component;
2623         RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
2624     }
2625     cpu->Reg[15] += cpu->GetInstructionSize();
2626     INC_PC(sizeof(pkh_inst));
2627     FETCH_INST;
2628     GOTO_NEXT_INST;
2629 }
2630 
2631 PKHTB_INST : {
2632     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2633         pkh_inst* inst_cream = (pkh_inst*)inst_base->component;
2634         int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
2635         RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
2636     }
2637     cpu->Reg[15] += cpu->GetInstructionSize();
2638     INC_PC(sizeof(pkh_inst));
2639     FETCH_INST;
2640     GOTO_NEXT_INST;
2641 }
2642 
2643 PLD_INST : {
2644     // Not implemented. PLD is a hint instruction, so it's optional.
2645 
2646     cpu->Reg[15] += cpu->GetInstructionSize();
2647     INC_PC(sizeof(pld_inst));
2648     FETCH_INST;
2649     GOTO_NEXT_INST;
2650 }
2651 
2652 QADD_INST:
2653 QDADD_INST:
2654 QDSUB_INST:
2655 QSUB_INST : {
2656     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2657         generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
2658         const u8 op1 = inst_cream->op1;
2659         const u32 rm_val = RM;
2660         const u32 rn_val = RN;
2661 
2662         u32 result = 0;
2663 
2664         // QADD
2665         if (op1 == 0x00) {
2666             result = rm_val + rn_val;
2667 
2668             if (AddOverflow(rm_val, rn_val, result)) {
2669                 result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
2670                 cpu->Cpsr |= (1 << 27);
2671             }
2672         }
2673         // QSUB
2674         else if (op1 == 0x01) {
2675             result = rm_val - rn_val;
2676 
2677             if (SubOverflow(rm_val, rn_val, result)) {
2678                 result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
2679                 cpu->Cpsr |= (1 << 27);
2680             }
2681         }
2682         // QDADD
2683         else if (op1 == 0x02) {
2684             u32 mul = (rn_val * 2);
2685 
2686             if (AddOverflow(rn_val, rn_val, rn_val * 2)) {
2687                 mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
2688                 cpu->Cpsr |= (1 << 27);
2689             }
2690 
2691             result = mul + rm_val;
2692 
2693             if (AddOverflow(rm_val, mul, result)) {
2694                 result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
2695                 cpu->Cpsr |= (1 << 27);
2696             }
2697         }
2698         // QDSUB
2699         else if (op1 == 0x03) {
2700             u32 mul = (rn_val * 2);
2701 
2702             if (AddOverflow(rn_val, rn_val, mul)) {
2703                 mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
2704                 cpu->Cpsr |= (1 << 27);
2705             }
2706 
2707             result = rm_val - mul;
2708 
2709             if (SubOverflow(rm_val, mul, result)) {
2710                 result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
2711                 cpu->Cpsr |= (1 << 27);
2712             }
2713         }
2714 
2715         RD = result;
2716     }
2717 
2718     cpu->Reg[15] += cpu->GetInstructionSize();
2719     INC_PC(sizeof(generic_arm_inst));
2720     FETCH_INST;
2721     GOTO_NEXT_INST;
2722 }
2723 
2724 QADD8_INST:
2725 QADD16_INST:
2726 QADDSUBX_INST:
2727 QSUB8_INST:
2728 QSUB16_INST:
2729 QSUBADDX_INST : {
2730     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2731         generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
2732         const u16 rm_lo = (RM & 0xFFFF);
2733         const u16 rm_hi = ((RM >> 16) & 0xFFFF);
2734         const u16 rn_lo = (RN & 0xFFFF);
2735         const u16 rn_hi = ((RN >> 16) & 0xFFFF);
2736         const u8 op2 = inst_cream->op2;
2737 
2738         u16 lo_result = 0;
2739         u16 hi_result = 0;
2740 
2741         // QADD16
2742         if (op2 == 0x00) {
2743             lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
2744             hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
2745         }
2746         // QASX
2747         else if (op2 == 0x01) {
2748             lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
2749             hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
2750         }
2751         // QSAX
2752         else if (op2 == 0x02) {
2753             lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
2754             hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
2755         }
2756         // QSUB16
2757         else if (op2 == 0x03) {
2758             lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
2759             hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
2760         }
2761         // QADD8
2762         else if (op2 == 0x04) {
2763             lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
2764                         ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
2765             hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
2766                         ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
2767         }
2768         // QSUB8
2769         else if (op2 == 0x07) {
2770             lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
2771                         ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
2772             hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
2773                         ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
2774         }
2775 
2776         RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
2777     }
2778 
2779     cpu->Reg[15] += cpu->GetInstructionSize();
2780     INC_PC(sizeof(generic_arm_inst));
2781     FETCH_INST;
2782     GOTO_NEXT_INST;
2783 }
2784 
2785 REV_INST:
2786 REV16_INST:
2787 REVSH_INST : {
2788 
2789     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2790         rev_inst* const inst_cream = (rev_inst*)inst_base->component;
2791 
2792         const u8 op1 = inst_cream->op1;
2793         const u8 op2 = inst_cream->op2;
2794 
2795         // REV
2796         if (op1 == 0x03 && op2 == 0x01) {
2797             RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) |
2798                  ((RM >> 24) & 0xFF);
2799         }
2800         // REV16
2801         else if (op1 == 0x03 && op2 == 0x05) {
2802             RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) |
2803                  ((RM & 0xFF000000) >> 8);
2804         }
2805         // REVSH
2806         else if (op1 == 0x07 && op2 == 0x05) {
2807             RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8);
2808             if (RD & 0x8000)
2809                 RD |= 0xffff0000;
2810         }
2811     }
2812 
2813     cpu->Reg[15] += cpu->GetInstructionSize();
2814     INC_PC(sizeof(rev_inst));
2815     FETCH_INST;
2816     GOTO_NEXT_INST;
2817 }
2818 
2819 RFE_INST : {
2820     // RFE is unconditional
2821     ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
2822 
2823     u32 address = 0;
2824     inst_cream->get_addr(cpu, inst_cream->inst, address);
2825 
2826     cpu->Cpsr = cpu->ReadMemory32(address);
2827     cpu->Reg[15] = cpu->ReadMemory32(address + 4);
2828 
2829     INC_PC(sizeof(ldst_inst));
2830     goto DISPATCH;
2831 }
2832 
2833 RSB_INST : {
2834     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2835         rsb_inst* const inst_cream = (rsb_inst*)inst_base->component;
2836 
2837         u32 rn_val = RN;
2838         if (inst_cream->Rn == 15)
2839             rn_val += 2 * cpu->GetInstructionSize();
2840 
2841         bool carry;
2842         bool overflow;
2843         RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, 1, &carry, &overflow);
2844 
2845         if (inst_cream->S && (inst_cream->Rd == 15)) {
2846             if (cpu->CurrentModeHasSPSR()) {
2847                 cpu->Cpsr = cpu->Spsr_copy;
2848                 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
2849                 LOAD_NZCVT;
2850             }
2851         } else if (inst_cream->S) {
2852             UPDATE_NFLAG(RD);
2853             UPDATE_ZFLAG(RD);
2854             cpu->CFlag = carry;
2855             cpu->VFlag = overflow;
2856         }
2857         if (inst_cream->Rd == 15) {
2858             INC_PC(sizeof(rsb_inst));
2859             goto DISPATCH;
2860         }
2861     }
2862     cpu->Reg[15] += cpu->GetInstructionSize();
2863     INC_PC(sizeof(rsb_inst));
2864     FETCH_INST;
2865     GOTO_NEXT_INST;
2866 }
2867 RSC_INST : {
2868     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2869         rsc_inst* const inst_cream = (rsc_inst*)inst_base->component;
2870 
2871         u32 rn_val = RN;
2872         if (inst_cream->Rn == 15)
2873             rn_val += 2 * cpu->GetInstructionSize();
2874 
2875         bool carry;
2876         bool overflow;
2877         RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
2878 
2879         if (inst_cream->S && (inst_cream->Rd == 15)) {
2880             if (cpu->CurrentModeHasSPSR()) {
2881                 cpu->Cpsr = cpu->Spsr_copy;
2882                 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
2883                 LOAD_NZCVT;
2884             }
2885         } else if (inst_cream->S) {
2886             UPDATE_NFLAG(RD);
2887             UPDATE_ZFLAG(RD);
2888             cpu->CFlag = carry;
2889             cpu->VFlag = overflow;
2890         }
2891         if (inst_cream->Rd == 15) {
2892             INC_PC(sizeof(rsc_inst));
2893             goto DISPATCH;
2894         }
2895     }
2896     cpu->Reg[15] += cpu->GetInstructionSize();
2897     INC_PC(sizeof(rsc_inst));
2898     FETCH_INST;
2899     GOTO_NEXT_INST;
2900 }
2901 
2902 SADD8_INST:
2903 SSUB8_INST:
2904 SADD16_INST:
2905 SADDSUBX_INST:
2906 SSUBADDX_INST:
2907 SSUB16_INST : {
2908     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
2909         generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
2910         const u8 op2 = inst_cream->op2;
2911 
2912         if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
2913             const s16 rn_lo = (RN & 0xFFFF);
2914             const s16 rn_hi = ((RN >> 16) & 0xFFFF);
2915             const s16 rm_lo = (RM & 0xFFFF);
2916             const s16 rm_hi = ((RM >> 16) & 0xFFFF);
2917 
2918             s32 lo_result = 0;
2919             s32 hi_result = 0;
2920 
2921             // SADD16
2922             if (inst_cream->op2 == 0x00) {
2923                 lo_result = (rn_lo + rm_lo);
2924                 hi_result = (rn_hi + rm_hi);
2925             }
2926             // SASX
2927             else if (op2 == 0x01) {
2928                 lo_result = (rn_lo - rm_hi);
2929                 hi_result = (rn_hi + rm_lo);
2930             }
2931             // SSAX
2932             else if (op2 == 0x02) {
2933                 lo_result = (rn_lo + rm_hi);
2934                 hi_result = (rn_hi - rm_lo);
2935             }
2936             // SSUB16
2937             else if (op2 == 0x03) {
2938                 lo_result = (rn_lo - rm_lo);
2939                 hi_result = (rn_hi - rm_hi);
2940             }
2941 
2942             RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
2943 
2944             if (lo_result >= 0) {
2945                 cpu->Cpsr |= (1 << 16);
2946                 cpu->Cpsr |= (1 << 17);
2947             } else {
2948                 cpu->Cpsr &= ~(1 << 16);
2949                 cpu->Cpsr &= ~(1 << 17);
2950             }
2951 
2952             if (hi_result >= 0) {
2953                 cpu->Cpsr |= (1 << 18);
2954                 cpu->Cpsr |= (1 << 19);
2955             } else {
2956                 cpu->Cpsr &= ~(1 << 18);
2957                 cpu->Cpsr &= ~(1 << 19);
2958             }
2959         } else if (op2 == 0x04 || op2 == 0x07) {
2960             s32 lo_val1, lo_val2;
2961             s32 hi_val1, hi_val2;
2962 
2963             // SADD8
2964             if (op2 == 0x04) {
2965                 lo_val1 = (s32)(s8)(RN & 0xFF) + (s32)(s8)(RM & 0xFF);
2966                 lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) + (s32)(s8)((RM >> 8) & 0xFF);
2967                 hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) + (s32)(s8)((RM >> 16) & 0xFF);
2968                 hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) + (s32)(s8)((RM >> 24) & 0xFF);
2969             }
2970             // SSUB8
2971             else {
2972                 lo_val1 = (s32)(s8)(RN & 0xFF) - (s32)(s8)(RM & 0xFF);
2973                 lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) - (s32)(s8)((RM >> 8) & 0xFF);
2974                 hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) - (s32)(s8)((RM >> 16) & 0xFF);
2975                 hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) - (s32)(s8)((RM >> 24) & 0xFF);
2976             }
2977 
2978             RD = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) |
2979                   ((hi_val2 & 0xFF) << 24));
2980 
2981             if (lo_val1 >= 0)
2982                 cpu->Cpsr |= (1 << 16);
2983             else
2984                 cpu->Cpsr &= ~(1 << 16);
2985 
2986             if (lo_val2 >= 0)
2987                 cpu->Cpsr |= (1 << 17);
2988             else
2989                 cpu->Cpsr &= ~(1 << 17);
2990 
2991             if (hi_val1 >= 0)
2992                 cpu->Cpsr |= (1 << 18);
2993             else
2994                 cpu->Cpsr &= ~(1 << 18);
2995 
2996             if (hi_val2 >= 0)
2997                 cpu->Cpsr |= (1 << 19);
2998             else
2999                 cpu->Cpsr &= ~(1 << 19);
3000         }
3001     }
3002 
3003     cpu->Reg[15] += cpu->GetInstructionSize();
3004     INC_PC(sizeof(generic_arm_inst));
3005     FETCH_INST;
3006     GOTO_NEXT_INST;
3007 }
3008 
3009 SBC_INST : {
3010     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3011         sbc_inst* const inst_cream = (sbc_inst*)inst_base->component;
3012 
3013         u32 rn_val = RN;
3014         if (inst_cream->Rn == 15)
3015             rn_val += 2 * cpu->GetInstructionSize();
3016 
3017         bool carry;
3018         bool overflow;
3019         RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
3020 
3021         if (inst_cream->S && (inst_cream->Rd == 15)) {
3022             if (cpu->CurrentModeHasSPSR()) {
3023                 cpu->Cpsr = cpu->Spsr_copy;
3024                 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
3025                 LOAD_NZCVT;
3026             }
3027         } else if (inst_cream->S) {
3028             UPDATE_NFLAG(RD);
3029             UPDATE_ZFLAG(RD);
3030             cpu->CFlag = carry;
3031             cpu->VFlag = overflow;
3032         }
3033         if (inst_cream->Rd == 15) {
3034             INC_PC(sizeof(sbc_inst));
3035             goto DISPATCH;
3036         }
3037     }
3038     cpu->Reg[15] += cpu->GetInstructionSize();
3039     INC_PC(sizeof(sbc_inst));
3040     FETCH_INST;
3041     GOTO_NEXT_INST;
3042 }
3043 
3044 SEL_INST : {
3045     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3046         generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
3047 
3048         const u32 to = RM;
3049         const u32 from = RN;
3050         const u32 cpsr = cpu->Cpsr;
3051 
3052         u32 result;
3053         if (cpsr & (1 << 16))
3054             result = from & 0xff;
3055         else
3056             result = to & 0xff;
3057 
3058         if (cpsr & (1 << 17))
3059             result |= from & 0x0000ff00;
3060         else
3061             result |= to & 0x0000ff00;
3062 
3063         if (cpsr & (1 << 18))
3064             result |= from & 0x00ff0000;
3065         else
3066             result |= to & 0x00ff0000;
3067 
3068         if (cpsr & (1 << 19))
3069             result |= from & 0xff000000;
3070         else
3071             result |= to & 0xff000000;
3072 
3073         RD = result;
3074     }
3075 
3076     cpu->Reg[15] += cpu->GetInstructionSize();
3077     INC_PC(sizeof(generic_arm_inst));
3078     FETCH_INST;
3079     GOTO_NEXT_INST;
3080 }
3081 
3082 SETEND_INST : {
3083     // SETEND is unconditional
3084     setend_inst* const inst_cream = (setend_inst*)inst_base->component;
3085     const bool big_endian = (inst_cream->set_bigend == 1);
3086 
3087     if (big_endian)
3088         cpu->Cpsr |= (1 << 9);
3089     else
3090         cpu->Cpsr &= ~(1 << 9);
3091 
3092     LOG_WARNING(Core_ARM11, "SETEND {} executed", big_endian ? "BE" : "LE");
3093 
3094     cpu->Reg[15] += cpu->GetInstructionSize();
3095     INC_PC(sizeof(setend_inst));
3096     FETCH_INST;
3097     GOTO_NEXT_INST;
3098 }
3099 
3100 SEV_INST : {
3101     // Stubbed, as SEV is a hint instruction.
3102     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3103         LOG_TRACE(Core_ARM11, "SEV executed.");
3104     }
3105 
3106     cpu->Reg[15] += cpu->GetInstructionSize();
3107     INC_PC_STUB;
3108     FETCH_INST;
3109     GOTO_NEXT_INST;
3110 }
3111 
3112 SHADD8_INST:
3113 SHADD16_INST:
3114 SHADDSUBX_INST:
3115 SHSUB8_INST:
3116 SHSUB16_INST:
3117 SHSUBADDX_INST : {
3118     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3119         generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
3120 
3121         const u8 op2 = inst_cream->op2;
3122         const u32 rm_val = RM;
3123         const u32 rn_val = RN;
3124 
3125         if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
3126             s32 lo_result = 0;
3127             s32 hi_result = 0;
3128 
3129             // SHADD16
3130             if (op2 == 0x00) {
3131                 lo_result = ((s16)(rn_val & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
3132                 hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
3133             }
3134             // SHASX
3135             else if (op2 == 0x01) {
3136                 lo_result = ((s16)(rn_val & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
3137                 hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
3138             }
3139             // SHSAX
3140             else if (op2 == 0x02) {
3141                 lo_result = ((s16)(rn_val & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
3142                 hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
3143             }
3144             // SHSUB16
3145             else if (op2 == 0x03) {
3146                 lo_result = ((s16)(rn_val & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
3147                 hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
3148             }
3149 
3150             RD = ((lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16));
3151         } else if (op2 == 0x04 || op2 == 0x07) {
3152             s16 lo_val1, lo_val2;
3153             s16 hi_val1, hi_val2;
3154 
3155             // SHADD8
3156             if (op2 == 0x04) {
3157                 lo_val1 = ((s8)(rn_val & 0xFF) + (s8)(rm_val & 0xFF)) >> 1;
3158                 lo_val2 = ((s8)((rn_val >> 8) & 0xFF) + (s8)((rm_val >> 8) & 0xFF)) >> 1;
3159 
3160                 hi_val1 = ((s8)((rn_val >> 16) & 0xFF) + (s8)((rm_val >> 16) & 0xFF)) >> 1;
3161                 hi_val2 = ((s8)((rn_val >> 24) & 0xFF) + (s8)((rm_val >> 24) & 0xFF)) >> 1;
3162             }
3163             // SHSUB8
3164             else {
3165                 lo_val1 = ((s8)(rn_val & 0xFF) - (s8)(rm_val & 0xFF)) >> 1;
3166                 lo_val2 = ((s8)((rn_val >> 8) & 0xFF) - (s8)((rm_val >> 8) & 0xFF)) >> 1;
3167 
3168                 hi_val1 = ((s8)((rn_val >> 16) & 0xFF) - (s8)((rm_val >> 16) & 0xFF)) >> 1;
3169                 hi_val2 = ((s8)((rn_val >> 24) & 0xFF) - (s8)((rm_val >> 24) & 0xFF)) >> 1;
3170             }
3171 
3172             RD = (lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) |
3173                  ((hi_val2 & 0xFF) << 24);
3174         }
3175     }
3176 
3177     cpu->Reg[15] += cpu->GetInstructionSize();
3178     INC_PC(sizeof(generic_arm_inst));
3179     FETCH_INST;
3180     GOTO_NEXT_INST;
3181 }
3182 
3183 SMLA_INST : {
3184     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3185         smla_inst* inst_cream = (smla_inst*)inst_base->component;
3186         s32 operand1, operand2;
3187         if (inst_cream->x == 0)
3188             operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
3189         else
3190             operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
3191 
3192         if (inst_cream->y == 0)
3193             operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
3194         else
3195             operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
3196 
3197         u32 product = operand1 * operand2;
3198         u32 result = product + RN;
3199         if (AddOverflow(product, RN, result))
3200             cpu->Cpsr |= (1 << 27);
3201         RD = result;
3202     }
3203     cpu->Reg[15] += cpu->GetInstructionSize();
3204     INC_PC(sizeof(smla_inst));
3205     FETCH_INST;
3206     GOTO_NEXT_INST;
3207 }
3208 
3209 SMLAD_INST:
3210 SMLSD_INST:
3211 SMUAD_INST:
3212 SMUSD_INST : {
3213     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3214         smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
3215         const u8 op2 = inst_cream->op2;
3216 
3217         u32 rm_val = cpu->Reg[inst_cream->Rm];
3218         const u32 rn_val = cpu->Reg[inst_cream->Rn];
3219 
3220         if (inst_cream->m)
3221             rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
3222 
3223         const s16 rm_lo = (rm_val & 0xFFFF);
3224         const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
3225         const s16 rn_lo = (rn_val & 0xFFFF);
3226         const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
3227 
3228         const u32 product1 = (rn_lo * rm_lo);
3229         const u32 product2 = (rn_hi * rm_hi);
3230 
3231         // SMUAD and SMLAD
3232         if (BIT(op2, 1) == 0) {
3233             u32 rd_val = (product1 + product2);
3234 
3235             if (inst_cream->Ra != 15) {
3236                 rd_val += cpu->Reg[inst_cream->Ra];
3237 
3238                 if (ARMul_AddOverflowQ(product1 + product2, cpu->Reg[inst_cream->Ra]))
3239                     cpu->Cpsr |= (1 << 27);
3240             }
3241 
3242             RD = rd_val;
3243 
3244             if (ARMul_AddOverflowQ(product1, product2))
3245                 cpu->Cpsr |= (1 << 27);
3246         }
3247         // SMUSD and SMLSD
3248         else {
3249             u32 rd_val = (product1 - product2);
3250 
3251             if (inst_cream->Ra != 15) {
3252                 rd_val += cpu->Reg[inst_cream->Ra];
3253 
3254                 if (ARMul_AddOverflowQ(product1 - product2, cpu->Reg[inst_cream->Ra]))
3255                     cpu->Cpsr |= (1 << 27);
3256             }
3257 
3258             RD = rd_val;
3259         }
3260     }
3261 
3262     cpu->Reg[15] += cpu->GetInstructionSize();
3263     INC_PC(sizeof(smlad_inst));
3264     FETCH_INST;
3265     GOTO_NEXT_INST;
3266 }
3267 
3268 SMLAL_INST : {
3269     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3270         umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
3271         long long int rm = RM;
3272         long long int rs = RS;
3273         if (BIT(rm, 31)) {
3274             rm |= 0xffffffff00000000LL;
3275         }
3276         if (BIT(rs, 31)) {
3277             rs |= 0xffffffff00000000LL;
3278         }
3279         long long int rst = rm * rs;
3280         long long int rdhi32 = RDHI;
3281         long long int hilo = (rdhi32 << 32) + RDLO;
3282         rst += hilo;
3283         RDLO = BITS(rst, 0, 31);
3284         RDHI = BITS(rst, 32, 63);
3285         if (inst_cream->S) {
3286             cpu->NFlag = BIT(RDHI, 31);
3287             cpu->ZFlag = (RDHI == 0 && RDLO == 0);
3288         }
3289     }
3290     cpu->Reg[15] += cpu->GetInstructionSize();
3291     INC_PC(sizeof(umlal_inst));
3292     FETCH_INST;
3293     GOTO_NEXT_INST;
3294 }
3295 
3296 SMLALXY_INST : {
3297     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3298         smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component;
3299 
3300         u64 operand1 = RN;
3301         u64 operand2 = RM;
3302 
3303         if (inst_cream->x != 0)
3304             operand1 >>= 16;
3305         if (inst_cream->y != 0)
3306             operand2 >>= 16;
3307         operand1 &= 0xFFFF;
3308         if (operand1 & 0x8000)
3309             operand1 -= 65536;
3310         operand2 &= 0xFFFF;
3311         if (operand2 & 0x8000)
3312             operand2 -= 65536;
3313 
3314         u64 dest = ((u64)RDHI << 32 | RDLO) + (operand1 * operand2);
3315         RDLO = (dest & 0xFFFFFFFF);
3316         RDHI = ((dest >> 32) & 0xFFFFFFFF);
3317     }
3318 
3319     cpu->Reg[15] += cpu->GetInstructionSize();
3320     INC_PC(sizeof(smlalxy_inst));
3321     FETCH_INST;
3322     GOTO_NEXT_INST;
3323 }
3324 
3325 SMLAW_INST : {
3326     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3327         smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
3328 
3329         const u32 rm_val = RM;
3330         const u32 rn_val = RN;
3331         const u32 ra_val = cpu->Reg[inst_cream->Ra];
3332         const bool high = (inst_cream->m == 1);
3333 
3334         const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF);
3335         const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16);
3336 
3337         RD = BITS(result, 16, 47);
3338 
3339         if ((result >> 16) != (s32)RD)
3340             cpu->Cpsr |= (1 << 27);
3341     }
3342 
3343     cpu->Reg[15] += cpu->GetInstructionSize();
3344     INC_PC(sizeof(smlad_inst));
3345     FETCH_INST;
3346     GOTO_NEXT_INST;
3347 }
3348 
3349 SMLALD_INST:
3350 SMLSLD_INST : {
3351     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3352         smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
3353 
3354         const bool do_swap = (inst_cream->swap == 1);
3355         const u32 rdlo_val = RDLO;
3356         const u32 rdhi_val = RDHI;
3357         const u32 rn_val = RN;
3358         u32 rm_val = RM;
3359 
3360         if (do_swap)
3361             rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
3362 
3363         const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
3364         const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
3365         s64 result;
3366 
3367         // SMLALD
3368         if (BIT(inst_cream->op2, 1) == 0) {
3369             result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
3370         }
3371         // SMLSLD
3372         else {
3373             result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
3374         }
3375 
3376         RDLO = (result & 0xFFFFFFFF);
3377         RDHI = ((result >> 32) & 0xFFFFFFFF);
3378     }
3379 
3380     cpu->Reg[15] += cpu->GetInstructionSize();
3381     INC_PC(sizeof(smlald_inst));
3382     FETCH_INST;
3383     GOTO_NEXT_INST;
3384 }
3385 
3386 SMMLA_INST:
3387 SMMLS_INST:
3388 SMMUL_INST : {
3389     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3390         smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
3391 
3392         const u32 rm_val = RM;
3393         const u32 rn_val = RN;
3394         const bool do_round = (inst_cream->m == 1);
3395 
3396         // Assume SMMUL by default.
3397         s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
3398 
3399         if (inst_cream->Ra != 15) {
3400             const u32 ra_val = cpu->Reg[inst_cream->Ra];
3401 
3402             // SMMLA, otherwise SMMLS
3403             if (BIT(inst_cream->op2, 1) == 0)
3404                 result += ((s64)ra_val << 32);
3405             else
3406                 result = ((s64)ra_val << 32) - result;
3407         }
3408 
3409         if (do_round)
3410             result += 0x80000000;
3411 
3412         RD = ((result >> 32) & 0xFFFFFFFF);
3413     }
3414 
3415     cpu->Reg[15] += cpu->GetInstructionSize();
3416     INC_PC(sizeof(smlad_inst));
3417     FETCH_INST;
3418     GOTO_NEXT_INST;
3419 }
3420 
3421 SMUL_INST : {
3422     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3423         smul_inst* inst_cream = (smul_inst*)inst_base->component;
3424         u32 operand1, operand2;
3425         if (inst_cream->x == 0)
3426             operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
3427         else
3428             operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
3429 
3430         if (inst_cream->y == 0)
3431             operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
3432         else
3433             operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
3434         RD = operand1 * operand2;
3435     }
3436     cpu->Reg[15] += cpu->GetInstructionSize();
3437     INC_PC(sizeof(smul_inst));
3438     FETCH_INST;
3439     GOTO_NEXT_INST;
3440 }
3441 SMULL_INST : {
3442     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3443         umull_inst* inst_cream = (umull_inst*)inst_base->component;
3444         s64 rm = RM;
3445         s64 rs = RS;
3446         if (BIT(rm, 31)) {
3447             rm |= 0xffffffff00000000LL;
3448         }
3449         if (BIT(rs, 31)) {
3450             rs |= 0xffffffff00000000LL;
3451         }
3452         s64 rst = rm * rs;
3453         RDHI = BITS(rst, 32, 63);
3454         RDLO = BITS(rst, 0, 31);
3455 
3456         if (inst_cream->S) {
3457             cpu->NFlag = BIT(RDHI, 31);
3458             cpu->ZFlag = (RDHI == 0 && RDLO == 0);
3459         }
3460     }
3461     cpu->Reg[15] += cpu->GetInstructionSize();
3462     INC_PC(sizeof(umull_inst));
3463     FETCH_INST;
3464     GOTO_NEXT_INST;
3465 }
3466 
3467 SMULW_INST : {
3468     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3469         smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
3470 
3471         s16 rm = (inst_cream->m == 1) ? ((RM >> 16) & 0xFFFF) : (RM & 0xFFFF);
3472 
3473         s64 result = (s64)rm * (s64)(s32)RN;
3474         RD = BITS(result, 16, 47);
3475     }
3476     cpu->Reg[15] += cpu->GetInstructionSize();
3477     INC_PC(sizeof(smlad_inst));
3478     FETCH_INST;
3479     GOTO_NEXT_INST;
3480 }
3481 
3482 SRS_INST : {
3483     // SRS is unconditional
3484     ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
3485 
3486     u32 address = 0;
3487     inst_cream->get_addr(cpu, inst_cream->inst, address);
3488 
3489     cpu->WriteMemory32(address + 0, cpu->Reg[14]);
3490     cpu->WriteMemory32(address + 4, cpu->Spsr_copy);
3491 
3492     cpu->Reg[15] += cpu->GetInstructionSize();
3493     INC_PC(sizeof(ldst_inst));
3494     FETCH_INST;
3495     GOTO_NEXT_INST;
3496 }
3497 
3498 SSAT_INST : {
3499     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3500         ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
3501 
3502         u8 shift_type = inst_cream->shift_type;
3503         u8 shift_amount = inst_cream->imm5;
3504         u32 rn_val = RN;
3505 
3506         // 32-bit ASR is encoded as an amount of 0.
3507         if (shift_type == 1 && shift_amount == 0)
3508             shift_amount = 31;
3509 
3510         if (shift_type == 0)
3511             rn_val <<= shift_amount;
3512         else if (shift_type == 1)
3513             rn_val = ((s32)rn_val >> shift_amount);
3514 
3515         bool saturated = false;
3516         rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
3517 
3518         if (saturated)
3519             cpu->Cpsr |= (1 << 27);
3520 
3521         RD = rn_val;
3522     }
3523 
3524     cpu->Reg[15] += cpu->GetInstructionSize();
3525     INC_PC(sizeof(ssat_inst));
3526     FETCH_INST;
3527     GOTO_NEXT_INST;
3528 }
3529 
3530 SSAT16_INST : {
3531     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3532         ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
3533         const u8 saturate_to = inst_cream->sat_imm;
3534 
3535         bool sat1 = false;
3536         bool sat2 = false;
3537 
3538         RD = (ARMul_SignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) |
3539              ARMul_SignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16;
3540 
3541         if (sat1 || sat2)
3542             cpu->Cpsr |= (1 << 27);
3543     }
3544 
3545     cpu->Reg[15] += cpu->GetInstructionSize();
3546     INC_PC(sizeof(ssat_inst));
3547     FETCH_INST;
3548     GOTO_NEXT_INST;
3549 }
3550 
3551 STC_INST : {
3552     // Instruction not implemented
3553     // LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
3554     cpu->Reg[15] += cpu->GetInstructionSize();
3555     INC_PC(sizeof(stc_inst));
3556     FETCH_INST;
3557     GOTO_NEXT_INST;
3558 }
3559 STM_INST : {
3560     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3561         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
3562         unsigned int inst = inst_cream->inst;
3563 
3564         unsigned int Rn = BITS(inst, 16, 19);
3565         unsigned int old_RN = cpu->Reg[Rn];
3566 
3567         inst_cream->get_addr(cpu, inst_cream->inst, addr);
3568         if (BIT(inst_cream->inst, 22) == 1) {
3569             for (int i = 0; i < 13; i++) {
3570                 if (BIT(inst_cream->inst, i)) {
3571                     cpu->WriteMemory32(addr, cpu->Reg[i]);
3572                     addr += 4;
3573                 }
3574             }
3575             if (BIT(inst_cream->inst, 13)) {
3576                 if (cpu->Mode == USER32MODE)
3577                     cpu->WriteMemory32(addr, cpu->Reg[13]);
3578                 else
3579                     cpu->WriteMemory32(addr, cpu->Reg_usr[0]);
3580 
3581                 addr += 4;
3582             }
3583             if (BIT(inst_cream->inst, 14)) {
3584                 if (cpu->Mode == USER32MODE)
3585                     cpu->WriteMemory32(addr, cpu->Reg[14]);
3586                 else
3587                     cpu->WriteMemory32(addr, cpu->Reg_usr[1]);
3588 
3589                 addr += 4;
3590             }
3591             if (BIT(inst_cream->inst, 15)) {
3592                 cpu->WriteMemory32(addr, cpu->Reg[15] + 8);
3593             }
3594         } else {
3595             for (unsigned int i = 0; i < 15; i++) {
3596                 if (BIT(inst_cream->inst, i)) {
3597                     if (i == Rn)
3598                         cpu->WriteMemory32(addr, old_RN);
3599                     else
3600                         cpu->WriteMemory32(addr, cpu->Reg[i]);
3601 
3602                     addr += 4;
3603                 }
3604             }
3605 
3606             // Check PC reg
3607             if (BIT(inst_cream->inst, 15)) {
3608                 cpu->WriteMemory32(addr, cpu->Reg[15] + 8);
3609             }
3610         }
3611     }
3612     cpu->Reg[15] += cpu->GetInstructionSize();
3613     INC_PC(sizeof(ldst_inst));
3614     FETCH_INST;
3615     GOTO_NEXT_INST;
3616 }
3617 SXTB_INST : {
3618     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3619         sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component;
3620 
3621         unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
3622         if (BIT(operand2, 7)) {
3623             operand2 |= 0xffffff00;
3624         } else {
3625             operand2 &= 0xff;
3626         }
3627         RD = operand2;
3628     }
3629     cpu->Reg[15] += cpu->GetInstructionSize();
3630     INC_PC(sizeof(sxtb_inst));
3631     FETCH_INST;
3632     GOTO_NEXT_INST;
3633 }
3634 STR_INST : {
3635     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3636         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
3637         inst_cream->get_addr(cpu, inst_cream->inst, addr);
3638 
3639         unsigned int reg = BITS(inst_cream->inst, 12, 15);
3640         unsigned int value = cpu->Reg[reg];
3641 
3642         if (reg == 15)
3643             value += 2 * cpu->GetInstructionSize();
3644 
3645         cpu->WriteMemory32(addr, value);
3646     }
3647     cpu->Reg[15] += cpu->GetInstructionSize();
3648     INC_PC(sizeof(ldst_inst));
3649     FETCH_INST;
3650     GOTO_NEXT_INST;
3651 }
3652 UXTB_INST : {
3653     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3654         uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component;
3655         RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
3656     }
3657     cpu->Reg[15] += cpu->GetInstructionSize();
3658     INC_PC(sizeof(uxtb_inst));
3659     FETCH_INST;
3660     GOTO_NEXT_INST;
3661 }
3662 UXTAB_INST : {
3663     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3664         uxtab_inst* inst_cream = (uxtab_inst*)inst_base->component;
3665 
3666         unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
3667         RD = RN + operand2;
3668     }
3669     cpu->Reg[15] += cpu->GetInstructionSize();
3670     INC_PC(sizeof(uxtab_inst));
3671     FETCH_INST;
3672     GOTO_NEXT_INST;
3673 }
3674 STRB_INST : {
3675     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3676         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
3677         inst_cream->get_addr(cpu, inst_cream->inst, addr);
3678         unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
3679         cpu->WriteMemory8(addr, value);
3680     }
3681     cpu->Reg[15] += cpu->GetInstructionSize();
3682     INC_PC(sizeof(ldst_inst));
3683     FETCH_INST;
3684     GOTO_NEXT_INST;
3685 }
3686 STRBT_INST : {
3687     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3688         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
3689         inst_cream->get_addr(cpu, inst_cream->inst, addr);
3690 
3691         const u32 previous_mode = cpu->Mode;
3692         const u32 value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
3693 
3694         cpu->ChangePrivilegeMode(USER32MODE);
3695         cpu->WriteMemory8(addr, value);
3696         cpu->ChangePrivilegeMode(previous_mode);
3697     }
3698     cpu->Reg[15] += cpu->GetInstructionSize();
3699     INC_PC(sizeof(ldst_inst));
3700     FETCH_INST;
3701     GOTO_NEXT_INST;
3702 }
3703 STRD_INST : {
3704     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3705         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
3706         inst_cream->get_addr(cpu, inst_cream->inst, addr);
3707 
3708         // The 3DS doesn't have the Large Physical Access Extension (LPAE)
3709         // so STRD wouldn't store these as a single write.
3710         cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
3711         cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
3712     }
3713     cpu->Reg[15] += cpu->GetInstructionSize();
3714     INC_PC(sizeof(ldst_inst));
3715     FETCH_INST;
3716     GOTO_NEXT_INST;
3717 }
3718 STREX_INST : {
3719     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3720         generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
3721         unsigned int write_addr = cpu->Reg[inst_cream->Rn];
3722 
3723         if (cpu->IsExclusiveMemoryAccess(write_addr)) {
3724             cpu->UnsetExclusiveMemoryAddress();
3725             cpu->WriteMemory32(write_addr, RM);
3726             RD = 0;
3727         } else {
3728             // Failed to write due to mutex access
3729             RD = 1;
3730         }
3731     }
3732     cpu->Reg[15] += cpu->GetInstructionSize();
3733     INC_PC(sizeof(generic_arm_inst));
3734     FETCH_INST;
3735     GOTO_NEXT_INST;
3736 }
3737 STREXB_INST : {
3738     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3739         generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
3740         unsigned int write_addr = cpu->Reg[inst_cream->Rn];
3741 
3742         if (cpu->IsExclusiveMemoryAccess(write_addr)) {
3743             cpu->UnsetExclusiveMemoryAddress();
3744             cpu->WriteMemory8(write_addr, cpu->Reg[inst_cream->Rm]);
3745             RD = 0;
3746         } else {
3747             // Failed to write due to mutex access
3748             RD = 1;
3749         }
3750     }
3751     cpu->Reg[15] += cpu->GetInstructionSize();
3752     INC_PC(sizeof(generic_arm_inst));
3753     FETCH_INST;
3754     GOTO_NEXT_INST;
3755 }
3756 STREXD_INST : {
3757     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3758         generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
3759         unsigned int write_addr = cpu->Reg[inst_cream->Rn];
3760 
3761         if (cpu->IsExclusiveMemoryAccess(write_addr)) {
3762             cpu->UnsetExclusiveMemoryAddress();
3763 
3764             const u32 rt = cpu->Reg[inst_cream->Rm + 0];
3765             const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
3766             u64 value;
3767 
3768             if (cpu->InBigEndianMode())
3769                 value = (((u64)rt << 32) | rt2);
3770             else
3771                 value = (((u64)rt2 << 32) | rt);
3772 
3773             cpu->WriteMemory64(write_addr, value);
3774             RD = 0;
3775         } else {
3776             // Failed to write due to mutex access
3777             RD = 1;
3778         }
3779     }
3780     cpu->Reg[15] += cpu->GetInstructionSize();
3781     INC_PC(sizeof(generic_arm_inst));
3782     FETCH_INST;
3783     GOTO_NEXT_INST;
3784 }
3785 STREXH_INST : {
3786     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3787         generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
3788         unsigned int write_addr = cpu->Reg[inst_cream->Rn];
3789 
3790         if (cpu->IsExclusiveMemoryAccess(write_addr)) {
3791             cpu->UnsetExclusiveMemoryAddress();
3792             cpu->WriteMemory16(write_addr, RM);
3793             RD = 0;
3794         } else {
3795             // Failed to write due to mutex access
3796             RD = 1;
3797         }
3798     }
3799     cpu->Reg[15] += cpu->GetInstructionSize();
3800     INC_PC(sizeof(generic_arm_inst));
3801     FETCH_INST;
3802     GOTO_NEXT_INST;
3803 }
3804 STRH_INST : {
3805     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3806         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
3807         inst_cream->get_addr(cpu, inst_cream->inst, addr);
3808 
3809         unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
3810         cpu->WriteMemory16(addr, value);
3811     }
3812     cpu->Reg[15] += cpu->GetInstructionSize();
3813     INC_PC(sizeof(ldst_inst));
3814     FETCH_INST;
3815     GOTO_NEXT_INST;
3816 }
3817 STRT_INST : {
3818     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3819         ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
3820         inst_cream->get_addr(cpu, inst_cream->inst, addr);
3821 
3822         const u32 previous_mode = cpu->Mode;
3823         const u32 rt_index = BITS(inst_cream->inst, 12, 15);
3824 
3825         u32 value = cpu->Reg[rt_index];
3826         if (rt_index == 15)
3827             value += 2 * cpu->GetInstructionSize();
3828 
3829         cpu->ChangePrivilegeMode(USER32MODE);
3830         cpu->WriteMemory32(addr, value);
3831         cpu->ChangePrivilegeMode(previous_mode);
3832     }
3833     cpu->Reg[15] += cpu->GetInstructionSize();
3834     INC_PC(sizeof(ldst_inst));
3835     FETCH_INST;
3836     GOTO_NEXT_INST;
3837 }
3838 SUB_INST : {
3839     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3840         sub_inst* const inst_cream = (sub_inst*)inst_base->component;
3841 
3842         u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn);
3843 
3844         bool carry;
3845         bool overflow;
3846         RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
3847 
3848         if (inst_cream->S && (inst_cream->Rd == 15)) {
3849             if (cpu->CurrentModeHasSPSR()) {
3850                 cpu->Cpsr = cpu->Spsr_copy;
3851                 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
3852                 LOAD_NZCVT;
3853             }
3854         } else if (inst_cream->S) {
3855             UPDATE_NFLAG(RD);
3856             UPDATE_ZFLAG(RD);
3857             cpu->CFlag = carry;
3858             cpu->VFlag = overflow;
3859         }
3860         if (inst_cream->Rd == 15) {
3861             INC_PC(sizeof(sub_inst));
3862             goto DISPATCH;
3863         }
3864     }
3865     cpu->Reg[15] += cpu->GetInstructionSize();
3866     INC_PC(sizeof(sub_inst));
3867     FETCH_INST;
3868     GOTO_NEXT_INST;
3869 }
3870 SWI_INST : {
3871     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3872         DEBUG_ASSERT(cpu->system != nullptr);
3873         swi_inst* const inst_cream = (swi_inst*)inst_base->component;
3874         cpu->system->GetRunningCore().GetTimer().AddTicks(num_instrs);
3875         cpu->NumInstrsToExecute =
3876             num_instrs >= cpu->NumInstrsToExecute ? 0 : cpu->NumInstrsToExecute - num_instrs;
3877         num_instrs = 0;
3878         Kernel::SVCContext{*cpu->system}.CallSVC(inst_cream->num & 0xFFFF);
3879         // The kernel would call ERET to get here, which clears exclusive memory state.
3880         cpu->UnsetExclusiveMemoryAddress();
3881     }
3882 
3883     cpu->Reg[15] += cpu->GetInstructionSize();
3884     INC_PC(sizeof(swi_inst));
3885     FETCH_INST;
3886     GOTO_NEXT_INST;
3887 }
3888 SWP_INST : {
3889     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3890         swp_inst* inst_cream = (swp_inst*)inst_base->component;
3891 
3892         addr = RN;
3893         unsigned int value = cpu->ReadMemory32(addr);
3894         cpu->WriteMemory32(addr, RM);
3895 
3896         RD = value;
3897     }
3898     cpu->Reg[15] += cpu->GetInstructionSize();
3899     INC_PC(sizeof(swp_inst));
3900     FETCH_INST;
3901     GOTO_NEXT_INST;
3902 }
3903 SWPB_INST : {
3904     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3905         swp_inst* inst_cream = (swp_inst*)inst_base->component;
3906         addr = RN;
3907         unsigned int value = cpu->ReadMemory8(addr);
3908         cpu->WriteMemory8(addr, (RM & 0xFF));
3909         RD = value;
3910     }
3911     cpu->Reg[15] += cpu->GetInstructionSize();
3912     INC_PC(sizeof(swp_inst));
3913     FETCH_INST;
3914     GOTO_NEXT_INST;
3915 }
3916 SXTAB_INST : {
3917     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3918         sxtab_inst* inst_cream = (sxtab_inst*)inst_base->component;
3919 
3920         unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
3921 
3922         // Sign extend for byte
3923         operand2 = (0x80 & operand2) ? (0xFFFFFF00 | operand2) : operand2;
3924         RD = RN + operand2;
3925     }
3926     cpu->Reg[15] += cpu->GetInstructionSize();
3927     INC_PC(sizeof(uxtab_inst));
3928     FETCH_INST;
3929     GOTO_NEXT_INST;
3930 }
3931 
3932 SXTAB16_INST:
3933 SXTB16_INST : {
3934     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3935         sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
3936 
3937         const u8 rotation = inst_cream->rotate * 8;
3938         u32 rm_val = RM;
3939         u32 rn_val = RN;
3940 
3941         if (rotation)
3942             rm_val = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
3943 
3944         // SXTB16
3945         if (inst_cream->Rn == 15) {
3946             u32 lo = (u32)(s8)rm_val;
3947             u32 hi = (u32)(s8)(rm_val >> 16);
3948             RD = (lo & 0xFFFF) | (hi << 16);
3949         }
3950         // SXTAB16
3951         else {
3952             u32 lo = rn_val + (u32)(s8)(rm_val & 0xFF);
3953             u32 hi = (rn_val >> 16) + (u32)(s8)((rm_val >> 16) & 0xFF);
3954             RD = (lo & 0xFFFF) | (hi << 16);
3955         }
3956     }
3957 
3958     cpu->Reg[15] += cpu->GetInstructionSize();
3959     INC_PC(sizeof(sxtab_inst));
3960     FETCH_INST;
3961     GOTO_NEXT_INST;
3962 }
3963 
3964 SXTAH_INST : {
3965     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3966         sxtah_inst* inst_cream = (sxtah_inst*)inst_base->component;
3967 
3968         unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
3969         // Sign extend for half
3970         operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2;
3971         RD = RN + operand2;
3972     }
3973     cpu->Reg[15] += cpu->GetInstructionSize();
3974     INC_PC(sizeof(sxtah_inst));
3975     FETCH_INST;
3976     GOTO_NEXT_INST;
3977 }
3978 
3979 TEQ_INST : {
3980     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
3981         teq_inst* const inst_cream = (teq_inst*)inst_base->component;
3982 
3983         u32 lop = RN;
3984         u32 rop = SHIFTER_OPERAND;
3985 
3986         if (inst_cream->Rn == 15)
3987             lop += cpu->GetInstructionSize() * 2;
3988 
3989         u32 result = lop ^ rop;
3990 
3991         UPDATE_NFLAG(result);
3992         UPDATE_ZFLAG(result);
3993         UPDATE_CFLAG_WITH_SC;
3994     }
3995     cpu->Reg[15] += cpu->GetInstructionSize();
3996     INC_PC(sizeof(teq_inst));
3997     FETCH_INST;
3998     GOTO_NEXT_INST;
3999 }
4000 TST_INST : {
4001     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4002         tst_inst* const inst_cream = (tst_inst*)inst_base->component;
4003 
4004         u32 lop = RN;
4005         u32 rop = SHIFTER_OPERAND;
4006 
4007         if (inst_cream->Rn == 15)
4008             lop += cpu->GetInstructionSize() * 2;
4009 
4010         u32 result = lop & rop;
4011 
4012         UPDATE_NFLAG(result);
4013         UPDATE_ZFLAG(result);
4014         UPDATE_CFLAG_WITH_SC;
4015     }
4016     cpu->Reg[15] += cpu->GetInstructionSize();
4017     INC_PC(sizeof(tst_inst));
4018     FETCH_INST;
4019     GOTO_NEXT_INST;
4020 }
4021 
4022 UADD8_INST:
4023 UADD16_INST:
4024 UADDSUBX_INST:
4025 USUB8_INST:
4026 USUB16_INST:
4027 USUBADDX_INST : {
4028     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4029         generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
4030 
4031         const u8 op2 = inst_cream->op2;
4032         const u32 rm_val = RM;
4033         const u32 rn_val = RN;
4034 
4035         s32 lo_result = 0;
4036         s32 hi_result = 0;
4037 
4038         // UADD16
4039         if (op2 == 0x00) {
4040             lo_result = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
4041             hi_result = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
4042 
4043             if (lo_result & 0xFFFF0000) {
4044                 cpu->Cpsr |= (1 << 16);
4045                 cpu->Cpsr |= (1 << 17);
4046             } else {
4047                 cpu->Cpsr &= ~(1 << 16);
4048                 cpu->Cpsr &= ~(1 << 17);
4049             }
4050 
4051             if (hi_result & 0xFFFF0000) {
4052                 cpu->Cpsr |= (1 << 18);
4053                 cpu->Cpsr |= (1 << 19);
4054             } else {
4055                 cpu->Cpsr &= ~(1 << 18);
4056                 cpu->Cpsr &= ~(1 << 19);
4057             }
4058         }
4059         // UASX
4060         else if (op2 == 0x01) {
4061             lo_result = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
4062             hi_result = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
4063 
4064             if (lo_result >= 0) {
4065                 cpu->Cpsr |= (1 << 16);
4066                 cpu->Cpsr |= (1 << 17);
4067             } else {
4068                 cpu->Cpsr &= ~(1 << 16);
4069                 cpu->Cpsr &= ~(1 << 17);
4070             }
4071 
4072             if (hi_result >= 0x10000) {
4073                 cpu->Cpsr |= (1 << 18);
4074                 cpu->Cpsr |= (1 << 19);
4075             } else {
4076                 cpu->Cpsr &= ~(1 << 18);
4077                 cpu->Cpsr &= ~(1 << 19);
4078             }
4079         }
4080         // USAX
4081         else if (op2 == 0x02) {
4082             lo_result = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
4083             hi_result = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
4084 
4085             if (lo_result >= 0x10000) {
4086                 cpu->Cpsr |= (1 << 16);
4087                 cpu->Cpsr |= (1 << 17);
4088             } else {
4089                 cpu->Cpsr &= ~(1 << 16);
4090                 cpu->Cpsr &= ~(1 << 17);
4091             }
4092 
4093             if (hi_result >= 0) {
4094                 cpu->Cpsr |= (1 << 18);
4095                 cpu->Cpsr |= (1 << 19);
4096             } else {
4097                 cpu->Cpsr &= ~(1 << 18);
4098                 cpu->Cpsr &= ~(1 << 19);
4099             }
4100         }
4101         // USUB16
4102         else if (op2 == 0x03) {
4103             lo_result = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
4104             hi_result = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
4105 
4106             if ((lo_result & 0xFFFF0000) == 0) {
4107                 cpu->Cpsr |= (1 << 16);
4108                 cpu->Cpsr |= (1 << 17);
4109             } else {
4110                 cpu->Cpsr &= ~(1 << 16);
4111                 cpu->Cpsr &= ~(1 << 17);
4112             }
4113 
4114             if ((hi_result & 0xFFFF0000) == 0) {
4115                 cpu->Cpsr |= (1 << 18);
4116                 cpu->Cpsr |= (1 << 19);
4117             } else {
4118                 cpu->Cpsr &= ~(1 << 18);
4119                 cpu->Cpsr &= ~(1 << 19);
4120             }
4121         }
4122         // UADD8
4123         else if (op2 == 0x04) {
4124             s16 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
4125             s16 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
4126             s16 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
4127             s16 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
4128 
4129             if (sum1 >= 0x100)
4130                 cpu->Cpsr |= (1 << 16);
4131             else
4132                 cpu->Cpsr &= ~(1 << 16);
4133 
4134             if (sum2 >= 0x100)
4135                 cpu->Cpsr |= (1 << 17);
4136             else
4137                 cpu->Cpsr &= ~(1 << 17);
4138 
4139             if (sum3 >= 0x100)
4140                 cpu->Cpsr |= (1 << 18);
4141             else
4142                 cpu->Cpsr &= ~(1 << 18);
4143 
4144             if (sum4 >= 0x100)
4145                 cpu->Cpsr |= (1 << 19);
4146             else
4147                 cpu->Cpsr &= ~(1 << 19);
4148 
4149             lo_result = ((sum1 & 0xFF) | (sum2 & 0xFF) << 8);
4150             hi_result = ((sum3 & 0xFF) | (sum4 & 0xFF) << 8);
4151         }
4152         // USUB8
4153         else if (op2 == 0x07) {
4154             s16 diff1 = (rn_val & 0xFF) - (rm_val & 0xFF);
4155             s16 diff2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
4156             s16 diff3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
4157             s16 diff4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
4158 
4159             if (diff1 >= 0)
4160                 cpu->Cpsr |= (1 << 16);
4161             else
4162                 cpu->Cpsr &= ~(1 << 16);
4163 
4164             if (diff2 >= 0)
4165                 cpu->Cpsr |= (1 << 17);
4166             else
4167                 cpu->Cpsr &= ~(1 << 17);
4168 
4169             if (diff3 >= 0)
4170                 cpu->Cpsr |= (1 << 18);
4171             else
4172                 cpu->Cpsr &= ~(1 << 18);
4173 
4174             if (diff4 >= 0)
4175                 cpu->Cpsr |= (1 << 19);
4176             else
4177                 cpu->Cpsr &= ~(1 << 19);
4178 
4179             lo_result = (diff1 & 0xFF) | ((diff2 & 0xFF) << 8);
4180             hi_result = (diff3 & 0xFF) | ((diff4 & 0xFF) << 8);
4181         }
4182 
4183         RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
4184     }
4185 
4186     cpu->Reg[15] += cpu->GetInstructionSize();
4187     INC_PC(sizeof(generic_arm_inst));
4188     FETCH_INST;
4189     GOTO_NEXT_INST;
4190 }
4191 
4192 UHADD8_INST:
4193 UHADD16_INST:
4194 UHADDSUBX_INST:
4195 UHSUBADDX_INST:
4196 UHSUB8_INST:
4197 UHSUB16_INST : {
4198     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4199         generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
4200         const u32 rm_val = RM;
4201         const u32 rn_val = RN;
4202         const u8 op2 = inst_cream->op2;
4203 
4204         if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
4205             u32 lo_val = 0;
4206             u32 hi_val = 0;
4207 
4208             // UHADD16
4209             if (op2 == 0x00) {
4210                 lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
4211                 hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
4212             }
4213             // UHASX
4214             else if (op2 == 0x01) {
4215                 lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
4216                 hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
4217             }
4218             // UHSAX
4219             else if (op2 == 0x02) {
4220                 lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
4221                 hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
4222             }
4223             // UHSUB16
4224             else if (op2 == 0x03) {
4225                 lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
4226                 hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
4227             }
4228 
4229             lo_val >>= 1;
4230             hi_val >>= 1;
4231 
4232             RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
4233         } else if (op2 == 0x04 || op2 == 0x07) {
4234             u32 sum1;
4235             u32 sum2;
4236             u32 sum3;
4237             u32 sum4;
4238 
4239             // UHADD8
4240             if (op2 == 0x04) {
4241                 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
4242                 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
4243                 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
4244                 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
4245             }
4246             // UHSUB8
4247             else {
4248                 sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
4249                 sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
4250                 sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
4251                 sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
4252             }
4253 
4254             sum1 >>= 1;
4255             sum2 >>= 1;
4256             sum3 >>= 1;
4257             sum4 >>= 1;
4258 
4259             RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) |
4260                  ((sum4 & 0xFF) << 24);
4261         }
4262     }
4263 
4264     cpu->Reg[15] += cpu->GetInstructionSize();
4265     INC_PC(sizeof(generic_arm_inst));
4266     FETCH_INST;
4267     GOTO_NEXT_INST;
4268 }
4269 
4270 UMAAL_INST : {
4271     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4272         umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
4273         const u64 rm = RM;
4274         const u64 rn = RN;
4275         const u64 rd_lo = RDLO;
4276         const u64 rd_hi = RDHI;
4277         const u64 result = (rm * rn) + rd_lo + rd_hi;
4278 
4279         RDLO = (result & 0xFFFFFFFF);
4280         RDHI = ((result >> 32) & 0xFFFFFFFF);
4281     }
4282     cpu->Reg[15] += cpu->GetInstructionSize();
4283     INC_PC(sizeof(umaal_inst));
4284     FETCH_INST;
4285     GOTO_NEXT_INST;
4286 }
4287 UMLAL_INST : {
4288     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4289         umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
4290         unsigned long long int rm = RM;
4291         unsigned long long int rs = RS;
4292         unsigned long long int rst = rm * rs;
4293         unsigned long long int add = ((unsigned long long)RDHI) << 32;
4294         add += RDLO;
4295         rst += add;
4296         RDLO = BITS(rst, 0, 31);
4297         RDHI = BITS(rst, 32, 63);
4298 
4299         if (inst_cream->S) {
4300             cpu->NFlag = BIT(RDHI, 31);
4301             cpu->ZFlag = (RDHI == 0 && RDLO == 0);
4302         }
4303     }
4304     cpu->Reg[15] += cpu->GetInstructionSize();
4305     INC_PC(sizeof(umlal_inst));
4306     FETCH_INST;
4307     GOTO_NEXT_INST;
4308 }
4309 UMULL_INST : {
4310     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4311         umull_inst* inst_cream = (umull_inst*)inst_base->component;
4312         unsigned long long int rm = RM;
4313         unsigned long long int rs = RS;
4314         unsigned long long int rst = rm * rs;
4315         RDHI = BITS(rst, 32, 63);
4316         RDLO = BITS(rst, 0, 31);
4317 
4318         if (inst_cream->S) {
4319             cpu->NFlag = BIT(RDHI, 31);
4320             cpu->ZFlag = (RDHI == 0 && RDLO == 0);
4321         }
4322     }
4323     cpu->Reg[15] += cpu->GetInstructionSize();
4324     INC_PC(sizeof(umull_inst));
4325     FETCH_INST;
4326     GOTO_NEXT_INST;
4327 }
4328 B_2_THUMB : {
4329     b_2_thumb* inst_cream = (b_2_thumb*)inst_base->component;
4330     cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
4331     INC_PC(sizeof(b_2_thumb));
4332     goto DISPATCH;
4333 }
4334 B_COND_THUMB : {
4335     b_cond_thumb* inst_cream = (b_cond_thumb*)inst_base->component;
4336 
4337     if (CondPassed(cpu, inst_cream->cond))
4338         cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
4339     else
4340         cpu->Reg[15] += 2;
4341 
4342     INC_PC(sizeof(b_cond_thumb));
4343     goto DISPATCH;
4344 }
4345 BL_1_THUMB : {
4346     bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component;
4347     cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
4348     cpu->Reg[15] += cpu->GetInstructionSize();
4349     INC_PC(sizeof(bl_1_thumb));
4350     FETCH_INST;
4351     GOTO_NEXT_INST;
4352 }
4353 BL_2_THUMB : {
4354     bl_2_thumb* inst_cream = (bl_2_thumb*)inst_base->component;
4355     int tmp = ((cpu->Reg[15] + 2) | 1);
4356     cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm);
4357     cpu->Reg[14] = tmp;
4358     INC_PC(sizeof(bl_2_thumb));
4359     goto DISPATCH;
4360 }
4361 BLX_1_THUMB : {
4362     // BLX 1 for armv5t and above
4363     u32 tmp = cpu->Reg[15];
4364     blx_1_thumb* inst_cream = (blx_1_thumb*)inst_base->component;
4365     cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
4366     cpu->Reg[14] = ((tmp + 2) | 1);
4367     cpu->TFlag = 0;
4368     INC_PC(sizeof(blx_1_thumb));
4369     goto DISPATCH;
4370 }
4371 
4372 UQADD8_INST:
4373 UQADD16_INST:
4374 UQADDSUBX_INST:
4375 UQSUB8_INST:
4376 UQSUB16_INST:
4377 UQSUBADDX_INST : {
4378     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4379         generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
4380 
4381         const u8 op2 = inst_cream->op2;
4382         const u32 rm_val = RM;
4383         const u32 rn_val = RN;
4384 
4385         u16 lo_val = 0;
4386         u16 hi_val = 0;
4387 
4388         // UQADD16
4389         if (op2 == 0x00) {
4390             lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
4391             hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
4392         }
4393         // UQASX
4394         else if (op2 == 0x01) {
4395             lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
4396             hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
4397         }
4398         // UQSAX
4399         else if (op2 == 0x02) {
4400             lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
4401             hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
4402         }
4403         // UQSUB16
4404         else if (op2 == 0x03) {
4405             lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
4406             hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
4407         }
4408         // UQADD8
4409         else if (op2 == 0x04) {
4410             lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
4411                      ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
4412             hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
4413                      ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
4414         }
4415         // UQSUB8
4416         else {
4417             lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
4418                      ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
4419             hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
4420                      ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
4421         }
4422 
4423         RD = ((lo_val & 0xFFFF) | hi_val << 16);
4424     }
4425 
4426     cpu->Reg[15] += cpu->GetInstructionSize();
4427     INC_PC(sizeof(generic_arm_inst));
4428     FETCH_INST;
4429     GOTO_NEXT_INST;
4430 }
4431 
4432 USAD8_INST:
4433 USADA8_INST : {
4434     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4435         generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
4436 
4437         const u8 ra_idx = inst_cream->Ra;
4438         const u32 rm_val = RM;
4439         const u32 rn_val = RN;
4440 
4441         const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
4442         const u8 diff2 =
4443             ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
4444         const u8 diff3 =
4445             ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
4446         const u8 diff4 =
4447             ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
4448 
4449         u32 finalDif = (diff1 + diff2 + diff3 + diff4);
4450 
4451         // Op is USADA8 if true.
4452         if (ra_idx != 15)
4453             finalDif += cpu->Reg[ra_idx];
4454 
4455         RD = finalDif;
4456     }
4457 
4458     cpu->Reg[15] += cpu->GetInstructionSize();
4459     INC_PC(sizeof(generic_arm_inst));
4460     FETCH_INST;
4461     GOTO_NEXT_INST;
4462 }
4463 
4464 USAT_INST : {
4465     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4466         ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
4467 
4468         u8 shift_type = inst_cream->shift_type;
4469         u8 shift_amount = inst_cream->imm5;
4470         u32 rn_val = RN;
4471 
4472         // 32-bit ASR is encoded as an amount of 0.
4473         if (shift_type == 1 && shift_amount == 0)
4474             shift_amount = 31;
4475 
4476         if (shift_type == 0)
4477             rn_val <<= shift_amount;
4478         else if (shift_type == 1)
4479             rn_val = ((s32)rn_val >> shift_amount);
4480 
4481         bool saturated = false;
4482         rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
4483 
4484         if (saturated)
4485             cpu->Cpsr |= (1 << 27);
4486 
4487         RD = rn_val;
4488     }
4489 
4490     cpu->Reg[15] += cpu->GetInstructionSize();
4491     INC_PC(sizeof(ssat_inst));
4492     FETCH_INST;
4493     GOTO_NEXT_INST;
4494 }
4495 
4496 USAT16_INST : {
4497     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4498         ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
4499         const u8 saturate_to = inst_cream->sat_imm;
4500 
4501         bool sat1 = false;
4502         bool sat2 = false;
4503 
4504         RD = (ARMul_UnsignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) |
4505              ARMul_UnsignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16;
4506 
4507         if (sat1 || sat2)
4508             cpu->Cpsr |= (1 << 27);
4509     }
4510 
4511     cpu->Reg[15] += cpu->GetInstructionSize();
4512     INC_PC(sizeof(ssat_inst));
4513     FETCH_INST;
4514     GOTO_NEXT_INST;
4515 }
4516 
4517 UXTAB16_INST:
4518 UXTB16_INST : {
4519     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4520         uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
4521 
4522         const u8 rn_idx = inst_cream->Rn;
4523         const u32 rm_val = RM;
4524         const u32 rotation = inst_cream->rotate * 8;
4525         const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
4526 
4527         // UXTB16, otherwise UXTAB16
4528         if (rn_idx == 15) {
4529             RD = rotated_rm & 0x00FF00FF;
4530         } else {
4531             const u32 rn_val = RN;
4532             const u8 lo_rotated = (rotated_rm & 0xFF);
4533             const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
4534             const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
4535             const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
4536 
4537             RD = ((hi_result << 16) | (lo_result & 0xFFFF));
4538         }
4539     }
4540 
4541     cpu->Reg[15] += cpu->GetInstructionSize();
4542     INC_PC(sizeof(uxtab_inst));
4543     FETCH_INST;
4544     GOTO_NEXT_INST;
4545 }
4546 
4547 WFE_INST : {
4548     // Stubbed, as WFE is a hint instruction.
4549     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4550         LOG_TRACE(Core_ARM11, "WFE executed.");
4551     }
4552 
4553     cpu->Reg[15] += cpu->GetInstructionSize();
4554     INC_PC_STUB;
4555     FETCH_INST;
4556     GOTO_NEXT_INST;
4557 }
4558 
4559 WFI_INST : {
4560     // Stubbed, as WFI is a hint instruction.
4561     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4562         LOG_TRACE(Core_ARM11, "WFI executed.");
4563     }
4564 
4565     cpu->Reg[15] += cpu->GetInstructionSize();
4566     INC_PC_STUB;
4567     FETCH_INST;
4568     GOTO_NEXT_INST;
4569 }
4570 
4571 YIELD_INST : {
4572     // Stubbed, as YIELD is a hint instruction.
4573     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
4574         LOG_TRACE(Core_ARM11, "YIELD executed.");
4575     }
4576 
4577     cpu->Reg[15] += cpu->GetInstructionSize();
4578     INC_PC_STUB;
4579     FETCH_INST;
4580     GOTO_NEXT_INST;
4581 }
4582 
4583 #define VFP_INTERPRETER_IMPL
4584 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
4585 #undef VFP_INTERPRETER_IMPL
4586 
4587 END : {
4588     SAVE_NZCVT;
4589     cpu->NumInstrsToExecute = 0;
4590     return num_instrs;
4591 }
4592 INIT_INST_LENGTH : {
4593     cpu->NumInstrsToExecute = 0;
4594     return num_instrs;
4595 }
4596 }
4597