27#include "llvm/ADT/STLExtras.h"
28#include "llvm/Support/MathExtras.h"
36#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
37#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
39#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
103 reg_info.
name =
"r8";
106 reg_info.
name =
"r9";
109 reg_info.
name =
"r10";
112 reg_info.
name =
"r11";
115 reg_info.
name =
"r12";
118 reg_info.
name =
"sp";
123 reg_info.
name =
"lr";
128 reg_info.
name =
"pc";
133 reg_info.
name =
"cpsr";
138 reg_info.
name =
"s0";
141 reg_info.
name =
"s1";
144 reg_info.
name =
"s2";
147 reg_info.
name =
"s3";
150 reg_info.
name =
"s4";
153 reg_info.
name =
"s5";
156 reg_info.
name =
"s6";
159 reg_info.
name =
"s7";
162 reg_info.
name =
"s8";
165 reg_info.
name =
"s9";
168 reg_info.
name =
"s10";
171 reg_info.
name =
"s11";
174 reg_info.
name =
"s12";
177 reg_info.
name =
"s13";
180 reg_info.
name =
"s14";
183 reg_info.
name =
"s15";
186 reg_info.
name =
"s16";
189 reg_info.
name =
"s17";
192 reg_info.
name =
"s18";
195 reg_info.
name =
"s19";
198 reg_info.
name =
"s20";
201 reg_info.
name =
"s21";
204 reg_info.
name =
"s22";
207 reg_info.
name =
"s23";
210 reg_info.
name =
"s24";
213 reg_info.
name =
"s25";
216 reg_info.
name =
"s26";
219 reg_info.
name =
"s27";
222 reg_info.
name =
"s28";
225 reg_info.
name =
"s29";
228 reg_info.
name =
"s30";
231 reg_info.
name =
"s31";
236 reg_info.
name =
"f0";
239 reg_info.
name =
"f1";
242 reg_info.
name =
"f2";
245 reg_info.
name =
"f3";
248 reg_info.
name =
"f4";
251 reg_info.
name =
"f5";
254 reg_info.
name =
"f6";
257 reg_info.
name =
"f7";
263 reg_info.
name =
"wCGR0/ACC0";
266 reg_info.
name =
"wCGR1/ACC1";
269 reg_info.
name =
"wCGR2/ACC2";
272 reg_info.
name =
"wCGR3/ACC3";
275 reg_info.
name =
"wCGR4/ACC4";
278 reg_info.
name =
"wCGR5/ACC5";
281 reg_info.
name =
"wCGR6/ACC6";
284 reg_info.
name =
"wCGR7/ACC7";
289 reg_info.
name =
"wR0";
292 reg_info.
name =
"wR1";
295 reg_info.
name =
"wR2";
298 reg_info.
name =
"wR3";
301 reg_info.
name =
"wR4";
304 reg_info.
name =
"wR5";
307 reg_info.
name =
"wR6";
310 reg_info.
name =
"wR7";
313 reg_info.
name =
"wR8";
316 reg_info.
name =
"wR9";
319 reg_info.
name =
"wR10";
322 reg_info.
name =
"wR11";
325 reg_info.
name =
"wR12";
328 reg_info.
name =
"wR13";
331 reg_info.
name =
"wR14";
334 reg_info.
name =
"wR15";
338 reg_info.
name =
"spsr";
341 reg_info.
name =
"spsr_fiq";
344 reg_info.
name =
"spsr_irq";
347 reg_info.
name =
"spsr_abt";
350 reg_info.
name =
"spsr_und";
353 reg_info.
name =
"spsr_svc";
357 reg_info.
name =
"r8_usr";
360 reg_info.
name =
"r9_usr";
363 reg_info.
name =
"r10_usr";
366 reg_info.
name =
"r11_usr";
369 reg_info.
name =
"r12_usr";
372 reg_info.
name =
"r13_usr";
375 reg_info.
name =
"r14_usr";
378 reg_info.
name =
"r8_fiq";
381 reg_info.
name =
"r9_fiq";
384 reg_info.
name =
"r10_fiq";
387 reg_info.
name =
"r11_fiq";
390 reg_info.
name =
"r12_fiq";
393 reg_info.
name =
"r13_fiq";
396 reg_info.
name =
"r14_fiq";
399 reg_info.
name =
"r13_irq";
402 reg_info.
name =
"r14_irq";
405 reg_info.
name =
"r13_abt";
408 reg_info.
name =
"r14_abt";
411 reg_info.
name =
"r13_und";
414 reg_info.
name =
"r14_und";
417 reg_info.
name =
"r13_svc";
420 reg_info.
name =
"r14_svc";
425 reg_info.
name =
"wC0";
428 reg_info.
name =
"wC1";
431 reg_info.
name =
"wC2";
434 reg_info.
name =
"wC3";
437 reg_info.
name =
"wC4";
440 reg_info.
name =
"wC5";
443 reg_info.
name =
"wC6";
446 reg_info.
name =
"wC7";
451 reg_info.
name =
"d0";
454 reg_info.
name =
"d1";
457 reg_info.
name =
"d2";
460 reg_info.
name =
"d3";
463 reg_info.
name =
"d4";
466 reg_info.
name =
"d5";
469 reg_info.
name =
"d6";
472 reg_info.
name =
"d7";
475 reg_info.
name =
"d8";
478 reg_info.
name =
"d9";
481 reg_info.
name =
"d10";
484 reg_info.
name =
"d11";
487 reg_info.
name =
"d12";
490 reg_info.
name =
"d13";
493 reg_info.
name =
"d14";
496 reg_info.
name =
"d15";
499 reg_info.
name =
"d16";
502 reg_info.
name =
"d17";
505 reg_info.
name =
"d18";
508 reg_info.
name =
"d19";
511 reg_info.
name =
"d20";
514 reg_info.
name =
"d21";
517 reg_info.
name =
"d22";
520 reg_info.
name =
"d23";
523 reg_info.
name =
"d24";
526 reg_info.
name =
"d25";
529 reg_info.
name =
"d26";
532 reg_info.
name =
"d27";
535 reg_info.
name =
"d28";
538 reg_info.
name =
"d29";
541 reg_info.
name =
"d30";
544 reg_info.
name =
"d31";
549 reg_info.
name =
"q0";
552 reg_info.
name =
"q1";
555 reg_info.
name =
"q2";
558 reg_info.
name =
"q3";
561 reg_info.
name =
"q4";
564 reg_info.
name =
"q5";
567 reg_info.
name =
"q6";
570 reg_info.
name =
"q7";
573 reg_info.
name =
"q8";
576 reg_info.
name =
"q9";
579 reg_info.
name =
"q10";
582 reg_info.
name =
"q11";
585 reg_info.
name =
"q12";
588 reg_info.
name =
"q13";
591 reg_info.
name =
"q14";
594 reg_info.
name =
"q15";
607 uint32_t TZ = llvm::countr_zero(ITMask);
621 unsigned short FirstCond =
Bits32(bits7_0, 7, 4);
622 if (FirstCond == 0xF) {
625 if (FirstCond == 0xE &&
ITCounter != 1) {
665#define PC_REGLIST_BIT 0x8000
667#define ARMv4 (1u << 0)
668#define ARMv4T (1u << 1)
669#define ARMv5T (1u << 2)
670#define ARMv5TE (1u << 3)
671#define ARMv5TEJ (1u << 4)
672#define ARMv6 (1u << 5)
673#define ARMv6K (1u << 6)
674#define ARMv6T2 (1u << 7)
675#define ARMv7 (1u << 8)
676#define ARMv7S (1u << 9)
677#define ARMv8 (1u << 10)
678#define ARMvAll (0xffffffffu)
680#define ARMV4T_ABOVE \
681 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \
684 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \
686#define ARMV5TE_ABOVE \
687 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
688#define ARMV5J_ABOVE \
689 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
690#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
691#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
692#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
695#define VFPv1 (1u << 1)
696#define VFPv2 (1u << 2)
697#define VFPv3 (1u << 3)
698#define AdvancedSIMD (1u << 4)
700#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
701#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
702#define VFPv2v3 (VFPv2 | VFPv3)
718 return "Emulate instructions for the ARM architecture.";
726 if (arch.
GetTriple().getArch() == llvm::Triple::arm) {
727 std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
731 return emulate_insn_up.release();
732 }
else if (arch.
GetTriple().getArch() == llvm::Triple::thumb) {
733 std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
737 return emulate_insn_up.release();
745 if (arch.
GetTriple().getArch() == llvm::Triple::arm)
747 else if (arch.
GetTriple().getArch() == llvm::Triple::thumb)
760 uint32_t random_data = rand();
763 return MemAWrite(context, address, random_data, addr_byte_size);
786std::optional<RegisterInfo>
824 bool is_apple =
false;
828 case llvm::Triple::Darwin:
829 case llvm::Triple::MacOSX:
830 case llvm::Triple::IOS:
831 case llvm::Triple::TvOS:
832 case llvm::Triple::WatchOS:
833 case llvm::Triple::XROS:
834 case llvm::Triple::BridgeOS:
846 uint32_t fp_regnum = 11;
858 bool is_apple =
false;
862 case llvm::Triple::Darwin:
863 case llvm::Triple::MacOSX:
864 case llvm::Triple::IOS:
897 EncodingSpecificOperations();
898 NullCheckIfThumbEE(13);
899 address = SP - 4*
BitCount(registers);
903 if (registers<i> ==
'1')
905 if i == 13 && i != LowestSetBit(registers)
906 MemA[address,4] =
bits(32) UNKNOWN;
908 MemA[address,4] = R[i];
909 address = address + 4;
913 if (registers<15> ==
'1')
914 MemA[address,4] = PCStoreValue();
920 bool success =
false;
926 uint32_t registers = 0;
930 registers =
Bits32(opcode, 7, 0);
932 if (
Bit32(opcode, 8))
933 registers |= (1u << 14);
940 registers =
Bits32(opcode, 15, 0) & ~0xa000;
946 Rt =
Bits32(opcode, 15, 12);
950 registers = (1u << Rt);
953 registers =
Bits32(opcode, 15, 0);
959 Rt =
Bits32(opcode, 15, 12);
963 registers = (1u << Rt);
974 std::optional<RegisterInfo> sp_reg =
976 for (i = 0; i < 15; ++i) {
978 std::optional<RegisterInfo> reg_info =
984 if (!
MemAWrite(context, addr, reg_value, addr_byte_size))
986 addr += addr_byte_size;
991 std::optional<RegisterInfo> reg_info =
1020 EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1023 if registers<i> ==
'1' then
1024 R[i] =
if UnalignedAllowed then MemU[address,4]
else MemA[address,4]; address = address + 4;
1025 if registers<15> ==
'1' then
1026 if UnalignedAllowed then
1030 if registers<13> ==
'0' then SP = SP + 4*
BitCount(registers);
1031 if registers<13> ==
'1' then SP =
bits(32) UNKNOWN;
1035 bool success =
false;
1042 uint32_t registers = 0;
1046 registers =
Bits32(opcode, 7, 0);
1048 if (
Bit32(opcode, 8))
1049 registers |= (1u << 15);
1056 registers =
Bits32(opcode, 15, 0) & ~0x2000;
1067 Rt =
Bits32(opcode, 15, 12);
1074 registers = (1u << Rt);
1077 registers =
Bits32(opcode, 15, 0);
1087 Rt =
Bits32(opcode, 15, 12);
1091 registers = (1u << Rt);
1103 std::optional<RegisterInfo> sp_reg =
1106 for (i = 0; i < 15; ++i) {
1109 data =
MemARead(context, addr, 4, 0, &success);
1115 addr += addr_byte_size;
1121 data =
MemARead(context, addr, 4, 0, &success);
1148 EncodingSpecificOperations();
1149 (result, carry, overflow) =
AddWithCarry(SP, imm32,
'0');
1155 APSR.N = result<31>;
1156 APSR.Z = IsZeroBit(result);
1162 bool success =
false;
1173 imm32 =
Bits32(opcode, 7, 0) << 2;
1182 addr_t sp_offset = imm32;
1190 std::optional<RegisterInfo> sp_reg =
1209 EncodingSpecificOperations();
1216 APSR.N = result<31>;
1217 APSR.Z = IsZeroBit(result);
1223 bool success =
false;
1246 std::optional<RegisterInfo> sp_reg =
1271 EncodingSpecificOperations();
1278 APSR.N = result<31>;
1279 APSR.Z = IsZeroBit(result);
1285 bool success =
false;
1294 Rm =
Bits32(opcode, 6, 3);
1301 Rm =
Bits32(opcode, 5, 3);
1308 Rm =
Bits32(opcode, 3, 0);
1315 if (!setflags && (
Rd == 15 || Rm == 15 || (
Rd == 13 && Rm == 13)))
1320 Rm =
Bits32(opcode, 3, 0);
1325 if (
Rd == 15 && setflags)
1343 std::optional<RegisterInfo> dwarf_reg =
1362 EncodingSpecificOperations();
1369 APSR.N = result<31>;
1370 APSR.Z = IsZeroBit(result);
1388 imm32 =
Bits32(opcode, 7, 0);
1407 uint32_t imm4 =
Bits32(opcode, 19, 16);
1408 uint32_t imm3 =
Bits32(opcode, 14, 12);
1409 uint32_t i =
Bit32(opcode, 26);
1410 uint32_t imm8 =
Bits32(opcode, 7, 0);
1411 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1427 if ((
Rd == 15) && setflags)
1436 uint32_t imm4 =
Bits32(opcode, 19, 16);
1437 uint32_t imm12 =
Bits32(opcode, 11, 0);
1438 imm32 = (imm4 << 12) | imm12;
1448 uint32_t result = imm32;
1473 EncodingSpecificOperations();
1474 operand1 =
SInt(R[n]);
1475 operand2 =
SInt(R[m]);
1476 result = operand1 * operand2;
1477 R[d] = result<31:0>;
1479 APSR.N = result<31>;
1480 APSR.Z = IsZeroBit(result);
1482 APSR.C =
bit UNKNOWN;
1497 d =
Bits32(opcode, 2, 0);
1498 n =
Bits32(opcode, 5, 3);
1499 m =
Bits32(opcode, 2, 0);
1510 d =
Bits32(opcode, 11, 8);
1511 n =
Bits32(opcode, 19, 16);
1512 m =
Bits32(opcode, 3, 0);
1523 d =
Bits32(opcode, 19, 16);
1524 n =
Bits32(opcode, 3, 0);
1525 m =
Bits32(opcode, 11, 8);
1529 if ((d == 15) || (n == 15) || (m == 15))
1542 bool success =
false;
1559 uint64_t result = operand1 * operand2;
1562 std::optional<RegisterInfo> op1_reg =
1564 std::optional<RegisterInfo> op2_reg =
1572 (0x0000ffff & result)))
1604 EncodingSpecificOperations();
1605 result =
NOT(imm32);
1611 APSR.N = result<31>;
1612 APSR.Z = IsZeroBit(result);
1636 if (
Rd == 15 && setflags)
1642 uint32_t result = ~imm32;
1664 EncodingSpecificOperations();
1665 (shifted, carry) =
Shift_C(R[m], shift_t, shift_n, APSR.C);
1666 result =
NOT(shifted);
1672 APSR.N = result<31>;
1673 APSR.Z = IsZeroBit(result);
1689 Rm =
Bits32(opcode, 5, 3);
1698 Rm =
Bits32(opcode, 3, 0);
1707 Rm =
Bits32(opcode, 3, 0);
1714 bool success =
false;
1723 uint32_t result = ~shifted;
1745 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1747 address =
if add then (base + imm32)
else (base - imm32);
1748 data = MemU[address,4];
1750 if address<1:0> ==
'00' then
LoadWritePC(data);
else UNPREDICTABLE;
1755 R[t] =
ROR(data, 8*
UInt(address<1:0>));
1757 R[t] =
bits(32) UNKNOWN;
1762 bool success =
false;
1770 std::optional<RegisterInfo> pc_reg =
1782 Rt =
Bits32(opcode, 10, 8);
1783 imm32 =
Bits32(opcode, 7, 0) << 2;
1787 Rt =
Bits32(opcode, 15, 12);
1788 imm32 =
Bits32(opcode, 11, 0) << 2;
1799 address = base + imm32;
1801 address = base - imm32;
1804 data =
MemURead(context, address, 4, 0, &success);
1809 if (
Bits32(address, 1, 0) == 0) {
1833 EncodingSpecificOperations();
1834 (result, carry, overflow) =
AddWithCarry(SP, imm32,
'0');
1840 APSR.N = result<31>;
1841 APSR.Z = IsZeroBit(result);
1847 bool success =
false;
1859 d =
Bits32(opcode, 10, 8);
1860 imm32 = (
Bits32(opcode, 7, 0) << 2);
1874 d =
Bits32(opcode, 11, 8);
1876 setflags =
Bit32(opcode, 20);
1879 if (d == 15 && setflags == 1)
1883 if (d == 15 && setflags == 0)
1890 d =
Bits32(opcode, 11, 8);
1892 uint32_t i =
Bit32(opcode, 26);
1893 uint32_t imm3 =
Bits32(opcode, 14, 12);
1894 uint32_t imm8 =
Bits32(opcode, 7, 0);
1895 imm32 = (i << 11) | (imm3 << 8) | imm8;
1914 std::optional<RegisterInfo> sp_reg =
1944 EncodingSpecificOperations();
1945 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
1946 (result, carry, overflow) =
AddWithCarry(SP, shifted,
'0');
1952 APSR.N = result<31>;
1953 APSR.Z = IsZeroBit(result);
1959 bool success =
false;
1968 Rm =
Bits32(opcode, 6, 3);
1977 addr_t addr = (int32_t)
sp + reg_value;
1981 std::optional<RegisterInfo> sp_reg =
1983 std::optional<RegisterInfo> other_reg =
2004 EncodingSpecificOperations();
2008 LR = PC<31:1> :
'1';
2009 if targetInstrSet == InstrSet_ARM then
2010 targetAddress =
Align(PC,4) + imm32;
2012 targetAddress = PC + imm32;
2018 bool success =
true;
2032 uint32_t S =
Bit32(opcode, 26);
2033 uint32_t imm10 =
Bits32(opcode, 25, 16);
2034 uint32_t J1 =
Bit32(opcode, 13);
2035 uint32_t J2 =
Bit32(opcode, 11);
2036 uint32_t imm11 =
Bits32(opcode, 10, 0);
2037 uint32_t I1 = !(J1 ^ S);
2038 uint32_t I2 = !(J2 ^ S);
2040 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2041 imm32 = llvm::SignExtend32<25>(imm25);
2042 target =
pc + imm32;
2051 uint32_t S =
Bit32(opcode, 26);
2052 uint32_t imm10H =
Bits32(opcode, 25, 16);
2053 uint32_t J1 =
Bit32(opcode, 13);
2054 uint32_t J2 =
Bit32(opcode, 11);
2055 uint32_t imm10L =
Bits32(opcode, 10, 1);
2056 uint32_t I1 = !(J1 ^ S);
2057 uint32_t I2 = !(J2 ^ S);
2059 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2060 imm32 = llvm::SignExtend32<25>(imm25);
2061 target =
Align(
pc, 4) + imm32;
2070 imm32 = llvm::SignExtend32<26>(
Bits32(opcode, 23, 0) << 2);
2071 target =
Align(
pc, 4) + imm32;
2077 imm32 = llvm::SignExtend32<26>(
Bits32(opcode, 23, 0) << 2 |
2078 Bits32(opcode, 24, 24) << 1);
2079 target =
pc + imm32;
2108 EncodingSpecificOperations();
2111 next_instr_addr = PC - 4;
2112 LR = next_instr_addr;
2114 next_instr_addr = PC - 2;
2115 LR = next_instr_addr<31:1> :
'1';
2120 bool success =
false;
2133 Rm =
Bits32(opcode, 6, 3);
2142 Rm =
Bits32(opcode, 3, 0);
2153 std::optional<RegisterInfo> dwarf_reg =
2173 EncodingSpecificOperations();
2184 Rm =
Bits32(opcode, 6, 3);
2189 Rm =
Bits32(opcode, 3, 0);
2194 bool success =
false;
2199 std::optional<RegisterInfo> dwarf_reg =
2221 EncodingSpecificOperations();
2225 if JazelleAcceptsExecution() then
2226 SwitchToJazelleExecution();
2228 SUBARCHITECTURE_DEFINED handler call;
2238 Rm =
Bits32(opcode, 19, 16);
2245 Rm =
Bits32(opcode, 3, 0);
2252 bool success =
false;
2257 std::optional<RegisterInfo> dwarf_reg =
2274 EncodingSpecificOperations();
2281 APSR.N = result<31>;
2282 APSR.Z = IsZeroBit(result);
2289 bool success =
false;
2301 addr_t ip_offset = imm32;
2302 addr_t addr = ip - ip_offset;
2306 std::optional<RegisterInfo> dwarf_reg =
2324 EncodingSpecificOperations();
2331 APSR.N = result<31>;
2332 APSR.Z = IsZeroBit(result);
2339 bool success =
false;
2351 addr_t sp_offset = imm32;
2356 std::optional<RegisterInfo> dwarf_reg =
2377 EncodingSpecificOperations();
2384 APSR.N = result<31>;
2385 APSR.Z = IsZeroBit(result);
2391 bool success =
false;
2410 if (
Rd == 15 && setflags)
2412 if (
Rd == 15 && !setflags)
2429 if (
Rd == 15 && setflags)
2439 uint64_t imm64 = imm32;
2463 EncodingSpecificOperations();
2464 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
2465 address =
if index then offset_addr
else R[n];
2466 MemU[address,4] =
if t == 15 then PCStoreValue()
else R[t];
2467 if wback then R[n] = offset_addr;
2471 bool success =
false;
2487 Rt =
Bits32(opcode, 15, 12);
2488 imm12 =
Bits32(opcode, 11, 0);
2489 Rn =
Bits32(opcode, 19, 16);
2498 if (wback && ((Rn == 15) || (Rn == Rt)))
2506 offset_addr =
sp + imm12;
2508 offset_addr =
sp - imm12;
2518 std::optional<RegisterInfo> sp_reg =
2520 std::optional<RegisterInfo> dwarf_reg =
2528 if (!
MemUWrite(context, addr, reg_value, addr_byte_size))
2534 if (!
MemUWrite(context, addr,
pc, addr_byte_size))
2557 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2558 address = SP - imm32;
2562 MemA[address,4] = S[d+r]; address = address+4;
2567 MemA[address,4] =
if BigEndian() then D[d+r]<63:32>
else D[d+r]<31:0>;
2568 MemA[address+4,4] =
if BigEndian() then D[d+r]<31:0>
else D[d+r]<63:32>;
2569 address = address+8;
2573 bool success =
false;
2586 single_regs =
false;
2587 d =
Bit32(opcode, 22) << 4 |
Bits32(opcode, 15, 12);
2588 imm32 =
Bits32(opcode, 7, 0) * addr_byte_size;
2590 regs =
Bits32(opcode, 7, 0) / 2;
2592 if (regs == 0 || regs > 16 || (d + regs) > 32)
2598 d =
Bits32(opcode, 15, 12) << 1 |
Bit32(opcode, 22);
2599 imm32 =
Bits32(opcode, 7, 0) * addr_byte_size;
2600 regs =
Bits32(opcode, 7, 0);
2602 if (regs == 0 || regs > 16 || (d + regs) > 32)
2609 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2610 addr_t sp_offset = imm32;
2617 std::optional<RegisterInfo> sp_reg =
2619 for (i = 0; i < regs; ++i) {
2620 std::optional<RegisterInfo> dwarf_reg =
2627 if (!
MemAWrite(context, addr, reg_value, reg_byte_size))
2629 addr += reg_byte_size;
2650 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2655 S[d+r] = MemA[address,4]; address = address+4;
2658 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2661 D[d+r] =
if BigEndian() then word1:word2
else word2:word1;
2665 bool success =
false;
2678 single_regs =
false;
2679 d =
Bit32(opcode, 22) << 4 |
Bits32(opcode, 15, 12);
2680 imm32 =
Bits32(opcode, 7, 0) * addr_byte_size;
2682 regs =
Bits32(opcode, 7, 0) / 2;
2684 if (regs == 0 || regs > 16 || (d + regs) > 32)
2690 d =
Bits32(opcode, 15, 12) << 1 |
Bit32(opcode, 22);
2691 imm32 =
Bits32(opcode, 7, 0) * addr_byte_size;
2692 regs =
Bits32(opcode, 7, 0);
2694 if (regs == 0 || regs > 16 || (d + regs) > 32)
2701 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2702 addr_t sp_offset = imm32;
2710 for (i = 0; i < regs; ++i) {
2711 std::optional<RegisterInfo> dwarf_reg =
2714 data =
MemARead(context, addr, reg_byte_size, 0, &success);
2719 addr += reg_byte_size;
2739 EncodingSpecificOperations();
2744 bool success =
false;
2756 imm32 =
Bits32(opcode, 7, 0);
2761 imm32 =
Bits32(opcode, 23, 0);
2783 EncodingSpecificOperations();
2784 ITSTATE.IT<7:0> = firstcond:mask;
2804 EncodingSpecificOperations();
2809 bool success =
false;
2822 imm32 = llvm::SignExtend32<9>(
Bits32(opcode, 7, 0) << 1);
2823 target =
pc + imm32;
2827 imm32 = llvm::SignExtend32<12>(
Bits32(opcode, 10, 0) << 1);
2828 target =
pc + imm32;
2834 if (
Bits32(opcode, 25, 23) == 7)
2838 uint32_t S =
Bit32(opcode, 26);
2839 uint32_t imm6 =
Bits32(opcode, 21, 16);
2840 uint32_t J1 =
Bit32(opcode, 13);
2841 uint32_t J2 =
Bit32(opcode, 11);
2842 uint32_t imm11 =
Bits32(opcode, 10, 0);
2844 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2845 imm32 = llvm::SignExtend32<21>(imm21);
2846 target =
pc + imm32;
2851 uint32_t S =
Bit32(opcode, 26);
2852 uint32_t imm10 =
Bits32(opcode, 25, 16);
2853 uint32_t J1 =
Bit32(opcode, 13);
2854 uint32_t J2 =
Bit32(opcode, 11);
2855 uint32_t imm11 =
Bits32(opcode, 10, 0);
2856 uint32_t I1 = !(J1 ^ S);
2857 uint32_t I2 = !(J2 ^ S);
2859 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2860 imm32 = llvm::SignExtend32<25>(imm25);
2861 target =
pc + imm32;
2866 imm32 = llvm::SignExtend32<26>(
Bits32(opcode, 23, 0) << 2);
2867 target =
pc + imm32;
2886 EncodingSpecificOperations();
2887 if nonzero ^
IsZero(R[n]) then
2891 bool success =
false;
2909 imm32 =
Bit32(opcode, 9) << 6 |
Bits32(opcode, 7, 3) << 1;
2911 target =
pc + imm32;
2940 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2942 halfwords =
UInt(MemU[R[n]+
LSL(R[m],1), 2]);
2944 halfwords =
UInt(MemU[R[n]+R[m], 1]);
2948 bool success =
false;
2958 Rn =
Bits32(opcode, 19, 16);
2959 Rm =
Bits32(opcode, 3, 0);
2961 if (Rn == 13 ||
BadReg(Rm))
2982 addr_t addr = base + (is_tbh ? index * 2 : index);
2987 uint32_t offset =
MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2998 context.SetISAAndImmediateSigned(
eModeThumb, 4 + offset);
3014 EncodingSpecificOperations();
3015 (result, carry, overflow) =
AddWithCarry(R[n], imm32,
'0');
3018 APSR.N = result<31>;
3019 APSR.Z = IsZeroBit(result);
3024 bool success =
false;
3038 d =
Bits32(opcode, 2, 0);
3039 n =
Bits32(opcode, 5, 3);
3041 imm32 =
Bits32(opcode, 8, 6);
3048 d =
Bits32(opcode, 10, 8);
3049 n =
Bits32(opcode, 10, 8);
3051 imm32 =
Bits32(opcode, 7, 0);
3059 d =
Bits32(opcode, 11, 8);
3060 n =
Bits32(opcode, 19, 16);
3069 if (
BadReg(d) || (n == 15))
3078 d =
Bits32(opcode, 11, 8);
3079 n =
Bits32(opcode, 19, 16);
3081 uint32_t i =
Bit32(opcode, 26);
3082 uint32_t imm3 =
Bits32(opcode, 14, 12);
3083 uint32_t imm8 =
Bits32(opcode, 7, 0);
3084 imm32 = (i << 11) | (imm3 << 8) | imm8;
3109 std::optional<RegisterInfo> reg_n =
3136 EncodingSpecificOperations();
3137 (result, carry, overflow) =
AddWithCarry(R[n], imm32,
'0');
3143 APSR.N = result<31>;
3144 APSR.Z = IsZeroBit(result);
3149 bool success =
false;
3159 Rn =
Bits32(opcode, 19, 16);
3182 std::optional<RegisterInfo> dwarf_reg =
3201 EncodingSpecificOperations();
3202 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
3203 (result, carry, overflow) =
AddWithCarry(R[n], shifted,
'0');
3209 APSR.N = result<31>;
3210 APSR.Z = IsZeroBit(result);
3215 bool success =
false;
3218 uint32_t
Rd, Rn, Rm;
3225 Rn =
Bits32(opcode, 5, 3);
3226 Rm =
Bits32(opcode, 8, 6);
3233 Rm =
Bits32(opcode, 6, 3);
3237 if (Rn == 15 && Rm == 15)
3244 Rn =
Bits32(opcode, 19, 16);
3245 Rm =
Bits32(opcode, 3, 0);
3263 uint32_t shifted =
Shift(val2, shift_t, shift_n,
APSR_C, &success);
3270 std::optional<RegisterInfo> op1_reg =
3272 std::optional<RegisterInfo> op2_reg =
3290 EncodingSpecificOperations();
3291 (result, carry, overflow) =
AddWithCarry(R[n], imm32,
'0');
3292 APSR.N = result<31>;
3293 APSR.Z = IsZeroBit(result);
3298 bool success =
false;
3304 Rn =
Bits32(opcode, 19, 16);
3310 Rn =
Bits32(opcode, 19, 16);
3337 EncodingSpecificOperations();
3338 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
3339 (result, carry, overflow) =
AddWithCarry(R[n], shifted,
'0');
3340 APSR.N = result<31>;
3341 APSR.Z = IsZeroBit(result);
3346 bool success =
false;
3354 Rn =
Bits32(opcode, 2, 0);
3355 Rm =
Bits32(opcode, 5, 3);
3360 Rn =
Bits32(opcode, 19, 16);
3361 Rm =
Bits32(opcode, 3, 0);
3364 if (Rn == 15 ||
BadReg(Rm))
3368 Rn =
Bits32(opcode, 19, 16);
3369 Rm =
Bits32(opcode, 3, 0);
3385 uint32_t shifted =
Shift(val2, shift_t, shift_n,
APSR_C, &success);
3403 EncodingSpecificOperations();
3405 APSR.N = result<31>;
3406 APSR.Z = IsZeroBit(result);
3411 bool success =
false;
3417 Rn =
Bits32(opcode, 10, 8);
3418 imm32 =
Bits32(opcode, 7, 0);
3421 Rn =
Bits32(opcode, 19, 16);
3427 Rn =
Bits32(opcode, 19, 16);
3454 EncodingSpecificOperations();
3455 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
3457 APSR.N = result<31>;
3458 APSR.Z = IsZeroBit(result);
3463 bool success =
false;
3471 Rn =
Bits32(opcode, 2, 0);
3472 Rm =
Bits32(opcode, 5, 3);
3477 Rn =
Bit32(opcode, 7) << 3 |
Bits32(opcode, 2, 0);
3478 Rm =
Bits32(opcode, 6, 3);
3481 if (Rn < 8 && Rm < 8)
3483 if (Rn == 15 || Rm == 15)
3487 Rn =
Bits32(opcode, 19, 16);
3488 Rm =
Bits32(opcode, 3, 0);
3490 if (Rn == 15 ||
BadReg(Rm))
3494 Rn =
Bits32(opcode, 19, 16);
3495 Rm =
Bits32(opcode, 3, 0);
3511 uint32_t shifted =
Shift(val2, shift_t, shift_n,
APSR_C, &success);
3531 EncodingSpecificOperations();
3538 APSR.N = result<31>;
3539 APSR.Z = IsZeroBit(result);
3557 EncodingSpecificOperations();
3558 shift_n =
UInt(R[m]<7:0>);
3562 APSR.N = result<31>;
3563 APSR.Z = IsZeroBit(result);
3579 EncodingSpecificOperations();
3586 APSR.N = result<31>;
3587 APSR.Z = IsZeroBit(result);
3604 EncodingSpecificOperations();
3605 shift_n =
UInt(R[m]<7:0>);
3609 APSR.N = result<31>;
3610 APSR.Z = IsZeroBit(result);
3627 EncodingSpecificOperations();
3634 APSR.N = result<31>;
3635 APSR.Z = IsZeroBit(result);
3652 EncodingSpecificOperations();
3653 shift_n =
UInt(R[m]<7:0>);
3657 APSR.N = result<31>;
3658 APSR.Z = IsZeroBit(result);
3675 EncodingSpecificOperations();
3682 APSR.N = result<31>;
3683 APSR.Z = IsZeroBit(result);
3701 EncodingSpecificOperations();
3702 shift_n =
UInt(R[m]<7:0>);
3706 APSR.N = result<31>;
3707 APSR.Z = IsZeroBit(result);
3725 EncodingSpecificOperations();
3732 APSR.N = result<31>;
3733 APSR.Z = IsZeroBit(result);
3750 bool success =
false;
3769 switch (use_encoding) {
3772 Rm =
Bits32(opcode, 5, 3);
3774 imm5 =
Bits32(opcode, 10, 6);
3783 Rm =
Bits32(opcode, 3, 0);
3785 imm5 =
Bits32(opcode, 14, 12) << 2 |
Bits32(opcode, 7, 6);
3791 Rm =
Bits32(opcode, 3, 0);
3793 imm5 =
Bits32(opcode, 11, 7);
3812 uint32_t result =
Shift_C(value, shift_type, amt,
APSR_C, carry, &success);
3835 bool success =
false;
3848 Rm =
Bits32(opcode, 5, 3);
3853 Rn =
Bits32(opcode, 19, 16);
3854 Rm =
Bits32(opcode, 3, 0);
3861 Rn =
Bits32(opcode, 3, 0);
3862 Rm =
Bits32(opcode, 11, 8);
3864 if (
Rd == 15 || Rn == 15 || Rm == 15)
3881 uint32_t amt =
Bits32(val, 7, 0);
3883 uint32_t result =
Shift_C(value, shift_type, amt,
APSR_C, carry, &success);
3906 EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3910 if registers<i> ==
'1' then
3911 R[i] = MemA[address, 4]; address = address + 4;
3912 if registers<15> ==
'1' then
3915 if wback && registers<n> ==
'0' then R[n] = R[n] + 4 *
BitCount (registers);
3916 if wback && registers<n> ==
'1' then R[n] =
bits(32) UNKNOWN;
3920 bool success =
false;
3923 uint32_t registers = 0;
3930 n =
Bits32(opcode, 10, 8);
3931 registers =
Bits32(opcode, 7, 0);
3932 registers = registers & 0x00ff;
3941 n =
Bits32(opcode, 19, 16);
3942 registers =
Bits32(opcode, 15, 0);
3943 registers = registers & 0xdfff;
3948 if ((n == 15) || (
BitCount(registers) < 2) ||
3958 if (wback &&
BitIsSet(registers, n))
3963 n =
Bits32(opcode, 19, 16);
3964 registers =
Bits32(opcode, 15, 0);
3966 if ((n == 15) || (
BitCount(registers) < 1))
3974 const addr_t base_address =
3981 std::optional<RegisterInfo> dwarf_reg =
3985 for (
int i = 0; i < 14; ++i) {
3989 if (wback && (n == 13))
3996 uint32_t data =
MemARead(context, base_address + offset, addr_byte_size,
4005 offset += addr_byte_size;
4014 MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4024 int32_t offset = addr_byte_size *
BitCount(registers);
4029 base_address + offset))
4032 if (wback &&
BitIsSet(registers, n))
4049 EncodingSpecificOperations();
4050 address = R[n] - 4*
BitCount(registers) + 4;
4053 if registers<i> ==
'1' then
4054 R[i] = MemA[address,4]; address = address + 4;
4056 if registers<15> ==
'1' then
4059 if wback && registers<n> ==
'0' then R[n] = R[n] - 4*
BitCount(registers);
4060 if wback && registers<n> ==
'1' then R[n] =
bits(32) UNKNOWN;
4063 bool success =
false;
4067 uint32_t registers = 0;
4075 n =
Bits32(opcode, 19, 16);
4076 registers =
Bits32(opcode, 15, 0);
4080 if ((n == 15) || (
BitCount(registers) < 1))
4097 Rn - (addr_byte_size *
BitCount(registers)) + addr_byte_size;
4101 std::optional<RegisterInfo> dwarf_reg =
4103 context.SetRegisterPlusOffset(*dwarf_reg, offset);
4106 for (
int i = 0; i < 14; ++i) {
4110 context.SetRegisterPlusOffset(*dwarf_reg, Rn - (address + offset));
4112 MemARead(context, address + offset, addr_byte_size, 0, &success);
4118 offset += addr_byte_size;
4125 context.SetRegisterPlusOffset(*dwarf_reg, offset);
4127 MemARead(context, address + offset, addr_byte_size, 0, &success);
4138 offset = (addr_byte_size *
BitCount(registers)) * -1;
4140 context.SetImmediateSigned(offset);
4141 addr_t addr = Rn + offset;
4148 if (wback &&
BitIsSet(registers, n))
4164 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4165 address = R[n] - 4*
BitCount(registers);
4168 if registers<i> ==
'1' then
4169 R[i] = MemA[address,4]; address = address + 4;
4170 if registers<15> ==
'1' then
4173 if wback && registers<n> ==
'0' then R[n] = R[n] - 4*
BitCount(registers);
4174 if wback && registers<n> ==
'1' then R[n] =
bits(32) UNKNOWN;
4177 bool success =
false;
4181 uint32_t registers = 0;
4187 n =
Bits32(opcode, 19, 16);
4188 registers =
Bits32(opcode, 15, 0);
4189 registers = registers & 0xdfff;
4194 if ((n == 15) || (
BitCount(registers) < 2) ||
4204 if (wback &&
BitIsSet(registers, n))
4211 n =
Bits32(opcode, 19, 16);
4212 registers =
Bits32(opcode, 15, 0);
4216 if ((n == 15) || (
BitCount(registers) < 1))
4237 std::optional<RegisterInfo> dwarf_reg =
4239 context.SetRegisterPlusOffset(*dwarf_reg, Rn - address);
4241 for (
int i = 0; i < 14; ++i) {
4244 context.SetRegisterPlusOffset(*dwarf_reg, Rn - (address + offset));
4246 MemARead(context, address + offset, addr_byte_size, 0, &success);
4254 offset += addr_byte_size;
4261 context.SetRegisterPlusOffset(*dwarf_reg, offset);
4263 MemARead(context, address + offset, addr_byte_size, 0, &success);
4274 offset = (addr_byte_size *
BitCount(registers)) * -1;
4276 context.SetImmediateSigned(offset);
4277 addr_t addr = Rn + offset;
4285 if (wback &&
BitIsSet(registers, n))
4300 EncodingSpecificOperations();
4304 if registers<i> ==
'1' then
4305 R[i] = MemA[address,4]; address = address + 4;
4306 if registers<15> ==
'1' then
4309 if wback && registers<n> ==
'0' then R[n] = R[n] + 4*
BitCount(registers);
4310 if wback && registers<n> ==
'1' then R[n] =
bits(32) UNKNOWN;
4313 bool success =
false;
4317 uint32_t registers = 0;
4323 n =
Bits32(opcode, 19, 16);
4324 registers =
Bits32(opcode, 15, 0);
4328 if ((n == 15) || (
BitCount(registers) < 1))
4344 addr_t address = Rn + addr_byte_size;
4348 std::optional<RegisterInfo> dwarf_reg =
4352 for (
int i = 0; i < 14; ++i) {
4358 MemARead(context, address + offset, addr_byte_size, 0, &success);
4366 offset += addr_byte_size;
4375 MemARead(context, address + offset, addr_byte_size, 0, &success);
4386 offset = addr_byte_size *
BitCount(registers);
4389 addr_t addr = Rn + offset;
4397 if (wback &&
BitIsSet(registers, n))
4412 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4413 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
4414 address =
if index then offset_addr
else R[n];
4415 data = MemU[address,4];
4416 if wback then R[n] = offset_addr;
4418 if address<1:0> ==
'00' then
LoadWritePC(data);
else UNPREDICTABLE;
4421 else R[t] =
bits(32) UNKNOWN;
4425 bool success =
false;
4434 bool add, index, wback;
4437 Rt =
Bits32(opcode, 2, 0);
4438 Rn =
Bits32(opcode, 5, 3);
4439 imm32 =
Bits32(opcode, 10, 6) << 2;
4449 Rt =
Bits32(opcode, 10, 8);
4451 imm32 =
Bits32(opcode, 7, 0) << 2;
4463 Rt =
Bits32(opcode, 15, 12);
4464 Rn =
Bits32(opcode, 19, 16);
4465 imm32 =
Bits32(opcode, 11, 0);
4488 Rt =
Bits32(opcode, 15, 12);
4489 Rn =
Bits32(opcode, 19, 16);
4490 imm32 =
Bits32(opcode, 7, 0);
4499 if ((wback && (Rn == Rt)) ||
4512 offset_addr = base + imm32;
4514 offset_addr = base - imm32;
4516 address = (index ? offset_addr : base);
4518 std::optional<RegisterInfo> base_reg =
4544 data =
MemURead(context, address, 4, 0, &success);
4549 if (
Bits32(address, 1, 0) == 0) {
4573 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4577 if registers<i> ==
'1' then
4578 if i == n && wback && i != LowestSetBit(registers) then
4579 MemA[address,4] =
bits(32) UNKNOWN;
4581 MemA[address,4] = R[i];
4582 address = address + 4;
4584 if registers<15> ==
'1' then
4585 MemA[address,4] = PCStoreValue();
4586 if wback then R[n] = R[n] + 4*
BitCount(registers);
4589 bool success =
false;
4593 uint32_t registers = 0;
4601 n =
Bits32(opcode, 10, 8);
4602 registers =
Bits32(opcode, 7, 0);
4603 registers = registers & 0x00ff;
4614 n =
Bits32(opcode, 19, 16);
4615 registers =
Bits32(opcode, 15, 0);
4616 registers = registers & 0x5fff;
4620 if ((n == 15) || (
BitCount(registers) < 2))
4624 if (wback &&
BitIsSet(registers, n))
4631 n =
Bits32(opcode, 19, 16);
4632 registers =
Bits32(opcode, 15, 0);
4636 if ((n == 15) || (
BitCount(registers) < 1))
4654 std::optional<RegisterInfo> base_reg =
4658 uint32_t lowest_set_bit = 14;
4659 for (uint32_t i = 0; i < 14; ++i) {
4662 if (i < lowest_set_bit)
4665 if ((i == n) && wback && (i != lowest_set_bit))
4676 std::optional<RegisterInfo> data_reg =
4679 if (!
MemAWrite(context, address + offset, data, addr_byte_size))
4684 offset += addr_byte_size;
4691 std::optional<RegisterInfo> pc_reg =
4698 if (!
MemAWrite(context, address + offset,
pc, addr_byte_size))
4704 offset = addr_byte_size *
BitCount(registers);
4707 addr_t data = address + offset;
4725 EncodingSpecificOperations();
4726 address = R[n] - 4*
BitCount(registers) + 4;
4729 if registers<i> ==
'1' then
4730 if i == n && wback && i != LowestSetBit(registers) then
4731 MemA[address,4] =
bits(32) UNKNOWN;
4733 MemA[address,4] = R[i];
4734 address = address + 4;
4736 if registers<15> ==
'1' then
4737 MemA[address,4] = PCStoreValue();
4739 if wback then R[n] = R[n] - 4*
BitCount(registers);
4742 bool success =
false;
4746 uint32_t registers = 0;
4754 n =
Bits32(opcode, 19, 16);
4755 registers =
Bits32(opcode, 15, 0);
4759 if ((n == 15) || (
BitCount(registers) < 1))
4772 addr_t address = Rn - (addr_byte_size *
BitCount(registers)) + 4;
4776 std::optional<RegisterInfo> base_reg =
4780 uint32_t lowest_bit_set = 14;
4781 for (uint32_t i = 0; i < 14; ++i) {
4784 if (i < lowest_bit_set)
4787 if ((i == n) && wback && (i != lowest_bit_set))
4797 std::optional<RegisterInfo> data_reg =
4799 context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
4800 Rn - (address + offset));
4801 if (!
MemAWrite(context, address + offset, data, addr_byte_size))
4806 offset += addr_byte_size;
4813 std::optional<RegisterInfo> pc_reg =
4815 context.SetRegisterPlusOffset(*pc_reg, 8);
4820 if (!
MemAWrite(context, address + offset,
pc, addr_byte_size))
4826 offset = (addr_byte_size *
BitCount(registers)) * -1;
4828 context.SetImmediateSigned(offset);
4829 addr_t data = Rn + offset;
4847 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4848 address = R[n] - 4*
BitCount(registers);
4851 if registers<i> ==
'1' then
4852 if i == n && wback && i != LowestSetBit(registers) then
4853 MemA[address,4] =
bits(32) UNKNOWN;
4855 MemA[address,4] = R[i];
4856 address = address + 4;
4858 if registers<15> ==
'1' then
4859 MemA[address,4] = PCStoreValue();
4861 if wback then R[n] = R[n] - 4*
BitCount(registers);
4864 bool success =
false;
4868 uint32_t registers = 0;
4880 n =
Bits32(opcode, 19, 16);
4881 registers =
Bits32(opcode, 15, 0);
4882 registers = registers & 0x5fff;
4885 if ((n == 15) ||
BitCount(registers) < 2)
4888 if (wback &&
BitIsSet(registers, n))
4900 n =
Bits32(opcode, 19, 16);
4901 registers =
Bits32(opcode, 15, 0);
4904 if ((n == 15) ||
BitCount(registers) < 1)
4924 std::optional<RegisterInfo> base_reg =
4928 uint32_t lowest_set_bit = 14;
4929 for (uint32_t i = 0; i < 14; ++i) {
4932 if (i < lowest_set_bit)
4935 if ((i == n) && wback && (i != lowest_set_bit))
4946 std::optional<RegisterInfo> data_reg =
4948 context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
4949 Rn - (address + offset));
4950 if (!
MemAWrite(context, address + offset, data, addr_byte_size))
4955 offset += addr_byte_size;
4962 std::optional<RegisterInfo> pc_reg =
4964 context.SetRegisterPlusOffset(*pc_reg, 8);
4969 if (!
MemAWrite(context, address + offset,
pc, addr_byte_size))
4975 offset = (addr_byte_size *
BitCount(registers)) * -1;
4977 context.SetImmediateSigned(offset);
4978 addr_t data = Rn + offset;
4996 EncodingSpecificOperations();
5000 if registers<i> ==
'1' then
5001 if i == n && wback && i != LowestSetBit(registers) then
5002 MemA[address,4] =
bits(32) UNKNOWN;
5004 MemA[address,4] = R[i];
5005 address = address + 4;
5007 if registers<15> ==
'1' then
5008 MemA[address,4] = PCStoreValue();
5010 if wback then R[n] = R[n] + 4*
BitCount(registers);
5013 bool success =
false;
5017 uint32_t registers = 0;
5025 n =
Bits32(opcode, 19, 16);
5026 registers =
Bits32(opcode, 15, 0);
5030 if ((n == 15) && (
BitCount(registers) < 1))
5043 addr_t address = Rn + addr_byte_size;
5047 std::optional<RegisterInfo> base_reg =
5050 uint32_t lowest_set_bit = 14;
5052 for (uint32_t i = 0; i < 14; ++i) {
5055 if (i < lowest_set_bit)
5058 if ((i == n) && wback && (i != lowest_set_bit))
5069 std::optional<RegisterInfo> data_reg =
5072 offset + addr_byte_size);
5073 if (!
MemAWrite(context, address + offset, data, addr_byte_size))
5078 offset += addr_byte_size;
5085 std::optional<RegisterInfo> pc_reg =
5092 if (!
MemAWrite(context, address + offset,
pc, addr_byte_size))
5098 offset = addr_byte_size *
BitCount(registers);
5101 addr_t data = Rn + offset;
5118 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5119 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
5120 address =
if index then offset_addr
else R[n];
5122 MemU[address,4] = R[t];
5124 MemU[address,4] =
bits(32) UNKNOWN;
5125 if wback then R[n] = offset_addr;
5128 bool success =
false;
5143 t =
Bits32(opcode, 2, 0);
5144 n =
Bits32(opcode, 5, 3);
5145 imm32 =
Bits32(opcode, 10, 6) << 2;
5155 t =
Bits32(opcode, 10, 8);
5157 imm32 =
Bits32(opcode, 7, 0) << 2;
5167 if (
Bits32(opcode, 19, 16) == 15)
5171 t =
Bits32(opcode, 15, 12);
5172 n =
Bits32(opcode, 19, 16);
5173 imm32 =
Bits32(opcode, 11, 0);
5190 if ((
Bits32(opcode, 19, 16) == 15) ||
5195 t =
Bits32(opcode, 15, 12);
5196 n =
Bits32(opcode, 19, 16);
5197 imm32 =
Bits32(opcode, 7, 0);
5205 if ((t == 15) || (wback && (n == t)))
5222 offset_addr = base_address + imm32;
5224 offset_addr = base_address - imm32;
5228 address = offset_addr;
5230 address = base_address;
5238 std::optional<RegisterInfo> base_reg =
5250 std::optional<RegisterInfo> data_reg =
5252 int32_t offset = address - base_address;
5254 if (!
MemUWrite(context, address, data, addr_byte_size))
5285 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5286 offset =
Shift(R[m], shift_t, shift_n, APSR.C);
5287 offset_addr =
if add then (R[n] + offset)
else (R[n] - offset);
5288 address =
if index then offset_addr
else R[n];
5290 data = PCStoreValue();
5294 MemU[address,4] = data;
5296 MemU[address,4] =
bits(32) UNKNOWN;
5297 if wback then R[n] = offset_addr;
5300 bool success =
false;
5320 t =
Bits32(opcode, 2, 0);
5321 n =
Bits32(opcode, 5, 3);
5322 m =
Bits32(opcode, 8, 6);
5336 if (
Bits32(opcode, 19, 16) == 15)
5340 t =
Bits32(opcode, 15, 12);
5341 n =
Bits32(opcode, 19, 16);
5342 m =
Bits32(opcode, 3, 0);
5351 shift_n =
Bits32(opcode, 5, 4);
5354 if ((t == 15) || (
BadReg(m)))
5361 t =
Bits32(opcode, 15, 12);
5362 n =
Bits32(opcode, 19, 16);
5363 m =
Bits32(opcode, 3, 0);
5372 uint32_t typ =
Bits32(opcode, 6, 5);
5373 uint32_t imm5 =
Bits32(opcode, 11, 7);
5381 if (wback && ((n == 15) || (n == t)))
5405 offset =
Shift(Rm_data, shift_t, shift_n,
APSR_C, &success);
5411 offset_addr = base_address + offset;
5413 offset_addr = base_address - offset;
5417 address = offset_addr;
5419 address = base_address;
5444 std::optional<RegisterInfo> base_reg =
5446 std::optional<RegisterInfo> data_reg =
5450 address - base_address);
5451 if (!
MemUWrite(context, address, data, addr_byte_size))
5474 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5475 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
5476 address =
if index then offset_addr
else R[n];
5477 MemU[address,1] = R[t]<7:0>;
5478 if wback then R[n] = offset_addr;
5481 bool success =
false;
5494 t =
Bits32(opcode, 2, 0);
5495 n =
Bits32(opcode, 5, 3);
5496 imm32 =
Bits32(opcode, 10, 6);
5506 if (
Bits32(opcode, 19, 16) == 15)
5510 t =
Bits32(opcode, 15, 12);
5511 n =
Bits32(opcode, 19, 16);
5512 imm32 =
Bits32(opcode, 11, 0);
5527 if (
Bits32(opcode, 19, 16) == 15)
5531 t =
Bits32(opcode, 15, 12);
5532 n =
Bits32(opcode, 19, 16);
5533 imm32 =
Bits32(opcode, 7, 0);
5541 if ((
BadReg(t)) || (wback && (n == t)))
5558 offset_addr = base_address + imm32;
5560 offset_addr = base_address - imm32;
5564 address = offset_addr;
5566 address = base_address;
5569 std::optional<RegisterInfo> base_reg =
5571 std::optional<RegisterInfo> data_reg =
5577 address - base_address);
5584 data =
Bits32(data, 7, 0);
5586 if (!
MemUWrite(context, address, data, 1))
5610 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5611 offset =
Shift(R[m], shift_t, shift_n, APSR.C);
5612 offset_addr =
if add then (R[n] + offset)
else (R[n] - offset);
5613 address =
if index then offset_addr
else R[n];
5615 MemU[address,2] = R[t]<15:0>;
5617 MemU[address,2] =
bits(16) UNKNOWN;
5618 if wback then R[n] = offset_addr;
5621 bool success =
false;
5639 t =
Bits32(opcode, 2, 0);
5640 n =
Bits32(opcode, 5, 3);
5641 m =
Bits32(opcode, 8, 6);
5657 t =
Bits32(opcode, 15, 12);
5658 n =
Bits32(opcode, 19, 16);
5659 m =
Bits32(opcode, 3, 0);
5670 shift_n =
Bits32(opcode, 5, 4);
5681 t =
Bits32(opcode, 15, 12);
5682 n =
Bits32(opcode, 19, 16);
5683 m =
Bits32(opcode, 3, 0);
5696 if ((t == 15) || (m == 15))
5700 if (wback && ((n == 15) || (n == t)))
5718 uint32_t offset =
Shift(Rm, shift_t, shift_n,
APSR_C, &success);
5725 offset_addr = Rn + offset;
5727 offset_addr = Rn - offset;
5732 address = offset_addr;
5748 std::optional<RegisterInfo> base_reg =
5750 std::optional<RegisterInfo> offset_reg =
5752 std::optional<RegisterInfo> data_reg =
5785 EncodingSpecificOperations();
5786 (result, carry, overflow) =
AddWithCarry(R[n], imm32, APSR.C);
5792 APSR.N = result<31>;
5793 APSR.Z = IsZeroBit(result);
5798 bool success =
false;
5808 Rn =
Bits32(opcode, 19, 16);
5816 Rn =
Bits32(opcode, 19, 16);
5820 if (
Rd == 15 && setflags)
5854 EncodingSpecificOperations();
5855 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
5856 (result, carry, overflow) =
AddWithCarry(R[n], shifted, APSR.C);
5862 APSR.N = result<31>;
5863 APSR.Z = IsZeroBit(result);
5868 bool success =
false;
5871 uint32_t
Rd, Rn, Rm;
5878 Rm =
Bits32(opcode, 5, 3);
5885 Rn =
Bits32(opcode, 19, 16);
5886 Rm =
Bits32(opcode, 3, 0);
5894 Rn =
Bits32(opcode, 19, 16);
5895 Rm =
Bits32(opcode, 3, 0);
5899 if (
Rd == 15 && setflags)
5916 uint32_t shifted =
Shift(val2, shift_t, shift_n,
APSR_C, &success);
5939 EncodingSpecificOperations();
5940 result =
if add then (
Align(PC,4) + imm32)
else (
Align(PC,4) - imm32);
5947 bool success =
false;
5963 add = (
Bits32(opcode, 24, 21) == 0);
5971 add = (
Bits32(opcode, 24, 21) == 0x4);
5982 uint32_t result = (add ?
Align(
pc, 4) + imm32 :
Align(
pc, 4) - imm32);
6002 EncodingSpecificOperations();
6003 result = R[n] AND imm32;
6009 APSR.N = result<31>;
6010 APSR.Z = IsZeroBit(result);
6015 bool success =
false;
6026 Rn =
Bits32(opcode, 19, 16);
6032 if (
Rd == 15 && setflags)
6034 if (
Rd == 13 || (
Rd == 15 && !setflags) ||
BadReg(Rn))
6039 Rn =
Bits32(opcode, 19, 16);
6045 if (
Rd == 15 && setflags)
6057 uint32_t result = val1 & imm32;
6077 EncodingSpecificOperations();
6078 (shifted, carry) =
Shift_C(R[m], shift_t, shift_n, APSR.C);
6079 result = R[n] AND shifted;
6085 APSR.N = result<31>;
6086 APSR.Z = IsZeroBit(result);
6091 bool success =
false;
6094 uint32_t
Rd, Rn, Rm;
6102 Rm =
Bits32(opcode, 5, 3);
6109 Rn =
Bits32(opcode, 19, 16);
6110 Rm =
Bits32(opcode, 3, 0);
6114 if (
Rd == 15 && setflags)
6121 Rn =
Bits32(opcode, 19, 16);
6122 Rm =
Bits32(opcode, 3, 0);
6126 if (
Rd == 15 && setflags)
6143 uint32_t shifted =
Shift_C(val2, shift_t, shift_n,
APSR_C, carry, &success);
6146 uint32_t result = val1 & shifted;
6167 EncodingSpecificOperations();
6168 result = R[n] AND
NOT(imm32);
6174 APSR.N = result<31>;
6175 APSR.Z = IsZeroBit(result);
6180 bool success =
false;
6191 Rn =
Bits32(opcode, 19, 16);
6201 Rn =
Bits32(opcode, 19, 16);
6209 if (
Rd == 15 && setflags)
6221 uint32_t result = val1 & ~imm32;
6242 EncodingSpecificOperations();
6243 (shifted, carry) =
Shift_C(R[m], shift_t, shift_n, APSR.C);
6244 result = R[n] AND
NOT(shifted);
6250 APSR.N = result<31>;
6251 APSR.Z = IsZeroBit(result);
6256 bool success =
false;
6259 uint32_t
Rd, Rn, Rm;
6267 Rm =
Bits32(opcode, 5, 3);
6274 Rn =
Bits32(opcode, 19, 16);
6275 Rm =
Bits32(opcode, 3, 0);
6283 Rn =
Bits32(opcode, 19, 16);
6284 Rm =
Bits32(opcode, 3, 0);
6290 if (
Rd == 15 && setflags)
6307 uint32_t shifted =
Shift_C(val2, shift_t, shift_n,
APSR_C, carry, &success);
6310 uint32_t result = val1 & ~shifted;
6330 EncodingSpecificOperations();
6331 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
6332 address =
if index then offset_addr
else R[n];
6333 data = MemU[address,4];
6334 if wback then R[n] = offset_addr;
6336 if address<1:0> ==
'00' then
LoadWritePC(data);
else UNPREDICTABLE;
6340 R[t] =
ROR(data, 8*
UInt(address<1:0>));
6343 bool success =
false;
6362 t =
Bits32(opcode, 15, 12);
6363 n =
Bits32(opcode, 19, 16);
6364 imm32 =
Bits32(opcode, 11, 0);
6373 if (wback && (n == t))
6390 offset_addr = base_address + imm32;
6392 offset_addr = base_address - imm32;
6396 address = offset_addr;
6398 address = base_address;
6402 std::optional<RegisterInfo> base_reg =
6408 uint64_t data =
MemURead(context, address, addr_byte_size, 0, &success);
6445 data =
ROR(data,
Bits32(address, 1, 0), &success);
6466 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6467 offset =
Shift(R[m], shift_t, shift_n, APSR.C);
6468 offset_addr =
if add then (R[n] + offset)
else (R[n] - offset);
6469 address =
if index then offset_addr
else R[n];
6470 data = MemU[address,4];
6471 if wback then R[n] = offset_addr;
6473 if address<1:0> ==
'00' then
LoadWritePC(data);
else UNPREDICTABLE;
6478 R[t] =
ROR(data, 8*
UInt(address<1:0>));
6480 R[t] =
bits(32) UNKNOWN;
6483 bool success =
false;
6502 t =
Bits32(opcode, 2, 0);
6503 n =
Bits32(opcode, 5, 3);
6504 m =
Bits32(opcode, 8, 6);
6520 t =
Bits32(opcode, 15, 12);
6521 n =
Bits32(opcode, 19, 16);
6522 m =
Bits32(opcode, 3, 0);
6531 shift_n =
Bits32(opcode, 5, 4);
6546 t =
Bits32(opcode, 15, 12);
6547 n =
Bits32(opcode, 19, 16);
6548 m =
Bits32(opcode, 3, 0);
6557 uint32_t type =
Bits32(opcode, 6, 5);
6558 uint32_t imm5 =
Bits32(opcode, 11, 7);
6566 if (wback && ((n == 15) || (n == t)))
6596 offset_addr = Rn + offset;
6598 offset_addr = Rn - offset;
6602 address = offset_addr;
6607 std::optional<RegisterInfo> base_reg =
6613 uint64_t data =
MemURead(context, address, addr_byte_size, 0, &success);
6650 data =
ROR(data,
Bits32(address, 1, 0), &success);
6672 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6673 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
6674 address =
if index then offset_addr
else R[n];
6675 R[t] = ZeroExtend(MemU[address,1], 32);
6676 if wback then R[n] = offset_addr;
6679 bool success =
false;
6693 t =
Bits32(opcode, 2, 0);
6694 n =
Bits32(opcode, 5, 3);
6695 imm32 =
Bits32(opcode, 10, 6);
6706 t =
Bits32(opcode, 15, 12);
6707 n =
Bits32(opcode, 19, 16);
6708 imm32 =
Bits32(opcode, 11, 0);
6736 t =
Bits32(opcode, 15, 12);
6737 n =
Bits32(opcode, 19, 16);
6738 imm32 =
Bits32(opcode, 7, 0);
6754 if (
BadReg(t) || (wback && (n == t)))
6773 offset_addr = Rn + imm32;
6775 offset_addr = Rn - imm32;
6779 address = offset_addr;
6784 std::optional<RegisterInfo> base_reg =
6786 std::optional<RegisterInfo> data_reg =
6793 uint64_t data =
MemURead(context, address, 1, 0, &success);
6819 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6821 address =
if add then (base + imm32)
else (base - imm32);
6822 R[t] = ZeroExtend(MemU[address,1], 32);
6825 bool success =
false;
6834 t =
Bits32(opcode, 15, 12);
6835 imm32 =
Bits32(opcode, 11, 0);
6850 t =
Bits32(opcode, 15, 12);
6851 imm32 =
Bits32(opcode, 11, 0);
6868 uint32_t base =
AlignPC(pc_val);
6873 address = base + imm32;
6875 address = base - imm32;
6882 uint64_t data =
MemURead(context, address, 1, 0, &success);
6900 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6901 offset =
Shift(R[m], shift_t, shift_n, APSR.C);
6902 offset_addr =
if add then (R[n] + offset)
else (R[n] - offset);
6903 address =
if index then offset_addr
else R[n];
6904 R[t] = ZeroExtend(MemU[address,1],32);
6905 if wback then R[n] = offset_addr;
6908 bool success =
false;
6924 t =
Bits32(opcode, 2, 0);
6925 n =
Bits32(opcode, 5, 3);
6926 m =
Bits32(opcode, 8, 6);
6940 t =
Bits32(opcode, 15, 12);
6941 n =
Bits32(opcode, 19, 16);
6942 m =
Bits32(opcode, 3, 0);
6951 shift_n =
Bits32(opcode, 5, 4);
6962 if ((t == 13) ||
BadReg(m))
6969 t =
Bits32(opcode, 15, 12);
6970 n =
Bits32(opcode, 19, 16);
6971 m =
Bits32(opcode, 3, 0);
6980 uint32_t type =
Bits32(opcode, 6, 5);
6981 uint32_t imm5 =
Bits32(opcode, 11, 7);
6985 if ((t == 15) || (m == 15))
6989 if (wback && ((n == 15) || (n == t)))
7017 offset_addr = Rn + offset;
7019 offset_addr = Rn - offset;
7023 address = offset_addr;
7028 std::optional<RegisterInfo> base_reg =
7035 uint64_t data =
MemURead(context, address, 1, 0, &success);
7062 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7063 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
7064 address =
if index then offset_addr
else R[n];
7065 data = MemU[address,2];
7066 if wback then R[n] = offset_addr;
7068 R[t] = ZeroExtend(data, 32);
7070 R[t] =
bits(32) UNKNOWN;
7073 bool success =
false;
7087 t =
Bits32(opcode, 2, 0);
7088 n =
Bits32(opcode, 5, 3);
7089 imm32 =
Bits32(opcode, 10, 6) << 1;
7102 t =
Bits32(opcode, 15, 12);
7103 n =
Bits32(opcode, 19, 16);
7104 imm32 =
Bits32(opcode, 11, 0);
7126 t =
Bits32(opcode, 15, 12);
7127 n =
Bits32(opcode, 19, 16);
7128 imm32 =
Bits32(opcode, 7, 0);
7136 if (
BadReg(t) || (wback && (n == t)))
7154 offset_addr = Rn + imm32;
7156 offset_addr = Rn - imm32;
7160 address = offset_addr;
7165 std::optional<RegisterInfo> base_reg =
7172 uint64_t data =
MemURead(context, address, 2, 0, &success);
7209 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7211 address =
if add then (base + imm32)
else (base - imm32);
7212 data = MemU[address,2];
7214 R[t] = ZeroExtend(data, 32);
7216 R[t] =
bits(32) UNKNOWN;
7219 bool success =
false;
7231 t =
Bits32(opcode, 15, 12);
7232 imm32 =
Bits32(opcode, 11, 0);
7242 uint32_t imm4H =
Bits32(opcode, 11, 8);
7243 uint32_t imm4L =
Bits32(opcode, 3, 0);
7246 t =
Bits32(opcode, 15, 12);
7247 imm32 = (imm4H << 4) | imm4L;
7270 address = base + imm32;
7272 address = base - imm32;
7275 std::optional<RegisterInfo> base_reg =
7282 uint64_t data =
MemURead(context, address, 2, 0, &success);
7313 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7314 offset =
Shift(R[m], shift_t, shift_n, APSR.C);
7315 offset_addr =
if add then (R[n] + offset)
else (R[n] - offset);
7316 address =
if index then offset_addr
else R[n];
7317 data = MemU[address,2];
7318 if wback then R[n] = offset_addr;
7320 R[t] = ZeroExtend(data, 32);
7322 R[t] =
bits(32) UNKNOWN;
7325 bool success =
false;
7343 t =
Bits32(opcode, 2, 0);
7344 n =
Bits32(opcode, 5, 3);
7345 m =
Bits32(opcode, 8, 6);
7362 t =
Bits32(opcode, 15, 12);
7363 n =
Bits32(opcode, 19, 16);
7364 m =
Bits32(opcode, 3, 0);
7373 shift_n =
Bits32(opcode, 5, 4);
7376 if ((t == 13) ||
BadReg(m))
7383 t =
Bits32(opcode, 15, 12);
7384 n =
Bits32(opcode, 19, 16);
7385 m =
Bits32(opcode, 3, 0);
7398 if ((t == 15) || (m == 15))
7402 if (wback && ((n == 15) || (n == t)))
7432 offset_addr = Rn + offset;
7434 offset_addr = Rn - offset;
7438 address = offset_addr;
7443 std::optional<RegisterInfo> base_reg =
7445 std::optional<RegisterInfo> offset_reg =
7451 uint64_t data =
MemURead(context, address, 2, 0, &success);
7489 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7490 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
7491 address =
if index then offset_addr
else R[n];
7492 R[t] = SignExtend(MemU[address,1], 32);
7493 if wback then R[n] = offset_addr;
7496 bool success =
false;
7512 t =
Bits32(opcode, 15, 12);
7513 n =
Bits32(opcode, 19, 16);
7514 imm32 =
Bits32(opcode, 11, 0);
7536 t =
Bits32(opcode, 15, 12);
7537 n =
Bits32(opcode, 19, 16);
7538 imm32 =
Bits32(opcode, 7, 0);
7549 (wback && (n == t)))
7558 t =
Bits32(opcode, 15, 12);
7559 n =
Bits32(opcode, 19, 16);
7561 uint32_t imm4H =
Bits32(opcode, 11, 8);
7562 uint32_t imm4L =
Bits32(opcode, 3, 0);
7563 imm32 = (imm4H << 4) | imm4L;
7572 if ((t == 15) || (wback && (n == t)))
7591 offset_addr = Rn + imm32;
7593 offset_addr = Rn - imm32;
7597 address = offset_addr;
7602 std::optional<RegisterInfo> base_reg =
7609 uint64_t unsigned_data =
MemURead(context, address, 1, 0, &success);
7613 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7615 (uint64_t)signed_data))
7638 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7640 address =
if add then (base + imm32)
else (base - imm32);
7641 R[t] = SignExtend(MemU[address,1], 32);
7644 bool success =
false;
7656 t =
Bits32(opcode, 15, 12);
7657 imm32 =
Bits32(opcode, 11, 0);
7668 t =
Bits32(opcode, 15, 12);
7669 uint32_t imm4H =
Bits32(opcode, 11, 8);
7670 uint32_t imm4L =
Bits32(opcode, 3, 0);
7671 imm32 = (imm4H << 4) | imm4L;
7689 uint64_t base =
AlignPC(pc_value);
7694 address = base + imm32;
7696 address = base - imm32;
7699 std::optional<RegisterInfo> base_reg =
7706 uint64_t unsigned_data =
MemURead(context, address, 1, 0, &success);
7710 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7712 (uint64_t)signed_data))
7726 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7727 offset =
Shift(R[m], shift_t, shift_n, APSR.C);
7728 offset_addr =
if add then (R[n] + offset)
else (R[n] - offset);
7729 address =
if index then offset_addr
else R[n];
7730 R[t] = SignExtend(MemU[address,1], 32);
7731 if wback then R[n] = offset_addr;
7734 bool success =
false;
7750 t =
Bits32(opcode, 2, 0);
7751 n =
Bits32(opcode, 5, 3);
7752 m =
Bits32(opcode, 8, 6);
7769 t =
Bits32(opcode, 15, 12);
7770 n =
Bits32(opcode, 19, 16);
7771 m =
Bits32(opcode, 3, 0);
7780 shift_n =
Bits32(opcode, 5, 4);
7783 if ((t == 13) ||
BadReg(m))
7790 t =
Bits32(opcode, 15, 12);
7791 n =
Bits32(opcode, 19, 16);
7792 m =
Bits32(opcode, 3, 0);
7805 if ((t == 15) || (m == 15))
7809 if (wback && ((n == 15) || (n == t)))
7837 offset_addr = Rn + offset;
7839 offset_addr = Rn - offset;
7843 address = offset_addr;
7848 std::optional<RegisterInfo> base_reg =
7850 std::optional<RegisterInfo> offset_reg =
7857 uint64_t unsigned_data =
MemURead(context, address, 1, 0, &success);
7861 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7863 (uint64_t)signed_data))
7886 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7887 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
7888 address =
if index then offset_addr
else R[n];
7889 data = MemU[address,2];
7890 if wback then R[n] = offset_addr;
7892 R[t] = SignExtend(data, 32);
7894 R[t] =
bits(32) UNKNOWN;
7897 bool success =
false;
7913 t =
Bits32(opcode, 15, 12);
7914 n =
Bits32(opcode, 19, 16);
7915 imm32 =
Bits32(opcode, 11, 0);
7938 t =
Bits32(opcode, 15, 12);
7939 n =
Bits32(opcode, 19, 16);
7940 imm32 =
Bits32(opcode, 7, 0);
7948 if (
BadReg(t) || (wback && (n == t)))
7957 t =
Bits32(opcode, 15, 12);
7958 n =
Bits32(opcode, 19, 16);
7959 uint32_t imm4H =
Bits32(opcode, 11, 8);
7960 uint32_t imm4L =
Bits32(opcode, 3, 0);
7961 imm32 = (imm4H << 4) | imm4L;
7970 if ((t == 15) || (wback && (n == t)))
7988 offset_addr = Rn + imm32;
7990 offset_addr = Rn - imm32;
7995 address = offset_addr;
8000 std::optional<RegisterInfo> base_reg =
8007 uint64_t data =
MemURead(context, address, 2, 0, &success);
8023 int64_t signed_data = llvm::SignExtend64<16>(data);
8027 (uint64_t)signed_data))
8045 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8047 address =
if add then (base + imm32)
else (base - imm32);
8048 data = MemU[address,2];
8050 R[t] = SignExtend(data, 32);
8052 R[t] =
bits(32) UNKNOWN;
8055 bool success =
false;
8067 t =
Bits32(opcode, 15, 12);
8068 imm32 =
Bits32(opcode, 11, 0);
8079 t =
Bits32(opcode, 15, 12);
8080 uint32_t imm4H =
Bits32(opcode, 11, 8);
8081 uint32_t imm4L =
Bits32(opcode, 3, 0);
8082 imm32 = (imm4H << 4) | imm4L;
8100 uint64_t base =
AlignPC(pc_value);
8105 address = base + imm32;
8107 address = base - imm32;
8110 std::optional<RegisterInfo> base_reg =
8117 uint64_t data =
MemURead(context, address, 2, 0, &success);
8124 int64_t signed_data = llvm::SignExtend64<16>(data);
8126 (uint64_t)signed_data))
8146 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8147 offset =
Shift(R[m], shift_t, shift_n, APSR.C);
8148 offset_addr =
if add then (R[n] + offset)
else (R[n] - offset);
8149 address =
if index then offset_addr
else R[n];
8150 data = MemU[address,2];
8151 if wback then R[n] = offset_addr;
8153 R[t] = SignExtend(data, 32);
8155 R[t] =
bits(32) UNKNOWN;
8158 bool success =
false;
8176 t =
Bits32(opcode, 2, 0);
8177 n =
Bits32(opcode, 5, 3);
8178 m =
Bits32(opcode, 8, 6);
8195 t =
Bits32(opcode, 15, 12);
8196 n =
Bits32(opcode, 19, 16);
8197 m =
Bits32(opcode, 3, 0);
8206 shift_n =
Bits32(opcode, 5, 4);
8209 if ((t == 13) ||
BadReg(m))
8217 t =
Bits32(opcode, 15, 12);
8218 n =
Bits32(opcode, 19, 16);
8219 m =
Bits32(opcode, 3, 0);
8232 if ((t == 15) || (m == 15))
8236 if (wback && ((n == 15) || (n == t)))
8265 offset_addr = Rn + offset;
8267 offset_addr = Rn - offset;
8271 address = offset_addr;
8276 std::optional<RegisterInfo> base_reg =
8278 std::optional<RegisterInfo> offset_reg =
8285 uint64_t data =
MemURead(context, address, 2, 0, &success);
8304 int64_t signed_data = llvm::SignExtend64<16>(data);
8306 (uint64_t)signed_data))
8325 EncodingSpecificOperations();
8326 rotated =
ROR(R[m], rotation);
8327 R[d] = SignExtend(rotated<7:0>, 32);
8330 bool success =
false;
8341 d =
Bits32(opcode, 2, 0);
8342 m =
Bits32(opcode, 5, 3);
8349 d =
Bits32(opcode, 11, 8);
8350 m =
Bits32(opcode, 3, 0);
8351 rotation =
Bits32(opcode, 5, 4) << 3;
8361 d =
Bits32(opcode, 15, 12);
8362 m =
Bits32(opcode, 3, 0);
8363 rotation =
Bits32(opcode, 11, 10) << 3;
8366 if ((d == 15) || (m == 15))
8381 uint64_t rotated =
ROR(Rm, rotation, &success);
8386 int64_t data = llvm::SignExtend64<8>(rotated);
8388 std::optional<RegisterInfo> source_reg =
8410 EncodingSpecificOperations();
8411 rotated =
ROR(R[m], rotation);
8412 R[d] = SignExtend(rotated<15:0>, 32);
8415 bool success =
false;
8426 d =
Bits32(opcode, 2, 0);
8427 m =
Bits32(opcode, 5, 3);
8434 d =
Bits32(opcode, 11, 8);
8435 m =
Bits32(opcode, 3, 0);
8436 rotation =
Bits32(opcode, 5, 4) << 3;
8446 d =
Bits32(opcode, 15, 12);
8447 m =
Bits32(opcode, 3, 0);
8448 rotation =
Bits32(opcode, 11, 10) << 3;
8451 if ((d == 15) || (m == 15))
8466 uint64_t rotated =
ROR(Rm, rotation, &success);
8471 std::optional<RegisterInfo> source_reg =
8478 int64_t data = llvm::SignExtend64<16>(rotated);
8495 EncodingSpecificOperations();
8496 rotated =
ROR(R[m], rotation);
8497 R[d] = ZeroExtend(rotated<7:0>, 32);
8500 bool success =
false;
8511 d =
Bits32(opcode, 2, 0);
8512 m =
Bits32(opcode, 5, 3);
8519 d =
Bits32(opcode, 11, 8);
8520 m =
Bits32(opcode, 3, 0);
8521 rotation =
Bits32(opcode, 5, 4) << 3;
8531 d =
Bits32(opcode, 15, 12);
8532 m =
Bits32(opcode, 3, 0);
8533 rotation =
Bits32(opcode, 11, 10) << 3;
8536 if ((d == 15) || (m == 15))
8551 uint64_t rotated =
ROR(Rm, rotation, &success);
8556 std::optional<RegisterInfo> source_reg =
8578 EncodingSpecificOperations();
8579 rotated =
ROR(R[m], rotation);
8580 R[d] = ZeroExtend(rotated<15:0>, 32);
8583 bool success =
false;
8593 d =
Bits32(opcode, 2, 0);
8594 m =
Bits32(opcode, 5, 3);
8601 d =
Bits32(opcode, 11, 8);
8602 m =
Bits32(opcode, 3, 0);
8603 rotation =
Bits32(opcode, 5, 4) << 3;
8613 d =
Bits32(opcode, 15, 12);
8614 m =
Bits32(opcode, 3, 0);
8615 rotation =
Bits32(opcode, 11, 10) << 3;
8618 if ((d == 15) || (m == 15))
8633 uint64_t rotated =
ROR(Rm, rotation, &success);
8638 std::optional<RegisterInfo> source_reg =
8659 EncodingSpecificOperations();
8663 address =
if increment then R[n]
else R[n]-8;
8664 if wordhigher then address = address+4;
8667 if wback then R[n] =
if increment then R[n]+8
else R[n]-8;
8670 bool success =
false;
8683 n =
Bits32(opcode, 19, 16);
8700 n =
Bits32(opcode, 19, 16);
8717 n =
Bits32(opcode, 19, 16);
8722 wordhigher = (
Bit32(opcode, 24) ==
Bit32(opcode, 23));
8754 address = address + 4;
8757 std::optional<RegisterInfo> base_reg =
8764 uint64_t data =
MemARead(context, address + 4, 4, 0, &success);
8771 uint64_t data2 =
MemARead(context, address, 4, 0, &success);
8806 EncodingSpecificOperations();
8807 result = R[n] EOR imm32;
8813 APSR.N = result<31>;
8814 APSR.Z = IsZeroBit(result);
8819 bool success =
false;
8830 Rn =
Bits32(opcode, 19, 16);
8836 if (
Rd == 15 && setflags)
8838 if (
Rd == 13 || (
Rd == 15 && !setflags) ||
BadReg(Rn))
8843 Rn =
Bits32(opcode, 19, 16);
8851 if (
Rd == 15 && setflags)
8863 uint32_t result = val1 ^ imm32;
8884 EncodingSpecificOperations();
8885 (shifted, carry) =
Shift_C(R[m], shift_t, shift_n, APSR.C);
8886 result = R[n] EOR shifted;
8892 APSR.N = result<31>;
8893 APSR.Z = IsZeroBit(result);
8898 bool success =
false;
8901 uint32_t
Rd, Rn, Rm;
8909 Rm =
Bits32(opcode, 5, 3);
8916 Rn =
Bits32(opcode, 19, 16);
8917 Rm =
Bits32(opcode, 3, 0);
8921 if (
Rd == 15 && setflags)
8928 Rn =
Bits32(opcode, 19, 16);
8929 Rm =
Bits32(opcode, 3, 0);
8935 if (
Rd == 15 && setflags)
8952 uint32_t shifted =
Shift_C(val2, shift_t, shift_n,
APSR_C, carry, &success);
8955 uint32_t result = val1 ^ shifted;
8975 EncodingSpecificOperations();
8976 result = R[n] OR imm32;
8982 APSR.N = result<31>;
8983 APSR.Z = IsZeroBit(result);
8988 bool success =
false;
8999 Rn =
Bits32(opcode, 19, 16);
9012 Rn =
Bits32(opcode, 19, 16);
9018 if (
Rd == 15 && setflags)
9030 uint32_t result = val1 | imm32;
9051 EncodingSpecificOperations();
9052 (shifted, carry) =
Shift_C(R[m], shift_t, shift_n, APSR.C);
9053 result = R[n] OR shifted;
9059 APSR.N = result<31>;
9060 APSR.Z = IsZeroBit(result);
9065 bool success =
false;
9068 uint32_t
Rd, Rn, Rm;
9076 Rm =
Bits32(opcode, 5, 3);
9083 Rn =
Bits32(opcode, 19, 16);
9084 Rm =
Bits32(opcode, 3, 0);
9095 Rn =
Bits32(opcode, 19, 16);
9096 Rm =
Bits32(opcode, 3, 0);
9100 if (
Rd == 15 && setflags)
9117 uint32_t shifted =
Shift_C(val2, shift_t, shift_n,
APSR_C, carry, &success);
9120 uint32_t result = val1 | shifted;
9140 EncodingSpecificOperations();
9147 APSR.N = result<31>;
9148 APSR.Z = IsZeroBit(result);
9153 bool success =
false;
9163 Rn =
Bits32(opcode, 5, 3);
9169 Rn =
Bits32(opcode, 19, 16);
9177 Rn =
Bits32(opcode, 19, 16);
9183 if (
Rd == 15 && setflags)
9212 EncodingSpecificOperations();
9213 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
9220 APSR.N = result<31>;
9221 APSR.Z = IsZeroBit(result);
9226 bool success =
false;
9237 Rn =
Bits32(opcode, 19, 16);
9238 Rm =
Bits32(opcode, 3, 0);
9247 Rn =
Bits32(opcode, 19, 16);
9248 Rm =
Bits32(opcode, 3, 0);
9254 if (
Rd == 15 && setflags)
9270 uint32_t shifted =
Shift(val2, shift_t, shift_n,
APSR_C, &success);
9291 EncodingSpecificOperations();
9298 APSR.N = result<31>;
9299 APSR.Z = IsZeroBit(result);
9304 bool success =
false;
9314 Rn =
Bits32(opcode, 19, 16);
9320 if (
Rd == 15 && setflags)
9350 EncodingSpecificOperations();
9351 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
9358 APSR.N = result<31>;
9359 APSR.Z = IsZeroBit(result);
9364 bool success =
false;
9375 Rn =
Bits32(opcode, 19, 16);
9376 Rm =
Bits32(opcode, 3, 0);
9382 if (
Rd == 15 && setflags)
9398 uint32_t shifted =
Shift(val2, shift_t, shift_n,
APSR_C, &success);
9420 EncodingSpecificOperations();
9427 APSR.N = result<31>;
9428 APSR.Z = IsZeroBit(result);
9433 bool success =
false;
9443 Rn =
Bits32(opcode, 19, 16);
9451 Rn =
Bits32(opcode, 19, 16);
9457 if (
Rd == 15 && setflags)
9488 EncodingSpecificOperations();
9489 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
9496 APSR.N = result<31>;
9497 APSR.Z = IsZeroBit(result);
9502 bool success =
false;
9513 Rm =
Bits32(opcode, 5, 3);
9520 Rn =
Bits32(opcode, 19, 16);
9521 Rm =
Bits32(opcode, 3, 0);
9529 Rn =
Bits32(opcode, 19, 16);
9530 Rm =
Bits32(opcode, 3, 0);
9536 if (
Rd == 15 && setflags)
9552 uint32_t shifted =
Shift(val2, shift_t, shift_n,
APSR_C, &success);
9572 EncodingSpecificOperations();
9576 APSR.N = result<31>;
9577 APSR.Z = IsZeroBit(result);
9582 bool success =
false;
9592 Rn =
Bits32(opcode, 5, 3);
9594 imm32 =
Bits32(opcode, 8, 6);
9599 imm32 =
Bits32(opcode, 7, 0);
9603 Rn =
Bits32(opcode, 19, 16);
9608 if (
Rd == 15 && setflags)
9616 if (
Rd == 13 || (
Rd == 15 && !setflags) || Rn == 15)
9621 Rn =
Bits32(opcode, 19, 16);
9662 EncodingSpecificOperations();
9669 APSR.N = result<31>;
9670 APSR.Z = IsZeroBit(result);
9675 bool success =
false;
9686 Rn =
Bits32(opcode, 19, 16);
9691 if (Rn == 15 && !setflags)
9700 if (
Rd == 15 && setflags)
9719 std::optional<RegisterInfo> dwarf_reg =
9721 int64_t imm32_signed = imm32;
9739 EncodingSpecificOperations();
9740 result = R[n] EOR imm32;
9741 APSR.N = result<31>;
9742 APSR.Z = IsZeroBit(result);
9747 bool success =
false;
9756 Rn =
Bits32(opcode, 19, 16);
9764 Rn =
Bits32(opcode, 19, 16);
9778 uint32_t result = val1 ^ imm32;
9798 EncodingSpecificOperations();
9799 (shifted, carry) =
Shift_C(R[m], shift_t, shift_n, APSR.C);
9800 result = R[n] EOR shifted;
9801 APSR.N = result<31>;
9802 APSR.Z = IsZeroBit(result);
9807 bool success =
false;
9816 Rn =
Bits32(opcode, 19, 16);
9817 Rm =
Bits32(opcode, 3, 0);
9823 Rn =
Bits32(opcode, 19, 16);
9824 Rm =
Bits32(opcode, 3, 0);
9841 uint32_t shifted =
Shift_C(val2, shift_t, shift_n,
APSR_C, carry, &success);
9844 uint32_t result = val1 ^ shifted;
9864 EncodingSpecificOperations();
9865 result = R[n] AND imm32;
9866 APSR.N = result<31>;
9867 APSR.Z = IsZeroBit(result);
9872 bool success =
false;
9881 Rn =
Bits32(opcode, 19, 16);
9889 Rn =
Bits32(opcode, 19, 16);
9903 uint32_t result = val1 & imm32;
9923 EncodingSpecificOperations();
9924 (shifted, carry) =
Shift_C(R[m], shift_t, shift_n, APSR.C);
9925 result = R[n] AND shifted;
9926 APSR.N = result<31>;
9927 APSR.Z = IsZeroBit(result);
9932 bool success =
false;
9941 Rn =
Bits32(opcode, 2, 0);
9942 Rm =
Bits32(opcode, 5, 3);
9947 Rn =
Bits32(opcode, 19, 16);
9948 Rm =
Bits32(opcode, 3, 0);
9954 Rn =
Bits32(opcode, 19, 16);
9955 Rm =
Bits32(opcode, 3, 0);
9972 uint32_t shifted =
Shift_C(val2, shift_t, shift_n,
APSR_C, carry, &success);
9975 uint32_t result = val1 & shifted;
9992 EncodingSpecificOperations();
9993 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
10000 APSR.N = result<31>;
10001 APSR.Z = IsZeroBit(result);
10006 bool success =
false;
10015 switch (encoding) {
10018 d =
Bits32(opcode, 11, 8);
10019 m =
Bits32(opcode, 3, 0);
10027 if ((d == 13) && ((shift_t !=
SRType_LSL) || (shift_n > 3)))
10031 if ((d == 15) ||
BadReg(m))
10037 d =
Bits32(opcode, 15, 12);
10038 m =
Bits32(opcode, 3, 0);
10043 if (d == 15 && setflags)
10059 uint32_t shifted =
Shift(Rm, shift_t, shift_n,
APSR_C, &success);
10072 std::optional<RegisterInfo> sp_reg =
10074 std::optional<RegisterInfo> dwarf_reg =
10090 EncodingSpecificOperations();
10091 shift_n =
UInt(R[s]<7:0>);
10092 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
10093 (result, carry, overflow) =
AddWithCarry(R[n], shifted,
'0');
10096 APSR.N = result<31>;
10097 APSR.Z = IsZeroBit(result);
10102 bool success =
false;
10112 switch (encoding) {
10115 d =
Bits32(opcode, 15, 12);
10116 n =
Bits32(opcode, 19, 16);
10117 m =
Bits32(opcode, 3, 0);
10118 s =
Bits32(opcode, 11, 8);
10125 if ((d == 15) || (n == 15) || (m == 15) || (s == 15))
10138 uint32_t shift_n =
Bits32(
Rs, 7, 0);
10145 uint32_t shifted =
Shift(Rm, shift_t, shift_n,
APSR_C, &success);
10159 std::optional<RegisterInfo> reg_n =
10161 std::optional<RegisterInfo> reg_m =
10186 EncodingSpecificOperations();
10187 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
10194 APSR.N = result<31>;
10195 APSR.Z = IsZeroBit(result);
10200 bool success =
false;
10210 switch (encoding) {
10213 d =
Bits32(opcode, 2, 0);
10214 n =
Bits32(opcode, 5, 3);
10215 m =
Bits32(opcode, 8, 6);
10226 d =
Bits32(opcode, 11, 8);
10227 n =
Bits32(opcode, 19, 16);
10228 m =
Bits32(opcode, 3, 0);
10232 if (d == 15 && setflags == 1)
10244 if ((d == 13) || ((d == 15) &&
BitIsClear(opcode, 20)) || (n == 15) ||
10253 d =
Bits32(opcode, 15, 12);
10254 n =
Bits32(opcode, 19, 16);
10255 m =
Bits32(opcode, 3, 0);
10260 if ((d == 15) && setflags)
10277 uint32_t shifted =
Shift(Rm, shift_t, shift_n,
APSR_C, &success);
10299 std::optional<RegisterInfo> reg_n =
10301 std::optional<RegisterInfo> reg_m =
10320 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10321 address = R[n] + imm32;
10322 if ExclusiveMonitorsPass(address,4) then
10323 MemA[address,4] = R[t];
10329 bool success =
false;
10338 switch (encoding) {
10343 d =
Bits32(opcode, 11, 8);
10344 t =
Bits32(opcode, 15, 12);
10345 n =
Bits32(opcode, 19, 16);
10346 imm32 =
Bits32(opcode, 7, 0) << 2;
10353 if ((d == n) || (d == t))
10361 d =
Bits32(opcode, 15, 12);
10362 t =
Bits32(opcode, 3, 0);
10363 n =
Bits32(opcode, 19, 16);
10367 if ((d == 15) || (t == 15) || (n == 15))
10371 if ((d == n) || (d == t))
10385 addr_t address = Rn + imm32;
10387 std::optional<RegisterInfo> base_reg =
10389 std::optional<RegisterInfo> data_reg =
10407 if (!
MemAWrite(context, address, Rt, addr_byte_size))
10431 EncodingSpecificOperations();
10432 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
10433 address =
if index then offset_addr
else R[n];
10434 MemU[address,1] = R[t]<7:0>;
10435 if wback then R[n] = offset_addr;
10438 bool success =
false;
10448 switch (encoding) {
10452 t =
Bits32(opcode, 15, 12);
10453 n =
Bits32(opcode, 19, 16);
10454 imm32 =
Bits32(opcode, 11, 0);
10466 if (wback && ((n == 15) || (n == t)))
10482 offset_addr = Rn + imm32;
10484 offset_addr = Rn - imm32;
10489 address = offset_addr;
10498 std::optional<RegisterInfo> base_reg =
10500 std::optional<RegisterInfo> data_reg =
10524 EncodingSpecificOperations();
10525 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
10526 address =
if index then offset_addr
else R[n];
10527 MemU[address,4] =
if t == 15 then PCStoreValue()
else R[t];
10528 if wback then R[n] = offset_addr;
10531 bool success =
false;
10543 switch (encoding) {
10549 t =
Bits32(opcode, 15, 12);
10550 n =
Bits32(opcode, 19, 16);
10551 imm32 =
Bits32(opcode, 11, 0);
10559 if (wback && ((n == 15) || (n == t)))
10575 offset_addr = Rn + imm32;
10577 offset_addr = Rn - imm32;
10582 address = offset_addr;
10586 std::optional<RegisterInfo> base_reg =
10588 std::optional<RegisterInfo> data_reg =
10604 if (!
MemUWrite(context, address, pc_value, addr_byte_size))
10607 if (!
MemUWrite(context, address, Rt, addr_byte_size))
10633 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10634 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
10635 address =
if index then offset_addr
else R[n];
10636 R[t] = MemA[address,4];
10637 R[t2] = MemA[address+4,4];
10638 if wback then R[n] = offset_addr;
10641 bool success =
false;
10652 switch (encoding) {
10658 t =
Bits32(opcode, 15, 12);
10659 t2 =
Bits32(opcode, 11, 8);
10660 n =
Bits32(opcode, 19, 16);
10661 imm32 =
Bits32(opcode, 7, 0) << 2;
10669 if (wback && ((n == t) || (n == t2)))
10683 t =
Bits32(opcode, 15, 12);
10687 n =
Bits32(opcode, 19, 16);
10688 imm32 = (
Bits32(opcode, 11, 8) << 4) |
Bits32(opcode, 3, 0);
10700 if (wback && ((n == t) || (n == t2)))
10720 offset_addr = Rn + imm32;
10722 offset_addr = Rn - imm32;
10727 address = offset_addr;
10741 uint32_t data =
MemARead(context, address, addr_byte_size, 0, &success);
10750 data =
MemARead(context, address + 4, addr_byte_size, 0, &success);
10779 EncodingSpecificOperations();
10780 offset_addr =
if add then (R[n] + R[m])
else (R[n] - R[m]);
10781 address =
if index then offset_addr
else R[n];
10782 R[t] = MemA[address,4];
10783 R[t2] = MemA[address+4,4];
10784 if wback then R[n] = offset_addr;
10787 bool success =
false;
10798 switch (encoding) {
10802 t =
Bits32(opcode, 15, 12);
10806 n =
Bits32(opcode, 19, 16);
10807 m =
Bits32(opcode, 3, 0);
10819 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10823 if (wback && ((n == 15) || (n == t) || (n == t2)))
10846 offset_addr = Rn + Rm;
10848 offset_addr = Rn - Rm;
10853 address = offset_addr;
10866 uint32_t data =
MemARead(context, address, addr_byte_size, 0, &success);
10875 data =
MemARead(context, address + 4, addr_byte_size, 0, &success);
10904 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10905 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
10906 address =
if index then offset_addr
else R[n];
10907 MemA[address,4] = R[t];
10908 MemA[address+4,4] = R[t2];
10909 if wback then R[n] = offset_addr;
10912 bool success =
false;
10923 switch (encoding) {
10928 t =
Bits32(opcode, 15, 12);
10929 t2 =
Bits32(opcode, 11, 8);
10930 n =
Bits32(opcode, 19, 16);
10931 imm32 =
Bits32(opcode, 7, 0) << 2;
10939 if (wback && ((n == t) || (n == t2)))
10952 t =
Bits32(opcode, 15, 12);
10957 n =
Bits32(opcode, 19, 16);
10958 imm32 = (
Bits32(opcode, 11, 8) << 4) |
Bits32(opcode, 3, 0);
10970 if (wback && ((n == 15) || (n == t) || (n == t2)))
10983 std::optional<RegisterInfo> base_reg =
10993 offset_addr = Rn + imm32;
10995 offset_addr = Rn - imm32;
11000 address = offset_addr;
11005 std::optional<RegisterInfo> data_reg =
11021 if (!
MemAWrite(context, address, data, addr_byte_size))
11027 (address + 4) - Rn);
11033 if (!
MemAWrite(context, address + 4, data, addr_byte_size))
11057 EncodingSpecificOperations();
11058 offset_addr =
if add then (R[n] + R[m])
else (R[n] - R[m]);
11059 address =
if index then offset_addr
else R[n];
11060 MemA[address,4] = R[t];
11061 MemA[address+4,4] = R[t2];
11062 if wback then R[n] = offset_addr;
11065 bool success =
false;
11076 switch (encoding) {
11080 t =
Bits32(opcode, 15, 12);
11085 n =
Bits32(opcode, 19, 16);
11086 m =
Bits32(opcode, 3, 0);
11098 if ((t2 == 15) || (m == 15))
11102 if (wback && ((n == 15) || (n == t) || (n == t2)))
11126 offset_addr = Rn + Rm;
11128 offset_addr = Rn - Rm;
11133 address = offset_addr;
11147 std::optional<RegisterInfo> base_reg =
11149 std::optional<RegisterInfo> offset_reg =
11151 std::optional<RegisterInfo> data_reg =
11158 if (!
MemAWrite(context, address, Rt, addr_byte_size))
11171 if (!
MemAWrite(context, address + 4, Rt2, addr_byte_size))
11194 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11195 address =
if add then R[n]
else R[n]-imm32;
11196 if wback then R[n] =
if add then R[n]+imm32
else R[n]-imm32;
11197 for r = 0 to regs-1
11198 if single_regs then
11199 S[d+r] = MemA[address,4]; address = address+4;
11201 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11204 D[d+r] =
if BigEndian() then word1:word2
else word2:word1;
11207 bool success =
false;
11218 switch (encoding) {
11231 single_regs =
false;
11236 d = (
Bit32(opcode, 22) << 4) |
Bits32(opcode, 15, 12);
11237 n =
Bits32(opcode, 19, 16);
11238 imm32 =
Bits32(opcode, 7, 0) << 2;
11241 regs =
Bits32(opcode, 7, 0) / 2;
11249 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11267 single_regs =
true;
11270 d = (
Bits32(opcode, 15, 12) << 1) |
Bit32(opcode, 22);
11271 n =
Bits32(opcode, 19, 16);
11274 imm32 =
Bits32(opcode, 7, 0) << 2;
11275 regs =
Bits32(opcode, 7, 0);
11283 if ((regs == 0) || ((d + regs) > 32))
11300 address = Rn - imm32;
11308 value = Rn + imm32;
11310 value = Rn - imm32;
11324 std::optional<RegisterInfo> base_reg =
11328 for (uint32_t r = 0; r < regs; ++r) {
11333 uint32_t data =
MemARead(context, address, addr_byte_size, 0, &success);
11338 start_reg + d + r, data))
11341 address = address + 4;
11347 MemARead(context, address, addr_byte_size, 0, &success);
11353 MemARead(context, address + 4, addr_byte_size, 0, &success);
11357 address = address + 8;
11364 data = (data << 32) | word2;
11367 data = (data << 32) | word1;
11371 start_reg + d + r, data))
11387 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11388 address =
if add then R[n]
else R[n]-imm32;
11389 if wback then R[n] =
if add then R[n]+imm32
else R[n]-imm32;
11390 for r = 0 to regs-1
11391 if single_regs then
11392 MemA[address,4] = S[d+r]; address = address+4;
11396 MemA[address,4] =
if BigEndian() then D[d+r]<63:32>
else D[d+r]<31:0>;
11397 MemA[address+4,4] =
if BigEndian() then D[d+r]<31:0>
else D[d+r]<63:32>;
11398 address = address+8;
11401 bool success =
false;
11412 switch (encoding) {
11425 single_regs =
false;
11430 d = (
Bit32(opcode, 22) << 4) |
Bits32(opcode, 15, 12);
11431 n =
Bits32(opcode, 19, 16);
11432 imm32 =
Bits32(opcode, 7, 0) << 2;
11435 regs =
Bits32(opcode, 7, 0) / 2;
11443 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11461 single_regs =
true;
11464 d = (
Bits32(opcode, 15, 12) << 1) |
Bit32(opcode, 22);
11465 n =
Bits32(opcode, 19, 16);
11468 imm32 =
Bits32(opcode, 7, 0) << 2;
11469 regs =
Bits32(opcode, 7, 0);
11477 if ((regs == 0) || ((d + regs) > 32))
11486 std::optional<RegisterInfo> base_reg =
11498 address = Rn - imm32;
11505 value = Rn + imm32;
11507 value = Rn - imm32;
11522 for (uint32_t r = 0; r < regs; ++r) {
11527 start_reg + d + r, 0, &success);
11531 std::optional<RegisterInfo> data_reg =
11535 if (!
MemAWrite(context, address, data, addr_byte_size))
11538 address = address + 4;
11546 start_reg + d + r, 0, &success);
11550 std::optional<RegisterInfo> data_reg =
11561 (address + 4) - Rn);
11568 if (!
MemAWrite(context, address,
Bits64(data, 31, 0), addr_byte_size))
11572 (address + 4) - Rn);
11578 address = address + 8;
11592 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11593 base =
if n == 15 then
Align(PC,4)
else R[n];
11594 address =
if add then (base + imm32)
else (base - imm32);
11596 S[d] = MemA[address,4];
11598 word1 = MemA[address,4]; word2 = MemA[address+4,4];
11601 D[d] =
if BigEndian() then word1:word2
else word2:word1;
11604 bool success =
false;
11613 switch (encoding) {
11618 single_reg =
false;
11620 imm32 =
Bits32(opcode, 7, 0) << 2;
11623 d = (
Bit32(opcode, 22) << 4) |
Bits32(opcode, 15, 12);
11624 n =
Bits32(opcode, 19, 16);
11633 imm32 =
Bits32(opcode, 7, 0) << 2;
11636 d = (
Bits32(opcode, 15, 12) << 1) |
Bit32(opcode, 22);
11637 n =
Bits32(opcode, 19, 16);
11644 std::optional<RegisterInfo> base_reg =
11661 address = base + imm32;
11663 address = base - imm32;
11674 uint32_t data =
MemARead(context, address, addr_byte_size, 0, &success);
11683 uint32_t word1 =
MemARead(context, address, addr_byte_size, 0, &success);
11689 MemARead(context, address + 4, addr_byte_size, 0, &success);
11698 data64 = (data64 << 32) | word2;
11701 data64 = (data64 << 32) | word1;
11719 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11720 address =
if add then (R[n] + imm32)
else (R[n] - imm32);
11722 MemA[address,4] = S[d];
11726 MemA[address,4] =
if BigEndian() then D[d]<63:32>
else D[d]<31:0>;
11727 MemA[address+4,4] =
if BigEndian() then D[d]<31:0>
else D[d]<63:32>;
11730 bool success =
false;
11739 switch (encoding) {
11744 single_reg =
false;
11746 imm32 =
Bits32(opcode, 7, 0) << 2;
11749 d = (
Bit32(opcode, 22) << 4) |
Bits32(opcode, 15, 12);
11750 n =
Bits32(opcode, 19, 16);
11763 imm32 =
Bits32(opcode, 7, 0) << 2;
11766 d = (
Bits32(opcode, 15, 12) << 1) |
Bit32(opcode, 22);
11767 n =
Bits32(opcode, 19, 16);
11786 address = Rn + imm32;
11788 address = Rn - imm32;
11793 std::optional<RegisterInfo> base_reg =
11795 std::optional<RegisterInfo> data_reg =
11808 if (!
MemAWrite(context, address, data, addr_byte_size))
11821 if (!
MemAWrite(context, address,
Bits64(data, 63, 32), addr_byte_size))
11825 (address + 4) - Rn);
11830 if (!
MemAWrite(context, address,
Bits64(data, 31, 0), addr_byte_size))
11834 (address + 4) - Rn);
11851 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11852 address = R[n];
if (address MOD alignment) != 0 then GenerateAlignmentException();
11853 if wback then R[n] = R[n] + (
if register_index then R[m]
else 8*regs);
11854 for r = 0 to regs-1
11855 for e = 0 to elements-1
11856 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11857 address = address + ebytes;
11860 bool success =
false;
11864 uint32_t alignment;
11872 bool register_index;
11874 switch (encoding) {
11888 uint32_t type =
Bits32(opcode, 11, 8);
11889 uint32_t align =
Bits32(opcode, 5, 4);
11895 }
else if (type == 10)
11901 }
else if (type == 6)
11906 }
else if (type == 2)
11916 alignment = 4 << align;
11919 ebytes = 1 <<
Bits32(opcode, 7, 6);
11920 esize = 8 * ebytes;
11921 elements = 8 / ebytes;
11924 d = (
Bit32(opcode, 22) << 4) |
Bits32(opcode, 15, 12);
11925 n =
Bits32(opcode, 19, 15);
11926 m =
Bits32(opcode, 3, 0);
11930 register_index = ((m != 15) && (m != 13));
11933 if ((d + regs) > 32)
11941 std::optional<RegisterInfo> base_reg =
11951 if ((address % alignment) != 0)
11962 if (register_index)
11967 uint32_t value = Rn + offset;
11977 for (uint32_t r = 0; r < regs; ++r) {
11979 uint64_t assembled_data = 0;
11980 for (uint32_t e = 0; e < elements; ++e) {
11984 uint64_t data =
MemURead(context, address, ebytes, 0, &success);
11989 (data << (e * esize)) |
11993 address = address + ebytes;
12009 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12010 address = R[n];
if (address MOD alignment) != 0 then GenerateAlignmentException();
12011 if wback then R[n] = R[n] + (
if register_index then R[m]
else ebytes);
12012 Elem[D[d],index,esize] = MemU[address,ebytes];
12015 bool success =
false;
12021 uint32_t alignment;
12026 bool register_index;
12028 switch (encoding) {
12031 uint32_t size =
Bits32(opcode, 11, 10);
12032 uint32_t index_align =
Bits32(opcode, 7, 4);
12046 index =
Bits32(index_align, 3, 1);
12048 }
else if (size == 1)
12057 index =
Bits32(index_align, 3, 2);
12064 }
else if (size == 2)
12072 if ((
Bits32(index_align, 1, 0) != 0) &&
12073 (
Bits32(index_align, 1, 0) != 3))
12079 index =
Bit32(index_align, 3);
12082 if (
Bits32(index_align, 1, 0) == 0)
12090 d = (
Bit32(opcode, 22) << 4) |
Bits32(opcode, 15, 12);
12091 n =
Bits32(opcode, 19, 16);
12092 m =
Bits32(opcode, 3, 0);
12097 register_index = ((m != 15) && (m != 13));
12115 if ((address % alignment) != 0)
12126 if (register_index)
12131 uint32_t value = Rn + offset;
12134 std::optional<RegisterInfo> base_reg =
12144 uint32_t element =
MemURead(context, address, esize, 0, &success);
12148 element = element << (index * esize);
12150 uint64_t reg_data =
12155 uint64_t all_ones = -1;
12156 uint64_t mask = all_ones
12157 << ((index + 1) * esize);
12161 mask = mask |
Bits64(all_ones, (index * esize) - 1,
12165 uint64_t masked_reg =
12168 masked_reg & element;
12185 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12186 address = R[n];
if (address MOD alignment) != 0 then GenerateAlignmentException();
12187 if wback then R[n] = R[n] + (
if register_index then R[m]
else 8*regs);
12188 for r = 0 to regs-1
12189 for e = 0 to elements-1
12190 MemU[address,ebytes] = Elem[D[d+r],e,esize];
12191 address = address + ebytes;
12194 bool success =
false;
12198 uint32_t alignment;
12206 bool register_index;
12208 switch (encoding) {
12211 uint32_t type =
Bits32(opcode, 11, 8);
12212 uint32_t align =
Bits32(opcode, 5, 4);
12221 }
else if (type == 10)
12227 }
else if (type == 6)
12233 }
else if (type == 2)
12244 alignment = 4 << align;
12247 ebytes = 1 <<
Bits32(opcode, 7, 6);
12248 esize = 8 * ebytes;
12249 elements = 8 / ebytes;
12252 d = (
Bit32(opcode, 22) << 4) |
Bits32(opcode, 15, 12);
12253 n =
Bits32(opcode, 19, 16);
12254 m =
Bits32(opcode, 3, 0);
12258 register_index = ((m != 15) && (m != 13));
12261 if ((d + regs) > 32)
12273 std::optional<RegisterInfo> base_reg =
12283 if ((address % alignment) != 0)
12294 if (register_index)
12309 for (uint32_t r = 0; r < regs; ++r) {
12310 std::optional<RegisterInfo> data_reg =
12318 for (uint32_t e = 0; e < elements; ++e) {
12320 uint64_t word =
Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12324 if (!
MemUWrite(context, address, word, ebytes))
12328 address = address + ebytes;
12341 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12342 address = R[n];
if (address MOD alignment) != 0 then GenerateAlignmentException();
12343 if wback then R[n] = R[n] + (
if register_index then R[m]
else ebytes);
12344 MemU[address,ebytes] = Elem[D[d],index,esize];
12347 bool success =
false;
12353 uint32_t alignment;
12358 bool register_index;
12360 switch (encoding) {
12363 uint32_t size =
Bits32(opcode, 11, 10);
12364 uint32_t index_align =
Bits32(opcode, 7, 4);
12379 index =
Bits32(index_align, 3, 1);
12381 }
else if (size == 1)
12390 index =
Bits32(index_align, 3, 2);
12397 }
else if (size == 2)
12405 if ((
Bits32(index_align, 1, 0) != 0) &&
12406 (
Bits32(index_align, 1, 0) != 3))
12412 index =
Bit32(index_align, 3);
12415 if (
Bits32(index_align, 1, 0) == 0)
12423 d = (
Bit32(opcode, 22) << 4) |
Bits32(opcode, 15, 12);
12424 n =
Bits32(opcode, 19, 16);
12425 m =
Bits32(opcode, 3, 0);
12430 register_index = ((m != 15) && (m != 13));
12440 std::optional<RegisterInfo> base_reg =
12450 if ((address % alignment) != 0)
12461 if (register_index)
12475 uint64_t register_data =
12481 Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12483 std::optional<RegisterInfo> data_reg =
12488 if (!
MemUWrite(context, address, word, ebytes))
12500 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12501 address = R[n];
if (address MOD alignment) != 0 then GenerateAlignmentException();
12502 if wback then R[n] = R[n] + (
if register_index then R[m]
else ebytes);
12503 replicated_element = Replicate(MemU[address,ebytes], elements);
12504 for r = 0 to regs-1
12505 D[d+r] = replicated_element;
12508 bool success =
false;
12514 uint32_t alignment;
12519 bool register_index;
12521 switch (encoding) {
12525 uint32_t size =
Bits32(opcode, 7, 6);
12526 if ((size == 3) || ((size == 0) &&
BitIsSet(opcode, 4)))
12531 ebytes = 1 << size;
12532 elements = 8 / ebytes;
12542 alignment = ebytes;
12545 d = (
Bit32(opcode, 22) << 4) |
Bits32(opcode, 15, 12);
12546 n =
Bits32(opcode, 19, 16);
12547 m =
Bits32(opcode, 3, 0);
12551 register_index = ((m != 15) && (m != 13));
12554 if ((d + regs) > 32)
12572 if ((address % alignment) != 0)
12583 if (register_index)
12589 std::optional<RegisterInfo> base_reg =
12601 uint64_t word =
MemURead(context, address, ebytes, 0, &success);
12605 uint64_t replicated_element = 0;
12606 uint32_t esize = ebytes * 8;
12607 for (uint32_t e = 0; e < elements; ++e)
12608 replicated_element =
12609 (replicated_element << esize) |
Bits64(word, esize - 1, 0);
12612 for (uint32_t r = 0; r < regs; ++r) {
12615 replicated_element))
12630 EncodingSpecificOperations();
12633 operand2 =
if register_form then
Shift(R[m], shift_t, shift_n, APSR.C)
else imm32;
12635 when
'0000' result = R[n] AND operand2;
12636 when
'0001' result = R[n] EOR operand2;
12639 when
'0100' (result, -, -) =
AddWithCarry(R[n], operand2,
'0');
12640 when
'0101' (result, -, -) =
AddWithCarry(R[n], operand2, APSR.c);
12641 when
'0110' (result, -, -) =
AddWithCarry(R[n],
NOT(operand2), APSR.C);
12642 when
'0111' (result, -, -) =
AddWithCarry(
NOT(R[n]), operand2, APSR.C);
12643 when
'1100' result = R[n] OR operand2;
12644 when
'1101' result = operand2;
12645 when
'1110' result = R[n] AND
NOT(operand2);
12646 when
'1111' result =
NOT(operand2);
12651 bool success =
false;
12657 bool register_form;
12662 switch (encoding) {
12668 imm32 =
Bits32(opcode, 7, 0);
12669 register_form =
false;
12680 n =
Bits32(opcode, 19, 16);
12682 register_form =
false;
12683 code =
Bits32(opcode, 24, 21);
12689 n =
Bits32(opcode, 19, 16);
12690 m =
Bits32(opcode, 3, 0);
12691 register_form =
true;
12705 if (register_form) {
12710 operand2 =
Shift(Rm, shift_t, shift_n,
APSR_C, &success);
12727 result.
result = Rn & operand2;
12732 result.
result = Rn ^ operand2;
12767 result.
result = Rn | operand2;
12772 result.
result = operand2;
12777 result.
result = Rn & ~(operand2);
12782 result.
result = ~(operand2);
12811 uint32_t arm_isa) {
12839 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12892 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12896 "add{s}<c> <Rd>, <Rn>, #const"},
12900 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12904 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12916 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12923 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12930 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12937 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12944 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12951 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12958 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12962 "sub{s}<c> <Rd>, <Rn>, #<const>"},
12969 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12997 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
13044 "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13047 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13060 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13063 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13068 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13073 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13076 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13081 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13084 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13089 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13092 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13095 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13106 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13109 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13112 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13125 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13128 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13133 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13136 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13139 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13142 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13153 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13156 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13171 static const size_t k_num_arm_opcodes = std::size(g_arm_opcodes);
13173 for (
size_t i = 0; i < k_num_arm_opcodes; ++i) {
13174 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13175 (g_arm_opcodes[i].variants & arm_isa) != 0)
13176 return &g_arm_opcodes[i];
13183 uint32_t arm_isa) {
13222 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13276 "b<c>.w #imm8 (outside or last in IT)"},
13310 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13333 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13342 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13351 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13360 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13366 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13370 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13379 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13383 "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13388 "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13391 "addw<c> <Rd>,<Rn>,#<imm12>"},
13395 "subs|sub<c> <Rd>, <Rn> #imm3"},
13400 "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13403 "subw<c> <Rd>, <Rn>, #imm12"},
13414 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13454 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13476 "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13551 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13554 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13558 "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13563 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13566 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13569 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13572 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13579 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13582 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13585 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13588 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13593 "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13596 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13599 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13602 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13607 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13610 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13613 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13616 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13621 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13624 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13627 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13638 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13641 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13644 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13659 "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13662 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13667 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13670 "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13673 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13676 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13681 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13684 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13687 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13698 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13701 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13722 const size_t k_num_thumb_opcodes = std::size(g_thumb_opcodes);
13723 for (
size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13724 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13725 (g_thumb_opcodes[i].variants & arm_isa) != 0)
13726 return &g_thumb_opcodes[i];
13735 if (arch_cstr.equals_insensitive(
"armv4t"))
13737 else if (arch_cstr.equals_insensitive(
"armv5tej"))
13739 else if (arch_cstr.equals_insensitive(
"armv5te"))
13741 else if (arch_cstr.equals_insensitive(
"armv5t"))
13743 else if (arch_cstr.equals_insensitive(
"armv6k"))
13745 else if (arch_cstr.equals_insensitive(
"armv6t2"))
13747 else if (arch_cstr.equals_insensitive(
"armv7s"))
13749 else if (arch_cstr.equals_insensitive(
"arm"))
13751 else if (arch_cstr.equals_insensitive(
"thumb"))
13753 else if (arch_cstr.starts_with_insensitive(
"armv4"))
13755 else if (arch_cstr.starts_with_insensitive(
"armv6"))
13757 else if (arch_cstr.starts_with_insensitive(
"armv7"))
13759 else if (arch_cstr.starts_with_insensitive(
"armv8"))
13792 bool success =
false;
13806 uint32_t thumb_opcode =
MemARead(read_inst_context,
pc, 2, 0, &success);
13809 if ((thumb_opcode & 0xe000) != 0xe000 ||
13810 ((thumb_opcode & 0x1800u) == 0)) {
13814 (thumb_opcode << 16) |
13815 MemARead(read_inst_context,
pc + 2, 2, 0, &success),
13855 bool result =
false;
13930 if (byte_size == 2) {
13931 if (
Bits32(opcode, 15, 12) == 0x0d &&
Bits32(opcode, 11, 8) != 0x0f)
13932 return Bits32(opcode, 11, 8);
13933 }
else if (byte_size == 4) {
13934 if (
Bits32(opcode, 31, 27) == 0x1e &&
Bits32(opcode, 15, 14) == 0x02 &&
13935 Bits32(opcode, 12, 12) == 0x00 &&
Bits32(opcode, 25, 22) <= 0x0d) {
13936 return Bits32(opcode, 25, 22);
13994 bool affect_execstate) {
14000 tmp_cpsr = tmp_cpsr | (
Bits32(value, 31, 27) << 27);
14001 if (affect_execstate)
14002 tmp_cpsr = tmp_cpsr | (
Bits32(value, 26, 24) << 24);
14006 tmp_cpsr = tmp_cpsr | (
Bits32(value, 19, 16) << 16);
14010 if (affect_execstate)
14011 tmp_cpsr = tmp_cpsr | (
Bits32(value, 15, 10) << 10);
14012 tmp_cpsr = tmp_cpsr | (
Bit32(value, 9) << 9);
14014 tmp_cpsr = tmp_cpsr | (
Bit32(value, 8) << 8);
14019 tmp_cpsr = tmp_cpsr | (
Bits32(value, 7, 6) << 6);
14020 if (affect_execstate)
14021 tmp_cpsr = tmp_cpsr | (
Bit32(value, 5) << 5);
14023 tmp_cpsr = tmp_cpsr |
Bits32(value, 4, 0);
14035 target = addr & 0xfffffffc;
14037 target = addr & 0xfffffffe;
14050 bool cpsr_changed =
false;
14055 cpsr_changed =
true;
14057 target = addr & 0xfffffffe;
14062 cpsr_changed =
true;
14064 target = addr & 0xfffffffc;
14069 if (cpsr_changed) {
14105 switch (arm_or_thumb) {
14137 uint64_t unsigned_sum = x + y + carry_in;
14138 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14142 overflow = ((int32_t)result == signed_sum ? 0 : 1);
14145 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14147 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14216 Context &context,
const uint32_t result,
const uint32_t
Rd,
bool setflags,
14217 const uint32_t carry,
const uint32_t overflow) {
14240 return WriteFlags(context, result, carry, overflow);
14256 const uint32_t carry,
14257 const uint32_t overflow) {
14263 if (overflow != ~0u)
14282 const bool auto_advance_pc =
14283 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14285 evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14287 bool success =
false;
14298 uint32_t orig_pc_value = 0;
14299 if (auto_advance_pc) {
14317 (opcode_data ==
nullptr ||
14321 if (auto_advance_pc) {
14322 uint32_t after_pc_value =
14327 if (after_pc_value == orig_pc_value) {
14344 if (cond == 0xe || cond == 0xf || cond ==
UINT32_MAX)
14352 out_stream.
Printf(
"TestEmulation: Missing test data.\n");
14356 static constexpr llvm::StringLiteral opcode_key(
"opcode");
14357 static constexpr llvm::StringLiteral before_key(
"before_state");
14358 static constexpr llvm::StringLiteral after_key(
"after_state");
14362 uint32_t test_opcode;
14363 if ((value_sp.get() ==
nullptr) ||
14365 out_stream.
Printf(
"TestEmulation: Error reading opcode from test file.\n");
14368 test_opcode = value_sp->GetValueAs<uint64_t>().value_or(0);
14370 if (arch.
GetTriple().getArch() == llvm::Triple::thumb ||
14373 if (test_opcode < 0x10000)
14377 }
else if (arch.
GetTriple().getArch() == llvm::Triple::arm) {
14381 out_stream.
Printf(
"TestEmulation: Invalid arch.\n");
14389 if ((value_sp.get() ==
nullptr) ||
14391 out_stream.
Printf(
"TestEmulation: Failed to find 'before' state.\n");
14397 out_stream.
Printf(
"TestEmulation: Failed loading 'before' state.\n");
14402 if ((value_sp.get() ==
nullptr) ||
14404 out_stream.
Printf(
"TestEmulation: Failed to find 'after' state.\n");
14410 out_stream.
Printf(
"TestEmulation: Failed loading 'after' state.\n");
14422 out_stream.
Printf(
"TestEmulation: EvaluateInstruction() failed.\n");
14426 success = before_state.
CompareState(after_state, out_stream);
14428 out_stream.
Printf(
"TestEmulation: State after emulation does not match "
14429 "'after' state.\n");
14458 unwind_plan.
Clear();
14464 row->GetCFAValue().SetIsRegisterPlusOffset(
dwarf_sp, 0);
static uint64_t NOT(uint64_t x)
static bool IsZero(uint64_t x)
static uint32_t CountITSize(uint32_t ITMask)
static std::optional< RegisterInfo > GetARMDWARFRegisterInfo(unsigned reg_num)
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
static bool ReadPseudoRegister(lldb_private::EmulateInstruction *instruction, void *baton, const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue ®_value)
static size_t ReadPseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton, const lldb_private::EmulateInstruction::Context &context, lldb::addr_t addr, void *dst, size_t length)
static bool WritePseudoRegister(lldb_private::EmulateInstruction *instruction, void *baton, const lldb_private::EmulateInstruction::Context &context, const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue ®_value)
static size_t WritePseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton, const lldb_private::EmulateInstruction::Context &context, lldb::addr_t addr, const void *dst, size_t length)
bool LoadStateFromDictionary(lldb_private::OptionValueDictionary *test_data)
bool CompareState(EmulationStateARM &other_state, lldb_private::Stream &out_stream)
A section + offset based address class.
AddressClass GetAddressClass() const
An architecture specification class.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool IsAlwaysThumbInstructions() const
Detect whether this architecture uses thumb code exclusively.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
bool EmulateLDRDRegister(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateRORReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTRRtSP(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTREX(const uint32_t opcode, const ARMEncoding encoding)
static bool SupportsEmulatingInstructionsOfTypeStatic(InstructionType inst_type)
bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) override
bool EmulateIT(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateVSTM(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLSLImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateShiftImm(const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
bool EmulateVLDR(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateTEQImm(const uint32_t opcode, const ARMEncoding encoding)
uint32_t CurrentCond(const uint32_t opcode)
bool EmulateB(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateADDRdSPImm(const uint32_t opcode, const ARMEncoding encoding)
bool WriteCoreReg(Context &context, const uint32_t result, const uint32_t Rd)
bool EmulateLDRSBRegister(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRDImmediate(const uint32_t opcode, const ARMEncoding encoding)
bool CurrentModeIsPrivileged()
bool EmulateEORImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTRThumb(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateCB(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTRDReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRRegister(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTMDA(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateCMPReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDM(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateTB(const uint32_t opcode, const ARMEncoding encoding)
bool EvaluateInstruction(uint32_t evaluate_options) override
bool EmulateASRImm(const uint32_t opcode, const ARMEncoding encoding)
bool ReadInstruction() override
bool MemAWrite(EmulateInstruction::Context &context, lldb::addr_t address, uint64_t data_val, uint32_t size)
bool EmulateVLD1SingleAll(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateBLXRm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateCMNImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSVC(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateORRReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSUBImmARM(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateShiftReg(const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
bool EmulateVLDM(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTRHRegister(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateRSBReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRHLiteral(const uint32_t opcode, const ARMEncoding encoding)
std::optional< RegisterInfo > GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) override
bool EmulateRORImm(const uint32_t opcode, const ARMEncoding encoding)
uint32_t ReadCoreReg(uint32_t regnum, bool *success)
bool EmulateLDRRtRnImm(const uint32_t opcode, const ARMEncoding encoding)
bool ALUWritePC(Context &context, uint32_t addr)
bool EmulateSTMDB(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSUBImmThumb(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateADCImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateBXRm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTMIB(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLSLReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRSBLiteral(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRBImmediate(const uint32_t opcode, const ARMEncoding encoding)
static llvm::StringRef GetPluginDescriptionStatic()
bool EmulateLDMIB(const uint32_t opcode, const ARMEncoding encoding)
static ARMOpcode * GetARMOpcodeForInstruction(const uint32_t opcode, uint32_t isa_mask)
bool EmulateVLD1Single(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateADDReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateORRImm(const uint32_t opcode, const ARMEncoding encoding)
void CPSRWriteByInstr(uint32_t value, uint32_t bytemask, bool affect_execstate)
bool EmulateTEQReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateADDSPImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateADDImmThumb(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSBCImm(const uint32_t opcode, const ARMEncoding encoding)
bool LoadWritePC(Context &context, uint32_t addr)
bool EmulateMOVRdImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateANDImm(const uint32_t opcode, const ARMEncoding encoding)
uint64_t MemURead(EmulateInstruction::Context &context, lldb::addr_t address, uint32_t size, uint64_t fail_value, bool *success_ptr)
bool EmulateSUBR7IPImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSXTH(const uint32_t opcode, const ARMEncoding encoding)
bool BranchWritePC(const Context &context, uint32_t addr)
bool EmulateTSTImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateVPOP(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateADDSPRm(const uint32_t opcode, const ARMEncoding encoding)
bool MemUWrite(EmulateInstruction::Context &context, lldb::addr_t address, uint64_t data_val, uint32_t size)
bool EmulateSTRBImmARM(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateMVNImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateVSTR(const uint32_t opcode, const ARMEncoding encoding)
virtual bool SetArchitecture(const ArchSpec &arch)
uint64_t MemARead(EmulateInstruction::Context &context, lldb::addr_t address, uint32_t size, uint64_t fail_value, bool *success_ptr)
bool EmulateMVNReg(const uint32_t opcode, const ARMEncoding encoding)
static ARMOpcode * GetThumbOpcodeForInstruction(const uint32_t opcode, uint32_t isa_mask)
bool EmulateSBCReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateMOVRdRm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateVPUSH(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateEORReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLSRReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateNop(const uint32_t opcode, const ARMEncoding encoding)
bool EmulatePOP(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRSHImmediate(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateMOVRdSP(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTRDImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateBICReg(const uint32_t opcode, const ARMEncoding encoding)
bool WriteFlags(Context &context, const uint32_t result, const uint32_t carry=~0u, const uint32_t overflow=~0u)
bool EmulateRSCImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLSRImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTRImmARM(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateUXTH(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateCMNReg(const uint32_t opcode, const ARMEncoding encoding)
bool TestEmulation(Stream &out_stream, ArchSpec &arch, OptionValueDictionary *test_data) override
bool EmulateADR(const uint32_t opcode, const ARMEncoding encoding)
bool EmulatePUSH(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRHRegister(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRRtPCRelative(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateASRReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRBLiteral(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateVST1Single(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateADCReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSUBSPcLrEtc(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateVST1Multiple(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateRSCReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateBXJRm(const uint32_t opcode, const ARMEncoding encoding)
bool BXWritePC(Context &context, uint32_t addr)
bool EmulateMOVLowHigh(const uint32_t opcode, const ARMEncoding encoding)
bool BadMode(uint32_t mode)
bool SetTargetTriple(const ArchSpec &arch) override
bool ConditionPassed(const uint32_t opcode)
bool EmulateSTM(const uint32_t opcode, const ARMEncoding encoding)
static llvm::StringRef GetPluginNameStatic()
uint32_t GetFramePointerDWARFRegisterNumber() const
bool WriteCoreRegOptionalFlags(Context &context, const uint32_t result, const uint32_t Rd, bool setflags, const uint32_t carry=~0u, const uint32_t overflow=~0u)
bool EmulateTSTReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRImmediateARM(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSUBSPReg(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateADDRegShift(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateADDImmARM(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateRFE(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateMUL(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateCMPImm(const uint32_t opcode, const ARMEncoding encoding)
bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr, Target *target) override
bool EmulateANDReg(const uint32_t opcode, const ARMEncoding encoding)
uint32_t GetFramePointerRegisterNumber() const
bool EmulateLDRBRegister(const uint32_t opcode, const ARMEncoding encoding)
bool SelectInstrSet(Mode arm_or_thumb)
bool EmulateBICImm(const uint32_t opcode, const ARMEncoding encoding)
static lldb_private::EmulateInstruction * CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type)
bool EmulateRRX(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSUBIPSPImm(const uint32_t opcode, const ARMEncoding encoding)
bool WriteBits32Unknown(int n)
bool EmulateUXTB(const uint32_t opcode, const ARMEncoding encoding)
InstructionCondition GetInstructionCondition() override
bool EmulateSUBSPImm(const uint32_t opcode, const ARMEncoding encoding)
AddWithCarryResult AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in)
bool EmulateRSBImm(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRSBImmediate(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDMDA(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTRRegister(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateVLD1Multiple(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSTRBThumb(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSXTB(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateSUBReg(const uint32_t opcode, const ARMEncoding encoding)
bool WriteBits32UnknownToMemory(lldb::addr_t address)
bool EmulateLDRSHRegister(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRSHLiteral(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDRHImmediate(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateLDMDB(const uint32_t opcode, const ARMEncoding encoding)
bool EmulateBLXImmediate(const uint32_t opcode, const ARMEncoding encoding)
"lldb/Core/EmulateInstruction.h" A class that allows emulation of CPU opcodes.
@ eContextRelativeBranchImmediate
@ eContextSetFramePointer
@ eContextAdjustBaseRegister
@ eContextWriteMemoryRandomBits
@ eContextTableBranchReadMemory
@ eContextWriteRegisterRandomBits
@ eContextAdjustStackPointer
@ eContextReturnFromException
@ eContextPushRegisterOnStack
@ eContextPopRegisterOffStack
@ eContextAbsoluteBranchRegister
@ eContextRegisterPlusOffset
lldb::ByteOrder GetByteOrder() const
void SetCallbacks(ReadMemoryCallback read_mem_callback, WriteMemoryCallback write_mem_callback, ReadRegisterCallback read_reg_callback, WriteRegisterCallback write_reg_callback)
static const InstructionCondition UnconditionalCondition
bool WriteRegisterUnsigned(const Context &context, const RegisterInfo ®_info, uint64_t reg_value)
uint32_t GetAddressByteSize() const
void SetBaton(void *baton)
virtual bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr, Target *target)
uint64_t ReadRegisterUnsigned(const RegisterInfo ®_info, uint64_t fail_value, bool *success_ptr)
uint32_t InstructionCondition
bool InitIT(uint32_t bits7_0)
void SetOpcode16(uint16_t inst, lldb::ByteOrder order)
uint32_t GetByteSize() const
uint32_t GetOpcode32(uint32_t invalid_opcode=UINT32_MAX) const
void SetOpcode32(uint32_t inst, lldb::ByteOrder order)
lldb::OptionValueSP GetValueForKey(llvm::StringRef key) const
OptionValueDictionary * GetAsDictionary()
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A stream class that can stream formatted output to a file.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
void SetRegisterKind(lldb::RegisterKind kind)
void SetReturnAddressRegister(uint32_t regnum)
void AppendRow(const RowSP &row_sp)
std::shared_ptr< Row > RowSP
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
void SetSourceName(const char *)
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
#define LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
lldb::ByteOrder InlHostByteOrder()
A class that represents a running process on the host machine.
static void SetBit32(uint32_t &bits, const uint32_t bit, const uint32_t val)
static uint64_t Bits64(const uint64_t bits, const uint32_t msbit, const uint32_t lsbit)
static void SetBits32(uint32_t &bits, const uint32_t msbit, const uint32_t lsbit, const uint32_t val)
static uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
static uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5, ARM_ShifterType &shift_t)
static uint32_t ARMExpandImm(uint32_t opcode)
static uint32_t LSL(const uint32_t value, const uint32_t amount, bool *success)
static uint32_t DecodeImmShiftARM(const uint32_t opcode, ARM_ShifterType &shift_t)
static uint32_t ThumbExpandImm(uint32_t opcode)
static uint32_t ROR(const uint32_t value, const uint32_t amount, bool *success)
static uint32_t ThumbImm12(uint32_t opcode)
static uint32_t Shift_C(const uint32_t value, ARM_ShifterType type, const uint32_t amount, const uint32_t carry_in, uint32_t &carry_out, bool *success)
InstructionType
Instruction types.
static uint32_t ThumbImm8Scaled(uint32_t opcode)
static uint32_t Shift(const uint32_t value, ARM_ShifterType type, const uint32_t amount, const uint32_t carry_in, bool *success)
static uint32_t ThumbImm7Scaled(uint32_t opcode)
static bool BitIsSet(const uint64_t value, const uint64_t bit)
static uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
static uint32_t DecodeImmShiftThumb(const uint32_t opcode, ARM_ShifterType &shift_t)
static uint32_t Align(uint32_t val, uint32_t alignment)
static bool BadReg(uint32_t n)
static uint32_t BitCount(uint64_t x)
static uint64_t UnsignedBits(const uint64_t value, const uint64_t msbit, const uint64_t lsbit)
static ARM_ShifterType DecodeRegShift(const uint32_t type)
static uint32_t Bits32(const uint32_t bits, const uint32_t msbit, const uint32_t lsbit)
static bool BitIsClear(const uint64_t value, const uint64_t bit)
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
static uint32_t Bit32(const uint32_t bits, const uint32_t bit)
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
std::shared_ptr< lldb_private::OptionValue > OptionValueSP
RegisterKind
Register numbering types.
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindDWARF
the register numbers seen DWARF
bool(EmulateInstructionARM::* callback)(const uint32_t opcode, const EmulateInstructionARM::ARMEncoding encoding)
EmulateInstructionARM::ARMEncoding encoding
void SetISA(uint32_t isa)
void SetRegisterRegisterOperands(RegisterInfo op1_reg, RegisterInfo op2_reg)
void SetISAAndImmediate(uint32_t isa, uint32_t data)
void SetImmediate(uint64_t immediate)
void SetISAAndImmediateSigned(uint32_t isa, int32_t data)
void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset)
void SetImmediateSigned(int64_t signed_immediate)
void SetRegisterToRegisterPlusIndirectOffset(RegisterInfo base_reg, RegisterInfo offset_reg, RegisterInfo data_reg)
void SetOffset(int64_t signed_offset)
void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg, RegisterInfo base_reg, int64_t offset)
void SetAddress(lldb::addr_t address)
void SetRegister(RegisterInfo reg)
void SetRegisterPlusIndirectOffset(RegisterInfo base_reg, RegisterInfo offset_reg)
Every register is described in detail including its name, alternate name (optional),...
lldb::Encoding encoding
Encoding of the register bits.
const char * alt_name
Alternate name of this register, can be NULL.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const char * name
Name of this register, can't be NULL.
lldb::Format format
Default display format.