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)
46 ::memset(®_info, 0,
sizeof(RegisterInfo));
50 reg_info.byte_size = 16;
56 reg_info.byte_size = 8;
60 reg_info.byte_size = 4;
64 reg_info.byte_size = 12;
68 reg_info.byte_size = 4;
102 reg_info.name =
"r8";
105 reg_info.name =
"r9";
108 reg_info.name =
"r10";
111 reg_info.name =
"r11";
114 reg_info.name =
"r12";
117 reg_info.name =
"sp";
118 reg_info.alt_name =
"r13";
122 reg_info.name =
"lr";
123 reg_info.alt_name =
"r14";
127 reg_info.name =
"pc";
128 reg_info.alt_name =
"r15";
132 reg_info.name =
"cpsr";
137 reg_info.name =
"s0";
140 reg_info.name =
"s1";
143 reg_info.name =
"s2";
146 reg_info.name =
"s3";
149 reg_info.name =
"s4";
152 reg_info.name =
"s5";
155 reg_info.name =
"s6";
158 reg_info.name =
"s7";
161 reg_info.name =
"s8";
164 reg_info.name =
"s9";
167 reg_info.name =
"s10";
170 reg_info.name =
"s11";
173 reg_info.name =
"s12";
176 reg_info.name =
"s13";
179 reg_info.name =
"s14";
182 reg_info.name =
"s15";
185 reg_info.name =
"s16";
188 reg_info.name =
"s17";
191 reg_info.name =
"s18";
194 reg_info.name =
"s19";
197 reg_info.name =
"s20";
200 reg_info.name =
"s21";
203 reg_info.name =
"s22";
206 reg_info.name =
"s23";
209 reg_info.name =
"s24";
212 reg_info.name =
"s25";
215 reg_info.name =
"s26";
218 reg_info.name =
"s27";
221 reg_info.name =
"s28";
224 reg_info.name =
"s29";
227 reg_info.name =
"s30";
230 reg_info.name =
"s31";
235 reg_info.name =
"f0";
238 reg_info.name =
"f1";
241 reg_info.name =
"f2";
244 reg_info.name =
"f3";
247 reg_info.name =
"f4";
250 reg_info.name =
"f5";
253 reg_info.name =
"f6";
256 reg_info.name =
"f7";
262 reg_info.name =
"wCGR0/ACC0";
265 reg_info.name =
"wCGR1/ACC1";
268 reg_info.name =
"wCGR2/ACC2";
271 reg_info.name =
"wCGR3/ACC3";
274 reg_info.name =
"wCGR4/ACC4";
277 reg_info.name =
"wCGR5/ACC5";
280 reg_info.name =
"wCGR6/ACC6";
283 reg_info.name =
"wCGR7/ACC7";
288 reg_info.name =
"wR0";
291 reg_info.name =
"wR1";
294 reg_info.name =
"wR2";
297 reg_info.name =
"wR3";
300 reg_info.name =
"wR4";
303 reg_info.name =
"wR5";
306 reg_info.name =
"wR6";
309 reg_info.name =
"wR7";
312 reg_info.name =
"wR8";
315 reg_info.name =
"wR9";
318 reg_info.name =
"wR10";
321 reg_info.name =
"wR11";
324 reg_info.name =
"wR12";
327 reg_info.name =
"wR13";
330 reg_info.name =
"wR14";
333 reg_info.name =
"wR15";
337 reg_info.name =
"spsr";
340 reg_info.name =
"spsr_fiq";
343 reg_info.name =
"spsr_irq";
346 reg_info.name =
"spsr_abt";
349 reg_info.name =
"spsr_und";
352 reg_info.name =
"spsr_svc";
356 reg_info.name =
"r8_usr";
359 reg_info.name =
"r9_usr";
362 reg_info.name =
"r10_usr";
365 reg_info.name =
"r11_usr";
368 reg_info.name =
"r12_usr";
371 reg_info.name =
"r13_usr";
374 reg_info.name =
"r14_usr";
377 reg_info.name =
"r8_fiq";
380 reg_info.name =
"r9_fiq";
383 reg_info.name =
"r10_fiq";
386 reg_info.name =
"r11_fiq";
389 reg_info.name =
"r12_fiq";
392 reg_info.name =
"r13_fiq";
395 reg_info.name =
"r14_fiq";
398 reg_info.name =
"r13_irq";
401 reg_info.name =
"r14_irq";
404 reg_info.name =
"r13_abt";
407 reg_info.name =
"r14_abt";
410 reg_info.name =
"r13_und";
413 reg_info.name =
"r14_und";
416 reg_info.name =
"r13_svc";
419 reg_info.name =
"r14_svc";
424 reg_info.name =
"wC0";
427 reg_info.name =
"wC1";
430 reg_info.name =
"wC2";
433 reg_info.name =
"wC3";
436 reg_info.name =
"wC4";
439 reg_info.name =
"wC5";
442 reg_info.name =
"wC6";
445 reg_info.name =
"wC7";
450 reg_info.name =
"d0";
453 reg_info.name =
"d1";
456 reg_info.name =
"d2";
459 reg_info.name =
"d3";
462 reg_info.name =
"d4";
465 reg_info.name =
"d5";
468 reg_info.name =
"d6";
471 reg_info.name =
"d7";
474 reg_info.name =
"d8";
477 reg_info.name =
"d9";
480 reg_info.name =
"d10";
483 reg_info.name =
"d11";
486 reg_info.name =
"d12";
489 reg_info.name =
"d13";
492 reg_info.name =
"d14";
495 reg_info.name =
"d15";
498 reg_info.name =
"d16";
501 reg_info.name =
"d17";
504 reg_info.name =
"d18";
507 reg_info.name =
"d19";
510 reg_info.name =
"d20";
513 reg_info.name =
"d21";
516 reg_info.name =
"d22";
519 reg_info.name =
"d23";
522 reg_info.name =
"d24";
525 reg_info.name =
"d25";
528 reg_info.name =
"d26";
531 reg_info.name =
"d27";
534 reg_info.name =
"d28";
537 reg_info.name =
"d29";
540 reg_info.name =
"d30";
543 reg_info.name =
"d31";
548 reg_info.name =
"q0";
551 reg_info.name =
"q1";
554 reg_info.name =
"q2";
557 reg_info.name =
"q3";
560 reg_info.name =
"q4";
563 reg_info.name =
"q5";
566 reg_info.name =
"q6";
569 reg_info.name =
"q7";
572 reg_info.name =
"q8";
575 reg_info.name =
"q9";
578 reg_info.name =
"q10";
581 reg_info.name =
"q11";
584 reg_info.name =
"q12";
587 reg_info.name =
"q13";
590 reg_info.name =
"q14";
593 reg_info.name =
"q15";
606 uint32_t TZ = llvm::countTrailingZeros(ITMask);
620 unsigned short FirstCond =
Bits32(bits7_0, 7, 4);
621 if (FirstCond == 0xF) {
624 if (FirstCond == 0xE && ITCounter != 1) {
633 void ITSession::ITAdvance() {
639 unsigned short NewITState4_0 =
Bits32(ITState, 4, 0) << 1;
645 bool ITSession::InITBlock() {
return ITCounter != 0; }
648 bool ITSession::LastInITBlock() {
return ITCounter == 1; }
653 return Bits32(ITState, 7, 4);
660 #define LDM_REGLIST 1
664 #define PC_REGLIST_BIT 0x8000
666 #define ARMv4 (1u << 0)
667 #define ARMv4T (1u << 1)
668 #define ARMv5T (1u << 2)
669 #define ARMv5TE (1u << 3)
670 #define ARMv5TEJ (1u << 4)
671 #define ARMv6 (1u << 5)
672 #define ARMv6K (1u << 6)
673 #define ARMv6T2 (1u << 7)
674 #define ARMv7 (1u << 8)
675 #define ARMv7S (1u << 9)
676 #define ARMv8 (1u << 10)
677 #define ARMvAll (0xffffffffu)
679 #define ARMV4T_ABOVE \
680 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \
682 #define ARMV5_ABOVE \
683 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \
685 #define ARMV5TE_ABOVE \
686 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
687 #define ARMV5J_ABOVE \
688 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
689 #define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
690 #define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
691 #define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
694 #define VFPv1 (1u << 1)
695 #define VFPv2 (1u << 2)
696 #define VFPv3 (1u << 3)
697 #define AdvancedSIMD (1u << 4)
699 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
700 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
701 #define VFPv2v3 (VFPv2 | VFPv3)
707 void EmulateInstructionARM::Initialize() {
708 PluginManager::RegisterPlugin(GetPluginNameStatic(),
709 GetPluginDescriptionStatic(), CreateInstance);
712 void EmulateInstructionARM::Terminate() {
713 PluginManager::UnregisterPlugin(CreateInstance);
716 llvm::StringRef EmulateInstructionARM::GetPluginDescriptionStatic() {
717 return "Emulate instructions for the ARM architecture.";
721 EmulateInstructionARM::CreateInstance(
const ArchSpec &arch,
723 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
725 if (arch.
GetTriple().getArch() == llvm::Triple::arm) {
726 std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
730 return emulate_insn_up.release();
731 }
else if (arch.
GetTriple().getArch() == llvm::Triple::thumb) {
732 std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
736 return emulate_insn_up.release();
743 bool EmulateInstructionARM::SetTargetTriple(
const ArchSpec &arch) {
744 if (arch.
GetTriple().getArch() == llvm::Triple::arm)
746 else if (arch.
GetTriple().getArch() == llvm::Triple::thumb)
754 bool EmulateInstructionARM::WriteBits32UnknownToMemory(
addr_t address) {
756 context.
type = EmulateInstruction::eContextWriteMemoryRandomBits;
760 const uint32_t addr_byte_size = GetAddressByteSize();
762 return MemAWrite(context, address, random_data, addr_byte_size);
767 bool EmulateInstructionARM::WriteBits32Unknown(
int n) {
769 context.
type = EmulateInstruction::eContextWriteRegisterRandomBits;
787 RegisterInfo ®_info) {
820 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber()
const {
821 if (m_arch.GetTriple().isAndroid())
823 bool is_apple =
false;
824 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
826 switch (m_arch.GetTriple().getOS()) {
827 case llvm::Triple::Darwin:
828 case llvm::Triple::MacOSX:
829 case llvm::Triple::IOS:
830 case llvm::Triple::TvOS:
831 case llvm::Triple::WatchOS:
849 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
855 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber()
const {
856 bool is_apple =
false;
857 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
859 switch (m_arch.GetTriple().getOS()) {
860 case llvm::Triple::Darwin:
861 case llvm::Triple::MacOSX:
862 case llvm::Triple::IOS:
879 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
889 bool EmulateInstructionARM::EmulatePUSH(
const uint32_t opcode,
893 if (ConditionPassed())
895 EncodingSpecificOperations();
896 NullCheckIfThumbEE(13);
897 address = SP - 4*
BitCount(registers);
901 if (registers<i> ==
'1')
903 if i == 13 && i != LowestSetBit(registers)
904 MemA[address,4] =
bits(32) UNKNOWN;
906 MemA[address,4] = R[i];
907 address = address + 4;
911 if (registers<15> ==
'1')
912 MemA[address,4] = PCStoreValue();
918 bool success =
false;
919 if (ConditionPassed(opcode)) {
920 const uint32_t addr_byte_size = GetAddressByteSize();
928 registers =
Bits32(opcode, 7, 0);
930 if (
Bit32(opcode, 8))
931 registers |= (1u << 14);
938 registers =
Bits32(opcode, 15, 0) & ~0xa000;
944 Rt =
Bits32(opcode, 15, 12);
948 registers = (1u << Rt);
951 registers =
Bits32(opcode, 15, 0);
957 Rt =
Bits32(opcode, 15, 12);
961 registers = (1u << Rt);
971 context.
type = EmulateInstruction::eContextPushRegisterOnStack;
972 RegisterInfo reg_info;
975 for (i = 0; i < 15; ++i) {
979 uint32_t reg_value = ReadCoreReg(i, &success);
982 if (!MemAWrite(context, addr, reg_value, addr_byte_size))
984 addr += addr_byte_size;
994 if (!MemAWrite(context, addr,
pc, addr_byte_size))
998 context.
type = EmulateInstruction::eContextAdjustStackPointer;
1011 bool EmulateInstructionARM::EmulatePOP(
const uint32_t opcode,
1015 if (ConditionPassed())
1017 EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1020 if registers<i> ==
'1' then
1021 R[i] =
if UnalignedAllowed then MemU[address,4]
else MemA[address,4]; address = address + 4;
1022 if registers<15> ==
'1' then
1023 if UnalignedAllowed then
1024 LoadWritePC(MemU[address,4]);
1026 LoadWritePC(MemA[address,4]);
1027 if registers<13> ==
'0' then SP = SP + 4*
BitCount(registers);
1028 if registers<13> ==
'1' then SP =
bits(32) UNKNOWN;
1032 bool success =
false;
1034 if (ConditionPassed(opcode)) {
1035 const uint32_t addr_byte_size = GetAddressByteSize();
1043 registers =
Bits32(opcode, 7, 0);
1045 if (
Bit32(opcode, 8))
1046 registers |= (1u << 15);
1053 registers =
Bits32(opcode, 15, 0) & ~0x2000;
1060 if (
BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1064 Rt =
Bits32(opcode, 15, 12);
1069 if (Rt == 15 && InITBlock() && !LastInITBlock())
1071 registers = (1u << Rt);
1074 registers =
Bits32(opcode, 15, 0);
1084 Rt =
Bits32(opcode, 15, 12);
1088 registers = (1u << Rt);
1098 context.
type = EmulateInstruction::eContextPopRegisterOffStack;
1100 RegisterInfo sp_reg;
1103 for (i = 0; i < 15; ++i) {
1106 data = MemARead(context, addr, 4, 0, &success);
1112 addr += addr_byte_size;
1118 data = MemARead(context, addr, 4, 0, &success);
1122 if (!LoadWritePC(context, data))
1127 context.
type = EmulateInstruction::eContextAdjustStackPointer;
1139 bool EmulateInstructionARM::EmulateADDRdSPImm(
const uint32_t opcode,
1143 if (ConditionPassed())
1145 EncodingSpecificOperations();
1146 (result, carry, overflow) = AddWithCarry(SP, imm32,
'0');
1152 APSR.N = result<31>;
1153 APSR.Z = IsZeroBit(result);
1159 bool success =
false;
1161 if (ConditionPassed(opcode)) {
1170 imm32 =
Bits32(opcode, 7, 0) << 2;
1173 Rd =
Bits32(opcode, 15, 12);
1179 addr_t sp_offset = imm32;
1183 if (Rd == GetFramePointerRegisterNumber())
1184 context.
type = eContextSetFramePointer;
1186 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
1187 RegisterInfo sp_reg;
1200 bool EmulateInstructionARM::EmulateMOVRdSP(
const uint32_t opcode,
1204 if (ConditionPassed())
1206 EncodingSpecificOperations();
1213 APSR.N = result<31>;
1214 APSR.Z = IsZeroBit(result);
1220 bool success =
false;
1222 if (ConditionPassed(opcode)) {
1239 if (Rd == GetFramePointerRegisterNumber())
1240 context.
type = EmulateInstruction::eContextSetFramePointer;
1242 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
1243 RegisterInfo sp_reg;
1255 bool EmulateInstructionARM::EmulateMOVLowHigh(
const uint32_t opcode,
1257 return EmulateMOVRdRm(opcode, encoding);
1262 bool EmulateInstructionARM::EmulateMOVRdRm(
const uint32_t opcode,
1266 if (ConditionPassed())
1268 EncodingSpecificOperations();
1275 APSR.N = result<31>;
1276 APSR.Z = IsZeroBit(result);
1282 bool success =
false;
1284 if (ConditionPassed(opcode)) {
1290 Rd =
Bit32(opcode, 7) << 3 |
Bits32(opcode, 2, 0);
1291 Rm =
Bits32(opcode, 6, 3);
1293 if (Rd == 15 && InITBlock() && !LastInITBlock())
1297 Rd =
Bits32(opcode, 2, 0);
1298 Rm =
Bits32(opcode, 5, 3);
1304 Rd =
Bits32(opcode, 11, 8);
1305 Rm =
Bits32(opcode, 3, 0);
1312 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1316 Rd =
Bits32(opcode, 15, 12);
1317 Rm =
Bits32(opcode, 3, 0);
1322 if (Rd == 15 && setflags)
1323 return EmulateSUBSPcLrEtc(opcode, encoding);
1328 uint32_t result = ReadCoreReg(Rm, &success);
1335 context.
type = EmulateInstruction::eContextAdjustStackPointer;
1336 else if (Rd == GetFramePointerRegisterNumber() && Rm == 13)
1337 context.
type = EmulateInstruction::eContextSetFramePointer;
1339 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
1340 RegisterInfo dwarf_reg;
1344 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1353 bool EmulateInstructionARM::EmulateMOVRdImm(
const uint32_t opcode,
1357 if (ConditionPassed())
1359 EncodingSpecificOperations();
1366 APSR.N = result<31>;
1367 APSR.Z = IsZeroBit(result);
1373 if (ConditionPassed(opcode)) {
1383 Rd =
Bits32(opcode, 10, 8);
1384 setflags = !InITBlock();
1385 imm32 =
Bits32(opcode, 7, 0);
1391 Rd =
Bits32(opcode, 11, 8);
1402 Rd =
Bits32(opcode, 11, 8);
1408 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1418 Rd =
Bits32(opcode, 15, 12);
1424 if ((Rd == 15) && setflags)
1425 return EmulateSUBSPcLrEtc(opcode, encoding);
1431 Rd =
Bits32(opcode, 15, 12);
1435 imm32 = (imm4 << 12) | imm12;
1449 context.
type = EmulateInstruction::eContextImmediate;
1452 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1466 bool EmulateInstructionARM::EmulateMUL(
const uint32_t opcode,
1469 if ConditionPassed() then
1470 EncodingSpecificOperations();
1471 operand1 =
SInt(R[n]);
1472 operand2 =
SInt(R[m]);
1473 result = operand1 * operand2;
1474 R[d] = result<31:0>;
1476 APSR.N = result<31>;
1477 APSR.Z = IsZeroBit(result);
1478 if ArchVersion() == 4 then
1479 APSR.C =
bit UNKNOWN;
1484 if (ConditionPassed(opcode)) {
1494 d =
Bits32(opcode, 2, 0);
1495 n =
Bits32(opcode, 5, 3);
1496 m =
Bits32(opcode, 2, 0);
1497 setflags = !InITBlock();
1500 if ((ArchVersion() <
ARMv6) && (d == n))
1507 d =
Bits32(opcode, 11, 8);
1508 n =
Bits32(opcode, 19, 16);
1509 m =
Bits32(opcode, 3, 0);
1520 d =
Bits32(opcode, 19, 16);
1521 n =
Bits32(opcode, 3, 0);
1522 m =
Bits32(opcode, 11, 8);
1526 if ((d == 15) || (n == 15) || (m == 15))
1530 if ((ArchVersion() <
ARMv6) && (d == n))
1539 bool success =
false;
1556 uint64_t result = operand1 * operand2;
1559 RegisterInfo op1_reg;
1560 RegisterInfo op2_reg;
1565 context.
type = eContextArithmetic;
1569 (0x0000ffff & result)))
1576 m_new_inst_cpsr = m_opcode_cpsr;
1579 if (m_new_inst_cpsr != m_opcode_cpsr) {
1595 bool EmulateInstructionARM::EmulateMVNImm(
const uint32_t opcode,
1599 if (ConditionPassed())
1601 EncodingSpecificOperations();
1602 result =
NOT(imm32);
1608 APSR.N = result<31>;
1609 APSR.Z = IsZeroBit(result);
1615 if (ConditionPassed(opcode)) {
1622 Rd =
Bits32(opcode, 11, 8);
1627 Rd =
Bits32(opcode, 15, 12);
1633 if (Rd == 15 && setflags)
1634 return EmulateSUBSPcLrEtc(opcode, encoding);
1643 context.
type = EmulateInstruction::eContextImmediate;
1646 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1655 bool EmulateInstructionARM::EmulateMVNReg(
const uint32_t opcode,
1659 if (ConditionPassed())
1661 EncodingSpecificOperations();
1662 (shifted, carry) =
Shift_C(R[m], shift_t, shift_n, APSR.C);
1663 result =
NOT(shifted);
1669 APSR.N = result<31>;
1670 APSR.Z = IsZeroBit(result);
1676 if (ConditionPassed(opcode)) {
1685 Rd =
Bits32(opcode, 2, 0);
1686 Rm =
Bits32(opcode, 5, 3);
1687 setflags = !InITBlock();
1694 Rd =
Bits32(opcode, 11, 8);
1695 Rm =
Bits32(opcode, 3, 0);
1703 Rd =
Bits32(opcode, 15, 12);
1704 Rm =
Bits32(opcode, 3, 0);
1711 bool success =
false;
1712 uint32_t value = ReadCoreReg(Rm, &success);
1724 context.
type = EmulateInstruction::eContextImmediate;
1727 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1736 bool EmulateInstructionARM::EmulateLDRRtPCRelative(
const uint32_t opcode,
1740 if (ConditionPassed())
1742 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1744 address =
if add then (base + imm32)
else (base - imm32);
1745 data = MemU[address,4];
1747 if address<1:0> ==
'00' then LoadWritePC(data);
else UNPREDICTABLE;
1748 elsif UnalignedSupport() || address<1:0> =
'00' then
1751 if CurrentInstrSet() == InstrSet_ARM then
1752 R[t] =
ROR(data, 8*
UInt(address<1:0>));
1754 R[t] =
bits(32) UNKNOWN;
1758 if (ConditionPassed(opcode)) {
1759 bool success =
false;
1766 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
1767 RegisterInfo pc_reg;
1779 Rt =
Bits32(opcode, 10, 8);
1780 imm32 =
Bits32(opcode, 7, 0) << 2;
1784 Rt =
Bits32(opcode, 15, 12);
1785 imm32 =
Bits32(opcode, 11, 0) << 2;
1787 if (Rt == 15 && InITBlock() && !LastInITBlock())
1796 address = base + imm32;
1798 address = base - imm32;
1801 data = MemURead(context, address, 4, 0, &success);
1806 if (
Bits32(address, 1, 0) == 0) {
1808 if (!LoadWritePC(context, data))
1812 }
else if (UnalignedSupport() ||
Bits32(address, 1, 0) == 0) {
1824 bool EmulateInstructionARM::EmulateADDSPImm(
const uint32_t opcode,
1828 if (ConditionPassed())
1830 EncodingSpecificOperations();
1831 (result, carry, overflow) = AddWithCarry(SP, imm32,
'0');
1837 APSR.N = result<31>;
1838 APSR.Z = IsZeroBit(result);
1844 bool success =
false;
1846 if (ConditionPassed(opcode)) {
1856 d =
Bits32(opcode, 10, 8);
1857 imm32 = (
Bits32(opcode, 7, 0) << 2);
1871 d =
Bits32(opcode, 11, 8);
1873 setflags =
Bit32(opcode, 20);
1876 if (d == 15 && setflags == 1)
1880 if (d == 15 && setflags == 0)
1887 d =
Bits32(opcode, 11, 8);
1892 imm32 = (i << 11) | (imm3 << 8) | imm8;
1907 context.
type = EmulateInstruction::eContextAdjustStackPointer;
1909 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
1911 RegisterInfo sp_reg;
1916 if (!ALUWritePC(context, res.
result))
1925 if (!WriteCoreRegOptionalFlags(context, res.
result, d, setflags,
1935 bool EmulateInstructionARM::EmulateADDSPRm(
const uint32_t opcode,
1939 if (ConditionPassed())
1941 EncodingSpecificOperations();
1942 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
1943 (result, carry, overflow) = AddWithCarry(SP, shifted,
'0');
1949 APSR.N = result<31>;
1950 APSR.Z = IsZeroBit(result);
1956 bool success =
false;
1958 if (ConditionPassed(opcode)) {
1965 Rm =
Bits32(opcode, 6, 3);
1970 int32_t reg_value = ReadCoreReg(Rm, &success);
1974 addr_t addr = (int32_t)
sp + reg_value;
1977 context.
type = eContextArithmetic;
1978 RegisterInfo sp_reg;
1981 RegisterInfo other_reg;
1996 bool EmulateInstructionARM::EmulateBLXImmediate(
const uint32_t opcode,
2000 if (ConditionPassed())
2002 EncodingSpecificOperations();
2003 if CurrentInstrSet() == InstrSet_ARM then
2006 LR = PC<31:1> :
'1';
2007 if targetInstrSet == InstrSet_ARM then
2008 targetAddress =
Align(PC,4) + imm32;
2010 targetAddress = PC + imm32;
2011 SelectInstrSet(targetInstrSet);
2012 BranchWritePC(targetAddress);
2016 bool success =
true;
2018 if (ConditionPassed(opcode)) {
2020 context.
type = EmulateInstruction::eContextRelativeBranchImmediate;
2038 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2039 imm32 = llvm::SignExtend32<25>(imm25);
2040 target =
pc + imm32;
2041 SelectInstrSet(eModeThumb);
2043 if (InITBlock() && !LastInITBlock())
2057 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2058 imm32 = llvm::SignExtend32<25>(imm25);
2059 target =
Align(
pc, 4) + imm32;
2060 SelectInstrSet(eModeARM);
2062 if (InITBlock() && !LastInITBlock())
2068 imm32 = llvm::SignExtend32<26>(
Bits32(opcode, 23, 0) << 2);
2069 target =
Align(
pc, 4) + imm32;
2070 SelectInstrSet(eModeARM);
2075 imm32 = llvm::SignExtend32<26>(
Bits32(opcode, 23, 0) << 2 |
2076 Bits32(opcode, 24, 24) << 1);
2077 target =
pc + imm32;
2078 SelectInstrSet(eModeThumb);
2087 if (!BranchWritePC(context, target))
2089 if (m_opcode_cpsr != m_new_inst_cpsr)
2100 bool EmulateInstructionARM::EmulateBLXRm(
const uint32_t opcode,
2104 if (ConditionPassed())
2106 EncodingSpecificOperations();
2108 if CurrentInstrSet() == InstrSet_ARM then
2109 next_instr_addr = PC - 4;
2110 LR = next_instr_addr;
2112 next_instr_addr = PC - 2;
2113 LR = next_instr_addr<31:1> :
'1';
2118 bool success =
false;
2120 if (ConditionPassed(opcode)) {
2122 context.
type = EmulateInstruction::eContextAbsoluteBranchRegister;
2131 Rm =
Bits32(opcode, 6, 3);
2135 if (InITBlock() && !LastInITBlock())
2140 Rm =
Bits32(opcode, 3, 0);
2148 addr_t target = ReadCoreReg(Rm, &success);
2151 RegisterInfo dwarf_reg;
2157 if (!BXWritePC(context, target))
2165 bool EmulateInstructionARM::EmulateBXRm(
const uint32_t opcode,
2169 if (ConditionPassed())
2171 EncodingSpecificOperations();
2176 if (ConditionPassed(opcode)) {
2178 context.
type = EmulateInstruction::eContextAbsoluteBranchRegister;
2182 Rm =
Bits32(opcode, 6, 3);
2183 if (InITBlock() && !LastInITBlock())
2187 Rm =
Bits32(opcode, 3, 0);
2192 bool success =
false;
2193 addr_t target = ReadCoreReg(Rm, &success);
2197 RegisterInfo dwarf_reg;
2200 if (!BXWritePC(context, target))
2213 bool EmulateInstructionARM::EmulateBXJRm(
const uint32_t opcode,
2217 if (ConditionPassed())
2219 EncodingSpecificOperations();
2220 if JMCR.JE ==
'0' || CurrentInstrSet() == InstrSet_ThumbEE then
2223 if JazelleAcceptsExecution() then
2224 SwitchToJazelleExecution();
2226 SUBARCHITECTURE_DEFINED handler call;
2230 if (ConditionPassed(opcode)) {
2232 context.
type = EmulateInstruction::eContextAbsoluteBranchRegister;
2236 Rm =
Bits32(opcode, 19, 16);
2239 if (InITBlock() && !LastInITBlock())
2243 Rm =
Bits32(opcode, 3, 0);
2250 bool success =
false;
2251 addr_t target = ReadCoreReg(Rm, &success);
2255 RegisterInfo dwarf_reg;
2258 if (!BXWritePC(context, target))
2266 bool EmulateInstructionARM::EmulateSUBR7IPImm(
const uint32_t opcode,
2270 if (ConditionPassed())
2272 EncodingSpecificOperations();
2273 (result, carry, overflow) = AddWithCarry(SP,
NOT(imm32),
'1');
2279 APSR.N = result<31>;
2280 APSR.Z = IsZeroBit(result);
2286 if (ConditionPassed(opcode)) {
2287 bool success =
false;
2288 const addr_t ip = ReadCoreReg(12, &success);
2299 addr_t ip_offset = imm32;
2300 addr_t addr = ip - ip_offset;
2303 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
2304 RegisterInfo dwarf_reg;
2316 bool EmulateInstructionARM::EmulateSUBIPSPImm(
const uint32_t opcode,
2320 if (ConditionPassed())
2322 EncodingSpecificOperations();
2323 (result, carry, overflow) = AddWithCarry(SP,
NOT(imm32),
'1');
2329 APSR.N = result<31>;
2330 APSR.Z = IsZeroBit(result);
2336 if (ConditionPassed(opcode)) {
2337 bool success =
false;
2349 addr_t sp_offset = imm32;
2353 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
2354 RegisterInfo dwarf_reg;
2369 bool EmulateInstructionARM::EmulateSUBSPImm(
const uint32_t opcode,
2373 if (ConditionPassed())
2375 EncodingSpecificOperations();
2376 (result, carry, overflow) = AddWithCarry(SP,
NOT(imm32),
'1');
2382 APSR.N = result<31>;
2383 APSR.Z = IsZeroBit(result);
2389 bool success =
false;
2390 if (ConditionPassed(opcode)) {
2405 Rd =
Bits32(opcode, 11, 8);
2408 if (Rd == 15 && setflags)
2409 return EmulateCMPImm(opcode, eEncodingT2);
2410 if (Rd == 15 && !setflags)
2414 Rd =
Bits32(opcode, 11, 8);
2421 Rd =
Bits32(opcode, 15, 12);
2427 if (Rd == 15 && setflags)
2428 return EmulateSUBSPcLrEtc(opcode, encoding);
2437 uint64_t imm64 = imm32;
2440 context.
type = EmulateInstruction::eContextAdjustStackPointer;
2443 context.
type = EmulateInstruction::eContextImmediate;
2447 if (!WriteCoreRegOptionalFlags(context, res.
result, Rd, setflags,
2455 bool EmulateInstructionARM::EmulateSTRRtSP(
const uint32_t opcode,
2459 if (ConditionPassed())
2461 EncodingSpecificOperations();
2462 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
2463 address =
if index then offset_addr
else R[n];
2464 MemU[address,4] =
if t == 15 then PCStoreValue()
else R[t];
2465 if wback then R[n] = offset_addr;
2469 bool success =
false;
2470 if (ConditionPassed(opcode)) {
2471 const uint32_t addr_byte_size = GetAddressByteSize();
2485 Rt =
Bits32(opcode, 15, 12);
2486 imm12 =
Bits32(opcode, 11, 0);
2487 Rn =
Bits32(opcode, 19, 16);
2496 if (wback && ((Rn == 15) || (Rn == Rt)))
2504 offset_addr =
sp + imm12;
2506 offset_addr =
sp - imm12;
2515 context.
type = EmulateInstruction::eContextPushRegisterOnStack;
2516 RegisterInfo sp_reg;
2517 RegisterInfo dwarf_reg;
2523 uint32_t reg_value = ReadCoreReg(Rt, &success);
2526 if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2532 if (!MemUWrite(context, addr,
pc, addr_byte_size))
2537 context.
type = EmulateInstruction::eContextAdjustStackPointer;
2549 bool EmulateInstructionARM::EmulateVPUSH(
const uint32_t opcode,
2553 if (ConditionPassed())
2555 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2556 address = SP - imm32;
2560 MemA[address,4] = S[d+r]; address = address+4;
2565 MemA[address,4] =
if BigEndian() then D[d+r]<63:32>
else D[d+r]<31:0>;
2566 MemA[address+4,4] =
if BigEndian() then D[d+r]<31:0>
else D[d+r]<63:32>;
2567 address = address+8;
2571 bool success =
false;
2572 if (ConditionPassed(opcode)) {
2573 const uint32_t addr_byte_size = GetAddressByteSize();
2584 single_regs =
false;
2585 d =
Bit32(opcode, 22) << 4 |
Bits32(opcode, 15, 12);
2586 imm32 =
Bits32(opcode, 7, 0) * addr_byte_size;
2588 regs =
Bits32(opcode, 7, 0) / 2;
2590 if (regs == 0 || regs > 16 || (d + regs) > 32)
2596 d =
Bits32(opcode, 15, 12) << 1 |
Bit32(opcode, 22);
2597 imm32 =
Bits32(opcode, 7, 0) * addr_byte_size;
2598 regs =
Bits32(opcode, 7, 0);
2600 if (regs == 0 || regs > 16 || (d + regs) > 32)
2607 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2608 addr_t sp_offset = imm32;
2613 context.
type = EmulateInstruction::eContextPushRegisterOnStack;
2615 RegisterInfo dwarf_reg;
2616 RegisterInfo sp_reg;
2618 for (i = 0; i < regs; ++i) {
2622 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
2625 if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2627 addr += reg_byte_size;
2630 context.
type = EmulateInstruction::eContextAdjustStackPointer;
2642 bool EmulateInstructionARM::EmulateVPOP(
const uint32_t opcode,
2646 if (ConditionPassed())
2648 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2653 S[d+r] = MemA[address,4]; address = address+4;
2656 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2659 D[d+r] =
if BigEndian() then word1:word2
else word2:word1;
2663 bool success =
false;
2664 if (ConditionPassed(opcode)) {
2665 const uint32_t addr_byte_size = GetAddressByteSize();
2676 single_regs =
false;
2677 d =
Bit32(opcode, 22) << 4 |
Bits32(opcode, 15, 12);
2678 imm32 =
Bits32(opcode, 7, 0) * addr_byte_size;
2680 regs =
Bits32(opcode, 7, 0) / 2;
2682 if (regs == 0 || regs > 16 || (d + regs) > 32)
2688 d =
Bits32(opcode, 15, 12) << 1 |
Bit32(opcode, 22);
2689 imm32 =
Bits32(opcode, 7, 0) * addr_byte_size;
2690 regs =
Bits32(opcode, 7, 0);
2692 if (regs == 0 || regs > 16 || (d + regs) > 32)
2699 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2700 addr_t sp_offset = imm32;
2706 context.
type = EmulateInstruction::eContextPopRegisterOffStack;
2708 RegisterInfo dwarf_reg;
2709 RegisterInfo sp_reg;
2711 for (i = 0; i < regs; ++i) {
2714 data = MemARead(context, addr, reg_byte_size, 0, &success);
2717 if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2719 addr += reg_byte_size;
2722 context.
type = EmulateInstruction::eContextAdjustStackPointer;
2733 bool EmulateInstructionARM::EmulateSVC(
const uint32_t opcode,
2737 if (ConditionPassed())
2739 EncodingSpecificOperations();
2744 bool success =
false;
2746 if (ConditionPassed(opcode)) {
2756 imm32 =
Bits32(opcode, 7, 0);
2761 imm32 =
Bits32(opcode, 23, 0);
2769 context.
type = EmulateInstruction::eContextSupervisorCall;
2779 bool EmulateInstructionARM::EmulateIT(
const uint32_t opcode,
2783 EncodingSpecificOperations();
2784 ITSTATE.IT<7:0> = firstcond:mask;
2787 m_it_session.InitIT(
Bits32(opcode, 7, 0));
2791 bool EmulateInstructionARM::EmulateNop(
const uint32_t opcode,
2798 bool EmulateInstructionARM::EmulateB(
const uint32_t opcode,
2802 if (ConditionPassed())
2804 EncodingSpecificOperations();
2805 BranchWritePC(PC + imm32);
2809 bool success =
false;
2811 if (ConditionPassed(opcode)) {
2813 context.
type = EmulateInstruction::eContextRelativeBranchImmediate;
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)
2844 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2845 imm32 = llvm::SignExtend32<21>(imm21);
2846 target =
pc + imm32;
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;
2873 if (!BranchWritePC(context, target))
2882 bool EmulateInstructionARM::EmulateCB(
const uint32_t opcode,
2886 EncodingSpecificOperations();
2887 if nonzero ^
IsZero(R[n]) then
2888 BranchWritePC(PC + imm32);
2891 bool success =
false;
2899 context.
type = EmulateInstruction::eContextRelativeBranchImmediate;
2909 imm32 =
Bit32(opcode, 9) << 6 |
Bits32(opcode, 7, 3) << 1;
2911 target =
pc + imm32;
2917 if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2918 if (!BranchWritePC(context, target))
2936 bool EmulateInstructionARM::EmulateTB(
const uint32_t opcode,
2940 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2942 halfwords =
UInt(MemU[R[n]+
LSL(R[m],1), 2]);
2944 halfwords =
UInt(MemU[R[n]+R[m], 1]);
2945 BranchWritePC(PC + 2*halfwords);
2948 bool success =
false;
2950 if (ConditionPassed(opcode)) {
2958 Rn =
Bits32(opcode, 19, 16);
2959 Rm =
Bits32(opcode, 3, 0);
2961 if (Rn == 13 ||
BadReg(Rm))
2963 if (InITBlock() && !LastInITBlock())
2972 uint32_t base = ReadCoreReg(Rn, &success);
2977 uint32_t index = ReadCoreReg(Rm, &success);
2982 addr_t addr = base + (is_tbh ? index * 2 : index);
2986 context.
type = EmulateInstruction::eContextTableBranchReadMemory;
2987 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2997 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2998 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
3000 if (!BranchWritePC(context, target))
3010 bool EmulateInstructionARM::EmulateADDImmThumb(
const uint32_t opcode,
3013 if ConditionPassed() then
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;
3026 if (ConditionPassed(opcode)) {
3038 d =
Bits32(opcode, 2, 0);
3039 n =
Bits32(opcode, 5, 3);
3040 setflags = !InITBlock();
3041 imm32 =
Bits32(opcode, 8, 6);
3048 d =
Bits32(opcode, 10, 8);
3049 n =
Bits32(opcode, 10, 8);
3050 setflags = !InITBlock();
3051 imm32 =
Bits32(opcode, 7, 0);
3059 d =
Bits32(opcode, 11, 8);
3060 n =
Bits32(opcode, 19, 16);
3066 return EmulateADDSPImm(opcode, eEncodingT3);
3069 if (
BadReg(d) || (n == 15))
3078 d =
Bits32(opcode, 11, 8);
3079 n =
Bits32(opcode, 19, 16);
3084 imm32 = (i << 11) | (imm3 << 8) | imm8;
3088 return EmulateADDSPImm(opcode, eEncodingT4);
3113 context.
type = eContextArithmetic;
3122 if (!WriteCoreRegOptionalFlags(context, res.
result, d, setflags,
3132 bool EmulateInstructionARM::EmulateADDImmARM(
const uint32_t opcode,
3136 if ConditionPassed() then
3137 EncodingSpecificOperations();
3138 (result, carry, overflow) = AddWithCarry(R[n], imm32,
'0');
3144 APSR.N = result<31>;
3145 APSR.Z = IsZeroBit(result);
3150 bool success =
false;
3152 if (ConditionPassed(opcode)) {
3159 Rd =
Bits32(opcode, 15, 12);
3160 Rn =
Bits32(opcode, 19, 16);
3169 uint32_t val1 = ReadCoreReg(Rn, &success);
3177 context.
type = EmulateInstruction::eContextAdjustStackPointer;
3178 else if (Rd == GetFramePointerRegisterNumber())
3179 context.
type = EmulateInstruction::eContextSetFramePointer;
3181 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
3183 RegisterInfo dwarf_reg;
3187 if (!WriteCoreRegOptionalFlags(context, res.
result, Rd, setflags,
3197 bool EmulateInstructionARM::EmulateADDReg(
const uint32_t opcode,
3201 if ConditionPassed() then
3202 EncodingSpecificOperations();
3203 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
3204 (result, carry, overflow) = AddWithCarry(R[n], shifted,
'0');
3210 APSR.N = result<31>;
3211 APSR.Z = IsZeroBit(result);
3216 bool success =
false;
3218 if (ConditionPassed(opcode)) {
3225 Rd =
Bits32(opcode, 2, 0);
3226 Rn =
Bits32(opcode, 5, 3);
3227 Rm =
Bits32(opcode, 8, 6);
3228 setflags = !InITBlock();
3233 Rd = Rn =
Bit32(opcode, 7) << 3 |
Bits32(opcode, 2, 0);
3234 Rm =
Bits32(opcode, 6, 3);
3238 if (Rn == 15 && Rm == 15)
3240 if (Rd == 15 && InITBlock() && !LastInITBlock())
3244 Rd =
Bits32(opcode, 15, 12);
3245 Rn =
Bits32(opcode, 19, 16);
3246 Rm =
Bits32(opcode, 3, 0);
3255 uint32_t val1 = ReadCoreReg(Rn, &success);
3260 uint32_t val2 = ReadCoreReg(Rm, &success);
3270 context.
type = eContextArithmetic;
3271 RegisterInfo op1_reg;
3272 RegisterInfo op2_reg;
3277 if (!WriteCoreRegOptionalFlags(context, res.
result, Rd, setflags,
3286 bool EmulateInstructionARM::EmulateCMNImm(
const uint32_t opcode,
3290 if ConditionPassed() then
3291 EncodingSpecificOperations();
3292 (result, carry, overflow) = AddWithCarry(R[n], imm32,
'0');
3293 APSR.N = result<31>;
3294 APSR.Z = IsZeroBit(result);
3299 bool success =
false;
3305 Rn =
Bits32(opcode, 19, 16);
3311 Rn =
Bits32(opcode, 19, 16);
3318 uint32_t reg_val = ReadCoreReg(Rn, &success);
3325 context.
type = EmulateInstruction::eContextImmediate;
3333 bool EmulateInstructionARM::EmulateCMNReg(
const uint32_t opcode,
3337 if ConditionPassed() then
3338 EncodingSpecificOperations();
3339 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
3340 (result, carry, overflow) = AddWithCarry(R[n], shifted,
'0');
3341 APSR.N = result<31>;
3342 APSR.Z = IsZeroBit(result);
3347 bool success =
false;
3355 Rn =
Bits32(opcode, 2, 0);
3356 Rm =
Bits32(opcode, 5, 3);
3361 Rn =
Bits32(opcode, 19, 16);
3362 Rm =
Bits32(opcode, 3, 0);
3365 if (Rn == 15 ||
BadReg(Rm))
3369 Rn =
Bits32(opcode, 19, 16);
3370 Rm =
Bits32(opcode, 3, 0);
3377 uint32_t val1 = ReadCoreReg(Rn, &success);
3382 uint32_t val2 = ReadCoreReg(Rm, &success);
3392 context.
type = EmulateInstruction::eContextImmediate;
3399 bool EmulateInstructionARM::EmulateCMPImm(
const uint32_t opcode,
3403 if ConditionPassed() then
3404 EncodingSpecificOperations();
3405 (result, carry, overflow) = AddWithCarry(R[n],
NOT(imm32),
'1');
3406 APSR.N = result<31>;
3407 APSR.Z = IsZeroBit(result);
3412 bool success =
false;
3418 Rn =
Bits32(opcode, 10, 8);
3419 imm32 =
Bits32(opcode, 7, 0);
3422 Rn =
Bits32(opcode, 19, 16);
3428 Rn =
Bits32(opcode, 19, 16);
3435 uint32_t reg_val = ReadCoreReg(Rn, &success);
3442 context.
type = EmulateInstruction::eContextImmediate;
3450 bool EmulateInstructionARM::EmulateCMPReg(
const uint32_t opcode,
3454 if ConditionPassed() then
3455 EncodingSpecificOperations();
3456 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
3457 (result, carry, overflow) = AddWithCarry(R[n],
NOT(shifted),
'1');
3458 APSR.N = result<31>;
3459 APSR.Z = IsZeroBit(result);
3464 bool success =
false;
3472 Rn =
Bits32(opcode, 2, 0);
3473 Rm =
Bits32(opcode, 5, 3);
3478 Rn =
Bit32(opcode, 7) << 3 |
Bits32(opcode, 2, 0);
3479 Rm =
Bits32(opcode, 6, 3);
3482 if (Rn < 8 && Rm < 8)
3484 if (Rn == 15 || Rm == 15)
3488 Rn =
Bits32(opcode, 19, 16);
3489 Rm =
Bits32(opcode, 3, 0);
3491 if (Rn == 15 ||
BadReg(Rm))
3495 Rn =
Bits32(opcode, 19, 16);
3496 Rm =
Bits32(opcode, 3, 0);
3503 uint32_t val1 = ReadCoreReg(Rn, &success);
3508 uint32_t val2 = ReadCoreReg(Rm, &success);
3518 context.
type = EmulateInstruction::eContextImmediate;
3527 bool EmulateInstructionARM::EmulateASRImm(
const uint32_t opcode,
3531 if ConditionPassed() then
3532 EncodingSpecificOperations();
3539 APSR.N = result<31>;
3540 APSR.Z = IsZeroBit(result);
3545 return EmulateShiftImm(opcode, encoding,
SRType_ASR);
3553 bool EmulateInstructionARM::EmulateASRReg(
const uint32_t opcode,
3557 if ConditionPassed() then
3558 EncodingSpecificOperations();
3559 shift_n =
UInt(R[m]<7:0>);
3563 APSR.N = result<31>;
3564 APSR.Z = IsZeroBit(result);
3569 return EmulateShiftReg(opcode, encoding,
SRType_ASR);
3575 bool EmulateInstructionARM::EmulateLSLImm(
const uint32_t opcode,
3579 if ConditionPassed() then
3580 EncodingSpecificOperations();
3587 APSR.N = result<31>;
3588 APSR.Z = IsZeroBit(result);
3593 return EmulateShiftImm(opcode, encoding,
SRType_LSL);
3600 bool EmulateInstructionARM::EmulateLSLReg(
const uint32_t opcode,
3604 if ConditionPassed() then
3605 EncodingSpecificOperations();
3606 shift_n =
UInt(R[m]<7:0>);
3610 APSR.N = result<31>;
3611 APSR.Z = IsZeroBit(result);
3616 return EmulateShiftReg(opcode, encoding,
SRType_LSL);
3623 bool EmulateInstructionARM::EmulateLSRImm(
const uint32_t opcode,
3627 if ConditionPassed() then
3628 EncodingSpecificOperations();
3635 APSR.N = result<31>;
3636 APSR.Z = IsZeroBit(result);
3641 return EmulateShiftImm(opcode, encoding,
SRType_LSR);
3648 bool EmulateInstructionARM::EmulateLSRReg(
const uint32_t opcode,
3652 if ConditionPassed() then
3653 EncodingSpecificOperations();
3654 shift_n =
UInt(R[m]<7:0>);
3658 APSR.N = result<31>;
3659 APSR.Z = IsZeroBit(result);
3664 return EmulateShiftReg(opcode, encoding,
SRType_LSR);
3671 bool EmulateInstructionARM::EmulateRORImm(
const uint32_t opcode,
3675 if ConditionPassed() then
3676 EncodingSpecificOperations();
3683 APSR.N = result<31>;
3684 APSR.Z = IsZeroBit(result);
3689 return EmulateShiftImm(opcode, encoding,
SRType_ROR);
3697 bool EmulateInstructionARM::EmulateRORReg(
const uint32_t opcode,
3701 if ConditionPassed() then
3702 EncodingSpecificOperations();
3703 shift_n =
UInt(R[m]<7:0>);
3707 APSR.N = result<31>;
3708 APSR.Z = IsZeroBit(result);
3713 return EmulateShiftReg(opcode, encoding,
SRType_ROR);
3721 bool EmulateInstructionARM::EmulateRRX(
const uint32_t opcode,
3725 if ConditionPassed() then
3726 EncodingSpecificOperations();
3733 APSR.N = result<31>;
3734 APSR.Z = IsZeroBit(result);
3739 return EmulateShiftImm(opcode, encoding,
SRType_RRX);
3742 bool EmulateInstructionARM::EmulateShiftImm(
const uint32_t opcode,
3751 bool success =
false;
3753 if (ConditionPassed(opcode)) {
3763 if (shift_type ==
SRType_ROR && use_encoding == eEncodingT1) {
3767 use_encoding = eEncodingT2;
3770 switch (use_encoding) {
3776 Rd =
Bits32(opcode, 2, 0);
3777 Rm =
Bits32(opcode, 5, 3);
3778 setflags = !InITBlock();
3779 imm5 =
Bits32(opcode, 10, 6);
3787 Rd =
Bits32(opcode, 11, 8);
3788 Rm =
Bits32(opcode, 3, 0);
3790 imm5 =
Bits32(opcode, 14, 12) << 2 |
Bits32(opcode, 7, 6);
3795 Rd =
Bits32(opcode, 15, 12);
3796 Rm =
Bits32(opcode, 3, 0);
3798 imm5 =
Bits32(opcode, 11, 7);
3809 uint32_t value = ReadCoreReg(Rm, &success);
3823 context.
type = EmulateInstruction::eContextImmediate;
3826 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3832 bool EmulateInstructionARM::EmulateShiftReg(
const uint32_t opcode,
3840 bool success =
false;
3842 if (ConditionPassed(opcode)) {
3851 Rd =
Bits32(opcode, 2, 0);
3853 Rm =
Bits32(opcode, 5, 3);
3854 setflags = !InITBlock();
3857 Rd =
Bits32(opcode, 11, 8);
3858 Rn =
Bits32(opcode, 19, 16);
3859 Rm =
Bits32(opcode, 3, 0);
3865 Rd =
Bits32(opcode, 15, 12);
3866 Rn =
Bits32(opcode, 3, 0);
3867 Rm =
Bits32(opcode, 11, 8);
3869 if (Rd == 15 || Rn == 15 || Rm == 15)
3877 uint32_t value = ReadCoreReg(Rn, &success);
3881 uint32_t val = ReadCoreReg(Rm, &success);
3894 context.
type = EmulateInstruction::eContextImmediate;
3897 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3906 bool EmulateInstructionARM::EmulateLDM(
const uint32_t opcode,
3910 if ConditionPassed()
3911 EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3915 if registers<i> ==
'1' then
3916 R[i] = MemA[address, 4]; address = address + 4;
3917 if registers<15> ==
'1' then
3918 LoadWritePC (MemA[address, 4]);
3920 if wback && registers<n> ==
'0' then R[n] = R[n] + 4 *
BitCount (registers);
3921 if wback && registers<n> ==
'1' then R[n] =
bits(32) UNKNOWN;
3925 bool success =
false;
3926 if (ConditionPassed(opcode)) {
3930 const uint32_t addr_byte_size = GetAddressByteSize();
3935 n =
Bits32(opcode, 10, 8);
3936 registers =
Bits32(opcode, 7, 0);
3937 registers = registers & 0x00ff;
3946 n =
Bits32(opcode, 19, 16);
3947 registers =
Bits32(opcode, 15, 0);
3948 registers = registers & 0xdfff;
3953 if ((n == 15) || (
BitCount(registers) < 2) ||
3959 if (
BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3963 if (wback &&
BitIsSet(registers, n))
3968 n =
Bits32(opcode, 19, 16);
3969 registers =
Bits32(opcode, 15, 0);
3971 if ((n == 15) || (
BitCount(registers) < 1))
3979 const addr_t base_address =
3985 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
3986 RegisterInfo dwarf_reg;
3990 for (
int i = 0; i < 14; ++i) {
3992 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
3994 if (wback && (n == 13))
3996 context.
type = EmulateInstruction::eContextPopRegisterOffStack;
4001 uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
4010 offset += addr_byte_size;
4016 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
4019 MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4023 if (!LoadWritePC(context, data))
4029 int32_t offset = addr_byte_size *
BitCount(registers);
4030 context.
type = EmulateInstruction::eContextAdjustBaseRegister;
4034 base_address + offset))
4037 if (wback &&
BitIsSet(registers, n))
4039 return WriteBits32Unknown(n);
4049 bool EmulateInstructionARM::EmulateLDMDA(
const uint32_t opcode,
4053 if ConditionPassed() then
4054 EncodingSpecificOperations();
4055 address = R[n] - 4*
BitCount(registers) + 4;
4058 if registers<i> ==
'1' then
4059 R[i] = MemA[address,4]; address = address + 4;
4061 if registers<15> ==
'1' then
4062 LoadWritePC(MemA[address,4]);
4064 if wback && registers<n> ==
'0' then R[n] = R[n] - 4*
BitCount(registers);
4065 if wback && registers<n> ==
'1' then R[n] =
bits(32) UNKNOWN;
4068 bool success =
false;
4070 if (ConditionPassed(opcode)) {
4074 const uint32_t addr_byte_size = GetAddressByteSize();
4080 n =
Bits32(opcode, 19, 16);
4081 registers =
Bits32(opcode, 15, 0);
4085 if ((n == 15) || (
BitCount(registers) < 1))
4096 addr_t Rn = ReadCoreReg(n, &success);
4102 Rn - (addr_byte_size *
BitCount(registers)) + addr_byte_size;
4105 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
4106 RegisterInfo dwarf_reg;
4108 context.SetRegisterPlusOffset(dwarf_reg, offset);
4111 for (
int i = 0; i < 14; ++i) {
4115 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4117 MemARead(context, address + offset, addr_byte_size, 0, &success);
4123 offset += addr_byte_size;
4130 context.SetRegisterPlusOffset(dwarf_reg, offset);
4132 MemARead(context, address + offset, addr_byte_size, 0, &success);
4136 if (!LoadWritePC(context, data))
4145 offset = (addr_byte_size *
BitCount(registers)) * -1;
4146 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4147 context.SetImmediateSigned(offset);
4148 addr_t addr = Rn + offset;
4155 if (wback &&
BitIsSet(registers, n))
4156 return WriteBits32Unknown(n);
4166 bool EmulateInstructionARM::EmulateLDMDB(
const uint32_t opcode,
4170 if ConditionPassed() then
4171 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4172 address = R[n] - 4*
BitCount(registers);
4175 if registers<i> ==
'1' then
4176 R[i] = MemA[address,4]; address = address + 4;
4177 if registers<15> ==
'1' then
4178 LoadWritePC(MemA[address,4]);
4180 if wback && registers<n> ==
'0' then R[n] = R[n] - 4*
BitCount(registers);
4181 if wback && registers<n> ==
'1' then R[n] =
bits(32) UNKNOWN;
4184 bool success =
false;
4186 if (ConditionPassed(opcode)) {
4190 const uint32_t addr_byte_size = GetAddressByteSize();
4194 n =
Bits32(opcode, 19, 16);
4195 registers =
Bits32(opcode, 15, 0);
4196 registers = registers & 0xdfff;
4201 if ((n == 15) || (
BitCount(registers) < 2) ||
4207 if (
BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4211 if (wback &&
BitIsSet(registers, n))
4218 n =
Bits32(opcode, 19, 16);
4219 registers =
Bits32(opcode, 15, 0);
4223 if ((n == 15) || (
BitCount(registers) < 1))
4243 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
4244 RegisterInfo dwarf_reg;
4246 context.SetRegisterPlusOffset(dwarf_reg, Rn - address);
4248 for (
int i = 0; i < 14; ++i) {
4251 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4253 MemARead(context, address + offset, addr_byte_size, 0, &success);
4261 offset += addr_byte_size;
4268 context.SetRegisterPlusOffset(dwarf_reg, offset);
4270 MemARead(context, address + offset, addr_byte_size, 0, &success);
4274 if (!LoadWritePC(context, data))
4283 offset = (addr_byte_size *
BitCount(registers)) * -1;
4284 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4285 context.SetImmediateSigned(offset);
4286 addr_t addr = Rn + offset;
4294 if (wback &&
BitIsSet(registers, n))
4295 return WriteBits32Unknown(n);
4305 bool EmulateInstructionARM::EmulateLDMIB(
const uint32_t opcode,
4308 if ConditionPassed() then
4309 EncodingSpecificOperations();
4313 if registers<i> ==
'1' then
4314 R[i] = MemA[address,4]; address = address + 4;
4315 if registers<15> ==
'1' then
4316 LoadWritePC(MemA[address,4]);
4318 if wback && registers<n> ==
'0' then R[n] = R[n] + 4*
BitCount(registers);
4319 if wback && registers<n> ==
'1' then R[n] =
bits(32) UNKNOWN;
4322 bool success =
false;
4324 if (ConditionPassed(opcode)) {
4328 const uint32_t addr_byte_size = GetAddressByteSize();
4332 n =
Bits32(opcode, 19, 16);
4333 registers =
Bits32(opcode, 15, 0);
4337 if ((n == 15) || (
BitCount(registers) < 1))
4353 addr_t address = Rn + addr_byte_size;
4356 context.
type = EmulateInstruction::eContextRegisterPlusOffset;
4357 RegisterInfo dwarf_reg;
4361 for (
int i = 0; i < 14; ++i) {
4367 MemARead(context, address + offset, addr_byte_size, 0, &success);
4375 offset += addr_byte_size;
4384 MemARead(context, address + offset, addr_byte_size, 0, &success);
4388 if (!LoadWritePC(context, data))
4397 offset = addr_byte_size *
BitCount(registers);
4398 context.
type = EmulateInstruction::eContextAdjustBaseRegister;
4400 addr_t addr = Rn + offset;
4408 if (wback &&
BitIsSet(registers, n))
4409 return WriteBits32Unknown(n);
4417 bool EmulateInstructionARM::EmulateLDRRtRnImm(
const uint32_t opcode,
4421 if (ConditionPassed())
4423 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4424 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
4425 address =
if index then offset_addr
else R[n];
4426 data = MemU[address,4];
4427 if wback then R[n] = offset_addr;
4429 if address<1:0> ==
'00' then LoadWritePC(data);
else UNPREDICTABLE;
4430 elsif UnalignedSupport() || address<1:0> =
'00' then
4432 else R[t] =
bits(32) UNKNOWN;
4436 bool success =
false;
4438 if (ConditionPassed(opcode)) {
4445 bool add, index, wback;
4448 Rt =
Bits32(opcode, 2, 0);
4449 Rn =
Bits32(opcode, 5, 3);
4450 imm32 =
Bits32(opcode, 10, 6) << 2;
4460 Rt =
Bits32(opcode, 10, 8);
4462 imm32 =
Bits32(opcode, 7, 0) << 2;
4474 Rt =
Bits32(opcode, 15, 12);
4475 Rn =
Bits32(opcode, 19, 16);
4476 imm32 =
Bits32(opcode, 11, 0);
4484 if ((Rt == 15) && InITBlock() && !LastInITBlock())
4499 Rt =
Bits32(opcode, 15, 12);
4500 Rn =
Bits32(opcode, 19, 16);
4501 imm32 =
Bits32(opcode, 7, 0);
4510 if ((wback && (Rn == Rt)) ||
4511 ((Rt == 15) && InITBlock() && !LastInITBlock()))
4519 uint32_t base = ReadCoreReg(Rn, &success);
4523 offset_addr = base + imm32;
4525 offset_addr = base - imm32;
4527 address = (index ? offset_addr : base);
4529 RegisterInfo base_reg;
4534 ctx.
type = eContextAdjustStackPointer;
4536 }
else if (Rn == GetFramePointerRegisterNumber()) {
4537 ctx.
type = eContextSetFramePointer;
4540 ctx.
type = EmulateInstruction::eContextAdjustBaseRegister;
4551 context.
type = EmulateInstruction::eContextRegisterLoad;
4555 data = MemURead(context, address, 4, 0, &success);
4560 if (
Bits32(address, 1, 0) == 0) {
4561 if (!LoadWritePC(context, data))
4565 }
else if (UnalignedSupport() ||
Bits32(address, 1, 0) == 0) {
4570 WriteBits32Unknown(Rt);
4580 bool EmulateInstructionARM::EmulateSTM(
const uint32_t opcode,
4583 if ConditionPassed() then
4584 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4588 if registers<i> ==
'1' then
4589 if i == n && wback && i != LowestSetBit(registers) then
4590 MemA[address,4] =
bits(32) UNKNOWN;
4592 MemA[address,4] = R[i];
4593 address = address + 4;
4595 if registers<15> ==
'1' then
4596 MemA[address,4] = PCStoreValue();
4597 if wback then R[n] = R[n] + 4*
BitCount(registers);
4600 bool success =
false;
4602 if (ConditionPassed(opcode)) {
4606 const uint32_t addr_byte_size = GetAddressByteSize();
4612 n =
Bits32(opcode, 10, 8);
4613 registers =
Bits32(opcode, 7, 0);
4614 registers = registers & 0x00ff;
4625 n =
Bits32(opcode, 19, 16);
4626 registers =
Bits32(opcode, 15, 0);
4627 registers = registers & 0x5fff;
4631 if ((n == 15) || (
BitCount(registers) < 2))
4635 if (wback &&
BitIsSet(registers, n))
4642 n =
Bits32(opcode, 19, 16);
4643 registers =
Bits32(opcode, 15, 0);
4647 if ((n == 15) || (
BitCount(registers) < 1))
4664 context.
type = EmulateInstruction::eContextRegisterStore;
4665 RegisterInfo base_reg;
4670 for (
uint32_t i = 0; i < 14; ++i) {
4673 if (i < lowest_set_bit)
4676 if ((i == n) && wback && (i != lowest_set_bit))
4679 WriteBits32UnknownToMemory(address + offset);
4687 RegisterInfo data_reg;
4690 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4695 offset += addr_byte_size;
4702 RegisterInfo pc_reg;
4709 if (!MemAWrite(context, address + offset,
pc, addr_byte_size))
4715 offset = addr_byte_size *
BitCount(registers);
4716 context.
type = EmulateInstruction::eContextAdjustBaseRegister;
4718 addr_t data = address + offset;
4732 bool EmulateInstructionARM::EmulateSTMDA(
const uint32_t opcode,
4735 if ConditionPassed() then
4736 EncodingSpecificOperations();
4737 address = R[n] - 4*
BitCount(registers) + 4;
4740 if registers<i> ==
'1' then
4741 if i == n && wback && i != LowestSetBit(registers) then
4742 MemA[address,4] =
bits(32) UNKNOWN;
4744 MemA[address,4] = R[i];
4745 address = address + 4;
4747 if registers<15> ==
'1' then
4748 MemA[address,4] = PCStoreValue();
4750 if wback then R[n] = R[n] - 4*
BitCount(registers);
4753 bool success =
false;
4755 if (ConditionPassed(opcode)) {
4759 const uint32_t addr_byte_size = GetAddressByteSize();
4765 n =
Bits32(opcode, 19, 16);
4766 registers =
Bits32(opcode, 15, 0);
4770 if ((n == 15) || (
BitCount(registers) < 1))
4779 addr_t Rn = ReadCoreReg(n, &success);
4783 addr_t address = Rn - (addr_byte_size *
BitCount(registers)) + 4;
4786 context.
type = EmulateInstruction::eContextRegisterStore;
4787 RegisterInfo base_reg;
4792 for (
uint32_t i = 0; i < 14; ++i) {
4795 if (i < lowest_bit_set)
4798 if ((i == n) && wback && (i != lowest_bit_set))
4800 WriteBits32UnknownToMemory(address + offset);
4808 RegisterInfo data_reg;
4810 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4811 Rn - (address + offset));
4812 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4817 offset += addr_byte_size;
4824 RegisterInfo pc_reg;
4826 context.SetRegisterPlusOffset(pc_reg, 8);
4831 if (!MemAWrite(context, address + offset,
pc, addr_byte_size))
4837 offset = (addr_byte_size *
BitCount(registers)) * -1;
4838 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4839 context.SetImmediateSigned(offset);
4840 addr_t data = Rn + offset;
4854 bool EmulateInstructionARM::EmulateSTMDB(
const uint32_t opcode,
4857 if ConditionPassed() then
4858 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4859 address = R[n] - 4*
BitCount(registers);
4862 if registers<i> ==
'1' then
4863 if i == n && wback && i != LowestSetBit(registers) then
4864 MemA[address,4] =
bits(32) UNKNOWN;
4866 MemA[address,4] = R[i];
4867 address = address + 4;
4869 if registers<15> ==
'1' then
4870 MemA[address,4] = PCStoreValue();
4872 if wback then R[n] = R[n] - 4*
BitCount(registers);
4875 bool success =
false;
4877 if (ConditionPassed(opcode)) {
4881 const uint32_t addr_byte_size = GetAddressByteSize();
4891 n =
Bits32(opcode, 19, 16);
4892 registers =
Bits32(opcode, 15, 0);
4893 registers = registers & 0x5fff;
4896 if ((n == 15) ||
BitCount(registers) < 2)
4899 if (wback &&
BitIsSet(registers, n))
4911 n =
Bits32(opcode, 19, 16);
4912 registers =
Bits32(opcode, 15, 0);
4915 if ((n == 15) ||
BitCount(registers) < 1)
4934 context.
type = EmulateInstruction::eContextRegisterStore;
4935 RegisterInfo base_reg;
4940 for (
uint32_t i = 0; i < 14; ++i) {
4943 if (i < lowest_set_bit)
4946 if ((i == n) && wback && (i != lowest_set_bit))
4949 WriteBits32UnknownToMemory(address + offset);
4957 RegisterInfo data_reg;
4959 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4960 Rn - (address + offset));
4961 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4966 offset += addr_byte_size;
4973 RegisterInfo pc_reg;
4975 context.SetRegisterPlusOffset(pc_reg, 8);
4980 if (!MemAWrite(context, address + offset,
pc, addr_byte_size))
4986 offset = (addr_byte_size *
BitCount(registers)) * -1;
4987 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4988 context.SetImmediateSigned(offset);
4989 addr_t data = Rn + offset;
5003 bool EmulateInstructionARM::EmulateSTMIB(
const uint32_t opcode,
5006 if ConditionPassed() then
5007 EncodingSpecificOperations();
5011 if registers<i> ==
'1' then
5012 if i == n && wback && i != LowestSetBit(registers) then
5013 MemA[address,4] =
bits(32) UNKNOWN;
5015 MemA[address,4] = R[i];
5016 address = address + 4;
5018 if registers<15> ==
'1' then
5019 MemA[address,4] = PCStoreValue();
5021 if wback then R[n] = R[n] + 4*
BitCount(registers);
5024 bool success =
false;
5026 if (ConditionPassed(opcode)) {
5030 const uint32_t addr_byte_size = GetAddressByteSize();
5036 n =
Bits32(opcode, 19, 16);
5037 registers =
Bits32(opcode, 15, 0);
5041 if ((n == 15) && (
BitCount(registers) < 1))
5050 addr_t Rn = ReadCoreReg(n, &success);
5054 addr_t address = Rn + addr_byte_size;
5057 context.
type = EmulateInstruction::eContextRegisterStore;
5058 RegisterInfo base_reg;
5063 for (
uint32_t i = 0; i < 14; ++i) {
5066 if (i < lowest_set_bit)
5069 if ((i == n) && wback && (i != lowest_set_bit))
5071 WriteBits32UnknownToMemory(address + offset);
5080 RegisterInfo data_reg;
5083 offset + addr_byte_size);
5084 if (!MemAWrite(context, address + offset, data, addr_byte_size))
5089 offset += addr_byte_size;
5096 RegisterInfo pc_reg;
5103 if (!MemAWrite(context, address + offset,
pc, addr_byte_size))
5109 offset = addr_byte_size *
BitCount(registers);
5110 context.
type = EmulateInstruction::eContextAdjustBaseRegister;
5112 addr_t data = Rn + offset;
5125 bool EmulateInstructionARM::EmulateSTRThumb(
const uint32_t opcode,
5128 if ConditionPassed() then
5129 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5130 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
5131 address =
if index then offset_addr
else R[n];
5132 if UnalignedSupport() || address<1:0> ==
'00' then
5133 MemU[address,4] = R[t];
5135 MemU[address,4] =
bits(32) UNKNOWN;
5136 if wback then R[n] = offset_addr;
5139 bool success =
false;
5141 if (ConditionPassed(opcode)) {
5142 const uint32_t addr_byte_size = GetAddressByteSize();
5154 t =
Bits32(opcode, 2, 0);
5155 n =
Bits32(opcode, 5, 3);
5156 imm32 =
Bits32(opcode, 10, 6) << 2;
5166 t =
Bits32(opcode, 10, 8);
5168 imm32 =
Bits32(opcode, 7, 0) << 2;
5178 if (
Bits32(opcode, 19, 16) == 15)
5182 t =
Bits32(opcode, 15, 12);
5183 n =
Bits32(opcode, 19, 16);
5184 imm32 =
Bits32(opcode, 11, 0);
5201 if ((
Bits32(opcode, 19, 16) == 15) ||
5206 t =
Bits32(opcode, 15, 12);
5207 n =
Bits32(opcode, 19, 16);
5208 imm32 =
Bits32(opcode, 7, 0);
5216 if ((t == 15) || (wback && (n == t)))
5228 uint32_t base_address = ReadCoreReg(n, &success);
5233 offset_addr = base_address + imm32;
5235 offset_addr = base_address - imm32;
5239 address = offset_addr;
5241 address = base_address;
5245 context.
type = eContextPushRegisterOnStack;
5247 context.
type = eContextRegisterStore;
5249 RegisterInfo base_reg;
5253 if (UnalignedSupport() ||
5261 RegisterInfo data_reg;
5263 int32_t offset = address - base_address;
5265 if (!MemUWrite(context, address, data, addr_byte_size))
5269 WriteBits32UnknownToMemory(address);
5275 context.
type = eContextAdjustStackPointer;
5277 context.
type = eContextAdjustBaseRegister;
5292 bool EmulateInstructionARM::EmulateSTRRegister(
const uint32_t opcode,
5295 if ConditionPassed() then
5296 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5297 offset =
Shift(R[m], shift_t, shift_n, APSR.C);
5298 offset_addr =
if add then (R[n] + offset)
else (R[n] - offset);
5299 address =
if index then offset_addr
else R[n];
5301 data = PCStoreValue();
5304 if UnalignedSupport() || address<1:0> ==
'00' || CurrentInstrSet() == InstrSet_ARM then
5305 MemU[address,4] = data;
5307 MemU[address,4] =
bits(32) UNKNOWN;
5308 if wback then R[n] = offset_addr;
5311 bool success =
false;
5313 if (ConditionPassed(opcode)) {
5314 const uint32_t addr_byte_size = GetAddressByteSize();
5331 t =
Bits32(opcode, 2, 0);
5332 n =
Bits32(opcode, 5, 3);
5333 m =
Bits32(opcode, 8, 6);
5347 if (
Bits32(opcode, 19, 16) == 15)
5351 t =
Bits32(opcode, 15, 12);
5352 n =
Bits32(opcode, 19, 16);
5353 m =
Bits32(opcode, 3, 0);
5362 shift_n =
Bits32(opcode, 5, 4);
5365 if ((t == 15) || (
BadReg(m)))
5372 t =
Bits32(opcode, 15, 12);
5373 n =
Bits32(opcode, 19, 16);
5374 m =
Bits32(opcode, 3, 0);
5392 if (wback && ((n == 15) || (n == t)))
5416 offset =
Shift(Rm_data, shift_t, shift_n,
APSR_C, &success);
5422 offset_addr = base_address + offset;
5424 offset_addr = base_address - offset;
5428 address = offset_addr;
5430 address = base_address;
5436 data = ReadCoreReg(
PC_REG, &success);
5446 context.
type = eContextRegisterStore;
5450 if (UnalignedSupport() ||
5452 CurrentInstrSet() == eModeARM) {
5455 RegisterInfo base_reg;
5458 RegisterInfo data_reg;
5462 address - base_address);
5463 if (!MemUWrite(context, address, data, addr_byte_size))
5468 WriteBits32UnknownToMemory(address);
5472 context.
type = eContextRegisterLoad;
5482 bool EmulateInstructionARM::EmulateSTRBThumb(
const uint32_t opcode,
5485 if ConditionPassed() then
5486 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5487 offset_addr =
if add then (R[n] + imm32)
else (R[n] - imm32);
5488 address =
if index then offset_addr
else R[n];
5489 MemU[address,1] = R[t]<7:0>;
5490 if wback then R[n] = offset_addr;
5493 bool success =
false;
5495 if (ConditionPassed(opcode)) {
5506 t =
Bits32(opcode, 2, 0);
5507 n =
Bits32(opcode, 5, 3);
5508 imm32 =
Bits32(opcode, 10, 6);
5518 if (
Bits32(opcode, 19, 16) == 15)
5522 t =
Bits32(opcode, 15, 12);
5523 n =
Bits32(opcode, 19, 16);
5524 imm32 =
Bits32(opcode, 11, 0);
5539 if (
Bits32(opcode, 19, 16) == 15)
5543 t =
Bits32(opcode, 15, 12);
5544 n =
Bits32(opcode, 19, 16);
5545 imm32 =
Bits32(opcode, 7, 0);
5553 if ((
BadReg(t)) || (wback && (n == t)))
5570 offset_addr = base_address + imm32;
5572 offset_addr = base_address - imm32;
5576 address = offset_addr;
5578 address = base_address;
5581 RegisterInfo base_reg;
5584 RegisterInfo data_reg;
5588 context.
type = eContextRegisterStore;
5590 address - base_address);
5597 data =
Bits32(data, 7, 0);
5599 if (!MemUWrite(context, address, data, 1))
5604 context.
type = eContextRegisterLoad;
5619 bool EmulateInstructionARM::EmulateSTRHRegister(
const uint32_t opcode,
5622 if ConditionPassed() then
5623 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5624 offset =
Shift(R[m], shift_t, shift_n, APSR.C);
5625 offset_addr =
if add then (R[n] + offset)
else (R[n] - offset);
5626 address =
if index then offset_addr
else R[n];
5627 if UnalignedSupport() || address<0> ==
'0' then
5628 MemU[address,2] = R[t]<15:0>;
5630 MemU[address,2] =
bits(16) UNKNOWN;
5631 if wback then R[n] = offset_addr;
5634 bool success =
false;
5636 if (ConditionPassed(opcode)) {
5652 t =
Bits32(opcode, 2, 0);
5653 n =
Bits32(opcode, 5, 3);
5654 m =
Bits32(opcode, 8, 6);
5670 t =
Bits32(opcode, 15, 12);
5671 n =
Bits32(opcode, 19, 16);
5672 m =
Bits32(opcode, 3, 0);
5683 shift_n =
Bits32(opcode, 5, 4);
5694 t =
Bits32(opcode, 15, 12);
5695 n =
Bits32(opcode, 19, 16);
5696 m =
Bits32(opcode, 3, 0);
5709 if ((t == 15) || (m == 15))
5713 if (wback && ((n == 15) || (n == t)))
5722 uint32_t Rm = ReadCoreReg(m, &success);
5726 uint32_t Rn = ReadCoreReg(n, &success);
5738 offset_addr = Rn + offset;
5740 offset_addr = Rn - offset;
5745 address = offset_addr;
5750 context.
type = eContextRegisterStore;
5751 RegisterInfo base_reg;
5753 RegisterInfo offset_reg;
5757 if (UnalignedSupport() ||
BitIsClear(address, 0)) {
5759 uint32_t Rt = ReadCoreReg(t, &success);
5764 context.
type = eContextRegisterStore;
5765 RegisterInfo base_reg;
5767 RegisterInfo offset_reg;
5769 RegisterInfo data_reg;
5774 if (!MemUWrite(context, address,
Bits32(Rt, 15, 0), 2))
5783 context.
type = eContextAdjustBaseRegister;
5797 bool EmulateInstructionARM::EmulateADCImm(
const uint32_t opcode,
5801 if ConditionPassed() then
5802 EncodingSpecificOperations();
5803 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5809 APSR.N = result<31>;
5810 APSR.Z = IsZeroBit(result);
5815 bool success =
false;
5817 if (ConditionPassed(opcode)) {
5824 Rd =
Bits32(opcode, 11, 8);
5825 Rn =
Bits32(opcode, 19, 16);
5832 Rd =
Bits32(opcode, 15, 12);
5833 Rn =
Bits32(opcode, 19, 16);
5837 if (Rd == 15 && setflags)
5838 return EmulateSUBSPcLrEtc(opcode, encoding);
5845 int32_t val1 = ReadCoreReg(Rn, &success);
5852 context.
type = EmulateInstruction::eContextImmediate;
5855 if (!WriteCoreRegOptionalFlags(context, res.
result, Rd, setflags,
5866 bool EmulateInstructionARM::EmulateADCReg(
const uint32_t opcode,
5870 if ConditionPassed() then
5871 EncodingSpecificOperations();
5872 shifted =
Shift(R[m], shift_t, shift_n, APSR.C);
5873 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5879 APSR.N = result<31>;
5880 APSR.Z = IsZeroBit(result);
5885 bool success =
false;
5887 if (ConditionPassed(opcode)) {
5894 Rd = Rn =
Bits32(opcode, 2, 0);
5895 Rm =
Bits32(opcode, 5, 3);
5896 setflags = !InITBlock();
5901 Rd =
Bits32(opcode, 11, 8);
5902 Rn =
Bits32(opcode, 19, 16);
5903 Rm =
Bits32(opcode, 3, 0);
5910 Rd =
Bits32(opcode, 15, 12);
5911 Rn =
Bits32(opcode, 19, 16);
5912 Rm =
Bits32(opcode, 3, 0);
5916 if (Rd == 15 && setflags)
5917 return EmulateSUBSPcLrEtc(opcode, encoding);
5924 int32_t val1 = ReadCoreReg(Rn, &success);
5929 int32_t val2 = ReadCoreReg(Rm, &success);
5939 context.
type = EmulateInstruction::eContextImmediate;
5942 if (!WriteCoreRegOptionalFlags(context, res.
result, Rd, setflags,
5951 bool EmulateInstructionARM::EmulateADR(
const uint32_t opcode,
5955 if ConditionPassed() then
5956 EncodingSpecificOperations();
5957 result =
if add then (
Align(PC,4) + imm32)
else (
Align(PC,4) - imm32);
5964 bool success =
false;
5966 if (ConditionPassed(opcode)) {
5972 Rd =
Bits32(opcode, 10, 8);
5978 Rd =
Bits32(opcode, 11, 8);
5980 add = (
Bits32(opcode, 24, 21) == 0);
5986 Rd =
Bits32(opcode, 15, 12);
5988 add = (
Bits32(opcode, 24, 21) == 0x4);
6002 context.
type = EmulateInstruction::eContextImmediate;
6005 if (!WriteCoreReg(context, result, Rd))
6014 bool EmulateInstructionARM::EmulateANDImm(
const uint32_t opcode,
6018 if ConditionPassed() then
6019 EncodingSpecificOperations();
6020 result = R[n] AND imm32;
6026 APSR.N = result<31>;
6027 APSR.Z = IsZeroBit(result);
6032 bool success =
false;
6034 if (ConditionPassed(opcode)) {
6042 Rd =
Bits32(opcode, 11, 8);
6043 Rn =
Bits32(opcode, 19, 16);
6049 if (Rd == 15 && setflags)
6050 return EmulateTSTImm(opcode, eEncodingT1);
6051 if (Rd == 13 || (Rd == 15 && !setflags) ||
BadReg(Rn))
6055 Rd =
Bits32(opcode, 15, 12);
6056 Rn =
Bits32(opcode, 19, 16);
6062 if (Rd == 15 && setflags)
6063 return EmulateSUBSPcLrEtc(opcode, encoding);
6070 uint32_t val1 = ReadCoreReg(Rn, &success);
6077 context.
type = EmulateInstruction::eContextImmediate;
6080 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6089 bool EmulateInstructionARM::EmulateANDReg(
const uint32_t opcode,
6093 if ConditionPassed() then
6094 EncodingSpecificOperations();
6095 (shifted, carry) =
Shift_C(R[m], shift_t, shift_n, APSR.C);
6096 result = R[n] AND shifted;
6102 APSR.N = result<31>;
6103 APSR.Z = IsZeroBit(result);