1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 #include "EmulateInstructionARM.h"
13 #include "EmulationStateARM.h"
14 #include "lldb/Core/Address.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Host/PosixApi.h"
17 #include "lldb/Interpreter/OptionValueArray.h"
18 #include "lldb/Interpreter/OptionValueDictionary.h"
19 #include "lldb/Symbol/UnwindPlan.h"
20 #include "lldb/Utility/ArchSpec.h"
21 #include "lldb/Utility/ConstString.h"
22 #include "lldb/Utility/Stream.h"
24 #include "Plugins/Process/Utility/ARMDefines.h"
25 #include "Plugins/Process/Utility/ARMUtils.h"
26 #include "Utility/ARM_DWARF_Registers.h"
28 #include "llvm/ADT/STLExtras.h"
29 #include "llvm/Support/MathExtras.h"
32 using namespace lldb_private;
34 // Convenient macro definitions.
35 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
36 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
38 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
40 //----------------------------------------------------------------------
42 // ITSession implementation
44 //----------------------------------------------------------------------
46 static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) {
47 ::memset(®_info, 0, sizeof(RegisterInfo));
48 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
50 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) {
51 reg_info.byte_size = 16;
52 reg_info.format = eFormatVectorOfUInt8;
53 reg_info.encoding = eEncodingVector;
56 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) {
57 reg_info.byte_size = 8;
58 reg_info.format = eFormatFloat;
59 reg_info.encoding = eEncodingIEEE754;
60 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) {
61 reg_info.byte_size = 4;
62 reg_info.format = eFormatFloat;
63 reg_info.encoding = eEncodingIEEE754;
64 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) {
65 reg_info.byte_size = 12;
66 reg_info.format = eFormatFloat;
67 reg_info.encoding = eEncodingIEEE754;
69 reg_info.byte_size = 4;
70 reg_info.format = eFormatHex;
71 reg_info.encoding = eEncodingUint;
74 reg_info.kinds[eRegisterKindDWARF] = reg_num;
100 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
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";
119 reg_info.alt_name = "r13";
120 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
123 reg_info.name = "lr";
124 reg_info.alt_name = "r14";
125 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
128 reg_info.name = "pc";
129 reg_info.alt_name = "r15";
130 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
133 reg_info.name = "cpsr";
134 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
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";
260 // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator
261 // register 0 - 7 (they do overlap with wCGR0 - wCGR7)
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";
287 // Intel wireless MMX data registers 0 - 15
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";
423 // Intel wireless MMX control register in co-processor 0 - 7
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";
547 // NEON 128-bit vector registers (overlays the d registers)
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";
604 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
605 static uint32_t CountITSize(uint32_t ITMask) {
606 // First count the trailing zeros of the IT mask.
607 uint32_t TZ = llvm::countTrailingZeros(ITMask);
609 #ifdef LLDB_CONFIGURATION_DEBUG
610 printf("Encoding error: IT Mask '0000'\n");
617 // Init ITState. Note that at least one bit is always 1 in mask.
618 bool ITSession::InitIT(uint32_t bits7_0) {
619 ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
624 unsigned short FirstCond = Bits32(bits7_0, 7, 4);
625 if (FirstCond == 0xF) {
626 #ifdef LLDB_CONFIGURATION_DEBUG
627 printf("Encoding error: IT FirstCond '1111'\n");
631 if (FirstCond == 0xE && ITCounter != 1) {
632 #ifdef LLDB_CONFIGURATION_DEBUG
633 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
642 // Update ITState if necessary.
643 void ITSession::ITAdvance() {
644 // assert(ITCounter);
649 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
650 SetBits32(ITState, 4, 0, NewITState4_0);
654 // Return true if we're inside an IT Block.
655 bool ITSession::InITBlock() { return ITCounter != 0; }
657 // Return true if we're the last instruction inside an IT Block.
658 bool ITSession::LastInITBlock() { return ITCounter == 1; }
660 // Get condition bits for the current thumb instruction.
661 uint32_t ITSession::GetCond() {
663 return Bits32(ITState, 7, 4);
668 // ARM constants used during decoding
670 #define LDM_REGLIST 1
674 #define PC_REGLIST_BIT 0x8000
676 #define ARMv4 (1u << 0)
677 #define ARMv4T (1u << 1)
678 #define ARMv5T (1u << 2)
679 #define ARMv5TE (1u << 3)
680 #define ARMv5TEJ (1u << 4)
681 #define ARMv6 (1u << 5)
682 #define ARMv6K (1u << 6)
683 #define ARMv6T2 (1u << 7)
684 #define ARMv7 (1u << 8)
685 #define ARMv7S (1u << 9)
686 #define ARMv8 (1u << 10)
687 #define ARMvAll (0xffffffffu)
689 #define ARMV4T_ABOVE \
690 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \
692 #define ARMV5_ABOVE \
693 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \
695 #define ARMV5TE_ABOVE \
696 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
697 #define ARMV5J_ABOVE \
698 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
699 #define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
700 #define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
701 #define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
704 #define VFPv1 (1u << 1)
705 #define VFPv2 (1u << 2)
706 #define VFPv3 (1u << 3)
707 #define AdvancedSIMD (1u << 4)
709 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
710 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
711 #define VFPv2v3 (VFPv2 | VFPv3)
713 //----------------------------------------------------------------------
715 // EmulateInstructionARM implementation
717 //----------------------------------------------------------------------
719 void EmulateInstructionARM::Initialize() {
720 PluginManager::RegisterPlugin(GetPluginNameStatic(),
721 GetPluginDescriptionStatic(), CreateInstance);
724 void EmulateInstructionARM::Terminate() {
725 PluginManager::UnregisterPlugin(CreateInstance);
728 ConstString EmulateInstructionARM::GetPluginNameStatic() {
729 static ConstString g_name("arm");
733 const char *EmulateInstructionARM::GetPluginDescriptionStatic() {
734 return "Emulate instructions for the ARM architecture.";
738 EmulateInstructionARM::CreateInstance(const ArchSpec &arch,
739 InstructionType inst_type) {
740 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
742 if (arch.GetTriple().getArch() == llvm::Triple::arm) {
743 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap(
744 new EmulateInstructionARM(arch));
746 if (emulate_insn_ap.get())
747 return emulate_insn_ap.release();
748 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
749 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap(
750 new EmulateInstructionARM(arch));
752 if (emulate_insn_ap.get())
753 return emulate_insn_ap.release();
760 bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) {
761 if (arch.GetTriple().getArch() == llvm::Triple::arm)
763 else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
769 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for
770 // many ARM instructions.
771 bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
772 EmulateInstruction::Context context;
773 context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
776 uint32_t random_data = rand();
777 const uint32_t addr_byte_size = GetAddressByteSize();
779 return MemAWrite(context, address, random_data, addr_byte_size);
782 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM
784 bool EmulateInstructionARM::WriteBits32Unknown(int n) {
785 EmulateInstruction::Context context;
786 context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
791 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
796 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
802 bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind,
804 RegisterInfo ®_info) {
805 if (reg_kind == eRegisterKindGeneric) {
807 case LLDB_REGNUM_GENERIC_PC:
808 reg_kind = eRegisterKindDWARF;
811 case LLDB_REGNUM_GENERIC_SP:
812 reg_kind = eRegisterKindDWARF;
815 case LLDB_REGNUM_GENERIC_FP:
816 reg_kind = eRegisterKindDWARF;
819 case LLDB_REGNUM_GENERIC_RA:
820 reg_kind = eRegisterKindDWARF;
823 case LLDB_REGNUM_GENERIC_FLAGS:
824 reg_kind = eRegisterKindDWARF;
825 reg_num = dwarf_cpsr;
832 if (reg_kind == eRegisterKindDWARF)
833 return GetARMDWARFRegisterInfo(reg_num, reg_info);
837 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
838 if (m_arch.GetTriple().isAndroid())
839 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
840 bool is_apple = false;
841 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
843 switch (m_arch.GetTriple().getOS()) {
844 case llvm::Triple::Darwin:
845 case llvm::Triple::MacOSX:
846 case llvm::Triple::IOS:
847 case llvm::Triple::TvOS:
848 case llvm::Triple::WatchOS:
849 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
856 /* On Apple iOS et al, the frame pointer register is always r7.
857 * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
860 uint32_t fp_regnum = 11;
865 if (m_opcode_mode == eModeThumb)
871 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
872 bool is_apple = false;
873 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
875 switch (m_arch.GetTriple().getOS()) {
876 case llvm::Triple::Darwin:
877 case llvm::Triple::MacOSX:
878 case llvm::Triple::IOS:
885 /* On Apple iOS et al, the frame pointer register is always r7.
886 * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
889 uint32_t fp_regnum = dwarf_r11;
892 fp_regnum = dwarf_r7;
894 if (m_opcode_mode == eModeThumb)
895 fp_regnum = dwarf_r7;
900 // Push Multiple Registers stores multiple registers to the stack, storing to
901 // consecutive memory locations ending just below the address in SP, and
903 // SP to point to the start of the stored data.
904 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
905 const ARMEncoding encoding) {
907 // ARM pseudo code...
908 if (ConditionPassed())
910 EncodingSpecificOperations();
911 NullCheckIfThumbEE(13);
912 address = SP - 4*BitCount(registers);
916 if (registers<i> == '1')
918 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
919 MemA[address,4] = bits(32) UNKNOWN;
921 MemA[address,4] = R[i];
922 address = address + 4;
926 if (registers<15> == '1') // Only possible for encoding A1 or A2
927 MemA[address,4] = PCStoreValue();
929 SP = SP - 4*BitCount(registers);
933 bool success = false;
934 if (ConditionPassed(opcode)) {
935 const uint32_t addr_byte_size = GetAddressByteSize();
936 const addr_t sp = ReadCoreReg(SP_REG, &success);
939 uint32_t registers = 0;
940 uint32_t Rt; // the source register
943 registers = Bits32(opcode, 7, 0);
944 // The M bit represents LR.
945 if (Bit32(opcode, 8))
946 registers |= (1u << 14);
947 // if BitCount(registers) < 1 then UNPREDICTABLE;
948 if (BitCount(registers) < 1)
952 // Ignore bits 15 & 13.
953 registers = Bits32(opcode, 15, 0) & ~0xa000;
954 // if BitCount(registers) < 2 then UNPREDICTABLE;
955 if (BitCount(registers) < 2)
959 Rt = Bits32(opcode, 15, 12);
960 // if BadReg(t) then UNPREDICTABLE;
963 registers = (1u << Rt);
966 registers = Bits32(opcode, 15, 0);
967 // Instead of return false, let's handle the following case as well,
968 // which amounts to pushing one reg onto the full descending stacks.
969 // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
972 Rt = Bits32(opcode, 15, 12);
973 // if t == 13 then UNPREDICTABLE;
976 registers = (1u << Rt);
981 addr_t sp_offset = addr_byte_size * BitCount(registers);
982 addr_t addr = sp - sp_offset;
985 EmulateInstruction::Context context;
986 context.type = EmulateInstruction::eContextPushRegisterOnStack;
987 RegisterInfo reg_info;
989 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
990 for (i = 0; i < 15; ++i) {
991 if (BitIsSet(registers, i)) {
992 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info);
993 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
994 uint32_t reg_value = ReadCoreReg(i, &success);
997 if (!MemAWrite(context, addr, reg_value, addr_byte_size))
999 addr += addr_byte_size;
1003 if (BitIsSet(registers, 15)) {
1004 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info);
1005 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
1006 const uint32_t pc = ReadCoreReg(PC_REG, &success);
1009 if (!MemAWrite(context, addr, pc, addr_byte_size))
1013 context.type = EmulateInstruction::eContextAdjustStackPointer;
1014 context.SetImmediateSigned(-sp_offset);
1016 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1017 LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1023 // Pop Multiple Registers loads multiple registers from the stack, loading from
1024 // consecutive memory locations staring at the address in SP, and updates
1025 // SP to point just above the loaded data.
1026 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1027 const ARMEncoding encoding) {
1029 // ARM pseudo code...
1030 if (ConditionPassed())
1032 EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1035 if registers<i> == '1' then
1036 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1037 if registers<15> == '1' then
1038 if UnalignedAllowed then
1039 LoadWritePC(MemU[address,4]);
1041 LoadWritePC(MemA[address,4]);
1042 if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1043 if registers<13> == '1' then SP = bits(32) UNKNOWN;
1047 bool success = false;
1049 if (ConditionPassed(opcode)) {
1050 const uint32_t addr_byte_size = GetAddressByteSize();
1051 const addr_t sp = ReadCoreReg(SP_REG, &success);
1054 uint32_t registers = 0;
1055 uint32_t Rt; // the destination register
1058 registers = Bits32(opcode, 7, 0);
1059 // The P bit represents PC.
1060 if (Bit32(opcode, 8))
1061 registers |= (1u << 15);
1062 // if BitCount(registers) < 1 then UNPREDICTABLE;
1063 if (BitCount(registers) < 1)
1068 registers = Bits32(opcode, 15, 0) & ~0x2000;
1069 // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1071 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1073 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1075 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1079 Rt = Bits32(opcode, 15, 12);
1080 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1084 if (Rt == 15 && InITBlock() && !LastInITBlock())
1086 registers = (1u << Rt);
1089 registers = Bits32(opcode, 15, 0);
1090 // Instead of return false, let's handle the following case as well,
1091 // which amounts to popping one reg from the full descending stacks.
1092 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1094 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1095 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1099 Rt = Bits32(opcode, 15, 12);
1100 // if t == 13 then UNPREDICTABLE;
1103 registers = (1u << Rt);
1108 addr_t sp_offset = addr_byte_size * BitCount(registers);
1112 EmulateInstruction::Context context;
1113 context.type = EmulateInstruction::eContextPopRegisterOffStack;
1115 RegisterInfo sp_reg;
1116 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1118 for (i = 0; i < 15; ++i) {
1119 if (BitIsSet(registers, i)) {
1120 context.SetAddress(addr);
1121 data = MemARead(context, addr, 4, 0, &success);
1124 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
1127 addr += addr_byte_size;
1131 if (BitIsSet(registers, 15)) {
1132 context.SetRegisterPlusOffset(sp_reg, addr - sp);
1133 data = MemARead(context, addr, 4, 0, &success);
1136 // In ARMv5T and above, this is an interworking branch.
1137 if (!LoadWritePC(context, data))
1139 // addr += addr_byte_size;
1142 context.type = EmulateInstruction::eContextAdjustStackPointer;
1143 context.SetImmediateSigned(sp_offset);
1145 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1146 LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1152 // Set r7 or ip to point to saved value residing within the stack.
1153 // ADD (SP plus immediate)
1154 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
1155 const ARMEncoding encoding) {
1157 // ARM pseudo code...
1158 if (ConditionPassed())
1160 EncodingSpecificOperations();
1161 (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1163 ALUWritePC(result); // setflags is always FALSE here
1167 APSR.N = result<31>;
1168 APSR.Z = IsZeroBit(result);
1174 bool success = false;
1176 if (ConditionPassed(opcode)) {
1177 const addr_t sp = ReadCoreReg(SP_REG, &success);
1180 uint32_t Rd; // the destination register
1185 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1188 Rd = Bits32(opcode, 15, 12);
1189 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1194 addr_t sp_offset = imm32;
1195 addr_t addr = sp + sp_offset; // a pointer to the stack area
1197 EmulateInstruction::Context context;
1198 if (Rd == GetFramePointerRegisterNumber())
1199 context.type = eContextSetFramePointer;
1201 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1202 RegisterInfo sp_reg;
1203 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1204 context.SetRegisterPlusOffset(sp_reg, sp_offset);
1206 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
1213 // Set r7 or ip to the current stack pointer.
1215 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1216 const ARMEncoding encoding) {
1218 // ARM pseudo code...
1219 if (ConditionPassed())
1221 EncodingSpecificOperations();
1224 ALUWritePC(result); // setflags is always FALSE here
1228 APSR.N = result<31>;
1229 APSR.Z = IsZeroBit(result);
1235 bool success = false;
1237 if (ConditionPassed(opcode)) {
1238 const addr_t sp = ReadCoreReg(SP_REG, &success);
1241 uint32_t Rd; // the destination register
1253 EmulateInstruction::Context context;
1254 if (Rd == GetFramePointerRegisterNumber())
1255 context.type = EmulateInstruction::eContextSetFramePointer;
1257 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1258 RegisterInfo sp_reg;
1259 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1260 context.SetRegisterPlusOffset(sp_reg, 0);
1262 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
1268 // Move from high register (r8-r15) to low register (r0-r7).
1270 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
1271 const ARMEncoding encoding) {
1272 return EmulateMOVRdRm(opcode, encoding);
1275 // Move from register to register.
1277 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1278 const ARMEncoding encoding) {
1280 // ARM pseudo code...
1281 if (ConditionPassed())
1283 EncodingSpecificOperations();
1286 ALUWritePC(result); // setflags is always FALSE here
1290 APSR.N = result<31>;
1291 APSR.Z = IsZeroBit(result);
1297 bool success = false;
1299 if (ConditionPassed(opcode)) {
1300 uint32_t Rm; // the source register
1301 uint32_t Rd; // the destination register
1305 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1306 Rm = Bits32(opcode, 6, 3);
1308 if (Rd == 15 && InITBlock() && !LastInITBlock())
1312 Rd = Bits32(opcode, 2, 0);
1313 Rm = Bits32(opcode, 5, 3);
1319 Rd = Bits32(opcode, 11, 8);
1320 Rm = Bits32(opcode, 3, 0);
1321 setflags = BitIsSet(opcode, 20);
1322 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1323 if (setflags && (BadReg(Rd) || BadReg(Rm)))
1325 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1327 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1331 Rd = Bits32(opcode, 15, 12);
1332 Rm = Bits32(opcode, 3, 0);
1333 setflags = BitIsSet(opcode, 20);
1335 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1337 if (Rd == 15 && setflags)
1338 return EmulateSUBSPcLrEtc(opcode, encoding);
1343 uint32_t result = ReadCoreReg(Rm, &success);
1347 // The context specifies that Rm is to be moved into Rd.
1348 EmulateInstruction::Context context;
1350 context.type = EmulateInstruction::eContextAdjustStackPointer;
1352 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1353 RegisterInfo dwarf_reg;
1354 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1355 context.SetRegisterPlusOffset(dwarf_reg, 0);
1357 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1363 // Move (immediate) writes an immediate value to the destination register. It
1364 // can optionally update the condition flags based on the value.
1366 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
1367 const ARMEncoding encoding) {
1369 // ARM pseudo code...
1370 if (ConditionPassed())
1372 EncodingSpecificOperations();
1374 if d == 15 then // Can only occur for ARM encoding
1375 ALUWritePC(result); // setflags is always FALSE here
1379 APSR.N = result<31>;
1380 APSR.Z = IsZeroBit(result);
1386 if (ConditionPassed(opcode)) {
1387 uint32_t Rd; // the destination register
1388 uint32_t imm32; // the immediate value to be written to Rd
1390 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1391 // for setflags == false, this value is a don't care initialized to
1392 // 0 to silence the static analyzer
1396 Rd = Bits32(opcode, 10, 8);
1397 setflags = !InITBlock();
1398 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1404 Rd = Bits32(opcode, 11, 8);
1405 setflags = BitIsSet(opcode, 20);
1406 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1413 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1415 Rd = Bits32(opcode, 11, 8);
1417 uint32_t imm4 = Bits32(opcode, 19, 16);
1418 uint32_t imm3 = Bits32(opcode, 14, 12);
1419 uint32_t i = Bit32(opcode, 26);
1420 uint32_t imm8 = Bits32(opcode, 7, 0);
1421 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1423 // if BadReg(d) then UNPREDICTABLE;
1429 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1430 // ARMExpandImm_C(imm12, APSR.C);
1431 Rd = Bits32(opcode, 15, 12);
1432 setflags = BitIsSet(opcode, 20);
1433 imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1435 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1437 if ((Rd == 15) && setflags)
1438 return EmulateSUBSPcLrEtc(opcode, encoding);
1443 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1444 Rd = Bits32(opcode, 15, 12);
1446 uint32_t imm4 = Bits32(opcode, 19, 16);
1447 uint32_t imm12 = Bits32(opcode, 11, 0);
1448 imm32 = (imm4 << 12) | imm12;
1450 // if d == 15 then UNPREDICTABLE;
1458 uint32_t result = imm32;
1460 // The context specifies that an immediate is to be moved into Rd.
1461 EmulateInstruction::Context context;
1462 context.type = EmulateInstruction::eContextImmediate;
1463 context.SetNoArgs();
1465 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1471 // MUL multiplies two register values. The least significant 32 bits of the
1472 // result are written to the destination
1473 // register. These 32 bits do not depend on whether the source register values
1474 // are considered to be signed values or unsigned values.
1476 // Optionally, it can update the condition flags based on the result. In the
1477 // Thumb instruction set, this option is limited to only a few forms of the
1479 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1480 const ARMEncoding encoding) {
1482 if ConditionPassed() then
1483 EncodingSpecificOperations();
1484 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1485 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1486 result = operand1 * operand2;
1487 R[d] = result<31:0>;
1489 APSR.N = result<31>;
1490 APSR.Z = IsZeroBit(result);
1491 if ArchVersion() == 4 then
1492 APSR.C = bit UNKNOWN;
1493 // else APSR.C unchanged
1494 // APSR.V always unchanged
1497 if (ConditionPassed(opcode)) {
1503 // EncodingSpecificOperations();
1506 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1507 d = Bits32(opcode, 2, 0);
1508 n = Bits32(opcode, 5, 3);
1509 m = Bits32(opcode, 2, 0);
1510 setflags = !InITBlock();
1512 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1513 if ((ArchVersion() < ARMv6) && (d == n))
1519 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1520 d = Bits32(opcode, 11, 8);
1521 n = Bits32(opcode, 19, 16);
1522 m = Bits32(opcode, 3, 0);
1525 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1526 if (BadReg(d) || BadReg(n) || BadReg(m))
1532 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1533 d = Bits32(opcode, 19, 16);
1534 n = Bits32(opcode, 3, 0);
1535 m = Bits32(opcode, 11, 8);
1536 setflags = BitIsSet(opcode, 20);
1538 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1539 if ((d == 15) || (n == 15) || (m == 15))
1542 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1543 if ((ArchVersion() < ARMv6) && (d == n))
1552 bool success = false;
1554 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1557 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1561 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1564 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1568 // result = operand1 * operand2;
1569 uint64_t result = operand1 * operand2;
1571 // R[d] = result<31:0>;
1572 RegisterInfo op1_reg;
1573 RegisterInfo op2_reg;
1574 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1575 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1577 EmulateInstruction::Context context;
1578 context.type = eContextArithmetic;
1579 context.SetRegisterRegisterOperands(op1_reg, op2_reg);
1581 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1582 (0x0000ffff & result)))
1587 // APSR.N = result<31>;
1588 // APSR.Z = IsZeroBit(result);
1589 m_new_inst_cpsr = m_opcode_cpsr;
1590 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1591 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1592 if (m_new_inst_cpsr != m_opcode_cpsr) {
1593 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1594 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1598 // if ArchVersion() == 4 then
1599 // APSR.C = bit UNKNOWN;
1605 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1606 // the destination register. It can optionally update the condition flags based
1608 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1609 const ARMEncoding encoding) {
1611 // ARM pseudo code...
1612 if (ConditionPassed())
1614 EncodingSpecificOperations();
1615 result = NOT(imm32);
1616 if d == 15 then // Can only occur for ARM encoding
1617 ALUWritePC(result); // setflags is always FALSE here
1621 APSR.N = result<31>;
1622 APSR.Z = IsZeroBit(result);
1628 if (ConditionPassed(opcode)) {
1629 uint32_t Rd; // the destination register
1630 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1631 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1635 Rd = Bits32(opcode, 11, 8);
1636 setflags = BitIsSet(opcode, 20);
1637 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1640 Rd = Bits32(opcode, 15, 12);
1641 setflags = BitIsSet(opcode, 20);
1642 imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1644 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1646 if (Rd == 15 && setflags)
1647 return EmulateSUBSPcLrEtc(opcode, encoding);
1652 uint32_t result = ~imm32;
1654 // The context specifies that an immediate is to be moved into Rd.
1655 EmulateInstruction::Context context;
1656 context.type = EmulateInstruction::eContextImmediate;
1657 context.SetNoArgs();
1659 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1665 // Bitwise NOT (register) writes the bitwise inverse of a register value to the
1666 // destination register. It can optionally update the condition flags based on
1668 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1669 const ARMEncoding encoding) {
1671 // ARM pseudo code...
1672 if (ConditionPassed())
1674 EncodingSpecificOperations();
1675 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1676 result = NOT(shifted);
1677 if d == 15 then // Can only occur for ARM encoding
1678 ALUWritePC(result); // setflags is always FALSE here
1682 APSR.N = result<31>;
1683 APSR.Z = IsZeroBit(result);
1689 if (ConditionPassed(opcode)) {
1690 uint32_t Rm; // the source register
1691 uint32_t Rd; // the destination register
1692 ARM_ShifterType shift_t;
1693 uint32_t shift_n; // the shift applied to the value read from Rm
1695 uint32_t carry; // the carry bit after the shift operation
1698 Rd = Bits32(opcode, 2, 0);
1699 Rm = Bits32(opcode, 5, 3);
1700 setflags = !InITBlock();
1701 shift_t = SRType_LSL;
1707 Rd = Bits32(opcode, 11, 8);
1708 Rm = Bits32(opcode, 3, 0);
1709 setflags = BitIsSet(opcode, 20);
1710 shift_n = DecodeImmShiftThumb(opcode, shift_t);
1711 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1712 if (BadReg(Rd) || BadReg(Rm))
1716 Rd = Bits32(opcode, 15, 12);
1717 Rm = Bits32(opcode, 3, 0);
1718 setflags = BitIsSet(opcode, 20);
1719 shift_n = DecodeImmShiftARM(opcode, shift_t);
1724 bool success = false;
1725 uint32_t value = ReadCoreReg(Rm, &success);
1730 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1733 uint32_t result = ~shifted;
1735 // The context specifies that an immediate is to be moved into Rd.
1736 EmulateInstruction::Context context;
1737 context.type = EmulateInstruction::eContextImmediate;
1738 context.SetNoArgs();
1740 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1746 // PC relative immediate load into register, possibly followed by ADD (SP plus
1749 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1750 const ARMEncoding encoding) {
1752 // ARM pseudo code...
1753 if (ConditionPassed())
1755 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1757 address = if add then (base + imm32) else (base - imm32);
1758 data = MemU[address,4];
1760 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1761 elsif UnalignedSupport() || address<1:0> = '00' then
1763 else // Can only apply before ARMv7
1764 if CurrentInstrSet() == InstrSet_ARM then
1765 R[t] = ROR(data, 8*UInt(address<1:0>));
1767 R[t] = bits(32) UNKNOWN;
1771 if (ConditionPassed(opcode)) {
1772 bool success = false;
1773 const uint32_t pc = ReadCoreReg(PC_REG, &success);
1777 // PC relative immediate load context
1778 EmulateInstruction::Context context;
1779 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1780 RegisterInfo pc_reg;
1781 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
1782 context.SetRegisterPlusOffset(pc_reg, 0);
1784 uint32_t Rt; // the destination register
1785 uint32_t imm32; // immediate offset from the PC
1786 bool add; // +imm32 or -imm32?
1787 addr_t base; // the base address
1788 addr_t address; // the PC relative address
1789 uint32_t data; // the literal data value from the PC relative load
1792 Rt = Bits32(opcode, 10, 8);
1793 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1797 Rt = Bits32(opcode, 15, 12);
1798 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1799 add = BitIsSet(opcode, 23);
1800 if (Rt == 15 && InITBlock() && !LastInITBlock())
1807 base = Align(pc, 4);
1809 address = base + imm32;
1811 address = base - imm32;
1813 context.SetRegisterPlusOffset(pc_reg, address - base);
1814 data = MemURead(context, address, 4, 0, &success);
1819 if (Bits32(address, 1, 0) == 0) {
1820 // In ARMv5T and above, this is an interworking branch.
1821 if (!LoadWritePC(context, data))
1825 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1826 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1829 } else // We don't handle ARM for now.
1835 // An add operation to adjust the SP.
1836 // ADD (SP plus immediate)
1837 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1838 const ARMEncoding encoding) {
1840 // ARM pseudo code...
1841 if (ConditionPassed())
1843 EncodingSpecificOperations();
1844 (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1845 if d == 15 then // Can only occur for ARM encoding
1846 ALUWritePC(result); // setflags is always FALSE here
1850 APSR.N = result<31>;
1851 APSR.Z = IsZeroBit(result);
1857 bool success = false;
1859 if (ConditionPassed(opcode)) {
1860 const addr_t sp = ReadCoreReg(SP_REG, &success);
1863 uint32_t imm32; // the immediate operand
1868 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1869 d = Bits32(opcode, 10, 8);
1870 imm32 = (Bits32(opcode, 7, 0) << 2);
1875 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1877 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1882 // d = UInt(Rd); setflags = (S == "1"); imm32 =
1883 // ThumbExpandImm(i:imm3:imm8);
1884 d = Bits32(opcode, 11, 8);
1885 imm32 = ThumbExpandImm(opcode);
1886 setflags = Bit32(opcode, 20);
1888 // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1889 if (d == 15 && setflags == 1)
1890 return false; // CMN (immediate) not yet supported
1892 // if d == 15 && S == "0" then UNPREDICTABLE;
1893 if (d == 15 && setflags == 0)
1898 // if Rn == '1111' then SEE ADR;
1899 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1900 d = Bits32(opcode, 11, 8);
1902 uint32_t i = Bit32(opcode, 26);
1903 uint32_t imm3 = Bits32(opcode, 14, 12);
1904 uint32_t imm8 = Bits32(opcode, 7, 0);
1905 imm32 = (i << 11) | (imm3 << 8) | imm8;
1907 // if d == 15 then UNPREDICTABLE;
1915 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1916 AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1918 EmulateInstruction::Context context;
1920 context.type = EmulateInstruction::eContextAdjustStackPointer;
1922 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1924 RegisterInfo sp_reg;
1925 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1926 context.SetRegisterPlusOffset(sp_reg, res.result - sp);
1929 if (!ALUWritePC(context, res.result))
1934 // APSR.N = result<31>;
1935 // APSR.Z = IsZeroBit(result);
1937 // APSR.V = overflow;
1938 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1939 res.carry_out, res.overflow))
1946 // An add operation to adjust the SP.
1947 // ADD (SP plus register)
1948 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1949 const ARMEncoding encoding) {
1951 // ARM pseudo code...
1952 if (ConditionPassed())
1954 EncodingSpecificOperations();
1955 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1956 (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1958 ALUWritePC(result); // setflags is always FALSE here
1962 APSR.N = result<31>;
1963 APSR.Z = IsZeroBit(result);
1969 bool success = false;
1971 if (ConditionPassed(opcode)) {
1972 const addr_t sp = ReadCoreReg(SP_REG, &success);
1975 uint32_t Rm; // the second operand
1978 Rm = Bits32(opcode, 6, 3);
1983 int32_t reg_value = ReadCoreReg(Rm, &success);
1987 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1989 EmulateInstruction::Context context;
1990 context.type = eContextArithmetic;
1991 RegisterInfo sp_reg;
1992 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1994 RegisterInfo other_reg;
1995 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1996 context.SetRegisterRegisterOperands(sp_reg, other_reg);
1998 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1999 LLDB_REGNUM_GENERIC_SP, addr))
2005 // Branch with Link and Exchange Instruction Sets (immediate) calls a
2006 // subroutine at a PC-relative address, and changes instruction set from ARM to
2007 // Thumb, or from Thumb to ARM.
2009 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
2010 const ARMEncoding encoding) {
2012 // ARM pseudo code...
2013 if (ConditionPassed())
2015 EncodingSpecificOperations();
2016 if CurrentInstrSet() == InstrSet_ARM then
2019 LR = PC<31:1> : '1';
2020 if targetInstrSet == InstrSet_ARM then
2021 targetAddress = Align(PC,4) + imm32;
2023 targetAddress = PC + imm32;
2024 SelectInstrSet(targetInstrSet);
2025 BranchWritePC(targetAddress);
2029 bool success = true;
2031 if (ConditionPassed(opcode)) {
2032 EmulateInstruction::Context context;
2033 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2034 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2037 addr_t lr; // next instruction address
2038 addr_t target; // target address
2039 int32_t imm32; // PC-relative offset
2042 lr = pc | 1u; // return address
2043 uint32_t S = Bit32(opcode, 26);
2044 uint32_t imm10 = Bits32(opcode, 25, 16);
2045 uint32_t J1 = Bit32(opcode, 13);
2046 uint32_t J2 = Bit32(opcode, 11);
2047 uint32_t imm11 = Bits32(opcode, 10, 0);
2048 uint32_t I1 = !(J1 ^ S);
2049 uint32_t I2 = !(J2 ^ S);
2051 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2052 imm32 = llvm::SignExtend32<25>(imm25);
2053 target = pc + imm32;
2054 SelectInstrSet(eModeThumb);
2055 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2056 if (InITBlock() && !LastInITBlock())
2061 lr = pc | 1u; // return address
2062 uint32_t S = Bit32(opcode, 26);
2063 uint32_t imm10H = Bits32(opcode, 25, 16);
2064 uint32_t J1 = Bit32(opcode, 13);
2065 uint32_t J2 = Bit32(opcode, 11);
2066 uint32_t imm10L = Bits32(opcode, 10, 1);
2067 uint32_t I1 = !(J1 ^ S);
2068 uint32_t I2 = !(J2 ^ S);
2070 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2071 imm32 = llvm::SignExtend32<25>(imm25);
2072 target = Align(pc, 4) + imm32;
2073 SelectInstrSet(eModeARM);
2074 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2075 if (InITBlock() && !LastInITBlock())
2080 lr = pc - 4; // return address
2081 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2082 target = Align(pc, 4) + imm32;
2083 SelectInstrSet(eModeARM);
2084 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2087 lr = pc - 4; // return address
2088 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2089 Bits32(opcode, 24, 24) << 1);
2090 target = pc + imm32;
2091 SelectInstrSet(eModeThumb);
2092 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2097 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2098 LLDB_REGNUM_GENERIC_RA, lr))
2100 if (!BranchWritePC(context, target))
2102 if (m_opcode_cpsr != m_new_inst_cpsr)
2103 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2104 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2110 // Branch with Link and Exchange (register) calls a subroutine at an address
2111 // and instruction set specified by a register.
2113 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2114 const ARMEncoding encoding) {
2116 // ARM pseudo code...
2117 if (ConditionPassed())
2119 EncodingSpecificOperations();
2121 if CurrentInstrSet() == InstrSet_ARM then
2122 next_instr_addr = PC - 4;
2123 LR = next_instr_addr;
2125 next_instr_addr = PC - 2;
2126 LR = next_instr_addr<31:1> : '1';
2131 bool success = false;
2133 if (ConditionPassed(opcode)) {
2134 EmulateInstruction::Context context;
2135 context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2136 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2137 addr_t lr; // next instruction address
2140 uint32_t Rm; // the register with the target address
2143 lr = (pc - 2) | 1u; // return address
2144 Rm = Bits32(opcode, 6, 3);
2145 // if m == 15 then UNPREDICTABLE;
2148 if (InITBlock() && !LastInITBlock())
2152 lr = pc - 4; // return address
2153 Rm = Bits32(opcode, 3, 0);
2154 // if m == 15 then UNPREDICTABLE;
2161 addr_t target = ReadCoreReg(Rm, &success);
2164 RegisterInfo dwarf_reg;
2165 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2166 context.SetRegister(dwarf_reg);
2167 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2168 LLDB_REGNUM_GENERIC_RA, lr))
2170 if (!BXWritePC(context, target))
2176 // Branch and Exchange causes a branch to an address and instruction set
2177 // specified by a register.
2178 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2179 const ARMEncoding encoding) {
2181 // ARM pseudo code...
2182 if (ConditionPassed())
2184 EncodingSpecificOperations();
2189 if (ConditionPassed(opcode)) {
2190 EmulateInstruction::Context context;
2191 context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2192 uint32_t Rm; // the register with the target address
2195 Rm = Bits32(opcode, 6, 3);
2196 if (InITBlock() && !LastInITBlock())
2200 Rm = Bits32(opcode, 3, 0);
2205 bool success = false;
2206 addr_t target = ReadCoreReg(Rm, &success);
2210 RegisterInfo dwarf_reg;
2211 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2212 context.SetRegister(dwarf_reg);
2213 if (!BXWritePC(context, target))
2219 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2220 // attempt fails, it branches to an address and instruction set specified by a
2221 // register as though it were a BX instruction.
2223 // TODO: Emulate Jazelle architecture?
2224 // We currently assume that switching to Jazelle state fails, thus
2225 // treating BXJ as a BX operation.
2226 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2227 const ARMEncoding encoding) {
2229 // ARM pseudo code...
2230 if (ConditionPassed())
2232 EncodingSpecificOperations();
2233 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2236 if JazelleAcceptsExecution() then
2237 SwitchToJazelleExecution();
2239 SUBARCHITECTURE_DEFINED handler call;
2243 if (ConditionPassed(opcode)) {
2244 EmulateInstruction::Context context;
2245 context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2246 uint32_t Rm; // the register with the target address
2249 Rm = Bits32(opcode, 19, 16);
2252 if (InITBlock() && !LastInITBlock())
2256 Rm = Bits32(opcode, 3, 0);
2263 bool success = false;
2264 addr_t target = ReadCoreReg(Rm, &success);
2268 RegisterInfo dwarf_reg;
2269 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2270 context.SetRegister(dwarf_reg);
2271 if (!BXWritePC(context, target))
2277 // Set r7 to point to some ip offset.
2279 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
2280 const ARMEncoding encoding) {
2282 // ARM pseudo code...
2283 if (ConditionPassed())
2285 EncodingSpecificOperations();
2286 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2287 if d == 15 then // Can only occur for ARM encoding
2288 ALUWritePC(result); // setflags is always FALSE here
2292 APSR.N = result<31>;
2293 APSR.Z = IsZeroBit(result);
2299 if (ConditionPassed(opcode)) {
2300 bool success = false;
2301 const addr_t ip = ReadCoreReg(12, &success);
2307 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2312 addr_t ip_offset = imm32;
2313 addr_t addr = ip - ip_offset; // the adjusted ip value
2315 EmulateInstruction::Context context;
2316 context.type = EmulateInstruction::eContextRegisterPlusOffset;
2317 RegisterInfo dwarf_reg;
2318 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg);
2319 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset);
2321 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
2327 // Set ip to point to some stack offset.
2328 // SUB (SP minus immediate)
2329 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
2330 const ARMEncoding encoding) {
2332 // ARM pseudo code...
2333 if (ConditionPassed())
2335 EncodingSpecificOperations();
2336 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2337 if d == 15 then // Can only occur for ARM encoding
2338 ALUWritePC(result); // setflags is always FALSE here
2342 APSR.N = result<31>;
2343 APSR.Z = IsZeroBit(result);
2349 if (ConditionPassed(opcode)) {
2350 bool success = false;
2351 const addr_t sp = ReadCoreReg(SP_REG, &success);
2357 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2362 addr_t sp_offset = imm32;
2363 addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2365 EmulateInstruction::Context context;
2366 context.type = EmulateInstruction::eContextRegisterPlusOffset;
2367 RegisterInfo dwarf_reg;
2368 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
2369 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset);
2371 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
2377 // This instruction subtracts an immediate value from the SP value, and writes
2378 // the result to the destination register.
2380 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2382 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
2383 const ARMEncoding encoding) {
2385 // ARM pseudo code...
2386 if (ConditionPassed())
2388 EncodingSpecificOperations();
2389 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2390 if d == 15 then // Can only occur for ARM encoding
2391 ALUWritePC(result); // setflags is always FALSE here
2395 APSR.N = result<31>;
2396 APSR.Z = IsZeroBit(result);
2402 bool success = false;
2403 if (ConditionPassed(opcode)) {
2404 const addr_t sp = ReadCoreReg(SP_REG, &success);
2415 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2418 Rd = Bits32(opcode, 11, 8);
2419 setflags = BitIsSet(opcode, 20);
2420 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2421 if (Rd == 15 && setflags)
2422 return EmulateCMPImm(opcode, eEncodingT2);
2423 if (Rd == 15 && !setflags)
2427 Rd = Bits32(opcode, 11, 8);
2429 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2434 Rd = Bits32(opcode, 15, 12);
2435 setflags = BitIsSet(opcode, 20);
2436 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2438 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2440 if (Rd == 15 && setflags)
2441 return EmulateSUBSPcLrEtc(opcode, encoding);
2446 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2448 EmulateInstruction::Context context;
2450 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2451 // to negate it, or the wrong
2452 // value gets passed down to context.SetImmediateSigned.
2453 context.type = EmulateInstruction::eContextAdjustStackPointer;
2454 context.SetImmediateSigned(-imm64); // the stack pointer offset
2456 context.type = EmulateInstruction::eContextImmediate;
2457 context.SetNoArgs();
2460 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2461 res.carry_out, res.overflow))
2467 // A store operation to the stack that also updates the SP.
2468 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2469 const ARMEncoding encoding) {
2471 // ARM pseudo code...
2472 if (ConditionPassed())
2474 EncodingSpecificOperations();
2475 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2476 address = if index then offset_addr else R[n];
2477 MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2478 if wback then R[n] = offset_addr;
2482 bool success = false;
2483 if (ConditionPassed(opcode)) {
2484 const uint32_t addr_byte_size = GetAddressByteSize();
2485 const addr_t sp = ReadCoreReg(SP_REG, &success);
2488 uint32_t Rt; // the source register
2491 Rn; // This function assumes Rn is the SP, but we should verify that.
2498 Rt = Bits32(opcode, 15, 12);
2499 imm12 = Bits32(opcode, 11, 0);
2500 Rn = Bits32(opcode, 19, 16);
2502 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP.
2505 index = BitIsSet(opcode, 24);
2506 add = BitIsSet(opcode, 23);
2507 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2509 if (wback && ((Rn == 15) || (Rn == Rt)))
2517 offset_addr = sp + imm12;
2519 offset_addr = sp - imm12;
2527 EmulateInstruction::Context context;
2528 context.type = EmulateInstruction::eContextPushRegisterOnStack;
2529 RegisterInfo sp_reg;
2530 RegisterInfo dwarf_reg;
2532 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2533 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2534 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2536 uint32_t reg_value = ReadCoreReg(Rt, &success);
2539 if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2542 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2545 if (!MemUWrite(context, addr, pc, addr_byte_size))
2550 context.type = EmulateInstruction::eContextAdjustStackPointer;
2551 context.SetImmediateSigned(addr - sp);
2552 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2553 LLDB_REGNUM_GENERIC_SP, offset_addr))
2560 // Vector Push stores multiple extension registers to the stack. It also
2561 // updates SP to point to the start of the stored data.
2562 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2563 const ARMEncoding encoding) {
2565 // ARM pseudo code...
2566 if (ConditionPassed())
2568 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2569 address = SP - imm32;
2573 MemA[address,4] = S[d+r]; address = address+4;
2576 // Store as two word-aligned words in the correct order for
2577 // current endianness.
2578 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2579 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2580 address = address+8;
2584 bool success = false;
2585 if (ConditionPassed(opcode)) {
2586 const uint32_t addr_byte_size = GetAddressByteSize();
2587 const addr_t sp = ReadCoreReg(SP_REG, &success);
2591 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
2592 uint32_t imm32; // stack offset
2593 uint32_t regs; // number of registers
2597 single_regs = false;
2598 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2599 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2600 // If UInt(imm8) is odd, see "FSTMX".
2601 regs = Bits32(opcode, 7, 0) / 2;
2602 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2603 if (regs == 0 || regs > 16 || (d + regs) > 32)
2609 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2610 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2611 regs = Bits32(opcode, 7, 0);
2612 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2613 if (regs == 0 || regs > 16 || (d + regs) > 32)
2619 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2620 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2621 addr_t sp_offset = imm32;
2622 addr_t addr = sp - sp_offset;
2625 EmulateInstruction::Context context;
2626 context.type = EmulateInstruction::eContextPushRegisterOnStack;
2628 RegisterInfo dwarf_reg;
2629 RegisterInfo sp_reg;
2630 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2631 for (i = 0; i < regs; ++i) {
2632 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2633 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2634 // uint64_t to accommodate 64-bit registers.
2635 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
2638 if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2640 addr += reg_byte_size;
2643 context.type = EmulateInstruction::eContextAdjustStackPointer;
2644 context.SetImmediateSigned(-sp_offset);
2646 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2647 LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2653 // Vector Pop loads multiple extension registers from the stack. It also
2654 // updates SP to point just above the loaded data.
2655 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2656 const ARMEncoding encoding) {
2658 // ARM pseudo code...
2659 if (ConditionPassed())
2661 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2666 S[d+r] = MemA[address,4]; address = address+4;
2669 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2670 // Combine the word-aligned words in the correct order for
2671 // current endianness.
2672 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2676 bool success = false;
2677 if (ConditionPassed(opcode)) {
2678 const uint32_t addr_byte_size = GetAddressByteSize();
2679 const addr_t sp = ReadCoreReg(SP_REG, &success);
2683 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
2684 uint32_t imm32; // stack offset
2685 uint32_t regs; // number of registers
2689 single_regs = false;
2690 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2691 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2692 // If UInt(imm8) is odd, see "FLDMX".
2693 regs = Bits32(opcode, 7, 0) / 2;
2694 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2695 if (regs == 0 || regs > 16 || (d + regs) > 32)
2701 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2702 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2703 regs = Bits32(opcode, 7, 0);
2704 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2705 if (regs == 0 || regs > 16 || (d + regs) > 32)
2711 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2712 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2713 addr_t sp_offset = imm32;
2716 uint64_t data; // uint64_t to accommodate 64-bit registers.
2718 EmulateInstruction::Context context;
2719 context.type = EmulateInstruction::eContextPopRegisterOffStack;
2721 RegisterInfo dwarf_reg;
2722 RegisterInfo sp_reg;
2723 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2724 for (i = 0; i < regs; ++i) {
2725 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2726 context.SetAddress(addr);
2727 data = MemARead(context, addr, reg_byte_size, 0, &success);
2730 if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2732 addr += reg_byte_size;
2735 context.type = EmulateInstruction::eContextAdjustStackPointer;
2736 context.SetImmediateSigned(sp_offset);
2738 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2739 LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2745 // SVC (previously SWI)
2746 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2747 const ARMEncoding encoding) {
2749 // ARM pseudo code...
2750 if (ConditionPassed())
2752 EncodingSpecificOperations();
2757 bool success = false;
2759 if (ConditionPassed(opcode)) {
2760 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2761 addr_t lr; // next instruction address
2764 uint32_t imm32; // the immediate constant
2765 uint32_t mode; // ARM or Thumb mode
2768 lr = (pc + 2) | 1u; // return address
2769 imm32 = Bits32(opcode, 7, 0);
2773 lr = pc + 4; // return address
2774 imm32 = Bits32(opcode, 23, 0);
2781 EmulateInstruction::Context context;
2782 context.type = EmulateInstruction::eContextSupervisorCall;
2783 context.SetISAAndImmediate(mode, imm32);
2784 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2785 LLDB_REGNUM_GENERIC_RA, lr))
2791 // If Then makes up to four following instructions (the IT block) conditional.
2792 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2793 const ARMEncoding encoding) {
2795 // ARM pseudo code...
2796 EncodingSpecificOperations();
2797 ITSTATE.IT<7:0> = firstcond:mask;
2800 m_it_session.InitIT(Bits32(opcode, 7, 0));
2804 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2805 const ARMEncoding encoding) {
2806 // NOP, nothing to do...
2810 // Branch causes a branch to a target address.
2811 bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2812 const ARMEncoding encoding) {
2814 // ARM pseudo code...
2815 if (ConditionPassed())
2817 EncodingSpecificOperations();
2818 BranchWritePC(PC + imm32);
2822 bool success = false;
2824 if (ConditionPassed(opcode)) {
2825 EmulateInstruction::Context context;
2826 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2827 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2830 addr_t target; // target address
2831 int32_t imm32; // PC-relative offset
2834 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2835 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2836 target = pc + imm32;
2837 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2840 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2841 target = pc + imm32;
2842 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2845 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2847 if (Bits32(opcode, 25, 23) == 7)
2848 return false; // See Branches and miscellaneous control on page
2851 uint32_t S = Bit32(opcode, 26);
2852 uint32_t imm6 = Bits32(opcode, 21, 16);
2853 uint32_t J1 = Bit32(opcode, 13);
2854 uint32_t J2 = Bit32(opcode, 11);
2855 uint32_t imm11 = Bits32(opcode, 10, 0);
2857 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2858 imm32 = llvm::SignExtend32<21>(imm21);
2859 target = pc + imm32;
2860 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2864 uint32_t S = Bit32(opcode, 26);
2865 uint32_t imm10 = Bits32(opcode, 25, 16);
2866 uint32_t J1 = Bit32(opcode, 13);
2867 uint32_t J2 = Bit32(opcode, 11);
2868 uint32_t imm11 = Bits32(opcode, 10, 0);
2869 uint32_t I1 = !(J1 ^ S);
2870 uint32_t I2 = !(J2 ^ S);
2872 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2873 imm32 = llvm::SignExtend32<25>(imm25);
2874 target = pc + imm32;
2875 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2879 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2880 target = pc + imm32;
2881 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2886 if (!BranchWritePC(context, target))
2892 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2893 // value in a register with zero and conditionally branch forward a constant
2894 // value. They do not affect the condition flags. CBNZ, CBZ
2895 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2896 const ARMEncoding encoding) {
2898 // ARM pseudo code...
2899 EncodingSpecificOperations();
2900 if nonzero ^ IsZero(R[n]) then
2901 BranchWritePC(PC + imm32);
2904 bool success = false;
2906 // Read the register value from the operand register Rn.
2907 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2911 EmulateInstruction::Context context;
2912 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2913 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2917 addr_t target; // target address
2918 uint32_t imm32; // PC-relative offset to branch forward
2922 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2923 nonzero = BitIsSet(opcode, 11);
2924 target = pc + imm32;
2925 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2930 if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2931 if (!BranchWritePC(context, target))
2937 // Table Branch Byte causes a PC-relative forward branch using a table of
2938 // single byte offsets.
2939 // A base register provides a pointer to the table, and a second register
2940 // supplies an index into the table.
2941 // The branch length is twice the value of the byte returned from the table.
2943 // Table Branch Halfword causes a PC-relative forward branch using a table of
2944 // single halfword offsets.
2945 // A base register provides a pointer to the table, and a second register
2946 // supplies an index into the table.
2947 // The branch length is twice the value of the halfword returned from the
2949 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2950 const ARMEncoding encoding) {
2952 // ARM pseudo code...
2953 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2955 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2957 halfwords = UInt(MemU[R[n]+R[m], 1]);
2958 BranchWritePC(PC + 2*halfwords);
2961 bool success = false;
2963 if (ConditionPassed(opcode)) {
2964 uint32_t Rn; // the base register which contains the address of the table of
2966 uint32_t Rm; // the index register which contains an integer pointing to a
2967 // byte/halfword in the table
2968 bool is_tbh; // true if table branch halfword
2971 Rn = Bits32(opcode, 19, 16);
2972 Rm = Bits32(opcode, 3, 0);
2973 is_tbh = BitIsSet(opcode, 4);
2974 if (Rn == 13 || BadReg(Rm))
2976 if (InITBlock() && !LastInITBlock())
2983 // Read the address of the table from the operand register Rn. The PC can
2984 // be used, in which case the table immediately follows this instruction.
2985 uint32_t base = ReadCoreReg(Rn, &success);
2990 uint32_t index = ReadCoreReg(Rm, &success);
2994 // the offsetted table address
2995 addr_t addr = base + (is_tbh ? index * 2 : index);
2997 // PC-relative offset to branch forward
2998 EmulateInstruction::Context context;
2999 context.type = EmulateInstruction::eContextTableBranchReadMemory;
3000 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
3004 const uint32_t pc = ReadCoreReg(PC_REG, &success);
3009 addr_t target = pc + offset;
3010 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
3011 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
3013 if (!BranchWritePC(context, target))
3020 // This instruction adds an immediate value to a register value, and writes the
3021 // result to the destination register. It can optionally update the condition
3022 // flags based on the result.
3023 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
3024 const ARMEncoding encoding) {
3026 if ConditionPassed() then
3027 EncodingSpecificOperations();
3028 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3031 APSR.N = result<31>;
3032 APSR.Z = IsZeroBit(result);
3037 bool success = false;
3039 if (ConditionPassed(opcode)) {
3046 // EncodingSpecificOperations();
3049 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3050 // ZeroExtend(imm3, 32);
3051 d = Bits32(opcode, 2, 0);
3052 n = Bits32(opcode, 5, 3);
3053 setflags = !InITBlock();
3054 imm32 = Bits32(opcode, 8, 6);
3059 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3060 // ZeroExtend(imm8, 32);
3061 d = Bits32(opcode, 10, 8);
3062 n = Bits32(opcode, 10, 8);
3063 setflags = !InITBlock();
3064 imm32 = Bits32(opcode, 7, 0);
3069 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3070 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3071 // ThumbExpandImm(i:imm3:imm8);
3072 d = Bits32(opcode, 11, 8);
3073 n = Bits32(opcode, 19, 16);
3074 setflags = BitIsSet(opcode, 20);
3075 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3077 // if Rn == '1101' then SEE ADD (SP plus immediate);
3079 return EmulateADDSPImm(opcode, eEncodingT3);
3081 // if BadReg(d) || n == 15 then UNPREDICTABLE;
3082 if (BadReg(d) || (n == 15))
3088 // if Rn == '1111' then SEE ADR;
3089 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3090 // ZeroExtend(i:imm3:imm8, 32);
3091 d = Bits32(opcode, 11, 8);
3092 n = Bits32(opcode, 19, 16);
3094 uint32_t i = Bit32(opcode, 26);
3095 uint32_t imm3 = Bits32(opcode, 14, 12);
3096 uint32_t imm8 = Bits32(opcode, 7, 0);
3097 imm32 = (i << 11) | (imm3 << 8) | imm8;
3099 // if Rn == '1101' then SEE ADD (SP plus immediate);
3101 return EmulateADDSPImm(opcode, eEncodingT4);
3103 // if BadReg(d) then UNPREDICTABLE;
3115 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3119 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3120 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3123 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
3125 EmulateInstruction::Context context;
3126 context.type = eContextArithmetic;
3127 context.SetRegisterPlusOffset(reg_n, imm32);
3131 // APSR.N = result<31>;
3132 // APSR.Z = IsZeroBit(result);
3134 // APSR.V = overflow;
3135 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3136 res.carry_out, res.overflow))
3142 // This instruction adds an immediate value to a register value, and writes the
3143 // result to the destination register. It can optionally update the condition
3144 // flags based on the result.
3145 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
3146 const ARMEncoding encoding) {
3148 // ARM pseudo code...
3149 if ConditionPassed() then
3150 EncodingSpecificOperations();
3151 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3153 ALUWritePC(result); // setflags is always FALSE here
3157 APSR.N = result<31>;
3158 APSR.Z = IsZeroBit(result);
3163 bool success = false;
3165 if (ConditionPassed(opcode)) {
3168 imm32; // the immediate value to be added to the value obtained from Rn
3172 Rd = Bits32(opcode, 15, 12);
3173 Rn = Bits32(opcode, 19, 16);
3174 setflags = BitIsSet(opcode, 20);
3175 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3181 // Read the first operand.
3182 uint32_t val1 = ReadCoreReg(Rn, &success);
3186 AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3188 EmulateInstruction::Context context;
3190 context.type = EmulateInstruction::eContextAdjustStackPointer;
3191 else if (Rd == GetFramePointerRegisterNumber())
3192 context.type = EmulateInstruction::eContextSetFramePointer;
3194 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3196 RegisterInfo dwarf_reg;
3197 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
3198 context.SetRegisterPlusOffset(dwarf_reg, imm32);
3200 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3201 res.carry_out, res.overflow))
3207 // This instruction adds a register value and an optionally-shifted register
3208 // value, and writes the result to the destination register. It can optionally
3209 // update the condition flags based on the result.
3210 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3211 const ARMEncoding encoding) {
3213 // ARM pseudo code...
3214 if ConditionPassed() then
3215 EncodingSpecificOperations();
3216 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3217 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3219 ALUWritePC(result); // setflags is always FALSE here
3223 APSR.N = result<31>;
3224 APSR.Z = IsZeroBit(result);
3229 bool success = false;
3231 if (ConditionPassed(opcode)) {
3232 uint32_t Rd, Rn, Rm;
3233 ARM_ShifterType shift_t;
3234 uint32_t shift_n; // the shift applied to the value read from Rm
3238 Rd = Bits32(opcode, 2, 0);
3239 Rn = Bits32(opcode, 5, 3);
3240 Rm = Bits32(opcode, 8, 6);
3241 setflags = !InITBlock();
3242 shift_t = SRType_LSL;
3246 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3247 Rm = Bits32(opcode, 6, 3);
3249 shift_t = SRType_LSL;
3251 if (Rn == 15 && Rm == 15)
3253 if (Rd == 15 && InITBlock() && !LastInITBlock())
3257 Rd = Bits32(opcode, 15, 12);
3258 Rn = Bits32(opcode, 19, 16);
3259 Rm = Bits32(opcode, 3, 0);
3260 setflags = BitIsSet(opcode, 20);
3261 shift_n = DecodeImmShiftARM(opcode, shift_t);
3267 // Read the first operand.
3268 uint32_t val1 = ReadCoreReg(Rn, &success);
3272 // Read the second operand.
3273 uint32_t val2 = ReadCoreReg(Rm, &success);
3277 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3280 AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3282 EmulateInstruction::Context context;
3283 context.type = eContextArithmetic;
3284 RegisterInfo op1_reg;
3285 RegisterInfo op2_reg;
3286 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
3287 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
3288 context.SetRegisterRegisterOperands(op1_reg, op2_reg);
3290 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3291 res.carry_out, res.overflow))
3297 // Compare Negative (immediate) adds a register value and an immediate value.
3298 // It updates the condition flags based on the result, and discards the result.
3299 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3300 const ARMEncoding encoding) {
3302 // ARM pseudo code...
3303 if ConditionPassed() then
3304 EncodingSpecificOperations();
3305 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3306 APSR.N = result<31>;
3307 APSR.Z = IsZeroBit(result);
3312 bool success = false;
3314 uint32_t Rn; // the first operand
3315 uint32_t imm32; // the immediate value to be compared with
3318 Rn = Bits32(opcode, 19, 16);
3319 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3324 Rn = Bits32(opcode, 19, 16);
3325 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3330 // Read the register value from the operand register Rn.
3331 uint32_t reg_val = ReadCoreReg(Rn, &success);
3335 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3337 EmulateInstruction::Context context;
3338 context.type = EmulateInstruction::eContextImmediate;
3339 context.SetNoArgs();
3340 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3343 // Compare Negative (register) adds a register value and an optionally-shifted
3344 // register value. It updates the condition flags based on the result, and
3345 // discards the result.
3346 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3347 const ARMEncoding encoding) {
3349 // ARM pseudo code...
3350 if ConditionPassed() then
3351 EncodingSpecificOperations();
3352 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3353 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3354 APSR.N = result<31>;
3355 APSR.Z = IsZeroBit(result);
3360 bool success = false;
3362 uint32_t Rn; // the first operand
3363 uint32_t Rm; // the second operand
3364 ARM_ShifterType shift_t;
3365 uint32_t shift_n; // the shift applied to the value read from Rm
3368 Rn = Bits32(opcode, 2, 0);
3369 Rm = Bits32(opcode, 5, 3);
3370 shift_t = SRType_LSL;
3374 Rn = Bits32(opcode, 19, 16);
3375 Rm = Bits32(opcode, 3, 0);
3376 shift_n = DecodeImmShiftThumb(opcode, shift_t);
3377 // if n == 15 || BadReg(m) then UNPREDICTABLE;
3378 if (Rn == 15 || BadReg(Rm))
3382 Rn = Bits32(opcode, 19, 16);
3383 Rm = Bits32(opcode, 3, 0);
3384 shift_n = DecodeImmShiftARM(opcode, shift_t);
3389 // Read the register value from register Rn.
3390 uint32_t val1 = ReadCoreReg(Rn, &success);
3394 // Read the register value from register Rm.
3395 uint32_t val2 = ReadCoreReg(Rm, &success);
3399 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3402 AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3404 EmulateInstruction::Context context;
3405 context.type = EmulateInstruction::eContextImmediate;
3406 context.SetNoArgs();
3407 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3410 // Compare (immediate) subtracts an immediate value from a register value. It
3411 // updates the condition flags based on the result, and discards the result.
3412 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3413 const ARMEncoding encoding) {
3415 // ARM pseudo code...
3416 if ConditionPassed() then
3417 EncodingSpecificOperations();
3418 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3419 APSR.N = result<31>;
3420 APSR.Z = IsZeroBit(result);
3425 bool success = false;
3427 uint32_t Rn; // the first operand
3428 uint32_t imm32; // the immediate value to be compared with
3431 Rn = Bits32(opcode, 10, 8);
3432 imm32 = Bits32(opcode, 7, 0);
3435 Rn = Bits32(opcode, 19, 16);
3436 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3441 Rn = Bits32(opcode, 19, 16);
3442 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3447 // Read the register value from the operand register Rn.
3448 uint32_t reg_val = ReadCoreReg(Rn, &success);
3452 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3454 EmulateInstruction::Context context;
3455 context.type = EmulateInstruction::eContextImmediate;
3456 context.SetNoArgs();
3457 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3460 // Compare (register) subtracts an optionally-shifted register value from a
3461 // register value. It updates the condition flags based on the result, and
3462 // discards the result.
3463 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3464 const ARMEncoding encoding) {
3466 // ARM pseudo code...
3467 if ConditionPassed() then
3468 EncodingSpecificOperations();
3469 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3470 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3471 APSR.N = result<31>;
3472 APSR.Z = IsZeroBit(result);
3477 bool success = false;
3479 uint32_t Rn; // the first operand
3480 uint32_t Rm; // the second operand
3481 ARM_ShifterType shift_t;
3482 uint32_t shift_n; // the shift applied to the value read from Rm
3485 Rn = Bits32(opcode, 2, 0);
3486 Rm = Bits32(opcode, 5, 3);
3487 shift_t = SRType_LSL;
3491 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3492 Rm = Bits32(opcode, 6, 3);
3493 shift_t = SRType_LSL;
3495 if (Rn < 8 && Rm < 8)
3497 if (Rn == 15 || Rm == 15)
3501 Rn = Bits32(opcode, 19, 16);
3502 Rm = Bits32(opcode, 3, 0);
3503 shift_n = DecodeImmShiftThumb(opcode, shift_t);
3504 if (Rn == 15 || BadReg(Rm))
3508 Rn = Bits32(opcode, 19, 16);
3509 Rm = Bits32(opcode, 3, 0);
3510 shift_n = DecodeImmShiftARM(opcode, shift_t);
3515 // Read the register value from register Rn.
3516 uint32_t val1 = ReadCoreReg(Rn, &success);
3520 // Read the register value from register Rm.
3521 uint32_t val2 = ReadCoreReg(Rm, &success);
3525 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3528 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3530 EmulateInstruction::Context context;
3531 context.type = EmulateInstruction::eContextImmediate;
3532 context.SetNoArgs();
3533 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3536 // Arithmetic Shift Right (immediate) shifts a register value right by an
3537 // immediate number of bits, shifting in copies of its sign bit, and writes the
3538 // result to the destination register. It can optionally update the condition
3539 // flags based on the result.
3540 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3541 const ARMEncoding encoding) {
3543 // ARM pseudo code...
3544 if ConditionPassed() then
3545 EncodingSpecificOperations();
3546 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3547 if d == 15 then // Can only occur for ARM encoding
3548 ALUWritePC(result); // setflags is always FALSE here
3552 APSR.N = result<31>;
3553 APSR.Z = IsZeroBit(result);
3558 return EmulateShiftImm(opcode, encoding, SRType_ASR);
3561 // Arithmetic Shift Right (register) shifts a register value right by a
3562 // variable number of bits, shifting in copies of its sign bit, and writes the
3563 // result to the destination register. The variable number of bits is read from
3564 // the bottom byte of a register. It can optionally update the condition flags
3565 // based on the result.
3566 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3567 const ARMEncoding encoding) {
3569 // ARM pseudo code...
3570 if ConditionPassed() then
3571 EncodingSpecificOperations();
3572 shift_n = UInt(R[m]<7:0>);
3573 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3576 APSR.N = result<31>;
3577 APSR.Z = IsZeroBit(result);
3582 return EmulateShiftReg(opcode, encoding, SRType_ASR);
3585 // Logical Shift Left (immediate) shifts a register value left by an immediate
3586 // number of bits, shifting in zeros, and writes the result to the destination
3587 // register. It can optionally update the condition flags based on the result.
3588 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3589 const ARMEncoding encoding) {
3591 // ARM pseudo code...
3592 if ConditionPassed() then
3593 EncodingSpecificOperations();
3594 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3595 if d == 15 then // Can only occur for ARM encoding
3596 ALUWritePC(result); // setflags is always FALSE here
3600 APSR.N = result<31>;
3601 APSR.Z = IsZeroBit(result);
3606 return EmulateShiftImm(opcode, encoding, SRType_LSL);
3609 // Logical Shift Left (register) shifts a register value left by a variable
3610 // number of bits, shifting in zeros, and writes the result to the destination
3611 // register. The variable number of bits is read from the bottom byte of a
3612 // register. It can optionally update the condition flags based on the result.
3613 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3614 const ARMEncoding encoding) {
3616 // ARM pseudo code...
3617 if ConditionPassed() then
3618 EncodingSpecificOperations();
3619 shift_n = UInt(R[m]<7:0>);
3620 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3623 APSR.N = result<31>;
3624 APSR.Z = IsZeroBit(result);
3629 return EmulateShiftReg(opcode, encoding, SRType_LSL);
3632 // Logical Shift Right (immediate) shifts a register value right by an
3633 // immediate number of bits, shifting in zeros, and writes the result to the
3634 // destination register. It can optionally update the condition flags based on
3636 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3637 const ARMEncoding encoding) {
3639 // ARM pseudo code...
3640 if ConditionPassed() then
3641 EncodingSpecificOperations();
3642 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3643 if d == 15 then // Can only occur for ARM encoding
3644 ALUWritePC(result); // setflags is always FALSE here
3648 APSR.N = result<31>;
3649 APSR.Z = IsZeroBit(result);
3654 return EmulateShiftImm(opcode, encoding, SRType_LSR);
3657 // Logical Shift Right (register) shifts a register value right by a variable
3658 // number of bits, shifting in zeros, and writes the result to the destination
3659 // register. The variable number of bits is read from the bottom byte of a
3660 // register. It can optionally update the condition flags based on the result.
3661 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3662 const ARMEncoding encoding) {
3664 // ARM pseudo code...
3665 if ConditionPassed() then
3666 EncodingSpecificOperations();
3667 shift_n = UInt(R[m]<7:0>);
3668 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3671 APSR.N = result<31>;
3672 APSR.Z = IsZeroBit(result);
3677 return EmulateShiftReg(opcode, encoding, SRType_LSR);
3680 // Rotate Right (immediate) provides the value of the contents of a register
3681 // rotated by a constant value. The bits that are rotated off the right end are
3682 // inserted into the vacated bit positions on the left. It can optionally
3683 // update the condition flags based on the result.
3684 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3685 const ARMEncoding encoding) {
3687 // ARM pseudo code...
3688 if ConditionPassed() then
3689 EncodingSpecificOperations();
3690 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3691 if d == 15 then // Can only occur for ARM encoding
3692 ALUWritePC(result); // setflags is always FALSE here
3696 APSR.N = result<31>;
3697 APSR.Z = IsZeroBit(result);
3702 return EmulateShiftImm(opcode, encoding, SRType_ROR);
3705 // Rotate Right (register) provides the value of the contents of a register
3706 // rotated by a variable number of bits. The bits that are rotated off the
3707 // right end are inserted into the vacated bit positions on the left. The
3708 // variable number of bits is read from the bottom byte of a register. It can
3709 // optionally update the condition flags based on the result.
3710 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3711 const ARMEncoding encoding) {
3713 // ARM pseudo code...
3714 if ConditionPassed() then
3715 EncodingSpecificOperations();
3716 shift_n = UInt(R[m]<7:0>);
3717 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3720 APSR.N = result<31>;
3721 APSR.Z = IsZeroBit(result);
3726 return EmulateShiftReg(opcode, encoding, SRType_ROR);
3729 // Rotate Right with Extend provides the value of the contents of a register
3730 // shifted right by one place, with the carry flag shifted into bit [31].
3732 // RRX can optionally update the condition flags based on the result.
3733 // In that case, bit [0] is shifted into the carry flag.
3734 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3735 const ARMEncoding encoding) {
3737 // ARM pseudo code...
3738 if ConditionPassed() then
3739 EncodingSpecificOperations();
3740 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3741 if d == 15 then // Can only occur for ARM encoding
3742 ALUWritePC(result); // setflags is always FALSE here
3746 APSR.N = result<31>;
3747 APSR.Z = IsZeroBit(result);
3752 return EmulateShiftImm(opcode, encoding, SRType_RRX);
3755 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3756 const ARMEncoding encoding,
3757 ARM_ShifterType shift_type) {
3758 // assert(shift_type == SRType_ASR
3759 // || shift_type == SRType_LSL
3760 // || shift_type == SRType_LSR
3761 // || shift_type == SRType_ROR
3762 // || shift_type == SRType_RRX);
3764 bool success = false;
3766 if (ConditionPassed(opcode)) {
3767 uint32_t Rd; // the destination register
3768 uint32_t Rm; // the first operand register
3769 uint32_t imm5; // encoding for the shift amount
3770 uint32_t carry; // the carry bit after the shift operation
3773 // Special case handling!
3774 // A8.6.139 ROR (immediate) -- Encoding T1
3775 ARMEncoding use_encoding = encoding;
3776 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3777 // Morph the T1 encoding from the ARM Architecture Manual into T2
3778 // encoding to have the same decoding of bit fields as the other Thumb2
3779 // shift operations.
3780 use_encoding = eEncodingT2;
3783 switch (use_encoding) {
3785 // Due to the above special case handling!
3786 if (shift_type == SRType_ROR)
3789 Rd = Bits32(opcode, 2, 0);
3790 Rm = Bits32(opcode, 5, 3);
3791 setflags = !InITBlock();
3792 imm5 = Bits32(opcode, 10, 6);
3796 // There's no imm form of RRX instructions.
3797 if (shift_type == SRType_RRX)
3800 Rd = Bits32(opcode, 11, 8);
3801 Rm = Bits32(opcode, 3, 0);
3802 setflags = BitIsSet(opcode, 20);
3803 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3804 if (BadReg(Rd) || BadReg(Rm))
3808 Rd = Bits32(opcode, 15, 12);
3809 Rm = Bits32(opcode, 3, 0);
3810 setflags = BitIsSet(opcode, 20);
3811 imm5 = Bits32(opcode, 11, 7);
3817 // A8.6.139 ROR (immediate)
3818 if (shift_type == SRType_ROR && imm5 == 0)
3819 shift_type = SRType_RRX;
3821 // Get the first operand.
3822 uint32_t value = ReadCoreReg(Rm, &success);
3826 // Decode the shift amount if not RRX.
3828 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3830 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3834 // The context specifies that an immediate is to be moved into Rd.
3835 EmulateInstruction::Context context;
3836 context.type = EmulateInstruction::eContextImmediate;
3837 context.SetNoArgs();
3839 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3845 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3846 const ARMEncoding encoding,
3847 ARM_ShifterType shift_type) {
3848 // assert(shift_type == SRType_ASR
3849 // || shift_type == SRType_LSL
3850 // || shift_type == SRType_LSR
3851 // || shift_type == SRType_ROR);
3853 bool success = false;
3855 if (ConditionPassed(opcode)) {
3856 uint32_t Rd; // the destination register
3857 uint32_t Rn; // the first operand register
3859 Rm; // the register whose bottom byte contains the amount to shift by
3860 uint32_t carry; // the carry bit after the shift operation
3864 Rd = Bits32(opcode, 2, 0);
3866 Rm = Bits32(opcode, 5, 3);
3867 setflags = !InITBlock();
3870 Rd = Bits32(opcode, 11, 8);
3871 Rn = Bits32(opcode, 19, 16);
3872 Rm = Bits32(opcode, 3, 0);
3873 setflags = BitIsSet(opcode, 20);
3874 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3878 Rd = Bits32(opcode, 15, 12);
3879 Rn = Bits32(opcode, 3, 0);
3880 Rm = Bits32(opcode, 11, 8);
3881 setflags = BitIsSet(opcode, 20);
3882 if (Rd == 15 || Rn == 15 || Rm == 15)
3889 // Get the first operand.
3890 uint32_t value = ReadCoreReg(Rn, &success);
3893 // Get the Rm register content.
3894 uint32_t val = ReadCoreReg(Rm, &success);
3898 // Get the shift amount.
3899 uint32_t amt = Bits32(val, 7, 0);
3901 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3905 // The context specifies that an immediate is to be moved into Rd.
3906 EmulateInstruction::Context context;
3907 context.type = EmulateInstruction::eContextImmediate;
3908 context.SetNoArgs();
3910 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3916 // LDM loads multiple registers from consecutive memory locations, using an
3917 // address from a base register. Optionally the address just above the highest
3918 // of those locations can be written back to the base register.
3919 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3920 const ARMEncoding encoding) {
3922 // ARM pseudo code...
3923 if ConditionPassed()
3924 EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3928 if registers<i> == '1' then
3929 R[i] = MemA[address, 4]; address = address + 4;
3930 if registers<15> == '1' then
3931 LoadWritePC (MemA[address, 4]);
3933 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3934 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3938 bool success = false;
3939 if (ConditionPassed(opcode)) {
3941 uint32_t registers = 0;
3943 const uint32_t addr_byte_size = GetAddressByteSize();
3946 // n = UInt(Rn); registers = '00000000':register_list; wback =
3947 // (registers<n> == '0');
3948 n = Bits32(opcode, 10, 8);
3949 registers = Bits32(opcode, 7, 0);
3950 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3951 wback = BitIsClear(registers, n);
3952 // if BitCount(registers) < 1 then UNPREDICTABLE;
3953 if (BitCount(registers) < 1)
3957 // if W == '1' && Rn == '1101' then SEE POP;
3958 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3959 n = Bits32(opcode, 19, 16);
3960 registers = Bits32(opcode, 15, 0);
3961 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3962 wback = BitIsSet(opcode, 21);
3964 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3966 if ((n == 15) || (BitCount(registers) < 2) ||
3967 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3970 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3972 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3975 // if wback && registers<n> == '1' then UNPREDICTABLE;
3976 if (wback && BitIsSet(registers, n))
3981 n = Bits32(opcode, 19, 16);
3982 registers = Bits32(opcode, 15, 0);
3983 wback = BitIsSet(opcode, 21);
3984 if ((n == 15) || (BitCount(registers) < 1))
3992 const addr_t base_address =
3993 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3997 EmulateInstruction::Context context;
3998 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3999 RegisterInfo dwarf_reg;
4000 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4001 context.SetRegisterPlusOffset(dwarf_reg, offset);
4003 for (int i = 0; i < 14; ++i) {
4004 if (BitIsSet(registers, i)) {
4005 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4006 context.SetRegisterPlusOffset(dwarf_reg, offset);
4007 if (wback && (n == 13)) // Pop Instruction
4009 context.type = EmulateInstruction::eContextPopRegisterOffStack;
4010 context.SetAddress(base_address + offset);
4013 // R[i] = MemA [address, 4]; address = address + 4;
4014 uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
4019 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4023 offset += addr_byte_size;
4027 if (BitIsSet(registers, 15)) {
4028 // LoadWritePC (MemA [address, 4]);
4029 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4030 context.SetRegisterPlusOffset(dwarf_reg, offset);
4032 MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4035 // In ARMv5T and above, this is an interworking branch.
4036 if (!LoadWritePC(context, data))
4040 if (wback && BitIsClear(registers, n)) {
4041 // R[n] = R[n] + 4 * BitCount (registers)
4042 int32_t offset = addr_byte_size * BitCount(registers);
4043 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4044 context.SetRegisterPlusOffset(dwarf_reg, offset);
4046 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4047 base_address + offset))
4050 if (wback && BitIsSet(registers, n))
4051 // R[n] bits(32) UNKNOWN;
4052 return WriteBits32Unknown(n);
4057 // LDMDA loads multiple registers from consecutive memory locations using an
4058 // address from a base register.
4059 // The consecutive memory locations end at this address and the address just
4060 // below the lowest of those locations can optionally be written back to the
4062 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4063 const ARMEncoding encoding) {
4065 // ARM pseudo code...
4066 if ConditionPassed() then
4067 EncodingSpecificOperations();
4068 address = R[n] - 4*BitCount(registers) + 4;
4071 if registers<i> == '1' then
4072 R[i] = MemA[address,4]; address = address + 4;
4074 if registers<15> == '1' then
4075 LoadWritePC(MemA[address,4]);
4077 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4078 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4081 bool success = false;
4083 if (ConditionPassed(opcode)) {
4085 uint32_t registers = 0;
4087 const uint32_t addr_byte_size = GetAddressByteSize();
4089 // EncodingSpecificOperations();
4092 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4093 n = Bits32(opcode, 19, 16);
4094 registers = Bits32(opcode, 15, 0);
4095 wback = BitIsSet(opcode, 21);
4097 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4098 if ((n == 15) || (BitCount(registers) < 1))
4106 // address = R[n] - 4*BitCount(registers) + 4;
4109 addr_t Rn = ReadCoreReg(n, &success);
4115 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4117 EmulateInstruction::Context context;
4118 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4119 RegisterInfo dwarf_reg;
4120 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4121 context.SetRegisterPlusOffset(dwarf_reg, offset);
4124 for (int i = 0; i < 14; ++i) {
4125 // if registers<i> == '1' then
4126 if (BitIsSet(registers, i)) {
4127 // R[i] = MemA[address,4]; address = address + 4;
4128 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4130 MemARead(context, address + offset, addr_byte_size, 0, &success);
4133 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4136 offset += addr_byte_size;
4140 // if registers<15> == '1' then
4141 // LoadWritePC(MemA[address,4]);
4142 if (BitIsSet(registers, 15)) {
4143 context.SetRegisterPlusOffset(dwarf_reg, offset);
4145 MemARead(context, address + offset, addr_byte_size, 0, &success);
4148 // In ARMv5T and above, this is an interworking branch.
4149 if (!LoadWritePC(context, data))
4153 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4154 if (wback && BitIsClear(registers, n)) {
4158 offset = (addr_byte_size * BitCount(registers)) * -1;
4159 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4160 context.SetImmediateSigned(offset);
4161 addr_t addr = Rn + offset;
4162 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4167 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4168 if (wback && BitIsSet(registers, n))
4169 return WriteBits32Unknown(n);
4174 // LDMDB loads multiple registers from consecutive memory locations using an
4175 // address from a base register. The
4176 // consecutive memory locations end just below this address, and the address of
4177 // the lowest of those locations can be optionally written back to the base
4179 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4180 const ARMEncoding encoding) {
4182 // ARM pseudo code...
4183 if ConditionPassed() then
4184 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4185 address = R[n] - 4*BitCount(registers);
4188 if registers<i> == '1' then
4189 R[i] = MemA[address,4]; address = address + 4;
4190 if registers<15> == '1' then
4191 LoadWritePC(MemA[address,4]);
4193 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4194 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4197 bool success = false;
4199 if (ConditionPassed(opcode)) {
4201 uint32_t registers = 0;
4203 const uint32_t addr_byte_size = GetAddressByteSize();
4206 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4207 n = Bits32(opcode, 19, 16);
4208 registers = Bits32(opcode, 15, 0);
4209 registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4210 wback = BitIsSet(opcode, 21);
4212 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4214 if ((n == 15) || (BitCount(registers) < 2) ||
4215 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4218 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4220 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4223 // if wback && registers<n> == '1' then UNPREDICTABLE;
4224 if (wback && BitIsSet(registers, n))
4230 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4231 n = Bits32(opcode, 19, 16);
4232 registers = Bits32(opcode, 15, 0);
4233 wback = BitIsSet(opcode, 21);
4235 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4236 if ((n == 15) || (BitCount(registers) < 1))
4245 // address = R[n] - 4*BitCount(registers);
4249 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4254 addr_t address = Rn - (addr_byte_size * BitCount(registers));
4255 EmulateInstruction::Context context;
4256 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4257 RegisterInfo dwarf_reg;
4258 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4259 context.SetRegisterPlusOffset(dwarf_reg, Rn - address);
4261 for (int i = 0; i < 14; ++i) {
4262 if (BitIsSet(registers, i)) {
4263 // R[i] = MemA[address,4]; address = address + 4;
4264 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4266 MemARead(context, address + offset, addr_byte_size, 0, &success);
4270 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4274 offset += addr_byte_size;
4278 // if registers<15> == '1' then
4279 // LoadWritePC(MemA[address,4]);
4280 if (BitIsSet(registers, 15)) {
4281 context.SetRegisterPlusOffset(dwarf_reg, offset);
4283 MemARead(context, address + offset, addr_byte_size, 0, &success);
4286 // In ARMv5T and above, this is an interworking branch.
4287 if (!LoadWritePC(context, data))
4291 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4292 if (wback && BitIsClear(registers, n)) {
4296 offset = (addr_byte_size * BitCount(registers)) * -1;
4297 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4298 context.SetImmediateSigned(offset);
4299 addr_t addr = Rn + offset;
4300 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4305 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4306 // possible for encoding A1
4307 if (wback && BitIsSet(registers, n))
4308 return WriteBits32Unknown(n);
4313 // LDMIB loads multiple registers from consecutive memory locations using an
4314 // address from a base register. The
4315 // consecutive memory locations start just above this address, and thea ddress
4316 // of the last of those locations can optinoally be written back to the base
4318 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4319 const ARMEncoding encoding) {
4321 if ConditionPassed() then
4322 EncodingSpecificOperations();
4326 if registers<i> == '1' then
4327 R[i] = MemA[address,4]; address = address + 4;
4328 if registers<15> == '1' then
4329 LoadWritePC(MemA[address,4]);
4331 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4332 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4335 bool success = false;
4337 if (ConditionPassed(opcode)) {
4339 uint32_t registers = 0;
4341 const uint32_t addr_byte_size = GetAddressByteSize();
4344 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4345 n = Bits32(opcode, 19, 16);
4346 registers = Bits32(opcode, 15, 0);
4347 wback = BitIsSet(opcode, 21);
4349 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4350 if ((n == 15) || (BitCount(registers) < 1))
4357 // address = R[n] + 4;
4361 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4366 addr_t address = Rn + addr_byte_size;
4368 EmulateInstruction::Context context;
4369 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4370 RegisterInfo dwarf_reg;
4371 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4372 context.SetRegisterPlusOffset(dwarf_reg, offset);
4374 for (int i = 0; i < 14; ++i) {
4375 if (BitIsSet(registers, i)) {
4376 // R[i] = MemA[address,4]; address = address + 4;
4378 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size);
4380 MemARead(context, address + offset, addr_byte_size, 0, &success);
4384 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4388 offset += addr_byte_size;
4392 // if registers<15> == '1' then
4393 // LoadWritePC(MemA[address,4]);
4394 if (BitIsSet(registers, 15)) {
4395 context.SetRegisterPlusOffset(dwarf_reg, offset);
4397 MemARead(context, address + offset, addr_byte_size, 0, &success);
4400 // In ARMv5T and above, this is an interworking branch.
4401 if (!LoadWritePC(context, data))
4405 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4406 if (wback && BitIsClear(registers, n)) {
4410 offset = addr_byte_size * BitCount(registers);
4411 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4412 context.SetImmediateSigned(offset);
4413 addr_t addr = Rn + offset;
4414 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4419 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4420 // possible for encoding A1
4421 if (wback && BitIsSet(registers, n))
4422 return WriteBits32Unknown(n);
4427 // Load Register (immediate) calculates an address from a base register value
4428 // and an immediate offset, loads a word from memory, and writes to a register.
4429 // LDR (immediate, Thumb)
4430 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
4431 const ARMEncoding encoding) {
4433 // ARM pseudo code...
4434 if (ConditionPassed())
4436 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4437 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4438 address = if index then offset_addr else R[n];
4439 data = MemU[address,4];
4440 if wback then R[n] = offset_addr;
4442 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4443 elsif UnalignedSupport() || address<1:0> = '00' then
4445 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4449 bool success = false;
4451 if (ConditionPassed(opcode)) {
4452 uint32_t Rt; // the destination register
4453 uint32_t Rn; // the base register
4454 uint32_t imm32; // the immediate offset used to form the address
4455 addr_t offset_addr; // the offset address
4456 addr_t address; // the calculated address
4457 uint32_t data; // the literal data value from memory load
4458 bool add, index, wback;
4461 Rt = Bits32(opcode, 2, 0);
4462 Rn = Bits32(opcode, 5, 3);
4463 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4464 // index = TRUE; add = TRUE; wback = FALSE
4472 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4473 Rt = Bits32(opcode, 10, 8);
4475 imm32 = Bits32(opcode, 7, 0) << 2;
4477 // index = TRUE; add = TRUE; wback = FALSE;
4485 // if Rn == '1111' then SEE LDR (literal);
4486 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4487 Rt = Bits32(opcode, 15, 12);
4488 Rn = Bits32(opcode, 19, 16);
4489 imm32 = Bits32(opcode, 11, 0);
4491 // index = TRUE; add = TRUE; wback = FALSE;
4496 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4497 if ((Rt == 15) && InITBlock() && !LastInITBlock())
4503 // if Rn == '1111' then SEE LDR (literal);
4504 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4505 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4506 // '00000100' then SEE POP;
4507 // if P == '0' && W == '0' then UNDEFINED;
4508 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4511 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4512 Rt = Bits32(opcode, 15, 12);
4513 Rn = Bits32(opcode, 19, 16);
4514 imm32 = Bits32(opcode, 7, 0);
4516 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4517 index = BitIsSet(opcode, 10);
4518 add = BitIsSet(opcode, 9);
4519 wback = BitIsSet(opcode, 8);
4521 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4522 // then UNPREDICTABLE;
4523 if ((wback && (Rn == Rt)) ||
4524 ((Rt == 15) && InITBlock() && !LastInITBlock()))
4532 uint32_t base = ReadCoreReg(Rn, &success);
4536 offset_addr = base + imm32;
4538 offset_addr = base - imm32;
4540 address = (index ? offset_addr : base);
4542 RegisterInfo base_reg;
4543 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4545 EmulateInstruction::Context ctx;
4547 ctx.type = eContextAdjustStackPointer;
4548 ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4549 } else if (Rn == GetFramePointerRegisterNumber()) {
4550 ctx.type = eContextSetFramePointer;
4551 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4553 ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4554 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4557 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4562 // Prepare to write to the Rt register.
4563 EmulateInstruction::Context context;
4564 context.type = EmulateInstruction::eContextRegisterLoad;
4565 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4567 // Read memory from the address.
4568 data = MemURead(context, address, 4, 0, &success);
4573 if (Bits32(address, 1, 0) == 0) {
4574 if (!LoadWritePC(context, data))
4578 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4579 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4583 WriteBits32Unknown(Rt);
4588 // STM (Store Multiple Increment After) stores multiple registers to consecutive
4589 // memory locations using an address
4590 // from a base register. The consecutive memory locations start at this
4591 // address, and the address just above the last of those locations can
4592 // optionally be written back to the base register.
4593 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4594 const ARMEncoding encoding) {
4596 if ConditionPassed() then
4597 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4601 if registers<i> == '1' then
4602 if i == n && wback && i != LowestSetBit(registers) then
4603 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4605 MemA[address,4] = R[i];
4606 address = address + 4;
4608 if registers<15> == '1' then // Only possible for encoding A1
4609 MemA[address,4] = PCStoreValue();
4610 if wback then R[n] = R[n] + 4*BitCount(registers);
4613 bool success = false;
4615 if (ConditionPassed(opcode)) {
4617 uint32_t registers = 0;
4619 const uint32_t addr_byte_size = GetAddressByteSize();
4621 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4624 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4625 n = Bits32(opcode, 10, 8);
4626 registers = Bits32(opcode, 7, 0);
4627 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4630 // if BitCount(registers) < 1 then UNPREDICTABLE;
4631 if (BitCount(registers) < 1)
4637 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4638 n = Bits32(opcode, 19, 16);
4639 registers = Bits32(opcode, 15, 0);
4640 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4641 wback = BitIsSet(opcode, 21);
4643 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4644 if ((n == 15) || (BitCount(registers) < 2))
4647 // if wback && registers<n> == '1' then UNPREDICTABLE;
4648 if (wback && BitIsSet(registers, n))
4654 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4655 n = Bits32(opcode, 19, 16);
4656 registers = Bits32(opcode, 15, 0);
4657 wback = BitIsSet(opcode, 21);
4659 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4660 if ((n == 15) || (BitCount(registers) < 1))
4671 const addr_t address =
4672 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4676 EmulateInstruction::Context context;
4677 context.type = EmulateInstruction::eContextRegisterStore;
4678 RegisterInfo base_reg;
4679 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4682 uint32_t lowest_set_bit = 14;
4683 for (uint32_t i = 0; i < 14; ++i) {
4684 // if registers<i> == '1' then
4685 if (BitIsSet(registers, i)) {
4686 if (i < lowest_set_bit)
4688 // if i == n && wback && i != LowestSetBit(registers) then
4689 if ((i == n) && wback && (i != lowest_set_bit))
4690 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4692 WriteBits32UnknownToMemory(address + offset);
4694 // MemA[address,4] = R[i];
4695 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4700 RegisterInfo data_reg;
4701 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4702 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
4703 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4707 // address = address + 4;
4708 offset += addr_byte_size;
4712 // if registers<15> == '1' then // Only possible for encoding A1
4713 // MemA[address,4] = PCStoreValue();
4714 if (BitIsSet(registers, 15)) {
4715 RegisterInfo pc_reg;
4716 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4717 context.SetRegisterPlusOffset(pc_reg, 8);
4718 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4722 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4726 // if wback then R[n] = R[n] + 4*BitCount(registers);
4728 offset = addr_byte_size * BitCount(registers);
4729 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4730 context.SetImmediateSigned(offset);
4731 addr_t data = address + offset;
4732 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4740 // STMDA (Store Multiple Decrement After) stores multiple registers to
4741 // consecutive memory locations using an address from a base register. The
4742 // consecutive memory locations end at this address, and the address just below
4743 // the lowest of those locations can optionally be written back to the base
4745 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4746 const ARMEncoding encoding) {
4748 if ConditionPassed() then
4749 EncodingSpecificOperations();
4750 address = R[n] - 4*BitCount(registers) + 4;
4753 if registers<i> == '1' then
4754 if i == n && wback && i != LowestSetBit(registers) then
4755 MemA[address,4] = bits(32) UNKNOWN;
4757 MemA[address,4] = R[i];
4758 address = address + 4;
4760 if registers<15> == '1' then
4761 MemA[address,4] = PCStoreValue();
4763 if wback then R[n] = R[n] - 4*BitCount(registers);
4766 bool success = false;
4768 if (ConditionPassed(opcode)) {
4770 uint32_t registers = 0;
4772 const uint32_t addr_byte_size = GetAddressByteSize();
4774 // EncodingSpecificOperations();
4777 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4778 n = Bits32(opcode, 19, 16);
4779 registers = Bits32(opcode, 15, 0);
4780 wback = BitIsSet(opcode, 21);
4782 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4783 if ((n == 15) || (BitCount(registers) < 1))
4790 // address = R[n] - 4*BitCount(registers) + 4;
4792 addr_t Rn = ReadCoreReg(n, &success);
4796 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4798 EmulateInstruction::Context context;
4799 context.type = EmulateInstruction::eContextRegisterStore;
4800 RegisterInfo base_reg;
4801 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4804 uint32_t lowest_bit_set = 14;
4805 for (uint32_t i = 0; i < 14; ++i) {
4806 // if registers<i> == '1' then
4807 if (BitIsSet(registers, i)) {
4808 if (i < lowest_bit_set)
4810 // if i == n && wback && i != LowestSetBit(registers) then
4811 if ((i == n) && wback && (i != lowest_bit_set))
4812 // MemA[address,4] = bits(32) UNKNOWN;
4813 WriteBits32UnknownToMemory(address + offset);
4815 // MemA[address,4] = R[i];
4816 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4821 RegisterInfo data_reg;
4822 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4823 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4824 Rn - (address + offset));
4825 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4829 // address = address + 4;
4830 offset += addr_byte_size;
4834 // if registers<15> == '1' then
4835 // MemA[address,4] = PCStoreValue();
4836 if (BitIsSet(registers, 15)) {
4837 RegisterInfo pc_reg;
4838 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4839 context.SetRegisterPlusOffset(pc_reg, 8);
4840 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4844 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4848 // if wback then R[n] = R[n] - 4*BitCount(registers);
4850 offset = (addr_byte_size * BitCount(registers)) * -1;
4851 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4852 context.SetImmediateSigned(offset);
4853 addr_t data = Rn + offset;
4854 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4862 // STMDB (Store Multiple Decrement Before) stores multiple registers to
4863 // consecutive memory locations using an address from a base register. The
4864 // consecutive memory locations end just below this address, and the address of
4865 // the first of those locations can optionally be written back to the base
4867 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4868 const ARMEncoding encoding) {
4870 if ConditionPassed() then
4871 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4872 address = R[n] - 4*BitCount(registers);
4875 if registers<i> == '1' then
4876 if i == n && wback && i != LowestSetBit(registers) then
4877 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4879 MemA[address,4] = R[i];
4880 address = address + 4;
4882 if registers<15> == '1' then // Only possible for encoding A1
4883 MemA[address,4] = PCStoreValue();
4885 if wback then R[n] = R[n] - 4*BitCount(registers);
4888 bool success = false;
4890 if (ConditionPassed(opcode)) {
4892 uint32_t registers = 0;
4894 const uint32_t addr_byte_size = GetAddressByteSize();
4896 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4899 // if W == '1' && Rn == '1101' then SEE PUSH;
4900 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4903 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4904 n = Bits32(opcode, 19, 16);
4905 registers = Bits32(opcode, 15, 0);
4906 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4907 wback = BitIsSet(opcode, 21);
4908 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4909 if ((n == 15) || BitCount(registers) < 2)
4911 // if wback && registers<n> == '1' then UNPREDICTABLE;
4912 if (wback && BitIsSet(registers, n))
4917 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4919 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4920 BitCount(Bits32(opcode, 15, 0)) >= 2) {
4923 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4924 n = Bits32(opcode, 19, 16);
4925 registers = Bits32(opcode, 15, 0);
4926 wback = BitIsSet(opcode, 21);
4927 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4928 if ((n == 15) || BitCount(registers) < 1)
4936 // address = R[n] - 4*BitCount(registers);
4940 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4944 addr_t address = Rn - (addr_byte_size * BitCount(registers));
4946 EmulateInstruction::Context context;
4947 context.type = EmulateInstruction::eContextRegisterStore;
4948 RegisterInfo base_reg;
4949 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4952 uint32_t lowest_set_bit = 14;
4953 for (uint32_t i = 0; i < 14; ++i) {
4954 // if registers<i> == '1' then
4955 if (BitIsSet(registers, i)) {
4956 if (i < lowest_set_bit)
4958 // if i == n && wback && i != LowestSetBit(registers) then
4959 if ((i == n) && wback && (i != lowest_set_bit))
4960 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4962 WriteBits32UnknownToMemory(address + offset);
4964 // MemA[address,4] = R[i];
4965 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4970 RegisterInfo data_reg;
4971 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4972 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4973 Rn - (address + offset));
4974 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4978 // address = address + 4;
4979 offset += addr_byte_size;
4983 // if registers<15> == '1' then // Only possible for encoding A1
4984 // MemA[address,4] = PCStoreValue();
4985 if (BitIsSet(registers, 15)) {
4986 RegisterInfo pc_reg;
4987 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4988 context.SetRegisterPlusOffset(pc_reg, 8);
4989 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4993 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4997 // if wback then R[n] = R[n] - 4*BitCount(registers);
4999 offset = (addr_byte_size * BitCount(registers)) * -1;
5000 context.type = EmulateInstruction::eContextAdjustBaseRegister;
5001 context.SetImmediateSigned(offset);
5002 addr_t data = Rn + offset;
5003 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5011 // STMIB (Store Multiple Increment Before) stores multiple registers to
5012 // consecutive memory locations using an address from a base register. The
5013 // consecutive memory locations start just above this address, and the address
5014 // of the last of those locations can optionally be written back to the base
5016 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
5017 const ARMEncoding encoding) {
5019 if ConditionPassed() then
5020 EncodingSpecificOperations();
5024 if registers<i> == '1' then
5025 if i == n && wback && i != LowestSetBit(registers) then
5026 MemA[address,4] = bits(32) UNKNOWN;
5028 MemA[address,4] = R[i];
5029 address = address + 4;
5031 if registers<15> == '1' then
5032 MemA[address,4] = PCStoreValue();
5034 if wback then R[n] = R[n] + 4*BitCount(registers);
5037 bool success = false;
5039 if (ConditionPassed(opcode)) {
5041 uint32_t registers = 0;
5043 const uint32_t addr_byte_size = GetAddressByteSize();
5045 // EncodingSpecificOperations();
5048 // n = UInt(Rn); registers = register_list; wback = (W == '1');
5049 n = Bits32(opcode, 19, 16);
5050 registers = Bits32(opcode, 15, 0);
5051 wback = BitIsSet(opcode, 21);
5053 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5054 if ((n == 15) && (BitCount(registers) < 1))
5060 // address = R[n] + 4;
5063 addr_t Rn = ReadCoreReg(n, &success);
5067 addr_t address = Rn + addr_byte_size;
5069 EmulateInstruction::Context context;
5070 context.type = EmulateInstruction::eContextRegisterStore;
5071 RegisterInfo base_reg;
5072 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5074 uint32_t lowest_set_bit = 14;
5076 for (uint32_t i = 0; i < 14; ++i) {
5077 // if registers<i> == '1' then
5078 if (BitIsSet(registers, i)) {
5079 if (i < lowest_set_bit)
5081 // if i == n && wback && i != LowestSetBit(registers) then
5082 if ((i == n) && wback && (i != lowest_set_bit))
5083 // MemA[address,4] = bits(32) UNKNOWN;
5084 WriteBits32UnknownToMemory(address + offset);
5087 // MemA[address,4] = R[i];
5088 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5093 RegisterInfo data_reg;
5094 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
5095 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5096 offset + addr_byte_size);
5097 if (!MemAWrite(context, address + offset, data, addr_byte_size))
5101 // address = address + 4;
5102 offset += addr_byte_size;
5106 // if registers<15> == '1' then
5107 // MemA[address,4] = PCStoreValue();
5108 if (BitIsSet(registers, 15)) {
5109 RegisterInfo pc_reg;
5110 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
5111 context.SetRegisterPlusOffset(pc_reg, 8);
5112 const uint32_t pc = ReadCoreReg(PC_REG, &success);
5116 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5120 // if wback then R[n] = R[n] + 4*BitCount(registers);
5122 offset = addr_byte_size * BitCount(registers);
5123 context.type = EmulateInstruction::eContextAdjustBaseRegister;
5124 context.SetImmediateSigned(offset);
5125 addr_t data = Rn + offset;
5126 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5134 // STR (store immediate) calculates an address from a base register value and an
5135 // immediate offset, and stores a word
5136 // from a register to memory. It can use offset, post-indexed, or pre-indexed
5138 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
5139 const ARMEncoding encoding) {
5141 if ConditionPassed() then
5142 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5143 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5144 address = if index then offset_addr else R[n];
5145 if UnalignedSupport() || address<1:0> == '00' then
5146 MemU[address,4] = R[t];
5147 else // Can only occur before ARMv7
5148 MemU[address,4] = bits(32) UNKNOWN;
5149 if wback then R[n] = offset_addr;
5152 bool success = false;
5154 if (ConditionPassed(opcode)) {
5155 const uint32_t addr_byte_size = GetAddressByteSize();
5163 // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5166 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
5167 t = Bits32(opcode, 2, 0);
5168 n = Bits32(opcode, 5, 3);
5169 imm32 = Bits32(opcode, 10, 6) << 2;
5171 // index = TRUE; add = TRUE; wback = FALSE;
5178 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
5179 t = Bits32(opcode, 10, 8);
5181 imm32 = Bits32(opcode, 7, 0) << 2;
5183 // index = TRUE; add = TRUE; wback = FALSE;
5190 // if Rn == '1111' then UNDEFINED;
5191 if (Bits32(opcode, 19, 16) == 15)
5194 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5195 t = Bits32(opcode, 15, 12);
5196 n = Bits32(opcode, 19, 16);
5197 imm32 = Bits32(opcode, 11, 0);
5199 // index = TRUE; add = TRUE; wback = FALSE;
5204 // if t == 15 then UNPREDICTABLE;
5210 // if P == '1' && U == '1' && W == '0' then SEE STRT;
5211 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
5212 // '00000100' then SEE PUSH;
5213 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5214 if ((Bits32(opcode, 19, 16) == 15) ||
5215 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
5218 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5219 t = Bits32(opcode, 15, 12);
5220 n = Bits32(opcode, 19, 16);
5221 imm32 = Bits32(opcode, 7, 0);
5223 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5224 index = BitIsSet(opcode, 10);
5225 add = BitIsSet(opcode, 9);
5226 wback = BitIsSet(opcode, 8);
5228 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
5229 if ((t == 15) || (wback && (n == t)))
5240 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5241 uint32_t base_address = ReadCoreReg(n, &success);
5246 offset_addr = base_address + imm32;
5248 offset_addr = base_address - imm32;
5250 // address = if index then offset_addr else R[n];
5252 address = offset_addr;
5254 address = base_address;
5256 EmulateInstruction::Context context;
5258 context.type = eContextPushRegisterOnStack;
5260 context.type = eContextRegisterStore;
5262 RegisterInfo base_reg;
5263 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5265 // if UnalignedSupport() || address<1:0> == '00' then
5266 if (UnalignedSupport() ||
5267 (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5268 // MemU[address,4] = R[t];
5270 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5274 RegisterInfo data_reg;
5275 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5276 int32_t offset = address - base_address;
5277 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
5278 if (!MemUWrite(context, address, data, addr_byte_size))
5281 // MemU[address,4] = bits(32) UNKNOWN;
5282 WriteBits32UnknownToMemory(address);
5285 // if wback then R[n] = offset_addr;
5288 context.type = eContextAdjustStackPointer;
5290 context.type = eContextAdjustBaseRegister;
5291 context.SetAddress(offset_addr);
5293 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5301 // STR (Store Register) calculates an address from a base register value and an
5302 // offset register value, stores a
5303 // word from a register to memory. The offset register value can optionally
5305 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
5306 const ARMEncoding encoding) {
5308 if ConditionPassed() then
5309 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5310 offset = Shift(R[m], shift_t, shift_n, APSR.C);
5311 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5312 address = if index then offset_addr else R[n];
5313 if t == 15 then // Only possible for encoding A1
5314 data = PCStoreValue();
5317 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
5318 MemU[address,4] = data;
5319 else // Can only occur before ARMv7
5320 MemU[address,4] = bits(32) UNKNOWN;
5321 if wback then R[n] = offset_addr;
5324 bool success = false;
5326 if (ConditionPassed(opcode)) {
5327 const uint32_t addr_byte_size = GetAddressByteSize();
5332 ARM_ShifterType shift_t;
5338 // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5341 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5343 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5344 t = Bits32(opcode, 2, 0);
5345 n = Bits32(opcode, 5, 3);
5346 m = Bits32(opcode, 8, 6);
5348 // index = TRUE; add = TRUE; wback = FALSE;
5353 // (shift_t, shift_n) = (SRType_LSL, 0);
5354 shift_t = SRType_LSL;
5359 // if Rn == '1111' then UNDEFINED;
5360 if (Bits32(opcode, 19, 16) == 15)
5363 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5364 t = Bits32(opcode, 15, 12);
5365 n = Bits32(opcode, 19, 16);
5366 m = Bits32(opcode, 3, 0);
5368 // index = TRUE; add = TRUE; wback = FALSE;
5373 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5374 shift_t = SRType_LSL;
5375 shift_n = Bits32(opcode, 5, 4);
5377 // if t == 15 || BadReg(m) then UNPREDICTABLE;
5378 if ((t == 15) || (BadReg(m)))
5383 // if P == '0' && W == '1' then SEE STRT;
5384 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5385 t = Bits32(opcode, 15, 12);
5386 n = Bits32(opcode, 19, 16);
5387 m = Bits32(opcode, 3, 0);
5389 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
5391 index = BitIsSet(opcode, 24);
5392 add = BitIsSet(opcode, 23);
5393 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5395 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5396 uint32_t typ = Bits32(opcode, 6, 5);
5397 uint32_t imm5 = Bits32(opcode, 11, 7);
5398 shift_n = DecodeImmShift(typ, imm5, shift_t);
5400 // if m == 15 then UNPREDICTABLE;
5404 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5405 if (wback && ((n == 15) || (n == t)))
5418 addr_t base_address =
5419 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5424 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5428 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5429 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
5433 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5435 offset_addr = base_address + offset;
5437 offset_addr = base_address - offset;
5439 // address = if index then offset_addr else R[n];
5441 address = offset_addr;
5443 address = base_address;
5446 // if t == 15 then // Only possible for encoding A1
5448 // data = PCStoreValue();
5449 data = ReadCoreReg(PC_REG, &success);
5453 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5458 EmulateInstruction::Context context;
5459 context.type = eContextRegisterStore;
5461 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
5462 // InstrSet_ARM then
5463 if (UnalignedSupport() ||
5464 (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
5465 CurrentInstrSet() == eModeARM) {
5466 // MemU[address,4] = data;
5468 RegisterInfo base_reg;
5469 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5471 RegisterInfo data_reg;
5472 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5474 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5475 address - base_address);
5476 if (!MemUWrite(context, address, data, addr_byte_size))
5480 // MemU[address,4] = bits(32) UNKNOWN;
5481 WriteBits32UnknownToMemory(address);
5483 // if wback then R[n] = offset_addr;
5485 context.type = eContextRegisterLoad;
5486 context.SetAddress(offset_addr);
5487 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5495 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
5496 const ARMEncoding encoding) {
5498 if ConditionPassed() then
5499 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5500 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5501 address = if index then offset_addr else R[n];
5502 MemU[address,1] = R[t]<7:0>;
5503 if wback then R[n] = offset_addr;
5506 bool success = false;
5508 if (ConditionPassed(opcode)) {
5515 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5518 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5519 t = Bits32(opcode, 2, 0);
5520 n = Bits32(opcode, 5, 3);
5521 imm32 = Bits32(opcode, 10, 6);
5523 // index = TRUE; add = TRUE; wback = FALSE;
5530 // if Rn == '1111' then UNDEFINED;
5531 if (Bits32(opcode, 19, 16) == 15)
5534 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5535 t = Bits32(opcode, 15, 12);
5536 n = Bits32(opcode, 19, 16);
5537 imm32 = Bits32(opcode, 11, 0);
5539 // index = TRUE; add = TRUE; wback = FALSE;
5544 // if BadReg(t) then UNPREDICTABLE;
5550 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5551 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5552 if (Bits32(opcode, 19, 16) == 15)
5555 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5556 t = Bits32(opcode, 15, 12);
5557 n = Bits32(opcode, 19, 16);
5558 imm32 = Bits32(opcode, 7, 0);
5560 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5561 index = BitIsSet(opcode, 10);
5562 add = BitIsSet(opcode, 9);
5563 wback = BitIsSet(opcode, 8);
5565 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5566 if ((BadReg(t)) || (wback && (n == t)))
5576 addr_t base_address =
5577 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5581 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5583 offset_addr = base_address + imm32;
5585 offset_addr = base_address - imm32;
5587 // address = if index then offset_addr else R[n];
5589 address = offset_addr;
5591 address = base_address;
5593 // MemU[address,1] = R[t]<7:0>
5594 RegisterInfo base_reg;
5595 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5597 RegisterInfo data_reg;
5598 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5600 EmulateInstruction::Context context;
5601 context.type = eContextRegisterStore;
5602 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5603 address - base_address);
5606 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5610 data = Bits32(data, 7, 0);
5612 if (!MemUWrite(context, address, data, 1))
5615 // if wback then R[n] = offset_addr;
5617 context.type = eContextRegisterLoad;
5618 context.SetAddress(offset_addr);
5619 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5628 // STRH (register) calculates an address from a base register value and an
5629 // offset register value, and stores a
5630 // halfword from a register to memory. The offset register value can be
5631 // shifted left by 0, 1, 2, or 3 bits.
5632 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5633 const ARMEncoding encoding) {
5635 if ConditionPassed() then
5636 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5637 offset = Shift(R[m], shift_t, shift_n, APSR.C);
5638 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5639 address = if index then offset_addr else R[n];
5640 if UnalignedSupport() || address<0> == '0' then
5641 MemU[address,2] = R[t]<15:0>;
5642 else // Can only occur before ARMv7
5643 MemU[address,2] = bits(16) UNKNOWN;
5644 if wback then R[n] = offset_addr;
5647 bool success = false;
5649 if (ConditionPassed(opcode)) {
5656 ARM_ShifterType shift_t;
5659 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5662 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5664 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5665 t = Bits32(opcode, 2, 0);
5666 n = Bits32(opcode, 5, 3);
5667 m = Bits32(opcode, 8, 6);
5669 // index = TRUE; add = TRUE; wback = FALSE;
5674 // (shift_t, shift_n) = (SRType_LSL, 0);
5675 shift_t = SRType_LSL;
5681 // if Rn == '1111' then UNDEFINED;
5682 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5683 t = Bits32(opcode, 15, 12);
5684 n = Bits32(opcode, 19, 16);
5685 m = Bits32(opcode, 3, 0);
5689 // index = TRUE; add = TRUE; wback = FALSE;
5694 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5695 shift_t = SRType_LSL;
5696 shift_n = Bits32(opcode, 5, 4);
5698 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5699 if (BadReg(t) || BadReg(m))
5705 // if P == '0' && W == '1' then SEE STRHT;
5706 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5707 t = Bits32(opcode, 15, 12);
5708 n = Bits32(opcode, 19, 16);
5709 m = Bits32(opcode, 3, 0);
5711 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
5713 index = BitIsSet(opcode, 24);
5714 add = BitIsSet(opcode, 23);
5715 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5717 // (shift_t, shift_n) = (SRType_LSL, 0);
5718 shift_t = SRType_LSL;
5721 // if t == 15 || m == 15 then UNPREDICTABLE;
5722 if ((t == 15) || (m == 15))
5725 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5726 if (wback && ((n == 15) || (n == t)))
5735 uint32_t Rm = ReadCoreReg(m, &success);
5739 uint32_t Rn = ReadCoreReg(n, &success);
5743 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5744 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5748 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5751 offset_addr = Rn + offset;
5753 offset_addr = Rn - offset;
5755 // address = if index then offset_addr else R[n];
5758 address = offset_addr;
5762 EmulateInstruction::Context context;
5763 context.type = eContextRegisterStore;
5764 RegisterInfo base_reg;
5765 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5766 RegisterInfo offset_reg;
5767 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5769 // if UnalignedSupport() || address<0> == '0' then
5770 if (UnalignedSupport() || BitIsClear(address, 0)) {
5771 // MemU[address,2] = R[t]<15:0>;
5772 uint32_t Rt = ReadCoreReg(t, &success);
5776 EmulateInstruction::Context context;
5777 context.type = eContextRegisterStore;
5778 RegisterInfo base_reg;
5779 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5780 RegisterInfo offset_reg;
5781 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5782 RegisterInfo data_reg;
5783 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5784 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
5787 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5789 } else // Can only occur before ARMv7
5791 // MemU[address,2] = bits(16) UNKNOWN;
5794 // if wback then R[n] = offset_addr;
5796 context.type = eContextAdjustBaseRegister;
5797 context.SetAddress(offset_addr);
5798 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5807 // Add with Carry (immediate) adds an immediate value and the carry flag value
5808 // to a register value, and writes the result to the destination register. It
5809 // can optionally update the condition flags based on the result.
5810 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5811 const ARMEncoding encoding) {
5813 // ARM pseudo code...
5814 if ConditionPassed() then
5815 EncodingSpecificOperations();
5816 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5817 if d == 15 then // Can only occur for ARM encoding
5818 ALUWritePC(result); // setflags is always FALSE here
5822 APSR.N = result<31>;
5823 APSR.Z = IsZeroBit(result);
5828 bool success = false;
5830 if (ConditionPassed(opcode)) {
5833 imm32; // the immediate value to be added to the value obtained from Rn
5837 Rd = Bits32(opcode, 11, 8);
5838 Rn = Bits32(opcode, 19, 16);
5839 setflags = BitIsSet(opcode, 20);
5840 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5841 if (BadReg(Rd) || BadReg(Rn))
5845 Rd = Bits32(opcode, 15, 12);
5846 Rn = Bits32(opcode, 19, 16);
5847 setflags = BitIsSet(opcode, 20);
5848 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5850 if (Rd == 15 && setflags)
5851 return EmulateSUBSPcLrEtc(opcode, encoding);
5857 // Read the first operand.
5858 int32_t val1 = ReadCoreReg(Rn, &success);
5862 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5864 EmulateInstruction::Context context;
5865 context.type = EmulateInstruction::eContextImmediate;
5866 context.SetNoArgs();
5868 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5869 res.carry_out, res.overflow))
5875 // Add with Carry (register) adds a register value, the carry flag value, and
5876 // an optionally-shifted register value, and writes the result to the
5877 // destination register. It can optionally update the condition flags based on
5879 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5880 const ARMEncoding encoding) {
5882 // ARM pseudo code...
5883 if ConditionPassed() then
5884 EncodingSpecificOperations();
5885 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5886 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5887 if d == 15 then // Can only occur for ARM encoding
5888 ALUWritePC(result); // setflags is always FALSE here
5892 APSR.N = result<31>;
5893 APSR.Z = IsZeroBit(result);
5898 bool success = false;
5900 if (ConditionPassed(opcode)) {
5901 uint32_t Rd, Rn, Rm;
5902 ARM_ShifterType shift_t;
5903 uint32_t shift_n; // the shift applied to the value read from Rm
5907 Rd = Rn = Bits32(opcode, 2, 0);
5908 Rm = Bits32(opcode, 5, 3);
5909 setflags = !InITBlock();
5910 shift_t = SRType_LSL;
5914 Rd = Bits32(opcode, 11, 8);
5915 Rn = Bits32(opcode, 19, 16);
5916 Rm = Bits32(opcode, 3, 0);
5917 setflags = BitIsSet(opcode, 20);
5918 shift_n = DecodeImmShiftThumb(opcode, shift_t);
5919 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5923 Rd = Bits32(opcode, 15, 12);
5924 Rn = Bits32(opcode, 19, 16);
5925 Rm = Bits32(opcode, 3, 0);
5926 setflags = BitIsSet(opcode, 20);
5927 shift_n = DecodeImmShiftARM(opcode, shift_t);
5929 if (Rd == 15 && setflags)
5930 return EmulateSUBSPcLrEtc(opcode, encoding);
5936 // Read the first operand.
5937 int32_t val1 = ReadCoreReg(Rn, &success);
5941 // Read the second operand.
5942 int32_t val2 = ReadCoreReg(Rm, &success);
5946 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5949 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5951 EmulateInstruction::Context context;
5952 context.type = EmulateInstruction::eContextImmediate;
5953 context.SetNoArgs();
5955 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5956 res.carry_out, res.overflow))
5962 // This instruction adds an immediate value to the PC value to form a PC-
5963 // relative address, and writes the result to the destination register.
5964 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
5965 const ARMEncoding encoding) {
5967 // ARM pseudo code...
5968 if ConditionPassed() then
5969 EncodingSpecificOperations();
5970 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5971 if d == 15 then // Can only occur for ARM encodings
5977 bool success = false;
5979 if (ConditionPassed(opcode)) {
5981 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5985 Rd = Bits32(opcode, 10, 8);
5986 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5991 Rd = Bits32(opcode, 11, 8);
5992 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5993 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5999 Rd = Bits32(opcode, 15, 12);
6000 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
6001 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
6007 // Read the PC value.
6008 uint32_t pc = ReadCoreReg(PC_REG, &success);
6012 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
6014 EmulateInstruction::Context context;
6015 context.type = EmulateInstruction::eContextImmediate;
6016 context.SetNoArgs();
6018 if (!WriteCoreReg(context, result, Rd))
6024 // This instruction performs a bitwise AND of a register value and an immediate
6025 // value, and writes the result to the destination register. It can optionally
6026 // update the condition flags based on the result.
6027 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
6028 const ARMEncoding encoding) {
6030 // ARM pseudo code...
6031 if ConditionPassed() then
6032 EncodingSpecificOperations();
6033 result = R[n] AND imm32;
6034 if d == 15 then // Can only occur for ARM encoding
6035 ALUWritePC(result); // setflags is always FALSE here
6039 APSR.N = result<31>;
6040 APSR.Z = IsZeroBit(result);
6045 bool success = false;
6047 if (ConditionPassed(opcode)) {
6050 imm32; // the immediate value to be ANDed to the value obtained from Rn
6052 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6055 Rd = Bits32(opcode, 11, 8);
6056 Rn = Bits32(opcode, 19, 16);
6057 setflags = BitIsSet(opcode, 20);
6058 imm32 = ThumbExpandImm_C(
6060 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6061 // if Rd == '1111' && S == '1' then SEE TST (immediate);
6062 if (Rd == 15 && setflags)
6063 return EmulateTSTImm(opcode, eEncodingT1);
6064 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
6068 Rd = Bits32(opcode, 15, 12);
6069 Rn = Bits32(opcode, 19, 16);
6070 setflags = BitIsSet(opcode, 20);
6072 ARMExpandImm_C(opcode, APSR_C,
6073 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6075 if (Rd == 15 && setflags)
6076 return EmulateSUBSPcLrEtc(opcode, encoding);
6082 // Read the first operand.
6083 uint32_t val1 = ReadCoreReg(Rn, &success);
6087 uint32_t result = val1 & imm32;
6089 EmulateInstruction::Context context;
6090 context.type = EmulateInstruction::eContextImmediate;
6091 context.SetNoArgs();
6093 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6099 // This instruction performs a bitwise AND of a register value and an
6100 // optionally-shifted register value, and writes the result to the destination
6101 // register. It can optionally update the condition flags based on the result.
6102 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
6103 const ARMEncoding encoding) {
6105 // ARM pseudo code...
6106 if ConditionPassed() then
6107 EncodingSpecificOperations();
6108 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6109 result = R[n] AND shifted;
6110 if d == 15 then // Can only occur for ARM encoding
6111 ALUWritePC(result); // setflags is always FALSE here
6115 APSR.N = result<31>;
6116 APSR.Z = IsZeroBit(result);
6121 bool success = false;
6123 if (ConditionPassed(opcode)) {
6124 uint32_t Rd, Rn, Rm;
6125 ARM_ShifterType shift_t;
6126 uint32_t shift_n; // the shift applied to the value read from Rm
6131 Rd = Rn = Bits32(opcode, 2, 0);
6132 Rm = Bits32(opcode, 5, 3);
6133 setflags = !InITBlock();
6134 shift_t = SRType_LSL;
6138 Rd = Bits32(opcode, 11, 8);
6139 Rn = Bits32(opcode, 19, 16);
6140 Rm = Bits32(opcode, 3, 0);
6141 setflags = BitIsSet(opcode, 20);
6142 shift_n = DecodeImmShiftThumb(opcode, shift_t);
6143 // if Rd == '1111' && S == '1' then SEE TST (register);
6144 if (Rd == 15 && setflags)
6145 return EmulateTSTReg(opcode, eEncodingT2);
6146 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
6150 Rd = Bits32(opcode, 15, 12);
6151 Rn = Bits32(opcode, 19, 16);
6152 Rm = Bits32(opcode, 3, 0);
6153 setflags = BitIsSet(opcode, 20);
6154 shift_n = DecodeImmShiftARM(opcode, shift_t);
6156 if (Rd == 15 && setflags)
6157 return EmulateSUBSPcLrEtc(opcode, encoding);
6163 // Read the first operand.
6164 uint32_t val1 = ReadCoreReg(Rn, &success);
6168 // Read the second operand.
6169 uint32_t val2 = ReadCoreReg(Rm, &success);
6173 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6176 uint32_t result = val1 & shifted;
6178 EmulateInstruction::Context context;
6179 context.type = EmulateInstruction::eContextImmediate;
6180 context.SetNoArgs();
6182 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6188 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
6189 // the complement of an immediate value, and writes the result to the
6190 // destination register. It can optionally update the condition flags based on
6192 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
6193 const ARMEncoding encoding) {
6195 // ARM pseudo code...
6196 if ConditionPassed() then
6197 EncodingSpecificOperations();
6198 result = R[n] AND NOT(imm32);
6199 if d == 15 then // Can only occur for ARM encoding
6200 ALUWritePC(result); // setflags is always FALSE here
6204 APSR.N = result<31>;
6205 APSR.Z = IsZeroBit(result);
6210 bool success = false;
6212 if (ConditionPassed(opcode)) {
6214 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
6215 // the value obtained from Rn
6217 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6220 Rd = Bits32(opcode, 11, 8);
6221 Rn = Bits32(opcode, 19, 16);
6222 setflags = BitIsSet(opcode, 20);
6223 imm32 = ThumbExpandImm_C(
6225 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6226 if (BadReg(Rd) || BadReg(Rn))
6230 Rd = Bits32(opcode, 15, 12);
6231 Rn = Bits32(opcode, 19, 16);
6232 setflags = BitIsSet(opcode, 20);
6234 ARMExpandImm_C(opcode, APSR_C,
6235 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6237 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6239 if (Rd == 15 && setflags)
6240 return EmulateSUBSPcLrEtc(opcode, encoding);
6246 // Read the first operand.
6247 uint32_t val1 = ReadCoreReg(Rn, &success);
6251 uint32_t result = val1 & ~imm32;
6253 EmulateInstruction::Context context;
6254 context.type = EmulateInstruction::eContextImmediate;
6255 context.SetNoArgs();
6257 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6263 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and
6264 // the complement of an optionally-shifted register value, and writes the
6265 // result to the destination register. It can optionally update the condition
6266 // flags based on the result.
6267 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
6268 const ARMEncoding encoding) {
6270 // ARM pseudo code...
6271 if ConditionPassed() then
6272 EncodingSpecificOperations();
6273 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6274 result = R[n] AND NOT(shifted);
6275 if d == 15 then // Can only occur for ARM encoding
6276 ALUWritePC(result); // setflags is always FALSE here
6280 APSR.N = result<31>;
6281 APSR.Z = IsZeroBit(result);
6286 bool success = false;
6288 if (ConditionPassed(opcode)) {
6289 uint32_t Rd, Rn, Rm;
6290 ARM_ShifterType shift_t;
6291 uint32_t shift_n; // the shift applied to the value read from Rm
6296 Rd = Rn = Bits32(opcode, 2, 0);
6297 Rm = Bits32(opcode, 5, 3);
6298 setflags = !InITBlock();
6299 shift_t = SRType_LSL;
6303 Rd = Bits32(opcode, 11, 8);
6304 Rn = Bits32(opcode, 19, 16);
6305 Rm = Bits32(opcode, 3, 0);
6306 setflags = BitIsSet(opcode, 20);
6307 shift_n = DecodeImmShiftThumb(opcode, shift_t);
6308 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
6312 Rd = Bits32(opcode, 15, 12);
6313 Rn = Bits32(opcode, 19, 16);
6314 Rm = Bits32(opcode, 3, 0);
6315 setflags = BitIsSet(opcode, 20);
6316 shift_n = DecodeImmShiftARM(opcode, shift_t);
6318 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6320 if (Rd == 15 && setflags)
6321 return EmulateSUBSPcLrEtc(opcode, encoding);
6327 // Read the first operand.
6328 uint32_t val1 = ReadCoreReg(Rn, &success);
6332 // Read the second operand.
6333 uint32_t val2 = ReadCoreReg(Rm, &success);
6337 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6340 uint32_t result = val1 & ~shifted;
6342 EmulateInstruction::Context context;
6343 context.type = EmulateInstruction::eContextImmediate;
6344 context.SetNoArgs();
6346 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6352 // LDR (immediate, ARM) calculates an address from a base register value and an
6353 // immediate offset, loads a word
6354 // from memory, and writes it to a register. It can use offset, post-indexed,
6355 // or pre-indexed addressing.
6356 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
6357 const ARMEncoding encoding) {
6359 if ConditionPassed() then
6360 EncodingSpecificOperations();
6361 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6362 address = if index then offset_addr else R[n];
6363 data = MemU[address,4];
6364 if wback then R[n] = offset_addr;
6366 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6367 elsif UnalignedSupport() || address<1:0> = '00' then
6369 else // Can only apply before ARMv7
6370 R[t] = ROR(data, 8*UInt(address<1:0>));
6373 bool success = false;
6375 if (ConditionPassed(opcode)) {
6376 const uint32_t addr_byte_size = GetAddressByteSize();
6387 // if Rn == '1111' then SEE LDR (literal);
6388 // if P == '0' && W == '1' then SEE LDRT;
6389 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
6390 // '000000000100' then SEE POP;
6391 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6392 t = Bits32(opcode, 15, 12);
6393 n = Bits32(opcode, 19, 16);
6394 imm32 = Bits32(opcode, 11, 0);
6396 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
6398 index = BitIsSet(opcode, 24);
6399 add = BitIsSet(opcode, 23);
6400 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6402 // if wback && n == t then UNPREDICTABLE;
6403 if (wback && (n == t))
6414 addr_t base_address = ReadCoreReg(n, &success);
6418 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6420 offset_addr = base_address + imm32;
6422 offset_addr = base_address - imm32;
6424 // address = if index then offset_addr else R[n];
6426 address = offset_addr;
6428 address = base_address;
6430 // data = MemU[address,4];
6432 RegisterInfo base_reg;
6433 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6435 EmulateInstruction::Context context;
6436 context.type = eContextRegisterLoad;
6437 context.SetRegisterPlusOffset(base_reg, address - base_address);
6439 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6443 // if wback then R[n] = offset_addr;
6445 context.type = eContextAdjustBaseRegister;
6446 context.SetAddress(offset_addr);
6447 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6454 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6455 if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6456 // LoadWritePC (data);
6457 context.type = eContextRegisterLoad;
6458 context.SetRegisterPlusOffset(base_reg, address - base_address);
6459 LoadWritePC(context, data);
6463 // elsif UnalignedSupport() || address<1:0> = '00' then
6464 else if (UnalignedSupport() ||
6465 (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6467 context.type = eContextRegisterLoad;
6468 context.SetRegisterPlusOffset(base_reg, address - base_address);
6469 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6473 // else // Can only apply before ARMv7
6475 // R[t] = ROR(data, 8*UInt(address<1:0>));
6476 data = ROR(data, Bits32(address, 1, 0), &success);
6479 context.type = eContextRegisterLoad;
6480 context.SetImmediate(data);
6481 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6489 // LDR (register) calculates an address from a base register value and an offset
6490 // register value, loads a word
6491 // from memory, and writes it to a register. The offset register value can
6492 // optionally be shifted.
6493 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
6494 const ARMEncoding encoding) {
6496 if ConditionPassed() then
6497 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6498 offset = Shift(R[m], shift_t, shift_n, APSR.C);
6499 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6500 address = if index then offset_addr else R[n];
6501 data = MemU[address,4];
6502 if wback then R[n] = offset_addr;
6504 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6505 elsif UnalignedSupport() || address<1:0> = '00' then
6507 else // Can only apply before ARMv7
6508 if CurrentInstrSet() == InstrSet_ARM then
6509 R[t] = ROR(data, 8*UInt(address<1:0>));
6511 R[t] = bits(32) UNKNOWN;
6514 bool success = false;
6516 if (ConditionPassed(opcode)) {
6517 const uint32_t addr_byte_size = GetAddressByteSize();
6525 ARM_ShifterType shift_t;
6530 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6532 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6533 t = Bits32(opcode, 2, 0);
6534 n = Bits32(opcode, 5, 3);
6535 m = Bits32(opcode, 8, 6);
6537 // index = TRUE; add = TRUE; wback = FALSE;
6542 // (shift_t, shift_n) = (SRType_LSL, 0);
6543 shift_t = SRType_LSL;
6549 // if Rn == '1111' then SEE LDR (literal);
6550 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6551 t = Bits32(opcode, 15, 12);
6552 n = Bits32(opcode, 19, 16);
6553 m = Bits32(opcode, 3, 0);
6555 // index = TRUE; add = TRUE; wback = FALSE;
6560 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6561 shift_t = SRType_LSL;
6562 shift_n = Bits32(opcode, 5, 4);
6564 // if BadReg(m) then UNPREDICTABLE;
6568 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6569 if ((t == 15) && InITBlock() && !LastInITBlock())
6575 // if P == '0' && W == '1' then SEE LDRT;
6576 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6577 t = Bits32(opcode, 15, 12);
6578 n = Bits32(opcode, 19, 16);
6579 m = Bits32(opcode, 3, 0);
6581 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
6583 index = BitIsSet(opcode, 24);
6584 add = BitIsSet(opcode, 23);
6585 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6587 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6588 uint32_t type = Bits32(opcode, 6, 5);
6589 uint32_t imm5 = Bits32(opcode, 11, 7);
6590 shift_n = DecodeImmShift(type, imm5, shift_t);
6592 // if m == 15 then UNPREDICTABLE;
6596 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6597 if (wback && ((n == 15) || (n == t)))
6606 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6611 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6618 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is
6619 // an application level alias for the CPSR".
6621 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6625 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6627 offset_addr = Rn + offset;
6629 offset_addr = Rn - offset;
6631 // address = if index then offset_addr else R[n];
6633 address = offset_addr;
6637 // data = MemU[address,4];
6638 RegisterInfo base_reg;
6639 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6641 EmulateInstruction::Context context;
6642 context.type = eContextRegisterLoad;
6643 context.SetRegisterPlusOffset(base_reg, address - Rn);
6645 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6649 // if wback then R[n] = offset_addr;
6651 context.type = eContextAdjustBaseRegister;
6652 context.SetAddress(offset_addr);
6653 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6660 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6661 if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6662 context.type = eContextRegisterLoad;
6663 context.SetRegisterPlusOffset(base_reg, address - Rn);
6664 LoadWritePC(context, data);
6668 // elsif UnalignedSupport() || address<1:0> = '00' then
6669 else if (UnalignedSupport() ||
6670 (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6672 context.type = eContextRegisterLoad;
6673 context.SetRegisterPlusOffset(base_reg, address - Rn);
6674 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6677 } else // Can only apply before ARMv7
6679 // if CurrentInstrSet() == InstrSet_ARM then
6680 if (CurrentInstrSet() == eModeARM) {
6681 // R[t] = ROR(data, 8*UInt(address<1:0>));
6682 data = ROR(data, Bits32(address, 1, 0), &success);
6685 context.type = eContextRegisterLoad;
6686 context.SetImmediate(data);
6687 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6691 // R[t] = bits(32) UNKNOWN;
6692 WriteBits32Unknown(t);
6699 // LDRB (immediate, Thumb)
6700 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6701 const ARMEncoding encoding) {
6703 if ConditionPassed() then
6704 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6705 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6706 address = if index then offset_addr else R[n];
6707 R[t] = ZeroExtend(MemU[address,1], 32);
6708 if wback then R[n] = offset_addr;
6711 bool success = false;
6713 if (ConditionPassed(opcode)) {
6721 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6724 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6725 t = Bits32(opcode, 2, 0);
6726 n = Bits32(opcode, 5, 3);
6727 imm32 = Bits32(opcode, 10, 6);
6729 // index = TRUE; add = TRUE; wback = FALSE;
6737 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6738 t = Bits32(opcode, 15, 12);
6739 n = Bits32(opcode, 19, 16);
6740 imm32 = Bits32(opcode, 11, 0);
6742 // index = TRUE; add = TRUE; wback = FALSE;
6747 // if Rt == '1111' then SEE PLD;
6749 return false; // PLD is not implemented yet
6751 // if Rn == '1111' then SEE LDRB (literal);
6753 return EmulateLDRBLiteral(opcode, eEncodingT1);
6755 // if t == 13 then UNPREDICTABLE;
6762 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6763 // if P == '0' && W == '0' then UNDEFINED;
6764 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6767 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6768 t = Bits32(opcode, 15, 12);
6769 n = Bits32(opcode, 19, 16);
6770 imm32 = Bits32(opcode, 7, 0);
6772 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6773 index = BitIsSet(opcode, 10);
6774 add = BitIsSet(opcode, 9);
6775 wback = BitIsSet(opcode, 8);
6777 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6779 return false; // PLD is not implemented yet
6781 // if Rn == '1111' then SEE LDRB (literal);
6783 return EmulateLDRBLiteral(opcode, eEncodingT1);
6785 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6786 if (BadReg(t) || (wback && (n == t)))
6796 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6803 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6805 offset_addr = Rn + imm32;
6807 offset_addr = Rn - imm32;
6809 // address = if index then offset_addr else R[n];
6811 address = offset_addr;
6815 // R[t] = ZeroExtend(MemU[address,1], 32);
6816 RegisterInfo base_reg;
6817 RegisterInfo data_reg;
6818 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6819 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6821 EmulateInstruction::Context context;
6822 context.type = eContextRegisterLoad;
6823 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
6825 uint64_t data = MemURead(context, address, 1, 0, &success);
6829 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6832 // if wback then R[n] = offset_addr;
6834 context.type = eContextAdjustBaseRegister;
6835 context.SetAddress(offset_addr);
6836 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6844 // LDRB (literal) calculates an address from the PC value and an immediate
6845 // offset, loads a byte from memory,
6846 // zero-extends it to form a 32-bit word and writes it to a register.
6847 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6848 const ARMEncoding encoding) {
6850 if ConditionPassed() then
6851 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6853 address = if add then (base + imm32) else (base - imm32);
6854 R[t] = ZeroExtend(MemU[address,1], 32);
6857 bool success = false;
6859 if (ConditionPassed(opcode)) {
6865 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6866 t = Bits32(opcode, 15, 12);
6867 imm32 = Bits32(opcode, 11, 0);
6868 add = BitIsSet(opcode, 23);
6870 // if Rt == '1111' then SEE PLD;
6872 return false; // PLD is not implemented yet
6874 // if t == 13 then UNPREDICTABLE;
6881 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6882 t = Bits32(opcode, 15, 12);
6883 imm32 = Bits32(opcode, 11, 0);
6884 add = BitIsSet(opcode, 23);
6886 // if t == 15 then UNPREDICTABLE;
6895 // base = Align(PC,4);
6896 uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6900 uint32_t base = AlignPC(pc_val);
6903 // address = if add then (base + imm32) else (base - imm32);
6905 address = base + imm32;
6907 address = base - imm32;
6909 // R[t] = ZeroExtend(MemU[address,1], 32);
6910 EmulateInstruction::Context context;
6911 context.type = eContextRelativeBranchImmediate;
6912 context.SetImmediate(address - base);
6914 uint64_t data = MemURead(context, address, 1, 0, &success);
6918 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6924 // LDRB (register) calculates an address from a base register value and an
6925 // offset rigister value, loads a byte from memory, zero-extends it to form a
6926 // 32-bit word, and writes it to a register. The offset register value can
6927 // optionally be shifted.
6928 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6929 const ARMEncoding encoding) {
6931 if ConditionPassed() then
6932 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6933 offset = Shift(R[m], shift_t, shift_n, APSR.C);
6934 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6935 address = if index then offset_addr else R[n];
6936 R[t] = ZeroExtend(MemU[address,1],32);
6937 if wback then R[n] = offset_addr;
6940 bool success = false;
6942 if (ConditionPassed(opcode)) {
6949 ARM_ShifterType shift_t;
6952 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6955 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6956 t = Bits32(opcode, 2, 0);
6957 n = Bits32(opcode, 5, 3);
6958 m = Bits32(opcode, 8, 6);
6960 // index = TRUE; add = TRUE; wback = FALSE;
6965 // (shift_t, shift_n) = (SRType_LSL, 0);
6966 shift_t = SRType_LSL;
6971 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6972 t = Bits32(opcode, 15, 12);
6973 n = Bits32(opcode, 19, 16);
6974 m = Bits32(opcode, 3, 0);
6976 // index = TRUE; add = TRUE; wback = FALSE;
6981 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6982 shift_t = SRType_LSL;
6983 shift_n = Bits32(opcode, 5, 4);
6985 // if Rt == '1111' then SEE PLD;
6987 return false; // PLD is not implemented yet
6989 // if Rn == '1111' then SEE LDRB (literal);
6991 return EmulateLDRBLiteral(opcode, eEncodingT1);
6993 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6994 if ((t == 13) || BadReg(m))
6999 // if P == '0' && W == '1' then SEE LDRBT;
7000 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7001 t = Bits32(opcode, 15, 12);
7002 n = Bits32(opcode, 19, 16);
7003 m = Bits32(opcode, 3, 0);
7005 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7007 index = BitIsSet(opcode, 24);
7008 add = BitIsSet(opcode, 23);
7009 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7011 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
7012 uint32_t type = Bits32(opcode, 6, 5);
7013 uint32_t imm5 = Bits32(opcode, 11, 7);
7014 shift_n = DecodeImmShift(type, imm5, shift_t);
7016 // if t == 15 || m == 15 then UNPREDICTABLE;
7017 if ((t == 15) || (m == 15))
7020 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7021 if (wback && ((n == 15) || (n == t)))
7032 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7034 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7038 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7042 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7044 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7049 offset_addr = Rn + offset;
7051 offset_addr = Rn - offset;
7053 // address = if index then offset_addr else R[n];
7055 address = offset_addr;
7059 // R[t] = ZeroExtend(MemU[address,1],32);
7060 RegisterInfo base_reg;
7061 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7063 EmulateInstruction::Context context;
7064 context.type = eContextRegisterLoad;
7065 context.SetRegisterPlusOffset(base_reg, address - Rn);
7067 uint64_t data = MemURead(context, address, 1, 0, &success);
7071 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
7074 // if wback then R[n] = offset_addr;
7076 context.type = eContextAdjustBaseRegister;
7077 context.SetAddress(offset_addr);
7078 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7086 // LDRH (immediate, Thumb) calculates an address from a base register value and
7087 // an immediate offset, loads a
7088 // halfword from memory, zero-extends it to form a 32-bit word, and writes it
7089 // to a register. It can use offset, post-indexed, or pre-indexed addressing.
7090 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
7091 const ARMEncoding encoding) {
7093 if ConditionPassed() then
7094 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7095 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7096 address = if index then offset_addr else R[n];
7097 data = MemU[address,2];
7098 if wback then R[n] = offset_addr;
7099 if UnalignedSupport() || address<0> = '0' then
7100 R[t] = ZeroExtend(data, 32);
7101 else // Can only apply before ARMv7
7102 R[t] = bits(32) UNKNOWN;
7105 bool success = false;
7107 if (ConditionPassed(opcode)) {
7115 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7118 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
7119 t = Bits32(opcode, 2, 0);
7120 n = Bits32(opcode, 5, 3);
7121 imm32 = Bits32(opcode, 10, 6) << 1;
7123 // index = TRUE; add = TRUE; wback = FALSE;
7131 // if Rt == '1111' then SEE "Unallocated memory hints";
7132 // if Rn == '1111' then SEE LDRH (literal);
7133 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7134 t = Bits32(opcode, 15, 12);
7135 n = Bits32(opcode, 19, 16);
7136 imm32 = Bits32(opcode, 11, 0);
7138 // index = TRUE; add = TRUE; wback = FALSE;
7143 // if t == 13 then UNPREDICTABLE;
7149 // if Rn == '1111' then SEE LDRH (literal);
7150 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7151 // "Unallocated memory hints";
7152 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
7153 // if P == '0' && W == '0' then UNDEFINED;
7154 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7157 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7158 t = Bits32(opcode, 15, 12);
7159 n = Bits32(opcode, 19, 16);
7160 imm32 = Bits32(opcode, 7, 0);
7162 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7163 index = BitIsSet(opcode, 10);
7164 add = BitIsSet(opcode, 9);
7165 wback = BitIsSet(opcode, 8);
7167 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7168 if (BadReg(t) || (wback && (n == t)))
7176 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7178 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7186 offset_addr = Rn + imm32;
7188 offset_addr = Rn - imm32;
7190 // address = if index then offset_addr else R[n];
7192 address = offset_addr;
7196 // data = MemU[address,2];
7197 RegisterInfo base_reg;
7198 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7200 EmulateInstruction::Context context;
7201 context.type = eContextRegisterLoad;
7202 context.SetRegisterPlusOffset(base_reg, address - Rn);
7204 uint64_t data = MemURead(context, address, 2, 0, &success);
7208 // if wback then R[n] = offset_addr;
7210 context.type = eContextAdjustBaseRegister;
7211 context.SetAddress(offset_addr);
7212 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7217 // if UnalignedSupport() || address<0> = '0' then
7218 if (UnalignedSupport() || BitIsClear(address, 0)) {
7219 // R[t] = ZeroExtend(data, 32);
7220 context.type = eContextRegisterLoad;
7221 context.SetRegisterPlusOffset(base_reg, address - Rn);
7222 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7225 } else // Can only apply before ARMv7
7227 // R[t] = bits(32) UNKNOWN;
7228 WriteBits32Unknown(t);
7234 // LDRH (literal) caculates an address from the PC value and an immediate
7235 // offset, loads a halfword from memory,
7236 // zero-extends it to form a 32-bit word, and writes it to a register.
7237 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
7238 const ARMEncoding encoding) {
7240 if ConditionPassed() then
7241 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7243 address = if add then (base + imm32) else (base - imm32);
7244 data = MemU[address,2];
7245 if UnalignedSupport() || address<0> = '0' then
7246 R[t] = ZeroExtend(data, 32);
7247 else // Can only apply before ARMv7
7248 R[t] = bits(32) UNKNOWN;
7251 bool success = false;
7253 if (ConditionPassed(opcode)) {
7258 // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7261 // if Rt == '1111' then SEE "Unallocated memory hints";
7262 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7263 t = Bits32(opcode, 15, 12);
7264 imm32 = Bits32(opcode, 11, 0);
7265 add = BitIsSet(opcode, 23);
7267 // if t == 13 then UNPREDICTABLE;
7274 uint32_t imm4H = Bits32(opcode, 11, 8);
7275 uint32_t imm4L = Bits32(opcode, 3, 0);
7277 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7278 t = Bits32(opcode, 15, 12);
7279 imm32 = (imm4H << 4) | imm4L;
7280 add = BitIsSet(opcode, 23);
7282 // if t == 15 then UNPREDICTABLE;
7292 // base = Align(PC,4);
7293 uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7297 addr_t base = AlignPC(pc_value);
7300 // address = if add then (base + imm32) else (base - imm32);
7302 address = base + imm32;
7304 address = base - imm32;
7306 // data = MemU[address,2];
7307 RegisterInfo base_reg;
7308 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7310 EmulateInstruction::Context context;
7311 context.type = eContextRegisterLoad;
7312 context.SetRegisterPlusOffset(base_reg, address - base);
7314 uint64_t data = MemURead(context, address, 2, 0, &success);
7318 // if UnalignedSupport() || address<0> = '0' then
7319 if (UnalignedSupport() || BitIsClear(address, 0)) {
7320 // R[t] = ZeroExtend(data, 32);
7321 context.type = eContextRegisterLoad;
7322 context.SetRegisterPlusOffset(base_reg, address - base);
7323 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7327 } else // Can only apply before ARMv7
7329 // R[t] = bits(32) UNKNOWN;
7330 WriteBits32Unknown(t);
7336 // LDRH (literal) calculates an address from a base register value and an offset
7337 // register value, loads a halfword
7338 // from memory, zero-extends it to form a 32-bit word, and writes it to a
7339 // register. The offset register value can be shifted left by 0, 1, 2, or 3
7341 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
7342 const ARMEncoding encoding) {
7344 if ConditionPassed() then
7345 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7346 offset = Shift(R[m], shift_t, shift_n, APSR.C);
7347 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7348 address = if index then offset_addr else R[n];
7349 data = MemU[address,2];
7350 if wback then R[n] = offset_addr;
7351 if UnalignedSupport() || address<0> = '0' then
7352 R[t] = ZeroExtend(data, 32);
7353 else // Can only apply before ARMv7
7354 R[t] = bits(32) UNKNOWN;
7357 bool success = false;
7359 if (ConditionPassed(opcode)) {
7366 ARM_ShifterType shift_t;
7369 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7372 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7374 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7375 t = Bits32(opcode, 2, 0);
7376 n = Bits32(opcode, 5, 3);
7377 m = Bits32(opcode, 8, 6);
7379 // index = TRUE; add = TRUE; wback = FALSE;
7384 // (shift_t, shift_n) = (SRType_LSL, 0);
7385 shift_t = SRType_LSL;
7391 // if Rn == '1111' then SEE LDRH (literal);
7392 // if Rt == '1111' then SEE "Unallocated memory hints";
7393 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7394 t = Bits32(opcode, 15, 12);
7395 n = Bits32(opcode, 19, 16);
7396 m = Bits32(opcode, 3, 0);
7398 // index = TRUE; add = TRUE; wback = FALSE;
7403 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7404 shift_t = SRType_LSL;
7405 shift_n = Bits32(opcode, 5, 4);
7407 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7408 if ((t == 13) || BadReg(m))
7413 // if P == '0' && W == '1' then SEE LDRHT;
7414 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7415 t = Bits32(opcode, 15, 12);
7416 n = Bits32(opcode, 19, 16);
7417 m = Bits32(opcode, 3, 0);
7419 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7421 index = BitIsSet(opcode, 24);
7422 add = BitIsSet(opcode, 23);
7423 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7425 // (shift_t, shift_n) = (SRType_LSL, 0);
7426 shift_t = SRType_LSL;
7429 // if t == 15 || m == 15 then UNPREDICTABLE;
7430 if ((t == 15) || (m == 15))
7433 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7434 if (wback && ((n == 15) || (n == t)))
7443 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7446 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7450 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7457 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7459 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7464 offset_addr = Rn + offset;
7466 offset_addr = Rn - offset;
7468 // address = if index then offset_addr else R[n];
7470 address = offset_addr;
7474 // data = MemU[address,2];
7475 RegisterInfo base_reg;
7476 RegisterInfo offset_reg;
7477 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7478 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7480 EmulateInstruction::Context context;
7481 context.type = eContextRegisterLoad;
7482 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7483 uint64_t data = MemURead(context, address, 2, 0, &success);
7487 // if wback then R[n] = offset_addr;
7489 context.type = eContextAdjustBaseRegister;
7490 context.SetAddress(offset_addr);
7491 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7496 // if UnalignedSupport() || address<0> = '0' then
7497 if (UnalignedSupport() || BitIsClear(address, 0)) {
7498 // R[t] = ZeroExtend(data, 32);
7499 context.type = eContextRegisterLoad;
7500 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7501 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7504 } else // Can only apply before ARMv7
7506 // R[t] = bits(32) UNKNOWN;
7507 WriteBits32Unknown(t);
7513 // LDRSB (immediate) calculates an address from a base register value and an
7514 // immediate offset, loads a byte from
7515 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7516 // It can use offset, post-indexed, or pre-indexed addressing.
7517 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7518 const ARMEncoding encoding) {
7520 if ConditionPassed() then
7521 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7522 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7523 address = if index then offset_addr else R[n];
7524 R[t] = SignExtend(MemU[address,1], 32);
7525 if wback then R[n] = offset_addr;
7528 bool success = false;
7530 if (ConditionPassed(opcode)) {
7538 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7541 // if Rt == '1111' then SEE PLI;
7542 // if Rn == '1111' then SEE LDRSB (literal);
7543 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7544 t = Bits32(opcode, 15, 12);
7545 n = Bits32(opcode, 19, 16);
7546 imm32 = Bits32(opcode, 11, 0);
7548 // index = TRUE; add = TRUE; wback = FALSE;
7553 // if t == 13 then UNPREDICTABLE;
7560 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7561 // if Rn == '1111' then SEE LDRSB (literal);
7562 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7563 // if P == '0' && W == '0' then UNDEFINED;
7564 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7567 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7568 t = Bits32(opcode, 15, 12);
7569 n = Bits32(opcode, 19, 16);
7570 imm32 = Bits32(opcode, 7, 0);
7572 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7573 index = BitIsSet(opcode, 10);
7574 add = BitIsSet(opcode, 9);
7575 wback = BitIsSet(opcode, 8);
7577 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7579 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7580 BitIsSet(opcode, 8)))) ||
7581 (wback && (n == t)))
7587 // if Rn == '1111' then SEE LDRSB (literal);
7588 // if P == '0' && W == '1' then SEE LDRSBT;
7589 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7590 t = Bits32(opcode, 15, 12);
7591 n = Bits32(opcode, 19, 16);
7593 uint32_t imm4H = Bits32(opcode, 11, 8);
7594 uint32_t imm4L = Bits32(opcode, 3, 0);
7595 imm32 = (imm4H << 4) | imm4L;
7597 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7599 index = BitIsSet(opcode, 24);
7600 add = BitIsSet(opcode, 23);
7601 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7603 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7604 if ((t == 15) || (wback && (n == t)))
7614 uint64_t Rn = ReadCoreReg(n, &success);
7621 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7623 offset_addr = Rn + imm32;
7625 offset_addr = Rn - imm32;
7627 // address = if index then offset_addr else R[n];
7629 address = offset_addr;
7633 // R[t] = SignExtend(MemU[address,1], 32);
7634 RegisterInfo base_reg;
7635 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7637 EmulateInstruction::Context context;
7638 context.type = eContextRegisterLoad;
7639 context.SetRegisterPlusOffset(base_reg, address - Rn);
7641 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7645 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7646 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7647 (uint64_t)signed_data))
7650 // if wback then R[n] = offset_addr;
7652 context.type = eContextAdjustBaseRegister;
7653 context.SetAddress(offset_addr);
7654 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7663 // LDRSB (literal) calculates an address from the PC value and an immediate
7664 // offset, loads a byte from memory,
7665 // sign-extends it to form a 32-bit word, and writes tit to a register.
7666 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7667 const ARMEncoding encoding) {
7669 if ConditionPassed() then
7670 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7672 address = if add then (base + imm32) else (base - imm32);
7673 R[t] = SignExtend(MemU[address,1], 32);
7676 bool success = false;
7678 if (ConditionPassed(opcode)) {
7683 // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7686 // if Rt == '1111' then SEE PLI;
7687 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7688 t = Bits32(opcode, 15, 12);
7689 imm32 = Bits32(opcode, 11, 0);
7690 add = BitIsSet(opcode, 23);
7692 // if t == 13 then UNPREDICTABLE;
7699 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7700 t = Bits32(opcode, 15, 12);
7701 uint32_t imm4H = Bits32(opcode, 11, 8);
7702 uint32_t imm4L = Bits32(opcode, 3, 0);
7703 imm32 = (imm4H << 4) | imm4L;
7704 add = BitIsSet(opcode, 23);
7706 // if t == 15 then UNPREDICTABLE;
7717 // base = Align(PC,4);
7718 uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7721 uint64_t base = AlignPC(pc_value);
7723 // address = if add then (base + imm32) else (base - imm32);
7726 address = base + imm32;
7728 address = base - imm32;
7730 // R[t] = SignExtend(MemU[address,1], 32);
7731 RegisterInfo base_reg;
7732 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7734 EmulateInstruction::Context context;
7735 context.type = eContextRegisterLoad;
7736 context.SetRegisterPlusOffset(base_reg, address - base);
7738 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7742 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7743 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7744 (uint64_t)signed_data))
7750 // LDRSB (register) calculates an address from a base register value and an
7751 // offset register value, loadsa byte from
7752 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7753 // The offset register value can be shifted left by 0, 1, 2, or 3 bits.
7754 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7755 const ARMEncoding encoding) {
7757 if ConditionPassed() then
7758 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7759 offset = Shift(R[m], shift_t, shift_n, APSR.C);
7760 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7761 address = if index then offset_addr else R[n];
7762 R[t] = SignExtend(MemU[address,1], 32);
7763 if wback then R[n] = offset_addr;
7766 bool success = false;
7768 if (ConditionPassed(opcode)) {
7775 ARM_ShifterType shift_t;
7778 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7781 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7782 t = Bits32(opcode, 2, 0);
7783 n = Bits32(opcode, 5, 3);
7784 m = Bits32(opcode, 8, 6);
7786 // index = TRUE; add = TRUE; wback = FALSE;
7791 // (shift_t, shift_n) = (SRType_LSL, 0);
7792 shift_t = SRType_LSL;
7798 // if Rt == '1111' then SEE PLI;
7799 // if Rn == '1111' then SEE LDRSB (literal);
7800 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7801 t = Bits32(opcode, 15, 12);
7802 n = Bits32(opcode, 19, 16);
7803 m = Bits32(opcode, 3, 0);
7805 // index = TRUE; add = TRUE; wback = FALSE;
7810 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7811 shift_t = SRType_LSL;
7812 shift_n = Bits32(opcode, 5, 4);
7814 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7815 if ((t == 13) || BadReg(m))
7820 // if P == '0' && W == '1' then SEE LDRSBT;
7821 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7822 t = Bits32(opcode, 15, 12);
7823 n = Bits32(opcode, 19, 16);
7824 m = Bits32(opcode, 3, 0);
7826 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7828 index = BitIsSet(opcode, 24);
7829 add = BitIsSet(opcode, 23);
7830 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7832 // (shift_t, shift_n) = (SRType_LSL, 0);
7833 shift_t = SRType_LSL;
7836 // if t == 15 || m == 15 then UNPREDICTABLE;
7837 if ((t == 15) || (m == 15))
7840 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7841 if (wback && ((n == 15) || (n == t)))
7850 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7854 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7855 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7862 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7864 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7869 offset_addr = Rn + offset;
7871 offset_addr = Rn - offset;
7873 // address = if index then offset_addr else R[n];
7875 address = offset_addr;
7879 // R[t] = SignExtend(MemU[address,1], 32);
7880 RegisterInfo base_reg;
7881 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7882 RegisterInfo offset_reg;
7883 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7885 EmulateInstruction::Context context;
7886 context.type = eContextRegisterLoad;
7887 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7889 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7893 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7894 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7895 (uint64_t)signed_data))
7898 // if wback then R[n] = offset_addr;
7900 context.type = eContextAdjustBaseRegister;
7901 context.SetAddress(offset_addr);
7902 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7910 // LDRSH (immediate) calculates an address from a base register value and an
7911 // immediate offset, loads a halfword from
7912 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7913 // It can use offset, post-indexed, or pre-indexed addressing.
7914 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7915 const ARMEncoding encoding) {
7917 if ConditionPassed() then
7918 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7919 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7920 address = if index then offset_addr else R[n];
7921 data = MemU[address,2];
7922 if wback then R[n] = offset_addr;
7923 if UnalignedSupport() || address<0> = '0' then
7924 R[t] = SignExtend(data, 32);
7925 else // Can only apply before ARMv7
7926 R[t] = bits(32) UNKNOWN;
7929 bool success = false;
7931 if (ConditionPassed(opcode)) {
7939 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7942 // if Rn == '1111' then SEE LDRSH (literal);
7943 // if Rt == '1111' then SEE "Unallocated memory hints";
7944 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7945 t = Bits32(opcode, 15, 12);
7946 n = Bits32(opcode, 19, 16);
7947 imm32 = Bits32(opcode, 11, 0);
7949 // index = TRUE; add = TRUE; wback = FALSE;
7954 // if t == 13 then UNPREDICTABLE;
7961 // if Rn == '1111' then SEE LDRSH (literal);
7962 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7963 // "Unallocated memory hints";
7964 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7965 // if P == '0' && W == '0' then UNDEFINED;
7966 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7969 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7970 t = Bits32(opcode, 15, 12);
7971 n = Bits32(opcode, 19, 16);
7972 imm32 = Bits32(opcode, 7, 0);
7974 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7975 index = BitIsSet(opcode, 10);
7976 add = BitIsSet(opcode, 9);
7977 wback = BitIsSet(opcode, 8);
7979 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7980 if (BadReg(t) || (wback && (n == t)))
7986 // if Rn == '1111' then SEE LDRSH (literal);
7987 // if P == '0' && W == '1' then SEE LDRSHT;
7988 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7989 t = Bits32(opcode, 15, 12);
7990 n = Bits32(opcode, 19, 16);
7991 uint32_t imm4H = Bits32(opcode, 11, 8);
7992 uint32_t imm4L = Bits32(opcode, 3, 0);
7993 imm32 = (imm4H << 4) | imm4L;
7995 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7997 index = BitIsSet(opcode, 24);
7998 add = BitIsSet(opcode, 23);
7999 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8001 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
8002 if ((t == 15) || (wback && (n == t)))
8012 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
8014 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8020 offset_addr = Rn + imm32;
8022 offset_addr = Rn - imm32;
8024 // address = if index then offset_addr else R[n];
8027 address = offset_addr;
8031 // data = MemU[address,2];
8032 RegisterInfo base_reg;
8033 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8035 EmulateInstruction::Context context;
8036 context.type = eContextRegisterLoad;
8037 context.SetRegisterPlusOffset(base_reg, address - Rn);
8039 uint64_t data = MemURead(context, address, 2, 0, &success);
8043 // if wback then R[n] = offset_addr;
8045 context.type = eContextAdjustBaseRegister;
8046 context.SetAddress(offset_addr);
8047 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8052 // if UnalignedSupport() || address<0> = '0' then
8053 if (UnalignedSupport() || BitIsClear(address, 0)) {
8054 // R[t] = SignExtend(data, 32);
8055 int64_t signed_data = llvm::SignExtend64<16>(data);
8056 context.type = eContextRegisterLoad;
8057 context.SetRegisterPlusOffset(base_reg, address - Rn);
8058 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8059 (uint64_t)signed_data))
8061 } else // Can only apply before ARMv7
8063 // R[t] = bits(32) UNKNOWN;
8064 WriteBits32Unknown(t);
8070 // LDRSH (literal) calculates an address from the PC value and an immediate
8071 // offset, loads a halfword from memory,
8072 // sign-extends it to from a 32-bit word, and writes it to a register.
8073 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
8074 const ARMEncoding encoding) {
8076 if ConditionPassed() then
8077 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8079 address = if add then (base + imm32) else (base - imm32);
8080 data = MemU[address,2];
8081 if UnalignedSupport() || address<0> = '0' then
8082 R[t] = SignExtend(data, 32);
8083 else // Can only apply before ARMv7
8084 R[t] = bits(32) UNKNOWN;
8087 bool success = false;
8089 if (ConditionPassed(opcode)) {
8094 // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8097 // if Rt == '1111' then SEE "Unallocated memory hints";
8098 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
8099 t = Bits32(opcode, 15, 12);
8100 imm32 = Bits32(opcode, 11, 0);
8101 add = BitIsSet(opcode, 23);
8103 // if t == 13 then UNPREDICTABLE;
8110 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
8111 t = Bits32(opcode, 15, 12);
8112 uint32_t imm4H = Bits32(opcode, 11, 8);
8113 uint32_t imm4L = Bits32(opcode, 3, 0);
8114 imm32 = (imm4H << 4) | imm4L;
8115 add = BitIsSet(opcode, 23);
8117 // if t == 15 then UNPREDICTABLE;
8127 // base = Align(PC,4);
8128 uint64_t pc_value = ReadCoreReg(PC_REG, &success);
8132 uint64_t base = AlignPC(pc_value);
8135 // address = if add then (base + imm32) else (base - imm32);
8137 address = base + imm32;
8139 address = base - imm32;
8141 // data = MemU[address,2];
8142 RegisterInfo base_reg;
8143 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
8145 EmulateInstruction::Context context;
8146 context.type = eContextRegisterLoad;
8147 context.SetRegisterPlusOffset(base_reg, imm32);
8149 uint64_t data = MemURead(context, address, 2, 0, &success);
8153 // if UnalignedSupport() || address<0> = '0' then
8154 if (UnalignedSupport() || BitIsClear(address, 0)) {
8155 // R[t] = SignExtend(data, 32);
8156 int64_t signed_data = llvm::SignExtend64<16>(data);
8157 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8158 (uint64_t)signed_data))
8160 } else // Can only apply before ARMv7
8162 // R[t] = bits(32) UNKNOWN;
8163 WriteBits32Unknown(t);
8169 // LDRSH (register) calculates an address from a base register value and an
8170 // offset register value, loads a halfword
8171 // from memory, sign-extends it to form a 32-bit word, and writes it to a
8172 // register. The offset register value can be shifted left by 0, 1, 2, or 3
8174 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
8175 const ARMEncoding encoding) {
8177 if ConditionPassed() then
8178 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8179 offset = Shift(R[m], shift_t, shift_n, APSR.C);
8180 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8181 address = if index then offset_addr else R[n];
8182 data = MemU[address,2];
8183 if wback then R[n] = offset_addr;
8184 if UnalignedSupport() || address<0> = '0' then
8185 R[t] = SignExtend(data, 32);
8186 else // Can only apply before ARMv7
8187 R[t] = bits(32) UNKNOWN;
8190 bool success = false;
8192 if (ConditionPassed(opcode)) {
8199 ARM_ShifterType shift_t;
8202 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8205 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
8207 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8208 t = Bits32(opcode, 2, 0);
8209 n = Bits32(opcode, 5, 3);
8210 m = Bits32(opcode, 8, 6);
8212 // index = TRUE; add = TRUE; wback = FALSE;
8217 // (shift_t, shift_n) = (SRType_LSL, 0);
8218 shift_t = SRType_LSL;
8224 // if Rn == '1111' then SEE LDRSH (literal);
8225 // if Rt == '1111' then SEE "Unallocated memory hints";
8226 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8227 t = Bits32(opcode, 15, 12);
8228 n = Bits32(opcode, 19, 16);
8229 m = Bits32(opcode, 3, 0);
8231 // index = TRUE; add = TRUE; wback = FALSE;
8236 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
8237 shift_t = SRType_LSL;
8238 shift_n = Bits32(opcode, 5, 4);
8240 // if t == 13 || BadReg(m) then UNPREDICTABLE;
8241 if ((t == 13) || BadReg(m))
8247 // if P == '0' && W == '1' then SEE LDRSHT;
8248 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8249 t = Bits32(opcode, 15, 12);
8250 n = Bits32(opcode, 19, 16);
8251 m = Bits32(opcode, 3, 0);
8253 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
8255 index = BitIsSet(opcode, 24);
8256 add = BitIsSet(opcode, 23);
8257 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8259 // (shift_t, shift_n) = (SRType_LSL, 0);
8260 shift_t = SRType_LSL;
8263 // if t == 15 || m == 15 then UNPREDICTABLE;
8264 if ((t == 15) || (m == 15))
8267 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
8268 if (wback && ((n == 15) || (n == t)))
8278 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8283 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8287 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
8288 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
8295 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8297 offset_addr = Rn + offset;
8299 offset_addr = Rn - offset;
8301 // address = if index then offset_addr else R[n];
8303 address = offset_addr;
8307 // data = MemU[address,2];
8308 RegisterInfo base_reg;
8309 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8311 RegisterInfo offset_reg;
8312 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
8314 EmulateInstruction::Context context;
8315 context.type = eContextRegisterLoad;
8316 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8318 uint64_t data = MemURead(context, address, 2, 0, &success);
8322 // if wback then R[n] = offset_addr;
8324 context.type = eContextAdjustBaseRegister;
8325 context.SetAddress(offset_addr);
8326 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8331 // if UnalignedSupport() || address<0> = '0' then
8332 if (UnalignedSupport() || BitIsClear(address, 0)) {
8333 // R[t] = SignExtend(data, 32);
8334 context.type = eContextRegisterLoad;
8335 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8337 int64_t signed_data = llvm::SignExtend64<16>(data);
8338 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8339 (uint64_t)signed_data))
8341 } else // Can only apply before ARMv7
8343 // R[t] = bits(32) UNKNOWN;
8344 WriteBits32Unknown(t);
8350 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
8351 // writes the result to the destination
8352 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before
8353 // extracting the 8-bit value.
8354 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
8355 const ARMEncoding encoding) {
8357 if ConditionPassed() then
8358 EncodingSpecificOperations();
8359 rotated = ROR(R[m], rotation);
8360 R[d] = SignExtend(rotated<7:0>, 32);
8363 bool success = false;
8365 if (ConditionPassed(opcode)) {
8370 // EncodingSpecificOperations();
8373 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8374 d = Bits32(opcode, 2, 0);
8375 m = Bits32(opcode, 5, 3);
8381 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8382 d = Bits32(opcode, 11, 8);
8383 m = Bits32(opcode, 3, 0);
8384 rotation = Bits32(opcode, 5, 4) << 3;
8386 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8387 if (BadReg(d) || BadReg(m))
8393 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8394 d = Bits32(opcode, 15, 12);
8395 m = Bits32(opcode, 3, 0);
8396 rotation = Bits32(opcode, 11, 10) << 3;
8398 // if d == 15 || m == 15 then UNPREDICTABLE;
8399 if ((d == 15) || (m == 15))
8409 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8413 // rotated = ROR(R[m], rotation);
8414 uint64_t rotated = ROR(Rm, rotation, &success);
8418 // R[d] = SignExtend(rotated<7:0>, 32);
8419 int64_t data = llvm::SignExtend64<8>(rotated);
8421 RegisterInfo source_reg;
8422 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8424 EmulateInstruction::Context context;
8425 context.type = eContextRegisterLoad;
8426 context.SetRegister(source_reg);
8428 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8435 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
8436 // writes the result to the destination
8437 // register. You can specify a rotation by 0, 8, 16, or 24 bits before
8438 // extracting the 16-bit value.
8439 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
8440 const ARMEncoding encoding) {
8442 if ConditionPassed() then
8443 EncodingSpecificOperations();
8444 rotated = ROR(R[m], rotation);
8445 R[d] = SignExtend(rotated<15:0>, 32);
8448 bool success = false;
8450 if (ConditionPassed(opcode)) {
8455 // EncodingSpecificOperations();
8458 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8459 d = Bits32(opcode, 2, 0);
8460 m = Bits32(opcode, 5, 3);
8466 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8467 d = Bits32(opcode, 11, 8);
8468 m = Bits32(opcode, 3, 0);
8469 rotation = Bits32(opcode, 5, 4) << 3;
8471 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8472 if (BadReg(d) || BadReg(m))
8478 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8479 d = Bits32(opcode, 15, 12);
8480 m = Bits32(opcode, 3, 0);
8481 rotation = Bits32(opcode, 11, 10) << 3;
8483 // if d == 15 || m == 15 then UNPREDICTABLE;
8484 if ((d == 15) || (m == 15))
8494 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8498 // rotated = ROR(R[m], rotation);
8499 uint64_t rotated = ROR(Rm, rotation, &success);
8503 // R[d] = SignExtend(rotated<15:0>, 32);
8504 RegisterInfo source_reg;
8505 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8507 EmulateInstruction::Context context;
8508 context.type = eContextRegisterLoad;
8509 context.SetRegister(source_reg);
8511 int64_t data = llvm::SignExtend64<16>(rotated);
8512 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8520 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and
8521 // writes the result to the destination
8522 // register. You can specify a rotation by 0, 8, 16, or 24 bits before
8523 // extracting the 8-bit value.
8524 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8525 const ARMEncoding encoding) {
8527 if ConditionPassed() then
8528 EncodingSpecificOperations();
8529 rotated = ROR(R[m], rotation);
8530 R[d] = ZeroExtend(rotated<7:0>, 32);
8533 bool success = false;
8535 if (ConditionPassed(opcode)) {
8540 // EncodingSpecificOperations();
8543 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8544 d = Bits32(opcode, 2, 0);
8545 m = Bits32(opcode, 5, 3);
8551 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8552 d = Bits32(opcode, 11, 8);
8553 m = Bits32(opcode, 3, 0);
8554 rotation = Bits32(opcode, 5, 4) << 3;
8556 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8557 if (BadReg(d) || BadReg(m))
8563 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8564 d = Bits32(opcode, 15, 12);
8565 m = Bits32(opcode, 3, 0);
8566 rotation = Bits32(opcode, 11, 10) << 3;
8568 // if d == 15 || m == 15 then UNPREDICTABLE;
8569 if ((d == 15) || (m == 15))
8579 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8583 // rotated = ROR(R[m], rotation);
8584 uint64_t rotated = ROR(Rm, rotation, &success);
8588 // R[d] = ZeroExtend(rotated<7:0>, 32);
8589 RegisterInfo source_reg;
8590 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8592 EmulateInstruction::Context context;
8593 context.type = eContextRegisterLoad;
8594 context.SetRegister(source_reg);
8596 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8597 Bits32(rotated, 7, 0)))
8603 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8604 // writes the result to the destination
8605 // register. You can specify a rotation by 0, 8, 16, or 24 bits before
8606 // extracting the 16-bit value.
8607 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8608 const ARMEncoding encoding) {
8610 if ConditionPassed() then
8611 EncodingSpecificOperations();
8612 rotated = ROR(R[m], rotation);
8613 R[d] = ZeroExtend(rotated<15:0>, 32);
8616 bool success = false;
8618 if (ConditionPassed(opcode)) {
8625 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8626 d = Bits32(opcode, 2, 0);
8627 m = Bits32(opcode, 5, 3);
8633 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8634 d = Bits32(opcode, 11, 8);
8635 m = Bits32(opcode, 3, 0);
8636 rotation = Bits32(opcode, 5, 4) << 3;
8638 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8639 if (BadReg(d) || BadReg(m))
8645 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8646 d = Bits32(opcode, 15, 12);
8647 m = Bits32(opcode, 3, 0);
8648 rotation = Bits32(opcode, 11, 10) << 3;
8650 // if d == 15 || m == 15 then UNPREDICTABLE;
8651 if ((d == 15) || (m == 15))
8661 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8665 // rotated = ROR(R[m], rotation);
8666 uint64_t rotated = ROR(Rm, rotation, &success);
8670 // R[d] = ZeroExtend(rotated<15:0>, 32);
8671 RegisterInfo source_reg;
8672 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8674 EmulateInstruction::Context context;
8675 context.type = eContextRegisterLoad;
8676 context.SetRegister(source_reg);
8678 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8679 Bits32(rotated, 15, 0)))
8685 // RFE (Return From Exception) loads the PC and the CPSR from the word at the
8686 // specified address and the following
8687 // word respectively.
8688 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8689 const ARMEncoding encoding) {
8691 if ConditionPassed() then
8692 EncodingSpecificOperations();
8693 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8696 address = if increment then R[n] else R[n]-8;
8697 if wordhigher then address = address+4;
8698 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8699 BranchWritePC(MemA[address,4]);
8700 if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8703 bool success = false;
8705 if (ConditionPassed(opcode)) {
8711 // EncodingSpecificOperations();
8714 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8716 n = Bits32(opcode, 19, 16);
8717 wback = BitIsSet(opcode, 21);
8721 // if n == 15 then UNPREDICTABLE;
8725 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8726 if (InITBlock() && !LastInITBlock())
8732 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8733 n = Bits32(opcode, 19, 16);
8734 wback = BitIsSet(opcode, 21);
8738 // if n == 15 then UNPREDICTABLE;
8742 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8743 if (InITBlock() && !LastInITBlock())
8750 n = Bits32(opcode, 19, 16);
8752 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8753 wback = BitIsSet(opcode, 21);
8754 increment = BitIsSet(opcode, 23);
8755 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8757 // if n == 15 then UNPREDICTABLE;
8767 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8769 if (!CurrentModeIsPrivileged())
8774 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8779 // address = if increment then R[n] else R[n]-8;
8785 // if wordhigher then address = address+4;
8787 address = address + 4;
8789 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8790 RegisterInfo base_reg;
8791 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8793 EmulateInstruction::Context context;
8794 context.type = eContextReturnFromException;
8795 context.SetRegisterPlusOffset(base_reg, address - Rn);
8797 uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8801 CPSRWriteByInstr(data, 15, true);
8803 // BranchWritePC(MemA[address,4]);
8804 uint64_t data2 = MemARead(context, address, 4, 0, &success);
8808 BranchWritePC(context, data2);
8810 // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8812 context.type = eContextAdjustBaseRegister;
8814 context.SetOffset(8);
8815 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8819 context.SetOffset(-8);
8820 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8826 } // if ConditionPassed()
8830 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8831 // register value and an immediate value, and writes the result to the
8832 // destination register. It can optionally update the condition flags based on
8834 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8835 const ARMEncoding encoding) {
8837 // ARM pseudo code...
8838 if ConditionPassed() then
8839 EncodingSpecificOperations();
8840 result = R[n] EOR imm32;
8841 if d == 15 then // Can only occur for ARM encoding
8842 ALUWritePC(result); // setflags is always FALSE here
8846 APSR.N = result<31>;
8847 APSR.Z = IsZeroBit(result);
8852 bool success = false;
8854 if (ConditionPassed(opcode)) {
8857 imm32; // the immediate value to be ORed to the value obtained from Rn
8859 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8862 Rd = Bits32(opcode, 11, 8);
8863 Rn = Bits32(opcode, 19, 16);
8864 setflags = BitIsSet(opcode, 20);
8865 imm32 = ThumbExpandImm_C(
8867 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8868 // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8869 if (Rd == 15 && setflags)
8870 return EmulateTEQImm(opcode, eEncodingT1);
8871 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8875 Rd = Bits32(opcode, 15, 12);
8876 Rn = Bits32(opcode, 19, 16);
8877 setflags = BitIsSet(opcode, 20);
8879 ARMExpandImm_C(opcode, APSR_C,
8880 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8882 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8884 if (Rd == 15 && setflags)
8885 return EmulateSUBSPcLrEtc(opcode, encoding);
8891 // Read the first operand.
8892 uint32_t val1 = ReadCoreReg(Rn, &success);
8896 uint32_t result = val1 ^ imm32;
8898 EmulateInstruction::Context context;
8899 context.type = EmulateInstruction::eContextImmediate;
8900 context.SetNoArgs();
8902 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8908 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a
8909 // register value and an optionally-shifted register value, and writes the
8910 // result to the destination register. It can optionally update the condition
8911 // flags based on the result.
8912 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8913 const ARMEncoding encoding) {
8915 // ARM pseudo code...
8916 if ConditionPassed() then
8917 EncodingSpecificOperations();
8918 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8919 result = R[n] EOR shifted;
8920 if d == 15 then // Can only occur for ARM encoding
8921 ALUWritePC(result); // setflags is always FALSE here
8925 APSR.N = result<31>;
8926 APSR.Z = IsZeroBit(result);
8931 bool success = false;
8933 if (ConditionPassed(opcode)) {
8934 uint32_t Rd, Rn, Rm;
8935 ARM_ShifterType shift_t;
8936 uint32_t shift_n; // the shift applied to the value read from Rm
8941 Rd = Rn = Bits32(opcode, 2, 0);
8942 Rm = Bits32(opcode, 5, 3);
8943 setflags = !InITBlock();
8944 shift_t = SRType_LSL;
8948 Rd = Bits32(opcode, 11, 8);
8949 Rn = Bits32(opcode, 19, 16);
8950 Rm = Bits32(opcode, 3, 0);
8951 setflags = BitIsSet(opcode, 20);
8952 shift_n = DecodeImmShiftThumb(opcode, shift_t);
8953 // if Rd == '1111' && S == '1' then SEE TEQ (register);
8954 if (Rd == 15 && setflags)
8955 return EmulateTEQReg(opcode, eEncodingT1);
8956 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8960 Rd = Bits32(opcode, 15, 12);
8961 Rn = Bits32(opcode, 19, 16);
8962 Rm = Bits32(opcode, 3, 0);
8963 setflags = BitIsSet(opcode, 20);
8964 shift_n = DecodeImmShiftARM(opcode, shift_t);
8966 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8968 if (Rd == 15 && setflags)
8969 return EmulateSUBSPcLrEtc(opcode, encoding);
8975 // Read the first operand.
8976 uint32_t val1 = ReadCoreReg(Rn, &success);
8980 // Read the second operand.
8981 uint32_t val2 = ReadCoreReg(Rm, &success);
8985 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8988 uint32_t result = val1 ^ shifted;
8990 EmulateInstruction::Context context;
8991 context.type = EmulateInstruction::eContextImmediate;
8992 context.SetNoArgs();
8994 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9000 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
9001 // and an immediate value, and writes the result to the destination register.
9002 // It can optionally update the condition flags based on the result.
9003 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
9004 const ARMEncoding encoding) {
9006 // ARM pseudo code...
9007 if ConditionPassed() then
9008 EncodingSpecificOperations();
9009 result = R[n] OR imm32;
9010 if d == 15 then // Can only occur for ARM encoding
9011 ALUWritePC(result); // setflags is always FALSE here
9015 APSR.N = result<31>;
9016 APSR.Z = IsZeroBit(result);
9021 bool success = false;
9023 if (ConditionPassed(opcode)) {
9026 imm32; // the immediate value to be ORed to the value obtained from Rn
9028 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9031 Rd = Bits32(opcode, 11, 8);
9032 Rn = Bits32(opcode, 19, 16);
9033 setflags = BitIsSet(opcode, 20);
9034 imm32 = ThumbExpandImm_C(
9036 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9037 // if Rn == '1111' then SEE MOV (immediate);
9039 return EmulateMOVRdImm(opcode, eEncodingT2);
9040 if (BadReg(Rd) || Rn == 13)
9044 Rd = Bits32(opcode, 15, 12);
9045 Rn = Bits32(opcode, 19, 16);
9046 setflags = BitIsSet(opcode, 20);
9048 ARMExpandImm_C(opcode, APSR_C,
9049 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9051 if (Rd == 15 && setflags)
9052 return EmulateSUBSPcLrEtc(opcode, encoding);
9058 // Read the first operand.
9059 uint32_t val1 = ReadCoreReg(Rn, &success);
9063 uint32_t result = val1 | imm32;
9065 EmulateInstruction::Context context;
9066 context.type = EmulateInstruction::eContextImmediate;
9067 context.SetNoArgs();
9069 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9075 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
9076 // and an optionally-shifted register value, and writes the result to the
9077 // destination register. It can optionally update the condition flags based on
9079 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
9080 const ARMEncoding encoding) {
9082 // ARM pseudo code...
9083 if ConditionPassed() then
9084 EncodingSpecificOperations();
9085 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9086 result = R[n] OR shifted;
9087 if d == 15 then // Can only occur for ARM encoding
9088 ALUWritePC(result); // setflags is always FALSE here
9092 APSR.N = result<31>;
9093 APSR.Z = IsZeroBit(result);
9098 bool success = false;
9100 if (ConditionPassed(opcode)) {
9101 uint32_t Rd, Rn, Rm;
9102 ARM_ShifterType shift_t;
9103 uint32_t shift_n; // the shift applied to the value read from Rm
9108 Rd = Rn = Bits32(opcode, 2, 0);
9109 Rm = Bits32(opcode, 5, 3);
9110 setflags = !InITBlock();
9111 shift_t = SRType_LSL;
9115 Rd = Bits32(opcode, 11, 8);
9116 Rn = Bits32(opcode, 19, 16);
9117 Rm = Bits32(opcode, 3, 0);
9118 setflags = BitIsSet(opcode, 20);
9119 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9120 // if Rn == '1111' then SEE MOV (register);
9122 return EmulateMOVRdRm(opcode, eEncodingT3);
9123 if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
9127 Rd = Bits32(opcode, 15, 12);
9128 Rn = Bits32(opcode, 19, 16);
9129 Rm = Bits32(opcode, 3, 0);
9130 setflags = BitIsSet(opcode, 20);
9131 shift_n = DecodeImmShiftARM(opcode, shift_t);
9133 if (Rd == 15 && setflags)
9134 return EmulateSUBSPcLrEtc(opcode, encoding);
9140 // Read the first operand.
9141 uint32_t val1 = ReadCoreReg(Rn, &success);
9145 // Read the second operand.
9146 uint32_t val2 = ReadCoreReg(Rm, &success);
9150 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9153 uint32_t result = val1 | shifted;
9155 EmulateInstruction::Context context;
9156 context.type = EmulateInstruction::eContextImmediate;
9157 context.SetNoArgs();
9159 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9165 // Reverse Subtract (immediate) subtracts a register value from an immediate
9166 // value, and writes the result to the destination register. It can optionally
9167 // update the condition flags based on the result.
9168 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
9169 const ARMEncoding encoding) {
9171 // ARM pseudo code...
9172 if ConditionPassed() then
9173 EncodingSpecificOperations();
9174 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
9175 if d == 15 then // Can only occur for ARM encoding
9176 ALUWritePC(result); // setflags is always FALSE here
9180 APSR.N = result<31>;
9181 APSR.Z = IsZeroBit(result);
9186 bool success = false;
9188 uint32_t Rd; // the destination register
9189 uint32_t Rn; // the first operand
9192 imm32; // the immediate value to be added to the value obtained from Rn
9195 Rd = Bits32(opcode, 2, 0);
9196 Rn = Bits32(opcode, 5, 3);
9197 setflags = !InITBlock();
9201 Rd = Bits32(opcode, 11, 8);
9202 Rn = Bits32(opcode, 19, 16);
9203 setflags = BitIsSet(opcode, 20);
9204 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9205 if (BadReg(Rd) || BadReg(Rn))
9209 Rd = Bits32(opcode, 15, 12);
9210 Rn = Bits32(opcode, 19, 16);
9211 setflags = BitIsSet(opcode, 20);
9212 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9214 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9216 if (Rd == 15 && setflags)
9217 return EmulateSUBSPcLrEtc(opcode, encoding);
9222 // Read the register value from the operand register Rn.
9223 uint32_t reg_val = ReadCoreReg(Rn, &success);
9227 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
9229 EmulateInstruction::Context context;
9230 context.type = EmulateInstruction::eContextImmediate;
9231 context.SetNoArgs();
9233 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9234 res.carry_out, res.overflow);
9237 // Reverse Subtract (register) subtracts a register value from an optionally-
9238 // shifted register value, and writes the result to the destination register.
9239 // It can optionally update the condition flags based on the result.
9240 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
9241 const ARMEncoding encoding) {
9243 // ARM pseudo code...
9244 if ConditionPassed() then
9245 EncodingSpecificOperations();
9246 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9247 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
9248 if d == 15 then // Can only occur for ARM encoding
9249 ALUWritePC(result); // setflags is always FALSE here
9253 APSR.N = result<31>;
9254 APSR.Z = IsZeroBit(result);
9259 bool success = false;
9261 uint32_t Rd; // the destination register
9262 uint32_t Rn; // the first operand
9263 uint32_t Rm; // the second operand
9265 ARM_ShifterType shift_t;
9266 uint32_t shift_n; // the shift applied to the value read from Rm
9269 Rd = Bits32(opcode, 11, 8);
9270 Rn = Bits32(opcode, 19, 16);
9271 Rm = Bits32(opcode, 3, 0);
9272 setflags = BitIsSet(opcode, 20);
9273 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9274 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
9275 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9279 Rd = Bits32(opcode, 15, 12);
9280 Rn = Bits32(opcode, 19, 16);
9281 Rm = Bits32(opcode, 3, 0);
9282 setflags = BitIsSet(opcode, 20);
9283 shift_n = DecodeImmShiftARM(opcode, shift_t);
9285 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9287 if (Rd == 15 && setflags)
9288 return EmulateSUBSPcLrEtc(opcode, encoding);
9293 // Read the register value from register Rn.
9294 uint32_t val1 = ReadCoreReg(Rn, &success);
9298 // Read the register value from register Rm.
9299 uint32_t val2 = ReadCoreReg(Rm, &success);
9303 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9306 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
9308 EmulateInstruction::Context context;
9309 context.type = EmulateInstruction::eContextImmediate;
9310 context.SetNoArgs();
9311 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9312 res.carry_out, res.overflow);
9315 // Reverse Subtract with Carry (immediate) subtracts a register value and the
9316 // value of NOT (Carry flag) from an immediate value, and writes the result to
9317 // the destination register. It can optionally update the condition flags based
9319 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
9320 const ARMEncoding encoding) {
9322 // ARM pseudo code...
9323 if ConditionPassed() then
9324 EncodingSpecificOperations();
9325 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
9327 ALUWritePC(result); // setflags is always FALSE here
9331 APSR.N = result<31>;
9332 APSR.Z = IsZeroBit(result);
9337 bool success = false;
9339 uint32_t Rd; // the destination register
9340 uint32_t Rn; // the first operand
9343 imm32; // the immediate value to be added to the value obtained from Rn
9346 Rd = Bits32(opcode, 15, 12);
9347 Rn = Bits32(opcode, 19, 16);
9348 setflags = BitIsSet(opcode, 20);
9349 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9351 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9353 if (Rd == 15 && setflags)
9354 return EmulateSUBSPcLrEtc(opcode, encoding);
9359 // Read the register value from the operand register Rn.
9360 uint32_t reg_val = ReadCoreReg(Rn, &success);
9364 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
9366 EmulateInstruction::Context context;
9367 context.type = EmulateInstruction::eContextImmediate;
9368 context.SetNoArgs();
9370 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9371 res.carry_out, res.overflow);
9374 // Reverse Subtract with Carry (register) subtracts a register value and the
9375 // value of NOT (Carry flag) from an optionally-shifted register value, and
9376 // writes the result to the destination register. It can optionally update the
9377 // condition flags based on the result.
9378 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
9379 const ARMEncoding encoding) {
9381 // ARM pseudo code...
9382 if ConditionPassed() then
9383 EncodingSpecificOperations();
9384 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9385 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
9387 ALUWritePC(result); // setflags is always FALSE here
9391 APSR.N = result<31>;
9392 APSR.Z = IsZeroBit(result);
9397 bool success = false;
9399 uint32_t Rd; // the destination register
9400 uint32_t Rn; // the first operand
9401 uint32_t Rm; // the second operand
9403 ARM_ShifterType shift_t;
9404 uint32_t shift_n; // the shift applied to the value read from Rm
9407 Rd = Bits32(opcode, 15, 12);
9408 Rn = Bits32(opcode, 19, 16);
9409 Rm = Bits32(opcode, 3, 0);
9410 setflags = BitIsSet(opcode, 20);
9411 shift_n = DecodeImmShiftARM(opcode, shift_t);
9413 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9415 if (Rd == 15 && setflags)
9416 return EmulateSUBSPcLrEtc(opcode, encoding);
9421 // Read the register value from register Rn.
9422 uint32_t val1 = ReadCoreReg(Rn, &success);
9426 // Read the register value from register Rm.
9427 uint32_t val2 = ReadCoreReg(Rm, &success);
9431 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9434 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
9436 EmulateInstruction::Context context;
9437 context.type = EmulateInstruction::eContextImmediate;
9438 context.SetNoArgs();
9439 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9440 res.carry_out, res.overflow);
9443 // Subtract with Carry (immediate) subtracts an immediate value and the value
9445 // NOT (Carry flag) from a register value, and writes the result to the
9446 // destination register.
9447 // It can optionally update the condition flags based on the result.
9448 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
9449 const ARMEncoding encoding) {
9451 // ARM pseudo code...
9452 if ConditionPassed() then
9453 EncodingSpecificOperations();
9454 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9455 if d == 15 then // Can only occur for ARM encoding
9456 ALUWritePC(result); // setflags is always FALSE here
9460 APSR.N = result<31>;
9461 APSR.Z = IsZeroBit(result);
9466 bool success = false;
9468 uint32_t Rd; // the destination register
9469 uint32_t Rn; // the first operand
9472 imm32; // the immediate value to be added to the value obtained from Rn
9475 Rd = Bits32(opcode, 11, 8);
9476 Rn = Bits32(opcode, 19, 16);
9477 setflags = BitIsSet(opcode, 20);
9478 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9479 if (BadReg(Rd) || BadReg(Rn))
9483 Rd = Bits32(opcode, 15, 12);
9484 Rn = Bits32(opcode, 19, 16);
9485 setflags = BitIsSet(opcode, 20);
9486 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9488 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9490 if (Rd == 15 && setflags)
9491 return EmulateSUBSPcLrEtc(opcode, encoding);
9496 // Read the register value from the operand register Rn.
9497 uint32_t reg_val = ReadCoreReg(Rn, &success);
9501 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9503 EmulateInstruction::Context context;
9504 context.type = EmulateInstruction::eContextImmediate;
9505 context.SetNoArgs();
9507 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9508 res.carry_out, res.overflow);
9511 // Subtract with Carry (register) subtracts an optionally-shifted register
9512 // value and the value of
9513 // NOT (Carry flag) from a register value, and writes the result to the
9514 // destination register.
9515 // It can optionally update the condition flags based on the result.
9516 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9517 const ARMEncoding encoding) {
9519 // ARM pseudo code...
9520 if ConditionPassed() then
9521 EncodingSpecificOperations();
9522 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9523 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9524 if d == 15 then // Can only occur for ARM encoding
9525 ALUWritePC(result); // setflags is always FALSE here
9529 APSR.N = result<31>;
9530 APSR.Z = IsZeroBit(result);
9535 bool success = false;
9537 uint32_t Rd; // the destination register
9538 uint32_t Rn; // the first operand
9539 uint32_t Rm; // the second operand
9541 ARM_ShifterType shift_t;
9542 uint32_t shift_n; // the shift applied to the value read from Rm
9545 Rd = Rn = Bits32(opcode, 2, 0);
9546 Rm = Bits32(opcode, 5, 3);
9547 setflags = !InITBlock();
9548 shift_t = SRType_LSL;
9552 Rd = Bits32(opcode, 11, 8);
9553 Rn = Bits32(opcode, 19, 16);
9554 Rm = Bits32(opcode, 3, 0);
9555 setflags = BitIsSet(opcode, 20);
9556 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9557 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9561 Rd = Bits32(opcode, 15, 12);
9562 Rn = Bits32(opcode, 19, 16);
9563 Rm = Bits32(opcode, 3, 0);
9564 setflags = BitIsSet(opcode, 20);
9565 shift_n = DecodeImmShiftARM(opcode, shift_t);
9567 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9569 if (Rd == 15 && setflags)
9570 return EmulateSUBSPcLrEtc(opcode, encoding);
9575 // Read the register value from register Rn.
9576 uint32_t val1 = ReadCoreReg(Rn, &success);
9580 // Read the register value from register Rm.
9581 uint32_t val2 = ReadCoreReg(Rm, &success);
9585 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9588 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9590 EmulateInstruction::Context context;
9591 context.type = EmulateInstruction::eContextImmediate;
9592 context.SetNoArgs();
9593 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9594 res.carry_out, res.overflow);
9597 // This instruction subtracts an immediate value from a register value, and
9598 // writes the result to the destination register. It can optionally update the
9599 // condition flags based on the result.
9600 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9601 const ARMEncoding encoding) {
9603 // ARM pseudo code...
9604 if ConditionPassed() then
9605 EncodingSpecificOperations();
9606 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9609 APSR.N = result<31>;
9610 APSR.Z = IsZeroBit(result);
9615 bool success = false;
9617 uint32_t Rd; // the destination register
9618 uint32_t Rn; // the first operand
9620 uint32_t imm32; // the immediate value to be subtracted from the value
9624 Rd = Bits32(opcode, 2, 0);
9625 Rn = Bits32(opcode, 5, 3);
9626 setflags = !InITBlock();
9627 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9630 Rd = Rn = Bits32(opcode, 10, 8);
9631 setflags = !InITBlock();
9632 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9635 Rd = Bits32(opcode, 11, 8);
9636 Rn = Bits32(opcode, 19, 16);
9637 setflags = BitIsSet(opcode, 20);
9638 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9640 // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9641 if (Rd == 15 && setflags)
9642 return EmulateCMPImm(opcode, eEncodingT2);
9644 // if Rn == '1101' then SEE SUB (SP minus immediate);
9646 return EmulateSUBSPImm(opcode, eEncodingT2);
9648 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9649 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9653 Rd = Bits32(opcode, 11, 8);
9654 Rn = Bits32(opcode, 19, 16);
9655 setflags = BitIsSet(opcode, 20);
9656 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9658 // if Rn == '1111' then SEE ADR;
9660 return EmulateADR(opcode, eEncodingT2);
9662 // if Rn == '1101' then SEE SUB (SP minus immediate);
9664 return EmulateSUBSPImm(opcode, eEncodingT3);
9672 // Read the register value from the operand register Rn.
9673 uint32_t reg_val = ReadCoreReg(Rn, &success);
9677 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9679 EmulateInstruction::Context context;
9680 context.type = EmulateInstruction::eContextImmediate;
9681 context.SetNoArgs();
9683 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9684 res.carry_out, res.overflow);
9687 // This instruction subtracts an immediate value from a register value, and
9688 // writes the result to the destination register. It can optionally update the
9689 // condition flags based on the result.
9690 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9691 const ARMEncoding encoding) {
9693 // ARM pseudo code...
9694 if ConditionPassed() then
9695 EncodingSpecificOperations();
9696 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9698 ALUWritePC(result); // setflags is always FALSE here
9702 APSR.N = result<31>;
9703 APSR.Z = IsZeroBit(result);
9708 bool success = false;
9710 if (ConditionPassed(opcode)) {
9711 uint32_t Rd; // the destination register
9712 uint32_t Rn; // the first operand
9714 uint32_t imm32; // the immediate value to be subtracted from the value
9718 Rd = Bits32(opcode, 15, 12);
9719 Rn = Bits32(opcode, 19, 16);
9720 setflags = BitIsSet(opcode, 20);
9721 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9723 // if Rn == '1111' && S == '0' then SEE ADR;
9724 if (Rn == 15 && !setflags)
9725 return EmulateADR(opcode, eEncodingA2);
9727 // if Rn == '1101' then SEE SUB (SP minus immediate);
9729 return EmulateSUBSPImm(opcode, eEncodingA1);
9731 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9733 if (Rd == 15 && setflags)
9734 return EmulateSUBSPcLrEtc(opcode, encoding);
9739 // Read the register value from the operand register Rn.
9740 uint32_t reg_val = ReadCoreReg(Rn, &success);
9744 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9746 EmulateInstruction::Context context;
9748 context.type = EmulateInstruction::eContextAdjustStackPointer;
9750 context.type = EmulateInstruction::eContextRegisterPlusOffset;
9752 RegisterInfo dwarf_reg;
9753 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
9754 int64_t imm32_signed = imm32;
9755 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed);
9757 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9758 res.carry_out, res.overflow))
9764 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9765 // register value and an immediate value. It updates the condition flags based
9766 // on the result, and discards the result.
9767 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9768 const ARMEncoding encoding) {
9770 // ARM pseudo code...
9771 if ConditionPassed() then
9772 EncodingSpecificOperations();
9773 result = R[n] EOR imm32;
9774 APSR.N = result<31>;
9775 APSR.Z = IsZeroBit(result);
9780 bool success = false;
9782 if (ConditionPassed(opcode)) {
9785 imm32; // the immediate value to be ANDed to the value obtained from Rn
9786 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9789 Rn = Bits32(opcode, 19, 16);
9790 imm32 = ThumbExpandImm_C(
9792 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9797 Rn = Bits32(opcode, 19, 16);
9799 ARMExpandImm_C(opcode, APSR_C,
9800 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9806 // Read the first operand.
9807 uint32_t val1 = ReadCoreReg(Rn, &success);
9811 uint32_t result = val1 ^ imm32;
9813 EmulateInstruction::Context context;
9814 context.type = EmulateInstruction::eContextImmediate;
9815 context.SetNoArgs();
9817 if (!WriteFlags(context, result, carry))
9823 // Test Equivalence (register) performs a bitwise exclusive OR operation on a
9824 // register value and an optionally-shifted register value. It updates the
9825 // condition flags based on the result, and discards the result.
9826 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9827 const ARMEncoding encoding) {
9829 // ARM pseudo code...
9830 if ConditionPassed() then
9831 EncodingSpecificOperations();
9832 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9833 result = R[n] EOR shifted;
9834 APSR.N = result<31>;
9835 APSR.Z = IsZeroBit(result);
9840 bool success = false;
9842 if (ConditionPassed(opcode)) {
9844 ARM_ShifterType shift_t;
9845 uint32_t shift_n; // the shift applied to the value read from Rm
9849 Rn = Bits32(opcode, 19, 16);
9850 Rm = Bits32(opcode, 3, 0);
9851 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9852 if (BadReg(Rn) || BadReg(Rm))
9856 Rn = Bits32(opcode, 19, 16);
9857 Rm = Bits32(opcode, 3, 0);
9858 shift_n = DecodeImmShiftARM(opcode, shift_t);
9864 // Read the first operand.
9865 uint32_t val1 = ReadCoreReg(Rn, &success);
9869 // Read the second operand.
9870 uint32_t val2 = ReadCoreReg(Rm, &success);
9874 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9877 uint32_t result = val1 ^ shifted;
9879 EmulateInstruction::Context context;
9880 context.type = EmulateInstruction::eContextImmediate;
9881 context.SetNoArgs();
9883 if (!WriteFlags(context, result, carry))
9889 // Test (immediate) performs a bitwise AND operation on a register value and an
9890 // immediate value. It updates the condition flags based on the result, and
9891 // discards the result.
9892 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9893 const ARMEncoding encoding) {
9895 // ARM pseudo code...
9896 if ConditionPassed() then
9897 EncodingSpecificOperations();
9898 result = R[n] AND imm32;
9899 APSR.N = result<31>;
9900 APSR.Z = IsZeroBit(result);
9905 bool success = false;
9907 if (ConditionPassed(opcode)) {
9910 imm32; // the immediate value to be ANDed to the value obtained from Rn
9911 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9914 Rn = Bits32(opcode, 19, 16);
9915 imm32 = ThumbExpandImm_C(
9917 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9922 Rn = Bits32(opcode, 19, 16);
9924 ARMExpandImm_C(opcode, APSR_C,
9925 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9931 // Read the first operand.
9932 uint32_t val1 = ReadCoreReg(Rn, &success);
9936 uint32_t result = val1 & imm32;
9938 EmulateInstruction::Context context;
9939 context.type = EmulateInstruction::eContextImmediate;
9940 context.SetNoArgs();
9942 if (!WriteFlags(context, result, carry))
9948 // Test (register) performs a bitwise AND operation on a register value and an
9949 // optionally-shifted register value. It updates the condition flags based on
9950 // the result, and discards the result.
9951 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
9952 const ARMEncoding encoding) {
9954 // ARM pseudo code...
9955 if ConditionPassed() then
9956 EncodingSpecificOperations();
9957 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9958 result = R[n] AND shifted;
9959 APSR.N = result<31>;
9960 APSR.Z = IsZeroBit(result);
9965 bool success = false;
9967 if (ConditionPassed(opcode)) {
9969 ARM_ShifterType shift_t;
9970 uint32_t shift_n; // the shift applied to the value read from Rm
9974 Rn = Bits32(opcode, 2, 0);
9975 Rm = Bits32(opcode, 5, 3);
9976 shift_t = SRType_LSL;
9980 Rn = Bits32(opcode, 19, 16);
9981 Rm = Bits32(opcode, 3, 0);
9982 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9983 if (BadReg(Rn) || BadReg(Rm))
9987 Rn = Bits32(opcode, 19, 16);
9988 Rm = Bits32(opcode, 3, 0);
9989 shift_n = DecodeImmShiftARM(opcode, shift_t);
9995 // Read the first operand.
9996 uint32_t val1 = ReadCoreReg(Rn, &success);
10000 // Read the second operand.
10001 uint32_t val2 = ReadCoreReg(Rm, &success);
10005 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
10008 uint32_t result = val1 & shifted;
10010 EmulateInstruction::Context context;
10011 context.type = EmulateInstruction::eContextImmediate;
10012 context.SetNoArgs();
10014 if (!WriteFlags(context, result, carry))
10020 // A8.6.216 SUB (SP minus register)
10021 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
10022 const ARMEncoding encoding) {
10024 if ConditionPassed() then
10025 EncodingSpecificOperations();
10026 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10027 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10028 if d == 15 then // Can only occur for ARM encoding
10029 ALUWritePC(result); // setflags is always FALSE here
10033 APSR.N = result<31>;
10034 APSR.Z = IsZeroBit(result);
10039 bool success = false;
10041 if (ConditionPassed(opcode)) {
10045 ARM_ShifterType shift_t;
10048 switch (encoding) {
10050 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10051 d = Bits32(opcode, 11, 8);
10052 m = Bits32(opcode, 3, 0);
10053 setflags = BitIsSet(opcode, 20);
10055 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10056 shift_n = DecodeImmShiftThumb(opcode, shift_t);
10058 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
10060 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
10063 // if d == 15 || BadReg(m) then UNPREDICTABLE;
10064 if ((d == 15) || BadReg(m))
10069 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10070 d = Bits32(opcode, 15, 12);
10071 m = Bits32(opcode, 3, 0);
10072 setflags = BitIsSet(opcode, 20);
10074 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10076 if (d == 15 && setflags)
10077 EmulateSUBSPcLrEtc(opcode, encoding);
10079 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10080 shift_n = DecodeImmShiftARM(opcode, shift_t);
10087 // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10088 uint32_t Rm = ReadCoreReg(m, &success);
10092 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10096 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10097 uint32_t sp_val = ReadCoreReg(SP_REG, &success);
10101 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
10103 EmulateInstruction::Context context;
10104 context.type = eContextArithmetic;
10105 RegisterInfo sp_reg;
10106 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
10107 RegisterInfo dwarf_reg;
10108 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
10109 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg);
10111 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10112 res.carry_out, res.overflow))
10118 // A8.6.7 ADD (register-shifted register)
10119 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
10120 const ARMEncoding encoding) {
10122 if ConditionPassed() then
10123 EncodingSpecificOperations();
10124 shift_n = UInt(R[s]<7:0>);
10125 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10126 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10129 APSR.N = result<31>;
10130 APSR.Z = IsZeroBit(result);
10135 bool success = false;
10137 if (ConditionPassed(opcode)) {
10143 ARM_ShifterType shift_t;
10145 switch (encoding) {
10147 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
10148 d = Bits32(opcode, 15, 12);
10149 n = Bits32(opcode, 19, 16);
10150 m = Bits32(opcode, 3, 0);
10151 s = Bits32(opcode, 11, 8);
10153 // setflags = (S == '1'); shift_t = DecodeRegShift(type);
10154 setflags = BitIsSet(opcode, 20);
10155 shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
10157 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
10158 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
10166 // shift_n = UInt(R[s]<7:0>);
10167 uint32_t Rs = ReadCoreReg(s, &success);
10171 uint32_t shift_n = Bits32(Rs, 7, 0);
10173 // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10174 uint32_t Rm = ReadCoreReg(m, &success);
10178 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10182 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10183 uint32_t Rn = ReadCoreReg(n, &success);
10187 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
10190 EmulateInstruction::Context context;
10191 context.type = eContextArithmetic;
10192 RegisterInfo reg_n;
10193 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10194 RegisterInfo reg_m;
10195 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10197 context.SetRegisterRegisterOperands(reg_n, reg_m);
10199 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
10203 // if setflags then
10204 // APSR.N = result<31>;
10205 // APSR.Z = IsZeroBit(result);
10207 // APSR.V = overflow;
10209 return WriteFlags(context, res.result, res.carry_out, res.overflow);
10214 // A8.6.213 SUB (register)
10215 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
10216 const ARMEncoding encoding) {
10218 if ConditionPassed() then
10219 EncodingSpecificOperations();
10220 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10221 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10222 if d == 15 then // Can only occur for ARM encoding
10223 ALUWritePC(result); // setflags is always FALSE here
10227 APSR.N = result<31>;
10228 APSR.Z = IsZeroBit(result);
10233 bool success = false;
10235 if (ConditionPassed(opcode)) {
10240 ARM_ShifterType shift_t;
10243 switch (encoding) {
10245 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
10246 d = Bits32(opcode, 2, 0);
10247 n = Bits32(opcode, 5, 3);
10248 m = Bits32(opcode, 8, 6);
10249 setflags = !InITBlock();
10251 // (shift_t, shift_n) = (SRType_LSL, 0);
10252 shift_t = SRType_LSL;
10258 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
10259 d = Bits32(opcode, 11, 8);
10260 n = Bits32(opcode, 19, 16);
10261 m = Bits32(opcode, 3, 0);
10262 setflags = BitIsSet(opcode, 20);
10264 // if Rd == "1111" && S == "1" then SEE CMP (register);
10265 if (d == 15 && setflags == 1)
10266 return EmulateCMPImm(opcode, eEncodingT3);
10268 // if Rn == "1101" then SEE SUB (SP minus register);
10270 return EmulateSUBSPReg(opcode, eEncodingT1);
10272 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10273 shift_n = DecodeImmShiftThumb(opcode, shift_t);
10275 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
10277 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
10284 // if Rn == '1101' then SEE SUB (SP minus register);
10285 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
10286 d = Bits32(opcode, 15, 12);
10287 n = Bits32(opcode, 19, 16);
10288 m = Bits32(opcode, 3, 0);
10289 setflags = BitIsSet(opcode, 20);
10291 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10293 if ((d == 15) && setflags)
10294 EmulateSUBSPcLrEtc(opcode, encoding);
10296 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10297 shift_n = DecodeImmShiftARM(opcode, shift_t);
10305 // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10306 uint32_t Rm = ReadCoreReg(m, &success);
10310 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10314 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10315 uint32_t Rn = ReadCoreReg(n, &success);
10319 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
10321 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result);
10322 // // setflags is always FALSE here else
10324 // if setflags then
10325 // APSR.N = result<31>;
10326 // APSR.Z = IsZeroBit(result);
10328 // APSR.V = overflow;
10330 EmulateInstruction::Context context;
10331 context.type = eContextArithmetic;
10332 RegisterInfo reg_n;
10333 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10334 RegisterInfo reg_m;
10335 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10336 context.SetRegisterRegisterOperands(reg_n, reg_m);
10338 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10339 res.carry_out, res.overflow))
10346 // Store Register Exclusive calculates an address from a base register value
10347 // and an immediate offset, and stores a word from a register to memory if the
10348 // executing processor has exclusive access to the memory addressed.
10349 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
10350 const ARMEncoding encoding) {
10352 if ConditionPassed() then
10353 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10354 address = R[n] + imm32;
10355 if ExclusiveMonitorsPass(address,4) then
10356 MemA[address,4] = R[t];
10362 bool success = false;
10364 if (ConditionPassed(opcode)) {
10369 const uint32_t addr_byte_size = GetAddressByteSize();
10371 switch (encoding) {
10373 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 =
10374 // ZeroExtend(imm8:'00',
10376 d = Bits32(opcode, 11, 8);
10377 t = Bits32(opcode, 15, 12);
10378 n = Bits32(opcode, 19, 16);
10379 imm32 = Bits32(opcode, 7, 0) << 2;
10381 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
10382 if (BadReg(d) || BadReg(t) || (n == 15))
10385 // if d == n || d == t then UNPREDICTABLE;
10386 if ((d == n) || (d == t))
10392 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
10394 d = Bits32(opcode, 15, 12);
10395 t = Bits32(opcode, 3, 0);
10396 n = Bits32(opcode, 19, 16);
10399 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
10400 if ((d == 15) || (t == 15) || (n == 15))
10403 // if d == n || d == t then UNPREDICTABLE;
10404 if ((d == n) || (d == t))
10413 // address = R[n] + imm32;
10414 uint32_t Rn = ReadCoreReg(n, &success);
10418 addr_t address = Rn + imm32;
10420 RegisterInfo base_reg;
10421 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10422 RegisterInfo data_reg;
10423 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10424 EmulateInstruction::Context context;
10425 context.type = eContextRegisterStore;
10426 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32);
10428 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass
10429 // (address, addr_byte_size)) -- For now, for the sake of emulation, we
10434 // MemA[address,4] = R[t];
10436 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
10440 if (!MemAWrite(context, address, Rt, addr_byte_size))
10444 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
10447 #if 0 // unreachable because if true
10451 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10454 #endif // unreachable because if true
10459 // A8.6.197 STRB (immediate, ARM)
10460 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
10461 const ARMEncoding encoding) {
10463 if ConditionPassed() then
10464 EncodingSpecificOperations();
10465 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10466 address = if index then offset_addr else R[n];
10467 MemU[address,1] = R[t]<7:0>;
10468 if wback then R[n] = offset_addr;
10471 bool success = false;
10473 if (ConditionPassed(opcode)) {
10481 switch (encoding) {
10483 // if P == '0' && W == '1' then SEE STRBT;
10484 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10485 t = Bits32(opcode, 15, 12);
10486 n = Bits32(opcode, 19, 16);
10487 imm32 = Bits32(opcode, 11, 0);
10489 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10490 index = BitIsSet(opcode, 24);
10491 add = BitIsSet(opcode, 23);
10492 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10494 // if t == 15 then UNPREDICTABLE;
10498 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10499 if (wback && ((n == 15) || (n == t)))
10508 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10509 uint32_t Rn = ReadCoreReg(n, &success);
10513 addr_t offset_addr;
10515 offset_addr = Rn + imm32;
10517 offset_addr = Rn - imm32;
10519 // address = if index then offset_addr else R[n];
10522 address = offset_addr;
10526 // MemU[address,1] = R[t]<7:0>;
10527 uint32_t Rt = ReadCoreReg(t, &success);
10531 RegisterInfo base_reg;
10532 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10533 RegisterInfo data_reg;
10534 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10535 EmulateInstruction::Context context;
10536 context.type = eContextRegisterStore;
10537 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10539 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10542 // if wback then R[n] = offset_addr;
10544 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10552 // A8.6.194 STR (immediate, ARM)
10553 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10554 const ARMEncoding encoding) {
10556 if ConditionPassed() then
10557 EncodingSpecificOperations();
10558 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10559 address = if index then offset_addr else R[n];
10560 MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10561 if wback then R[n] = offset_addr;
10564 bool success = false;
10566 if (ConditionPassed(opcode)) {
10574 const uint32_t addr_byte_size = GetAddressByteSize();
10576 switch (encoding) {
10578 // if P == '0' && W == '1' then SEE STRT;
10579 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10580 // '000000000100' then SEE PUSH;
10581 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10582 t = Bits32(opcode, 15, 12);
10583 n = Bits32(opcode, 19, 16);
10584 imm32 = Bits32(opcode, 11, 0);
10586 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10587 index = BitIsSet(opcode, 24);
10588 add = BitIsSet(opcode, 23);
10589 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10591 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10592 if (wback && ((n == 15) || (n == t)))
10601 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10602 uint32_t Rn = ReadCoreReg(n, &success);
10606 addr_t offset_addr;
10608 offset_addr = Rn + imm32;
10610 offset_addr = Rn - imm32;
10612 // address = if index then offset_addr else R[n];
10615 address = offset_addr;
10619 RegisterInfo base_reg;
10620 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10621 RegisterInfo data_reg;
10622 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10623 EmulateInstruction::Context context;
10624 context.type = eContextRegisterStore;
10625 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10627 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10628 uint32_t Rt = ReadCoreReg(t, &success);
10633 uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10637 if (!MemUWrite(context, address, pc_value, addr_byte_size))
10640 if (!MemUWrite(context, address, Rt, addr_byte_size))
10644 // if wback then R[n] = offset_addr;
10646 context.type = eContextAdjustBaseRegister;
10647 context.SetImmediate(offset_addr);
10649 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10657 // A8.6.66 LDRD (immediate)
10658 // Load Register Dual (immediate) calculates an address from a base register
10659 // value and an immediate offset, loads two words from memory, and writes them
10660 // to two registers. It can use offset, post-indexed, or pre-indexed
10662 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10663 const ARMEncoding encoding) {
10665 if ConditionPassed() then
10666 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10667 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10668 address = if index then offset_addr else R[n];
10669 R[t] = MemA[address,4];
10670 R[t2] = MemA[address+4,4];
10671 if wback then R[n] = offset_addr;
10674 bool success = false;
10676 if (ConditionPassed(opcode)) {
10685 switch (encoding) {
10687 // if P == '0' && W == '0' then SEE 'Related encodings';
10688 // if Rn == '1111' then SEE LDRD (literal);
10689 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10690 // ZeroExtend(imm8:'00', 32);
10691 t = Bits32(opcode, 15, 12);
10692 t2 = Bits32(opcode, 11, 8);
10693 n = Bits32(opcode, 19, 16);
10694 imm32 = Bits32(opcode, 7, 0) << 2;
10696 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10697 index = BitIsSet(opcode, 24);
10698 add = BitIsSet(opcode, 23);
10699 wback = BitIsSet(opcode, 21);
10701 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10702 if (wback && ((n == t) || (n == t2)))
10705 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10706 if (BadReg(t) || BadReg(t2) || (t == t2))
10712 // if Rn == '1111' then SEE LDRD (literal);
10713 // if Rt<0> == '1' then UNPREDICTABLE;
10714 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10716 t = Bits32(opcode, 15, 12);
10717 if (BitIsSet(t, 0))
10720 n = Bits32(opcode, 19, 16);
10721 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10723 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10724 index = BitIsSet(opcode, 24);
10725 add = BitIsSet(opcode, 23);
10726 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10728 // if P == '0' && W == '1' then UNPREDICTABLE;
10729 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10732 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10733 if (wback && ((n == t) || (n == t2)))
10736 // if t2 == 15 then UNPREDICTABLE;
10746 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10747 uint32_t Rn = ReadCoreReg(n, &success);
10751 addr_t offset_addr;
10753 offset_addr = Rn + imm32;
10755 offset_addr = Rn - imm32;
10757 // address = if index then offset_addr else R[n];
10760 address = offset_addr;
10764 // R[t] = MemA[address,4];
10765 RegisterInfo base_reg;
10766 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10768 EmulateInstruction::Context context;
10770 context.type = eContextPopRegisterOffStack;
10772 context.type = eContextRegisterLoad;
10773 context.SetAddress(address);
10775 const uint32_t addr_byte_size = GetAddressByteSize();
10776 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10780 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10783 // R[t2] = MemA[address+4,4];
10784 context.SetAddress(address + 4);
10785 data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10789 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10793 // if wback then R[n] = offset_addr;
10795 context.type = eContextAdjustBaseRegister;
10796 context.SetAddress(offset_addr);
10798 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10806 // A8.6.68 LDRD (register)
10807 // Load Register Dual (register) calculates an address from a base register
10808 // value and a register offset, loads two words from memory, and writes them to
10809 // two registers. It can use offset, post-indexed or pre-indexed addressing.
10810 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10811 const ARMEncoding encoding) {
10813 if ConditionPassed() then
10814 EncodingSpecificOperations();
10815 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10816 address = if index then offset_addr else R[n];
10817 R[t] = MemA[address,4];
10818 R[t2] = MemA[address+4,4];
10819 if wback then R[n] = offset_addr;
10822 bool success = false;
10824 if (ConditionPassed(opcode)) {
10833 switch (encoding) {
10835 // if Rt<0> == '1' then UNPREDICTABLE;
10836 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10837 t = Bits32(opcode, 15, 12);
10838 if (BitIsSet(t, 0))
10841 n = Bits32(opcode, 19, 16);
10842 m = Bits32(opcode, 3, 0);
10844 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10845 index = BitIsSet(opcode, 24);
10846 add = BitIsSet(opcode, 23);
10847 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10849 // if P == '0' && W == '1' then UNPREDICTABLE;
10850 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10853 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10854 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10857 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10858 if (wback && ((n == 15) || (n == t) || (n == t2)))
10861 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10862 if ((ArchVersion() < 6) && wback && (m == n))
10870 uint32_t Rn = ReadCoreReg(n, &success);
10873 RegisterInfo base_reg;
10874 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10876 uint32_t Rm = ReadCoreReg(m, &success);
10879 RegisterInfo offset_reg;
10880 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10882 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10883 addr_t offset_addr;
10885 offset_addr = Rn + Rm;
10887 offset_addr = Rn - Rm;
10889 // address = if index then offset_addr else R[n];
10892 address = offset_addr;
10896 EmulateInstruction::Context context;
10898 context.type = eContextPopRegisterOffStack;
10900 context.type = eContextRegisterLoad;
10901 context.SetAddress(address);
10903 // R[t] = MemA[address,4];
10904 const uint32_t addr_byte_size = GetAddressByteSize();
10905 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10909 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10912 // R[t2] = MemA[address+4,4];
10914 data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10918 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10922 // if wback then R[n] = offset_addr;
10924 context.type = eContextAdjustBaseRegister;
10925 context.SetAddress(offset_addr);
10927 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10935 // A8.6.200 STRD (immediate)
10936 // Store Register Dual (immediate) calculates an address from a base register
10937 // value and an immediate offset, and stores two words from two registers to
10938 // memory. It can use offset, post-indexed, or pre-indexed addressing.
10939 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
10940 const ARMEncoding encoding) {
10942 if ConditionPassed() then
10943 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10944 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10945 address = if index then offset_addr else R[n];
10946 MemA[address,4] = R[t];
10947 MemA[address+4,4] = R[t2];
10948 if wback then R[n] = offset_addr;
10951 bool success = false;
10953 if (ConditionPassed(opcode)) {
10962 switch (encoding) {
10964 // if P == '0' && W == '0' then SEE 'Related encodings';
10965 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10966 // ZeroExtend(imm8:'00', 32);
10967 t = Bits32(opcode, 15, 12);
10968 t2 = Bits32(opcode, 11, 8);
10969 n = Bits32(opcode, 19, 16);
10970 imm32 = Bits32(opcode, 7, 0) << 2;
10972 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10973 index = BitIsSet(opcode, 24);
10974 add = BitIsSet(opcode, 23);
10975 wback = BitIsSet(opcode, 21);
10977 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10978 if (wback && ((n == t) || (n == t2)))
10981 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10982 if ((n == 15) || BadReg(t) || BadReg(t2))
10988 // if Rt<0> == '1' then UNPREDICTABLE;
10989 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10991 t = Bits32(opcode, 15, 12);
10992 if (BitIsSet(t, 0))
10996 n = Bits32(opcode, 19, 16);
10997 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10999 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11000 index = BitIsSet(opcode, 24);
11001 add = BitIsSet(opcode, 23);
11002 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11004 // if P == '0' && W == '1' then UNPREDICTABLE;
11005 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11008 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11009 if (wback && ((n == 15) || (n == t) || (n == t2)))
11012 // if t2 == 15 then UNPREDICTABLE;
11022 RegisterInfo base_reg;
11023 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11025 uint32_t Rn = ReadCoreReg(n, &success);
11029 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
11030 addr_t offset_addr;
11032 offset_addr = Rn + imm32;
11034 offset_addr = Rn - imm32;
11036 // address = if index then offset_addr else R[n];
11039 address = offset_addr;
11043 // MemA[address,4] = R[t];
11044 RegisterInfo data_reg;
11045 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11047 uint32_t data = ReadCoreReg(t, &success);
11051 EmulateInstruction::Context context;
11053 context.type = eContextPushRegisterOnStack;
11055 context.type = eContextRegisterStore;
11056 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11058 const uint32_t addr_byte_size = GetAddressByteSize();
11060 if (!MemAWrite(context, address, data, addr_byte_size))
11063 // MemA[address+4,4] = R[t2];
11064 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11065 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11066 (address + 4) - Rn);
11068 data = ReadCoreReg(t2, &success);
11072 if (!MemAWrite(context, address + 4, data, addr_byte_size))
11075 // if wback then R[n] = offset_addr;
11078 context.type = eContextAdjustStackPointer;
11080 context.type = eContextAdjustBaseRegister;
11081 context.SetAddress(offset_addr);
11083 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11091 // A8.6.201 STRD (register)
11092 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
11093 const ARMEncoding encoding) {
11095 if ConditionPassed() then
11096 EncodingSpecificOperations();
11097 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11098 address = if index then offset_addr else R[n];
11099 MemA[address,4] = R[t];
11100 MemA[address+4,4] = R[t2];
11101 if wback then R[n] = offset_addr;
11104 bool success = false;
11106 if (ConditionPassed(opcode)) {
11115 switch (encoding) {
11117 // if Rt<0> == '1' then UNPREDICTABLE;
11118 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
11119 t = Bits32(opcode, 15, 12);
11120 if (BitIsSet(t, 0))
11124 n = Bits32(opcode, 19, 16);
11125 m = Bits32(opcode, 3, 0);
11127 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11128 index = BitIsSet(opcode, 24);
11129 add = BitIsSet(opcode, 23);
11130 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11132 // if P == '0' && W == '1' then UNPREDICTABLE;
11133 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11136 // if t2 == 15 || m == 15 then UNPREDICTABLE;
11137 if ((t2 == 15) || (m == 15))
11140 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11141 if (wback && ((n == 15) || (n == t) || (n == t2)))
11144 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
11145 if ((ArchVersion() < 6) && wback && (m == n))
11154 RegisterInfo base_reg;
11155 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11156 RegisterInfo offset_reg;
11157 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
11158 RegisterInfo data_reg;
11160 uint32_t Rn = ReadCoreReg(n, &success);
11164 uint32_t Rm = ReadCoreReg(m, &success);
11168 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11169 addr_t offset_addr;
11171 offset_addr = Rn + Rm;
11173 offset_addr = Rn - Rm;
11175 // address = if index then offset_addr else R[n];
11178 address = offset_addr;
11181 // MemA[address,4] = R[t];
11182 uint32_t Rt = ReadCoreReg(t, &success);
11186 EmulateInstruction::Context context;
11188 context.type = eContextPushRegisterOnStack;
11190 context.type = eContextRegisterStore;
11192 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11193 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11196 const uint32_t addr_byte_size = GetAddressByteSize();
11198 if (!MemAWrite(context, address, Rt, addr_byte_size))
11201 // MemA[address+4,4] = R[t2];
11202 uint32_t Rt2 = ReadCoreReg(t2, &success);
11206 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11208 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11211 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
11214 // if wback then R[n] = offset_addr;
11216 context.type = eContextAdjustBaseRegister;
11217 context.SetAddress(offset_addr);
11219 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11228 // Vector Load Multiple loads multiple extension registers from consecutive
11229 // memory locations using an address from an ARM core register.
11230 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
11231 const ARMEncoding encoding) {
11233 if ConditionPassed() then
11234 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11235 address = if add then R[n] else R[n]-imm32;
11236 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11237 for r = 0 to regs-1
11238 if single_regs then
11239 S[d+r] = MemA[address,4]; address = address+4;
11241 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11242 // Combine the word-aligned words in the correct order for
11243 // current endianness.
11244 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11247 bool success = false;
11249 if (ConditionPassed(opcode)) {
11258 switch (encoding) {
11261 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11262 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11263 // if P == '1' && W == '0' then SEE VLDR;
11264 // if P == U && W == '1' then UNDEFINED;
11265 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11268 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11269 // !), 101 (DB with !)
11270 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11271 single_regs = false;
11272 add = BitIsSet(opcode, 23);
11273 wback = BitIsSet(opcode, 21);
11275 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11276 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11277 n = Bits32(opcode, 19, 16);
11278 imm32 = Bits32(opcode, 7, 0) << 2;
11280 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
11281 regs = Bits32(opcode, 7, 0) / 2;
11283 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11285 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
11288 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11289 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11296 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11297 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11298 // if P == '1' && W == '0' then SEE VLDR;
11299 // if P == U && W == '1' then UNDEFINED;
11300 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11303 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11304 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11306 // UInt(Vd:D); n = UInt(Rn);
11307 single_regs = true;
11308 add = BitIsSet(opcode, 23);
11309 wback = BitIsSet(opcode, 21);
11310 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11311 n = Bits32(opcode, 19, 16);
11313 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11314 imm32 = Bits32(opcode, 7, 0) << 2;
11315 regs = Bits32(opcode, 7, 0);
11317 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11319 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11322 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11323 if ((regs == 0) || ((d + regs) > 32))
11331 RegisterInfo base_reg;
11332 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11334 uint32_t Rn = ReadCoreReg(n, &success);
11338 // address = if add then R[n] else R[n]-imm32;
11343 address = Rn - imm32;
11345 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11346 EmulateInstruction::Context context;
11351 value = Rn + imm32;
11353 value = Rn - imm32;
11355 context.type = eContextAdjustBaseRegister;
11356 context.SetImmediateSigned(value - Rn);
11357 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11362 const uint32_t addr_byte_size = GetAddressByteSize();
11363 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11365 context.type = eContextRegisterLoad;
11367 // for r = 0 to regs-1
11368 for (uint32_t r = 0; r < regs; ++r) {
11370 // S[d+r] = MemA[address,4]; address = address+4;
11371 context.SetRegisterPlusOffset(base_reg, address - Rn);
11373 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11377 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11378 start_reg + d + r, data))
11381 address = address + 4;
11383 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
11385 context.SetRegisterPlusOffset(base_reg, address - Rn);
11387 MemARead(context, address, addr_byte_size, 0, &success);
11391 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn);
11393 MemARead(context, address + 4, addr_byte_size, 0, &success);
11397 address = address + 8;
11398 // // Combine the word-aligned words in the correct order for current
11400 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11402 if (GetByteOrder() == eByteOrderBig) {
11404 data = (data << 32) | word2;
11407 data = (data << 32) | word1;
11410 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11411 start_reg + d + r, data))
11420 // Vector Store Multiple stores multiple extension registers to consecutive
11421 // memory locations using an address from an
11422 // ARM core register.
11423 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
11424 const ARMEncoding encoding) {
11426 if ConditionPassed() then
11427 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11428 address = if add then R[n] else R[n]-imm32;
11429 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11430 for r = 0 to regs-1
11431 if single_regs then
11432 MemA[address,4] = S[d+r]; address = address+4;
11434 // Store as two word-aligned words in the correct order for
11435 // current endianness.
11436 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11437 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11438 address = address+8;
11441 bool success = false;
11443 if (ConditionPassed(opcode)) {
11452 switch (encoding) {
11455 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11456 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11457 // if P == '1' && W == '0' then SEE VSTR;
11458 // if P == U && W == '1' then UNDEFINED;
11459 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11462 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11463 // !), 101 (DB with !)
11464 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11465 single_regs = false;
11466 add = BitIsSet(opcode, 23);
11467 wback = BitIsSet(opcode, 21);
11469 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11470 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11471 n = Bits32(opcode, 19, 16);
11472 imm32 = Bits32(opcode, 7, 0) << 2;
11474 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11475 regs = Bits32(opcode, 7, 0) / 2;
11477 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11479 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11482 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11483 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11490 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11491 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11492 // if P == '1' && W == '0' then SEE VSTR;
11493 // if P == U && W == '1' then UNDEFINED;
11494 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11497 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11498 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11500 // UInt(Vd:D); n = UInt(Rn);
11501 single_regs = true;
11502 add = BitIsSet(opcode, 23);
11503 wback = BitIsSet(opcode, 21);
11504 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11505 n = Bits32(opcode, 19, 16);
11507 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11508 imm32 = Bits32(opcode, 7, 0) << 2;
11509 regs = Bits32(opcode, 7, 0);
11511 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11513 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11516 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11517 if ((regs == 0) || ((d + regs) > 32))
11526 RegisterInfo base_reg;
11527 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11529 uint32_t Rn = ReadCoreReg(n, &success);
11533 // address = if add then R[n] else R[n]-imm32;
11538 address = Rn - imm32;
11540 EmulateInstruction::Context context;
11541 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11545 value = Rn + imm32;
11547 value = Rn - imm32;
11549 context.type = eContextAdjustBaseRegister;
11550 context.SetRegisterPlusOffset(base_reg, value - Rn);
11552 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11557 const uint32_t addr_byte_size = GetAddressByteSize();
11558 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11560 context.type = eContextRegisterStore;
11561 // for r = 0 to regs-1
11562 for (uint32_t r = 0; r < regs; ++r) {
11565 // MemA[address,4] = S[d+r]; address = address+4;
11566 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11567 start_reg + d + r, 0, &success);
11571 RegisterInfo data_reg;
11572 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11573 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11575 if (!MemAWrite(context, address, data, addr_byte_size))
11578 address = address + 4;
11580 // // Store as two word-aligned words in the correct order for current
11581 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11583 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11585 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11586 start_reg + d + r, 0, &success);
11590 RegisterInfo data_reg;
11591 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11593 if (GetByteOrder() == eByteOrderBig) {
11594 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11596 if (!MemAWrite(context, address, Bits64(data, 63, 32),
11600 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11601 (address + 4) - Rn);
11602 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11606 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11608 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11611 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11612 (address + 4) - Rn);
11613 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11617 // address = address+8;
11618 address = address + 8;
11626 // This instruction loads a single extension register from memory, using an
11627 // address from an ARM core register, with an optional offset.
11628 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11629 ARMEncoding encoding) {
11631 if ConditionPassed() then
11632 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11633 base = if n == 15 then Align(PC,4) else R[n];
11634 address = if add then (base + imm32) else (base - imm32);
11636 S[d] = MemA[address,4];
11638 word1 = MemA[address,4]; word2 = MemA[address+4,4];
11639 // Combine the word-aligned words in the correct order for current
11641 D[d] = if BigEndian() then word1:word2 else word2:word1;
11644 bool success = false;
11646 if (ConditionPassed(opcode)) {
11653 switch (encoding) {
11656 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11658 single_reg = false;
11659 add = BitIsSet(opcode, 23);
11660 imm32 = Bits32(opcode, 7, 0) << 2;
11662 // d = UInt(D:Vd); n = UInt(Rn);
11663 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11664 n = Bits32(opcode, 19, 16);
11670 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11672 add = BitIsSet(opcode, 23);
11673 imm32 = Bits32(opcode, 7, 0) << 2;
11675 // d = UInt(Vd:D); n = UInt(Rn);
11676 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11677 n = Bits32(opcode, 19, 16);
11684 RegisterInfo base_reg;
11685 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11687 uint32_t Rn = ReadCoreReg(n, &success);
11691 // base = if n == 15 then Align(PC,4) else R[n];
11694 base = AlignPC(Rn);
11698 // address = if add then (base + imm32) else (base - imm32);
11701 address = base + imm32;
11703 address = base - imm32;
11705 const uint32_t addr_byte_size = GetAddressByteSize();
11706 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11708 EmulateInstruction::Context context;
11709 context.type = eContextRegisterLoad;
11710 context.SetRegisterPlusOffset(base_reg, address - base);
11713 // S[d] = MemA[address,4];
11714 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11718 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11722 // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11723 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11727 context.SetRegisterPlusOffset(base_reg, (address + 4) - base);
11729 MemARead(context, address + 4, addr_byte_size, 0, &success);
11732 // // Combine the word-aligned words in the correct order for current
11734 // D[d] = if BigEndian() then word1:word2 else word2:word1;
11736 if (GetByteOrder() == eByteOrderBig) {
11738 data64 = (data64 << 32) | word2;
11741 data64 = (data64 << 32) | word1;
11744 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11753 // This instruction stores a signle extension register to memory, using an
11754 // address from an ARM core register, with an optional offset.
11755 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11756 ARMEncoding encoding) {
11758 if ConditionPassed() then
11759 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11760 address = if add then (R[n] + imm32) else (R[n] - imm32);
11762 MemA[address,4] = S[d];
11764 // Store as two word-aligned words in the correct order for current
11766 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11767 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11770 bool success = false;
11772 if (ConditionPassed(opcode)) {
11779 switch (encoding) {
11782 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11784 single_reg = false;
11785 add = BitIsSet(opcode, 23);
11786 imm32 = Bits32(opcode, 7, 0) << 2;
11788 // d = UInt(D:Vd); n = UInt(Rn);
11789 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11790 n = Bits32(opcode, 19, 16);
11792 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11793 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11800 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11802 add = BitIsSet(opcode, 23);
11803 imm32 = Bits32(opcode, 7, 0) << 2;
11805 // d = UInt(Vd:D); n = UInt(Rn);
11806 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11807 n = Bits32(opcode, 19, 16);
11809 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11810 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11819 RegisterInfo base_reg;
11820 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11822 uint32_t Rn = ReadCoreReg(n, &success);
11826 // address = if add then (R[n] + imm32) else (R[n] - imm32);
11829 address = Rn + imm32;
11831 address = Rn - imm32;
11833 const uint32_t addr_byte_size = GetAddressByteSize();
11834 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11836 RegisterInfo data_reg;
11837 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg);
11838 EmulateInstruction::Context context;
11839 context.type = eContextRegisterStore;
11840 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11843 // MemA[address,4] = S[d];
11845 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11849 if (!MemAWrite(context, address, data, addr_byte_size))
11852 // // Store as two word-aligned words in the correct order for current
11854 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11855 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11857 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11861 if (GetByteOrder() == eByteOrderBig) {
11862 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11865 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11866 (address + 4) - Rn);
11867 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11871 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11874 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11875 (address + 4) - Rn);
11876 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11885 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements
11886 // from memory into one, two, three or four registers, without de-interleaving.
11887 // Every element of each register is loaded.
11888 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11889 ARMEncoding encoding) {
11891 if ConditionPassed() then
11892 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11893 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11894 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11895 for r = 0 to regs-1
11896 for e = 0 to elements-1
11897 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11898 address = address + ebytes;
11901 bool success = false;
11903 if (ConditionPassed(opcode)) {
11905 uint32_t alignment;
11913 bool register_index;
11915 switch (encoding) {
11917 case eEncodingA1: {
11920 // regs = 1; if align<1> == '1' then UNDEFINED;
11922 // regs = 2; if align == '11' then UNDEFINED;
11924 // regs = 3; if align<1> == '1' then UNDEFINED;
11928 // SEE 'Related encodings';
11929 uint32_t type = Bits32(opcode, 11, 8);
11930 uint32_t align = Bits32(opcode, 5, 4);
11931 if (type == 7) // '0111'
11934 if (BitIsSet(align, 1))
11936 } else if (type == 10) // '1010'
11942 } else if (type == 6) // '0110'
11945 if (BitIsSet(align, 1))
11947 } else if (type == 2) // '0010'
11953 // alignment = if align == '00' then 1 else 4 << UInt(align);
11957 alignment = 4 << align;
11959 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11960 ebytes = 1 << Bits32(opcode, 7, 6);
11961 esize = 8 * ebytes;
11962 elements = 8 / ebytes;
11964 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11965 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11966 n = Bits32(opcode, 19, 15);
11967 m = Bits32(opcode, 3, 0);
11969 // wback = (m != 15); register_index = (m != 15 && m != 13);
11971 register_index = ((m != 15) && (m != 13));
11973 // if d+regs > 32 then UNPREDICTABLE;
11974 if ((d + regs) > 32)
11982 RegisterInfo base_reg;
11983 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11985 uint32_t Rn = ReadCoreReg(n, &success);
11989 // address = R[n]; if (address MOD alignment) != 0 then
11990 // GenerateAlignmentException();
11991 addr_t address = Rn;
11992 if ((address % alignment) != 0)
11995 EmulateInstruction::Context context;
11996 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11998 uint32_t Rm = ReadCoreReg(m, &success);
12003 if (register_index)
12008 uint32_t value = Rn + offset;
12009 context.type = eContextAdjustBaseRegister;
12010 context.SetRegisterPlusOffset(base_reg, offset);
12012 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12017 // for r = 0 to regs-1
12018 for (uint32_t r = 0; r < regs; ++r) {
12019 // for e = 0 to elements-1
12020 uint64_t assembled_data = 0;
12021 for (uint32_t e = 0; e < elements; ++e) {
12022 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
12023 context.type = eContextRegisterLoad;
12024 context.SetRegisterPlusOffset(base_reg, address - Rn);
12025 uint64_t data = MemURead(context, address, ebytes, 0, &success);
12030 (data << (e * esize)) |
12031 assembled_data; // New data goes to the left of existing data
12033 // address = address + ebytes;
12034 address = address + ebytes;
12036 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12044 // A8.6.308 VLD1 (single element to one lane)
12046 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
12047 const ARMEncoding encoding) {
12049 if ConditionPassed() then
12050 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12051 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12052 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12053 Elem[D[d],index,esize] = MemU[address,ebytes];
12056 bool success = false;
12058 if (ConditionPassed(opcode)) {
12062 uint32_t alignment;
12067 bool register_index;
12069 switch (encoding) {
12071 case eEncodingA1: {
12072 uint32_t size = Bits32(opcode, 11, 10);
12073 uint32_t index_align = Bits32(opcode, 7, 4);
12074 // if size == '11' then SEE VLD1 (single element to all lanes);
12076 return EmulateVLD1SingleAll(opcode, encoding);
12078 if (size == 0) // when '00'
12080 // if index_align<0> != '0' then UNDEFINED;
12081 if (BitIsClear(index_align, 0))
12084 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12087 index = Bits32(index_align, 3, 1);
12089 } else if (size == 1) // when '01'
12091 // if index_align<1> != '0' then UNDEFINED;
12092 if (BitIsClear(index_align, 1))
12095 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12098 index = Bits32(index_align, 3, 2);
12100 // alignment = if index_align<0> == '0' then 1 else 2;
12101 if (BitIsClear(index_align, 0))
12105 } else if (size == 2) // when '10'
12107 // if index_align<2> != '0' then UNDEFINED;
12108 if (BitIsClear(index_align, 2))
12111 // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12113 if ((Bits32(index_align, 1, 0) != 0) &&
12114 (Bits32(index_align, 1, 0) != 3))
12117 // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12120 index = Bit32(index_align, 3);
12122 // alignment = if index_align<1:0> == '00' then 1 else 4;
12123 if (Bits32(index_align, 1, 0) == 0)
12130 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12131 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12132 n = Bits32(opcode, 19, 16);
12133 m = Bits32(opcode, 3, 0);
12135 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12136 // then UNPREDICTABLE;
12138 register_index = ((m != 15) && (m != 13));
12149 RegisterInfo base_reg;
12150 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12152 uint32_t Rn = ReadCoreReg(n, &success);
12156 // address = R[n]; if (address MOD alignment) != 0 then
12157 // GenerateAlignmentException();
12158 addr_t address = Rn;
12159 if ((address % alignment) != 0)
12162 EmulateInstruction::Context context;
12163 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12165 uint32_t Rm = ReadCoreReg(m, &success);
12170 if (register_index)
12175 uint32_t value = Rn + offset;
12177 context.type = eContextAdjustBaseRegister;
12178 context.SetRegisterPlusOffset(base_reg, offset);
12180 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12185 // Elem[D[d],index,esize] = MemU[address,ebytes];
12186 uint32_t element = MemURead(context, address, esize, 0, &success);
12190 element = element << (index * esize);
12192 uint64_t reg_data =
12193 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12197 uint64_t all_ones = -1;
12198 uint64_t mask = all_ones
12199 << ((index + 1) * esize); // mask is all 1's to left of
12200 // where 'element' goes, & all 0's
12201 // at element & to the right of element.
12203 mask = mask | Bits64(all_ones, (index * esize) - 1,
12204 0); // add 1's to the right of where 'element' goes.
12205 // now mask should be 0's where element goes & 1's everywhere else.
12207 uint64_t masked_reg =
12208 reg_data & mask; // Take original reg value & zero out 'element' bits
12210 masked_reg & element; // Put 'element' into those bits in reg_data.
12212 context.type = eContextRegisterLoad;
12213 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
12220 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single
12221 // elements) stores elements to memory from one, two, three, or four registers,
12222 // without interleaving. Every element of each register is stored.
12223 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
12224 ARMEncoding encoding) {
12226 if ConditionPassed() then
12227 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12228 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12229 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12230 for r = 0 to regs-1
12231 for e = 0 to elements-1
12232 MemU[address,ebytes] = Elem[D[d+r],e,esize];
12233 address = address + ebytes;
12236 bool success = false;
12238 if (ConditionPassed(opcode)) {
12240 uint32_t alignment;
12248 bool register_index;
12250 switch (encoding) {
12252 case eEncodingA1: {
12253 uint32_t type = Bits32(opcode, 11, 8);
12254 uint32_t align = Bits32(opcode, 5, 4);
12257 if (type == 7) // when '0111'
12259 // regs = 1; if align<1> == '1' then UNDEFINED;
12261 if (BitIsSet(align, 1))
12263 } else if (type == 10) // when '1010'
12265 // regs = 2; if align == '11' then UNDEFINED;
12269 } else if (type == 6) // when '0110'
12271 // regs = 3; if align<1> == '1' then UNDEFINED;
12273 if (BitIsSet(align, 1))
12275 } else if (type == 2) // when '0010'
12279 // SEE 'Related encodings';
12282 // alignment = if align == '00' then 1 else 4 << UInt(align);
12286 alignment = 4 << align;
12288 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12289 ebytes = 1 << Bits32(opcode, 7, 6);
12290 esize = 8 * ebytes;
12291 elements = 8 / ebytes;
12293 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12294 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12295 n = Bits32(opcode, 19, 16);
12296 m = Bits32(opcode, 3, 0);
12298 // wback = (m != 15); register_index = (m != 15 && m != 13);
12300 register_index = ((m != 15) && (m != 13));
12302 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12303 if ((d + regs) > 32)
12315 RegisterInfo base_reg;
12316 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12318 uint32_t Rn = ReadCoreReg(n, &success);
12322 // address = R[n]; if (address MOD alignment) != 0 then
12323 // GenerateAlignmentException();
12324 addr_t address = Rn;
12325 if ((address % alignment) != 0)
12328 EmulateInstruction::Context context;
12329 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12331 uint32_t Rm = ReadCoreReg(m, &success);
12336 if (register_index)
12341 context.type = eContextAdjustBaseRegister;
12342 context.SetRegisterPlusOffset(base_reg, offset);
12344 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12349 RegisterInfo data_reg;
12350 context.type = eContextRegisterStore;
12351 // for r = 0 to regs-1
12352 for (uint32_t r = 0; r < regs; ++r) {
12353 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
12354 uint64_t register_data = ReadRegisterUnsigned(
12355 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
12359 // for e = 0 to elements-1
12360 for (uint32_t e = 0; e < elements; ++e) {
12361 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
12362 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12364 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
12366 if (!MemUWrite(context, address, word, ebytes))
12369 // address = address + ebytes;
12370 address = address + ebytes;
12377 // A8.6.392 VST1 (single element from one lane) This instruction stores one
12378 // element to memory from one element of a register.
12379 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
12380 ARMEncoding encoding) {
12382 if ConditionPassed() then
12383 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12384 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12385 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12386 MemU[address,ebytes] = Elem[D[d],index,esize];
12389 bool success = false;
12391 if (ConditionPassed(opcode)) {
12395 uint32_t alignment;
12400 bool register_index;
12402 switch (encoding) {
12404 case eEncodingA1: {
12405 uint32_t size = Bits32(opcode, 11, 10);
12406 uint32_t index_align = Bits32(opcode, 7, 4);
12408 // if size == '11' then UNDEFINED;
12413 if (size == 0) // when '00'
12415 // if index_align<0> != '0' then UNDEFINED;
12416 if (BitIsClear(index_align, 0))
12418 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12421 index = Bits32(index_align, 3, 1);
12423 } else if (size == 1) // when '01'
12425 // if index_align<1> != '0' then UNDEFINED;
12426 if (BitIsClear(index_align, 1))
12429 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12432 index = Bits32(index_align, 3, 2);
12434 // alignment = if index_align<0> == '0' then 1 else 2;
12435 if (BitIsClear(index_align, 0))
12439 } else if (size == 2) // when '10'
12441 // if index_align<2> != '0' then UNDEFINED;
12442 if (BitIsClear(index_align, 2))
12445 // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12447 if ((Bits32(index_align, 1, 0) != 0) &&
12448 (Bits32(index_align, 1, 0) != 3))
12451 // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12454 index = Bit32(index_align, 3);
12456 // alignment = if index_align<1:0> == '00' then 1 else 4;
12457 if (Bits32(index_align, 1, 0) == 0)
12464 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12465 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12466 n = Bits32(opcode, 19, 16);
12467 m = Bits32(opcode, 3, 0);
12469 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12470 // then UNPREDICTABLE;
12472 register_index = ((m != 15) && (m != 13));
12482 RegisterInfo base_reg;
12483 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12485 uint32_t Rn = ReadCoreReg(n, &success);
12489 // address = R[n]; if (address MOD alignment) != 0 then
12490 // GenerateAlignmentException();
12491 addr_t address = Rn;
12492 if ((address % alignment) != 0)
12495 EmulateInstruction::Context context;
12496 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12498 uint32_t Rm = ReadCoreReg(m, &success);
12503 if (register_index)
12508 context.type = eContextAdjustBaseRegister;
12509 context.SetRegisterPlusOffset(base_reg, offset);
12511 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12516 // MemU[address,ebytes] = Elem[D[d],index,esize];
12517 uint64_t register_data =
12518 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12523 Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12525 RegisterInfo data_reg;
12526 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12527 context.type = eContextRegisterStore;
12528 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
12530 if (!MemUWrite(context, address, word, ebytes))
12536 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one
12537 // element from memory into every element of one or two vectors.
12538 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12539 const ARMEncoding encoding) {
12541 if ConditionPassed() then
12542 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12543 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12544 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12545 replicated_element = Replicate(MemU[address,ebytes], elements);
12546 for r = 0 to regs-1
12547 D[d+r] = replicated_element;
12550 bool success = false;
12552 if (ConditionPassed(opcode)) {
12556 uint32_t alignment;
12561 bool register_index;
12563 switch (encoding) {
12565 case eEncodingA1: {
12566 // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12567 uint32_t size = Bits32(opcode, 7, 6);
12568 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12571 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12573 ebytes = 1 << size;
12574 elements = 8 / ebytes;
12575 if (BitIsClear(opcode, 5))
12580 // alignment = if a == '0' then 1 else ebytes;
12581 if (BitIsClear(opcode, 4))
12584 alignment = ebytes;
12586 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12587 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12588 n = Bits32(opcode, 19, 16);
12589 m = Bits32(opcode, 3, 0);
12591 // wback = (m != 15); register_index = (m != 15 && m != 13);
12593 register_index = ((m != 15) && (m != 13));
12595 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12596 if ((d + regs) > 32)
12607 RegisterInfo base_reg;
12608 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12610 uint32_t Rn = ReadCoreReg(n, &success);
12614 // address = R[n]; if (address MOD alignment) != 0 then
12615 // GenerateAlignmentException();
12616 addr_t address = Rn;
12617 if ((address % alignment) != 0)
12620 EmulateInstruction::Context context;
12621 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12623 uint32_t Rm = ReadCoreReg(m, &success);
12628 if (register_index)
12633 context.type = eContextAdjustBaseRegister;
12634 context.SetRegisterPlusOffset(base_reg, offset);
12636 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12641 // replicated_element = Replicate(MemU[address,ebytes], elements);
12643 context.type = eContextRegisterLoad;
12644 uint64_t word = MemURead(context, address, ebytes, 0, &success);
12648 uint64_t replicated_element = 0;
12649 uint32_t esize = ebytes * 8;
12650 for (uint32_t e = 0; e < elements; ++e)
12651 replicated_element =
12652 (replicated_element << esize) | Bits64(word, esize - 1, 0);
12654 // for r = 0 to regs-1
12655 for (uint32_t r = 0; r < regs; ++r) {
12656 // D[d+r] = replicated_element;
12657 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12658 replicated_element))
12665 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const?
12666 // instruction provides an exception return without the use of the stack. It
12667 // subtracts the immediate constant from the LR, branches to the resulting
12668 // address, and also copies the SPSR to the CPSR.
12669 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12670 const ARMEncoding encoding) {
12672 if ConditionPassed() then
12673 EncodingSpecificOperations();
12674 if CurrentInstrSet() == InstrSet_ThumbEE then
12676 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12678 when '0000' result = R[n] AND operand2; // AND
12679 when '0001' result = R[n] EOR operand2; // EOR
12680 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12681 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12682 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12683 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12684 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12685 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12686 when '1100' result = R[n] OR operand2; // ORR
12687 when '1101' result = operand2; // MOV
12688 when '1110' result = R[n] AND NOT(operand2); // BIC
12689 when '1111' result = NOT(operand2); // MVN
12690 CPSRWriteByInstr(SPSR[], '1111', TRUE);
12691 BranchWritePC(result);
12694 bool success = false;
12696 if (ConditionPassed(opcode)) {
12700 bool register_form;
12701 ARM_ShifterType shift_t;
12705 switch (encoding) {
12707 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14;
12708 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010';
12711 imm32 = Bits32(opcode, 7, 0);
12712 register_form = false;
12715 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12716 if (InITBlock() && !LastInITBlock())
12722 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12723 n = Bits32(opcode, 19, 16);
12724 imm32 = ARMExpandImm(opcode);
12725 register_form = false;
12726 code = Bits32(opcode, 24, 21);
12731 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12732 n = Bits32(opcode, 19, 16);
12733 m = Bits32(opcode, 3, 0);
12734 register_form = true;
12736 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12737 shift_n = DecodeImmShiftARM(opcode, shift_t);
12745 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12748 if (register_form) {
12749 uint32_t Rm = ReadCoreReg(m, &success);
12753 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12760 uint32_t Rn = ReadCoreReg(n, &success);
12764 AddWithCarryResult result;
12768 case 0: // when '0000'
12769 // result = R[n] AND operand2; // AND
12770 result.result = Rn & operand2;
12773 case 1: // when '0001'
12774 // result = R[n] EOR operand2; // EOR
12775 result.result = Rn ^ operand2;
12778 case 2: // when '0010'
12779 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12780 result = AddWithCarry(Rn, ~(operand2), 1);
12783 case 3: // when '0011'
12784 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12785 result = AddWithCarry(~(Rn), operand2, 1);
12788 case 4: // when '0100'
12789 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12790 result = AddWithCarry(Rn, operand2, 0);
12793 case 5: // when '0101'
12794 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12795 result = AddWithCarry(Rn, operand2, APSR_C);
12798 case 6: // when '0110'
12799 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12800 result = AddWithCarry(Rn, ~(operand2), APSR_C);
12803 case 7: // when '0111'
12804 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12805 result = AddWithCarry(~(Rn), operand2, APSR_C);
12808 case 10: // when '1100'
12809 // result = R[n] OR operand2; // ORR
12810 result.result = Rn | operand2;
12813 case 11: // when '1101'
12814 // result = operand2; // MOV
12815 result.result = operand2;
12818 case 12: // when '1110'
12819 // result = R[n] AND NOT(operand2); // BIC
12820 result.result = Rn & ~(operand2);
12823 case 15: // when '1111'
12824 // result = NOT(operand2); // MVN
12825 result.result = ~(operand2);
12831 // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12833 // For now, in emulation mode, we don't have access to the SPSR, so we will
12834 // use the CPSR instead, and hope for the best.
12836 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12840 CPSRWriteByInstr(spsr, 15, true);
12842 // BranchWritePC(result);
12843 EmulateInstruction::Context context;
12844 context.type = eContextAdjustPC;
12845 context.SetImmediate(result.result);
12847 BranchWritePC(context, result.result);
12852 EmulateInstructionARM::ARMOpcode *
12853 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12854 uint32_t arm_isa) {
12855 static ARMOpcode g_arm_opcodes[] = {
12856 //----------------------------------------------------------------------
12857 // Prologue instructions
12858 //----------------------------------------------------------------------
12860 // push register(s)
12861 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12862 &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12863 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12864 &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12866 // set r7 to point to a stack offset
12867 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12868 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12869 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12870 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12871 // copy the stack pointer to ip
12872 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12873 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12874 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12875 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12876 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12877 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12879 // adjust the stack pointer
12880 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12881 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12882 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12883 &EmulateInstructionARM::EmulateSUBSPReg,
12884 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12886 // push one register
12887 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12888 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12889 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12891 // vector push consecutive extension register(s)
12892 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12893 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12894 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12895 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12897 //----------------------------------------------------------------------
12898 // Epilogue instructions
12899 //----------------------------------------------------------------------
12901 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12902 &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12903 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12904 &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12905 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12906 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12907 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12908 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12910 //----------------------------------------------------------------------
12911 // Supervisor Call (previously Software Interrupt)
12912 //----------------------------------------------------------------------
12913 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12914 &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12916 //----------------------------------------------------------------------
12917 // Branch instructions
12918 //----------------------------------------------------------------------
12919 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
12921 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
12922 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12923 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12924 &EmulateInstructionARM::EmulateB, "b #imm24"},
12925 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12926 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12927 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
12928 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12929 // for example, "bx lr"
12930 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
12931 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12933 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
12934 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12936 //----------------------------------------------------------------------
12937 // Data-processing instructions
12938 //----------------------------------------------------------------------
12940 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12941 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12943 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12944 &EmulateInstructionARM::EmulateADCReg,
12945 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12947 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12948 &EmulateInstructionARM::EmulateADDImmARM,
12949 "add{s}<c> <Rd>, <Rn>, #const"},
12951 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12952 &EmulateInstructionARM::EmulateADDReg,
12953 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12954 // add (register-shifted register)
12955 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12956 &EmulateInstructionARM::EmulateADDRegShift,
12957 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12959 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12960 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12961 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12962 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12964 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12965 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12967 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12968 &EmulateInstructionARM::EmulateANDReg,
12969 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12971 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12972 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12974 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12975 &EmulateInstructionARM::EmulateBICReg,
12976 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12978 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12979 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12981 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12982 &EmulateInstructionARM::EmulateEORReg,
12983 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12985 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12986 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12988 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12989 &EmulateInstructionARM::EmulateORRReg,
12990 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12992 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12993 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12995 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12996 &EmulateInstructionARM::EmulateRSBReg,
12997 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12999 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13000 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
13002 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13003 &EmulateInstructionARM::EmulateRSCReg,
13004 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13006 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13007 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13009 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13010 &EmulateInstructionARM::EmulateSBCReg,
13011 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13012 // sub (immediate, ARM)
13013 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13014 &EmulateInstructionARM::EmulateSUBImmARM,
13015 "sub{s}<c> <Rd>, <Rn>, #<const>"},
13016 // sub (sp minus immediate)
13017 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13018 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
13020 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13021 &EmulateInstructionARM::EmulateSUBReg,
13022 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
13024 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13025 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
13027 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13028 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13030 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13031 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
13033 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13034 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
13037 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13038 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
13039 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
13040 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
13042 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13043 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
13045 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13046 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
13048 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13049 &EmulateInstructionARM::EmulateMVNReg,
13050 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
13052 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13053 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13055 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13056 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13058 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13059 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
13061 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13062 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
13064 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
13065 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
13067 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13068 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
13070 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13071 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
13073 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13074 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
13076 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
13077 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
13079 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13080 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
13081 // rrx is a special case encoding of ror (immediate)
13082 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13083 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
13085 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13086 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
13088 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
13089 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
13091 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
13092 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
13094 // subs pc, lr and related instructions
13095 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13096 &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13097 "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13098 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13099 &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13100 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13102 //----------------------------------------------------------------------
13103 // Load instructions
13104 //----------------------------------------------------------------------
13105 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13106 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13107 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13108 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
13109 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13110 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13111 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13112 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
13113 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13114 &EmulateInstructionARM::EmulateLDRImmediateARM,
13115 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13116 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13117 &EmulateInstructionARM::EmulateLDRRegister,
13118 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13119 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13120 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
13121 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13122 &EmulateInstructionARM::EmulateLDRBRegister,
13123 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13124 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13125 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13126 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13127 &EmulateInstructionARM::EmulateLDRHRegister,
13128 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13129 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13130 &EmulateInstructionARM::EmulateLDRSBImmediate,
13131 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13132 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13133 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
13134 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13135 &EmulateInstructionARM::EmulateLDRSBRegister,
13136 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13137 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13138 &EmulateInstructionARM::EmulateLDRSHImmediate,
13139 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13140 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13141 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13142 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13143 &EmulateInstructionARM::EmulateLDRSHRegister,
13144 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13145 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13146 &EmulateInstructionARM::EmulateLDRDImmediate,
13147 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13148 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13149 &EmulateInstructionARM::EmulateLDRDRegister,
13150 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13151 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13152 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13153 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13154 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13155 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13156 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13157 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13158 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13159 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13160 &EmulateInstructionARM::EmulateVLD1Multiple,
13161 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13162 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13163 &EmulateInstructionARM::EmulateVLD1Single,
13164 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13165 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13166 &EmulateInstructionARM::EmulateVLD1SingleAll,
13167 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13169 //----------------------------------------------------------------------
13170 // Store instructions
13171 //----------------------------------------------------------------------
13172 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13173 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13174 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13175 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
13176 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13177 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13178 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13179 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
13180 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13181 &EmulateInstructionARM::EmulateSTRRegister,
13182 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13183 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13184 &EmulateInstructionARM::EmulateSTRHRegister,
13185 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13186 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13187 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
13188 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13189 &EmulateInstructionARM::EmulateSTRBImmARM,
13190 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13191 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13192 &EmulateInstructionARM::EmulateSTRImmARM,
13193 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13194 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13195 &EmulateInstructionARM::EmulateSTRDImm,
13196 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13197 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13198 &EmulateInstructionARM::EmulateSTRDReg,
13199 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13200 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13201 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13202 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13203 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13204 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13205 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
13206 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13207 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
13208 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13209 &EmulateInstructionARM::EmulateVST1Multiple,
13210 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13211 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13212 &EmulateInstructionARM::EmulateVST1Single,
13213 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13215 //----------------------------------------------------------------------
13216 // Other instructions
13217 //----------------------------------------------------------------------
13218 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13219 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
13220 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13221 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
13222 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13223 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
13224 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13225 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
13226 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13227 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
13230 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
13232 for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
13233 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13234 (g_arm_opcodes[i].variants & arm_isa) != 0)
13235 return &g_arm_opcodes[i];
13240 EmulateInstructionARM::ARMOpcode *
13241 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
13242 uint32_t arm_isa) {
13244 static ARMOpcode g_thumb_opcodes[] = {
13245 //----------------------------------------------------------------------
13246 // Prologue instructions
13247 //----------------------------------------------------------------------
13249 // push register(s)
13250 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
13251 &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
13252 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13253 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
13254 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13255 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
13257 // set r7 to point to a stack offset
13258 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13259 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
13260 // copy the stack pointer to r7
13261 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
13262 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
13263 // move from high register to low register (comes after "mov r7, sp" to
13264 // resolve ambiguity)
13265 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
13266 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
13268 // PC-relative load into register (see also EmulateADDSPRm)
13269 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13270 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
13272 // adjust the stack pointer
13273 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
13274 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
13275 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13276 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
13277 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13278 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
13279 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13280 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
13281 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13282 &EmulateInstructionARM::EmulateSUBSPReg,
13283 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13285 // vector push consecutive extension register(s)
13286 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13287 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
13288 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13289 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
13291 //----------------------------------------------------------------------
13292 // Epilogue instructions
13293 //----------------------------------------------------------------------
13295 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13296 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
13297 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13298 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
13299 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13300 &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
13301 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13302 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
13303 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13304 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
13305 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13306 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13307 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13308 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13310 //----------------------------------------------------------------------
13311 // Supervisor Call (previously Software Interrupt)
13312 //----------------------------------------------------------------------
13313 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13314 &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
13316 //----------------------------------------------------------------------
13317 // If Then makes up to four following instructions conditional.
13318 //----------------------------------------------------------------------
13319 // The next 5 opcode _must_ come before the if then instruction
13320 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13321 &EmulateInstructionARM::EmulateNop, "nop"},
13322 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13323 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
13324 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13325 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
13326 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13327 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
13328 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13329 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
13330 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13331 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
13333 //----------------------------------------------------------------------
13334 // Branch instructions
13335 //----------------------------------------------------------------------
13336 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
13337 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13338 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
13339 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13340 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
13341 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13342 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
13343 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13344 &EmulateInstructionARM::EmulateB,
13345 "b<c>.w #imm8 (outside or last in IT)"},
13347 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
13348 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13350 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
13351 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13352 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
13353 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13354 // for example, "bx lr"
13355 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
13356 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13358 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
13359 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13360 // compare and branch
13361 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13362 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
13363 // table branch byte
13364 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13365 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
13366 // table branch halfword
13367 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13368 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
13370 //----------------------------------------------------------------------
13371 // Data-processing instructions
13372 //----------------------------------------------------------------------
13374 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13375 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
13377 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
13378 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
13379 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13380 &EmulateInstructionARM::EmulateADCReg,
13381 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13383 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13384 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
13385 // Make sure "add sp, <Rm>" comes before this instruction, so there's no
13386 // ambiguity decoding the two.
13387 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
13388 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
13390 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13391 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13392 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13393 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13394 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13395 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13397 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13398 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
13400 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13401 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
13402 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13403 &EmulateInstructionARM::EmulateANDReg,
13404 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13406 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13407 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
13409 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
13410 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
13411 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13412 &EmulateInstructionARM::EmulateBICReg,
13413 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13415 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13416 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
13418 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
13419 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
13420 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13421 &EmulateInstructionARM::EmulateEORReg,
13422 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13424 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13425 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
13427 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
13428 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
13429 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13430 &EmulateInstructionARM::EmulateORRReg,
13431 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13433 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
13434 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
13435 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13436 &EmulateInstructionARM::EmulateRSBImm,
13437 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13439 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13440 &EmulateInstructionARM::EmulateRSBReg,
13441 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13443 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13444 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13446 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
13447 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
13448 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13449 &EmulateInstructionARM::EmulateSBCReg,
13450 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13451 // add (immediate, Thumb)
13452 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13453 &EmulateInstructionARM::EmulateADDImmThumb,
13454 "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13455 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13456 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
13457 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13458 &EmulateInstructionARM::EmulateADDImmThumb,
13459 "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13460 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13461 &EmulateInstructionARM::EmulateADDImmThumb,
13462 "addw<c> <Rd>,<Rn>,#<imm12>"},
13463 // sub (immediate, Thumb)
13464 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13465 &EmulateInstructionARM::EmulateSUBImmThumb,
13466 "subs|sub<c> <Rd>, <Rn> #imm3"},
13467 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13468 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13469 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13470 &EmulateInstructionARM::EmulateSUBImmThumb,
13471 "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13472 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13473 &EmulateInstructionARM::EmulateSUBImmThumb,
13474 "subw<c> <Rd>, <Rn>, #imm12"},
13475 // sub (sp minus immediate)
13476 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13477 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13478 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13479 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13481 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13482 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13483 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13484 &EmulateInstructionARM::EmulateSUBReg,
13485 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13487 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13488 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13490 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13491 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13493 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13494 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13496 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13497 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13498 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13499 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13501 // move from high register to high register
13502 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13503 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13504 // move from low register to low register
13505 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13506 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13507 // mov{s}<c>.w <Rd>, <Rm>
13508 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13509 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13511 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13512 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13513 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13514 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13515 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13516 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13518 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13519 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13521 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13522 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13523 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13524 &EmulateInstructionARM::EmulateMVNReg,
13525 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13527 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13528 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13530 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13531 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13532 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13533 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13535 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13536 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13537 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13538 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13539 // cmp (register) (Rn and Rm both from r0-r7)
13540 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13541 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13542 // cmp (register) (Rn and Rm not both from r0-r7)
13543 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13544 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13545 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13546 &EmulateInstructionARM::EmulateCMPReg,
13547 "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13549 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13550 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13551 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13552 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13554 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13555 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13556 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13557 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13559 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13560 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13561 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13562 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13564 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13565 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13566 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13567 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13569 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13570 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13571 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13572 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13574 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13575 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13576 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13577 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13578 // rrx is a special case encoding of ror (immediate)
13579 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13580 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13582 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13583 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13585 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13586 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13587 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13588 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13590 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13591 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13593 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13594 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13596 // subs pc, lr and related instructions
13597 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13598 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13600 //----------------------------------------------------------------------
13601 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13602 // LDM.. Instructions in this table;
13603 // otherwise the wrong instructions will be selected.
13604 //----------------------------------------------------------------------
13606 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13607 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13608 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13609 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13611 //----------------------------------------------------------------------
13612 // Load instructions
13613 //----------------------------------------------------------------------
13614 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13615 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13616 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13617 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13618 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13619 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13620 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13621 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13622 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13623 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13624 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13625 &EmulateInstructionARM::EmulateLDRRtRnImm,
13626 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13627 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13628 &EmulateInstructionARM::EmulateLDRRtRnImm,
13629 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13630 // Thumb2 PC-relative load into register
13631 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13632 &EmulateInstructionARM::EmulateLDRRtPCRelative,
13633 "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13634 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13635 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13636 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13637 &EmulateInstructionARM::EmulateLDRRegister,
13638 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13639 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13640 &EmulateInstructionARM::EmulateLDRBImmediate,
13641 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13642 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13643 &EmulateInstructionARM::EmulateLDRBImmediate,
13644 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13645 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13646 &EmulateInstructionARM::EmulateLDRBImmediate,
13647 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13648 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13649 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13650 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13651 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13652 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13653 &EmulateInstructionARM::EmulateLDRBRegister,
13654 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13655 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13656 &EmulateInstructionARM::EmulateLDRHImmediate,
13657 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13658 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13659 &EmulateInstructionARM::EmulateLDRHImmediate,
13660 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13661 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13662 &EmulateInstructionARM::EmulateLDRHImmediate,
13663 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13664 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13665 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13666 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13667 &EmulateInstructionARM::EmulateLDRHRegister,
13668 "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13669 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13670 &EmulateInstructionARM::EmulateLDRHRegister,
13671 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13672 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13673 &EmulateInstructionARM::EmulateLDRSBImmediate,
13674 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13675 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13676 &EmulateInstructionARM::EmulateLDRSBImmediate,
13677 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13678 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13679 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13680 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13681 &EmulateInstructionARM::EmulateLDRSBRegister,
13682 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13683 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13684 &EmulateInstructionARM::EmulateLDRSBRegister,
13685 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13686 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13687 &EmulateInstructionARM::EmulateLDRSHImmediate,
13688 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13689 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13690 &EmulateInstructionARM::EmulateLDRSHImmediate,
13691 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13692 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13693 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13694 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13695 &EmulateInstructionARM::EmulateLDRSHRegister,
13696 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13697 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13698 &EmulateInstructionARM::EmulateLDRSHRegister,
13699 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13700 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13701 &EmulateInstructionARM::EmulateLDRDImmediate,
13702 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13703 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13704 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13705 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13706 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13707 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13708 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13709 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13710 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13711 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13712 &EmulateInstructionARM::EmulateVLD1Multiple,
13713 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13714 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13715 &EmulateInstructionARM::EmulateVLD1Single,
13716 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13717 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13718 &EmulateInstructionARM::EmulateVLD1SingleAll,
13719 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13721 //----------------------------------------------------------------------
13722 // Store instructions
13723 //----------------------------------------------------------------------
13724 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13725 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13726 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13727 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13728 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13729 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13730 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13731 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13732 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13733 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13734 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13735 &EmulateInstructionARM::EmulateSTRThumb,
13736 "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13737 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13738 &EmulateInstructionARM::EmulateSTRThumb,
13739 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13740 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13741 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13742 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13743 &EmulateInstructionARM::EmulateSTRRegister,
13744 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13745 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13746 &EmulateInstructionARM::EmulateSTRBThumb,
13747 "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13748 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13749 &EmulateInstructionARM::EmulateSTRBThumb,
13750 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13751 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13752 &EmulateInstructionARM::EmulateSTRBThumb,
13753 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13754 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13755 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13756 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13757 &EmulateInstructionARM::EmulateSTRHRegister,
13758 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13759 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13760 &EmulateInstructionARM::EmulateSTREX,
13761 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13762 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13763 &EmulateInstructionARM::EmulateSTRDImm,
13764 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13765 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13766 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13767 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13768 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13769 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13770 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13771 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13772 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13773 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13774 &EmulateInstructionARM::EmulateVST1Multiple,
13775 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13776 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13777 &EmulateInstructionARM::EmulateVST1Single,
13778 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13780 //----------------------------------------------------------------------
13781 // Other instructions
13782 //----------------------------------------------------------------------
13783 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13784 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13785 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13786 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13787 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13788 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13789 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13790 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13791 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13792 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13793 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13794 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13795 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13796 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13797 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13798 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13801 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
13802 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13803 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13804 (g_thumb_opcodes[i].variants & arm_isa) != 0)
13805 return &g_thumb_opcodes[i];
13810 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13813 const char *arch_cstr = arch.GetArchitectureName();
13815 if (0 == ::strcasecmp(arch_cstr, "armv4t"))
13816 m_arm_isa = ARMv4T;
13817 else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))
13818 m_arm_isa = ARMv5TEJ;
13819 else if (0 == ::strcasecmp(arch_cstr, "armv5te"))
13820 m_arm_isa = ARMv5TE;
13821 else if (0 == ::strcasecmp(arch_cstr, "armv5t"))
13822 m_arm_isa = ARMv5T;
13823 else if (0 == ::strcasecmp(arch_cstr, "armv6k"))
13824 m_arm_isa = ARMv6K;
13825 else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))
13826 m_arm_isa = ARMv6T2;
13827 else if (0 == ::strcasecmp(arch_cstr, "armv7s"))
13828 m_arm_isa = ARMv7S;
13829 else if (0 == ::strcasecmp(arch_cstr, "arm"))
13830 m_arm_isa = ARMvAll;
13831 else if (0 == ::strcasecmp(arch_cstr, "thumb"))
13832 m_arm_isa = ARMvAll;
13833 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5))
13835 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5))
13837 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5))
13839 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5))
13842 return m_arm_isa != 0;
13845 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13846 const Address &inst_addr,
13848 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13849 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13850 m_arch.IsAlwaysThumbInstructions())
13851 m_opcode_mode = eModeThumb;
13853 AddressClass addr_class = inst_addr.GetAddressClass();
13855 if ((addr_class == AddressClass::eCode) ||
13856 (addr_class == AddressClass::eUnknown))
13857 m_opcode_mode = eModeARM;
13858 else if (addr_class == AddressClass::eCodeAlternateISA)
13859 m_opcode_mode = eModeThumb;
13863 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13864 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13866 m_opcode_cpsr = CPSR_MODE_USR;
13872 bool EmulateInstructionARM::ReadInstruction() {
13873 bool success = false;
13874 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13875 LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13878 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13879 LLDB_INVALID_ADDRESS, &success);
13881 Context read_inst_context;
13882 read_inst_context.type = eContextReadOpcode;
13883 read_inst_context.SetNoArgs();
13885 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13886 m_opcode_mode = eModeThumb;
13887 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13890 if ((thumb_opcode & 0xe000) != 0xe000 ||
13891 ((thumb_opcode & 0x1800u) == 0)) {
13892 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13894 m_opcode.SetOpcode32(
13895 (thumb_opcode << 16) |
13896 MemARead(read_inst_context, pc + 2, 2, 0, &success),
13901 m_opcode_mode = eModeARM;
13902 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13906 if (!m_ignore_conditions) {
13907 // If we are not ignoreing the conditions then init the it session from
13908 // the current value of cpsr.
13909 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
13910 Bits32(m_opcode_cpsr, 26, 25);
13912 m_it_session.InitIT(it);
13917 m_opcode_mode = eModeInvalid;
13918 m_addr = LLDB_INVALID_ADDRESS;
13923 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
13925 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
13926 // If we are ignoring conditions, then always return true. this allows us to
13927 // iterate over disassembly code and still emulate an instruction even if we
13928 // don't have all the right bits set in the CPSR register...
13929 if (m_ignore_conditions)
13932 const uint32_t cond = CurrentCond(opcode);
13933 if (cond == UINT32_MAX)
13936 bool result = false;
13937 switch (UnsignedBits(cond, 3, 1)) {
13939 if (m_opcode_cpsr == 0)
13942 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13945 if (m_opcode_cpsr == 0)
13948 result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13951 if (m_opcode_cpsr == 0)
13954 result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13957 if (m_opcode_cpsr == 0)
13960 result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13963 if (m_opcode_cpsr == 0)
13966 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
13967 ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13970 if (m_opcode_cpsr == 0)
13973 bool n = (m_opcode_cpsr & MASK_CPSR_N);
13974 bool v = (m_opcode_cpsr & MASK_CPSR_V);
13979 if (m_opcode_cpsr == 0)
13982 bool n = (m_opcode_cpsr & MASK_CPSR_N);
13983 bool v = (m_opcode_cpsr & MASK_CPSR_V);
13984 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13988 // Always execute (cond == 0b1110, or the special 0b1111 which gives
13989 // opcodes different meanings, but always means execution happens.
13998 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
13999 switch (m_opcode_mode) {
14004 return UnsignedBits(opcode, 31, 28);
14007 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
14008 // 'cond' field of the encoding.
14010 const uint32_t byte_size = m_opcode.GetByteSize();
14011 if (byte_size == 2) {
14012 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
14013 return Bits32(opcode, 11, 8);
14014 } else if (byte_size == 4) {
14015 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
14016 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
14017 return Bits32(opcode, 25, 22);
14020 // We have an invalid thumb instruction, let's bail out.
14023 return m_it_session.GetCond();
14026 return UINT32_MAX; // Return invalid value
14029 bool EmulateInstructionARM::InITBlock() {
14030 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
14033 bool EmulateInstructionARM::LastInITBlock() {
14034 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
14037 bool EmulateInstructionARM::BadMode(uint32_t mode) {
14041 return false; // '10000'
14043 return false; // '10001'
14045 return false; // '10010'
14047 return false; // '10011'
14049 return false; // '10110'
14051 return false; // '10111'
14053 return false; // '11011'
14055 return false; // '11111'
14062 bool EmulateInstructionARM::CurrentModeIsPrivileged() {
14063 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
14074 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
14075 bool affect_execstate) {
14076 bool privileged = CurrentModeIsPrivileged();
14078 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
14080 if (BitIsSet(bytemask, 3)) {
14081 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
14082 if (affect_execstate)
14083 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
14086 if (BitIsSet(bytemask, 2)) {
14087 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
14090 if (BitIsSet(bytemask, 1)) {
14091 if (affect_execstate)
14092 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
14093 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
14095 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
14098 if (BitIsSet(bytemask, 0)) {
14100 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
14101 if (affect_execstate)
14102 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
14104 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
14107 m_opcode_cpsr = tmp_cpsr;
14110 bool EmulateInstructionARM::BranchWritePC(const Context &context,
14114 // Check the current instruction set.
14115 if (CurrentInstrSet() == eModeARM)
14116 target = addr & 0xfffffffc;
14118 target = addr & 0xfffffffe;
14120 return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14121 LLDB_REGNUM_GENERIC_PC, target);
14124 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
14125 // inspecting addr.
14126 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
14128 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
14129 // we want to record it and issue a WriteRegister callback so the clients can
14130 // track the mode changes accordingly.
14131 bool cpsr_changed = false;
14133 if (BitIsSet(addr, 0)) {
14134 if (CurrentInstrSet() != eModeThumb) {
14135 SelectInstrSet(eModeThumb);
14136 cpsr_changed = true;
14138 target = addr & 0xfffffffe;
14139 context.SetISA(eModeThumb);
14140 } else if (BitIsClear(addr, 1)) {
14141 if (CurrentInstrSet() != eModeARM) {
14142 SelectInstrSet(eModeARM);
14143 cpsr_changed = true;
14145 target = addr & 0xfffffffc;
14146 context.SetISA(eModeARM);
14148 return false; // address<1:0> == '10' => UNPREDICTABLE
14150 if (cpsr_changed) {
14151 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14152 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14155 return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14156 LLDB_REGNUM_GENERIC_PC, target);
14159 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14161 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
14162 if (ArchVersion() >= ARMv5T)
14163 return BXWritePC(context, addr);
14165 return BranchWritePC((const Context)context, addr);
14168 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14169 // versions and current instruction set.
14170 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
14171 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
14172 return BXWritePC(context, addr);
14174 return BranchWritePC((const Context)context, addr);
14177 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
14178 return m_opcode_mode;
14181 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next
14182 // ReadInstruction() is performed. This function has a side effect of updating
14183 // the m_new_inst_cpsr member variable if necessary.
14184 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
14185 m_new_inst_cpsr = m_opcode_cpsr;
14186 switch (arm_or_thumb) {
14190 // Clear the T bit.
14191 m_new_inst_cpsr &= ~MASK_CPSR_T;
14195 m_new_inst_cpsr |= MASK_CPSR_T;
14201 // This function returns TRUE if the processor currently provides support for
14202 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
14203 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
14204 bool EmulateInstructionARM::UnalignedSupport() {
14205 return (ArchVersion() >= ARMv7);
14208 // The main addition and subtraction instructions can produce status
14209 // information about both unsigned carry and signed overflow conditions. This
14210 // status information can be used to synthesize multi-word additions and
14212 EmulateInstructionARM::AddWithCarryResult
14213 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
14218 uint64_t unsigned_sum = x + y + carry_in;
14219 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14221 result = UnsignedBits(unsigned_sum, 31, 0);
14222 // carry_out = (result == unsigned_sum ? 0 : 1);
14223 overflow = ((int32_t)result == signed_sum ? 0 : 1);
14226 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14228 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14230 AddWithCarryResult res = {result, carry_out, overflow};
14234 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
14235 lldb::RegisterKind reg_kind;
14239 reg_kind = eRegisterKindGeneric;
14240 reg_num = LLDB_REGNUM_GENERIC_SP;
14243 reg_kind = eRegisterKindGeneric;
14244 reg_num = LLDB_REGNUM_GENERIC_RA;
14247 reg_kind = eRegisterKindGeneric;
14248 reg_num = LLDB_REGNUM_GENERIC_PC;
14251 if (num < SP_REG) {
14252 reg_kind = eRegisterKindDWARF;
14253 reg_num = dwarf_r0 + num;
14255 // assert(0 && "Invalid register number");
14262 // Read our register.
14263 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
14265 // When executing an ARM instruction , PC reads as the address of the current
14266 // instruction plus 8. When executing a Thumb instruction , PC reads as the
14267 // address of the current instruction plus 4.
14269 if (CurrentInstrSet() == eModeARM)
14278 // Write the result to the ARM core register Rd, and optionally update the
14279 // condition flags based on the result.
14281 // This helper method tries to encapsulate the following pseudocode from the
14282 // ARM Architecture Reference Manual:
14284 // if d == 15 then // Can only occur for encoding A1
14285 // ALUWritePC(result); // setflags is always FALSE here
14288 // if setflags then
14289 // APSR.N = result<31>;
14290 // APSR.Z = IsZeroBit(result);
14292 // // APSR.V unchanged
14294 // In the above case, the API client does not pass in the overflow arg, which
14295 // defaults to ~0u.
14296 bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
14297 Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
14298 const uint32_t carry, const uint32_t overflow) {
14300 if (!ALUWritePC(context, result))
14303 lldb::RegisterKind reg_kind;
14307 reg_kind = eRegisterKindGeneric;
14308 reg_num = LLDB_REGNUM_GENERIC_SP;
14311 reg_kind = eRegisterKindGeneric;
14312 reg_num = LLDB_REGNUM_GENERIC_RA;
14315 reg_kind = eRegisterKindDWARF;
14316 reg_num = dwarf_r0 + Rd;
14318 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
14321 return WriteFlags(context, result, carry, overflow);
14326 // This helper method tries to encapsulate the following pseudocode from the
14327 // ARM Architecture Reference Manual:
14329 // APSR.N = result<31>;
14330 // APSR.Z = IsZeroBit(result);
14332 // APSR.V = overflow
14334 // Default arguments can be specified for carry and overflow parameters, which
14335 // means not to update the respective flags.
14336 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
14337 const uint32_t carry,
14338 const uint32_t overflow) {
14339 m_new_inst_cpsr = m_opcode_cpsr;
14340 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
14341 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
14343 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
14344 if (overflow != ~0u)
14345 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
14346 if (m_new_inst_cpsr != m_opcode_cpsr) {
14347 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14348 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14354 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
14355 ARMOpcode *opcode_data = NULL;
14357 if (m_opcode_mode == eModeThumb)
14359 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14360 else if (m_opcode_mode == eModeARM)
14361 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14363 const bool auto_advance_pc =
14364 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14365 m_ignore_conditions =
14366 evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14368 bool success = false;
14369 if (m_opcode_cpsr == 0 || !m_ignore_conditions) {
14371 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
14374 // Only return false if we are unable to read the CPSR if we care about
14376 if (!success && !m_ignore_conditions)
14379 uint32_t orig_pc_value = 0;
14380 if (auto_advance_pc) {
14382 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14387 // Call the Emulate... function if we managed to decode the opcode.
14389 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
14390 opcode_data->encoding);
14395 // Advance the ITSTATE bits to their values for the next instruction if we
14396 // haven't just executed an IT instruction what initialized it.
14397 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
14398 (opcode_data == nullptr ||
14399 opcode_data->callback != &EmulateInstructionARM::EmulateIT))
14400 m_it_session.ITAdvance();
14402 if (auto_advance_pc) {
14403 uint32_t after_pc_value =
14404 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14408 if (auto_advance_pc && (after_pc_value == orig_pc_value)) {
14409 after_pc_value += m_opcode.GetByteSize();
14411 EmulateInstruction::Context context;
14412 context.type = eContextAdvancePC;
14413 context.SetNoArgs();
14414 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
14422 EmulateInstruction::InstructionCondition
14423 EmulateInstructionARM::GetInstructionCondition() {
14424 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
14425 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
14426 return EmulateInstruction::UnconditionalCondition;
14430 bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch,
14431 OptionValueDictionary *test_data) {
14433 out_stream->Printf("TestEmulation: Missing test data.\n");
14437 static ConstString opcode_key("opcode");
14438 static ConstString before_key("before_state");
14439 static ConstString after_key("after_state");
14441 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
14443 uint32_t test_opcode;
14444 if ((value_sp.get() == NULL) ||
14445 (value_sp->GetType() != OptionValue::eTypeUInt64)) {
14446 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n");
14449 test_opcode = value_sp->GetUInt64Value();
14451 if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
14452 arch.IsAlwaysThumbInstructions()) {
14453 m_opcode_mode = eModeThumb;
14454 if (test_opcode < 0x10000)
14455 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14457 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14458 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14459 m_opcode_mode = eModeARM;
14460 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14462 out_stream->Printf("TestEmulation: Invalid arch.\n");
14466 EmulationStateARM before_state;
14467 EmulationStateARM after_state;
14469 value_sp = test_data->GetValueForKey(before_key);
14470 if ((value_sp.get() == NULL) ||
14471 (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14472 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n");
14476 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14477 if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14478 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n");
14482 value_sp = test_data->GetValueForKey(after_key);
14483 if ((value_sp.get() == NULL) ||
14484 (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14485 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n");
14489 state_dictionary = value_sp->GetAsDictionary();
14490 if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14491 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n");
14495 SetBaton((void *)&before_state);
14496 SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14497 &EmulationStateARM::WritePseudoMemory,
14498 &EmulationStateARM::ReadPseudoRegister,
14499 &EmulationStateARM::WritePseudoRegister);
14501 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14503 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n");
14507 success = before_state.CompareState(after_state);
14509 out_stream->Printf(
14510 "TestEmulation: 'before' and 'after' states do not match.\n");
14517 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14519 // if (reg_kind == eRegisterKindGeneric)
14521 // switch (reg_num)
14523 // case LLDB_REGNUM_GENERIC_PC: return "pc";
14524 // case LLDB_REGNUM_GENERIC_SP: return "sp";
14525 // case LLDB_REGNUM_GENERIC_FP: return "fp";
14526 // case LLDB_REGNUM_GENERIC_RA: return "lr";
14527 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14528 // default: return NULL;
14531 // else if (reg_kind == eRegisterKindDWARF)
14533 // return GetARMDWARFRegisterName (reg_num);
14538 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14539 unwind_plan.Clear();
14540 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14542 UnwindPlan::RowSP row(new UnwindPlan::Row);
14544 // Our previous Call Frame Address is the stack pointer
14545 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14547 unwind_plan.AppendRow(row);
14548 unwind_plan.SetSourceName("EmulateInstructionARM");
14549 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14550 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14551 unwind_plan.SetReturnAddressRegister(dwarf_lr);