From 60b571e49a90d38697b3aca23020d9da42fc7d7f Mon Sep 17 00:00:00 2001 From: dim Date: Sun, 2 Apr 2017 17:24:58 +0000 Subject: Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release: MFC r309142 (by emaste): Add WITH_LLD_AS_LD build knob If set it installs LLD as /usr/bin/ld. LLD (as of version 3.9) is not capable of linking the world and kernel, but can self-host and link many substantial applications. GNU ld continues to be used for the world and kernel build, regardless of how this knob is set. It is on by default for arm64, and off for all other CPU architectures. Sponsored by: The FreeBSD Foundation MFC r310840: Reapply 310775, now it also builds correctly if lldb is disabled: Move llvm-objdump from CLANG_EXTRAS to installed by default We currently install three tools from binutils 2.17.50: as, ld, and objdump. Work is underway to migrate to a permissively-licensed tool-chain, with one goal being the retirement of binutils 2.17.50. LLVM's llvm-objdump is intended to be compatible with GNU objdump although it is currently missing some options and may have formatting differences. Enable it by default for testing and further investigation. It may later be changed to install as /usr/bin/objdump, it becomes a fully viable replacement. Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D8879 MFC r312855 (by emaste): Rename LLD_AS_LD to LLD_IS_LD, for consistency with CLANG_IS_CC Reported by: Dan McGregor MFC r313559 | glebius | 2017-02-10 18:34:48 +0100 (Fri, 10 Feb 2017) | 5 lines Don't check struct rtentry on FreeBSD, it is an internal kernel structure. On other systems it may be API structure for SIOCADDRT/SIOCDELRT. Reviewed by: emaste, dim MFC r314152 (by jkim): Remove an assembler flag, which is redundant since r309124. The upstream took care of it by introducing a macro NO_EXEC_STACK_DIRECTIVE. http://llvm.org/viewvc/llvm-project?rev=273500&view=rev Reviewed by: dim MFC r314564: Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 (branches/release_40 296509). The release will follow soon. Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11 support to build; see UPDATING for more information. Also note that as of 4.0.0, lld should be able to link the base system on amd64 and aarch64. See the WITH_LLD_IS_LLD setting in src.conf(5). Though please be aware that this is work in progress. Release notes for llvm, clang and lld will be available here: Thanks to Ed Maste, Jan Beich, Antoine Brodin and Eric Fiselier for their help. Relnotes: yes Exp-run: antoine PR: 215969, 216008 MFC r314708: For now, revert r287232 from upstream llvm trunk (by Daniil Fukalov): [SCEV] limit recursion depth of CompareSCEVComplexity Summary: CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled loop) and runs almost infinite time. Added cache of "equal" SCEV pairs to earlier cutoff of further estimation. Recursion depth limit was also introduced as a parameter. Reviewers: sanjoy Subscribers: mzolotukhin, tstellarAMD, llvm-commits Differential Revision: https://reviews.llvm.org/D26389 This commit is the cause of excessive compile times on skein_block.c (and possibly other files) during kernel builds on amd64. We never saw the problematic behavior described in this upstream commit, so for now it is better to revert it. An upstream bug has been filed here: https://bugs.llvm.org/show_bug.cgi?id=32142 Reported by: mjg MFC r314795: Reapply r287232 from upstream llvm trunk (by Daniil Fukalov): [SCEV] limit recursion depth of CompareSCEVComplexity Summary: CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled loop) and runs almost infinite time. Added cache of "equal" SCEV pairs to earlier cutoff of further estimation. Recursion depth limit was also introduced as a parameter. Reviewers: sanjoy Subscribers: mzolotukhin, tstellarAMD, llvm-commits Differential Revision: https://reviews.llvm.org/D26389 Pull in r296992 from upstream llvm trunk (by Sanjoy Das): [SCEV] Decrease the recursion threshold for CompareValueComplexity Fixes PR32142. r287232 accidentally increased the recursion threshold for CompareValueComplexity from 2 to 32. This change reverses that change by introducing a separate flag for CompareValueComplexity's threshold. The latter revision fixes the excessive compile times for skein_block.c. MFC r314907 | mmel | 2017-03-08 12:40:27 +0100 (Wed, 08 Mar 2017) | 7 lines Unbreak ARMv6 world. The new compiler_rt library imported with clang 4.0.0 have several fatal issues (non-functional __udivsi3 for example) with ARM specific instrict functions. As temporary workaround, until upstream solve these problems, disable all thumb[1][2] related feature. MFC r315016: Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release. We were already very close to the last release candidate, so this is a pretty minor update. Relnotes: yes MFC r316005: Revert r314907, and pull in r298713 from upstream compiler-rt trunk (by Weiming Zhao): builtins: Select correct code fragments when compiling for Thumb1/Thum2/ARM ISA. Summary: Value of __ARM_ARCH_ISA_THUMB isn't based on the actual compilation mode (-mthumb, -marm), it reflect's capability of given CPU. Due to this: - use __tbumb__ and __thumb2__ insteand of __ARM_ARCH_ISA_THUMB - use '.thumb' directive consistently in all affected files - decorate all thumb functions using DEFINE_COMPILERRT_THUMB_FUNCTION() --------- Note: This patch doesn't fix broken Thumb1 variant of __udivsi3 ! Reviewers: weimingz, rengolin, compnerd Subscribers: aemerson, dim Differential Revision: https://reviews.llvm.org/D30938 Discussed with: mmel --- .../Instruction/ARM/EmulateInstructionARM.cpp | 22872 ++++++++++--------- 1 file changed, 11590 insertions(+), 11282 deletions(-) (limited to 'contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp') diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index 884078b..99caca9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -11,11 +11,12 @@ #include "EmulateInstructionARM.h" #include "EmulationStateARM.h" -#include "lldb/Core/ArchSpec.h" #include "lldb/Core/Address.h" +#include "lldb/Core/ArchSpec.h" #include "lldb/Core/ConstString.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Stream.h" +#include "lldb/Host/PosixApi.h" #include "lldb/Interpreter/OptionValueArray.h" #include "lldb/Interpreter/OptionValueDictionary.h" #include "lldb/Symbol/UnwindPlan.h" @@ -45,121 +46,113 @@ using namespace lldb_private; // A8.6.50 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. -static uint32_t -CountITSize (uint32_t ITMask) { - // First count the trailing zeros of the IT mask. - uint32_t TZ = llvm::countTrailingZeros(ITMask); - if (TZ > 3) - { +static uint32_t CountITSize(uint32_t ITMask) { + // First count the trailing zeros of the IT mask. + uint32_t TZ = llvm::countTrailingZeros(ITMask); + if (TZ > 3) { #ifdef LLDB_CONFIGURATION_DEBUG - printf("Encoding error: IT Mask '0000'\n"); + printf("Encoding error: IT Mask '0000'\n"); #endif - return 0; - } - return (4 - TZ); + return 0; + } + return (4 - TZ); } // Init ITState. Note that at least one bit is always 1 in mask. -bool ITSession::InitIT(uint32_t bits7_0) -{ - ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); - if (ITCounter == 0) - return false; +bool ITSession::InitIT(uint32_t bits7_0) { + ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); + if (ITCounter == 0) + return false; - // A8.6.50 IT - unsigned short FirstCond = Bits32(bits7_0, 7, 4); - if (FirstCond == 0xF) - { + // A8.6.50 IT + unsigned short FirstCond = Bits32(bits7_0, 7, 4); + if (FirstCond == 0xF) { #ifdef LLDB_CONFIGURATION_DEBUG - printf("Encoding error: IT FirstCond '1111'\n"); + printf("Encoding error: IT FirstCond '1111'\n"); #endif - return false; - } - if (FirstCond == 0xE && ITCounter != 1) - { + return false; + } + if (FirstCond == 0xE && ITCounter != 1) { #ifdef LLDB_CONFIGURATION_DEBUG - printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); + printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); #endif - return false; - } + return false; + } - ITState = bits7_0; - return true; + ITState = bits7_0; + return true; } // Update ITState if necessary. -void ITSession::ITAdvance() -{ - //assert(ITCounter); - --ITCounter; - if (ITCounter == 0) - ITState = 0; - else - { - unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; - SetBits32(ITState, 4, 0, NewITState4_0); - } +void ITSession::ITAdvance() { + // assert(ITCounter); + --ITCounter; + if (ITCounter == 0) + ITState = 0; + else { + unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; + SetBits32(ITState, 4, 0, NewITState4_0); + } } // Return true if we're inside an IT Block. -bool ITSession::InITBlock() -{ - return ITCounter != 0; -} +bool ITSession::InITBlock() { return ITCounter != 0; } // Return true if we're the last instruction inside an IT Block. -bool ITSession::LastInITBlock() -{ - return ITCounter == 1; -} +bool ITSession::LastInITBlock() { return ITCounter == 1; } // Get condition bits for the current thumb instruction. -uint32_t ITSession::GetCond() -{ - if (InITBlock()) - return Bits32(ITState, 7, 4); - else - return COND_AL; +uint32_t ITSession::GetCond() { + if (InITBlock()) + return Bits32(ITState, 7, 4); + else + return COND_AL; } // ARM constants used during decoding -#define REG_RD 0 -#define LDM_REGLIST 1 -#define SP_REG 13 -#define LR_REG 14 -#define PC_REG 15 -#define PC_REGLIST_BIT 0x8000 - -#define ARMv4 (1u << 0) -#define ARMv4T (1u << 1) -#define ARMv5T (1u << 2) -#define ARMv5TE (1u << 3) -#define ARMv5TEJ (1u << 4) -#define ARMv6 (1u << 5) -#define ARMv6K (1u << 6) -#define ARMv6T2 (1u << 7) -#define ARMv7 (1u << 8) -#define ARMv7S (1u << 9) -#define ARMv8 (1u << 10) -#define ARMvAll (0xffffffffu) - -#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) -#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) -#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) -#define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) -#define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) -#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8) -#define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8) - -#define No_VFP 0 -#define VFPv1 (1u << 1) -#define VFPv2 (1u << 2) -#define VFPv3 (1u << 3) +#define REG_RD 0 +#define LDM_REGLIST 1 +#define SP_REG 13 +#define LR_REG 14 +#define PC_REG 15 +#define PC_REGLIST_BIT 0x8000 + +#define ARMv4 (1u << 0) +#define ARMv4T (1u << 1) +#define ARMv5T (1u << 2) +#define ARMv5TE (1u << 3) +#define ARMv5TEJ (1u << 4) +#define ARMv6 (1u << 5) +#define ARMv6K (1u << 6) +#define ARMv6T2 (1u << 7) +#define ARMv7 (1u << 8) +#define ARMv7S (1u << 9) +#define ARMv8 (1u << 10) +#define ARMvAll (0xffffffffu) + +#define ARMV4T_ABOVE \ + (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \ + ARMv7S | ARMv8) +#define ARMV5_ABOVE \ + (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \ + ARMv8) +#define ARMV5TE_ABOVE \ + (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) +#define ARMV5J_ABOVE \ + (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) +#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) +#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8) +#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8) + +#define No_VFP 0 +#define VFPv1 (1u << 1) +#define VFPv2 (1u << 2) +#define VFPv3 (1u << 3) #define AdvancedSIMD (1u << 4) #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) -#define VFPv2v3 (VFPv2 | VFPv3) +#define VFPv2v3 (VFPv2 | VFPv3) //---------------------------------------------------------------------- // @@ -167,200 +160,194 @@ uint32_t ITSession::GetCond() // //---------------------------------------------------------------------- -void -EmulateInstructionARM::Initialize () -{ - PluginManager::RegisterPlugin (GetPluginNameStatic (), - GetPluginDescriptionStatic (), - CreateInstance); +void EmulateInstructionARM::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); } -void -EmulateInstructionARM::Terminate () -{ - PluginManager::UnregisterPlugin (CreateInstance); +void EmulateInstructionARM::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); } -ConstString -EmulateInstructionARM::GetPluginNameStatic () -{ - static ConstString g_name("arm"); - return g_name; +ConstString EmulateInstructionARM::GetPluginNameStatic() { + static ConstString g_name("arm"); + return g_name; } -const char * -EmulateInstructionARM::GetPluginDescriptionStatic () -{ - return "Emulate instructions for the ARM architecture."; +const char *EmulateInstructionARM::GetPluginDescriptionStatic() { + return "Emulate instructions for the ARM architecture."; } EmulateInstruction * -EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) -{ - if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(inst_type)) - { - if (arch.GetTriple().getArch() == llvm::Triple::arm) - { - std::unique_ptr emulate_insn_ap (new EmulateInstructionARM (arch)); - - if (emulate_insn_ap.get()) - return emulate_insn_ap.release(); - } - else if (arch.GetTriple().getArch() == llvm::Triple::thumb) - { - std::unique_ptr emulate_insn_ap (new EmulateInstructionARM (arch)); - - if (emulate_insn_ap.get()) - return emulate_insn_ap.release(); - } +EmulateInstructionARM::CreateInstance(const ArchSpec &arch, + InstructionType inst_type) { + if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( + inst_type)) { + if (arch.GetTriple().getArch() == llvm::Triple::arm) { + std::unique_ptr emulate_insn_ap( + new EmulateInstructionARM(arch)); + + if (emulate_insn_ap.get()) + return emulate_insn_ap.release(); + } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { + std::unique_ptr emulate_insn_ap( + new EmulateInstructionARM(arch)); + + if (emulate_insn_ap.get()) + return emulate_insn_ap.release(); } - - return NULL; -} + } -bool -EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) -{ - if (arch.GetTriple().getArch () == llvm::Triple::arm) - return true; - else if (arch.GetTriple().getArch () == llvm::Triple::thumb) - return true; - - return false; + return NULL; } - -// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. -bool -EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) -{ - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextWriteMemoryRandomBits; - context.SetNoArgs (); - uint32_t random_data = rand (); - const uint32_t addr_byte_size = GetAddressByteSize(); - - if (!MemAWrite (context, address, random_data, addr_byte_size)) - return false; - +bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { + if (arch.GetTriple().getArch() == llvm::Triple::arm) + return true; + else if (arch.GetTriple().getArch() == llvm::Triple::thumb) return true; + + return false; } -// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. -bool -EmulateInstructionARM::WriteBits32Unknown (int n) -{ - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextWriteRegisterRandomBits; - context.SetNoArgs (); +// Write "bits (32) UNKNOWN" to memory address "address". Helper function for +// many ARM instructions. +bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextWriteMemoryRandomBits; + context.SetNoArgs(); - bool success; - uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) - return false; - - return true; -} + uint32_t random_data = rand(); + const uint32_t addr_byte_size = GetAddressByteSize(); -bool -EmulateInstructionARM::GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo ®_info) -{ - if (reg_kind == eRegisterKindGeneric) - { - switch (reg_num) - { - case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; - case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; - case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; - case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; - case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; - default: return false; - } - } - - if (reg_kind == eRegisterKindDWARF) - return GetARMDWARFRegisterInfo(reg_num, reg_info); + if (!MemAWrite(context, address, random_data, addr_byte_size)) return false; + + return true; } -uint32_t -EmulateInstructionARM::GetFramePointerRegisterNumber () const -{ - if (m_arch.GetTriple().isAndroid()) - return LLDB_INVALID_REGNUM; // Don't use frame pointer on android - bool is_apple = false; - if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) - is_apple = true; - switch (m_arch.GetTriple().getOS()) - { - case llvm::Triple::Darwin: - case llvm::Triple::MacOSX: - case llvm::Triple::IOS: - case llvm::Triple::TvOS: - case llvm::Triple::WatchOS: - is_apple = true; - break; - default: - break; +// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM +// instructions. +bool EmulateInstructionARM::WriteBits32Unknown(int n) { + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextWriteRegisterRandomBits; + context.SetNoArgs(); + + bool success; + uint32_t data = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + + if (!success) + return false; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) + return false; + + return true; +} + +bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, + uint32_t reg_num, + RegisterInfo ®_info) { + if (reg_kind == eRegisterKindGeneric) { + switch (reg_num) { + case LLDB_REGNUM_GENERIC_PC: + reg_kind = eRegisterKindDWARF; + reg_num = dwarf_pc; + break; + case LLDB_REGNUM_GENERIC_SP: + reg_kind = eRegisterKindDWARF; + reg_num = dwarf_sp; + break; + case LLDB_REGNUM_GENERIC_FP: + reg_kind = eRegisterKindDWARF; + reg_num = dwarf_r7; + break; + case LLDB_REGNUM_GENERIC_RA: + reg_kind = eRegisterKindDWARF; + reg_num = dwarf_lr; + break; + case LLDB_REGNUM_GENERIC_FLAGS: + reg_kind = eRegisterKindDWARF; + reg_num = dwarf_cpsr; + break; + default: + return false; } + } + + if (reg_kind == eRegisterKindDWARF) + return GetARMDWARFRegisterInfo(reg_num, reg_info); + return false; +} + +uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { + if (m_arch.GetTriple().isAndroid()) + return LLDB_INVALID_REGNUM; // Don't use frame pointer on android + bool is_apple = false; + if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) + is_apple = true; + switch (m_arch.GetTriple().getOS()) { + case llvm::Triple::Darwin: + case llvm::Triple::MacOSX: + case llvm::Triple::IOS: + case llvm::Triple::TvOS: + case llvm::Triple::WatchOS: + is_apple = true; + break; + default: + break; + } - /* On Apple iOS et al, the frame pointer register is always r7. - * Typically on other ARM systems, thumb code uses r7; arm code uses r11. - */ + /* On Apple iOS et al, the frame pointer register is always r7. + * Typically on other ARM systems, thumb code uses r7; arm code uses r11. + */ - uint32_t fp_regnum = 11; + uint32_t fp_regnum = 11; - if (is_apple) - fp_regnum = 7; + if (is_apple) + fp_regnum = 7; - if (m_opcode_mode == eModeThumb) - fp_regnum = 7; + if (m_opcode_mode == eModeThumb) + fp_regnum = 7; - return fp_regnum; + return fp_regnum; } -uint32_t -EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const -{ - bool is_apple = false; - if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) - is_apple = true; - switch (m_arch.GetTriple().getOS()) - { - case llvm::Triple::Darwin: - case llvm::Triple::MacOSX: - case llvm::Triple::IOS: - is_apple = true; - break; - default: - break; - } +uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { + bool is_apple = false; + if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) + is_apple = true; + switch (m_arch.GetTriple().getOS()) { + case llvm::Triple::Darwin: + case llvm::Triple::MacOSX: + case llvm::Triple::IOS: + is_apple = true; + break; + default: + break; + } - /* On Apple iOS et al, the frame pointer register is always r7. - * Typically on other ARM systems, thumb code uses r7; arm code uses r11. - */ + /* On Apple iOS et al, the frame pointer register is always r7. + * Typically on other ARM systems, thumb code uses r7; arm code uses r11. + */ - uint32_t fp_regnum = dwarf_r11; + uint32_t fp_regnum = dwarf_r11; - if (is_apple) - fp_regnum = dwarf_r7; + if (is_apple) + fp_regnum = dwarf_r7; - if (m_opcode_mode == eModeThumb) - fp_regnum = dwarf_r7; + if (m_opcode_mode == eModeThumb) + fp_regnum = dwarf_r7; - return fp_regnum; + return fp_regnum; } // Push Multiple Registers stores multiple registers to the stack, storing to // consecutive memory locations ending just below the address in SP, and updates // SP to point to the start of the stored data. -bool -EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -388,105 +375,101 @@ EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding enc } #endif - bool success = false; - if (ConditionPassed(opcode)) - { - const uint32_t addr_byte_size = GetAddressByteSize(); - const addr_t sp = ReadCoreReg (SP_REG, &success); - if (!success) - return false; - uint32_t registers = 0; - uint32_t Rt; // the source register - switch (encoding) { - case eEncodingT1: - registers = Bits32(opcode, 7, 0); - // The M bit represents LR. - if (Bit32(opcode, 8)) - registers |= (1u << 14); - // if BitCount(registers) < 1 then UNPREDICTABLE; - if (BitCount(registers) < 1) - return false; - break; - case eEncodingT2: - // Ignore bits 15 & 13. - registers = Bits32(opcode, 15, 0) & ~0xa000; - // if BitCount(registers) < 2 then UNPREDICTABLE; - if (BitCount(registers) < 2) - return false; - break; - case eEncodingT3: - Rt = Bits32(opcode, 15, 12); - // if BadReg(t) then UNPREDICTABLE; - if (BadReg(Rt)) - return false; - registers = (1u << Rt); - break; - case eEncodingA1: - registers = Bits32(opcode, 15, 0); - // Instead of return false, let's handle the following case as well, - // which amounts to pushing one reg onto the full descending stacks. - // if BitCount(register_list) < 2 then SEE STMDB / STMFD; - break; - case eEncodingA2: - Rt = Bits32(opcode, 15, 12); - // if t == 13 then UNPREDICTABLE; - if (Rt == dwarf_sp) - return false; - registers = (1u << Rt); - break; - default: - return false; - } - addr_t sp_offset = addr_byte_size * BitCount (registers); - addr_t addr = sp - sp_offset; - uint32_t i; - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextPushRegisterOnStack; - RegisterInfo reg_info; - RegisterInfo sp_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); - for (i=0; i<15; ++i) - { - if (BitIsSet (registers, i)) - { - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); - context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); - uint32_t reg_value = ReadCoreReg(i, &success); - if (!success) - return false; - if (!MemAWrite (context, addr, reg_value, addr_byte_size)) - return false; - addr += addr_byte_size; - } - } - - if (BitIsSet (registers, 15)) - { - GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); - context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); - const uint32_t pc = ReadCoreReg(PC_REG, &success); - if (!success) - return false; - if (!MemAWrite (context, addr, pc, addr_byte_size)) - return false; - } - - context.type = EmulateInstruction::eContextAdjustStackPointer; - context.SetImmediateSigned (-sp_offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) - return false; + bool success = false; + if (ConditionPassed(opcode)) { + const uint32_t addr_byte_size = GetAddressByteSize(); + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + uint32_t registers = 0; + uint32_t Rt; // the source register + switch (encoding) { + case eEncodingT1: + registers = Bits32(opcode, 7, 0); + // The M bit represents LR. + if (Bit32(opcode, 8)) + registers |= (1u << 14); + // if BitCount(registers) < 1 then UNPREDICTABLE; + if (BitCount(registers) < 1) + return false; + break; + case eEncodingT2: + // Ignore bits 15 & 13. + registers = Bits32(opcode, 15, 0) & ~0xa000; + // if BitCount(registers) < 2 then UNPREDICTABLE; + if (BitCount(registers) < 2) + return false; + break; + case eEncodingT3: + Rt = Bits32(opcode, 15, 12); + // if BadReg(t) then UNPREDICTABLE; + if (BadReg(Rt)) + return false; + registers = (1u << Rt); + break; + case eEncodingA1: + registers = Bits32(opcode, 15, 0); + // Instead of return false, let's handle the following case as well, + // which amounts to pushing one reg onto the full descending stacks. + // if BitCount(register_list) < 2 then SEE STMDB / STMFD; + break; + case eEncodingA2: + Rt = Bits32(opcode, 15, 12); + // if t == 13 then UNPREDICTABLE; + if (Rt == dwarf_sp) + return false; + registers = (1u << Rt); + break; + default: + return false; } - return true; + addr_t sp_offset = addr_byte_size * BitCount(registers); + addr_t addr = sp - sp_offset; + uint32_t i; + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextPushRegisterOnStack; + RegisterInfo reg_info; + RegisterInfo sp_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); + for (i = 0; i < 15; ++i) { + if (BitIsSet(registers, i)) { + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); + context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); + uint32_t reg_value = ReadCoreReg(i, &success); + if (!success) + return false; + if (!MemAWrite(context, addr, reg_value, addr_byte_size)) + return false; + addr += addr_byte_size; + } + } + + if (BitIsSet(registers, 15)) { + GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); + context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + if (!MemAWrite(context, addr, pc, addr_byte_size)) + return false; + } + + context.type = EmulateInstruction::eContextAdjustStackPointer; + context.SetImmediateSigned(-sp_offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) + return false; + } + return true; } // Pop Multiple Registers loads multiple registers from the stack, loading from // consecutive memory locations staring at the address in SP, and updates // SP to point just above the loaded data. -bool -EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -506,115 +489,115 @@ EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding enco } #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - const uint32_t addr_byte_size = GetAddressByteSize(); - const addr_t sp = ReadCoreReg (SP_REG, &success); + if (ConditionPassed(opcode)) { + const uint32_t addr_byte_size = GetAddressByteSize(); + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + uint32_t registers = 0; + uint32_t Rt; // the destination register + switch (encoding) { + case eEncodingT1: + registers = Bits32(opcode, 7, 0); + // The P bit represents PC. + if (Bit32(opcode, 8)) + registers |= (1u << 15); + // if BitCount(registers) < 1 then UNPREDICTABLE; + if (BitCount(registers) < 1) + return false; + break; + case eEncodingT2: + // Ignore bit 13. + registers = Bits32(opcode, 15, 0) & ~0x2000; + // if BitCount(registers) < 2 || (P == '1' && M == '1') then + // UNPREDICTABLE; + if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) + return false; + // if registers<15> == '1' && InITBlock() && !LastInITBlock() then + // UNPREDICTABLE; + if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) + return false; + break; + case eEncodingT3: + Rt = Bits32(opcode, 15, 12); + // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then + // UNPREDICTABLE; + if (Rt == 13) + return false; + if (Rt == 15 && InITBlock() && !LastInITBlock()) + return false; + registers = (1u << Rt); + break; + case eEncodingA1: + registers = Bits32(opcode, 15, 0); + // Instead of return false, let's handle the following case as well, + // which amounts to popping one reg from the full descending stacks. + // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; + + // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; + if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) + return false; + break; + case eEncodingA2: + Rt = Bits32(opcode, 15, 12); + // if t == 13 then UNPREDICTABLE; + if (Rt == dwarf_sp) + return false; + registers = (1u << Rt); + break; + default: + return false; + } + addr_t sp_offset = addr_byte_size * BitCount(registers); + addr_t addr = sp; + uint32_t i, data; + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextPopRegisterOffStack; + + RegisterInfo sp_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); + + for (i = 0; i < 15; ++i) { + if (BitIsSet(registers, i)) { + context.SetAddress(addr); + data = MemARead(context, addr, 4, 0, &success); if (!success) - return false; - uint32_t registers = 0; - uint32_t Rt; // the destination register - switch (encoding) { - case eEncodingT1: - registers = Bits32(opcode, 7, 0); - // The P bit represents PC. - if (Bit32(opcode, 8)) - registers |= (1u << 15); - // if BitCount(registers) < 1 then UNPREDICTABLE; - if (BitCount(registers) < 1) - return false; - break; - case eEncodingT2: - // Ignore bit 13. - registers = Bits32(opcode, 15, 0) & ~0x2000; - // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; - if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) - return false; - // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) - return false; - break; - case eEncodingT3: - Rt = Bits32(opcode, 15, 12); - // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; - if (Rt == 13) - return false; - if (Rt == 15 && InITBlock() && !LastInITBlock()) - return false; - registers = (1u << Rt); - break; - case eEncodingA1: - registers = Bits32(opcode, 15, 0); - // Instead of return false, let's handle the following case as well, - // which amounts to popping one reg from the full descending stacks. - // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; - - // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; - if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) - return false; - break; - case eEncodingA2: - Rt = Bits32(opcode, 15, 12); - // if t == 13 then UNPREDICTABLE; - if (Rt == dwarf_sp) - return false; - registers = (1u << Rt); - break; - default: - return false; - } - addr_t sp_offset = addr_byte_size * BitCount (registers); - addr_t addr = sp; - uint32_t i, data; - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextPopRegisterOffStack; - - RegisterInfo sp_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); + return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, + data)) + return false; + addr += addr_byte_size; + } + } - for (i=0; i<15; ++i) - { - if (BitIsSet (registers, i)) - { - context.SetAddress(addr); - data = MemARead(context, addr, 4, 0, &success); - if (!success) - return false; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) - return false; - addr += addr_byte_size; - } - } - - if (BitIsSet (registers, 15)) - { - context.SetRegisterPlusOffset (sp_reg, addr - sp); - data = MemARead(context, addr, 4, 0, &success); - if (!success) - return false; - // In ARMv5T and above, this is an interworking branch. - if (!LoadWritePC(context, data)) - return false; - //addr += addr_byte_size; - } - - context.type = EmulateInstruction::eContextAdjustStackPointer; - context.SetImmediateSigned (sp_offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) - return false; + if (BitIsSet(registers, 15)) { + context.SetRegisterPlusOffset(sp_reg, addr - sp); + data = MemARead(context, addr, 4, 0, &success); + if (!success) + return false; + // In ARMv5T and above, this is an interworking branch. + if (!LoadWritePC(context, data)) + return false; + // addr += addr_byte_size; } - return true; + + context.type = EmulateInstruction::eContextAdjustStackPointer; + context.SetImmediateSigned(sp_offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) + return false; + } + return true; } // Set r7 or ip to point to saved value residing within the stack. // ADD (SP plus immediate) -bool -EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -633,50 +616,49 @@ EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncodi } #endif - bool success = false; - - if (ConditionPassed(opcode)) - { - const addr_t sp = ReadCoreReg (SP_REG, &success); - if (!success) - return false; - uint32_t Rd; // the destination register - uint32_t imm32; - switch (encoding) { - case eEncodingT1: - Rd = 7; - imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - break; - default: - return false; - } - addr_t sp_offset = imm32; - addr_t addr = sp + sp_offset; // a pointer to the stack area + bool success = false; - EmulateInstruction::Context context; - if (Rd == GetFramePointerRegisterNumber()) - context.type = eContextSetFramePointer; - else - context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo sp_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); - context.SetRegisterPlusOffset (sp_reg, sp_offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) - return false; + if (ConditionPassed(opcode)) { + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + uint32_t Rd; // the destination register + uint32_t imm32; + switch (encoding) { + case eEncodingT1: + Rd = 7; + imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + break; + default: + return false; } - return true; + addr_t sp_offset = imm32; + addr_t addr = sp + sp_offset; // a pointer to the stack area + + EmulateInstruction::Context context; + if (Rd == GetFramePointerRegisterNumber()) + context.type = eContextSetFramePointer; + else + context.type = EmulateInstruction::eContextRegisterPlusOffset; + RegisterInfo sp_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); + context.SetRegisterPlusOffset(sp_reg, sp_offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, + addr)) + return false; + } + return true; } // Set r7 or ip to the current stack pointer. // MOV (register) -bool -EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -695,53 +677,50 @@ EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding } #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - const addr_t sp = ReadCoreReg (SP_REG, &success); - if (!success) - return false; - uint32_t Rd; // the destination register - switch (encoding) { - case eEncodingT1: - Rd = 7; - break; - case eEncodingA1: - Rd = 12; - break; - default: - return false; - } - - EmulateInstruction::Context context; - if (Rd == GetFramePointerRegisterNumber()) - context.type = EmulateInstruction::eContextSetFramePointer; - else - context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo sp_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); - context.SetRegisterPlusOffset (sp_reg, 0); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) - return false; + if (ConditionPassed(opcode)) { + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + uint32_t Rd; // the destination register + switch (encoding) { + case eEncodingT1: + Rd = 7; + break; + case eEncodingA1: + Rd = 12; + break; + default: + return false; } - return true; + + EmulateInstruction::Context context; + if (Rd == GetFramePointerRegisterNumber()) + context.type = EmulateInstruction::eContextSetFramePointer; + else + context.type = EmulateInstruction::eContextRegisterPlusOffset; + RegisterInfo sp_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); + context.SetRegisterPlusOffset(sp_reg, 0); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) + return false; + } + return true; } // Move from high register (r8-r15) to low register (r0-r7). // MOV (register) -bool -EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) -{ - return EmulateMOVRdRm (opcode, encoding); +bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, + const ARMEncoding encoding) { + return EmulateMOVRdRm(opcode, encoding); } // Move from register to register. // MOV (register) -bool -EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -760,77 +739,77 @@ EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding } #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rm; // the source register - uint32_t Rd; // the destination register - bool setflags; - switch (encoding) { - case eEncodingT1: - Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 6, 3); - setflags = false; - if (Rd == 15 && InITBlock() && !LastInITBlock()) - return false; - break; - case eEncodingT2: - Rd = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - setflags = true; - if (InITBlock()) - return false; - break; - case eEncodingT3: - Rd = Bits32(opcode, 11, 8); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; - if (setflags && (BadReg(Rd) || BadReg(Rm))) - return false; - // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; - if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - uint32_t result = ReadCoreReg(Rm, &success); - if (!success) - return false; + if (ConditionPassed(opcode)) { + uint32_t Rm; // the source register + uint32_t Rd; // the destination register + bool setflags; + switch (encoding) { + case eEncodingT1: + Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 6, 3); + setflags = false; + if (Rd == 15 && InITBlock() && !LastInITBlock()) + return false; + break; + case eEncodingT2: + Rd = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + setflags = true; + if (InITBlock()) + return false; + break; + case eEncodingT3: + Rd = Bits32(opcode, 11, 8); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; + if (setflags && (BadReg(Rd) || BadReg(Rm))) + return false; + // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then + // UNPREDICTABLE; + if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } + uint32_t result = ReadCoreReg(Rm, &success); + if (!success) + return false; - // The context specifies that Rm is to be moved into Rd. - EmulateInstruction::Context context; - if (Rd == 13) - context.type = EmulateInstruction::eContextAdjustStackPointer; - else - context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); - context.SetRegisterPlusOffset (dwarf_reg, 0); + // The context specifies that Rm is to be moved into Rd. + EmulateInstruction::Context context; + if (Rd == 13) + context.type = EmulateInstruction::eContextAdjustStackPointer; + else + context.type = EmulateInstruction::eContextRegisterPlusOffset; + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); + context.SetRegisterPlusOffset(dwarf_reg, 0); - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) + return false; + } + return true; } // Move (immediate) writes an immediate value to the destination register. It // can optionally update the condition flags based on the value. // MOV (immediate) -bool -EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -849,101 +828,102 @@ EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding } #endif - if (ConditionPassed(opcode)) - { - uint32_t Rd; // the destination register - uint32_t imm32; // the immediate value to be written to Rd - uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. - // for setflags == false, this value is a don't care - // initialized to 0 to silence the static analyzer - bool setflags; - switch (encoding) { - case eEncodingT1: - Rd = Bits32(opcode, 10, 8); - setflags = !InITBlock(); - imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) - carry = APSR_C; - - break; - - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); - if (BadReg(Rd)) - return false; - - break; - - case eEncodingT3: - { - // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); - Rd = Bits32 (opcode, 11, 8); - setflags = false; - uint32_t imm4 = Bits32 (opcode, 19, 16); - uint32_t imm3 = Bits32 (opcode, 14, 12); - uint32_t i = Bit32 (opcode, 26); - uint32_t imm8 = Bits32 (opcode, 7, 0); - imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; - - // if BadReg(d) then UNPREDICTABLE; - if (BadReg (Rd)) - return false; - } - break; - - case eEncodingA1: - // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); - Rd = Bits32 (opcode, 15, 12); - setflags = BitIsSet (opcode, 20); - imm32 = ARMExpandImm_C (opcode, APSR_C, carry); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if ((Rd == 15) && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - - break; - - case eEncodingA2: - { - // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); - Rd = Bits32 (opcode, 15, 12); - setflags = false; - uint32_t imm4 = Bits32 (opcode, 19, 16); - uint32_t imm12 = Bits32 (opcode, 11, 0); - imm32 = (imm4 << 12) | imm12; - - // if d == 15 then UNPREDICTABLE; - if (Rd == 15) - return false; - } - break; - - default: - return false; - } - uint32_t result = imm32; + if (ConditionPassed(opcode)) { + uint32_t Rd; // the destination register + uint32_t imm32; // the immediate value to be written to Rd + uint32_t carry = + 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. + // for setflags == false, this value is a don't care + // initialized to 0 to silence the static analyzer + bool setflags; + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 10, 8); + setflags = !InITBlock(); + imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) + carry = APSR_C; - // The context specifies that an immediate is to be moved into Rd. - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + break; - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); + if (BadReg(Rd)) + return false; + + break; + + case eEncodingT3: { + // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, + // 32); + Rd = Bits32(opcode, 11, 8); + setflags = false; + uint32_t imm4 = Bits32(opcode, 19, 16); + uint32_t imm3 = Bits32(opcode, 14, 12); + uint32_t i = Bit32(opcode, 26); + uint32_t imm8 = Bits32(opcode, 7, 0); + imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; + + // if BadReg(d) then UNPREDICTABLE; + if (BadReg(Rd)) + return false; + } break; + + case eEncodingA1: + // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = + // ARMExpandImm_C(imm12, APSR.C); + Rd = Bits32(opcode, 15, 12); + setflags = BitIsSet(opcode, 20); + imm32 = ARMExpandImm_C(opcode, APSR_C, carry); + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if ((Rd == 15) && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + + break; + + case eEncodingA2: { + // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); + Rd = Bits32(opcode, 15, 12); + setflags = false; + uint32_t imm4 = Bits32(opcode, 19, 16); + uint32_t imm12 = Bits32(opcode, 11, 0); + imm32 = (imm4 << 12) | imm12; + + // if d == 15 then UNPREDICTABLE; + if (Rd == 15) + return false; + } break; + + default: + return false; } - return true; -} + uint32_t result = imm32; -// MUL multiplies two register values. The least significant 32 bits of the result are written to the destination -// register. These 32 bits do not depend on whether the source register values are considered to be signed values or + // The context specifies that an immediate is to be moved into Rd. + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; +} + +// MUL multiplies two register values. The least significant 32 bits of the +// result are written to the destination +// register. These 32 bits do not depend on whether the source register values +// are considered to be signed values or // unsigned values. // -// Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is +// Optionally, it can update the condition flags based on the result. In the +// Thumb instruction set, this option is // limited to only a few forms of the instruction. -bool -EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -959,118 +939,120 @@ EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding enco // else APSR.C unchanged // APSR.V always unchanged #endif - - if (ConditionPassed(opcode)) - { - uint32_t d; - uint32_t n; - uint32_t m; - bool setflags; - - // EncodingSpecificOperations(); - switch (encoding) - { - case eEncodingT1: - // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); - d = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - m = Bits32 (opcode, 2, 0); - setflags = !InITBlock(); - - // if ArchVersion() < 6 && d == n then UNPREDICTABLE; - if ((ArchVersion() < ARMv6) && (d == n)) - return false; - - break; - - case eEncodingT2: - // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; - d = Bits32 (opcode, 11, 8); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - setflags = false; - - // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; - if (BadReg (d) || BadReg (n) || BadReg (m)) - return false; - - break; - - case eEncodingA1: - // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - d = Bits32 (opcode, 19, 16); - n = Bits32 (opcode, 3, 0); - m = Bits32 (opcode, 11, 8); - setflags = BitIsSet (opcode, 20); - - // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if ((d == 15) || (n == 15) || (m == 15)) - return false; - - // if ArchVersion() < 6 && d == n then UNPREDICTABLE; - if ((ArchVersion() < ARMv6) && (d == n)) - return false; - - break; - - default: - return false; - } - bool success = false; + if (ConditionPassed(opcode)) { + uint32_t d; + uint32_t n; + uint32_t m; + bool setflags; - // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results - uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results - uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - // result = operand1 * operand2; - uint64_t result = operand1 * operand2; - - // R[d] = result<31:0>; - RegisterInfo op1_reg; - RegisterInfo op2_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); - - EmulateInstruction::Context context; - context.type = eContextArithmetic; - context.SetRegisterRegisterOperands (op1_reg, op2_reg); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) - return false; - - // if setflags then - if (setflags) - { - // APSR.N = result<31>; - // APSR.Z = IsZeroBit(result); - m_new_inst_cpsr = m_opcode_cpsr; - SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); - SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); - if (m_new_inst_cpsr != m_opcode_cpsr) - { - if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) - return false; - } - - // if ArchVersion() == 4 then - // APSR.C = bit UNKNOWN; - } + // EncodingSpecificOperations(); + switch (encoding) { + case eEncodingT1: + // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); + d = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + m = Bits32(opcode, 2, 0); + setflags = !InITBlock(); + + // if ArchVersion() < 6 && d == n then UNPREDICTABLE; + if ((ArchVersion() < ARMv6) && (d == n)) + return false; + + break; + + case eEncodingT2: + // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; + d = Bits32(opcode, 11, 8); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + setflags = false; + + // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + if (BadReg(d) || BadReg(n) || BadReg(m)) + return false; + + break; + + case eEncodingA1: + // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); + d = Bits32(opcode, 19, 16); + n = Bits32(opcode, 3, 0); + m = Bits32(opcode, 11, 8); + setflags = BitIsSet(opcode, 20); + + // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; + if ((d == 15) || (n == 15) || (m == 15)) + return false; + + // if ArchVersion() < 6 && d == n then UNPREDICTABLE; + if ((ArchVersion() < ARMv6) && (d == n)) + return false; + + break; + + default: + return false; } - return true; -} - -// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. + + bool success = false; + + // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final + // results + uint64_t operand1 = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final + // results + uint64_t operand2 = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + // result = operand1 * operand2; + uint64_t result = operand1 * operand2; + + // R[d] = result<31:0>; + RegisterInfo op1_reg; + RegisterInfo op2_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); + + EmulateInstruction::Context context; + context.type = eContextArithmetic; + context.SetRegisterRegisterOperands(op1_reg, op2_reg); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, + (0x0000ffff & result))) + return false; + + // if setflags then + if (setflags) { + // APSR.N = result<31>; + // APSR.Z = IsZeroBit(result); + m_new_inst_cpsr = m_opcode_cpsr; + SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); + SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); + if (m_new_inst_cpsr != m_opcode_cpsr) { + if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) + return false; + } + + // if ArchVersion() == 4 then + // APSR.C = bit UNKNOWN; + } + } + return true; +} + +// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to +// the destination register. // It can optionally update the condition flags based on the value. -bool -EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1089,48 +1071,48 @@ EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding e } #endif - if (ConditionPassed(opcode)) - { - uint32_t Rd; // the destination register - uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C - uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C - bool setflags; - switch (encoding) { - case eEncodingT1: - Rd = Bits32(opcode, 11, 8); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm_C(opcode, APSR_C, carry); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - uint32_t result = ~imm32; - - // The context specifies that an immediate is to be moved into Rd. - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); - - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; + if (ConditionPassed(opcode)) { + uint32_t Rd; // the destination register + uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C + uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C + bool setflags; + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 11, 8); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + setflags = BitIsSet(opcode, 20); + imm32 = ARMExpandImm_C(opcode, APSR_C, carry); + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; } - return true; + uint32_t result = ~imm32; + + // The context specifies that an immediate is to be moved into Rd. + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. +// Bitwise NOT (register) writes the bitwise inverse of a register value to the +// destination register. // It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1150,68 +1132,68 @@ EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding e } #endif - if (ConditionPassed(opcode)) - { - uint32_t Rm; // the source register - uint32_t Rd; // the destination register - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - bool setflags; - uint32_t carry; // the carry bit after the shift operation - switch (encoding) { - case eEncodingT1: - Rd = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - shift_t = SRType_LSL; - shift_n = 0; - if (InITBlock()) - return false; - break; - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; - if (BadReg(Rd) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftARM(opcode, shift_t); - break; - default: - return false; - } - bool success = false; - uint32_t value = ReadCoreReg(Rm, &success); - if (!success) - return false; + if (ConditionPassed(opcode)) { + uint32_t Rm; // the source register + uint32_t Rd; // the destination register + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + bool setflags; + uint32_t carry; // the carry bit after the shift operation + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + shift_t = SRType_LSL; + shift_n = 0; + if (InITBlock()) + return false; + break; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; + if (BadReg(Rd) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftARM(opcode, shift_t); + break; + default: + return false; + } + bool success = false; + uint32_t value = ReadCoreReg(Rm, &success); + if (!success) + return false; - uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); - if (!success) - return false; - uint32_t result = ~shifted; - - // The context specifies that an immediate is to be moved into Rd. - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + uint32_t shifted = + Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; + uint32_t result = ~shifted; - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + // The context specifies that an immediate is to be moved into Rd. + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -// PC relative immediate load into register, possibly followed by ADD (SP plus register). +// PC relative immediate load into register, possibly followed by ADD (SP plus +// register). // LDR (literal) -bool -EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1232,82 +1214,74 @@ EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARME } #endif - if (ConditionPassed(opcode)) - { - bool success = false; - const uint32_t pc = ReadCoreReg(PC_REG, &success); - if (!success) - return false; - - // PC relative immediate load context - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo pc_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); - context.SetRegisterPlusOffset (pc_reg, 0); - - uint32_t Rt; // the destination register - uint32_t imm32; // immediate offset from the PC - bool add; // +imm32 or -imm32? - addr_t base; // the base address - addr_t address; // the PC relative address - uint32_t data; // the literal data value from the PC relative load - switch (encoding) { - case eEncodingT1: - Rt = Bits32(opcode, 10, 8); - imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); - add = true; - break; - case eEncodingT2: - Rt = Bits32(opcode, 15, 12); - imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); - add = BitIsSet(opcode, 23); - if (Rt == 15 && InITBlock() && !LastInITBlock()) - return false; - break; - default: - return false; - } - - base = Align(pc, 4); - if (add) - address = base + imm32; - else - address = base - imm32; + if (ConditionPassed(opcode)) { + bool success = false; + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; - context.SetRegisterPlusOffset(pc_reg, address - base); - data = MemURead(context, address, 4, 0, &success); - if (!success) - return false; + // PC relative immediate load context + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterPlusOffset; + RegisterInfo pc_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); + context.SetRegisterPlusOffset(pc_reg, 0); + + uint32_t Rt; // the destination register + uint32_t imm32; // immediate offset from the PC + bool add; // +imm32 or -imm32? + addr_t base; // the base address + addr_t address; // the PC relative address + uint32_t data; // the literal data value from the PC relative load + switch (encoding) { + case eEncodingT1: + Rt = Bits32(opcode, 10, 8); + imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); + add = true; + break; + case eEncodingT2: + Rt = Bits32(opcode, 15, 12); + imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); + add = BitIsSet(opcode, 23); + if (Rt == 15 && InITBlock() && !LastInITBlock()) + return false; + break; + default: + return false; + } - if (Rt == 15) - { - if (Bits32(address, 1, 0) == 0) - { - // In ARMv5T and above, this is an interworking branch. - if (!LoadWritePC(context, data)) - return false; - } - else - return false; - } - else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) - { - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) - return false; - } - else // We don't handle ARM for now. - return false; + base = Align(pc, 4); + if (add) + address = base + imm32; + else + address = base - imm32; - } - return true; + context.SetRegisterPlusOffset(pc_reg, address - base); + data = MemURead(context, address, 4, 0, &success); + if (!success) + return false; + + if (Rt == 15) { + if (Bits32(address, 1, 0) == 0) { + // In ARMv5T and above, this is an interworking branch. + if (!LoadWritePC(context, data)) + return false; + } else + return false; + } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, + data)) + return false; + } else // We don't handle ARM for now. + return false; + } + return true; } // An add operation to adjust the SP. // ADD (SP plus immediate) -bool -EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1326,105 +1300,99 @@ EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding } #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - const addr_t sp = ReadCoreReg (SP_REG, &success); - if (!success) - return false; - uint32_t imm32; // the immediate operand - uint32_t d; - bool setflags; - switch (encoding) - { - case eEncodingT1: - // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); - d = Bits32 (opcode, 10, 8); - imm32 = (Bits32 (opcode, 7, 0) << 2); - setflags = false; - break; - - case eEncodingT2: - // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); - d = 13; - imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32) - setflags = false; - break; - - case eEncodingT3: - // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8); - d = Bits32 (opcode, 11, 8); - imm32 = ThumbExpandImm (opcode); - setflags = Bit32 (opcode, 20); - - // if Rd == "1111" && S == "1" then SEE CMN (immediate); - if (d == 15 && setflags == 1) - return false; // CMN (immediate) not yet supported - - // if d == 15 && S == "0" then UNPREDICTABLE; - if (d == 15 && setflags == 0) - return false; - break; - - case eEncodingT4: - { - // if Rn == '1111' then SEE ADR; - // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); - d = Bits32 (opcode, 11, 8); - setflags = false; - uint32_t i = Bit32 (opcode, 26); - uint32_t imm3 = Bits32 (opcode, 14, 12); - uint32_t imm8 = Bits32 (opcode, 7, 0); - imm32 = (i << 11) | (imm3 << 8) | imm8; - - // if d == 15 then UNPREDICTABLE; - if (d == 15) - return false; - } - break; + if (ConditionPassed(opcode)) { + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + uint32_t imm32; // the immediate operand + uint32_t d; + bool setflags; + switch (encoding) { + case eEncodingT1: + // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); + d = Bits32(opcode, 10, 8); + imm32 = (Bits32(opcode, 7, 0) << 2); + setflags = false; + break; - default: - return false; - } - // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); - AddWithCarryResult res = AddWithCarry (sp, imm32, 0); + case eEncodingT2: + // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); + d = 13; + imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) + setflags = false; + break; - EmulateInstruction::Context context; - if (d == 13) - context.type = EmulateInstruction::eContextAdjustStackPointer; - else - context.type = EmulateInstruction::eContextRegisterPlusOffset; + case eEncodingT3: + // d = UInt(Rd); setflags = (S == "1"); imm32 = + // ThumbExpandImm(i:imm3:imm8); + d = Bits32(opcode, 11, 8); + imm32 = ThumbExpandImm(opcode); + setflags = Bit32(opcode, 20); + + // if Rd == "1111" && S == "1" then SEE CMN (immediate); + if (d == 15 && setflags == 1) + return false; // CMN (immediate) not yet supported + + // if d == 15 && S == "0" then UNPREDICTABLE; + if (d == 15 && setflags == 0) + return false; + break; + + case eEncodingT4: { + // if Rn == '1111' then SEE ADR; + // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); + d = Bits32(opcode, 11, 8); + setflags = false; + uint32_t i = Bit32(opcode, 26); + uint32_t imm3 = Bits32(opcode, 14, 12); + uint32_t imm8 = Bits32(opcode, 7, 0); + imm32 = (i << 11) | (imm3 << 8) | imm8; + + // if d == 15 then UNPREDICTABLE; + if (d == 15) + return false; + } break; - RegisterInfo sp_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); - context.SetRegisterPlusOffset (sp_reg, res.result - sp); + default: + return false; + } + // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); + AddWithCarryResult res = AddWithCarry(sp, imm32, 0); - if (d == 15) - { - if (!ALUWritePC (context, res.result)) - return false; - } - else - { - // R[d] = result; - // if setflags then - // APSR.N = result<31>; - // APSR.Z = IsZeroBit(result); - // APSR.C = carry; - // APSR.V = overflow; - if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) - return false; - } + EmulateInstruction::Context context; + if (d == 13) + context.type = EmulateInstruction::eContextAdjustStackPointer; + else + context.type = EmulateInstruction::eContextRegisterPlusOffset; + + RegisterInfo sp_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); + context.SetRegisterPlusOffset(sp_reg, res.result - sp); + + if (d == 15) { + if (!ALUWritePC(context, res.result)) + return false; + } else { + // R[d] = result; + // if setflags then + // APSR.N = result<31>; + // APSR.Z = IsZeroBit(result); + // APSR.C = carry; + // APSR.V = overflow; + if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, + res.carry_out, res.overflow)) + return false; } - return true; + } + return true; } // An add operation to adjust the SP. // ADD (SP plus register) -bool -EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1444,49 +1412,48 @@ EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding } #endif - bool success = false; - - if (ConditionPassed(opcode)) - { - const addr_t sp = ReadCoreReg (SP_REG, &success); - if (!success) - return false; - uint32_t Rm; // the second operand - switch (encoding) { - case eEncodingT2: - Rm = Bits32(opcode, 6, 3); - break; - default: - return false; - } - int32_t reg_value = ReadCoreReg(Rm, &success); - if (!success) - return false; + bool success = false; - addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value - - EmulateInstruction::Context context; - context.type = eContextArithmetic; - RegisterInfo sp_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); - - RegisterInfo other_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); - context.SetRegisterRegisterOperands (sp_reg, other_reg); - - if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) - return false; + if (ConditionPassed(opcode)) { + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + uint32_t Rm; // the second operand + switch (encoding) { + case eEncodingT2: + Rm = Bits32(opcode, 6, 3); + break; + default: + return false; } - return true; + int32_t reg_value = ReadCoreReg(Rm, &success); + if (!success) + return false; + + addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value + + EmulateInstruction::Context context; + context.type = eContextArithmetic; + RegisterInfo sp_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); + + RegisterInfo other_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); + context.SetRegisterRegisterOperands(sp_reg, other_reg); + + if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_SP, addr)) + return false; + } + return true; } // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine // at a PC-relative address, and changes instruction set from ARM to Thumb, or // from Thumb to ARM. // BLX (immediate) -bool -EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1505,91 +1472,92 @@ EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEnco } #endif - bool success = true; + bool success = true; - if (ConditionPassed(opcode)) - { - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRelativeBranchImmediate; - const uint32_t pc = ReadCoreReg(PC_REG, &success); - if (!success) - return false; - addr_t lr; // next instruction address - addr_t target; // target address - int32_t imm32; // PC-relative offset - switch (encoding) { - case eEncodingT1: - { - lr = pc | 1u; // return address - uint32_t S = Bit32(opcode, 26); - uint32_t imm10 = Bits32(opcode, 25, 16); - uint32_t J1 = Bit32(opcode, 13); - uint32_t J2 = Bit32(opcode, 11); - uint32_t imm11 = Bits32(opcode, 10, 0); - uint32_t I1 = !(J1 ^ S); - uint32_t I2 = !(J2 ^ S); - uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); - imm32 = llvm::SignExtend32<25>(imm25); - target = pc + imm32; - SelectInstrSet (eModeThumb); - context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); - if (InITBlock() && !LastInITBlock()) - return false; - break; - } - case eEncodingT2: - { - lr = pc | 1u; // return address - uint32_t S = Bit32(opcode, 26); - uint32_t imm10H = Bits32(opcode, 25, 16); - uint32_t J1 = Bit32(opcode, 13); - uint32_t J2 = Bit32(opcode, 11); - uint32_t imm10L = Bits32(opcode, 10, 1); - uint32_t I1 = !(J1 ^ S); - uint32_t I2 = !(J2 ^ S); - uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); - imm32 = llvm::SignExtend32<25>(imm25); - target = Align(pc, 4) + imm32; - SelectInstrSet (eModeARM); - context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); - if (InITBlock() && !LastInITBlock()) - return false; - break; - } - case eEncodingA1: - lr = pc - 4; // return address - imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); - target = Align(pc, 4) + imm32; - SelectInstrSet (eModeARM); - context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); - break; - case eEncodingA2: - lr = pc - 4; // return address - imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); - target = pc + imm32; - SelectInstrSet (eModeThumb); - context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); - break; - default: - return false; - } - if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) - return false; - if (!BranchWritePC(context, target)) - return false; - if (m_opcode_cpsr != m_new_inst_cpsr) - if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) - return false; + if (ConditionPassed(opcode)) { + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRelativeBranchImmediate; + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + addr_t lr; // next instruction address + addr_t target; // target address + int32_t imm32; // PC-relative offset + switch (encoding) { + case eEncodingT1: { + lr = pc | 1u; // return address + uint32_t S = Bit32(opcode, 26); + uint32_t imm10 = Bits32(opcode, 25, 16); + uint32_t J1 = Bit32(opcode, 13); + uint32_t J2 = Bit32(opcode, 11); + uint32_t imm11 = Bits32(opcode, 10, 0); + uint32_t I1 = !(J1 ^ S); + uint32_t I2 = !(J2 ^ S); + uint32_t imm25 = + (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); + imm32 = llvm::SignExtend32<25>(imm25); + target = pc + imm32; + SelectInstrSet(eModeThumb); + context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); + if (InITBlock() && !LastInITBlock()) + return false; + break; + } + case eEncodingT2: { + lr = pc | 1u; // return address + uint32_t S = Bit32(opcode, 26); + uint32_t imm10H = Bits32(opcode, 25, 16); + uint32_t J1 = Bit32(opcode, 13); + uint32_t J2 = Bit32(opcode, 11); + uint32_t imm10L = Bits32(opcode, 10, 1); + uint32_t I1 = !(J1 ^ S); + uint32_t I2 = !(J2 ^ S); + uint32_t imm25 = + (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); + imm32 = llvm::SignExtend32<25>(imm25); + target = Align(pc, 4) + imm32; + SelectInstrSet(eModeARM); + context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); + if (InITBlock() && !LastInITBlock()) + return false; + break; } - return true; + case eEncodingA1: + lr = pc - 4; // return address + imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); + target = Align(pc, 4) + imm32; + SelectInstrSet(eModeARM); + context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); + break; + case eEncodingA2: + lr = pc - 4; // return address + imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | + Bits32(opcode, 24, 24) << 1); + target = pc + imm32; + SelectInstrSet(eModeThumb); + context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); + break; + default: + return false; + } + if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_RA, lr)) + return false; + if (!BranchWritePC(context, target)) + return false; + if (m_opcode_cpsr != m_new_inst_cpsr) + if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) + return false; + } + return true; } // Branch with Link and Exchange (register) calls a subroutine at an address and // instruction set specified by a register. // BLX (register) -bool -EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1606,103 +1574,104 @@ EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding en } #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextAbsoluteBranchRegister; - const uint32_t pc = ReadCoreReg(PC_REG, &success); - addr_t lr; // next instruction address - if (!success) - return false; - uint32_t Rm; // the register with the target address - switch (encoding) { - case eEncodingT1: - lr = (pc - 2) | 1u; // return address - Rm = Bits32(opcode, 6, 3); - // if m == 15 then UNPREDICTABLE; - if (Rm == 15) - return false; - if (InITBlock() && !LastInITBlock()) - return false; - break; - case eEncodingA1: - lr = pc - 4; // return address - Rm = Bits32(opcode, 3, 0); - // if m == 15 then UNPREDICTABLE; - if (Rm == 15) - return false; - break; - default: - return false; - } - addr_t target = ReadCoreReg (Rm, &success); - if (!success) - return false; - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); - context.SetRegister (dwarf_reg); - if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) - return false; - if (!BXWritePC(context, target)) - return false; - } - return true; -} - -// Branch and Exchange causes a branch to an address and instruction set specified by a register. -bool -EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) -{ -#if 0 - // ARM pseudo code... - if (ConditionPassed()) + if (ConditionPassed(opcode)) { + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextAbsoluteBranchRegister; + const uint32_t pc = ReadCoreReg(PC_REG, &success); + addr_t lr; // next instruction address + if (!success) + return false; + uint32_t Rm; // the register with the target address + switch (encoding) { + case eEncodingT1: + lr = (pc - 2) | 1u; // return address + Rm = Bits32(opcode, 6, 3); + // if m == 15 then UNPREDICTABLE; + if (Rm == 15) + return false; + if (InITBlock() && !LastInITBlock()) + return false; + break; + case eEncodingA1: + lr = pc - 4; // return address + Rm = Bits32(opcode, 3, 0); + // if m == 15 then UNPREDICTABLE; + if (Rm == 15) + return false; + break; + default: + return false; + } + addr_t target = ReadCoreReg(Rm, &success); + if (!success) + return false; + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); + context.SetRegister(dwarf_reg); + if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_RA, lr)) + return false; + if (!BXWritePC(context, target)) + return false; + } + return true; +} + +// Branch and Exchange causes a branch to an address and instruction set +// specified by a register. +bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, + const ARMEncoding encoding) { +#if 0 + // ARM pseudo code... + if (ConditionPassed()) { EncodingSpecificOperations(); BXWritePC(R[m]); } #endif - if (ConditionPassed(opcode)) - { - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextAbsoluteBranchRegister; - uint32_t Rm; // the register with the target address - switch (encoding) { - case eEncodingT1: - Rm = Bits32(opcode, 6, 3); - if (InITBlock() && !LastInITBlock()) - return false; - break; - case eEncodingA1: - Rm = Bits32(opcode, 3, 0); - break; - default: - return false; - } - bool success = false; - addr_t target = ReadCoreReg (Rm, &success); - if (!success) - return false; - - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); - context.SetRegister (dwarf_reg); - if (!BXWritePC(context, target)) - return false; + if (ConditionPassed(opcode)) { + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextAbsoluteBranchRegister; + uint32_t Rm; // the register with the target address + switch (encoding) { + case eEncodingT1: + Rm = Bits32(opcode, 6, 3); + if (InITBlock() && !LastInITBlock()) + return false; + break; + case eEncodingA1: + Rm = Bits32(opcode, 3, 0); + break; + default: + return false; } - return true; + bool success = false; + addr_t target = ReadCoreReg(Rm, &success); + if (!success) + return false; + + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); + context.SetRegister(dwarf_reg); + if (!BXWritePC(context, target)) + return false; + } + return true; } -// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an -// address and instruction set specified by a register as though it were a BX instruction. +// Branch and Exchange Jazelle attempts to change to Jazelle state. If the +// attempt fails, it branches to an +// address and instruction set specified by a register as though it were a BX +// instruction. // // TODO: Emulate Jazelle architecture? -// We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. -bool -EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) -{ +// We currently assume that switching to Jazelle state fails, thus +// treating BXJ as a BX operation. +bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1718,46 +1687,44 @@ EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding en } #endif - if (ConditionPassed(opcode)) - { - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextAbsoluteBranchRegister; - uint32_t Rm; // the register with the target address - switch (encoding) { - case eEncodingT1: - Rm = Bits32(opcode, 19, 16); - if (BadReg(Rm)) - return false; - if (InITBlock() && !LastInITBlock()) - return false; - break; - case eEncodingA1: - Rm = Bits32(opcode, 3, 0); - if (Rm == 15) - return false; - break; - default: - return false; - } - bool success = false; - addr_t target = ReadCoreReg (Rm, &success); - if (!success) - return false; - - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); - context.SetRegister (dwarf_reg); - if (!BXWritePC(context, target)) - return false; + if (ConditionPassed(opcode)) { + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextAbsoluteBranchRegister; + uint32_t Rm; // the register with the target address + switch (encoding) { + case eEncodingT1: + Rm = Bits32(opcode, 19, 16); + if (BadReg(Rm)) + return false; + if (InITBlock() && !LastInITBlock()) + return false; + break; + case eEncodingA1: + Rm = Bits32(opcode, 3, 0); + if (Rm == 15) + return false; + break; + default: + return false; } - return true; + bool success = false; + addr_t target = ReadCoreReg(Rm, &success); + if (!success) + return false; + + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); + context.SetRegister(dwarf_reg); + if (!BXWritePC(context, target)) + return false; + } + return true; } // Set r7 to point to some ip offset. // SUB (immediate) -bool -EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1776,40 +1743,38 @@ EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncodi } #endif - if (ConditionPassed(opcode)) - { - bool success = false; - const addr_t ip = ReadCoreReg (12, &success); - if (!success) - return false; - uint32_t imm32; - switch (encoding) { - case eEncodingA1: - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - break; - default: - return false; - } - addr_t ip_offset = imm32; - addr_t addr = ip - ip_offset; // the adjusted ip value - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); - context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) - return false; + if (ConditionPassed(opcode)) { + bool success = false; + const addr_t ip = ReadCoreReg(12, &success); + if (!success) + return false; + uint32_t imm32; + switch (encoding) { + case eEncodingA1: + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + break; + default: + return false; } - return true; + addr_t ip_offset = imm32; + addr_t addr = ip - ip_offset; // the adjusted ip value + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterPlusOffset; + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); + context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) + return false; + } + return true; } // Set ip to point to some stack offset. // SUB (SP minus immediate) -bool -EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1828,42 +1793,41 @@ EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncodi } #endif - if (ConditionPassed(opcode)) - { - bool success = false; - const addr_t sp = ReadCoreReg (SP_REG, &success); - if (!success) - return false; - uint32_t imm32; - switch (encoding) { - case eEncodingA1: - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - break; - default: - return false; - } - addr_t sp_offset = imm32; - addr_t addr = sp - sp_offset; // the adjusted stack pointer value - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); - context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) - return false; + if (ConditionPassed(opcode)) { + bool success = false; + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + uint32_t imm32; + switch (encoding) { + case eEncodingA1: + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + break; + default: + return false; } - return true; + addr_t sp_offset = imm32; + addr_t addr = sp - sp_offset; // the adjusted stack pointer value + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterPlusOffset; + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); + context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) + return false; + } + return true; } // This instruction subtracts an immediate value from the SP value, and writes // the result to the destination register. // -// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. -bool -EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) -{ +// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local +// storage. +bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1882,76 +1846,74 @@ EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding } #endif - bool success = false; - if (ConditionPassed(opcode)) - { - const addr_t sp = ReadCoreReg (SP_REG, &success); - if (!success) - return false; - - uint32_t Rd; - bool setflags; - uint32_t imm32; - switch (encoding) { - case eEncodingT1: - Rd = 13; - setflags = false; - imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) - break; - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) - if (Rd == 15 && setflags) - return EmulateCMPImm(opcode, eEncodingT2); - if (Rd == 15 && !setflags) - return false; - break; - case eEncodingT3: - Rd = Bits32(opcode, 11, 8); - setflags = false; - imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) - if (Rd == 15) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); + bool success = false; + if (ConditionPassed(opcode)) { + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; - EmulateInstruction::Context context; - if (Rd == 13) - { - uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong - // value gets passed down to context.SetImmediateSigned. - context.type = EmulateInstruction::eContextAdjustStackPointer; - context.SetImmediateSigned (-imm64); // the stack pointer offset - } - else - { - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); - } + uint32_t Rd; + bool setflags; + uint32_t imm32; + switch (encoding) { + case eEncodingT1: + Rd = 13; + setflags = false; + imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) + break; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) + if (Rd == 15 && setflags) + return EmulateCMPImm(opcode, eEncodingT2); + if (Rd == 15 && !setflags) + return false; + break; + case eEncodingT3: + Rd = Bits32(opcode, 11, 8); + setflags = false; + imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) + if (Rd == 15) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + setflags = BitIsSet(opcode, 20); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } + AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; + EmulateInstruction::Context context; + if (Rd == 13) { + uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting + // to negate it, or the wrong + // value gets passed down to context.SetImmediateSigned. + context.type = EmulateInstruction::eContextAdjustStackPointer; + context.SetImmediateSigned(-imm64); // the stack pointer offset + } else { + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); } - return true; + + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; + } + return true; } // A store operation to the stack that also updates the SP. -bool -EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -1964,93 +1926,88 @@ EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding } #endif - bool success = false; - if (ConditionPassed(opcode)) - { - const uint32_t addr_byte_size = GetAddressByteSize(); - const addr_t sp = ReadCoreReg (SP_REG, &success); - if (!success) - return false; - uint32_t Rt; // the source register - uint32_t imm12; - uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. - - bool index; - bool add; - bool wback; - switch (encoding) { - case eEncodingA1: - Rt = Bits32(opcode, 15, 12); - imm12 = Bits32(opcode, 11, 0); - Rn = Bits32 (opcode, 19, 16); - - if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. - return false; - - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); - - if (wback && ((Rn == 15) || (Rn == Rt))) - return false; - break; - default: - return false; - } - addr_t offset_addr; - if (add) - offset_addr = sp + imm12; - else - offset_addr = sp - imm12; - - addr_t addr; - if (index) - addr = offset_addr; - else - addr = sp; - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextPushRegisterOnStack; - RegisterInfo sp_reg; - RegisterInfo dwarf_reg; - - GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); - context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); - if (Rt != 15) - { - uint32_t reg_value = ReadCoreReg(Rt, &success); - if (!success) - return false; - if (!MemUWrite (context, addr, reg_value, addr_byte_size)) - return false; - } - else - { - const uint32_t pc = ReadCoreReg(PC_REG, &success); - if (!success) - return false; - if (!MemUWrite (context, addr, pc, addr_byte_size)) - return false; - } - + bool success = false; + if (ConditionPassed(opcode)) { + const uint32_t addr_byte_size = GetAddressByteSize(); + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + uint32_t Rt; // the source register + uint32_t imm12; + uint32_t + Rn; // This function assumes Rn is the SP, but we should verify that. + + bool index; + bool add; + bool wback; + switch (encoding) { + case eEncodingA1: + Rt = Bits32(opcode, 15, 12); + imm12 = Bits32(opcode, 11, 0); + Rn = Bits32(opcode, 19, 16); - if (wback) - { - context.type = EmulateInstruction::eContextAdjustStackPointer; - context.SetImmediateSigned (addr - sp); - if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) - return false; - } + if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. + return false; + + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); + + if (wback && ((Rn == 15) || (Rn == Rt))) + return false; + break; + default: + return false; } - return true; + addr_t offset_addr; + if (add) + offset_addr = sp + imm12; + else + offset_addr = sp - imm12; + + addr_t addr; + if (index) + addr = offset_addr; + else + addr = sp; + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextPushRegisterOnStack; + RegisterInfo sp_reg; + RegisterInfo dwarf_reg; + + GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); + context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); + if (Rt != 15) { + uint32_t reg_value = ReadCoreReg(Rt, &success); + if (!success) + return false; + if (!MemUWrite(context, addr, reg_value, addr_byte_size)) + return false; + } else { + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + if (!MemUWrite(context, addr, pc, addr_byte_size)) + return false; + } + + if (wback) { + context.type = EmulateInstruction::eContextAdjustStackPointer; + context.SetImmediateSigned(addr - sp); + if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_SP, offset_addr)) + return false; + } + } + return true; } // Vector Push stores multiple extension registers to the stack. // It also updates SP to point to the start of the stored data. -bool -EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -2070,81 +2027,79 @@ EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding en } #endif - bool success = false; - if (ConditionPassed(opcode)) - { - const uint32_t addr_byte_size = GetAddressByteSize(); - const addr_t sp = ReadCoreReg (SP_REG, &success); - if (!success) - return false; - bool single_regs; - uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register - uint32_t imm32; // stack offset - uint32_t regs; // number of registers - switch (encoding) { - case eEncodingT1: - case eEncodingA1: - single_regs = false; - d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); - imm32 = Bits32(opcode, 7, 0) * addr_byte_size; - // If UInt(imm8) is odd, see "FSTMX". - regs = Bits32(opcode, 7, 0) / 2; - // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if (regs == 0 || regs > 16 || (d + regs) > 32) - return false; - break; - case eEncodingT2: - case eEncodingA2: - single_regs = true; - d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); - imm32 = Bits32(opcode, 7, 0) * addr_byte_size; - regs = Bits32(opcode, 7, 0); - // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if (regs == 0 || regs > 16 || (d + regs) > 32) - return false; - break; - default: - return false; - } - uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; - uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; - addr_t sp_offset = imm32; - addr_t addr = sp - sp_offset; - uint32_t i; - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextPushRegisterOnStack; + bool success = false; + if (ConditionPassed(opcode)) { + const uint32_t addr_byte_size = GetAddressByteSize(); + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + bool single_regs; + uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register + uint32_t imm32; // stack offset + uint32_t regs; // number of registers + switch (encoding) { + case eEncodingT1: + case eEncodingA1: + single_regs = false; + d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); + imm32 = Bits32(opcode, 7, 0) * addr_byte_size; + // If UInt(imm8) is odd, see "FSTMX". + regs = Bits32(opcode, 7, 0) / 2; + // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; + if (regs == 0 || regs > 16 || (d + regs) > 32) + return false; + break; + case eEncodingT2: + case eEncodingA2: + single_regs = true; + d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); + imm32 = Bits32(opcode, 7, 0) * addr_byte_size; + regs = Bits32(opcode, 7, 0); + // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; + if (regs == 0 || regs > 16 || (d + regs) > 32) + return false; + break; + default: + return false; + } + uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; + uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; + addr_t sp_offset = imm32; + addr_t addr = sp - sp_offset; + uint32_t i; - RegisterInfo dwarf_reg; - RegisterInfo sp_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); - for (i=0; i 16 || (d+regs) > 32 then UNPREDICTABLE; - if (regs == 0 || regs > 16 || (d + regs) > 32) - return false; - break; - case eEncodingT2: - case eEncodingA2: - single_regs = true; - d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); - imm32 = Bits32(opcode, 7, 0) * addr_byte_size; - regs = Bits32(opcode, 7, 0); - // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if (regs == 0 || regs > 16 || (d + regs) > 32) - return false; - break; - default: - return false; - } - uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; - uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; - addr_t sp_offset = imm32; - addr_t addr = sp; - uint32_t i; - uint64_t data; // uint64_t to accommodate 64-bit registers. - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextPopRegisterOffStack; + bool success = false; + if (ConditionPassed(opcode)) { + const uint32_t addr_byte_size = GetAddressByteSize(); + const addr_t sp = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + bool single_regs; + uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register + uint32_t imm32; // stack offset + uint32_t regs; // number of registers + switch (encoding) { + case eEncodingT1: + case eEncodingA1: + single_regs = false; + d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); + imm32 = Bits32(opcode, 7, 0) * addr_byte_size; + // If UInt(imm8) is odd, see "FLDMX". + regs = Bits32(opcode, 7, 0) / 2; + // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; + if (regs == 0 || regs > 16 || (d + regs) > 32) + return false; + break; + case eEncodingT2: + case eEncodingA2: + single_regs = true; + d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); + imm32 = Bits32(opcode, 7, 0) * addr_byte_size; + regs = Bits32(opcode, 7, 0); + // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; + if (regs == 0 || regs > 16 || (d + regs) > 32) + return false; + break; + default: + return false; + } + uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; + uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; + addr_t sp_offset = imm32; + addr_t addr = sp; + uint32_t i; + uint64_t data; // uint64_t to accommodate 64-bit registers. - RegisterInfo dwarf_reg; - RegisterInfo sp_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); - for (i=0; i = firstcond:mask; #endif - m_it_session.InitIT(Bits32(opcode, 7, 0)); - return true; + m_it_session.InitIT(Bits32(opcode, 7, 0)); + return true; } -bool -EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) -{ - // NOP, nothing to do... - return true; +bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, + const ARMEncoding encoding) { + // NOP, nothing to do... + return true; } // Branch causes a branch to a target address. -bool -EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateB(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -2314,81 +2264,83 @@ EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encodi } #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRelativeBranchImmediate; - const uint32_t pc = ReadCoreReg(PC_REG, &success); - if (!success) - return false; - addr_t target; // target address - int32_t imm32; // PC-relative offset - switch (encoding) { - case eEncodingT1: - // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). - imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); - target = pc + imm32; - context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); - break; - case eEncodingT2: - imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); - target = pc + imm32; - context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); - break; - case eEncodingT3: - // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). - { - if (Bits32(opcode, 25, 23) == 7) - return false; // See Branches and miscellaneous control on page A6-235. - - uint32_t S = Bit32(opcode, 26); - uint32_t imm6 = Bits32(opcode, 21, 16); - uint32_t J1 = Bit32(opcode, 13); - uint32_t J2 = Bit32(opcode, 11); - uint32_t imm11 = Bits32(opcode, 10, 0); - uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); - imm32 = llvm::SignExtend32<21>(imm21); - target = pc + imm32; - context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); - break; - } - case eEncodingT4: - { - uint32_t S = Bit32(opcode, 26); - uint32_t imm10 = Bits32(opcode, 25, 16); - uint32_t J1 = Bit32(opcode, 13); - uint32_t J2 = Bit32(opcode, 11); - uint32_t imm11 = Bits32(opcode, 10, 0); - uint32_t I1 = !(J1 ^ S); - uint32_t I2 = !(J2 ^ S); - uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); - imm32 = llvm::SignExtend32<25>(imm25); - target = pc + imm32; - context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); - break; - } - case eEncodingA1: - imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); - target = pc + imm32; - context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); - break; - default: - return false; - } - if (!BranchWritePC(context, target)) - return false; + if (ConditionPassed(opcode)) { + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRelativeBranchImmediate; + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + addr_t target; // target address + int32_t imm32; // PC-relative offset + switch (encoding) { + case eEncodingT1: + // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). + imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); + target = pc + imm32; + context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); + break; + case eEncodingT2: + imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); + target = pc + imm32; + context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); + break; + case eEncodingT3: + // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). + { + if (Bits32(opcode, 25, 23) == 7) + return false; // See Branches and miscellaneous control on page + // A6-235. + + uint32_t S = Bit32(opcode, 26); + uint32_t imm6 = Bits32(opcode, 21, 16); + uint32_t J1 = Bit32(opcode, 13); + uint32_t J2 = Bit32(opcode, 11); + uint32_t imm11 = Bits32(opcode, 10, 0); + uint32_t imm21 = + (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); + imm32 = llvm::SignExtend32<21>(imm21); + target = pc + imm32; + context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); + break; + } + case eEncodingT4: { + uint32_t S = Bit32(opcode, 26); + uint32_t imm10 = Bits32(opcode, 25, 16); + uint32_t J1 = Bit32(opcode, 13); + uint32_t J2 = Bit32(opcode, 11); + uint32_t imm11 = Bits32(opcode, 10, 0); + uint32_t I1 = !(J1 ^ S); + uint32_t I2 = !(J2 ^ S); + uint32_t imm25 = + (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); + imm32 = llvm::SignExtend32<25>(imm25); + target = pc + imm32; + context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); + break; } - return true; + case eEncodingA1: + imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); + target = pc + imm32; + context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); + break; + default: + return false; + } + if (!BranchWritePC(context, target)) + return false; + } + return true; } -// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with -// zero and conditionally branch forward a constant value. They do not affect the condition flags. +// Compare and Branch on Nonzero and Compare and Branch on Zero compare the +// value in a register with +// zero and conditionally branch forward a constant value. They do not affect +// the condition flags. // CBNZ, CBZ -bool -EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... EncodingSpecificOperations(); @@ -2396,50 +2348,53 @@ EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encod BranchWritePC(PC + imm32); #endif - bool success = false; + bool success = false; - // Read the register value from the operand register Rn. - uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); - if (!success) - return false; - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRelativeBranchImmediate; - const uint32_t pc = ReadCoreReg(PC_REG, &success); - if (!success) - return false; + // Read the register value from the operand register Rn. + uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); + if (!success) + return false; - addr_t target; // target address - uint32_t imm32; // PC-relative offset to branch forward - bool nonzero; - switch (encoding) { - case eEncodingT1: - imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; - nonzero = BitIsSet(opcode, 11); - target = pc + imm32; - context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); - break; - default: - return false; - } - if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) - if (!BranchWritePC(context, target)) - return false; + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRelativeBranchImmediate; + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; - return true; + addr_t target; // target address + uint32_t imm32; // PC-relative offset to branch forward + bool nonzero; + switch (encoding) { + case eEncodingT1: + imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; + nonzero = BitIsSet(opcode, 11); + target = pc + imm32; + context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); + break; + default: + return false; + } + if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) + if (!BranchWritePC(context, target)) + return false; + + return true; } -// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. -// A base register provides a pointer to the table, and a second register supplies an index into the table. +// Table Branch Byte causes a PC-relative forward branch using a table of single +// byte offsets. +// A base register provides a pointer to the table, and a second register +// supplies an index into the table. // The branch length is twice the value of the byte returned from the table. // -// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. -// A base register provides a pointer to the table, and a second register supplies an index into the table. +// Table Branch Halfword causes a PC-relative forward branch using a table of +// single halfword offsets. +// A base register provides a pointer to the table, and a second register +// supplies an index into the table. // The branch length is twice the value of the halfword returned from the table. // TBB, TBH -bool -EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -2450,69 +2405,71 @@ EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encod BranchWritePC(PC + 2*halfwords); #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rn; // the base register which contains the address of the table of branch lengths - uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table - bool is_tbh; // true if table branch halfword - switch (encoding) { - case eEncodingT1: - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - is_tbh = BitIsSet(opcode, 4); - if (Rn == 13 || BadReg(Rm)) - return false; - if (InITBlock() && !LastInITBlock()) - return false; - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rn; // the base register which contains the address of the table of + // branch lengths + uint32_t Rm; // the index register which contains an integer pointing to a + // byte/halfword in the table + bool is_tbh; // true if table branch halfword + switch (encoding) { + case eEncodingT1: + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + is_tbh = BitIsSet(opcode, 4); + if (Rn == 13 || BadReg(Rm)) + return false; + if (InITBlock() && !LastInITBlock()) + return false; + break; + default: + return false; + } - // Read the address of the table from the operand register Rn. - // The PC can be used, in which case the table immediately follows this instruction. - uint32_t base = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the address of the table from the operand register Rn. + // The PC can be used, in which case the table immediately follows this + // instruction. + uint32_t base = ReadCoreReg(Rn, &success); + if (!success) + return false; - // the table index - uint32_t index = ReadCoreReg(Rm, &success); - if (!success) - return false; + // the table index + uint32_t index = ReadCoreReg(Rm, &success); + if (!success) + return false; - // the offsetted table address - addr_t addr = base + (is_tbh ? index*2 : index); + // the offsetted table address + addr_t addr = base + (is_tbh ? index * 2 : index); - // PC-relative offset to branch forward - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextTableBranchReadMemory; - uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; - if (!success) - return false; + // PC-relative offset to branch forward + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextTableBranchReadMemory; + uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; + if (!success) + return false; - const uint32_t pc = ReadCoreReg(PC_REG, &success); - if (!success) - return false; + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; - // target address - addr_t target = pc + offset; - context.type = EmulateInstruction::eContextRelativeBranchImmediate; - context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); + // target address + addr_t target = pc + offset; + context.type = EmulateInstruction::eContextRelativeBranchImmediate; + context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); - if (!BranchWritePC(context, target)) - return false; - } + if (!BranchWritePC(context, target)) + return false; + } - return true; + return true; } -// This instruction adds an immediate value to a register value, and writes the result to the destination register. +// This instruction adds an immediate value to a register value, and writes the +// result to the destination register. // It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -2525,114 +2482,116 @@ EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncod APSR.V = overflow; #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t d; - uint32_t n; - bool setflags; - uint32_t imm32; - uint32_t carry_out; - - //EncodingSpecificOperations(); - switch (encoding) - { - case eEncodingT1: - // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); - d = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - setflags = !InITBlock(); - imm32 = Bits32 (opcode, 8,6); - - break; - - case eEncodingT2: - // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); - d = Bits32 (opcode, 10, 8); - n = Bits32 (opcode, 10, 8); - setflags = !InITBlock(); - imm32 = Bits32 (opcode, 7, 0); - - break; - - case eEncodingT3: - // if Rd == '1111' && S == '1' then SEE CMN (immediate); - // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); - d = Bits32 (opcode, 11, 8); - n = Bits32 (opcode, 19, 16); - setflags = BitIsSet (opcode, 20); - imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); - - // if Rn == '1101' then SEE ADD (SP plus immediate); - if (n == 13) - return EmulateADDSPImm(opcode, eEncodingT3); - - // if BadReg(d) || n == 15 then UNPREDICTABLE; - if (BadReg (d) || (n == 15)) - return false; - - break; - - case eEncodingT4: - { - // if Rn == '1111' then SEE ADR; - // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); - d = Bits32 (opcode, 11, 8); - n = Bits32 (opcode, 19, 16); - setflags = false; - uint32_t i = Bit32 (opcode, 26); - uint32_t imm3 = Bits32 (opcode, 14, 12); - uint32_t imm8 = Bits32 (opcode, 7, 0); - imm32 = (i << 11) | (imm3 << 8) | imm8; - - // if Rn == '1101' then SEE ADD (SP plus immediate); - if (n == 13) - return EmulateADDSPImm(opcode, eEncodingT4); - - // if BadReg(d) then UNPREDICTABLE; - if (BadReg (d)) - return false; - - break; - } + if (ConditionPassed(opcode)) { + uint32_t d; + uint32_t n; + bool setflags; + uint32_t imm32; + uint32_t carry_out; - default: - return false; - } + // EncodingSpecificOperations(); + switch (encoding) { + case eEncodingT1: + // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = + // ZeroExtend(imm3, 32); + d = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + imm32 = Bits32(opcode, 8, 6); - uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; + break; - //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); - AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); + case eEncodingT2: + // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = + // ZeroExtend(imm8, 32); + d = Bits32(opcode, 10, 8); + n = Bits32(opcode, 10, 8); + setflags = !InITBlock(); + imm32 = Bits32(opcode, 7, 0); - RegisterInfo reg_n; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); + break; - EmulateInstruction::Context context; - context.type = eContextArithmetic; - context.SetRegisterPlusOffset (reg_n, imm32); + case eEncodingT3: + // if Rd == '1111' && S == '1' then SEE CMN (immediate); + // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = + // ThumbExpandImm(i:imm3:imm8); + d = Bits32(opcode, 11, 8); + n = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); + + // if Rn == '1101' then SEE ADD (SP plus immediate); + if (n == 13) + return EmulateADDSPImm(opcode, eEncodingT3); + + // if BadReg(d) || n == 15 then UNPREDICTABLE; + if (BadReg(d) || (n == 15)) + return false; - //R[d] = result; - //if setflags then - //APSR.N = result<31>; - //APSR.Z = IsZeroBit(result); - //APSR.C = carry; - //APSR.V = overflow; - if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) - return false; + break; + + case eEncodingT4: { + // if Rn == '1111' then SEE ADR; + // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = + // ZeroExtend(i:imm3:imm8, 32); + d = Bits32(opcode, 11, 8); + n = Bits32(opcode, 19, 16); + setflags = false; + uint32_t i = Bit32(opcode, 26); + uint32_t imm3 = Bits32(opcode, 14, 12); + uint32_t imm8 = Bits32(opcode, 7, 0); + imm32 = (i << 11) | (imm3 << 8) | imm8; + + // if Rn == '1101' then SEE ADD (SP plus immediate); + if (n == 13) + return EmulateADDSPImm(opcode, eEncodingT4); + + // if BadReg(d) then UNPREDICTABLE; + if (BadReg(d)) + return false; + break; } - return true; -} - -// This instruction adds an immediate value to a register value, and writes the result to the destination + + default: + return false; + } + + uint64_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); + AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); + + RegisterInfo reg_n; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); + + EmulateInstruction::Context context; + context.type = eContextArithmetic; + context.SetRegisterPlusOffset(reg_n, imm32); + + // R[d] = result; + // if setflags then + // APSR.N = result<31>; + // APSR.Z = IsZeroBit(result); + // APSR.C = carry; + // APSR.V = overflow; + if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, + res.carry_out, res.overflow)) + return false; + } + return true; +} + +// This instruction adds an immediate value to a register value, and writes the +// result to the destination // register. It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -2649,55 +2608,56 @@ EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncodin APSR.V = overflow; #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn; - uint32_t imm32; // the immediate value to be added to the value obtained from Rn - bool setflags; - switch (encoding) - { - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn; + uint32_t + imm32; // the immediate value to be added to the value obtained from Rn + bool setflags; + switch (encoding) { + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - AddWithCarryResult res = AddWithCarry(val1, imm32, 0); + AddWithCarryResult res = AddWithCarry(val1, imm32, 0); - EmulateInstruction::Context context; - if (Rd == 13) - context.type = EmulateInstruction::eContextAdjustStackPointer; - else if (Rd == GetFramePointerRegisterNumber()) - context.type = EmulateInstruction::eContextSetFramePointer; - else - context.type = EmulateInstruction::eContextRegisterPlusOffset; + EmulateInstruction::Context context; + if (Rd == 13) + context.type = EmulateInstruction::eContextAdjustStackPointer; + else if (Rd == GetFramePointerRegisterNumber()) + context.type = EmulateInstruction::eContextSetFramePointer; + else + context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); - context.SetRegisterPlusOffset (dwarf_reg, imm32); + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); + context.SetRegisterPlusOffset(dwarf_reg, imm32); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; + } + return true; } -// This instruction adds a register value and an optionally-shifted register value, and writes the result -// to the destination register. It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) -{ +// This instruction adds a register value and an optionally-shifted register +// value, and writes the result +// to the destination register. It can optionally update the condition flags +// based on the result. +bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -2715,80 +2675,78 @@ EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn, Rm; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - bool setflags; - switch (encoding) - { - case eEncodingT1: - Rd = Bits32(opcode, 2, 0); - Rn = Bits32(opcode, 5, 3); - Rm = Bits32(opcode, 8, 6); - setflags = !InITBlock(); - shift_t = SRType_LSL; - shift_n = 0; - break; - case eEncodingT2: - Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 6, 3); - setflags = false; - shift_t = SRType_LSL; - shift_n = 0; - if (Rn == 15 && Rm == 15) - return false; - if (Rd == 15 && InITBlock() && !LastInITBlock()) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftARM(opcode, shift_t); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn, Rm; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + bool setflags; + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 2, 0); + Rn = Bits32(opcode, 5, 3); + Rm = Bits32(opcode, 8, 6); + setflags = !InITBlock(); + shift_t = SRType_LSL; + shift_n = 0; + break; + case eEncodingT2: + Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 6, 3); + setflags = false; + shift_t = SRType_LSL; + shift_n = 0; + if (Rn == 15 && Rm == 15) + return false; + if (Rd == 15 && InITBlock() && !LastInITBlock()) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftARM(opcode, shift_t); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - // Read the second operand. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; + // Read the second operand. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - AddWithCarryResult res = AddWithCarry(val1, shifted, 0); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + AddWithCarryResult res = AddWithCarry(val1, shifted, 0); - EmulateInstruction::Context context; - context.type = eContextArithmetic; - RegisterInfo op1_reg; - RegisterInfo op2_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); - context.SetRegisterRegisterOperands (op1_reg, op2_reg); + EmulateInstruction::Context context; + context.type = eContextArithmetic; + RegisterInfo op1_reg; + RegisterInfo op2_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); + context.SetRegisterRegisterOperands(op1_reg, op2_reg); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; + } + return true; } // Compare Negative (immediate) adds a register value and an immediate value. // It updates the condition flags based on the result, and discards the result. -bool -EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -2800,45 +2758,45 @@ EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; + + uint32_t Rn; // the first operand + uint32_t imm32; // the immediate value to be compared with + switch (encoding) { + case eEncodingT1: + Rn = Bits32(opcode, 19, 16); + imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) + if (Rn == 15) + return false; + break; + case eEncodingA1: + Rn = Bits32(opcode, 19, 16); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + break; + default: + return false; + } + // Read the register value from the operand register Rn. + uint32_t reg_val = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t Rn; // the first operand - uint32_t imm32; // the immediate value to be compared with - switch (encoding) { - case eEncodingT1: - Rn = Bits32(opcode, 19, 16); - imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) - if (Rn == 15) - return false; - break; - case eEncodingA1: - Rn = Bits32(opcode, 19, 16); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - break; - default: - return false; - } - // Read the register value from the operand register Rn. - uint32_t reg_val = ReadCoreReg(Rn, &success); - if (!success) - return false; - - AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); + AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); - if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) - return false; + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) + return false; - return true; + return true; } -// Compare Negative (register) adds a register value and an optionally-shifted register value. +// Compare Negative (register) adds a register value and an optionally-shifted +// register value. // It updates the condition flags based on the result, and discards the result. -bool -EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -2851,64 +2809,63 @@ EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; + + uint32_t Rn; // the first operand + uint32_t Rm; // the second operand + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + switch (encoding) { + case eEncodingT1: + Rn = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + shift_t = SRType_LSL; + shift_n = 0; + break; + case eEncodingT2: + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + // if n == 15 || BadReg(m) then UNPREDICTABLE; + if (Rn == 15 || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + shift_n = DecodeImmShiftARM(opcode, shift_t); + break; + default: + return false; + } + // Read the register value from register Rn. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t Rn; // the first operand - uint32_t Rm; // the second operand - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - switch (encoding) { - case eEncodingT1: - Rn = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - shift_t = SRType_LSL; - shift_n = 0; - break; - case eEncodingT2: - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - // if n == 15 || BadReg(m) then UNPREDICTABLE; - if (Rn == 15 || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - shift_n = DecodeImmShiftARM(opcode, shift_t); - break; - default: - return false; - } - // Read the register value from register Rn. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the register value from register Rm. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - // Read the register value from register Rm. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; - - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - AddWithCarryResult res = AddWithCarry(val1, shifted, 0); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + AddWithCarryResult res = AddWithCarry(val1, shifted, 0); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs(); - if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) - return false; + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) + return false; - return true; + return true; } // Compare (immediate) subtracts an immediate value from a register value. // It updates the condition flags based on the result, and discards the result. -bool -EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -2920,49 +2877,49 @@ EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; + + uint32_t Rn; // the first operand + uint32_t imm32; // the immediate value to be compared with + switch (encoding) { + case eEncodingT1: + Rn = Bits32(opcode, 10, 8); + imm32 = Bits32(opcode, 7, 0); + break; + case eEncodingT2: + Rn = Bits32(opcode, 19, 16); + imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) + if (Rn == 15) + return false; + break; + case eEncodingA1: + Rn = Bits32(opcode, 19, 16); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + break; + default: + return false; + } + // Read the register value from the operand register Rn. + uint32_t reg_val = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t Rn; // the first operand - uint32_t imm32; // the immediate value to be compared with - switch (encoding) { - case eEncodingT1: - Rn = Bits32(opcode, 10, 8); - imm32 = Bits32(opcode, 7, 0); - break; - case eEncodingT2: - Rn = Bits32(opcode, 19, 16); - imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) - if (Rn == 15) - return false; - break; - case eEncodingA1: - Rn = Bits32(opcode, 19, 16); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - break; - default: - return false; - } - // Read the register value from the operand register Rn. - uint32_t reg_val = ReadCoreReg(Rn, &success); - if (!success) - return false; - - AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); + AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); - if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) - return false; + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) + return false; - return true; + return true; } -// Compare (register) subtracts an optionally-shifted register value from a register value. +// Compare (register) subtracts an optionally-shifted register value from a +// register value. // It updates the condition flags based on the result, and discards the result. -bool -EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -2975,74 +2932,75 @@ EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; + + uint32_t Rn; // the first operand + uint32_t Rm; // the second operand + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + switch (encoding) { + case eEncodingT1: + Rn = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + shift_t = SRType_LSL; + shift_n = 0; + break; + case eEncodingT2: + Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 6, 3); + shift_t = SRType_LSL; + shift_n = 0; + if (Rn < 8 && Rm < 8) + return false; + if (Rn == 15 || Rm == 15) + return false; + break; + case eEncodingT3: + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + if (Rn == 15 || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + shift_n = DecodeImmShiftARM(opcode, shift_t); + break; + default: + return false; + } + // Read the register value from register Rn. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t Rn; // the first operand - uint32_t Rm; // the second operand - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - switch (encoding) { - case eEncodingT1: - Rn = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - shift_t = SRType_LSL; - shift_n = 0; - break; - case eEncodingT2: - Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 6, 3); - shift_t = SRType_LSL; - shift_n = 0; - if (Rn < 8 && Rm < 8) - return false; - if (Rn == 15 || Rm == 15) - return false; - break; - case eEncodingT3: - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - if (Rn == 15 || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - shift_n = DecodeImmShiftARM(opcode, shift_t); - break; - default: - return false; - } - // Read the register value from register Rn. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the register value from register Rm. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - // Read the register value from register Rm. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; - - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs(); - if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) - return false; + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) + return false; - return true; + return true; } -// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, -// shifting in copies of its sign bit, and writes the result to the destination register. It can +// Arithmetic Shift Right (immediate) shifts a register value right by an +// immediate number of bits, +// shifting in copies of its sign bit, and writes the result to the destination +// register. It can // optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3059,16 +3017,18 @@ EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - return EmulateShiftImm (opcode, encoding, SRType_ASR); + return EmulateShiftImm(opcode, encoding, SRType_ASR); } -// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, -// shifting in copies of its sign bit, and writes the result to the destination register. -// The variable number of bits is read from the bottom byte of a register. It can optionally update +// Arithmetic Shift Right (register) shifts a register value right by a variable +// number of bits, +// shifting in copies of its sign bit, and writes the result to the destination +// register. +// The variable number of bits is read from the bottom byte of a register. It +// can optionally update // the condition flags based on the result. -bool -EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3083,15 +3043,16 @@ EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - return EmulateShiftReg (opcode, encoding, SRType_ASR); + return EmulateShiftReg(opcode, encoding, SRType_ASR); } -// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, -// shifting in zeros, and writes the result to the destination register. It can optionally +// Logical Shift Left (immediate) shifts a register value left by an immediate +// number of bits, +// shifting in zeros, and writes the result to the destination register. It can +// optionally // update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3108,16 +3069,18 @@ EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - return EmulateShiftImm (opcode, encoding, SRType_LSL); + return EmulateShiftImm(opcode, encoding, SRType_LSL); } -// Logical Shift Left (register) shifts a register value left by a variable number of bits, -// shifting in zeros, and writes the result to the destination register. The variable number -// of bits is read from the bottom byte of a register. It can optionally update the condition +// Logical Shift Left (register) shifts a register value left by a variable +// number of bits, +// shifting in zeros, and writes the result to the destination register. The +// variable number +// of bits is read from the bottom byte of a register. It can optionally update +// the condition // flags based on the result. -bool -EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3132,15 +3095,16 @@ EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - return EmulateShiftReg (opcode, encoding, SRType_LSL); + return EmulateShiftReg(opcode, encoding, SRType_LSL); } -// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, -// shifting in zeros, and writes the result to the destination register. It can optionally +// Logical Shift Right (immediate) shifts a register value right by an immediate +// number of bits, +// shifting in zeros, and writes the result to the destination register. It can +// optionally // update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3157,16 +3121,18 @@ EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - return EmulateShiftImm (opcode, encoding, SRType_LSR); + return EmulateShiftImm(opcode, encoding, SRType_LSR); } -// Logical Shift Right (register) shifts a register value right by a variable number of bits, -// shifting in zeros, and writes the result to the destination register. The variable number -// of bits is read from the bottom byte of a register. It can optionally update the condition +// Logical Shift Right (register) shifts a register value right by a variable +// number of bits, +// shifting in zeros, and writes the result to the destination register. The +// variable number +// of bits is read from the bottom byte of a register. It can optionally update +// the condition // flags based on the result. -bool -EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3181,15 +3147,16 @@ EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - return EmulateShiftReg (opcode, encoding, SRType_LSR); + return EmulateShiftReg(opcode, encoding, SRType_LSR); } -// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. -// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. +// Rotate Right (immediate) provides the value of the contents of a register +// rotated by a constant value. +// The bits that are rotated off the right end are inserted into the vacated bit +// positions on the left. // It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3206,16 +3173,18 @@ EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - return EmulateShiftImm (opcode, encoding, SRType_ROR); + return EmulateShiftImm(opcode, encoding, SRType_ROR); } -// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. -// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. -// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition +// Rotate Right (register) provides the value of the contents of a register +// rotated by a variable number of bits. +// The bits that are rotated off the right end are inserted into the vacated bit +// positions on the left. +// The variable number of bits is read from the bottom byte of a register. It +// can optionally update the condition // flags based on the result. -bool -EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3230,17 +3199,17 @@ EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - return EmulateShiftReg (opcode, encoding, SRType_ROR); + return EmulateShiftReg(opcode, encoding, SRType_ROR); } -// Rotate Right with Extend provides the value of the contents of a register shifted right by one place, +// Rotate Right with Extend provides the value of the contents of a register +// shifted right by one place, // with the carry flag shifted into bit [31]. // // RRX can optionally update the condition flags based on the result. // In that case, bit [0] is shifted into the carry flag. -bool -EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3257,176 +3226,177 @@ EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding enco // APSR.V unchanged #endif - return EmulateShiftImm (opcode, encoding, SRType_RRX); + return EmulateShiftImm(opcode, encoding, SRType_RRX); } -bool -EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) -{ -// assert(shift_type == SRType_ASR -// || shift_type == SRType_LSL -// || shift_type == SRType_LSR -// || shift_type == SRType_ROR -// || shift_type == SRType_RRX); +bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, + const ARMEncoding encoding, + ARM_ShifterType shift_type) { + // assert(shift_type == SRType_ASR + // || shift_type == SRType_LSL + // || shift_type == SRType_LSR + // || shift_type == SRType_ROR + // || shift_type == SRType_RRX); - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd; // the destination register - uint32_t Rm; // the first operand register - uint32_t imm5; // encoding for the shift amount - uint32_t carry; // the carry bit after the shift operation - bool setflags; - - // Special case handling! - // A8.6.139 ROR (immediate) -- Encoding T1 - ARMEncoding use_encoding = encoding; - if (shift_type == SRType_ROR && use_encoding == eEncodingT1) - { - // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to - // have the same decoding of bit fields as the other Thumb2 shift operations. - use_encoding = eEncodingT2; - } + if (ConditionPassed(opcode)) { + uint32_t Rd; // the destination register + uint32_t Rm; // the first operand register + uint32_t imm5; // encoding for the shift amount + uint32_t carry; // the carry bit after the shift operation + bool setflags; - switch (use_encoding) { - case eEncodingT1: - // Due to the above special case handling! - if (shift_type == SRType_ROR) - return false; + // Special case handling! + // A8.6.139 ROR (immediate) -- Encoding T1 + ARMEncoding use_encoding = encoding; + if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { + // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding + // to + // have the same decoding of bit fields as the other Thumb2 shift + // operations. + use_encoding = eEncodingT2; + } - Rd = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - imm5 = Bits32(opcode, 10, 6); - break; - case eEncodingT2: - // A8.6.141 RRX - // There's no imm form of RRX instructions. - if (shift_type == SRType_RRX) - return false; + switch (use_encoding) { + case eEncodingT1: + // Due to the above special case handling! + if (shift_type == SRType_ROR) + return false; - Rd = Bits32(opcode, 11, 8); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); - if (BadReg(Rd) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - imm5 = Bits32(opcode, 11, 7); - break; - default: - return false; - } + Rd = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + imm5 = Bits32(opcode, 10, 6); + break; + case eEncodingT2: + // A8.6.141 RRX + // There's no imm form of RRX instructions. + if (shift_type == SRType_RRX) + return false; - // A8.6.139 ROR (immediate) - if (shift_type == SRType_ROR && imm5 == 0) - shift_type = SRType_RRX; + Rd = Bits32(opcode, 11, 8); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); + if (BadReg(Rd) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + imm5 = Bits32(opcode, 11, 7); + break; + default: + return false; + } - // Get the first operand. - uint32_t value = ReadCoreReg (Rm, &success); - if (!success) - return false; + // A8.6.139 ROR (immediate) + if (shift_type == SRType_ROR && imm5 == 0) + shift_type = SRType_RRX; - // Decode the shift amount if not RRX. - uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); + // Get the first operand. + uint32_t value = ReadCoreReg(Rm, &success); + if (!success) + return false; - uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); - if (!success) - return false; + // Decode the shift amount if not RRX. + uint32_t amt = + (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); - // The context specifies that an immediate is to be moved into Rd. - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); - - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); + if (!success) + return false; + + // The context specifies that an immediate is to be moved into Rd. + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -bool -EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) -{ - // assert(shift_type == SRType_ASR - // || shift_type == SRType_LSL - // || shift_type == SRType_LSR - // || shift_type == SRType_ROR); +bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, + const ARMEncoding encoding, + ARM_ShifterType shift_type) { + // assert(shift_type == SRType_ASR + // || shift_type == SRType_LSL + // || shift_type == SRType_LSR + // || shift_type == SRType_ROR); - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd; // the destination register - uint32_t Rn; // the first operand register - uint32_t Rm; // the register whose bottom byte contains the amount to shift by - uint32_t carry; // the carry bit after the shift operation - bool setflags; - switch (encoding) { - case eEncodingT1: - Rd = Bits32(opcode, 2, 0); - Rn = Rd; - Rm = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - break; - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 3, 0); - Rm = Bits32(opcode, 11, 8); - setflags = BitIsSet(opcode, 20); - if (Rd == 15 || Rn == 15 || Rm == 15) - return false; - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd; // the destination register + uint32_t Rn; // the first operand register + uint32_t + Rm; // the register whose bottom byte contains the amount to shift by + uint32_t carry; // the carry bit after the shift operation + bool setflags; + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 2, 0); + Rn = Rd; + Rm = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + break; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 3, 0); + Rm = Bits32(opcode, 11, 8); + setflags = BitIsSet(opcode, 20); + if (Rd == 15 || Rn == 15 || Rm == 15) + return false; + break; + default: + return false; + } - // Get the first operand. - uint32_t value = ReadCoreReg (Rn, &success); - if (!success) - return false; - // Get the Rm register content. - uint32_t val = ReadCoreReg (Rm, &success); - if (!success) - return false; + // Get the first operand. + uint32_t value = ReadCoreReg(Rn, &success); + if (!success) + return false; + // Get the Rm register content. + uint32_t val = ReadCoreReg(Rm, &success); + if (!success) + return false; - // Get the shift amount. - uint32_t amt = Bits32(val, 7, 0); + // Get the shift amount. + uint32_t amt = Bits32(val, 7, 0); - uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); - if (!success) - return false; + uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); + if (!success) + return false; - // The context specifies that an immediate is to be moved into Rd. - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); - - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + // The context specifies that an immediate is to be moved into Rd. + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } // LDM loads multiple registers from consecutive memory locations, using an -// address from a base register. Optionally the address just above the highest of those locations +// address from a base register. Optionally the address just above the highest +// of those locations // can be written back to the base register. -bool -EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() @@ -3443,133 +3413,133 @@ EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding enco if wback && registers == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 #endif - - bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t n; - uint32_t registers = 0; - bool wback; - const uint32_t addr_byte_size = GetAddressByteSize(); - switch (encoding) + + bool success = false; + if (ConditionPassed(opcode)) { + uint32_t n; + uint32_t registers = 0; + bool wback; + const uint32_t addr_byte_size = GetAddressByteSize(); + switch (encoding) { + case eEncodingT1: + // n = UInt(Rn); registers = '00000000':register_list; wback = + // (registers == '0'); + n = Bits32(opcode, 10, 8); + registers = Bits32(opcode, 7, 0); + registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. + wback = BitIsClear(registers, n); + // if BitCount(registers) < 1 then UNPREDICTABLE; + if (BitCount(registers) < 1) + return false; + break; + case eEncodingT2: + // if W == '1' && Rn == '1101' then SEE POP; + // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + registers = registers & 0xdfff; // Make sure bit 13 is zero. + wback = BitIsSet(opcode, 21); + + // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then + // UNPREDICTABLE; + if ((n == 15) || (BitCount(registers) < 2) || + (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) + return false; + + // if registers<15> == '1' && InITBlock() && !LastInITBlock() then + // UNPREDICTABLE; + if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) + return false; + + // if wback && registers == '1' then UNPREDICTABLE; + if (wback && BitIsSet(registers, n)) + return false; + break; + + case eEncodingA1: + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + wback = BitIsSet(opcode, 21); + if ((n == 15) || (BitCount(registers) < 1)) + return false; + break; + default: + return false; + } + + int32_t offset = 0; + const addr_t base_address = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterPlusOffset; + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); + context.SetRegisterPlusOffset(dwarf_reg, offset); + + for (int i = 0; i < 14; ++i) { + if (BitIsSet(registers, i)) { + context.type = EmulateInstruction::eContextRegisterPlusOffset; + context.SetRegisterPlusOffset(dwarf_reg, offset); + if (wback && (n == 13)) // Pop Instruction { - case eEncodingT1: - // n = UInt(Rn); registers = '00000000':register_list; wback = (registers == '0'); - n = Bits32 (opcode, 10, 8); - registers = Bits32 (opcode, 7, 0); - registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. - wback = BitIsClear (registers, n); - // if BitCount(registers) < 1 then UNPREDICTABLE; - if (BitCount(registers) < 1) - return false; - break; - case eEncodingT2: - // if W == '1' && Rn == '1101' then SEE POP; - // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - registers = registers & 0xdfff; // Make sure bit 13 is zero. - wback = BitIsSet (opcode, 21); - - // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; - if ((n == 15) - || (BitCount (registers) < 2) - || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) - return false; - - // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) - return false; - - // if wback && registers == '1' then UNPREDICTABLE; - if (wback - && BitIsSet (registers, n)) - return false; - break; - - case eEncodingA1: - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - wback = BitIsSet (opcode, 21); - if ((n == 15) - || (BitCount (registers) < 1)) - return false; - break; - default: - return false; + context.type = EmulateInstruction::eContextPopRegisterOffStack; + context.SetAddress(base_address + offset); } - - int32_t offset = 0; - const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + + // R[i] = MemA [address, 4]; address = address + 4; + uint32_t data = MemARead(context, base_address + offset, addr_byte_size, + 0, &success); if (!success) - return false; + return false; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); - context.SetRegisterPlusOffset (dwarf_reg, offset); - - for (int i = 0; i < 14; ++i) - { - if (BitIsSet (registers, i)) - { - context.type = EmulateInstruction::eContextRegisterPlusOffset; - context.SetRegisterPlusOffset (dwarf_reg, offset); - if (wback && (n == 13)) // Pop Instruction - { - context.type = EmulateInstruction::eContextPopRegisterOffStack; - context.SetAddress(base_address + offset); - } - - // R[i] = MemA [address, 4]; address = address + 4; - uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, + data)) + return false; - offset += addr_byte_size; - } - } - - if (BitIsSet (registers, 15)) - { - //LoadWritePC (MemA [address, 4]); - context.type = EmulateInstruction::eContextRegisterPlusOffset; - context.SetRegisterPlusOffset (dwarf_reg, offset); - uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); - if (!success) - return false; - // In ARMv5T and above, this is an interworking branch. - if (!LoadWritePC(context, data)) - return false; - } - - if (wback && BitIsClear (registers, n)) - { - // R[n] = R[n] + 4 * BitCount (registers) - int32_t offset = addr_byte_size * BitCount (registers); - context.type = EmulateInstruction::eContextAdjustBaseRegister; - context.SetRegisterPlusOffset (dwarf_reg, offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) - return false; - } - if (wback && BitIsSet (registers, n)) - // R[n] bits(32) UNKNOWN; - return WriteBits32Unknown (n); + offset += addr_byte_size; + } } - return true; + + if (BitIsSet(registers, 15)) { + // LoadWritePC (MemA [address, 4]); + context.type = EmulateInstruction::eContextRegisterPlusOffset; + context.SetRegisterPlusOffset(dwarf_reg, offset); + uint32_t data = + MemARead(context, base_address + offset, addr_byte_size, 0, &success); + if (!success) + return false; + // In ARMv5T and above, this is an interworking branch. + if (!LoadWritePC(context, data)) + return false; + } + + if (wback && BitIsClear(registers, n)) { + // R[n] = R[n] + 4 * BitCount (registers) + int32_t offset = addr_byte_size * BitCount(registers); + context.type = EmulateInstruction::eContextAdjustBaseRegister; + context.SetRegisterPlusOffset(dwarf_reg, offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + base_address + offset)) + return false; + } + if (wback && BitIsSet(registers, n)) + // R[n] bits(32) UNKNOWN; + return WriteBits32Unknown(n); + } + return true; } - -// LDMDA loads multiple registers from consecutive memory locations using an address from a base register. -// The consecutive memory locations end at this address and the address just below the lowest of those locations + +// LDMDA loads multiple registers from consecutive memory locations using an +// address from a base register. +// The consecutive memory locations end at this address and the address just +// below the lowest of those locations // can optionally be written back to the base register. -bool -EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3586,107 +3556,107 @@ EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding en if wback && registers == '0' then R[n] = R[n] - 4*BitCount(registers); if wback && registers == '1' then R[n] = bits(32) UNKNOWN; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t n; - uint32_t registers = 0; - bool wback; - const uint32_t addr_byte_size = GetAddressByteSize(); - - // EncodingSpecificOperations(); - switch (encoding) - { - case eEncodingA1: - // n = UInt(Rn); registers = register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - wback = BitIsSet (opcode, 21); - - // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if ((n == 15) || (BitCount (registers) < 1)) - return false; - - break; - default: - return false; - } - // address = R[n] - 4*BitCount(registers) + 4; - - int32_t offset = 0; - addr_t Rn = ReadCoreReg (n, &success); - - if (!success) - return false; - - addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); - context.SetRegisterPlusOffset (dwarf_reg, offset); - - // for i = 0 to 14 - for (int i = 0; i < 14; ++i) - { - // if registers == '1' then - if (BitIsSet (registers, i)) - { - // R[i] = MemA[address,4]; address = address + 4; - context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); - uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); - if (!success) - return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) - return false; - offset += addr_byte_size; - } - } - - // if registers<15> == '1' then - // LoadWritePC(MemA[address,4]); - if (BitIsSet (registers, 15)) - { - context.SetRegisterPlusOffset (dwarf_reg, offset); - uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); - if (!success) - return false; - // In ARMv5T and above, this is an interworking branch. - if (!LoadWritePC(context, data)) - return false; - } - - // if wback && registers == '0' then R[n] = R[n] - 4*BitCount(registers); - if (wback && BitIsClear (registers, n)) - { - if (!success) - return false; + bool success = false; - offset = (addr_byte_size * BitCount (registers)) * -1; - context.type = EmulateInstruction::eContextAdjustBaseRegister; - context.SetImmediateSigned (offset); - addr_t addr = Rn + offset; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) - return false; - } - - // if wback && registers == '1' then R[n] = bits(32) UNKNOWN; - if (wback && BitIsSet (registers, n)) - return WriteBits32Unknown (n); + if (ConditionPassed(opcode)) { + uint32_t n; + uint32_t registers = 0; + bool wback; + const uint32_t addr_byte_size = GetAddressByteSize(); + + // EncodingSpecificOperations(); + switch (encoding) { + case eEncodingA1: + // n = UInt(Rn); registers = register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + wback = BitIsSet(opcode, 21); + + // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; + if ((n == 15) || (BitCount(registers) < 1)) + return false; + + break; + + default: + return false; } - return true; + // address = R[n] - 4*BitCount(registers) + 4; + + int32_t offset = 0; + addr_t Rn = ReadCoreReg(n, &success); + + if (!success) + return false; + + addr_t address = + Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterPlusOffset; + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); + context.SetRegisterPlusOffset(dwarf_reg, offset); + + // for i = 0 to 14 + for (int i = 0; i < 14; ++i) { + // if registers == '1' then + if (BitIsSet(registers, i)) { + // R[i] = MemA[address,4]; address = address + 4; + context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); + uint32_t data = + MemARead(context, address + offset, addr_byte_size, 0, &success); + if (!success) + return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, + data)) + return false; + offset += addr_byte_size; + } + } + + // if registers<15> == '1' then + // LoadWritePC(MemA[address,4]); + if (BitIsSet(registers, 15)) { + context.SetRegisterPlusOffset(dwarf_reg, offset); + uint32_t data = + MemARead(context, address + offset, addr_byte_size, 0, &success); + if (!success) + return false; + // In ARMv5T and above, this is an interworking branch. + if (!LoadWritePC(context, data)) + return false; + } + + // if wback && registers == '0' then R[n] = R[n] - 4*BitCount(registers); + if (wback && BitIsClear(registers, n)) { + if (!success) + return false; + + offset = (addr_byte_size * BitCount(registers)) * -1; + context.type = EmulateInstruction::eContextAdjustBaseRegister; + context.SetImmediateSigned(offset); + addr_t addr = Rn + offset; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + addr)) + return false; + } + + // if wback && registers == '1' then R[n] = bits(32) UNKNOWN; + if (wback && BitIsSet(registers, n)) + return WriteBits32Unknown(n); + } + return true; } - -// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The -// consecutive memory locations end just below this address, and the address of the lowest of those locations can + +// LDMDB loads multiple registers from consecutive memory locations using an +// address from a base register. The +// consecutive memory locations end just below this address, and the address of +// the lowest of those locations can // be optionally written back to the base register. -bool -EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -3702,241 +3672,243 @@ EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding en if wback && registers == '0' then R[n] = R[n] - 4*BitCount(registers); if wback && registers == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 #endif + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t n; + uint32_t registers = 0; + bool wback; + const uint32_t addr_byte_size = GetAddressByteSize(); + switch (encoding) { + case eEncodingT1: + // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + registers = registers & 0xdfff; // Make sure bit 13 is a zero. + wback = BitIsSet(opcode, 21); + + // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then + // UNPREDICTABLE; + if ((n == 15) || (BitCount(registers) < 2) || + (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) + return false; + + // if registers<15> == '1' && InITBlock() && !LastInITBlock() then + // UNPREDICTABLE; + if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) + return false; + + // if wback && registers == '1' then UNPREDICTABLE; + if (wback && BitIsSet(registers, n)) + return false; + + break; + + case eEncodingA1: + // n = UInt(Rn); registers = register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + wback = BitIsSet(opcode, 21); + + // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; + if ((n == 15) || (BitCount(registers) < 1)) + return false; + + break; + + default: + return false; + } + + // address = R[n] - 4*BitCount(registers); + + int32_t offset = 0; + addr_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + + if (!success) + return false; + + addr_t address = Rn - (addr_byte_size * BitCount(registers)); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterPlusOffset; + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); + context.SetRegisterPlusOffset(dwarf_reg, Rn - address); + + for (int i = 0; i < 14; ++i) { + if (BitIsSet(registers, i)) { + // R[i] = MemA[address,4]; address = address + 4; + context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); + uint32_t data = + MemARead(context, address + offset, addr_byte_size, 0, &success); + if (!success) + return false; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, + data)) + return false; + + offset += addr_byte_size; + } + } + + // if registers<15> == '1' then + // LoadWritePC(MemA[address,4]); + if (BitIsSet(registers, 15)) { + context.SetRegisterPlusOffset(dwarf_reg, offset); + uint32_t data = + MemARead(context, address + offset, addr_byte_size, 0, &success); + if (!success) + return false; + // In ARMv5T and above, this is an interworking branch. + if (!LoadWritePC(context, data)) + return false; + } + + // if wback && registers == '0' then R[n] = R[n] - 4*BitCount(registers); + if (wback && BitIsClear(registers, n)) { + if (!success) + return false; + + offset = (addr_byte_size * BitCount(registers)) * -1; + context.type = EmulateInstruction::eContextAdjustBaseRegister; + context.SetImmediateSigned(offset); + addr_t addr = Rn + offset; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + addr)) + return false; + } + + // if wback && registers == '1' then R[n] = bits(32) UNKNOWN; // Only + // possible for encoding A1 + if (wback && BitIsSet(registers, n)) + return WriteBits32Unknown(n); + } + return true; +} + +// LDMIB loads multiple registers from consecutive memory locations using an +// address from a base register. The +// consecutive memory locations start just above this address, and thea ddress +// of the last of those locations can +// optinoally be written back to the base register. +bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, + const ARMEncoding encoding) { +#if 0 + if ConditionPassed() then + EncodingSpecificOperations(); + address = R[n] + 4; - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t n; - uint32_t registers = 0; - bool wback; - const uint32_t addr_byte_size = GetAddressByteSize(); - switch (encoding) - { - case eEncodingT1: - // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - registers = registers & 0xdfff; // Make sure bit 13 is a zero. - wback = BitIsSet (opcode, 21); - - // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; - if ((n == 15) - || (BitCount (registers) < 2) - || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) - return false; - - // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) - return false; - - // if wback && registers == '1' then UNPREDICTABLE; - if (wback && BitIsSet (registers, n)) - return false; - - break; - - case eEncodingA1: - // n = UInt(Rn); registers = register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - wback = BitIsSet (opcode, 21); - - // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if ((n == 15) || (BitCount (registers) < 1)) - return false; - - break; - - default: - return false; - } - - // address = R[n] - 4*BitCount(registers); - - int32_t offset = 0; - addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - - if (!success) - return false; - - addr_t address = Rn - (addr_byte_size * BitCount (registers)); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); - context.SetRegisterPlusOffset (dwarf_reg, Rn - address); - - for (int i = 0; i < 14; ++i) - { - if (BitIsSet (registers, i)) - { - // R[i] = MemA[address,4]; address = address + 4; - context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); - uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) - return false; - - offset += addr_byte_size; - } - } - - // if registers<15> == '1' then - // LoadWritePC(MemA[address,4]); - if (BitIsSet (registers, 15)) - { - context.SetRegisterPlusOffset (dwarf_reg, offset); - uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); - if (!success) - return false; - // In ARMv5T and above, this is an interworking branch. - if (!LoadWritePC(context, data)) - return false; - } - - // if wback && registers == '0' then R[n] = R[n] - 4*BitCount(registers); - if (wback && BitIsClear (registers, n)) - { - if (!success) - return false; - - offset = (addr_byte_size * BitCount (registers)) * -1; - context.type = EmulateInstruction::eContextAdjustBaseRegister; - context.SetImmediateSigned (offset); - addr_t addr = Rn + offset; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) - return false; - } - - // if wback && registers == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 - if (wback && BitIsSet (registers, n)) - return WriteBits32Unknown (n); - } - return true; -} - -// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The -// consecutive memory locations start just above this address, and thea ddress of the last of those locations can -// optinoally be written back to the base register. -bool -EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) -{ -#if 0 - if ConditionPassed() then - EncodingSpecificOperations(); - address = R[n] + 4; - - for i = 0 to 14 - if registers == '1' then - R[i] = MemA[address,4]; address = address + 4; - if registers<15> == '1' then - LoadWritePC(MemA[address,4]); + for i = 0 to 14 + if registers == '1' then + R[i] = MemA[address,4]; address = address + 4; + if registers<15> == '1' then + LoadWritePC(MemA[address,4]); if wback && registers == '0' then R[n] = R[n] + 4*BitCount(registers); if wback && registers == '1' then R[n] = bits(32) UNKNOWN; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t n; - uint32_t registers = 0; - bool wback; - const uint32_t addr_byte_size = GetAddressByteSize(); - switch (encoding) - { - case eEncodingA1: - // n = UInt(Rn); registers = register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - wback = BitIsSet (opcode, 21); - - // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if ((n == 15) || (BitCount (registers) < 1)) - return false; - - break; - default: - return false; - } - // address = R[n] + 4; - - int32_t offset = 0; - addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t n; + uint32_t registers = 0; + bool wback; + const uint32_t addr_byte_size = GetAddressByteSize(); + switch (encoding) { + case eEncodingA1: + // n = UInt(Rn); registers = register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + wback = BitIsSet(opcode, 21); + + // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; + if ((n == 15) || (BitCount(registers) < 1)) + return false; + + break; + default: + return false; + } + // address = R[n] + 4; + + int32_t offset = 0; + addr_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + + if (!success) + return false; + + addr_t address = Rn + addr_byte_size; + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterPlusOffset; + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); + context.SetRegisterPlusOffset(dwarf_reg, offset); + + for (int i = 0; i < 14; ++i) { + if (BitIsSet(registers, i)) { + // R[i] = MemA[address,4]; address = address + 4; + + context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); + uint32_t data = + MemARead(context, address + offset, addr_byte_size, 0, &success); if (!success) - return false; - - addr_t address = Rn + addr_byte_size; - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterPlusOffset; - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); - context.SetRegisterPlusOffset (dwarf_reg, offset); + return false; - for (int i = 0; i < 14; ++i) - { - if (BitIsSet (registers, i)) - { - // R[i] = MemA[address,4]; address = address + 4; - - context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); - uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) - return false; - - offset += addr_byte_size; - } - } - - // if registers<15> == '1' then - // LoadWritePC(MemA[address,4]); - if (BitIsSet (registers, 15)) - { - context.SetRegisterPlusOffset (dwarf_reg, offset); - uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); - if (!success) - return false; - // In ARMv5T and above, this is an interworking branch. - if (!LoadWritePC(context, data)) - return false; - } - - // if wback && registers == '0' then R[n] = R[n] + 4*BitCount(registers); - if (wback && BitIsClear (registers, n)) - { - if (!success) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, + data)) + return false; - offset = addr_byte_size * BitCount (registers); - context.type = EmulateInstruction::eContextAdjustBaseRegister; - context.SetImmediateSigned (offset); - addr_t addr = Rn + offset; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) - return false; - } - - // if wback && registers == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 - if (wback && BitIsSet (registers, n)) - return WriteBits32Unknown (n); + offset += addr_byte_size; + } } - return true; + + // if registers<15> == '1' then + // LoadWritePC(MemA[address,4]); + if (BitIsSet(registers, 15)) { + context.SetRegisterPlusOffset(dwarf_reg, offset); + uint32_t data = + MemARead(context, address + offset, addr_byte_size, 0, &success); + if (!success) + return false; + // In ARMv5T and above, this is an interworking branch. + if (!LoadWritePC(context, data)) + return false; + } + + // if wback && registers == '0' then R[n] = R[n] + 4*BitCount(registers); + if (wback && BitIsClear(registers, n)) { + if (!success) + return false; + + offset = addr_byte_size * BitCount(registers); + context.type = EmulateInstruction::eContextAdjustBaseRegister; + context.SetImmediateSigned(offset); + addr_t addr = Rn + offset; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + addr)) + return false; + } + + // if wback && registers == '1' then R[n] = bits(32) UNKNOWN; // Only + // possible for encoding A1 + if (wback && BitIsSet(registers, n)) + return WriteBits32Unknown(n); + } + return true; } - -// Load Register (immediate) calculates an address from a base register value and + +// Load Register (immediate) calculates an address from a base register value +// and // an immediate offset, loads a word from memory, and writes to a register. // LDR (immediate, Thumb) -bool -EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if (ConditionPassed()) @@ -3954,160 +3926,152 @@ EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncodi } #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rt; // the destination register - uint32_t Rn; // the base register - uint32_t imm32; // the immediate offset used to form the address - addr_t offset_addr; // the offset address - addr_t address; // the calculated address - uint32_t data; // the literal data value from memory load - bool add, index, wback; - switch (encoding) { - case eEncodingT1: - Rt = Bits32(opcode, 2, 0); - Rn = Bits32(opcode, 5, 3); - imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); - // index = TRUE; add = TRUE; wback = FALSE - add = true; - index = true; - wback = false; - - break; - - case eEncodingT2: - // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); - Rt = Bits32 (opcode, 10, 8); - Rn = 13; - imm32 = Bits32 (opcode, 7, 0) << 2; - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - break; - - case eEncodingT3: - // if Rn == '1111' then SEE LDR (literal); - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - Rt = Bits32 (opcode, 15, 12); - Rn = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 11, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if ((Rt == 15) && InITBlock() && !LastInITBlock()) - return false; - - break; - - case eEncodingT4: - // if Rn == '1111' then SEE LDR (literal); - // if P == '1' && U == '1' && W == '0' then SEE LDRT; - // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; - // if P == '0' && W == '0' then UNDEFINED; - if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) - return false; - - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - Rt = Bits32 (opcode, 15, 12); - Rn = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0); - - // index = (P == '1'); add = (U == '1'); wback = (W == '1'); - index = BitIsSet (opcode, 10); - add = BitIsSet (opcode, 9); - wback = BitIsSet (opcode, 8); - - // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; - if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) - return false; - - break; - - default: - return false; - } - uint32_t base = ReadCoreReg (Rn, &success); - if (!success) - return false; - if (add) - offset_addr = base + imm32; - else - offset_addr = base - imm32; + if (ConditionPassed(opcode)) { + uint32_t Rt; // the destination register + uint32_t Rn; // the base register + uint32_t imm32; // the immediate offset used to form the address + addr_t offset_addr; // the offset address + addr_t address; // the calculated address + uint32_t data; // the literal data value from memory load + bool add, index, wback; + switch (encoding) { + case eEncodingT1: + Rt = Bits32(opcode, 2, 0); + Rn = Bits32(opcode, 5, 3); + imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); + // index = TRUE; add = TRUE; wback = FALSE + add = true; + index = true; + wback = false; - address = (index ? offset_addr : base); + break; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); - if (wback) - { - EmulateInstruction::Context ctx; - if (Rn == 13) - { - ctx.type = eContextAdjustStackPointer; - ctx.SetImmediateSigned((int32_t) (offset_addr - base)); - } - else if (Rn == GetFramePointerRegisterNumber()) - { - ctx.type = eContextSetFramePointer; - ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); - } - else - { - ctx.type = EmulateInstruction::eContextAdjustBaseRegister; - ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); - } - + case eEncodingT2: + // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); + Rt = Bits32(opcode, 10, 8); + Rn = 13; + imm32 = Bits32(opcode, 7, 0) << 2; - if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) - return false; - } + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; - // Prepare to write to the Rt register. - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); + break; - // Read memory from the address. - data = MemURead(context, address, 4, 0, &success); - if (!success) - return false; + case eEncodingT3: + // if Rn == '1111' then SEE LDR (literal); + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + Rt = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 11, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; + if ((Rt == 15) && InITBlock() && !LastInITBlock()) + return false; - if (Rt == 15) - { - if (Bits32(address, 1, 0) == 0) - { - if (!LoadWritePC(context, data)) - return false; - } - else - return false; - } - else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) - { - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) - return false; - } - else - WriteBits32Unknown (Rt); + break; + + case eEncodingT4: + // if Rn == '1111' then SEE LDR (literal); + // if P == '1' && U == '1' && W == '0' then SEE LDRT; + // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == + // '00000100' then SEE POP; + // if P == '0' && W == '0' then UNDEFINED; + if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) + return false; + + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); + Rt = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0); + + // index = (P == '1'); add = (U == '1'); wback = (W == '1'); + index = BitIsSet(opcode, 10); + add = BitIsSet(opcode, 9); + wback = BitIsSet(opcode, 8); + + // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) + // then UNPREDICTABLE; + if ((wback && (Rn == Rt)) || + ((Rt == 15) && InITBlock() && !LastInITBlock())) + return false; + + break; + + default: + return false; } - return true; + uint32_t base = ReadCoreReg(Rn, &success); + if (!success) + return false; + if (add) + offset_addr = base + imm32; + else + offset_addr = base - imm32; + + address = (index ? offset_addr : base); + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); + if (wback) { + EmulateInstruction::Context ctx; + if (Rn == 13) { + ctx.type = eContextAdjustStackPointer; + ctx.SetImmediateSigned((int32_t)(offset_addr - base)); + } else if (Rn == GetFramePointerRegisterNumber()) { + ctx.type = eContextSetFramePointer; + ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); + } else { + ctx.type = EmulateInstruction::eContextAdjustBaseRegister; + ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); + } + + if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, + offset_addr)) + return false; + } + + // Prepare to write to the Rt register. + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); + + // Read memory from the address. + data = MemURead(context, address, 4, 0, &success); + if (!success) + return false; + + if (Rt == 15) { + if (Bits32(address, 1, 0) == 0) { + if (!LoadWritePC(context, data)) + return false; + } else + return false; + } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, + data)) + return false; + } else + WriteBits32Unknown(Rt); + } + return true; } -// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address -// from a base register. The consecutive memory locations start at this address, and the address just above the last +// STM (Store Multiple Increment After) stores multiple registers to consecutive +// memory locations using an address +// from a base register. The consecutive memory locations start at this +// address, and the address just above the last // of those locations can optionally be written back to the base register. -bool -EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -4125,143 +4089,141 @@ EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding enco MemA[address,4] = PCStoreValue(); if wback then R[n] = R[n] + 4*BitCount(registers); #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t n; - uint32_t registers = 0; - bool wback; - const uint32_t addr_byte_size = GetAddressByteSize(); - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; - n = Bits32 (opcode, 10, 8); - registers = Bits32 (opcode, 7, 0); - registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. - wback = true; - - // if BitCount(registers) < 1 then UNPREDICTABLE; - if (BitCount (registers) < 1) - return false; - - break; - - case eEncodingT2: - // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. - wback = BitIsSet (opcode, 21); - - // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; - if ((n == 15) || (BitCount (registers) < 2)) - return false; - - // if wback && registers == '1' then UNPREDICTABLE; - if (wback && BitIsSet (registers, n)) - return false; - - break; - - case eEncodingA1: - // n = UInt(Rn); registers = register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - wback = BitIsSet (opcode, 21); - - // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if ((n == 15) || (BitCount (registers) < 1)) - return false; - - break; - - default: - return false; - } - - // address = R[n]; - int32_t offset = 0; - const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterStore; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - // for i = 0 to 14 - uint32_t lowest_set_bit = 14; - for (uint32_t i = 0; i < 14; ++i) - { - // if registers == '1' then - if (BitIsSet (registers, i)) - { - if (i < lowest_set_bit) - lowest_set_bit = i; - // if i == n && wback && i != LowestSetBit(registers) then - if ((i == n) && wback && (i != lowest_set_bit)) - // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 - WriteBits32UnknownToMemory (address + offset); - else - { - // MemA[address,4] = R[i]; - uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); - if (!success) - return false; - - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); - if (!MemAWrite (context, address + offset, data, addr_byte_size)) - return false; - } - - // address = address + 4; - offset += addr_byte_size; - } - } - - // if registers<15> == '1' then // Only possible for encoding A1 - // MemA[address,4] = PCStoreValue(); - if (BitIsSet (registers, 15)) - { - RegisterInfo pc_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); - context.SetRegisterPlusOffset (pc_reg, 8); - const uint32_t pc = ReadCoreReg (PC_REG, &success); - if (!success) - return false; - - if (!MemAWrite (context, address + offset, pc, addr_byte_size)) - return false; - } - - // if wback then R[n] = R[n] + 4*BitCount(registers); - if (wback) - { - offset = addr_byte_size * BitCount (registers); - context.type = EmulateInstruction::eContextAdjustBaseRegister; - context.SetImmediateSigned (offset); - addr_t data = address + offset; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) - return false; - } + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t n; + uint32_t registers = 0; + bool wback; + const uint32_t addr_byte_size = GetAddressByteSize(); + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; + n = Bits32(opcode, 10, 8); + registers = Bits32(opcode, 7, 0); + registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. + wback = true; + + // if BitCount(registers) < 1 then UNPREDICTABLE; + if (BitCount(registers) < 1) + return false; + + break; + + case eEncodingT2: + // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. + wback = BitIsSet(opcode, 21); + + // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; + if ((n == 15) || (BitCount(registers) < 2)) + return false; + + // if wback && registers == '1' then UNPREDICTABLE; + if (wback && BitIsSet(registers, n)) + return false; + + break; + + case eEncodingA1: + // n = UInt(Rn); registers = register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + wback = BitIsSet(opcode, 21); + + // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; + if ((n == 15) || (BitCount(registers) < 1)) + return false; + + break; + + default: + return false; } - return true; + + // address = R[n]; + int32_t offset = 0; + const addr_t address = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterStore; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + // for i = 0 to 14 + uint32_t lowest_set_bit = 14; + for (uint32_t i = 0; i < 14; ++i) { + // if registers == '1' then + if (BitIsSet(registers, i)) { + if (i < lowest_set_bit) + lowest_set_bit = i; + // if i == n && wback && i != LowestSetBit(registers) then + if ((i == n) && wback && (i != lowest_set_bit)) + // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings + // T1 and A1 + WriteBits32UnknownToMemory(address + offset); + else { + // MemA[address,4] = R[i]; + uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, + 0, &success); + if (!success) + return false; + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); + if (!MemAWrite(context, address + offset, data, addr_byte_size)) + return false; + } + + // address = address + 4; + offset += addr_byte_size; + } + } + + // if registers<15> == '1' then // Only possible for encoding A1 + // MemA[address,4] = PCStoreValue(); + if (BitIsSet(registers, 15)) { + RegisterInfo pc_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); + context.SetRegisterPlusOffset(pc_reg, 8); + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + + if (!MemAWrite(context, address + offset, pc, addr_byte_size)) + return false; + } + + // if wback then R[n] = R[n] + 4*BitCount(registers); + if (wback) { + offset = addr_byte_size * BitCount(registers); + context.type = EmulateInstruction::eContextAdjustBaseRegister; + context.SetImmediateSigned(offset); + addr_t data = address + offset; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + data)) + return false; + } + } + return true; } -// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address -// from a base register. The consecutive memory locations end at this address, and the address just below the lowest +// STMDA (Store Multiple Decrement After) stores multiple registers to +// consecutive memory locations using an address +// from a base register. The consecutive memory locations end at this address, +// and the address just below the lowest // of those locations can optionally be written back to the base register. -bool -EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -4280,113 +4242,110 @@ EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding en if wback then R[n] = R[n] - 4*BitCount(registers); #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t n; - uint32_t registers = 0; - bool wback; - const uint32_t addr_byte_size = GetAddressByteSize(); - - // EncodingSpecificOperations(); - switch (encoding) - { - case eEncodingA1: - // n = UInt(Rn); registers = register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - wback = BitIsSet (opcode, 21); - - // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if ((n == 15) || (BitCount (registers) < 1)) - return false; - break; - default: - return false; - } - - // address = R[n] - 4*BitCount(registers) + 4; - int32_t offset = 0; - addr_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterStore; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - // for i = 0 to 14 - uint32_t lowest_bit_set = 14; - for (uint32_t i = 0; i < 14; ++i) - { - // if registers == '1' then - if (BitIsSet (registers, i)) - { - if (i < lowest_bit_set) - lowest_bit_set = i; - //if i == n && wback && i != LowestSetBit(registers) then - if ((i == n) && wback && (i != lowest_bit_set)) - // MemA[address,4] = bits(32) UNKNOWN; - WriteBits32UnknownToMemory (address + offset); - else - { - // MemA[address,4] = R[i]; - uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); - if (!success) - return false; - - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); - if (!MemAWrite (context, address + offset, data, addr_byte_size)) - return false; - } - - // address = address + 4; - offset += addr_byte_size; - } - } - - // if registers<15> == '1' then - // MemA[address,4] = PCStoreValue(); - if (BitIsSet (registers, 15)) - { - RegisterInfo pc_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); - context.SetRegisterPlusOffset (pc_reg, 8); - const uint32_t pc = ReadCoreReg (PC_REG, &success); - if (!success) - return false; - - if (!MemAWrite (context, address + offset, pc, addr_byte_size)) - return false; - } - - // if wback then R[n] = R[n] - 4*BitCount(registers); - if (wback) - { - offset = (addr_byte_size * BitCount (registers)) * -1; - context.type = EmulateInstruction::eContextAdjustBaseRegister; - context.SetImmediateSigned (offset); - addr_t data = Rn + offset; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) - return false; - } + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t n; + uint32_t registers = 0; + bool wback; + const uint32_t addr_byte_size = GetAddressByteSize(); + + // EncodingSpecificOperations(); + switch (encoding) { + case eEncodingA1: + // n = UInt(Rn); registers = register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + wback = BitIsSet(opcode, 21); + + // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; + if ((n == 15) || (BitCount(registers) < 1)) + return false; + break; + default: + return false; } - return true; + + // address = R[n] - 4*BitCount(registers) + 4; + int32_t offset = 0; + addr_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterStore; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + // for i = 0 to 14 + uint32_t lowest_bit_set = 14; + for (uint32_t i = 0; i < 14; ++i) { + // if registers == '1' then + if (BitIsSet(registers, i)) { + if (i < lowest_bit_set) + lowest_bit_set = i; + // if i == n && wback && i != LowestSetBit(registers) then + if ((i == n) && wback && (i != lowest_bit_set)) + // MemA[address,4] = bits(32) UNKNOWN; + WriteBits32UnknownToMemory(address + offset); + else { + // MemA[address,4] = R[i]; + uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, + 0, &success); + if (!success) + return false; + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + Rn - (address + offset)); + if (!MemAWrite(context, address + offset, data, addr_byte_size)) + return false; + } + + // address = address + 4; + offset += addr_byte_size; + } + } + + // if registers<15> == '1' then + // MemA[address,4] = PCStoreValue(); + if (BitIsSet(registers, 15)) { + RegisterInfo pc_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); + context.SetRegisterPlusOffset(pc_reg, 8); + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + + if (!MemAWrite(context, address + offset, pc, addr_byte_size)) + return false; + } + + // if wback then R[n] = R[n] - 4*BitCount(registers); + if (wback) { + offset = (addr_byte_size * BitCount(registers)) * -1; + context.type = EmulateInstruction::eContextAdjustBaseRegister; + context.SetImmediateSigned(offset); + addr_t data = Rn + offset; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + data)) + return false; + } + } + return true; } - -// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address -// from a base register. The consecutive memory locations end just below this address, and the address of the first of + +// STMDB (Store Multiple Decrement Before) stores multiple registers to +// consecutive memory locations using an address +// from a base register. The consecutive memory locations end just below this +// address, and the address of the first of // those locations can optionally be written back to the base register. -bool -EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -4406,138 +4365,136 @@ EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding en if wback then R[n] = R[n] - 4*BitCount(registers); #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t n; - uint32_t registers = 0; - bool wback; - const uint32_t addr_byte_size = GetAddressByteSize(); - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // if W == '1' && Rn == '1101' then SEE PUSH; - if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) - { - // See PUSH - } - // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. - wback = BitIsSet (opcode, 21); - // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; - if ((n == 15) || BitCount (registers) < 2) - return false; - // if wback && registers == '1' then UNPREDICTABLE; - if (wback && BitIsSet (registers, n)) - return false; - break; - - case eEncodingA1: - // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE PUSH; - if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) - { - // See Push - } - // n = UInt(Rn); registers = register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - wback = BitIsSet (opcode, 21); - // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if ((n == 15) || BitCount (registers) < 1) - return false; - break; - - default: - return false; - } - - // address = R[n] - 4*BitCount(registers); - - int32_t offset = 0; - addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t n; + uint32_t registers = 0; + bool wback; + const uint32_t addr_byte_size = GetAddressByteSize(); + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // if W == '1' && Rn == '1101' then SEE PUSH; + if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { + // See PUSH + } + // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. + wback = BitIsSet(opcode, 21); + // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; + if ((n == 15) || BitCount(registers) < 2) return false; - - addr_t address = Rn - (addr_byte_size * BitCount (registers)); - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterStore; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - // for i = 0 to 14 - uint32_t lowest_set_bit = 14; - for (uint32_t i = 0; i < 14; ++i) - { - // if registers == '1' then - if (BitIsSet (registers, i)) - { - if (i < lowest_set_bit) - lowest_set_bit = i; - // if i == n && wback && i != LowestSetBit(registers) then - if ((i == n) && wback && (i != lowest_set_bit)) - // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 - WriteBits32UnknownToMemory (address + offset); - else - { - // MemA[address,4] = R[i]; - uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); - if (!success) - return false; - - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); - if (!MemAWrite (context, address + offset, data, addr_byte_size)) - return false; - } - - // address = address + 4; - offset += addr_byte_size; - } - } - - // if registers<15> == '1' then // Only possible for encoding A1 - // MemA[address,4] = PCStoreValue(); - if (BitIsSet (registers, 15)) - { - RegisterInfo pc_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); - context.SetRegisterPlusOffset (pc_reg, 8); - const uint32_t pc = ReadCoreReg (PC_REG, &success); - if (!success) - return false; - - if (!MemAWrite (context, address + offset, pc, addr_byte_size)) - return false; - } - - // if wback then R[n] = R[n] - 4*BitCount(registers); - if (wback) - { - offset = (addr_byte_size * BitCount (registers)) * -1; - context.type = EmulateInstruction::eContextAdjustBaseRegister; - context.SetImmediateSigned (offset); - addr_t data = Rn + offset; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) - return false; - } + // if wback && registers == '1' then UNPREDICTABLE; + if (wback && BitIsSet(registers, n)) + return false; + break; + + case eEncodingA1: + // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE + // PUSH; + if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && + BitCount(Bits32(opcode, 15, 0)) >= 2) { + // See Push + } + // n = UInt(Rn); registers = register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + wback = BitIsSet(opcode, 21); + // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; + if ((n == 15) || BitCount(registers) < 1) + return false; + break; + + default: + return false; } - return true; + + // address = R[n] - 4*BitCount(registers); + + int32_t offset = 0; + addr_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + addr_t address = Rn - (addr_byte_size * BitCount(registers)); + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterStore; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + // for i = 0 to 14 + uint32_t lowest_set_bit = 14; + for (uint32_t i = 0; i < 14; ++i) { + // if registers == '1' then + if (BitIsSet(registers, i)) { + if (i < lowest_set_bit) + lowest_set_bit = i; + // if i == n && wback && i != LowestSetBit(registers) then + if ((i == n) && wback && (i != lowest_set_bit)) + // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding + // A1 + WriteBits32UnknownToMemory(address + offset); + else { + // MemA[address,4] = R[i]; + uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, + 0, &success); + if (!success) + return false; + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + Rn - (address + offset)); + if (!MemAWrite(context, address + offset, data, addr_byte_size)) + return false; + } + + // address = address + 4; + offset += addr_byte_size; + } + } + + // if registers<15> == '1' then // Only possible for encoding A1 + // MemA[address,4] = PCStoreValue(); + if (BitIsSet(registers, 15)) { + RegisterInfo pc_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); + context.SetRegisterPlusOffset(pc_reg, 8); + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + + if (!MemAWrite(context, address + offset, pc, addr_byte_size)) + return false; + } + + // if wback then R[n] = R[n] - 4*BitCount(registers); + if (wback) { + offset = (addr_byte_size * BitCount(registers)) * -1; + context.type = EmulateInstruction::eContextAdjustBaseRegister; + context.SetImmediateSigned(offset); + addr_t data = Rn + offset; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + data)) + return false; + } + } + return true; } - -// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address -// from a base register. The consecutive memory locations start just above this address, and the address of the last + +// STMIB (Store Multiple Increment Before) stores multiple registers to +// consecutive memory locations using an address +// from a base register. The consecutive memory locations start just above this +// address, and the address of the last // of those locations can optionally be written back to the base register. -bool -EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -4555,114 +4512,111 @@ EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding en MemA[address,4] = PCStoreValue(); if wback then R[n] = R[n] + 4*BitCount(registers); -#endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t n; - uint32_t registers = 0; - bool wback; - const uint32_t addr_byte_size = GetAddressByteSize(); - - // EncodingSpecificOperations(); - switch (encoding) - { - case eEncodingA1: - // n = UInt(Rn); registers = register_list; wback = (W == '1'); - n = Bits32 (opcode, 19, 16); - registers = Bits32 (opcode, 15, 0); - wback = BitIsSet (opcode, 21); - - // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if ((n == 15) && (BitCount (registers) < 1)) - return false; - break; - default: - return false; - } - // address = R[n] + 4; - - int32_t offset = 0; - addr_t Rn = ReadCoreReg (n, &success); - if (!success) +#endif + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t n; + uint32_t registers = 0; + bool wback; + const uint32_t addr_byte_size = GetAddressByteSize(); + + // EncodingSpecificOperations(); + switch (encoding) { + case eEncodingA1: + // n = UInt(Rn); registers = register_list; wback = (W == '1'); + n = Bits32(opcode, 19, 16); + registers = Bits32(opcode, 15, 0); + wback = BitIsSet(opcode, 21); + + // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; + if ((n == 15) && (BitCount(registers) < 1)) + return false; + break; + default: + return false; + } + // address = R[n] + 4; + + int32_t offset = 0; + addr_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + addr_t address = Rn + addr_byte_size; + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextRegisterStore; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t lowest_set_bit = 14; + // for i = 0 to 14 + for (uint32_t i = 0; i < 14; ++i) { + // if registers == '1' then + if (BitIsSet(registers, i)) { + if (i < lowest_set_bit) + lowest_set_bit = i; + // if i == n && wback && i != LowestSetBit(registers) then + if ((i == n) && wback && (i != lowest_set_bit)) + // MemA[address,4] = bits(32) UNKNOWN; + WriteBits32UnknownToMemory(address + offset); + // else + else { + // MemA[address,4] = R[i]; + uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, + 0, &success); + if (!success) return false; - - addr_t address = Rn + addr_byte_size; - - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextRegisterStore; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t lowest_set_bit = 14; - // for i = 0 to 14 - for (uint32_t i = 0; i < 14; ++i) - { - // if registers == '1' then - if (BitIsSet (registers, i)) - { - if (i < lowest_set_bit) - lowest_set_bit = i; - // if i == n && wback && i != LowestSetBit(registers) then - if ((i == n) && wback && (i != lowest_set_bit)) - // MemA[address,4] = bits(32) UNKNOWN; - WriteBits32UnknownToMemory (address + offset); - // else - else - { - // MemA[address,4] = R[i]; - uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); - if (!success) - return false; - - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); - if (!MemAWrite (context, address + offset, data, addr_byte_size)) - return false; - } - - // address = address + 4; - offset += addr_byte_size; - } - } - - // if registers<15> == '1' then - // MemA[address,4] = PCStoreValue(); - if (BitIsSet (registers, 15)) - { - RegisterInfo pc_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); - context.SetRegisterPlusOffset (pc_reg, 8); - const uint32_t pc = ReadCoreReg (PC_REG, &success); - if (!success) + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + offset + addr_byte_size); + if (!MemAWrite(context, address + offset, data, addr_byte_size)) return false; - - if (!MemAWrite (context, address + offset, pc, addr_byte_size)) - return false; - } - - // if wback then R[n] = R[n] + 4*BitCount(registers); - if (wback) - { - offset = addr_byte_size * BitCount (registers); - context.type = EmulateInstruction::eContextAdjustBaseRegister; - context.SetImmediateSigned (offset); - addr_t data = Rn + offset; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) - return false; } + + // address = address + 4; + offset += addr_byte_size; + } } - return true; + + // if registers<15> == '1' then + // MemA[address,4] = PCStoreValue(); + if (BitIsSet(registers, 15)) { + RegisterInfo pc_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); + context.SetRegisterPlusOffset(pc_reg, 8); + const uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + + if (!MemAWrite(context, address + offset, pc, addr_byte_size)) + return false; + } + + // if wback then R[n] = R[n] + 4*BitCount(registers); + if (wback) { + offset = addr_byte_size * BitCount(registers); + context.type = EmulateInstruction::eContextAdjustBaseRegister; + context.SetImmediateSigned(offset); + addr_t data = Rn + offset; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + data)) + return false; + } + } + return true; } -// STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word -// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. -bool -EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) -{ +// STR (store immediate) calculates an address from a base register value and an +// immediate offset, and stores a word +// from a register to memory. It can use offset, post-indexed, or pre-indexed +// addressing. +bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -4674,163 +4628,162 @@ EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding MemU[address,4] = bits(32) UNKNOWN; if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - const uint32_t addr_byte_size = GetAddressByteSize(); - - uint32_t t; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - // EncodingSpecificOperations (); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - imm32 = Bits32 (opcode, 10, 6) << 2; - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = false; - wback = false; - break; - - case eEncodingT2: - // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); - t = Bits32 (opcode, 10, 8); - n = 13; - imm32 = Bits32 (opcode, 7, 0) << 2; - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - break; - - case eEncodingT3: - // if Rn == '1111' then UNDEFINED; - if (Bits32 (opcode, 19, 16) == 15) - return false; - - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 11, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // if t == 15 then UNPREDICTABLE; - if (t == 15) - return false; - break; - - case eEncodingT4: - // if P == '1' && U == '1' && W == '0' then SEE STRT; - // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; - // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; - if ((Bits32 (opcode, 19, 16) == 15) - || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) - return false; - - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0); - - // index = (P == '1'); add = (U == '1'); wback = (W == '1'); - index = BitIsSet (opcode, 10); - add = BitIsSet (opcode, 9); - wback = BitIsSet (opcode, 8); - - // if t == 15 || (wback && n == t) then UNPREDICTABLE; - if ((t == 15) || (wback && (n == t))) - return false; - break; - - default: - return false; - } - - addr_t offset_addr; - addr_t address; - - // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - uint32_t base_address = ReadCoreReg (n, &success); - if (!success) - return false; - - if (add) - offset_addr = base_address + imm32; - else - offset_addr = base_address - imm32; - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = base_address; - - EmulateInstruction::Context context; - if (n == 13) - context.type = eContextPushRegisterOnStack; - else - context.type = eContextRegisterStore; + bool success = false; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - // if UnalignedSupport() || address<1:0> == '00' then - if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) - { - // MemU[address,4] = R[t]; - uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); - if (!success) - return false; - - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); - int32_t offset = address - base_address; - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); - if (!MemUWrite (context, address, data, addr_byte_size)) - return false; - } - else - { - // MemU[address,4] = bits(32) UNKNOWN; - WriteBits32UnknownToMemory (address); - } - - // if wback then R[n] = offset_addr; - if (wback) - { - if (n == 13) - context.type = eContextAdjustStackPointer; - else - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); + if (ConditionPassed(opcode)) { + const uint32_t addr_byte_size = GetAddressByteSize(); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + uint32_t t; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + // EncodingSpecificOperations (); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + imm32 = Bits32(opcode, 10, 6) << 2; + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = false; + wback = false; + break; + + case eEncodingT2: + // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); + t = Bits32(opcode, 10, 8); + n = 13; + imm32 = Bits32(opcode, 7, 0) << 2; + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + break; + + case eEncodingT3: + // if Rn == '1111' then UNDEFINED; + if (Bits32(opcode, 19, 16) == 15) + return false; + + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 11, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // if t == 15 then UNPREDICTABLE; + if (t == 15) + return false; + break; + + case eEncodingT4: + // if P == '1' && U == '1' && W == '0' then SEE STRT; + // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == + // '00000100' then SEE PUSH; + // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; + if ((Bits32(opcode, 19, 16) == 15) || + (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) + return false; + + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0); + + // index = (P == '1'); add = (U == '1'); wback = (W == '1'); + index = BitIsSet(opcode, 10); + add = BitIsSet(opcode, 9); + wback = BitIsSet(opcode, 8); + + // if t == 15 || (wback && n == t) then UNPREDICTABLE; + if ((t == 15) || (wback && (n == t))) + return false; + break; + + default: + return false; } - return true; + + addr_t offset_addr; + addr_t address; + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + uint32_t base_address = ReadCoreReg(n, &success); + if (!success) + return false; + + if (add) + offset_addr = base_address + imm32; + else + offset_addr = base_address - imm32; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = base_address; + + EmulateInstruction::Context context; + if (n == 13) + context.type = eContextPushRegisterOnStack; + else + context.type = eContextRegisterStore; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + // if UnalignedSupport() || address<1:0> == '00' then + if (UnalignedSupport() || + (BitIsClear(address, 1) && BitIsClear(address, 0))) { + // MemU[address,4] = R[t]; + uint32_t data = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); + if (!success) + return false; + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); + int32_t offset = address - base_address; + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); + if (!MemUWrite(context, address, data, addr_byte_size)) + return false; + } else { + // MemU[address,4] = bits(32) UNKNOWN; + WriteBits32UnknownToMemory(address); + } + + // if wback then R[n] = offset_addr; + if (wback) { + if (n == 13) + context.type = eContextAdjustStackPointer; + else + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } - -// STR (Store Register) calculates an address from a base register value and an offset register value, stores a -// word from a register to memory. The offset register value can optionally be shifted. -bool -EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) -{ + +// STR (Store Register) calculates an address from a base register value and an +// offset register value, stores a +// word from a register to memory. The offset register value can optionally be +// shifted. +bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -4847,180 +4800,180 @@ EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncod MemU[address,4] = bits(32) UNKNOWN; if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - const uint32_t addr_byte_size = GetAddressByteSize(); - - uint32_t t; - uint32_t n; - uint32_t m; - ARM_ShifterType shift_t; - uint32_t shift_n; - bool index; - bool add; - bool wback; - - // EncodingSpecificOperations (); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - m = Bits32 (opcode, 8, 6); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - break; - - case eEncodingT2: - // if Rn == '1111' then UNDEFINED; - if (Bits32 (opcode, 19, 16) == 15) - return false; - - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - shift_t = SRType_LSL; - shift_n = Bits32 (opcode, 5, 4); - - // if t == 15 || BadReg(m) then UNPREDICTABLE; - if ((t == 15) || (BadReg (m))) - return false; - break; - - case eEncodingA1: - { - // if P == '0' && W == '1' then SEE STRT; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); - - // (shift_t, shift_n) = DecodeImmShift(type, imm5); - uint32_t typ = Bits32 (opcode, 6, 5); - uint32_t imm5 = Bits32 (opcode, 11, 7); - shift_n = DecodeImmShift(typ, imm5, shift_t); - - // if m == 15 then UNPREDICTABLE; - if (m == 15) - return false; - - // if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t))) - return false; - - break; - } - default: - return false; - } - - addr_t offset_addr; - addr_t address; - int32_t offset = 0; - - addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - // offset = Shift(R[m], shift_t, shift_n, APSR.C); - offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - - // offset_addr = if add then (R[n] + offset) else (R[n] - offset); - if (add) - offset_addr = base_address + offset; - else - offset_addr = base_address - offset; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = base_address; - - uint32_t data; - // if t == 15 then // Only possible for encoding A1 - if (t == 15) - // data = PCStoreValue(); - data = ReadCoreReg (PC_REG, &success); - else - // data = R[t]; - data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); - - if (!success) - return false; - - EmulateInstruction::Context context; - context.type = eContextRegisterStore; - - // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then - if (UnalignedSupport () - || (BitIsClear (address, 1) && BitIsClear (address, 0)) - || CurrentInstrSet() == eModeARM) - { - // MemU[address,4] = data; - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); - - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); - if (!MemUWrite (context, address, data, addr_byte_size)) - return false; - - } - else - // MemU[address,4] = bits(32) UNKNOWN; - WriteBits32UnknownToMemory (address); - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextRegisterLoad; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + bool success = false; + + if (ConditionPassed(opcode)) { + const uint32_t addr_byte_size = GetAddressByteSize(); + + uint32_t t; + uint32_t n; + uint32_t m; + ARM_ShifterType shift_t; + uint32_t shift_n; + bool index; + bool add; + bool wback; + + // EncodingSpecificOperations (); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation + // in ThumbEE"; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + m = Bits32(opcode, 8, 6); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + break; + + case eEncodingT2: + // if Rn == '1111' then UNDEFINED; + if (Bits32(opcode, 19, 16) == 15) + return false; + + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); + shift_t = SRType_LSL; + shift_n = Bits32(opcode, 5, 4); + + // if t == 15 || BadReg(m) then UNPREDICTABLE; + if ((t == 15) || (BadReg(m))) + return false; + break; + + case eEncodingA1: { + // if P == '0' && W == '1' then SEE STRT; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || + // (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); + + // (shift_t, shift_n) = DecodeImmShift(type, imm5); + uint32_t typ = Bits32(opcode, 6, 5); + uint32_t imm5 = Bits32(opcode, 11, 7); + shift_n = DecodeImmShift(typ, imm5, shift_t); + + // if m == 15 then UNPREDICTABLE; + if (m == 15) + return false; + + // if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t))) + return false; + + break; } - return true; + default: + return false; + } + + addr_t offset_addr; + addr_t address; + int32_t offset = 0; + + addr_t base_address = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + uint32_t Rm_data = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + // offset = Shift(R[m], shift_t, shift_n, APSR.C); + offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + + // offset_addr = if add then (R[n] + offset) else (R[n] - offset); + if (add) + offset_addr = base_address + offset; + else + offset_addr = base_address - offset; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = base_address; + + uint32_t data; + // if t == 15 then // Only possible for encoding A1 + if (t == 15) + // data = PCStoreValue(); + data = ReadCoreReg(PC_REG, &success); + else + // data = R[t]; + data = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); + + if (!success) + return false; + + EmulateInstruction::Context context; + context.type = eContextRegisterStore; + + // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == + // InstrSet_ARM then + if (UnalignedSupport() || + (BitIsClear(address, 1) && BitIsClear(address, 0)) || + CurrentInstrSet() == eModeARM) { + // MemU[address,4] = data; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); + + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + address - base_address); + if (!MemUWrite(context, address, data, addr_byte_size)) + return false; + + } else + // MemU[address,4] = bits(32) UNKNOWN; + WriteBits32UnknownToMemory(address); + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextRegisterLoad; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } - -bool -EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) -{ + +bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -5030,134 +4983,134 @@ EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncodin if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - imm32 = Bits32 (opcode, 10, 6); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - break; - - case eEncodingT2: - // if Rn == '1111' then UNDEFINED; - if (Bits32 (opcode, 19, 16) == 15) - return false; - - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 11, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // if BadReg(t) then UNPREDICTABLE; - if (BadReg (t)) - return false; - break; - - case eEncodingT3: - // if P == '1' && U == '1' && W == '0' then SEE STRBT; - // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; - if (Bits32 (opcode, 19, 16) == 15) - return false; - - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0); - - // index = (P == '1'); add = (U == '1'); wback = (W == '1'); - index = BitIsSet (opcode, 10); - add = BitIsSet (opcode, 9); - wback = BitIsSet (opcode, 8); - - // if BadReg(t) || (wback && n == t) then UNPREDICTABLE - if ((BadReg (t)) || (wback && (n == t))) - return false; - break; - - default: - return false; - } - - addr_t offset_addr; - addr_t address; - addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - if (add) - offset_addr = base_address + imm32; - else - offset_addr = base_address - imm32; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = base_address; - - // MemU[address,1] = R[t]<7:0> - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterStore; - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); - - uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); - if (!success) - return false; - - data = Bits32 (data, 7, 0); + bool success = false; - if (!MemUWrite (context, address, data, 1)) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextRegisterLoad; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } - + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + imm32 = Bits32(opcode, 10, 6); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + break; + + case eEncodingT2: + // if Rn == '1111' then UNDEFINED; + if (Bits32(opcode, 19, 16) == 15) + return false; + + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 11, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // if BadReg(t) then UNPREDICTABLE; + if (BadReg(t)) + return false; + break; + + case eEncodingT3: + // if P == '1' && U == '1' && W == '0' then SEE STRBT; + // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; + if (Bits32(opcode, 19, 16) == 15) + return false; + + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0); + + // index = (P == '1'); add = (U == '1'); wback = (W == '1'); + index = BitIsSet(opcode, 10); + add = BitIsSet(opcode, 9); + wback = BitIsSet(opcode, 8); + + // if BadReg(t) || (wback && n == t) then UNPREDICTABLE + if ((BadReg(t)) || (wback && (n == t))) + return false; + break; + + default: + return false; } - return true; + addr_t offset_addr; + addr_t address; + addr_t base_address = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + if (add) + offset_addr = base_address + imm32; + else + offset_addr = base_address - imm32; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = base_address; + + // MemU[address,1] = R[t]<7:0> + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterStore; + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + address - base_address); + + uint32_t data = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); + if (!success) + return false; + + data = Bits32(data, 7, 0); + + if (!MemUWrite(context, address, data, 1)) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextRegisterLoad; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + + return true; } -// STRH (register) calculates an address from a base register value and an offset register value, and stores a -// halfword from a register to memory. The offset register value can be shifted left by 0, 1, 2, or 3 bits. -bool -EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) -{ +// STRH (register) calculates an address from a base register value and an +// offset register value, and stores a +// halfword from a register to memory. The offset register value can be shifted +// left by 0, 1, 2, or 3 bits. +bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -5170,174 +5123,174 @@ EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEnco MemU[address,2] = bits(16) UNKNOWN; if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t m; + bool index; + bool add; + bool wback; + ARM_ShifterType shift_t; + uint32_t shift_n; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation + // in ThumbEE"; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + m = Bits32(opcode, 8, 6); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + + break; + + case eEncodingT2: + // if Rn == '1111' then UNDEFINED; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + if (n == 15) + return false; + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); + shift_t = SRType_LSL; + shift_n = Bits32(opcode, 5, 4); + + // if BadReg(t) || BadReg(m) then UNPREDICTABLE; + if (BadReg(t) || BadReg(m)) + return false; + + break; + + case eEncodingA1: + // if P == '0' && W == '1' then SEE STRHT; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || + // (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + + // if t == 15 || m == 15 then UNPREDICTABLE; + if ((t == 15) || (m == 15)) + return false; + + // if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t))) + return false; + + break; + + default: + return false; + } + + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // offset = Shift(R[m], shift_t, shift_n, APSR.C); + uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + + // offset_addr = if add then (R[n] + offset) else (R[n] - offset); + addr_t offset_addr; + if (add) + offset_addr = Rn + offset; + else + offset_addr = Rn - offset; + + // address = if index then offset_addr else R[n]; + addr_t address; + if (index) + address = offset_addr; + else + address = Rn; + + EmulateInstruction::Context context; + context.type = eContextRegisterStore; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + RegisterInfo offset_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); + + // if UnalignedSupport() || address<0> == '0' then + if (UnalignedSupport() || BitIsClear(address, 0)) { + // MemU[address,2] = R[t]<15:0>; + uint32_t Rt = ReadCoreReg(t, &success); + if (!success) + return false; + + EmulateInstruction::Context context; + context.type = eContextRegisterStore; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + RegisterInfo offset_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); + context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, + data_reg); + + if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) + return false; + } else // Can only occur before ARMv7 { - uint32_t t; - uint32_t n; - uint32_t m; - bool index; - bool add; - bool wback; - ARM_ShifterType shift_t; - uint32_t shift_n; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - m = Bits32 (opcode, 8, 6); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - - break; - - case eEncodingT2: - // if Rn == '1111' then UNDEFINED; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - if (n == 15) - return false; - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - shift_t = SRType_LSL; - shift_n = Bits32 (opcode, 5, 4); - - // if BadReg(t) || BadReg(m) then UNPREDICTABLE; - if (BadReg (t) || BadReg (m)) - return false; - - break; - - case eEncodingA1: - // if P == '0' && W == '1' then SEE STRHT; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - - // if t == 15 || m == 15 then UNPREDICTABLE; - if ((t == 15) || (m == 15)) - return false; - - // if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t))) - return false; - - break; - - default: - return false; - } - - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; - - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - // offset = Shift(R[m], shift_t, shift_n, APSR.C); - uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - - // offset_addr = if add then (R[n] + offset) else (R[n] - offset); - addr_t offset_addr; - if (add) - offset_addr = Rn + offset; - else - offset_addr = Rn - offset; - - // address = if index then offset_addr else R[n]; - addr_t address; - if (index) - address = offset_addr; - else - address = Rn; - - EmulateInstruction::Context context; - context.type = eContextRegisterStore; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - RegisterInfo offset_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); - - // if UnalignedSupport() || address<0> == '0' then - if (UnalignedSupport() || BitIsClear (address, 0)) - { - // MemU[address,2] = R[t]<15:0>; - uint32_t Rt = ReadCoreReg (t, &success); - if (!success) - return false; - - EmulateInstruction::Context context; - context.type = eContextRegisterStore; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - RegisterInfo offset_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); - context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); - - if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) - return false; - } - else // Can only occur before ARMv7 - { - // MemU[address,2] = bits(16) UNKNOWN; - } - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + // MemU[address,2] = bits(16) UNKNOWN; } - return true; + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + + return true; } - -// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, -// and writes the result to the destination register. It can optionally update the condition flags + +// Add with Carry (immediate) adds an immediate value and the carry flag value +// to a register value, +// and writes the result to the destination register. It can optionally update +// the condition flags // based on the result. -bool -EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -5354,59 +5307,60 @@ EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn; - uint32_t imm32; // the immediate value to be added to the value obtained from Rn - bool setflags; - switch (encoding) - { - case eEncodingT1: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) - if (BadReg(Rd) || BadReg(Rn)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn; + uint32_t + imm32; // the immediate value to be added to the value obtained from Rn + bool setflags; + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) + if (BadReg(Rd) || BadReg(Rn)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } - // Read the first operand. - int32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + int32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); + AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; + } + return true; } -// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted -// register value, and writes the result to the destination register. It can optionally update the +// Add with Carry (register) adds a register value, the carry flag value, and an +// optionally-shifted +// register value, and writes the result to the destination register. It can +// optionally update the // condition flags based on the result. -bool -EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -5424,76 +5378,75 @@ EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn, Rm; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - bool setflags; - switch (encoding) - { - case eEncodingT1: - Rd = Rn = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - shift_t = SRType_LSL; - shift_n = 0; - break; - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftARM(opcode, shift_t); - - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - - // Read the first operand. - int32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; - - // Read the second operand. - int32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; + bool success = false; - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn, Rm; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + bool setflags; + switch (encoding) { + case eEncodingT1: + Rd = Rn = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + shift_t = SRType_LSL; + shift_n = 0; + break; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftARM(opcode, shift_t); + + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + // Read the first operand. + int32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; - } - return true; + // Read the second operand. + int32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; + + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; + } + return true; } -// This instruction adds an immediate value to the PC value to form a PC-relative address, +// This instruction adds an immediate value to the PC value to form a +// PC-relative address, // and writes the result to the destination register. -bool -EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -5505,60 +5458,59 @@ EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding enco R[d] = result; #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd; - uint32_t imm32; // the immediate value to be added/subtracted to/from the PC - bool add; - switch (encoding) - { - case eEncodingT1: - Rd = Bits32(opcode, 10, 8); - imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) - add = true; - break; - case eEncodingT2: - case eEncodingT3: - Rd = Bits32(opcode, 11, 8); - imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) - add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB - if (BadReg(Rd)) - return false; - break; - case eEncodingA1: - case eEncodingA2: - Rd = Bits32(opcode, 15, 12); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd; + uint32_t imm32; // the immediate value to be added/subtracted to/from the PC + bool add; + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 10, 8); + imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) + add = true; + break; + case eEncodingT2: + case eEncodingT3: + Rd = Bits32(opcode, 11, 8); + imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) + add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB + if (BadReg(Rd)) + return false; + break; + case eEncodingA1: + case eEncodingA2: + Rd = Bits32(opcode, 15, 12); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB + break; + default: + return false; + } - // Read the PC value. - uint32_t pc = ReadCoreReg(PC_REG, &success); - if (!success) - return false; + // Read the PC value. + uint32_t pc = ReadCoreReg(PC_REG, &success); + if (!success) + return false; - uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); + uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreReg(context, result, Rd)) - return false; - } - return true; + if (!WriteCoreReg(context, result, Rd)) + return false; + } + return true; } -// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result -// to the destination register. It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) -{ +// This instruction performs a bitwise AND of a register value and an immediate +// value, and writes the result +// to the destination register. It can optionally update the condition flags +// based on the result. +bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -5575,63 +5527,67 @@ EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn; - uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn - bool setflags; - uint32_t carry; // the carry bit after ARM/Thumb Expand operation - switch (encoding) - { - case eEncodingT1: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) - // if Rd == '1111' && S == '1' then SEE TST (immediate); - if (Rd == 15 && setflags) - return EmulateTSTImm(opcode, eEncodingT1); - if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) - - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn; + uint32_t + imm32; // the immediate value to be ANDed to the value obtained from Rn + bool setflags; + uint32_t carry; // the carry bit after ARM/Thumb Expand operation + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm_C( + opcode, APSR_C, + carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) + // if Rd == '1111' && S == '1' then SEE TST (immediate); + if (Rd == 15 && setflags) + return EmulateTSTImm(opcode, eEncodingT1); + if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = + ARMExpandImm_C(opcode, APSR_C, + carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) + + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t result = val1 & imm32; + uint32_t result = val1 & imm32; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -// This instruction performs a bitwise AND of a register value and an optionally-shifted register value, -// and writes the result to the destination register. It can optionally update the condition flags +// This instruction performs a bitwise AND of a register value and an +// optionally-shifted register value, +// and writes the result to the destination register. It can optionally update +// the condition flags // based on the result. -bool -EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -5649,81 +5605,80 @@ EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn, Rm; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - bool setflags; - uint32_t carry; - switch (encoding) - { - case eEncodingT1: - Rd = Rn = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - shift_t = SRType_LSL; - shift_n = 0; - break; - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - // if Rd == '1111' && S == '1' then SEE TST (register); - if (Rd == 15 && setflags) - return EmulateTSTReg(opcode, eEncodingT2); - if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftARM(opcode, shift_t); - - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn, Rm; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + bool setflags; + uint32_t carry; + switch (encoding) { + case eEncodingT1: + Rd = Rn = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + shift_t = SRType_LSL; + shift_n = 0; + break; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + // if Rd == '1111' && S == '1' then SEE TST (register); + if (Rd == 15 && setflags) + return EmulateTSTReg(opcode, eEncodingT2); + if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftARM(opcode, shift_t); + + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - // Read the second operand. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; + // Read the second operand. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); - if (!success) - return false; - uint32_t result = val1 & shifted; + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; + uint32_t result = val1 & shifted; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an -// immediate value, and writes the result to the destination register. It can optionally update the +// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and +// the complement of an +// immediate value, and writes the result to the destination register. It can +// optionally update the // condition flags based on the result. -bool -EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -5740,61 +5695,66 @@ EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn; - uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn - bool setflags; - uint32_t carry; // the carry bit after ARM/Thumb Expand operation - switch (encoding) - { - case eEncodingT1: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) - if (BadReg(Rd) || BadReg(Rn)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn; + uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to + // the value obtained from Rn + bool setflags; + uint32_t carry; // the carry bit after ARM/Thumb Expand operation + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm_C( + opcode, APSR_C, + carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) + if (BadReg(Rd) || BadReg(Rn)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = + ARMExpandImm_C(opcode, APSR_C, + carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t result = val1 & ~imm32; + uint32_t result = val1 & ~imm32; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an -// optionally-shifted register value, and writes the result to the destination register. +// Bitwise Bit Clear (register) performs a bitwise AND of a register value and +// the complement of an +// optionally-shifted register value, and writes the result to the destination +// register. // It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -5812,78 +5772,78 @@ EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn, Rm; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - bool setflags; - uint32_t carry; - switch (encoding) - { - case eEncodingT1: - Rd = Rn = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - shift_t = SRType_LSL; - shift_n = 0; - break; - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftARM(opcode, shift_t); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn, Rm; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + bool setflags; + uint32_t carry; + switch (encoding) { + case eEncodingT1: + Rd = Rn = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + shift_t = SRType_LSL; + shift_n = 0; + break; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftARM(opcode, shift_t); + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - // Read the second operand. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; + // Read the second operand. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); - if (!success) - return false; - uint32_t result = val1 & ~shifted; + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; + uint32_t result = val1 & ~shifted; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word -// from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. -bool -EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) -{ +// LDR (immediate, ARM) calculates an address from a base register value and an +// immediate offset, loads a word +// from memory, and writes it to a register. It can use offset, post-indexed, +// or pre-indexed addressing. +bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -5898,131 +5858,129 @@ EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARME else // Can only apply before ARMv7 R[t] = ROR(data, 8*UInt(address<1:0>)); #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - const uint32_t addr_byte_size = GetAddressByteSize(); - - uint32_t t; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - - switch (encoding) - { - case eEncodingA1: - // if Rn == '1111' then SEE LDR (literal); - // if P == '0' && W == '1' then SEE LDRT; - // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; - // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 11, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); - - // if wback && n == t then UNPREDICTABLE; - if (wback && (n == t)) - return false; - - break; - - default: - return false; - } - - addr_t address; - addr_t offset_addr; - addr_t base_address = ReadCoreReg (n, &success); - if (!success) - return false; - - // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - if (add) - offset_addr = base_address + imm32; - else - offset_addr = base_address - imm32; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = base_address; - - // data = MemU[address,4]; - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - base_address); - - uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); - if (!success) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } - - // if t == 15 then - if (t == 15) - { - // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; - if (BitIsClear (address, 1) && BitIsClear (address, 0)) - { - // LoadWritePC (data); - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - base_address); - LoadWritePC (context, data); - } - else - return false; - } - // elsif UnalignedSupport() || address<1:0> = '00' then - else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) - { - // R[t] = data; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - base_address); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - } - // else // Can only apply before ARMv7 - else - { - // R[t] = ROR(data, 8*UInt(address<1:0>)); - data = ROR (data, Bits32 (address, 1, 0), &success); - if (!success) - return false; - context.type = eContextRegisterLoad; - context.SetImmediate (data); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - } + bool success = false; + + if (ConditionPassed(opcode)) { + const uint32_t addr_byte_size = GetAddressByteSize(); + + uint32_t t; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + + switch (encoding) { + case eEncodingA1: + // if Rn == '1111' then SEE LDR (literal); + // if P == '0' && W == '1' then SEE LDRT; + // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == + // '000000000100' then SEE POP; + // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 11, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || + // (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); + + // if wback && n == t then UNPREDICTABLE; + if (wback && (n == t)) + return false; + + break; + + default: + return false; } - return true; + + addr_t address; + addr_t offset_addr; + addr_t base_address = ReadCoreReg(n, &success); + if (!success) + return false; + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + if (add) + offset_addr = base_address + imm32; + else + offset_addr = base_address - imm32; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = base_address; + + // data = MemU[address,4]; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - base_address); + + uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); + if (!success) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + + // if t == 15 then + if (t == 15) { + // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; + if (BitIsClear(address, 1) && BitIsClear(address, 0)) { + // LoadWritePC (data); + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - base_address); + LoadWritePC(context, data); + } else + return false; + } + // elsif UnalignedSupport() || address<1:0> = '00' then + else if (UnalignedSupport() || + (BitIsClear(address, 1) && BitIsClear(address, 0))) { + // R[t] = data; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - base_address); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + data)) + return false; + } + // else // Can only apply before ARMv7 + else { + // R[t] = ROR(data, 8*UInt(address<1:0>)); + data = ROR(data, Bits32(address, 1, 0), &success); + if (!success) + return false; + context.type = eContextRegisterLoad; + context.SetImmediate(data); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + data)) + return false; + } + } + return true; } - -// LDR (register) calculates an address from a base register value and an offset register value, loads a word -// from memory, and writes it to a register. The offset register value can optionally be shifted. -bool -EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) -{ + +// LDR (register) calculates an address from a base register value and an offset +// register value, loads a word +// from memory, and writes it to a register. The offset register value can +// optionally be shifted. +bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -6041,200 +5999,195 @@ EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncod else R[t] = bits(32) UNKNOWN; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - const uint32_t addr_byte_size = GetAddressByteSize(); - - uint32_t t; - uint32_t n; - uint32_t m; - bool index; - bool add; - bool wback; - ARM_ShifterType shift_t; - uint32_t shift_n; - - switch (encoding) - { - case eEncodingT1: - // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - m = Bits32 (opcode, 8, 6); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - - break; - - case eEncodingT2: - // if Rn == '1111' then SEE LDR (literal); - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - shift_t = SRType_LSL; - shift_n = Bits32 (opcode, 5, 4); - - // if BadReg(m) then UNPREDICTABLE; - if (BadReg (m)) - return false; - - // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if ((t == 15) && InITBlock() && !LastInITBlock()) - return false; - - break; - - case eEncodingA1: - { - // if P == '0' && W == '1' then SEE LDRT; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); - - // (shift_t, shift_n) = DecodeImmShift(type, imm5); - uint32_t type = Bits32 (opcode, 6, 5); - uint32_t imm5 = Bits32 (opcode, 11, 7); - shift_n = DecodeImmShift (type, imm5, shift_t); - - // if m == 15 then UNPREDICTABLE; - if (m == 15) - return false; - - // if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t))) - return false; - } - break; - - - default: - return false; - } - - uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - addr_t offset_addr; - addr_t address; - - // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". - addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); - if (!success) - return false; - - // offset_addr = if add then (R[n] + offset) else (R[n] - offset); - if (add) - offset_addr = Rn + offset; - else - offset_addr = Rn - offset; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = Rn; - - // data = MemU[address,4]; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - EmulateInstruction::Context context; + + bool success = false; + + if (ConditionPassed(opcode)) { + const uint32_t addr_byte_size = GetAddressByteSize(); + + uint32_t t; + uint32_t n; + uint32_t m; + bool index; + bool add; + bool wback; + ARM_ShifterType shift_t; + uint32_t shift_n; + + switch (encoding) { + case eEncodingT1: + // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation + // in ThumbEE"; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + m = Bits32(opcode, 8, 6); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + + break; + + case eEncodingT2: + // if Rn == '1111' then SEE LDR (literal); + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); + shift_t = SRType_LSL; + shift_n = Bits32(opcode, 5, 4); + + // if BadReg(m) then UNPREDICTABLE; + if (BadReg(m)) + return false; + + // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; + if ((t == 15) && InITBlock() && !LastInITBlock()) + return false; + + break; + + case eEncodingA1: { + // if P == '0' && W == '1' then SEE LDRT; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || + // (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); + + // (shift_t, shift_n) = DecodeImmShift(type, imm5); + uint32_t type = Bits32(opcode, 6, 5); + uint32_t imm5 = Bits32(opcode, 11, 7); + shift_n = DecodeImmShift(type, imm5, shift_t); + + // if m == 15 then UNPREDICTABLE; + if (m == 15) + return false; + + // if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t))) + return false; + } break; + + default: + return false; + } + + uint32_t Rm = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + uint32_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + addr_t offset_addr; + addr_t address; + + // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an + // application level alias for the CPSR". + addr_t offset = + Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); + if (!success) + return false; + + // offset_addr = if add then (R[n] + offset) else (R[n] - offset); + if (add) + offset_addr = Rn + offset; + else + offset_addr = Rn - offset; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = Rn; + + // data = MemU[address,4]; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - Rn); + + uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); + if (!success) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + + // if t == 15 then + if (t == 15) { + // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; + if (BitIsClear(address, 1) && BitIsClear(address, 0)) { context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - Rn); - - uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); + context.SetRegisterPlusOffset(base_reg, address - Rn); + LoadWritePC(context, data); + } else + return false; + } + // elsif UnalignedSupport() || address<1:0> = '00' then + else if (UnalignedSupport() || + (BitIsClear(address, 1) && BitIsClear(address, 0))) { + // R[t] = data; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - Rn); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + data)) + return false; + } else // Can only apply before ARMv7 + { + // if CurrentInstrSet() == InstrSet_ARM then + if (CurrentInstrSet() == eModeARM) { + // R[t] = ROR(data, 8*UInt(address<1:0>)); + data = ROR(data, Bits32(address, 1, 0), &success); if (!success) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } - - // if t == 15 then - if (t == 15) - { - // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; - if (BitIsClear (address, 1) && BitIsClear (address, 0)) - { - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - Rn); - LoadWritePC (context, data); - } - else - return false; - } - // elsif UnalignedSupport() || address<1:0> = '00' then - else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) - { - // R[t] = data; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - Rn); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - } - else // Can only apply before ARMv7 - { - // if CurrentInstrSet() == InstrSet_ARM then - if (CurrentInstrSet () == eModeARM) - { - // R[t] = ROR(data, 8*UInt(address<1:0>)); - data = ROR (data, Bits32 (address, 1, 0), &success); - if (!success) - return false; - context.type = eContextRegisterLoad; - context.SetImmediate (data); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - } - else - { - // R[t] = bits(32) UNKNOWN; - WriteBits32Unknown (t); - } - } + return false; + context.type = eContextRegisterLoad; + context.SetImmediate(data); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + data)) + return false; + } else { + // R[t] = bits(32) UNKNOWN; + WriteBits32Unknown(t); + } } - return true; + } + return true; } // LDRB (immediate, Thumb) -bool -EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -6243,146 +6196,145 @@ EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEnc R[t] = ZeroExtend(MemU[address,1], 32); if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - imm32 = Bits32 (opcode, 10, 6); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback= false; - - break; - - case eEncodingT2: - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 11, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // if Rt == '1111' then SEE PLD; - if (t == 15) - return false; // PLD is not implemented yet - - // if Rn == '1111' then SEE LDRB (literal); - if (n == 15) - return EmulateLDRBLiteral(opcode, eEncodingT1); - - // if t == 13 then UNPREDICTABLE; - if (t == 13) - return false; - - break; - - case eEncodingT3: - // if P == '1' && U == '1' && W == '0' then SEE LDRBT; - // if P == '0' && W == '0' then UNDEFINED; - if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) - return false; - - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0); - - // index = (P == '1'); add = (U == '1'); wback = (W == '1'); - index = BitIsSet (opcode, 10); - add = BitIsSet (opcode, 9); - wback = BitIsSet (opcode, 8); - - // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; - if (t == 15) - return false; // PLD is not implemented yet - - // if Rn == '1111' then SEE LDRB (literal); - if (n == 15) - return EmulateLDRBLiteral(opcode, eEncodingT1); - - // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; - if (BadReg (t) || (wback && (n == t))) - return false; - - break; - - default: - return false; - } - - uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - addr_t address; - addr_t offset_addr; - - // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - if (add) - offset_addr = Rn + imm32; - else - offset_addr = Rn - imm32; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = Rn; - - // R[t] = ZeroExtend(MemU[address,1], 32); - RegisterInfo base_reg; - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); - - uint64_t data = MemURead (context, address, 1, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + imm32 = Bits32(opcode, 10, 6); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + break; + + case eEncodingT2: + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 11, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // if Rt == '1111' then SEE PLD; + if (t == 15) + return false; // PLD is not implemented yet + + // if Rn == '1111' then SEE LDRB (literal); + if (n == 15) + return EmulateLDRBLiteral(opcode, eEncodingT1); + + // if t == 13 then UNPREDICTABLE; + if (t == 13) + return false; + + break; + + case eEncodingT3: + // if P == '1' && U == '1' && W == '0' then SEE LDRBT; + // if P == '0' && W == '0' then UNDEFINED; + if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) + return false; + + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0); + + // index = (P == '1'); add = (U == '1'); wback = (W == '1'); + index = BitIsSet(opcode, 10); + add = BitIsSet(opcode, 9); + wback = BitIsSet(opcode, 8); + + // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; + if (t == 15) + return false; // PLD is not implemented yet + + // if Rn == '1111' then SEE LDRB (literal); + if (n == 15) + return EmulateLDRBLiteral(opcode, eEncodingT1); + + // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; + if (BadReg(t) || (wback && (n == t))) + return false; + + break; + + default: + return false; } - return true; + + uint32_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + addr_t address; + addr_t offset_addr; + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + if (add) + offset_addr = Rn + imm32; + else + offset_addr = Rn - imm32; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = Rn; + + // R[t] = ZeroExtend(MemU[address,1], 32); + RegisterInfo base_reg; + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); + + uint64_t data = MemURead(context, address, 1, 0, &success); + if (!success) + return false; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } - -// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, + +// LDRB (literal) calculates an address from the PC value and an immediate +// offset, loads a byte from memory, // zero-extends it to form a 32-bit word and writes it to a register. -bool -EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(15); @@ -6390,82 +6342,81 @@ EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncod address = if add then (base + imm32) else (base - imm32); R[t] = ZeroExtend(MemU[address,1], 32); #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t imm32; - bool add; - switch (encoding) - { - case eEncodingT1: - // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - t = Bits32 (opcode, 15, 12); - imm32 = Bits32 (opcode, 11, 0); - add = BitIsSet (opcode, 23); - - // if Rt == '1111' then SEE PLD; - if (t == 15) - return false; // PLD is not implemented yet - - // if t == 13 then UNPREDICTABLE; - if (t == 13) - return false; - - break; - - case eEncodingA1: - // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - t = Bits32 (opcode, 15, 12); - imm32 = Bits32 (opcode, 11, 0); - add = BitIsSet (opcode, 23); - - // if t == 15 then UNPREDICTABLE; - if (t == 15) - return false; - break; - - default: - return false; - } - - // base = Align(PC,4); - uint32_t pc_val = ReadCoreReg (PC_REG, &success); - if (!success) - return false; - - uint32_t base = AlignPC (pc_val); - - addr_t address; - // address = if add then (base + imm32) else (base - imm32); - if (add) - address = base + imm32; - else - address = base - imm32; - - // R[t] = ZeroExtend(MemU[address,1], 32); - EmulateInstruction::Context context; - context.type = eContextRelativeBranchImmediate; - context.SetImmediate (address - base); - - uint64_t data = MemURead (context, address, 1, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t imm32; + bool add; + switch (encoding) { + case eEncodingT1: + // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); + t = Bits32(opcode, 15, 12); + imm32 = Bits32(opcode, 11, 0); + add = BitIsSet(opcode, 23); + + // if Rt == '1111' then SEE PLD; + if (t == 15) + return false; // PLD is not implemented yet + + // if t == 13 then UNPREDICTABLE; + if (t == 13) + return false; + + break; + + case eEncodingA1: + // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); + t = Bits32(opcode, 15, 12); + imm32 = Bits32(opcode, 11, 0); + add = BitIsSet(opcode, 23); + + // if t == 15 then UNPREDICTABLE; + if (t == 15) + return false; + break; + + default: + return false; } - return true; + + // base = Align(PC,4); + uint32_t pc_val = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + + uint32_t base = AlignPC(pc_val); + + addr_t address; + // address = if add then (base + imm32) else (base - imm32); + if (add) + address = base + imm32; + else + address = base - imm32; + + // R[t] = ZeroExtend(MemU[address,1], 32); + EmulateInstruction::Context context; + context.type = eContextRelativeBranchImmediate; + context.SetImmediate(address - base); + + uint64_t data = MemURead(context, address, 1, 0, &success); + if (!success) + return false; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) + return false; + } + return true; } - -// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from -// memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can + +// LDRB (register) calculates an address from a base register value and an +// offset rigister value, loads a byte from +// memory, zero-extends it to form a 32-bit word, and writes it to a register. +// The offset register value can // optionally be shifted. -bool -EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -6475,160 +6426,160 @@ EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEnco R[t] = ZeroExtend(MemU[address,1],32); if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t n; - uint32_t m; - bool index; - bool add; - bool wback; - ARM_ShifterType shift_t; - uint32_t shift_n; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - m = Bits32 (opcode, 8, 6); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - break; - - case eEncodingT2: - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - shift_t = SRType_LSL; - shift_n = Bits32 (opcode, 5, 4); - // if Rt == '1111' then SEE PLD; - if (t == 15) - return false; // PLD is not implemented yet + bool success = false; - // if Rn == '1111' then SEE LDRB (literal); - if (n == 15) - return EmulateLDRBLiteral(opcode, eEncodingT1); - - // if t == 13 || BadReg(m) then UNPREDICTABLE; - if ((t == 13) || BadReg (m)) - return false; - break; - - case eEncodingA1: - { - // if P == '0' && W == '1' then SEE LDRBT; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); - - // (shift_t, shift_n) = DecodeImmShift(type, imm5); - uint32_t type = Bits32 (opcode, 6, 5); - uint32_t imm5 = Bits32 (opcode, 11, 7); - shift_n = DecodeImmShift (type, imm5, shift_t); - - // if t == 15 || m == 15 then UNPREDICTABLE; - if ((t == 15) || (m == 15)) - return false; - - // if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t))) - return false; - } - break; - - default: - return false; - } - - addr_t offset_addr; - addr_t address; - - // offset = Shift(R[m], shift_t, shift_n, APSR.C); - uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - - // offset_addr = if add then (R[n] + offset) else (R[n] - offset); - uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - if (add) - offset_addr = Rn + offset; - else - offset_addr = Rn - offset; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = Rn; - - // R[t] = ZeroExtend(MemU[address,1],32); - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - Rn); - - uint64_t data = MemURead (context, address, 1, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t m; + bool index; + bool add; + bool wback; + ARM_ShifterType shift_t; + uint32_t shift_n; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + m = Bits32(opcode, 8, 6); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + break; + + case eEncodingT2: + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); + shift_t = SRType_LSL; + shift_n = Bits32(opcode, 5, 4); + + // if Rt == '1111' then SEE PLD; + if (t == 15) + return false; // PLD is not implemented yet + + // if Rn == '1111' then SEE LDRB (literal); + if (n == 15) + return EmulateLDRBLiteral(opcode, eEncodingT1); + + // if t == 13 || BadReg(m) then UNPREDICTABLE; + if ((t == 13) || BadReg(m)) + return false; + break; + + case eEncodingA1: { + // if P == '0' && W == '1' then SEE LDRBT; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || + // (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); + + // (shift_t, shift_n) = DecodeImmShift(type, imm5); + uint32_t type = Bits32(opcode, 6, 5); + uint32_t imm5 = Bits32(opcode, 11, 7); + shift_n = DecodeImmShift(type, imm5, shift_t); + + // if t == 15 || m == 15 then UNPREDICTABLE; + if ((t == 15) || (m == 15)) + return false; + + // if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t))) + return false; + } break; + + default: + return false; } - return true; + + addr_t offset_addr; + addr_t address; + + // offset = Shift(R[m], shift_t, shift_n, APSR.C); + uint32_t Rm = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + + // offset_addr = if add then (R[n] + offset) else (R[n] - offset); + uint32_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + if (add) + offset_addr = Rn + offset; + else + offset_addr = Rn - offset; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = Rn; + + // R[t] = ZeroExtend(MemU[address,1],32); + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - Rn); + + uint64_t data = MemURead(context, address, 1, 0, &success); + if (!success) + return false; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } - -// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a -// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, + +// LDRH (immediate, Thumb) calculates an address from a base register value and +// an immediate offset, loads a +// halfword from memory, zero-extends it to form a 32-bit word, and writes it to +// a register. It can use offset, // post-indexed, or pre-indexed addressing. -bool -EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -6641,143 +6592,141 @@ EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEnc else // Can only apply before ARMv7 R[t] = bits(32) UNKNOWN; #endif - - - bool success = false; - - if (ConditionPassed(opcode)) + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + imm32 = Bits32(opcode, 10, 6) << 1; + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + break; + + case eEncodingT2: + // if Rt == '1111' then SEE "Unallocated memory hints"; + // if Rn == '1111' then SEE LDRH (literal); + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 11, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // if t == 13 then UNPREDICTABLE; + if (t == 13) + return false; + break; + + case eEncodingT3: + // if Rn == '1111' then SEE LDRH (literal); + // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE + // "Unallocated memory hints"; + // if P == '1' && U == '1' && W == '0' then SEE LDRHT; + // if P == '0' && W == '0' then UNDEFINED; + if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) + return false; + + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0); + + // index = (P == '1'); add = (U == '1'); wback = (W == '1'); + index = BitIsSet(opcode, 10); + add = BitIsSet(opcode, 9); + wback = BitIsSet(opcode, 8); + + // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; + if (BadReg(t) || (wback && (n == t))) + return false; + break; + + default: + return false; + } + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + uint32_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + addr_t offset_addr; + addr_t address; + + if (add) + offset_addr = Rn + imm32; + else + offset_addr = Rn - imm32; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = Rn; + + // data = MemU[address,2]; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - Rn); + + uint64_t data = MemURead(context, address, 2, 0, &success); + if (!success) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + + // if UnalignedSupport() || address<0> = '0' then + if (UnalignedSupport() || BitIsClear(address, 0)) { + // R[t] = ZeroExtend(data, 32); + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - Rn); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + data)) + return false; + } else // Can only apply before ARMv7 { - uint32_t t; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - imm32 = Bits32 (opcode, 10, 6) << 1; - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - break; - - case eEncodingT2: - // if Rt == '1111' then SEE "Unallocated memory hints"; - // if Rn == '1111' then SEE LDRH (literal); - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 11, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // if t == 13 then UNPREDICTABLE; - if (t == 13) - return false; - break; - - case eEncodingT3: - // if Rn == '1111' then SEE LDRH (literal); - // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; - // if P == '1' && U == '1' && W == '0' then SEE LDRHT; - // if P == '0' && W == '0' then UNDEFINED; - if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) - return false; - - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0); - - // index = (P == '1'); add = (U == '1'); wback = (W == '1'); - index = BitIsSet (opcode, 10); - add = BitIsSet (opcode, 9); - wback = BitIsSet (opcode, 8); - - // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; - if (BadReg (t) || (wback && (n == t))) - return false; - break; - - default: - return false; - } - - // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - addr_t offset_addr; - addr_t address; - - if (add) - offset_addr = Rn + imm32; - else - offset_addr = Rn - imm32; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = Rn; - - // data = MemU[address,2]; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - Rn); - - uint64_t data = MemURead (context, address, 2, 0, &success); - if (!success) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } - - // if UnalignedSupport() || address<0> = '0' then - if (UnalignedSupport () || BitIsClear (address, 0)) - { - // R[t] = ZeroExtend(data, 32); - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - Rn); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - } - else // Can only apply before ARMv7 - { - // R[t] = bits(32) UNKNOWN; - WriteBits32Unknown (t); - } + // R[t] = bits(32) UNKNOWN; + WriteBits32Unknown(t); } - return true; + } + return true; } - -// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, -// zero-extends it to form a 32-bit word, and writes it to a register. -bool -EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) -{ + +// LDRH (literal) caculates an address from the PC value and an immediate +// offset, loads a halfword from memory, +// zero-extends it to form a 32-bit word, and writes it to a register. +bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(15); @@ -6789,103 +6738,99 @@ EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncod else // Can only apply before ARMv7 R[t] = bits(32) UNKNOWN; #endif - - bool success = false; - - if (ConditionPassed(opcode)) + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t imm32; + bool add; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(15); + switch (encoding) { + case eEncodingT1: + // if Rt == '1111' then SEE "Unallocated memory hints"; + // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); + t = Bits32(opcode, 15, 12); + imm32 = Bits32(opcode, 11, 0); + add = BitIsSet(opcode, 23); + + // if t == 13 then UNPREDICTABLE; + if (t == 13) + return false; + + break; + + case eEncodingA1: { + uint32_t imm4H = Bits32(opcode, 11, 8); + uint32_t imm4L = Bits32(opcode, 3, 0); + + // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); + t = Bits32(opcode, 15, 12); + imm32 = (imm4H << 4) | imm4L; + add = BitIsSet(opcode, 23); + + // if t == 15 then UNPREDICTABLE; + if (t == 15) + return false; + break; + } + + default: + return false; + } + + // base = Align(PC,4); + uint64_t pc_value = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + + addr_t base = AlignPC(pc_value); + addr_t address; + + // address = if add then (base + imm32) else (base - imm32); + if (add) + address = base + imm32; + else + address = base - imm32; + + // data = MemU[address,2]; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - base); + + uint64_t data = MemURead(context, address, 2, 0, &success); + if (!success) + return false; + + // if UnalignedSupport() || address<0> = '0' then + if (UnalignedSupport() || BitIsClear(address, 0)) { + // R[t] = ZeroExtend(data, 32); + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - base); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + data)) + return false; + + } else // Can only apply before ARMv7 { - uint32_t t; - uint32_t imm32; - bool add; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(15); - switch (encoding) - { - case eEncodingT1: - // if Rt == '1111' then SEE "Unallocated memory hints"; - // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - t = Bits32 (opcode, 15, 12); - imm32 = Bits32 (opcode, 11, 0); - add = BitIsSet (opcode, 23); - - // if t == 13 then UNPREDICTABLE; - if (t == 13) - return false; - - break; - - case eEncodingA1: - { - uint32_t imm4H = Bits32 (opcode, 11, 8); - uint32_t imm4L = Bits32 (opcode, 3, 0); - - // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); - t = Bits32 (opcode, 15, 12); - imm32 = (imm4H << 4) | imm4L; - add = BitIsSet (opcode, 23); - - // if t == 15 then UNPREDICTABLE; - if (t == 15) - return false; - break; - } - - default: - return false; - } - - // base = Align(PC,4); - uint64_t pc_value = ReadCoreReg (PC_REG, &success); - if (!success) - return false; - - addr_t base = AlignPC (pc_value); - addr_t address; - - // address = if add then (base + imm32) else (base - imm32); - if (add) - address = base + imm32; - else - address = base - imm32; - - // data = MemU[address,2]; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - base); - - uint64_t data = MemURead (context, address, 2, 0, &success); - if (!success) - return false; - - - // if UnalignedSupport() || address<0> = '0' then - if (UnalignedSupport () || BitIsClear (address, 0)) - { - // R[t] = ZeroExtend(data, 32); - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - base); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - - } - else // Can only apply before ARMv7 - { - // R[t] = bits(32) UNKNOWN; - WriteBits32Unknown (t); - } + // R[t] = bits(32) UNKNOWN; + WriteBits32Unknown(t); } - return true; + } + return true; } - -// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword -// from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can + +// LDRH (literal) calculates an address from a base register value and an offset +// register value, loads a halfword +// from memory, zero-extends it to form a 32-bit word, and writes it to a +// register. The offset register value can // be shifted left by 0, 1, 2, or 3 bits. -bool -EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -6899,168 +6844,170 @@ EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEnco else // Can only apply before ARMv7 R[t] = bits(32) UNKNOWN; #endif - - bool success = false; - - if (ConditionPassed(opcode)) + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t m; + bool index; + bool add; + bool wback; + ARM_ShifterType shift_t; + uint32_t shift_n; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation + // in ThumbEE"; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + m = Bits32(opcode, 8, 6); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + + break; + + case eEncodingT2: + // if Rn == '1111' then SEE LDRH (literal); + // if Rt == '1111' then SEE "Unallocated memory hints"; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); + shift_t = SRType_LSL; + shift_n = Bits32(opcode, 5, 4); + + // if t == 13 || BadReg(m) then UNPREDICTABLE; + if ((t == 13) || BadReg(m)) + return false; + break; + + case eEncodingA1: + // if P == '0' && W == '1' then SEE LDRHT; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || + // (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + + // if t == 15 || m == 15 then UNPREDICTABLE; + if ((t == 15) || (m == 15)) + return false; + + // if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t))) + return false; + + break; + + default: + return false; + } + + // offset = Shift(R[m], shift_t, shift_n, APSR.C); + + uint64_t Rm = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + + addr_t offset_addr; + addr_t address; + + // offset_addr = if add then (R[n] + offset) else (R[n] - offset); + uint64_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + if (add) + offset_addr = Rn + offset; + else + offset_addr = Rn - offset; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = Rn; + + // data = MemU[address,2]; + RegisterInfo base_reg; + RegisterInfo offset_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); + uint64_t data = MemURead(context, address, 2, 0, &success); + if (!success) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + + // if UnalignedSupport() || address<0> = '0' then + if (UnalignedSupport() || BitIsClear(address, 0)) { + // R[t] = ZeroExtend(data, 32); + context.type = eContextRegisterLoad; + context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + data)) + return false; + } else // Can only apply before ARMv7 { - uint32_t t; - uint32_t n; - uint32_t m; - bool index; - bool add; - bool wback; - ARM_ShifterType shift_t; - uint32_t shift_n; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - m = Bits32 (opcode, 8, 6); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - - break; - - case eEncodingT2: - // if Rn == '1111' then SEE LDRH (literal); - // if Rt == '1111' then SEE "Unallocated memory hints"; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - shift_t = SRType_LSL; - shift_n = Bits32 (opcode, 5, 4); - - // if t == 13 || BadReg(m) then UNPREDICTABLE; - if ((t == 13) || BadReg (m)) - return false; - break; - - case eEncodingA1: - // if P == '0' && W == '1' then SEE LDRHT; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - - // if t == 15 || m == 15 then UNPREDICTABLE; - if ((t == 15) || (m == 15)) - return false; - - // if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t))) - return false; - - break; - - default: - return false; - } - - // offset = Shift(R[m], shift_t, shift_n, APSR.C); - - uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - - addr_t offset_addr; - addr_t address; - - // offset_addr = if add then (R[n] + offset) else (R[n] - offset); - uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - if (add) - offset_addr = Rn + offset; - else - offset_addr = Rn - offset; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = Rn; - - // data = MemU[address,2]; - RegisterInfo base_reg; - RegisterInfo offset_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); - uint64_t data = MemURead (context, address, 2, 0, &success); - if (!success) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } - - // if UnalignedSupport() || address<0> = '0' then - if (UnalignedSupport() || BitIsClear (address, 0)) - { - // R[t] = ZeroExtend(data, 32); - context.type = eContextRegisterLoad; - context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - } - else // Can only apply before ARMv7 - { - // R[t] = bits(32) UNKNOWN; - WriteBits32Unknown (t); - } - } - return true; + // R[t] = bits(32) UNKNOWN; + WriteBits32Unknown(t); + } + } + return true; } - -// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from -// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, + +// LDRSB (immediate) calculates an address from a base register value and an +// immediate offset, loads a byte from +// memory, sign-extends it to form a 32-bit word, and writes it to a register. +// It can use offset, post-indexed, // or pre-indexed addressing. -bool -EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -7069,147 +7016,147 @@ EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEn R[t] = SignExtend(MemU[address,1], 32); if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // if Rt == '1111' then SEE PLI; - // if Rn == '1111' then SEE LDRSB (literal); - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 11, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // if t == 13 then UNPREDICTABLE; - if (t == 13) - return false; - - break; - - case eEncodingT2: - // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; - // if Rn == '1111' then SEE LDRSB (literal); - // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; - // if P == '0' && W == '0' then UNDEFINED; - if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) - return false; - - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0); - - // index = (P == '1'); add = (U == '1'); wback = (W == '1'); - index = BitIsSet (opcode, 10); - add = BitIsSet (opcode, 9); - wback = BitIsSet (opcode, 8); - - // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; - if (((t == 13) || ((t == 15) - && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) - || (wback && (n == t))) - return false; - - break; - - case eEncodingA1: - { - // if Rn == '1111' then SEE LDRSB (literal); - // if P == '0' && W == '1' then SEE LDRSBT; - // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - - uint32_t imm4H = Bits32 (opcode, 11, 8); - uint32_t imm4L = Bits32 (opcode, 3, 0); - imm32 = (imm4H << 4) | imm4L; - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); - - // if t == 15 || (wback && n == t) then UNPREDICTABLE; - if ((t == 15) || (wback && (n == t))) - return false; - - break; - } - - default: - return false; - } - - uint64_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - addr_t offset_addr; - addr_t address; - - // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - if (add) - offset_addr = Rn + imm32; - else - offset_addr = Rn - imm32; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = Rn; - - // R[t] = SignExtend(MemU[address,1], 32); - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - Rn); - - uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); - if (!success) - return false; - - int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // if Rt == '1111' then SEE PLI; + // if Rn == '1111' then SEE LDRSB (literal); + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 11, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // if t == 13 then UNPREDICTABLE; + if (t == 13) + return false; + + break; + + case eEncodingT2: + // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; + // if Rn == '1111' then SEE LDRSB (literal); + // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; + // if P == '0' && W == '0' then UNDEFINED; + if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) + return false; + + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0); + + // index = (P == '1'); add = (U == '1'); wback = (W == '1'); + index = BitIsSet(opcode, 10); + add = BitIsSet(opcode, 9); + wback = BitIsSet(opcode, 8); + + // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; + if (((t == 13) || + ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || + BitIsSet(opcode, 8)))) || + (wback && (n == t))) + return false; + + break; + + case eEncodingA1: { + // if Rn == '1111' then SEE LDRSB (literal); + // if P == '0' && W == '1' then SEE LDRSBT; + // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + + uint32_t imm4H = Bits32(opcode, 11, 8); + uint32_t imm4L = Bits32(opcode, 3, 0); + imm32 = (imm4H << 4) | imm4L; + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || + // (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); + + // if t == 15 || (wback && n == t) then UNPREDICTABLE; + if ((t == 15) || (wback && (n == t))) + return false; + + break; } - - return true; + + default: + return false; + } + + uint64_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + addr_t offset_addr; + addr_t address; + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + if (add) + offset_addr = Rn + imm32; + else + offset_addr = Rn - imm32; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = Rn; + + // R[t] = SignExtend(MemU[address,1], 32); + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - Rn); + + uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); + if (!success) + return false; + + int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + (uint64_t)signed_data)) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + + return true; } - -// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, + +// LDRSB (literal) calculates an address from the PC value and an immediate +// offset, loads a byte from memory, // sign-extends it to form a 32-bit word, and writes tit to a register. -bool -EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(15); @@ -7217,89 +7164,88 @@ EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEnco address = if add then (base + imm32) else (base - imm32); R[t] = SignExtend(MemU[address,1], 32); #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t imm32; - bool add; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(15); - switch (encoding) - { - case eEncodingT1: - // if Rt == '1111' then SEE PLI; - // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - t = Bits32 (opcode, 15, 12); - imm32 = Bits32 (opcode, 11, 0); - add = BitIsSet (opcode, 23); - - // if t == 13 then UNPREDICTABLE; - if (t == 13) - return false; - - break; - - case eEncodingA1: - { - // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); - t = Bits32 (opcode, 15, 12); - uint32_t imm4H = Bits32 (opcode, 11, 8); - uint32_t imm4L = Bits32 (opcode, 3, 0); - imm32 = (imm4H << 4) | imm4L; - add = BitIsSet (opcode, 23); - - // if t == 15 then UNPREDICTABLE; - if (t == 15) - return false; - - break; - } - - default: - return false; - } - - // base = Align(PC,4); - uint64_t pc_value = ReadCoreReg (PC_REG, &success); - if (!success) - return false; - uint64_t base = AlignPC (pc_value); - // address = if add then (base + imm32) else (base - imm32); - addr_t address; - if (add) - address = base + imm32; - else - address = base - imm32; - - // R[t] = SignExtend(MemU[address,1], 32); - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - base); - - uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); - if (!success) - return false; - - int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) - return false; + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t imm32; + bool add; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(15); + switch (encoding) { + case eEncodingT1: + // if Rt == '1111' then SEE PLI; + // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); + t = Bits32(opcode, 15, 12); + imm32 = Bits32(opcode, 11, 0); + add = BitIsSet(opcode, 23); + + // if t == 13 then UNPREDICTABLE; + if (t == 13) + return false; + + break; + + case eEncodingA1: { + // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); + t = Bits32(opcode, 15, 12); + uint32_t imm4H = Bits32(opcode, 11, 8); + uint32_t imm4L = Bits32(opcode, 3, 0); + imm32 = (imm4H << 4) | imm4L; + add = BitIsSet(opcode, 23); + + // if t == 15 then UNPREDICTABLE; + if (t == 15) + return false; + + break; } - return true; + + default: + return false; + } + + // base = Align(PC,4); + uint64_t pc_value = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + uint64_t base = AlignPC(pc_value); + + // address = if add then (base + imm32) else (base - imm32); + addr_t address; + if (add) + address = base + imm32; + else + address = base - imm32; + + // R[t] = SignExtend(MemU[address,1], 32); + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - base); + + uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); + if (!success) + return false; + + int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + (uint64_t)signed_data)) + return false; + } + return true; } - -// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from -// memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be + +// LDRSB (register) calculates an address from a base register value and an +// offset register value, loadsa byte from +// memory, sign-extends it to form a 32-bit word, and writes it to a register. +// The offset register value can be // shifted left by 0, 1, 2, or 3 bits. -bool -EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -7309,155 +7255,158 @@ EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEnc R[t] = SignExtend(MemU[address,1], 32); if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t n; - uint32_t m; - bool index; - bool add; - bool wback; - ARM_ShifterType shift_t; - uint32_t shift_n; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - m = Bits32 (opcode, 8, 6); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - - break; - - case eEncodingT2: - // if Rt == '1111' then SEE PLI; - // if Rn == '1111' then SEE LDRSB (literal); - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - shift_t = SRType_LSL; - shift_n = Bits32 (opcode, 5, 4); - - // if t == 13 || BadReg(m) then UNPREDICTABLE; - if ((t == 13) || BadReg (m)) - return false; - break; - - case eEncodingA1: - // if P == '0' && W == '1' then SEE LDRSBT; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - - // if t == 15 || m == 15 then UNPREDICTABLE; - if ((t == 15) || (m == 15)) - return false; - - // if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t))) - return false; - break; - - default: - return false; - } - - uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - // offset = Shift(R[m], shift_t, shift_n, APSR.C); - addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - - addr_t offset_addr; - addr_t address; - - // offset_addr = if add then (R[n] + offset) else (R[n] - offset); - uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - if (add) - offset_addr = Rn + offset; - else - offset_addr = Rn - offset; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = Rn; - - // R[t] = SignExtend(MemU[address,1], 32); - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - RegisterInfo offset_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); - - uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); - if (!success) - return false; - - int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t m; + bool index; + bool add; + bool wback; + ARM_ShifterType shift_t; + uint32_t shift_n; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + m = Bits32(opcode, 8, 6); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + + break; + + case eEncodingT2: + // if Rt == '1111' then SEE PLI; + // if Rn == '1111' then SEE LDRSB (literal); + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); + shift_t = SRType_LSL; + shift_n = Bits32(opcode, 5, 4); + + // if t == 13 || BadReg(m) then UNPREDICTABLE; + if ((t == 13) || BadReg(m)) + return false; + break; + + case eEncodingA1: + // if P == '0' && W == '1' then SEE LDRSBT; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || + // (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + + // if t == 15 || m == 15 then UNPREDICTABLE; + if ((t == 15) || (m == 15)) + return false; + + // if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t))) + return false; + break; + + default: + return false; } - return true; + + uint64_t Rm = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + // offset = Shift(R[m], shift_t, shift_n, APSR.C); + addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + + addr_t offset_addr; + addr_t address; + + // offset_addr = if add then (R[n] + offset) else (R[n] - offset); + uint64_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + if (add) + offset_addr = Rn + offset; + else + offset_addr = Rn - offset; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = Rn; + + // R[t] = SignExtend(MemU[address,1], 32); + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + RegisterInfo offset_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); + + uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); + if (!success) + return false; + + int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + (uint64_t)signed_data)) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } - -// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from -// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or + +// LDRSH (immediate) calculates an address from a base register value and an +// immediate offset, loads a halfword from +// memory, sign-extends it to form a 32-bit word, and writes it to a register. +// It can use offset, post-indexed, or // pre-indexed addressing. -bool -EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -7471,153 +7420,152 @@ EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEn R[t] = bits(32) UNKNOWN; #endif - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // if Rn == '1111' then SEE LDRSH (literal); - // if Rt == '1111' then SEE "Unallocated memory hints"; - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 11, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // if t == 13 then UNPREDICTABLE; - if (t == 13) - return false; - - break; - - case eEncodingT2: - // if Rn == '1111' then SEE LDRSH (literal); - // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; - // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; - // if P == '0' && W == '0' then UNDEFINED; - if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) - return false; - - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0); - - // index = (P == '1'); add = (U == '1'); wback = (W == '1'); - index = BitIsSet (opcode, 10); - add = BitIsSet (opcode, 9); - wback = BitIsSet (opcode, 8); - - // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; - if (BadReg (t) || (wback && (n == t))) - return false; - - break; - - case eEncodingA1: - { - // if Rn == '1111' then SEE LDRSH (literal); - // if P == '0' && W == '1' then SEE LDRSHT; - // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - uint32_t imm4H = Bits32 (opcode, 11,8); - uint32_t imm4L = Bits32 (opcode, 3, 0); - imm32 = (imm4H << 4) | imm4L; - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - - // if t == 15 || (wback && n == t) then UNPREDICTABLE; - if ((t == 15) || (wback && (n == t))) - return false; - - break; - } - - default: - return false; - } - - // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - addr_t offset_addr; - if (add) - offset_addr = Rn + imm32; - else - offset_addr = Rn - imm32; - - // address = if index then offset_addr else R[n]; - addr_t address; - if (index) - address = offset_addr; - else - address = Rn; - - // data = MemU[address,2]; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - Rn); - - uint64_t data = MemURead (context, address, 2, 0, &success); - if (!success) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } - - // if UnalignedSupport() || address<0> = '0' then - if (UnalignedSupport() || BitIsClear (address, 0)) - { - // R[t] = SignExtend(data, 32); - int64_t signed_data = llvm::SignExtend64<16>(data); - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - Rn); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) - return false; - } - else // Can only apply before ARMv7 - { - // R[t] = bits(32) UNKNOWN; - WriteBits32Unknown (t); - } + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // if Rn == '1111' then SEE LDRSH (literal); + // if Rt == '1111' then SEE "Unallocated memory hints"; + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 11, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // if t == 13 then UNPREDICTABLE; + if (t == 13) + return false; + + break; + + case eEncodingT2: + // if Rn == '1111' then SEE LDRSH (literal); + // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE + // "Unallocated memory hints"; + // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; + // if P == '0' && W == '0' then UNDEFINED; + if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) + return false; + + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0); + + // index = (P == '1'); add = (U == '1'); wback = (W == '1'); + index = BitIsSet(opcode, 10); + add = BitIsSet(opcode, 9); + wback = BitIsSet(opcode, 8); + + // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; + if (BadReg(t) || (wback && (n == t))) + return false; + + break; + + case eEncodingA1: { + // if Rn == '1111' then SEE LDRSH (literal); + // if P == '0' && W == '1' then SEE LDRSHT; + // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + uint32_t imm4H = Bits32(opcode, 11, 8); + uint32_t imm4L = Bits32(opcode, 3, 0); + imm32 = (imm4H << 4) | imm4L; + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || + // (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); + + // if t == 15 || (wback && n == t) then UNPREDICTABLE; + if ((t == 15) || (wback && (n == t))) + return false; + + break; + } + + default: + return false; + } + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + uint64_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + addr_t offset_addr; + if (add) + offset_addr = Rn + imm32; + else + offset_addr = Rn - imm32; + + // address = if index then offset_addr else R[n]; + addr_t address; + if (index) + address = offset_addr; + else + address = Rn; + + // data = MemU[address,2]; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - Rn); + + uint64_t data = MemURead(context, address, 2, 0, &success); + if (!success) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; } - return true; + + // if UnalignedSupport() || address<0> = '0' then + if (UnalignedSupport() || BitIsClear(address, 0)) { + // R[t] = SignExtend(data, 32); + int64_t signed_data = llvm::SignExtend64<16>(data); + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - Rn); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + (uint64_t)signed_data)) + return false; + } else // Can only apply before ARMv7 + { + // R[t] = bits(32) UNKNOWN; + WriteBits32Unknown(t); + } + } + return true; } - -// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, + +// LDRSH (literal) calculates an address from the PC value and an immediate +// offset, loads a halfword from memory, // sign-extends it to from a 32-bit word, and writes it to a register. -bool -EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(15); @@ -7629,99 +7577,96 @@ EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEnco else // Can only apply before ARMv7 R[t] = bits(32) UNKNOWN; #endif - - bool success = false; - - if (ConditionPassed(opcode)) + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t imm32; + bool add; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(15); + switch (encoding) { + case eEncodingT1: + // if Rt == '1111' then SEE "Unallocated memory hints"; + // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); + t = Bits32(opcode, 15, 12); + imm32 = Bits32(opcode, 11, 0); + add = BitIsSet(opcode, 23); + + // if t == 13 then UNPREDICTABLE; + if (t == 13) + return false; + + break; + + case eEncodingA1: { + // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); + t = Bits32(opcode, 15, 12); + uint32_t imm4H = Bits32(opcode, 11, 8); + uint32_t imm4L = Bits32(opcode, 3, 0); + imm32 = (imm4H << 4) | imm4L; + add = BitIsSet(opcode, 23); + + // if t == 15 then UNPREDICTABLE; + if (t == 15) + return false; + + break; + } + default: + return false; + } + + // base = Align(PC,4); + uint64_t pc_value = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + + uint64_t base = AlignPC(pc_value); + + addr_t address; + // address = if add then (base + imm32) else (base - imm32); + if (add) + address = base + imm32; + else + address = base - imm32; + + // data = MemU[address,2]; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, imm32); + + uint64_t data = MemURead(context, address, 2, 0, &success); + if (!success) + return false; + + // if UnalignedSupport() || address<0> = '0' then + if (UnalignedSupport() || BitIsClear(address, 0)) { + // R[t] = SignExtend(data, 32); + int64_t signed_data = llvm::SignExtend64<16>(data); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + (uint64_t)signed_data)) + return false; + } else // Can only apply before ARMv7 { - uint32_t t; - uint32_t imm32; - bool add; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(15); - switch (encoding) - { - case eEncodingT1: - // if Rt == '1111' then SEE "Unallocated memory hints"; - // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - t = Bits32 (opcode, 15, 12); - imm32 = Bits32 (opcode, 11, 0); - add = BitIsSet (opcode, 23); - - // if t == 13 then UNPREDICTABLE; - if (t == 13) - return false; - - break; - - case eEncodingA1: - { - // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); - t = Bits32 (opcode, 15, 12); - uint32_t imm4H = Bits32 (opcode, 11, 8); - uint32_t imm4L = Bits32 (opcode, 3, 0); - imm32 = (imm4H << 4) | imm4L; - add = BitIsSet (opcode, 23); - - // if t == 15 then UNPREDICTABLE; - if (t == 15) - return false; - - break; - } - default: - return false; - } - - // base = Align(PC,4); - uint64_t pc_value = ReadCoreReg (PC_REG, &success); - if (!success) - return false; - - uint64_t base = AlignPC (pc_value); - - addr_t address; - // address = if add then (base + imm32) else (base - imm32); - if (add) - address = base + imm32; - else - address = base - imm32; - - // data = MemU[address,2]; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, imm32); - - uint64_t data = MemURead (context, address, 2, 0, &success); - if (!success) - return false; - - // if UnalignedSupport() || address<0> = '0' then - if (UnalignedSupport() || BitIsClear (address, 0)) - { - // R[t] = SignExtend(data, 32); - int64_t signed_data = llvm::SignExtend64<16>(data); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) - return false; - } - else // Can only apply before ARMv7 - { - // R[t] = bits(32) UNKNOWN; - WriteBits32Unknown (t); - } + // R[t] = bits(32) UNKNOWN; + WriteBits32Unknown(t); } - return true; + } + return true; } - -// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword -// from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be + +// LDRSH (register) calculates an address from a base register value and an +// offset register value, loads a halfword +// from memory, sign-extends it to form a 32-bit word, and writes it to a +// register. The offset register value can be // shifted left by 0, 1, 2, or 3 bits. -bool -EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -7735,502 +7680,507 @@ EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEnc else // Can only apply before ARMv7 R[t] = bits(32) UNKNOWN; #endif - - bool success = false; - - if (ConditionPassed(opcode)) + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t m; + bool index; + bool add; + bool wback; + ARM_ShifterType shift_t; + uint32_t shift_n; + + // EncodingSpecificOperations(); NullCheckIfThumbEE(n); + switch (encoding) { + case eEncodingT1: + // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation + // in ThumbEE"; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + m = Bits32(opcode, 8, 6); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + + break; + + case eEncodingT2: + // if Rn == '1111' then SEE LDRSH (literal); + // if Rt == '1111' then SEE "Unallocated memory hints"; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = TRUE; add = TRUE; wback = FALSE; + index = true; + add = true; + wback = false; + + // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); + shift_t = SRType_LSL; + shift_n = Bits32(opcode, 5, 4); + + // if t == 13 || BadReg(m) then UNPREDICTABLE; + if ((t == 13) || BadReg(m)) + return false; + + break; + + case eEncodingA1: + // if P == '0' && W == '1' then SEE LDRSHT; + // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || + // (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + + // if t == 15 || m == 15 then UNPREDICTABLE; + if ((t == 15) || (m == 15)) + return false; + + // if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t))) + return false; + + break; + + default: + return false; + } + + uint64_t Rm = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + uint64_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + // offset = Shift(R[m], shift_t, shift_n, APSR.C); + addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + + addr_t offset_addr; + addr_t address; + + // offset_addr = if add then (R[n] + offset) else (R[n] - offset); + if (add) + offset_addr = Rn + offset; + else + offset_addr = Rn - offset; + + // address = if index then offset_addr else R[n]; + if (index) + address = offset_addr; + else + address = Rn; + + // data = MemU[address,2]; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + RegisterInfo offset_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); + + uint64_t data = MemURead(context, address, 2, 0, &success); + if (!success) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + + // if UnalignedSupport() || address<0> = '0' then + if (UnalignedSupport() || BitIsClear(address, 0)) { + // R[t] = SignExtend(data, 32); + context.type = eContextRegisterLoad; + context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); + + int64_t signed_data = llvm::SignExtend64<16>(data); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, + (uint64_t)signed_data)) + return false; + } else // Can only apply before ARMv7 { - uint32_t t; - uint32_t n; - uint32_t m; - bool index; - bool add; - bool wback; - ARM_ShifterType shift_t; - uint32_t shift_n; - - // EncodingSpecificOperations(); NullCheckIfThumbEE(n); - switch (encoding) - { - case eEncodingT1: - // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - m = Bits32 (opcode, 8, 6); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - - break; - - case eEncodingT2: - // if Rn == '1111' then SEE LDRSH (literal); - // if Rt == '1111' then SEE "Unallocated memory hints"; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = TRUE; add = TRUE; wback = FALSE; - index = true; - add = true; - wback = false; - - // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - shift_t = SRType_LSL; - shift_n = Bits32 (opcode, 5, 4); - - // if t == 13 || BadReg(m) then UNPREDICTABLE; - if ((t == 13) || BadReg (m)) - return false; - - break; - - case eEncodingA1: - // if P == '0' && W == '1' then SEE LDRSHT; - // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - - // if t == 15 || m == 15 then UNPREDICTABLE; - if ((t == 15) || (m == 15)) - return false; - - // if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t))) - return false; - - break; - - default: - return false; - } - - uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - // offset = Shift(R[m], shift_t, shift_n, APSR.C); - addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - - addr_t offset_addr; - addr_t address; - - // offset_addr = if add then (R[n] + offset) else (R[n] - offset); - if (add) - offset_addr = Rn + offset; - else - offset_addr = Rn - offset; - - // address = if index then offset_addr else R[n]; - if (index) - address = offset_addr; - else - address = Rn; - - // data = MemU[address,2]; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - RegisterInfo offset_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); - - uint64_t data = MemURead (context, address, 2, 0, &success); - if (!success) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } - - // if UnalignedSupport() || address<0> = '0' then - if (UnalignedSupport() || BitIsClear (address, 0)) - { - // R[t] = SignExtend(data, 32); - context.type = eContextRegisterLoad; - context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); - - int64_t signed_data = llvm::SignExtend64<16>(data); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) - return false; - } - else // Can only apply before ARMv7 - { - // R[t] = bits(32) UNKNOWN; - WriteBits32Unknown (t); - } + // R[t] = bits(32) UNKNOWN; + WriteBits32Unknown(t); } - return true; + } + return true; } - -// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination -// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. -bool -EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) -{ + +// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and +// writes the result to the destination +// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before +// extracting the 8-bit value. +bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); rotated = ROR(R[m], rotation); R[d] = SignExtend(rotated<7:0>, 32); #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t d; - uint32_t m; - uint32_t rotation; - - // EncodingSpecificOperations(); - switch (encoding) - { - case eEncodingT1: - // d = UInt(Rd); m = UInt(Rm); rotation = 0; - d = Bits32 (opcode, 2, 0); - m = Bits32 (opcode, 5, 3); - rotation = 0; - - break; - - case eEncodingT2: - // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - d = Bits32 (opcode, 11, 8); - m = Bits32 (opcode, 3, 0); - rotation = Bits32 (opcode, 5, 4) << 3; - - // if BadReg(d) || BadReg(m) then UNPREDICTABLE; - if (BadReg (d) || BadReg (m)) - return false; - - break; - - case eEncodingA1: - // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - d = Bits32 (opcode, 15, 12); - m = Bits32 (opcode, 3, 0); - rotation = Bits32 (opcode, 11, 10) << 3; - - // if d == 15 || m == 15 then UNPREDICTABLE; - if ((d == 15) || (m == 15)) - return false; - - break; - - default: - return false; - } - - uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - // rotated = ROR(R[m], rotation); - uint64_t rotated = ROR (Rm, rotation, &success); - if (!success) - return false; - - // R[d] = SignExtend(rotated<7:0>, 32); - int64_t data = llvm::SignExtend64<8>(rotated); - - RegisterInfo source_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegister (source_reg); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) - return false; + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t d; + uint32_t m; + uint32_t rotation; + + // EncodingSpecificOperations(); + switch (encoding) { + case eEncodingT1: + // d = UInt(Rd); m = UInt(Rm); rotation = 0; + d = Bits32(opcode, 2, 0); + m = Bits32(opcode, 5, 3); + rotation = 0; + + break; + + case eEncodingT2: + // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); + d = Bits32(opcode, 11, 8); + m = Bits32(opcode, 3, 0); + rotation = Bits32(opcode, 5, 4) << 3; + + // if BadReg(d) || BadReg(m) then UNPREDICTABLE; + if (BadReg(d) || BadReg(m)) + return false; + + break; + + case eEncodingA1: + // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); + d = Bits32(opcode, 15, 12); + m = Bits32(opcode, 3, 0); + rotation = Bits32(opcode, 11, 10) << 3; + + // if d == 15 || m == 15 then UNPREDICTABLE; + if ((d == 15) || (m == 15)) + return false; + + break; + + default: + return false; } - return true; -} - -// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination -// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. -bool -EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) -{ -#if 0 - if ConditionPassed() then - EncodingSpecificOperations(); - rotated = ROR(R[m], rotation); - R[d] = SignExtend(rotated<15:0>, 32); -#endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t d; - uint32_t m; - uint32_t rotation; - - // EncodingSpecificOperations(); - switch (encoding) - { - case eEncodingT1: - // d = UInt(Rd); m = UInt(Rm); rotation = 0; - d = Bits32 (opcode, 2, 0); - m = Bits32 (opcode, 5, 3); - rotation = 0; - - break; - - case eEncodingT2: - // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - d = Bits32 (opcode, 11, 8); - m = Bits32 (opcode, 3, 0); - rotation = Bits32 (opcode, 5, 4) << 3; - - // if BadReg(d) || BadReg(m) then UNPREDICTABLE; - if (BadReg (d) || BadReg (m)) - return false; - - break; - - case eEncodingA1: - // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - d = Bits32 (opcode, 15, 12); - m = Bits32 (opcode, 3, 0); - rotation = Bits32 (opcode, 11, 10) << 3; - - // if d == 15 || m == 15 then UNPREDICTABLE; - if ((d == 15) || (m == 15)) - return false; - - break; - - default: - return false; - } - - uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - // rotated = ROR(R[m], rotation); - uint64_t rotated = ROR (Rm, rotation, &success); - if (!success) - return false; - - // R[d] = SignExtend(rotated<15:0>, 32); - RegisterInfo source_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegister (source_reg); - - int64_t data = llvm::SignExtend64<16> (rotated); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) - return false; + + uint64_t Rm = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + // rotated = ROR(R[m], rotation); + uint64_t rotated = ROR(Rm, rotation, &success); + if (!success) + return false; + + // R[d] = SignExtend(rotated<7:0>, 32); + int64_t data = llvm::SignExtend64<8>(rotated); + + RegisterInfo source_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegister(source_reg); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, + (uint64_t)data)) + return false; + } + return true; +} + +// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and +// writes the result to the destination +// register. You can specify a rotation by 0, 8, 16, or 24 bits before +// extracting the 16-bit value. +bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, + const ARMEncoding encoding) { +#if 0 + if ConditionPassed() then + EncodingSpecificOperations(); + rotated = ROR(R[m], rotation); + R[d] = SignExtend(rotated<15:0>, 32); +#endif + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t d; + uint32_t m; + uint32_t rotation; + + // EncodingSpecificOperations(); + switch (encoding) { + case eEncodingT1: + // d = UInt(Rd); m = UInt(Rm); rotation = 0; + d = Bits32(opcode, 2, 0); + m = Bits32(opcode, 5, 3); + rotation = 0; + + break; + + case eEncodingT2: + // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); + d = Bits32(opcode, 11, 8); + m = Bits32(opcode, 3, 0); + rotation = Bits32(opcode, 5, 4) << 3; + + // if BadReg(d) || BadReg(m) then UNPREDICTABLE; + if (BadReg(d) || BadReg(m)) + return false; + + break; + + case eEncodingA1: + // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); + d = Bits32(opcode, 15, 12); + m = Bits32(opcode, 3, 0); + rotation = Bits32(opcode, 11, 10) << 3; + + // if d == 15 || m == 15 then UNPREDICTABLE; + if ((d == 15) || (m == 15)) + return false; + + break; + + default: + return false; } - - return true; + + uint64_t Rm = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + // rotated = ROR(R[m], rotation); + uint64_t rotated = ROR(Rm, rotation, &success); + if (!success) + return false; + + // R[d] = SignExtend(rotated<15:0>, 32); + RegisterInfo source_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegister(source_reg); + + int64_t data = llvm::SignExtend64<16>(rotated); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, + (uint64_t)data)) + return false; + } + + return true; } - -// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination -// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. -bool -EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) -{ + +// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and +// writes the result to the destination +// register. You can specify a rotation by 0, 8, 16, or 24 bits before +// extracting the 8-bit value. +bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); rotated = ROR(R[m], rotation); R[d] = ZeroExtend(rotated<7:0>, 32); #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t d; - uint32_t m; - uint32_t rotation; - - // EncodingSpecificOperations(); - switch (encoding) - { - case eEncodingT1: - // d = UInt(Rd); m = UInt(Rm); rotation = 0; - d = Bits32 (opcode, 2, 0); - m = Bits32 (opcode, 5, 3); - rotation = 0; - - break; - - case eEncodingT2: - // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - d = Bits32 (opcode, 11, 8); - m = Bits32 (opcode, 3, 0); - rotation = Bits32 (opcode, 5, 4) << 3; - - // if BadReg(d) || BadReg(m) then UNPREDICTABLE; - if (BadReg (d) || BadReg (m)) - return false; - - break; - - case eEncodingA1: - // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - d = Bits32 (opcode, 15, 12); - m = Bits32 (opcode, 3, 0); - rotation = Bits32 (opcode, 11, 10) << 3; - - // if d == 15 || m == 15 then UNPREDICTABLE; - if ((d == 15) || (m == 15)) - return false; - - break; - - default: - return false; - } - - uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - // rotated = ROR(R[m], rotation); - uint64_t rotated = ROR (Rm, rotation, &success); - if (!success) - return false; - - // R[d] = ZeroExtend(rotated<7:0>, 32); - RegisterInfo source_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegister (source_reg); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) - return false; + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t d; + uint32_t m; + uint32_t rotation; + + // EncodingSpecificOperations(); + switch (encoding) { + case eEncodingT1: + // d = UInt(Rd); m = UInt(Rm); rotation = 0; + d = Bits32(opcode, 2, 0); + m = Bits32(opcode, 5, 3); + rotation = 0; + + break; + + case eEncodingT2: + // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); + d = Bits32(opcode, 11, 8); + m = Bits32(opcode, 3, 0); + rotation = Bits32(opcode, 5, 4) << 3; + + // if BadReg(d) || BadReg(m) then UNPREDICTABLE; + if (BadReg(d) || BadReg(m)) + return false; + + break; + + case eEncodingA1: + // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); + d = Bits32(opcode, 15, 12); + m = Bits32(opcode, 3, 0); + rotation = Bits32(opcode, 11, 10) << 3; + + // if d == 15 || m == 15 then UNPREDICTABLE; + if ((d == 15) || (m == 15)) + return false; + + break; + + default: + return false; } - return true; -} - -// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination -// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. -bool -EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) -{ + + uint64_t Rm = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + // rotated = ROR(R[m], rotation); + uint64_t rotated = ROR(Rm, rotation, &success); + if (!success) + return false; + + // R[d] = ZeroExtend(rotated<7:0>, 32); + RegisterInfo source_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegister(source_reg); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, + Bits32(rotated, 7, 0))) + return false; + } + return true; +} + +// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and +// writes the result to the destination +// register. You can specify a rotation by 0, 8, 16, or 24 bits before +// extracting the 16-bit value. +bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); rotated = ROR(R[m], rotation); R[d] = ZeroExtend(rotated<15:0>, 32); #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t d; - uint32_t m; - uint32_t rotation; - - switch (encoding) - { - case eEncodingT1: - // d = UInt(Rd); m = UInt(Rm); rotation = 0; - d = Bits32 (opcode, 2, 0); - m = Bits32 (opcode, 5, 3); - rotation = 0; - - break; - - case eEncodingT2: - // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - d = Bits32 (opcode, 11, 8); - m = Bits32 (opcode, 3, 0); - rotation = Bits32 (opcode, 5, 4) << 3; - - // if BadReg(d) || BadReg(m) then UNPREDICTABLE; - if (BadReg (d) || BadReg (m)) - return false; - - break; - - case eEncodingA1: - // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - d = Bits32 (opcode, 15, 12); - m = Bits32 (opcode, 3, 0); - rotation = Bits32 (opcode, 11, 10) << 3; - - // if d == 15 || m == 15 then UNPREDICTABLE; - if ((d == 15) || (m == 15)) - return false; - - break; - - default: - return false; - } - - uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); - if (!success) - return false; - - // rotated = ROR(R[m], rotation); - uint64_t rotated = ROR (Rm, rotation, &success); - if (!success) - return false; - - // R[d] = ZeroExtend(rotated<15:0>, 32); - RegisterInfo source_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); - - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegister (source_reg); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) - return false; + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t d; + uint32_t m; + uint32_t rotation; + + switch (encoding) { + case eEncodingT1: + // d = UInt(Rd); m = UInt(Rm); rotation = 0; + d = Bits32(opcode, 2, 0); + m = Bits32(opcode, 5, 3); + rotation = 0; + + break; + + case eEncodingT2: + // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); + d = Bits32(opcode, 11, 8); + m = Bits32(opcode, 3, 0); + rotation = Bits32(opcode, 5, 4) << 3; + + // if BadReg(d) || BadReg(m) then UNPREDICTABLE; + if (BadReg(d) || BadReg(m)) + return false; + + break; + + case eEncodingA1: + // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); + d = Bits32(opcode, 15, 12); + m = Bits32(opcode, 3, 0); + rotation = Bits32(opcode, 11, 10) << 3; + + // if d == 15 || m == 15 then UNPREDICTABLE; + if ((d == 15) || (m == 15)) + return false; + + break; + + default: + return false; } - return true; + + uint64_t Rm = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); + if (!success) + return false; + + // rotated = ROR(R[m], rotation); + uint64_t rotated = ROR(Rm, rotation, &success); + if (!success) + return false; + + // R[d] = ZeroExtend(rotated<15:0>, 32); + RegisterInfo source_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegister(source_reg); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, + Bits32(rotated, 15, 0))) + return false; + } + return true; } - -// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following -// word respectively. -bool -EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) -{ + +// RFE (Return From Exception) loads the PC and the CPSR from the word at the +// specified address and the following +// word respectively. +bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -8243,142 +8193,141 @@ EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding enco BranchWritePC(MemA[address,4]); if wback then R[n] = if increment then R[n]+8 else R[n]-8; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t n; - bool wback; - bool increment; - bool wordhigher; - - // EncodingSpecificOperations(); - switch (encoding) - { - case eEncodingT1: - // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; - n = Bits32 (opcode, 19, 16); - wback = BitIsSet (opcode, 21); - increment = false; - wordhigher = false; - - // if n == 15 then UNPREDICTABLE; - if (n == 15) - return false; - - // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (InITBlock() && !LastInITBlock()) - return false; - - break; - - case eEncodingT2: - // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; - n = Bits32 (opcode, 19, 16); - wback = BitIsSet (opcode, 21); - increment = true; - wordhigher = false; - - // if n == 15 then UNPREDICTABLE; - if (n == 15) - return false; - - // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (InITBlock() && !LastInITBlock()) - return false; - - break; - - case eEncodingA1: - // n = UInt(Rn); - n = Bits32 (opcode, 19, 16); - - // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); - wback = BitIsSet (opcode, 21); - increment = BitIsSet (opcode, 23); - wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); - - // if n == 15 then UNPREDICTABLE; - if (n == 15) - return false; - - break; - - default: - return false; - } - - // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then - if (!CurrentModeIsPrivileged ()) - // UNPREDICTABLE; + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t n; + bool wback; + bool increment; + bool wordhigher; + + // EncodingSpecificOperations(); + switch (encoding) { + case eEncodingT1: + // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = + // FALSE; + n = Bits32(opcode, 19, 16); + wback = BitIsSet(opcode, 21); + increment = false; + wordhigher = false; + + // if n == 15 then UNPREDICTABLE; + if (n == 15) + return false; + + // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + if (InITBlock() && !LastInITBlock()) + return false; + + break; + + case eEncodingT2: + // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; + n = Bits32(opcode, 19, 16); + wback = BitIsSet(opcode, 21); + increment = true; + wordhigher = false; + + // if n == 15 then UNPREDICTABLE; + if (n == 15) + return false; + + // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + if (InITBlock() && !LastInITBlock()) + return false; + + break; + + case eEncodingA1: + // n = UInt(Rn); + n = Bits32(opcode, 19, 16); + + // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); + wback = BitIsSet(opcode, 21); + increment = BitIsSet(opcode, 23); + wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); + + // if n == 15 then UNPREDICTABLE; + if (n == 15) + return false; + + break; + + default: + return false; + } + + // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE + // then + if (!CurrentModeIsPrivileged()) + // UNPREDICTABLE; + return false; + else { + uint64_t Rn = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); + if (!success) + return false; + + addr_t address; + // address = if increment then R[n] else R[n]-8; + if (increment) + address = Rn; + else + address = Rn - 8; + + // if wordhigher then address = address+4; + if (wordhigher) + address = address + 4; + + // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + EmulateInstruction::Context context; + context.type = eContextReturnFromException; + context.SetRegisterPlusOffset(base_reg, address - Rn); + + uint64_t data = MemARead(context, address + 4, 4, 0, &success); + if (!success) + return false; + + CPSRWriteByInstr(data, 15, true); + + // BranchWritePC(MemA[address,4]); + uint64_t data2 = MemARead(context, address, 4, 0, &success); + if (!success) + return false; + + BranchWritePC(context, data2); + + // if wback then R[n] = if increment then R[n]+8 else R[n]-8; + if (wback) { + context.type = eContextAdjustBaseRegister; + if (increment) { + context.SetOffset(8); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + Rn + 8)) + return false; + } else { + context.SetOffset(-8); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + Rn - 8)) return false; - else - { - uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); - if (!success) - return false; - - addr_t address; - // address = if increment then R[n] else R[n]-8; - if (increment) - address = Rn; - else - address = Rn - 8; - - // if wordhigher then address = address+4; - if (wordhigher) - address = address + 4; - - // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - EmulateInstruction::Context context; - context.type = eContextReturnFromException; - context.SetRegisterPlusOffset (base_reg, address - Rn); - - uint64_t data = MemARead (context, address + 4, 4, 0, &success); - if (!success) - return false; - - CPSRWriteByInstr (data, 15, true); - - // BranchWritePC(MemA[address,4]); - uint64_t data2 = MemARead (context, address, 4, 0, &success); - if (!success) - return false; - - BranchWritePC (context, data2); - - // if wback then R[n] = if increment then R[n]+8 else R[n]-8; - if (wback) - { - context.type = eContextAdjustBaseRegister; - if (increment) - { - context.SetOffset (8); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) - return false; - } - else - { - context.SetOffset (-8); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) - return false; - } - } // if wback } - } // if ConditionPassed() - return true; + } // if wback + } + } // if ConditionPassed() + return true; } - -// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, -// and writes the result to the destination register. It can optionally update the condition flags based on + +// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a +// register value and an immediate value, +// and writes the result to the destination register. It can optionally update +// the condition flags based on // the result. -bool -EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -8395,64 +8344,69 @@ EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn; - uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn - bool setflags; - uint32_t carry; // the carry bit after ARM/Thumb Expand operation - switch (encoding) - { - case eEncodingT1: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) - // if Rd == '1111' && S == '1' then SEE TEQ (immediate); - if (Rd == 15 && setflags) - return EmulateTEQImm (opcode, eEncodingT1); - if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn; + uint32_t + imm32; // the immediate value to be ORed to the value obtained from Rn + bool setflags; + uint32_t carry; // the carry bit after ARM/Thumb Expand operation + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm_C( + opcode, APSR_C, + carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) + // if Rd == '1111' && S == '1' then SEE TEQ (immediate); + if (Rd == 15 && setflags) + return EmulateTEQImm(opcode, eEncodingT1); + if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = + ARMExpandImm_C(opcode, APSR_C, + carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t result = val1 ^ imm32; + uint32_t result = val1 ^ imm32; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an -// optionally-shifted register value, and writes the result to the destination register. +// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register +// value and an +// optionally-shifted register value, and writes the result to the destination +// register. // It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -8470,82 +8424,82 @@ EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn, Rm; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - bool setflags; - uint32_t carry; - switch (encoding) - { - case eEncodingT1: - Rd = Rn = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - shift_t = SRType_LSL; - shift_n = 0; - break; - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - // if Rd == '1111' && S == '1' then SEE TEQ (register); - if (Rd == 15 && setflags) - return EmulateTEQReg (opcode, eEncodingT1); - if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftARM(opcode, shift_t); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn, Rm; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + bool setflags; + uint32_t carry; + switch (encoding) { + case eEncodingT1: + Rd = Rn = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + shift_t = SRType_LSL; + shift_n = 0; + break; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + // if Rd == '1111' && S == '1' then SEE TEQ (register); + if (Rd == 15 && setflags) + return EmulateTEQReg(opcode, eEncodingT1); + if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftARM(opcode, shift_t); + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - // Read the second operand. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; + // Read the second operand. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); - if (!success) - return false; - uint32_t result = val1 ^ shifted; + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; + uint32_t result = val1 ^ shifted; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and -// writes the result to the destination register. It can optionally update the condition flags based +// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value +// and an immediate value, and +// writes the result to the destination register. It can optionally update the +// condition flags based // on the result. -bool -EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -8562,63 +8516,67 @@ EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn; - uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn - bool setflags; - uint32_t carry; // the carry bit after ARM/Thumb Expand operation - switch (encoding) - { - case eEncodingT1: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) - // if Rn == '1111' then SEE MOV (immediate); - if (Rn == 15) - return EmulateMOVRdImm (opcode, eEncodingT2); - if (BadReg(Rd) || Rn == 13) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) - - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn; + uint32_t + imm32; // the immediate value to be ORed to the value obtained from Rn + bool setflags; + uint32_t carry; // the carry bit after ARM/Thumb Expand operation + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm_C( + opcode, APSR_C, + carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) + // if Rn == '1111' then SEE MOV (immediate); + if (Rn == 15) + return EmulateMOVRdImm(opcode, eEncodingT2); + if (BadReg(Rd) || Rn == 13) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = + ARMExpandImm_C(opcode, APSR_C, + carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) + + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t result = val1 | imm32; + uint32_t result = val1 | imm32; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register -// value, and writes the result to the destination register. It can optionally update the condition flags based +// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value +// and an optionally-shifted register +// value, and writes the result to the destination register. It can optionally +// update the condition flags based // on the result. -bool -EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -8636,80 +8594,79 @@ EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rd, Rn, Rm; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - bool setflags; - uint32_t carry; - switch (encoding) - { - case eEncodingT1: - Rd = Rn = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - shift_t = SRType_LSL; - shift_n = 0; - break; - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - // if Rn == '1111' then SEE MOV (register); - if (Rn == 15) - return EmulateMOVRdRm (opcode, eEncodingT3); - if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftARM(opcode, shift_t); - - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rd, Rn, Rm; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + bool setflags; + uint32_t carry; + switch (encoding) { + case eEncodingT1: + Rd = Rn = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + shift_t = SRType_LSL; + shift_n = 0; + break; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + // if Rn == '1111' then SEE MOV (register); + if (Rn == 15) + return EmulateMOVRdRm(opcode, eEncodingT3); + if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftARM(opcode, shift_t); + + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - // Read the second operand. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; + // Read the second operand. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); - if (!success) - return false; - uint32_t result = val1 | shifted; + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; + uint32_t result = val1 | shifted; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) - return false; - } - return true; + if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) + return false; + } + return true; } -// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to -// the destination register. It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) -{ +// Reverse Subtract (immediate) subtracts a register value from an immediate +// value, and writes the result to +// the destination register. It can optionally update the condition flags based +// on the result. +bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -8726,62 +8683,66 @@ EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; + + uint32_t Rd; // the destination register + uint32_t Rn; // the first operand + bool setflags; + uint32_t + imm32; // the immediate value to be added to the value obtained from Rn + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 2, 0); + Rn = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + imm32 = 0; + break; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) + if (BadReg(Rd) || BadReg(Rn)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } + // Read the register value from the operand register Rn. + uint32_t reg_val = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t Rd; // the destination register - uint32_t Rn; // the first operand - bool setflags; - uint32_t imm32; // the immediate value to be added to the value obtained from Rn - switch (encoding) { - case eEncodingT1: - Rd = Bits32(opcode, 2, 0); - Rn = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - imm32 = 0; - break; - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) - if (BadReg(Rd) || BadReg(Rn)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - // Read the register value from the operand register Rn. - uint32_t reg_val = ReadCoreReg(Rn, &success); - if (!success) - return false; - - AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); + AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; - return true; + return true; } -// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the -// result to the destination register. It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) -{ +// Reverse Subtract (register) subtracts a register value from an +// optionally-shifted register value, and writes the +// result to the destination register. It can optionally update the condition +// flags based on the result. +bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -8799,69 +8760,72 @@ EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; + + uint32_t Rd; // the destination register + uint32_t Rn; // the first operand + uint32_t Rm; // the second operand + bool setflags; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; + if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftARM(opcode, shift_t); + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } + // Read the register value from register Rn. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t Rd; // the destination register - uint32_t Rn; // the first operand - uint32_t Rm; // the second operand - bool setflags; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - switch (encoding) { - case eEncodingT1: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; - if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftARM(opcode, shift_t); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - // Read the register value from register Rn. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the register value from register Rm. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - // Read the register value from register Rm. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; - - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; - return true; + return true; } -// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from -// an immediate value, and writes the result to the destination register. It can optionally update the condition +// Reverse Subtract with Carry (immediate) subtracts a register value and the +// value of NOT (Carry flag) from +// an immediate value, and writes the result to the destination register. It can +// optionally update the condition // flags based on the result. -bool -EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -8878,49 +8842,53 @@ EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; + + uint32_t Rd; // the destination register + uint32_t Rn; // the first operand + bool setflags; + uint32_t + imm32; // the immediate value to be added to the value obtained from Rn + switch (encoding) { + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } + // Read the register value from the operand register Rn. + uint32_t reg_val = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t Rd; // the destination register - uint32_t Rn; // the first operand - bool setflags; - uint32_t imm32; // the immediate value to be added to the value obtained from Rn - switch (encoding) { - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - // Read the register value from the operand register Rn. - uint32_t reg_val = ReadCoreReg(Rn, &success); - if (!success) - return false; - - AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); + AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; - return true; + return true; } -// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an -// optionally-shifted register value, and writes the result to the destination register. It can optionally update the +// Reverse Subtract with Carry (register) subtracts a register value and the +// value of NOT (Carry flag) from an +// optionally-shifted register value, and writes the result to the destination +// register. It can optionally update the // condition flags based on the result. -bool -EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -8938,59 +8906,61 @@ EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; + + uint32_t Rd; // the destination register + uint32_t Rn; // the first operand + uint32_t Rm; // the second operand + bool setflags; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + switch (encoding) { + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftARM(opcode, shift_t); + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } + // Read the register value from register Rn. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t Rd; // the destination register - uint32_t Rn; // the first operand - uint32_t Rm; // the second operand - bool setflags; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - switch (encoding) { - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftARM(opcode, shift_t); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - // Read the register value from register Rn. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the register value from register Rm. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - // Read the register value from register Rm. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; - - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; - return true; + return true; } // Subtract with Carry (immediate) subtracts an immediate value and the value of -// NOT (Carry flag) from a register value, and writes the result to the destination register. +// NOT (Carry flag) from a register value, and writes the result to the +// destination register. // It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -9007,57 +8977,61 @@ EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; + bool success = false; + + uint32_t Rd; // the destination register + uint32_t Rn; // the first operand + bool setflags; + uint32_t + imm32; // the immediate value to be added to the value obtained from Rn + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) + if (BadReg(Rd) || BadReg(Rn)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } + // Read the register value from the operand register Rn. + uint32_t reg_val = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t Rd; // the destination register - uint32_t Rn; // the first operand - bool setflags; - uint32_t imm32; // the immediate value to be added to the value obtained from Rn - switch (encoding) { - case eEncodingT1: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) - if (BadReg(Rd) || BadReg(Rn)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - // Read the register value from the operand register Rn. - uint32_t reg_val = ReadCoreReg(Rn, &success); - if (!success) - return false; - - AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); + AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; - return true; + return true; } -// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of -// NOT (Carry flag) from a register value, and writes the result to the destination register. +// Subtract with Carry (register) subtracts an optionally-shifted register value +// and the value of +// NOT (Carry flag) from a register value, and writes the result to the +// destination register. // It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -9075,74 +9049,77 @@ EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding e APSR.V = overflow; #endif - bool success = false; - - uint32_t Rd; // the destination register - uint32_t Rn; // the first operand - uint32_t Rm; // the second operand - bool setflags; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - switch (encoding) { - case eEncodingT1: - Rd = Rn = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - shift_t = SRType_LSL; - shift_n = 0; - break; - case eEncodingT2: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - setflags = BitIsSet(opcode, 20); - shift_n = DecodeImmShiftARM(opcode, shift_t); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - // Read the register value from register Rn. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; - - // Read the register value from register Rm. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; - - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); + bool success = false; + + uint32_t Rd; // the destination register + uint32_t Rn; // the first operand + uint32_t Rm; // the second operand + bool setflags; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + switch (encoding) { + case eEncodingT1: + Rd = Rn = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + shift_t = SRType_LSL; + shift_n = 0; + break; + case eEncodingT2: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + shift_n = DecodeImmShiftARM(opcode, shift_t); + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; + } + // Read the register value from register Rn. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; + // Read the register value from register Rm. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - return true; + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); + + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; + + return true; } -// This instruction subtracts an immediate value from a register value, and writes the result -// to the destination register. It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) -{ +// This instruction subtracts an immediate value from a register value, and +// writes the result +// to the destination register. It can optionally update the condition flags +// based on the result. +bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -9156,84 +9133,87 @@ EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncod APSR.V = overflow; #endif - bool success = false; - - uint32_t Rd; // the destination register - uint32_t Rn; // the first operand - bool setflags; - uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn - switch (encoding) { - case eEncodingT1: - Rd = Bits32(opcode, 2, 0); - Rn = Bits32(opcode, 5, 3); - setflags = !InITBlock(); - imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) - break; - case eEncodingT2: - Rd = Rn = Bits32(opcode, 10, 8); - setflags = !InITBlock(); - imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) - break; - case eEncodingT3: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) - - // if Rd == '1111' && S == '1' then SEE CMP (immediate); - if (Rd == 15 && setflags) - return EmulateCMPImm (opcode, eEncodingT2); - - // if Rn == '1101' then SEE SUB (SP minus immediate); - if (Rn == 13) - return EmulateSUBSPImm (opcode, eEncodingT2); - - // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; - if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) - return false; - break; - case eEncodingT4: - Rd = Bits32(opcode, 11, 8); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) - - // if Rn == '1111' then SEE ADR; - if (Rn == 15) - return EmulateADR (opcode, eEncodingT2); - - // if Rn == '1101' then SEE SUB (SP minus immediate); - if (Rn == 13) - return EmulateSUBSPImm (opcode, eEncodingT3); + bool success = false; + + uint32_t Rd; // the destination register + uint32_t Rn; // the first operand + bool setflags; + uint32_t imm32; // the immediate value to be subtracted from the value + // obtained from Rn + switch (encoding) { + case eEncodingT1: + Rd = Bits32(opcode, 2, 0); + Rn = Bits32(opcode, 5, 3); + setflags = !InITBlock(); + imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) + break; + case eEncodingT2: + Rd = Rn = Bits32(opcode, 10, 8); + setflags = !InITBlock(); + imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) + break; + case eEncodingT3: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) + + // if Rd == '1111' && S == '1' then SEE CMP (immediate); + if (Rd == 15 && setflags) + return EmulateCMPImm(opcode, eEncodingT2); + + // if Rn == '1101' then SEE SUB (SP minus immediate); + if (Rn == 13) + return EmulateSUBSPImm(opcode, eEncodingT2); + + // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; + if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) + return false; + break; + case eEncodingT4: + Rd = Bits32(opcode, 11, 8); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) + + // if Rn == '1111' then SEE ADR; + if (Rn == 15) + return EmulateADR(opcode, eEncodingT2); + + // if Rn == '1101' then SEE SUB (SP minus immediate); + if (Rn == 13) + return EmulateSUBSPImm(opcode, eEncodingT3); + + if (BadReg(Rd)) + return false; + break; + default: + return false; + } + // Read the register value from the operand register Rn. + uint32_t reg_val = ReadCoreReg(Rn, &success); + if (!success) + return false; - if (BadReg(Rd)) - return false; - break; - default: - return false; - } - // Read the register value from the operand register Rn. - uint32_t reg_val = ReadCoreReg(Rn, &success); - if (!success) - return false; - - AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); + AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; - return true; + return true; } -// This instruction subtracts an immediate value from a register value, and writes the result -// to the destination register. It can optionally update the condition flags based on the result. -bool -EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) -{ +// This instruction subtracts an immediate value from a register value, and +// writes the result +// to the destination register. It can optionally update the condition flags +// based on the result. +bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -9250,65 +9230,68 @@ EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncodin APSR.V = overflow; #endif - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t Rd; // the destination register - uint32_t Rn; // the first operand - bool setflags; - uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn - switch (encoding) { - case eEncodingA1: - Rd = Bits32(opcode, 15, 12); - Rn = Bits32(opcode, 19, 16); - setflags = BitIsSet(opcode, 20); - imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - - // if Rn == '1111' && S == '0' then SEE ADR; - if (Rn == 15 && !setflags) - return EmulateADR (opcode, eEncodingA2); - - // if Rn == '1101' then SEE SUB (SP minus immediate); - if (Rn == 13) - return EmulateSUBSPImm (opcode, eEncodingA1); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (Rd == 15 && setflags) - return EmulateSUBSPcLrEtc (opcode, encoding); - break; - default: - return false; - } - // Read the register value from the operand register Rn. - uint32_t reg_val = ReadCoreReg(Rn, &success); - if (!success) - return false; - - AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); - - EmulateInstruction::Context context; - if (Rd == 13) - context.type = EmulateInstruction::eContextAdjustStackPointer; - else - context.type = EmulateInstruction::eContextRegisterPlusOffset; - - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); - int64_t imm32_signed = imm32; - context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed); + bool success = false; - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) - return false; + if (ConditionPassed(opcode)) { + uint32_t Rd; // the destination register + uint32_t Rn; // the first operand + bool setflags; + uint32_t imm32; // the immediate value to be subtracted from the value + // obtained from Rn + switch (encoding) { + case eEncodingA1: + Rd = Bits32(opcode, 15, 12); + Rn = Bits32(opcode, 19, 16); + setflags = BitIsSet(opcode, 20); + imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + + // if Rn == '1111' && S == '0' then SEE ADR; + if (Rn == 15 && !setflags) + return EmulateADR(opcode, eEncodingA2); + + // if Rn == '1101' then SEE SUB (SP minus immediate); + if (Rn == 13) + return EmulateSUBSPImm(opcode, eEncodingA1); + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (Rd == 15 && setflags) + return EmulateSUBSPcLrEtc(opcode, encoding); + break; + default: + return false; } - return true; -} + // Read the register value from the operand register Rn. + uint32_t reg_val = ReadCoreReg(Rn, &success); + if (!success) + return false; + + AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); -// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an -// immediate value. It updates the condition flags based on the result, and discards the result. -bool -EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) -{ + EmulateInstruction::Context context; + if (Rd == 13) + context.type = EmulateInstruction::eContextAdjustStackPointer; + else + context.type = EmulateInstruction::eContextRegisterPlusOffset; + + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); + int64_t imm32_signed = imm32; + context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); + + if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow)) + return false; + } + return true; +} + +// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a +// register value and an +// immediate value. It updates the condition flags based on the result, and +// discards the result. +bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -9320,52 +9303,56 @@ EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rn; - uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn - uint32_t carry; // the carry bit after ARM/Thumb Expand operation - switch (encoding) - { - case eEncodingT1: - Rn = Bits32(opcode, 19, 16); - imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) - if (BadReg(Rn)) - return false; - break; - case eEncodingA1: - Rn = Bits32(opcode, 19, 16); - imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rn; + uint32_t + imm32; // the immediate value to be ANDed to the value obtained from Rn + uint32_t carry; // the carry bit after ARM/Thumb Expand operation + switch (encoding) { + case eEncodingT1: + Rn = Bits32(opcode, 19, 16); + imm32 = ThumbExpandImm_C( + opcode, APSR_C, + carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) + if (BadReg(Rn)) + return false; + break; + case eEncodingA1: + Rn = Bits32(opcode, 19, 16); + imm32 = + ARMExpandImm_C(opcode, APSR_C, + carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t result = val1 ^ imm32; + uint32_t result = val1 ^ imm32; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteFlags(context, result, carry)) - return false; - } - return true; + if (!WriteFlags(context, result, carry)) + return false; + } + return true; } -// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an -// optionally-shifted register value. It updates the condition flags based on the result, and discards +// Test Equivalence (register) performs a bitwise exclusive OR operation on a +// register value and an +// optionally-shifted register value. It updates the condition flags based on +// the result, and discards // the result. -bool -EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -9378,62 +9365,60 @@ EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rn, Rm; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - uint32_t carry; - switch (encoding) - { - case eEncodingT1: - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - if (BadReg(Rn) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - shift_n = DecodeImmShiftARM(opcode, shift_t); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rn, Rm; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + uint32_t carry; + switch (encoding) { + case eEncodingT1: + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + if (BadReg(Rn) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + shift_n = DecodeImmShiftARM(opcode, shift_t); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - // Read the second operand. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; + // Read the second operand. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); - if (!success) - return false; - uint32_t result = val1 ^ shifted; + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; + uint32_t result = val1 ^ shifted; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteFlags(context, result, carry)) - return false; - } - return true; + if (!WriteFlags(context, result, carry)) + return false; + } + return true; } -// Test (immediate) performs a bitwise AND operation on a register value and an immediate value. +// Test (immediate) performs a bitwise AND operation on a register value and an +// immediate value. // It updates the condition flags based on the result, and discards the result. -bool -EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -9445,51 +9430,54 @@ EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rn; - uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn - uint32_t carry; // the carry bit after ARM/Thumb Expand operation - switch (encoding) - { - case eEncodingT1: - Rn = Bits32(opcode, 19, 16); - imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) - if (BadReg(Rn)) - return false; - break; - case eEncodingA1: - Rn = Bits32(opcode, 19, 16); - imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rn; + uint32_t + imm32; // the immediate value to be ANDed to the value obtained from Rn + uint32_t carry; // the carry bit after ARM/Thumb Expand operation + switch (encoding) { + case eEncodingT1: + Rn = Bits32(opcode, 19, 16); + imm32 = ThumbExpandImm_C( + opcode, APSR_C, + carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) + if (BadReg(Rn)) + return false; + break; + case eEncodingA1: + Rn = Bits32(opcode, 19, 16); + imm32 = + ARMExpandImm_C(opcode, APSR_C, + carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - uint32_t result = val1 & imm32; + uint32_t result = val1 & imm32; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteFlags(context, result, carry)) - return false; - } - return true; + if (!WriteFlags(context, result, carry)) + return false; + } + return true; } -// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. +// Test (register) performs a bitwise AND operation on a register value and an +// optionally-shifted register value. // It updates the condition flags based on the result, and discards the result. -bool -EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 // ARM pseudo code... if ConditionPassed() then @@ -9502,67 +9490,64 @@ EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding e // APSR.V unchanged #endif - bool success = false; + bool success = false; - if (ConditionPassed(opcode)) - { - uint32_t Rn, Rm; - ARM_ShifterType shift_t; - uint32_t shift_n; // the shift applied to the value read from Rm - uint32_t carry; - switch (encoding) - { - case eEncodingT1: - Rn = Bits32(opcode, 2, 0); - Rm = Bits32(opcode, 5, 3); - shift_t = SRType_LSL; - shift_n = 0; - break; - case eEncodingT2: - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - shift_n = DecodeImmShiftThumb(opcode, shift_t); - if (BadReg(Rn) || BadReg(Rm)) - return false; - break; - case eEncodingA1: - Rn = Bits32(opcode, 19, 16); - Rm = Bits32(opcode, 3, 0); - shift_n = DecodeImmShiftARM(opcode, shift_t); - break; - default: - return false; - } + if (ConditionPassed(opcode)) { + uint32_t Rn, Rm; + ARM_ShifterType shift_t; + uint32_t shift_n; // the shift applied to the value read from Rm + uint32_t carry; + switch (encoding) { + case eEncodingT1: + Rn = Bits32(opcode, 2, 0); + Rm = Bits32(opcode, 5, 3); + shift_t = SRType_LSL; + shift_n = 0; + break; + case eEncodingT2: + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + if (BadReg(Rn) || BadReg(Rm)) + return false; + break; + case eEncodingA1: + Rn = Bits32(opcode, 19, 16); + Rm = Bits32(opcode, 3, 0); + shift_n = DecodeImmShiftARM(opcode, shift_t); + break; + default: + return false; + } - // Read the first operand. - uint32_t val1 = ReadCoreReg(Rn, &success); - if (!success) - return false; + // Read the first operand. + uint32_t val1 = ReadCoreReg(Rn, &success); + if (!success) + return false; - // Read the second operand. - uint32_t val2 = ReadCoreReg(Rm, &success); - if (!success) - return false; + // Read the second operand. + uint32_t val2 = ReadCoreReg(Rm, &success); + if (!success) + return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); - if (!success) - return false; - uint32_t result = val1 & shifted; + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; + uint32_t result = val1 & shifted; - EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextImmediate; - context.SetNoArgs (); + EmulateInstruction::Context context; + context.type = EmulateInstruction::eContextImmediate; + context.SetNoArgs(); - if (!WriteFlags(context, result, carry)) - return false; - } - return true; + if (!WriteFlags(context, result, carry)) + return false; + } + return true; } - + // A8.6.216 SUB (SP minus register) -bool -EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -9578,90 +9563,89 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding APSR.C = carry; APSR.V = overflow; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t d; - uint32_t m; - bool setflags; - ARM_ShifterType shift_t; - uint32_t shift_n; - switch (encoding) - { - case eEncodingT1: - // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); - d = Bits32 (opcode, 11, 8); - m = Bits32 (opcode, 3, 0); - setflags = BitIsSet (opcode, 20); - - // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); - shift_n = DecodeImmShiftThumb (opcode, shift_t); - - // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; - if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) - return false; - - // if d == 15 || BadReg(m) then UNPREDICTABLE; - if ((d == 15) || BadReg (m)) - return false; - break; - - case eEncodingA1: - // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); - d = Bits32 (opcode, 15, 12); - m = Bits32 (opcode, 3, 0); - setflags = BitIsSet (opcode, 20); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if (d == 15 && setflags) - EmulateSUBSPcLrEtc (opcode, encoding); - - // (shift_t, shift_n) = DecodeImmShift(type, imm5); - shift_n = DecodeImmShiftARM (opcode, shift_t); - break; - - default: - return false; - } + bool success = false; - // shifted = Shift(R[m], shift_t, shift_n, APSR.C); - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; + if (ConditionPassed(opcode)) { + uint32_t d; + uint32_t m; + bool setflags; + ARM_ShifterType shift_t; + uint32_t shift_n; - uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; + switch (encoding) { + case eEncodingT1: + // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); + d = Bits32(opcode, 11, 8); + m = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); - // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); - uint32_t sp_val = ReadCoreReg (SP_REG, &success); - if (!success) - return false; + // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + + // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then + // UNPREDICTABLE; + if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) + return false; - AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); + // if d == 15 || BadReg(m) then UNPREDICTABLE; + if ((d == 15) || BadReg(m)) + return false; + break; - EmulateInstruction::Context context; - context.type = eContextArithmetic; - RegisterInfo sp_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); - RegisterInfo dwarf_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); - context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); + case eEncodingA1: + // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); + d = Bits32(opcode, 15, 12); + m = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); - if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) - return false; + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if (d == 15 && setflags) + EmulateSUBSPcLrEtc(opcode, encoding); + + // (shift_t, shift_n) = DecodeImmShift(type, imm5); + shift_n = DecodeImmShiftARM(opcode, shift_t); + break; + + default: + return false; } - return true; + + // shifted = Shift(R[m], shift_t, shift_n, APSR.C); + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + + uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + + // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); + uint32_t sp_val = ReadCoreReg(SP_REG, &success); + if (!success) + return false; + + AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); + + EmulateInstruction::Context context; + context.type = eContextArithmetic; + RegisterInfo sp_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); + RegisterInfo dwarf_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); + context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); + + if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, + res.carry_out, res.overflow)) + return false; + } + return true; } - - + // A8.6.7 ADD (register-shifted register) -bool -EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -9670,96 +9654,94 @@ EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncod (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); R[d] = result; if setflags then - APSR.N = result<31>; - APSR.Z = IsZeroBit(result); - APSR.C = carry; - APSR.V = overflow; -#endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t d; - uint32_t n; - uint32_t m; - uint32_t s; - bool setflags; - ARM_ShifterType shift_t; - - switch (encoding) - { - case eEncodingA1: - // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - d = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - s = Bits32 (opcode, 11, 8); - - // setflags = (S == '1'); shift_t = DecodeRegShift(type); - setflags = BitIsSet (opcode, 20); - shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); - - // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) - return false; - break; - - default: - return false; - } - - // shift_n = UInt(R[s]<7:0>); - uint32_t Rs = ReadCoreReg (s, &success); - if (!success) - return false; - - uint32_t shift_n = Bits32 (Rs, 7, 0); - - // shifted = Shift(R[m], shift_t, shift_n, APSR.C); - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; - - uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; + APSR.N = result<31>; + APSR.Z = IsZeroBit(result); + APSR.C = carry; + APSR.V = overflow; +#endif - // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); - - // R[d] = result; - EmulateInstruction::Context context; - context.type = eContextArithmetic; - RegisterInfo reg_n; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); - RegisterInfo reg_m; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); - - context.SetRegisterRegisterOperands (reg_n, reg_m); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) - return false; - - // if setflags then - // APSR.N = result<31>; - // APSR.Z = IsZeroBit(result); - // APSR.C = carry; - // APSR.V = overflow; - if (setflags) - return WriteFlags (context, res.result, res.carry_out, res.overflow); + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t d; + uint32_t n; + uint32_t m; + uint32_t s; + bool setflags; + ARM_ShifterType shift_t; + + switch (encoding) { + case eEncodingA1: + // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); + d = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + s = Bits32(opcode, 11, 8); + + // setflags = (S == '1'); shift_t = DecodeRegShift(type); + setflags = BitIsSet(opcode, 20); + shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); + + // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; + if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) + return false; + break; + + default: + return false; } - return true; + + // shift_n = UInt(R[s]<7:0>); + uint32_t Rs = ReadCoreReg(s, &success); + if (!success) + return false; + + uint32_t shift_n = Bits32(Rs, 7, 0); + + // shifted = Shift(R[m], shift_t, shift_n, APSR.C); + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + + uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + + // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); + + // R[d] = result; + EmulateInstruction::Context context; + context.type = eContextArithmetic; + RegisterInfo reg_n; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); + RegisterInfo reg_m; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); + + context.SetRegisterRegisterOperands(reg_n, reg_m); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, + res.result)) + return false; + + // if setflags then + // APSR.N = result<31>; + // APSR.Z = IsZeroBit(result); + // APSR.C = carry; + // APSR.V = overflow; + if (setflags) + return WriteFlags(context, res.result, res.carry_out, res.overflow); + } + return true; } // A8.6.213 SUB (register) -bool -EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -9775,124 +9757,127 @@ EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding e APSR.C = carry; APSR.V = overflow; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t d; - uint32_t n; - uint32_t m; - bool setflags; - ARM_ShifterType shift_t; - uint32_t shift_n; - - switch (encoding) - { - case eEncodingT1: - // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); - d = Bits32 (opcode, 2, 0); - n = Bits32 (opcode, 5, 3); - m = Bits32 (opcode, 8, 6); - setflags = !InITBlock(); - - // (shift_t, shift_n) = (SRType_LSL, 0); - shift_t = SRType_LSL; - shift_n = 0; - - break; - - case eEncodingT2: - // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); - d = Bits32 (opcode, 11, 8); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - setflags = BitIsSet (opcode, 20); - - // if Rd == "1111" && S == "1" then SEE CMP (register); - if (d == 15 && setflags == 1) - return EmulateCMPImm (opcode, eEncodingT3); - - // if Rn == "1101" then SEE SUB (SP minus register); - if (n == 13) - return EmulateSUBSPReg (opcode, eEncodingT1); - // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); - shift_n = DecodeImmShiftThumb (opcode, shift_t); - - // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; - if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) - return false; - - break; - - case eEncodingA1: - // if Rn == '1101' then SEE SUB (SP minus register); - // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - d = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - setflags = BitIsSet (opcode, 20); - - // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - if ((d == 15) && setflags) - EmulateSUBSPcLrEtc (opcode, encoding); - - // (shift_t, shift_n) = DecodeImmShift(type, imm5); - shift_n = DecodeImmShiftARM (opcode, shift_t); - - break; - - default: - return false; - } - - // shifted = Shift(R[m], shift_t, shift_n, APSR.C); - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; - - uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); - if (!success) - return false; - - // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); - - // if d == 15 then // Can only occur for ARM encoding - // ALUWritePC(result); // setflags is always FALSE here - // else - // R[d] = result; - // if setflags then - // APSR.N = result<31>; - // APSR.Z = IsZeroBit(result); - // APSR.C = carry; - // APSR.V = overflow; - - EmulateInstruction::Context context; - context.type = eContextArithmetic; - RegisterInfo reg_n; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); - RegisterInfo reg_m; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); - context.SetRegisterRegisterOperands (reg_n, reg_m); - - if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) - return false; + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t d; + uint32_t n; + uint32_t m; + bool setflags; + ARM_ShifterType shift_t; + uint32_t shift_n; + + switch (encoding) { + case eEncodingT1: + // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); + d = Bits32(opcode, 2, 0); + n = Bits32(opcode, 5, 3); + m = Bits32(opcode, 8, 6); + setflags = !InITBlock(); + + // (shift_t, shift_n) = (SRType_LSL, 0); + shift_t = SRType_LSL; + shift_n = 0; + + break; + + case eEncodingT2: + // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); + d = Bits32(opcode, 11, 8); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + + // if Rd == "1111" && S == "1" then SEE CMP (register); + if (d == 15 && setflags == 1) + return EmulateCMPImm(opcode, eEncodingT3); + + // if Rn == "1101" then SEE SUB (SP minus register); + if (n == 13) + return EmulateSUBSPReg(opcode, eEncodingT1); + + // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); + shift_n = DecodeImmShiftThumb(opcode, shift_t); + + // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then + // UNPREDICTABLE; + if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || + BadReg(m)) + return false; + + break; + + case eEncodingA1: + // if Rn == '1101' then SEE SUB (SP minus register); + // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); + d = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + setflags = BitIsSet(opcode, 20); + + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related + // instructions; + if ((d == 15) && setflags) + EmulateSUBSPcLrEtc(opcode, encoding); + + // (shift_t, shift_n) = DecodeImmShift(type, imm5); + shift_n = DecodeImmShiftARM(opcode, shift_t); + + break; + + default: + return false; } - return true; + + // shifted = Shift(R[m], shift_t, shift_n, APSR.C); + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + + uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + + // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); + + // if d == 15 then // Can only occur for ARM encoding + // ALUWritePC(result); // setflags is always FALSE here + // else + // R[d] = result; + // if setflags then + // APSR.N = result<31>; + // APSR.Z = IsZeroBit(result); + // APSR.C = carry; + // APSR.V = overflow; + + EmulateInstruction::Context context; + context.type = eContextArithmetic; + RegisterInfo reg_n; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); + RegisterInfo reg_m; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); + context.SetRegisterRegisterOperands(reg_n, reg_m); + + if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, + res.carry_out, res.overflow)) + return false; + } + return true; } - + // A8.6.202 STREX -// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a -// word from a register to memory if the executing processor has exclusive access to the memory addressed. -bool -EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) -{ +// Store Register Exclusive calculates an address from a base register value and +// an immediate offset, and stores a +// word from a register to memory if the executing processor has exclusive +// access to the memory addressed. +bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -9903,90 +9888,92 @@ EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding en else R[d] = 1; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t d; - uint32_t t; - uint32_t n; - uint32_t imm32; - const uint32_t addr_byte_size = GetAddressByteSize(); - - switch (encoding) - { - case eEncodingT1: - // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - d = Bits32 (opcode, 11, 8); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0) << 2; - - // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; - if (BadReg (d) || BadReg (t) || (n == 15)) - return false; - - // if d == n || d == t then UNPREDICTABLE; - if ((d == n) || (d == t)) - return false; - - break; - - case eEncodingA1: - // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset - d = Bits32 (opcode, 15, 12); - t = Bits32 (opcode, 3, 0); - n = Bits32 (opcode, 19, 16); - imm32 = 0; - - // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; - if ((d == 15) || (t == 15) || (n == 15)) - return false; - - // if d == n || d == t then UNPREDICTABLE; - if ((d == n) || (d == t)) - return false; - - break; - - default: - return false; - } - - // address = R[n] + imm32; - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - addr_t address = Rn + imm32; - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); - EmulateInstruction::Context context; - context.type = eContextRegisterStore; - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); - - // if ExclusiveMonitorsPass(address,4) then - // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this - // always return true. - if (true) - { - // MemA[address,4] = R[t]; - uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); - if (!success) - return false; - - if (!MemAWrite (context, address, Rt, addr_byte_size)) - return false; - - // R[d] = 0; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) - return false; - } -#if 0 // unreachable because if true + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t d; + uint32_t t; + uint32_t n; + uint32_t imm32; + const uint32_t addr_byte_size = GetAddressByteSize(); + + switch (encoding) { + case eEncodingT1: + // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', + // 32); + d = Bits32(opcode, 11, 8); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0) << 2; + + // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; + if (BadReg(d) || BadReg(t) || (n == 15)) + return false; + + // if d == n || d == t then UNPREDICTABLE; + if ((d == n) || (d == t)) + return false; + + break; + + case eEncodingA1: + // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero + // offset + d = Bits32(opcode, 15, 12); + t = Bits32(opcode, 3, 0); + n = Bits32(opcode, 19, 16); + imm32 = 0; + + // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; + if ((d == 15) || (t == 15) || (n == 15)) + return false; + + // if d == n || d == t then UNPREDICTABLE; + if ((d == n) || (d == t)) + return false; + + break; + + default: + return false; + } + + // address = R[n] + imm32; + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + addr_t address = Rn + imm32; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); + EmulateInstruction::Context context; + context.type = eContextRegisterStore; + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); + + // if ExclusiveMonitorsPass(address,4) then + // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the + // sake of emulation, we will say this + // always return + // true. + if (true) { + // MemA[address,4] = R[t]; + uint32_t Rt = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); + if (!success) + return false; + + if (!MemAWrite(context, address, Rt, addr_byte_size)) + return false; + + // R[d] = 0; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) + return false; + } +#if 0 // unreachable because if true else { // R[d] = 1; @@ -9994,14 +9981,13 @@ EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding en return false; } #endif // unreachable because if true - } - return true; + } + return true; } // A8.6.197 STRB (immediate, ARM) -bool -EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -10010,94 +9996,91 @@ EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncodi MemU[address,1] = R[t]<7:0>; if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - - switch (encoding) - { - case eEncodingA1: - // if P == '0' && W == '1' then SEE STRBT; - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 11, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - - // if t == 15 then UNPREDICTABLE; - if (t == 15) - return false; - - // if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t))) - return false; - - break; - - default: - return false; - } - - // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - addr_t offset_addr; - if (add) - offset_addr = Rn + imm32; - else - offset_addr = Rn - imm32; - - // address = if index then offset_addr else R[n]; - addr_t address; - if (index) - address = offset_addr; - else - address = Rn; - - // MemU[address,1] = R[t]<7:0>; - uint32_t Rt = ReadCoreReg (t, &success); - if (!success) - return false; - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); - EmulateInstruction::Context context; - context.type = eContextRegisterStore; - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); - - if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + + switch (encoding) { + case eEncodingA1: + // if P == '0' && W == '1' then SEE STRBT; + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 11, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); + + // if t == 15 then UNPREDICTABLE; + if (t == 15) + return false; + + // if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t))) + return false; + + break; + + default: + return false; } - return true; + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + addr_t offset_addr; + if (add) + offset_addr = Rn + imm32; + else + offset_addr = Rn - imm32; + + // address = if index then offset_addr else R[n]; + addr_t address; + if (index) + address = offset_addr; + else + address = Rn; + + // MemU[address,1] = R[t]<7:0>; + uint32_t Rt = ReadCoreReg(t, &success); + if (!success) + return false; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); + EmulateInstruction::Context context; + context.type = eContextRegisterStore; + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); + + if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } // A8.6.194 STR (immediate, ARM) -bool -EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -10106,110 +10089,107 @@ EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncodin MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - - const uint32_t addr_byte_size = GetAddressByteSize(); - - switch (encoding) - { - case eEncodingA1: - // if P == '0' && W == '1' then SEE STRT; - // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; - // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - t = Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 11, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - - // if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t))) - return false; - - break; - - default: - return false; - } - - // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - addr_t offset_addr; - if (add) - offset_addr = Rn + imm32; - else - offset_addr = Rn - imm32; - - // address = if index then offset_addr else R[n]; - addr_t address; - if (index) - address = offset_addr; - else - address = Rn; - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); - EmulateInstruction::Context context; - context.type = eContextRegisterStore; - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); - - // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; - uint32_t Rt = ReadCoreReg (t, &success); - if (!success) - return false; - - if (t == 15) - { - uint32_t pc_value = ReadCoreReg (PC_REG, &success); - if (!success) - return false; - - if (!MemUWrite (context, address, pc_value, addr_byte_size)) - return false; - } - else - { - if (!MemUWrite (context, address, Rt, addr_byte_size)) - return false; - } - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetImmediate (offset_addr); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + + const uint32_t addr_byte_size = GetAddressByteSize(); + + switch (encoding) { + case eEncodingA1: + // if P == '0' && W == '1' then SEE STRT; + // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == + // '000000000100' then SEE PUSH; + // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + t = Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 11, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); + + // if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t))) + return false; + + break; + + default: + return false; } - return true; + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + addr_t offset_addr; + if (add) + offset_addr = Rn + imm32; + else + offset_addr = Rn - imm32; + + // address = if index then offset_addr else R[n]; + addr_t address; + if (index) + address = offset_addr; + else + address = Rn; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); + EmulateInstruction::Context context; + context.type = eContextRegisterStore; + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); + + // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; + uint32_t Rt = ReadCoreReg(t, &success); + if (!success) + return false; + + if (t == 15) { + uint32_t pc_value = ReadCoreReg(PC_REG, &success); + if (!success) + return false; + + if (!MemUWrite(context, address, pc_value, addr_byte_size)) + return false; + } else { + if (!MemUWrite(context, address, Rt, addr_byte_size)) + return false; + } + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetImmediate(offset_addr); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } // A8.6.66 LDRD (immediate) -// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two -// words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. -bool -EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) -{ +// Load Register Dual (immediate) calculates an address from a base register +// value and an immediate offset, loads two +// words from memory, and writes them to two registers. It can use offset, +// post-indexed, or pre-indexed addressing. +bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -10219,144 +10199,146 @@ EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEnc R[t2] = MemA[address+4,4]; if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t t2; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - - switch (encoding) - { - case eEncodingT1: - //if P == '0' && W == '0' then SEE 'Related encodings'; - //if Rn == '1111' then SEE LDRD (literal); - //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - t = Bits32 (opcode, 15, 12); - t2 = Bits32 (opcode, 11, 8); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0) << 2; - - //index = (P == '1'); add = (U == '1'); wback = (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsSet (opcode, 21); - - //if wback && (n == t || n == t2) then UNPREDICTABLE; - if (wback && ((n == t) || (n == t2))) - return false; - - //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; - if (BadReg (t) || BadReg (t2) || (t == t2)) - return false; - - break; - - case eEncodingA1: - //if Rn == '1111' then SEE LDRD (literal); - //if Rt<0> == '1' then UNPREDICTABLE; - //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); - t = Bits32 (opcode, 15, 12); - if (BitIsSet (t, 0)) - return false; - t2 = t + 1; - n = Bits32 (opcode, 19, 16); - imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); - - //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - - //if P == '0' && W == '1' then UNPREDICTABLE; - if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) - return false; - - //if wback && (n == t || n == t2) then UNPREDICTABLE; - if (wback && ((n == t) || (n == t2))) - return false; - - //if t2 == 15 then UNPREDICTABLE; - if (t2 == 15) - return false; - - break; - - default: - return false; - } - - //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - addr_t offset_addr; - if (add) - offset_addr = Rn + imm32; - else - offset_addr = Rn - imm32; - - //address = if index then offset_addr else R[n]; - addr_t address; - if (index) - address = offset_addr; - else - address = Rn; - - //R[t] = MemA[address,4]; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - EmulateInstruction::Context context; - if (n == 13) - context.type = eContextPopRegisterOffStack; - else - context.type = eContextRegisterLoad; - context.SetAddress(address); - - const uint32_t addr_byte_size = GetAddressByteSize(); - uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - - //R[t2] = MemA[address+4,4]; - context.SetAddress(address + 4); - data = MemARead (context, address + 4, addr_byte_size, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) - return false; - - //if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t t2; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + + switch (encoding) { + case eEncodingT1: + // if P == '0' && W == '0' then SEE 'Related encodings'; + // if Rn == '1111' then SEE LDRD (literal); + // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = + // ZeroExtend(imm8:'00', 32); + t = Bits32(opcode, 15, 12); + t2 = Bits32(opcode, 11, 8); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0) << 2; + + // index = (P == '1'); add = (U == '1'); wback = (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsSet(opcode, 21); + + // if wback && (n == t || n == t2) then UNPREDICTABLE; + if (wback && ((n == t) || (n == t2))) + return false; + + // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; + if (BadReg(t) || BadReg(t2) || (t == t2)) + return false; + + break; + + case eEncodingA1: + // if Rn == '1111' then SEE LDRD (literal); + // if Rt<0> == '1' then UNPREDICTABLE; + // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, + // 32); + t = Bits32(opcode, 15, 12); + if (BitIsSet(t, 0)) + return false; + t2 = t + 1; + n = Bits32(opcode, 19, 16); + imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); + + // if P == '0' && W == '1' then UNPREDICTABLE; + if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) + return false; + + // if wback && (n == t || n == t2) then UNPREDICTABLE; + if (wback && ((n == t) || (n == t2))) + return false; + + // if t2 == 15 then UNPREDICTABLE; + if (t2 == 15) + return false; + + break; + + default: + return false; } - return true; + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + addr_t offset_addr; + if (add) + offset_addr = Rn + imm32; + else + offset_addr = Rn - imm32; + + // address = if index then offset_addr else R[n]; + addr_t address; + if (index) + address = offset_addr; + else + address = Rn; + + // R[t] = MemA[address,4]; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + EmulateInstruction::Context context; + if (n == 13) + context.type = eContextPopRegisterOffStack; + else + context.type = eContextRegisterLoad; + context.SetAddress(address); + + const uint32_t addr_byte_size = GetAddressByteSize(); + uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); + if (!success) + return false; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) + return false; + + // R[t2] = MemA[address+4,4]; + context.SetAddress(address + 4); + data = MemARead(context, address + 4, addr_byte_size, 0, &success); + if (!success) + return false; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, + data)) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } - + // A8.6.68 LDRD (register) -// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two -// words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. -bool -EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) -{ +// Load Register Dual (register) calculates an address from a base register +// value and a register offset, loads two +// words from memory, and writes them to two registers. It can use offset, +// post-indexed or pre-indexed addressing. +bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -10366,127 +10348,127 @@ EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEnco R[t2] = MemA[address+4,4]; if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t t2; - uint32_t n; - uint32_t m; - bool index; - bool add; - bool wback; - - switch (encoding) - { - case eEncodingA1: - // if Rt<0> == '1' then UNPREDICTABLE; - // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - if (BitIsSet (t, 0)) - return false; - t2 = t + 1; - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - - // if P == '0' && W == '1' then UNPREDICTABLE; - if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) - return false; - - // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; - if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) - return false; - - // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t) || (n == t2))) - return false; - - // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; - if ((ArchVersion() < 6) && wback && (m == n)) - return false; - break; - - default: - return false; - } - - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; - RegisterInfo offset_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); - - // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); - addr_t offset_addr; - if (add) - offset_addr = Rn + Rm; - else - offset_addr = Rn - Rm; - - // address = if index then offset_addr else R[n]; - addr_t address; - if (index) - address = offset_addr; - else - address = Rn; - - EmulateInstruction::Context context; - if (n == 13) - context.type = eContextPopRegisterOffStack; - else - context.type = eContextRegisterLoad; - context.SetAddress(address); - - // R[t] = MemA[address,4]; - const uint32_t addr_byte_size = GetAddressByteSize(); - uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) - return false; - - // R[t2] = MemA[address+4,4]; - - data = MemARead (context, address + 4, addr_byte_size, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t t2; + uint32_t n; + uint32_t m; + bool index; + bool add; + bool wback; + + switch (encoding) { + case eEncodingA1: + // if Rt<0> == '1' then UNPREDICTABLE; + // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + if (BitIsSet(t, 0)) + return false; + t2 = t + 1; + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); + + // if P == '0' && W == '1' then UNPREDICTABLE; + if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) + return false; + + // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; + if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) + return false; + + // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t) || (n == t2))) + return false; + + // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; + if ((ArchVersion() < 6) && wback && (m == n)) + return false; + break; + + default: + return false; } - return true; + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + RegisterInfo offset_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); + + // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); + addr_t offset_addr; + if (add) + offset_addr = Rn + Rm; + else + offset_addr = Rn - Rm; + + // address = if index then offset_addr else R[n]; + addr_t address; + if (index) + address = offset_addr; + else + address = Rn; + + EmulateInstruction::Context context; + if (n == 13) + context.type = eContextPopRegisterOffStack; + else + context.type = eContextRegisterLoad; + context.SetAddress(address); + + // R[t] = MemA[address,4]; + const uint32_t addr_byte_size = GetAddressByteSize(); + uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); + if (!success) + return false; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) + return false; + + // R[t2] = MemA[address+4,4]; + + data = MemARead(context, address + 4, addr_byte_size, 0, &success); + if (!success) + return false; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, + data)) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } // A8.6.200 STRD (immediate) -// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and -// stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. -bool -EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) -{ +// Store Register Dual (immediate) calculates an address from a base register +// value and an immediate offset, and +// stores two words from two registers to memory. It can use offset, +// post-indexed, or pre-indexed addressing. +bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); NullCheckIfThumbEE(n); @@ -10496,151 +10478,150 @@ EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding MemA[address+4,4] = R[t2]; if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t t2; - uint32_t n; - uint32_t imm32; - bool index; - bool add; - bool wback; - - switch (encoding) - { - case eEncodingT1: - // if P == '0' && W == '0' then SEE 'Related encodings'; - // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - t = Bits32 (opcode, 15, 12); - t2 = Bits32 (opcode, 11, 8); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0) << 2; - - // index = (P == '1'); add = (U == '1'); wback = (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsSet (opcode, 21); - - // if wback && (n == t || n == t2) then UNPREDICTABLE; - if (wback && ((n == t) || (n == t2))) - return false; - - // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; - if ((n == 15) || BadReg (t) || BadReg (t2)) - return false; - - break; - - case eEncodingA1: - // if Rt<0> == '1' then UNPREDICTABLE; - // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); - t = Bits32 (opcode, 15, 12); - if (BitIsSet (t, 0)) - return false; - - t2 = t + 1; - n = Bits32 (opcode, 19, 16); - imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - - // if P == '0' && W == '1' then UNPREDICTABLE; - if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) - return false; - - // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t) || (n == t2))) - return false; - - // if t2 == 15 then UNPREDICTABLE; - if (t2 == 15) - return false; - - break; - - default: - return false; - } - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - addr_t offset_addr; - if (add) - offset_addr = Rn + imm32; - else - offset_addr = Rn - imm32; - - //address = if index then offset_addr else R[n]; - addr_t address; - if (index) - address = offset_addr; - else - address = Rn; - - //MemA[address,4] = R[t]; - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); - - uint32_t data = ReadCoreReg (t, &success); - if (!success) - return false; - - EmulateInstruction::Context context; - if (n == 13) - context.type = eContextPushRegisterOnStack; - else - context.type = eContextRegisterStore; - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); - - const uint32_t addr_byte_size = GetAddressByteSize(); - - if (!MemAWrite (context, address, data, addr_byte_size)) - return false; - //MemA[address+4,4] = R[t2]; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); - - data = ReadCoreReg (t2, &success); - if (!success) - return false; - - if (!MemAWrite (context, address + 4, data, addr_byte_size)) - return false; - - //if wback then R[n] = offset_addr; - if (wback) - { - if (n == 13) - context.type = eContextAdjustStackPointer; - else - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t t2; + uint32_t n; + uint32_t imm32; + bool index; + bool add; + bool wback; + + switch (encoding) { + case eEncodingT1: + // if P == '0' && W == '0' then SEE 'Related encodings'; + // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = + // ZeroExtend(imm8:'00', 32); + t = Bits32(opcode, 15, 12); + t2 = Bits32(opcode, 11, 8); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0) << 2; + + // index = (P == '1'); add = (U == '1'); wback = (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsSet(opcode, 21); + + // if wback && (n == t || n == t2) then UNPREDICTABLE; + if (wback && ((n == t) || (n == t2))) + return false; + + // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; + if ((n == 15) || BadReg(t) || BadReg(t2)) + return false; + + break; + + case eEncodingA1: + // if Rt<0> == '1' then UNPREDICTABLE; + // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, + // 32); + t = Bits32(opcode, 15, 12); + if (BitIsSet(t, 0)) + return false; + + t2 = t + 1; + n = Bits32(opcode, 19, 16); + imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); + + // if P == '0' && W == '1' then UNPREDICTABLE; + if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) + return false; + + // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t) || (n == t2))) + return false; + + // if t2 == 15 then UNPREDICTABLE; + if (t2 == 15) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - } + break; + + default: + return false; } - return true; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); + addr_t offset_addr; + if (add) + offset_addr = Rn + imm32; + else + offset_addr = Rn - imm32; + + // address = if index then offset_addr else R[n]; + addr_t address; + if (index) + address = offset_addr; + else + address = Rn; + + // MemA[address,4] = R[t]; + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); + + uint32_t data = ReadCoreReg(t, &success); + if (!success) + return false; + + EmulateInstruction::Context context; + if (n == 13) + context.type = eContextPushRegisterOnStack; + else + context.type = eContextRegisterStore; + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); + + const uint32_t addr_byte_size = GetAddressByteSize(); + + if (!MemAWrite(context, address, data, addr_byte_size)) + return false; + + // MemA[address+4,4] = R[t2]; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + (address + 4) - Rn); + + data = ReadCoreReg(t2, &success); + if (!success) + return false; + + if (!MemAWrite(context, address + 4, data, addr_byte_size)) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + if (n == 13) + context.type = eContextAdjustStackPointer; + else + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } - - + // A8.6.201 STRD (register) -bool -EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); @@ -10650,137 +10631,136 @@ EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding MemA[address+4,4] = R[t2]; if wback then R[n] = offset_addr; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - uint32_t t; - uint32_t t2; - uint32_t n; - uint32_t m; - bool index; - bool add; - bool wback; - - switch (encoding) - { - case eEncodingA1: - // if Rt<0> == '1' then UNPREDICTABLE; - // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); - t = Bits32 (opcode, 15, 12); - if (BitIsSet (t, 0)) - return false; - - t2 = t+1; - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - index = BitIsSet (opcode, 24); - add = BitIsSet (opcode, 23); - wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - - // if P == '0' && W == '1' then UNPREDICTABLE; - if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) - return false; - - // if t2 == 15 || m == 15 then UNPREDICTABLE; - if ((t2 == 15) || (m == 15)) - return false; - - // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; - if (wback && ((n == 15) || (n == t) || (n == t2))) - return false; - - // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; - if ((ArchVersion() < 6) && wback && (m == n)) - return false; - - break; - - default: - return false; - } - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - RegisterInfo offset_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); - RegisterInfo data_reg; - - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; - - // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); - addr_t offset_addr; - if (add) - offset_addr = Rn + Rm; - else - offset_addr = Rn - Rm; - - // address = if index then offset_addr else R[n]; - addr_t address; - if (index) - address = offset_addr; - else - address = Rn; - // MemA[address,4] = R[t]; - uint32_t Rt = ReadCoreReg (t, &success); - if (!success) - return false; - - EmulateInstruction::Context context; - if (t == 13) - context.type = eContextPushRegisterOnStack; - else - context.type = eContextRegisterStore; - - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); - context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); - - const uint32_t addr_byte_size = GetAddressByteSize(); - - if (!MemAWrite (context, address, Rt, addr_byte_size)) - return false; - - // MemA[address+4,4] = R[t2]; - uint32_t Rt2 = ReadCoreReg (t2, &success); - if (!success) - return false; - - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); - - context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); - - if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) - return false; - - // if wback then R[n] = offset_addr; - if (wback) - { - context.type = eContextAdjustBaseRegister; - context.SetAddress (offset_addr); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) - return false; - - } + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t t; + uint32_t t2; + uint32_t n; + uint32_t m; + bool index; + bool add; + bool wback; + + switch (encoding) { + case eEncodingA1: + // if Rt<0> == '1' then UNPREDICTABLE; + // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); + t = Bits32(opcode, 15, 12); + if (BitIsSet(t, 0)) + return false; + + t2 = t + 1; + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); + index = BitIsSet(opcode, 24); + add = BitIsSet(opcode, 23); + wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); + + // if P == '0' && W == '1' then UNPREDICTABLE; + if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) + return false; + + // if t2 == 15 || m == 15 then UNPREDICTABLE; + if ((t2 == 15) || (m == 15)) + return false; + + // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; + if (wback && ((n == 15) || (n == t) || (n == t2))) + return false; + + // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; + if ((ArchVersion() < 6) && wback && (m == n)) + return false; + + break; + + default: + return false; } - return true; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + RegisterInfo offset_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); + RegisterInfo data_reg; + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + + // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); + addr_t offset_addr; + if (add) + offset_addr = Rn + Rm; + else + offset_addr = Rn - Rm; + + // address = if index then offset_addr else R[n]; + addr_t address; + if (index) + address = offset_addr; + else + address = Rn; + // MemA[address,4] = R[t]; + uint32_t Rt = ReadCoreReg(t, &success); + if (!success) + return false; + + EmulateInstruction::Context context; + if (t == 13) + context.type = eContextPushRegisterOnStack; + else + context.type = eContextRegisterStore; + + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); + context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, + data_reg); + + const uint32_t addr_byte_size = GetAddressByteSize(); + + if (!MemAWrite(context, address, Rt, addr_byte_size)) + return false; + + // MemA[address+4,4] = R[t2]; + uint32_t Rt2 = ReadCoreReg(t2, &success); + if (!success) + return false; + + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); + + context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, + data_reg); + + if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) + return false; + + // if wback then R[n] = offset_addr; + if (wback) { + context.type = eContextAdjustBaseRegister; + context.SetAddress(offset_addr); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + offset_addr)) + return false; + } + } + return true; } - + // A8.6.319 VLDM -// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from +// Vector Load Multiple loads multiple extension registers from consecutive +// memory locations using an address from // an ARM core register. -bool -EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); @@ -10794,381 +10774,391 @@ EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding enc // Combine the word-aligned words in the correct order for current endianness. D[d+r] = if BigEndian() then word1:word2 else word2:word1; #endif - - bool success = false; - - if (ConditionPassed(opcode)) - { - bool single_regs; - bool add; - bool wback; - uint32_t d; - uint32_t n; - uint32_t imm32; - uint32_t regs; - - switch (encoding) - { - case eEncodingT1: - case eEncodingA1: - // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; - // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; - // if P == '1' && W == '0' then SEE VLDR; - // if P == U && W == '1' then UNDEFINED; - if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) - return false; - - // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); - single_regs = false; - add = BitIsSet (opcode, 23); - wback = BitIsSet (opcode, 21); - - // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0) << 2; - - // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. - regs = Bits32 (opcode, 7, 0) / 2; - - // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; - if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) - return false; - - // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) - return false; - - break; - - case eEncodingT2: - case eEncodingA2: - // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; - // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; - // if P == '1' && W == '0' then SEE VLDR; - // if P == U && W == '1' then UNDEFINED; - if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) - return false; - - // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); - single_regs = true; - add = BitIsSet (opcode, 23); - wback = BitIsSet (opcode, 21); - d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); - n = Bits32 (opcode, 19, 16); - - // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); - imm32 = Bits32 (opcode, 7, 0) << 2; - regs = Bits32 (opcode, 7, 0); - - // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; - if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) - return false; - - // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; - if ((regs == 0) || ((d + regs) > 32)) - return false; - break; - - default: - return false; - } - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rn = ReadCoreReg (n, &success); + + bool success = false; + + if (ConditionPassed(opcode)) { + bool single_regs; + bool add; + bool wback; + uint32_t d; + uint32_t n; + uint32_t imm32; + uint32_t regs; + + switch (encoding) { + case eEncodingT1: + case eEncodingA1: + // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; + // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; + // if P == '1' && W == '0' then SEE VLDR; + // if P == U && W == '1' then UNDEFINED; + if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) + return false; + + // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with + // !), 101 (DB with !) + // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); + single_regs = false; + add = BitIsSet(opcode, 23); + wback = BitIsSet(opcode, 21); + + // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); + d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0) << 2; + + // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. + regs = Bits32(opcode, 7, 0) / 2; + + // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then + // UNPREDICTABLE; + if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) + return false; + + // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; + if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) + return false; + + break; + + case eEncodingT2: + case eEncodingA2: + // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; + // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; + // if P == '1' && W == '0' then SEE VLDR; + // if P == U && W == '1' then UNDEFINED; + if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) + return false; + + // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with + // !), 101 (DB with !) + // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = + // UInt(Vd:D); n = UInt(Rn); + single_regs = true; + add = BitIsSet(opcode, 23); + wback = BitIsSet(opcode, 21); + d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); + n = Bits32(opcode, 19, 16); + + // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); + imm32 = Bits32(opcode, 7, 0) << 2; + regs = Bits32(opcode, 7, 0); + + // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then + // UNPREDICTABLE; + if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) + return false; + + // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; + if ((regs == 0) || ((d + regs) > 32)) + return false; + break; + + default: + return false; + } + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // address = if add then R[n] else R[n]-imm32; + addr_t address; + if (add) + address = Rn; + else + address = Rn - imm32; + + // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; + EmulateInstruction::Context context; + + if (wback) { + uint32_t value; + if (add) + value = Rn + imm32; + else + value = Rn - imm32; + + context.type = eContextAdjustBaseRegister; + context.SetImmediateSigned(value - Rn); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + value)) + return false; + } + + const uint32_t addr_byte_size = GetAddressByteSize(); + uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; + + context.type = eContextRegisterLoad; + + // for r = 0 to regs-1 + for (uint32_t r = 0; r < regs; ++r) { + if (single_regs) { + // S[d+r] = MemA[address,4]; address = address+4; + context.SetRegisterPlusOffset(base_reg, address - Rn); + + uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); if (!success) - return false; - - // address = if add then R[n] else R[n]-imm32; - addr_t address; - if (add) - address = Rn; - else - address = Rn - imm32; - - // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; - EmulateInstruction::Context context; - - if (wback) - { - uint32_t value; - if (add) - value = Rn + imm32; - else - value = Rn - imm32; - - context.type = eContextAdjustBaseRegister; - context.SetImmediateSigned (value - Rn); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) - return false; - - } - - const uint32_t addr_byte_size = GetAddressByteSize(); - uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; + return false; - context.type = eContextRegisterLoad; - - // for r = 0 to regs-1 - for (uint32_t r = 0; r < regs; ++r) - { - if (single_regs) - { - // S[d+r] = MemA[address,4]; address = address+4; - context.SetRegisterPlusOffset (base_reg, address - Rn); - - uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) - return false; - - address = address + 4; - } - else - { - // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; - context.SetRegisterPlusOffset (base_reg, address - Rn); - uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); - if (!success) - return false; - - context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); - uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); - if (!success) - return false; - - address = address + 8; - // // Combine the word-aligned words in the correct order for current endianness. - // D[d+r] = if BigEndian() then word1:word2 else word2:word1; - uint64_t data; - if (GetByteOrder() == eByteOrderBig) - { - data = word1; - data = (data << 32) | word2; - } - else - { - data = word2; - data = (data << 32) | word1; - } - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) - return false; - } + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, + start_reg + d + r, data)) + return false; + + address = address + 4; + } else { + // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = + // address+8; + context.SetRegisterPlusOffset(base_reg, address - Rn); + uint32_t word1 = + MemARead(context, address, addr_byte_size, 0, &success); + if (!success) + return false; + + context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); + uint32_t word2 = + MemARead(context, address + 4, addr_byte_size, 0, &success); + if (!success) + return false; + + address = address + 8; + // // Combine the word-aligned words in the correct order for current + // endianness. + // D[d+r] = if BigEndian() then word1:word2 else word2:word1; + uint64_t data; + if (GetByteOrder() == eByteOrderBig) { + data = word1; + data = (data << 32) | word2; + } else { + data = word2; + data = (data << 32) | word1; } + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, + start_reg + d + r, data)) + return false; + } } - return true; + } + return true; } -// A8.6.399 VSTM -// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an -// ARM core register. -bool -EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) -{ -#if 0 - if ConditionPassed() then - EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); - address = if add then R[n] else R[n]-imm32; - if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; - for r = 0 to regs-1 - if single_regs then - MemA[address,4] = S[d+r]; address = address+4; - else - // Store as two word-aligned words in the correct order for current endianness. - MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; - MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; - address = address+8; -#endif - - bool success = false; - - if (ConditionPassed (opcode)) - { - bool single_regs; - bool add; - bool wback; - uint32_t d; - uint32_t n; - uint32_t imm32; - uint32_t regs; - - switch (encoding) - { - case eEncodingT1: - case eEncodingA1: - // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; - // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; - // if P == '1' && W == '0' then SEE VSTR; - // if P == U && W == '1' then UNDEFINED; - if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) - return false; - - // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); - single_regs = false; - add = BitIsSet (opcode, 23); - wback = BitIsSet (opcode, 21); - - // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - imm32 = Bits32 (opcode, 7, 0) << 2; - - // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. - regs = Bits32 (opcode, 7, 0) / 2; - - // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; - if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) - return false; - - // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) - return false; - - break; - - case eEncodingT2: - case eEncodingA2: - // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; - // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; - // if P == '1' && W == '0' then SEE VSTR; - // if P == U && W == '1' then UNDEFINED; - if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) - return false; - - // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); - single_regs = true; - add = BitIsSet (opcode, 23); - wback = BitIsSet (opcode, 21); - d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); - n = Bits32 (opcode, 19, 16); - - // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); - imm32 = Bits32 (opcode, 7, 0) << 2; - regs = Bits32 (opcode, 7, 0); - - // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; - if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) - return false; - - // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; - if ((regs == 0) || ((d + regs) > 32)) - return false; - - break; - - default: - return false; - } - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rn = ReadCoreReg (n, &success); +// A8.6.399 VSTM +// Vector Store Multiple stores multiple extension registers to consecutive +// memory locations using an address from an +// ARM core register. +bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, + const ARMEncoding encoding) { +#if 0 + if ConditionPassed() then + EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); + address = if add then R[n] else R[n]-imm32; + if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; + for r = 0 to regs-1 + if single_regs then + MemA[address,4] = S[d+r]; address = address+4; + else + // Store as two word-aligned words in the correct order for current endianness. + MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; + MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; + address = address+8; +#endif + + bool success = false; + + if (ConditionPassed(opcode)) { + bool single_regs; + bool add; + bool wback; + uint32_t d; + uint32_t n; + uint32_t imm32; + uint32_t regs; + + switch (encoding) { + case eEncodingT1: + case eEncodingA1: + // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; + // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; + // if P == '1' && W == '0' then SEE VSTR; + // if P == U && W == '1' then UNDEFINED; + if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) + return false; + + // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with + // !), 101 (DB with !) + // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); + single_regs = false; + add = BitIsSet(opcode, 23); + wback = BitIsSet(opcode, 21); + + // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); + d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + imm32 = Bits32(opcode, 7, 0) << 2; + + // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. + regs = Bits32(opcode, 7, 0) / 2; + + // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then + // UNPREDICTABLE; + if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) + return false; + + // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; + if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) + return false; + + break; + + case eEncodingT2: + case eEncodingA2: + // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; + // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; + // if P == '1' && W == '0' then SEE VSTR; + // if P == U && W == '1' then UNDEFINED; + if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) + return false; + + // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with + // !), 101 (DB with !) + // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = + // UInt(Vd:D); n = UInt(Rn); + single_regs = true; + add = BitIsSet(opcode, 23); + wback = BitIsSet(opcode, 21); + d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); + n = Bits32(opcode, 19, 16); + + // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); + imm32 = Bits32(opcode, 7, 0) << 2; + regs = Bits32(opcode, 7, 0); + + // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then + // UNPREDICTABLE; + if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) + return false; + + // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; + if ((regs == 0) || ((d + regs) > 32)) + return false; + + break; + + default: + return false; + } + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // address = if add then R[n] else R[n]-imm32; + addr_t address; + if (add) + address = Rn; + else + address = Rn - imm32; + + EmulateInstruction::Context context; + // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; + if (wback) { + uint32_t value; + if (add) + value = Rn + imm32; + else + value = Rn - imm32; + + context.type = eContextAdjustBaseRegister; + context.SetRegisterPlusOffset(base_reg, value - Rn); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + value)) + return false; + } + + const uint32_t addr_byte_size = GetAddressByteSize(); + uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; + + context.type = eContextRegisterStore; + // for r = 0 to regs-1 + for (uint32_t r = 0; r < regs; ++r) { + + if (single_regs) { + // MemA[address,4] = S[d+r]; address = address+4; + uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, + start_reg + d + r, 0, &success); if (!success) + return false; + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + address - Rn); + if (!MemAWrite(context, address, data, addr_byte_size)) + return false; + + address = address + 4; + } else { + // // Store as two word-aligned words in the correct order for current + // endianness. + // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else + // D[d+r]<31:0>; + // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else + // D[d+r]<63:32>; + uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, + start_reg + d + r, 0, &success); + if (!success) + return false; + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); + + if (GetByteOrder() == eByteOrderBig) { + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + address - Rn); + if (!MemAWrite(context, address, Bits64(data, 63, 32), + addr_byte_size)) return false; - - // address = if add then R[n] else R[n]-imm32; - addr_t address; - if (add) - address = Rn; - else - address = Rn - imm32; - - EmulateInstruction::Context context; - // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; - if (wback) - { - uint32_t value; - if (add) - value = Rn + imm32; - else - value = Rn - imm32; - - context.type = eContextAdjustBaseRegister; - context.SetRegisterPlusOffset (base_reg, value - Rn); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) - return false; - } - - const uint32_t addr_byte_size = GetAddressByteSize(); - uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; - context.type = eContextRegisterStore; - // for r = 0 to regs-1 - for (uint32_t r = 0; r < regs; ++r) - { - - if (single_regs) - { - // MemA[address,4] = S[d+r]; address = address+4; - uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); - if (!success) - return false; - - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); - if (!MemAWrite (context, address, data, addr_byte_size)) - return false; - - address = address + 4; - } - else - { - // // Store as two word-aligned words in the correct order for current endianness. - // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; - // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; - uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); - if (!success) - return false; - - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); - - if (GetByteOrder() == eByteOrderBig) - { - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); - if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) - return false; - - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); - if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) - return false; - } - else - { - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); - if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) - return false; - - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); - if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) - return false; - } - // address = address+8; - address = address + 8; - } + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + (address + 4) - Rn); + if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), + addr_byte_size)) + return false; + } else { + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + address - Rn); + if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) + return false; + + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + (address + 4) - Rn); + if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), + addr_byte_size)) + return false; } + // address = address+8; + address = address + 8; + } } - return true; + } + return true; } - + // A8.6.320 -// This instruction loads a single extension register from memory, using an address from an ARM core register, with +// This instruction loads a single extension register from memory, using an +// address from an ARM core register, with // an optional offset. -bool -EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, + ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); @@ -11180,125 +11170,122 @@ EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) word1 = MemA[address,4]; word2 = MemA[address+4,4]; // Combine the word-aligned words in the correct order for current endianness. D[d] = if BigEndian() then word1:word2 else word2:word1; -#endif - - bool success = false; - - if (ConditionPassed (opcode)) - { - bool single_reg; - bool add; - uint32_t imm32; - uint32_t d; - uint32_t n; - - switch (encoding) - { - case eEncodingT1: - case eEncodingA1: - // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); - single_reg = false; - add = BitIsSet (opcode, 23); - imm32 = Bits32 (opcode, 7, 0) << 2; - - // d = UInt(D:Vd); n = UInt(Rn); - d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - - break; - - case eEncodingT2: - case eEncodingA2: - // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); - single_reg = true; - add = BitIsSet (opcode, 23); - imm32 = Bits32 (opcode, 7, 0) << 2; - - // d = UInt(Vd:D); n = UInt(Rn); - d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); - n = Bits32 (opcode, 19, 16); - - break; - - default: - return false; - } - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - // base = if n == 15 then Align(PC,4) else R[n]; - uint32_t base; - if (n == 15) - base = AlignPC (Rn); - else - base = Rn; - - // address = if add then (base + imm32) else (base - imm32); - addr_t address; - if (add) - address = base + imm32; - else - address = base - imm32; - - const uint32_t addr_byte_size = GetAddressByteSize(); - uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; +#endif - EmulateInstruction::Context context; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - base); - - if (single_reg) - { - // S[d] = MemA[address,4]; - uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); - if (!success) - return false; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) - return false; - } - else - { - // word1 = MemA[address,4]; word2 = MemA[address+4,4]; - uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); - if (!success) - return false; - - context.SetRegisterPlusOffset (base_reg, (address + 4) - base); - uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); - if (!success) - return false; - // // Combine the word-aligned words in the correct order for current endianness. - // D[d] = if BigEndian() then word1:word2 else word2:word1; - uint64_t data64; - if (GetByteOrder() == eByteOrderBig) - { - data64 = word1; - data64 = (data64 << 32) | word2; - } - else - { - data64 = word2; - data64 = (data64 << 32) | word1; - } - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) - return false; - } + bool success = false; + + if (ConditionPassed(opcode)) { + bool single_reg; + bool add; + uint32_t imm32; + uint32_t d; + uint32_t n; + + switch (encoding) { + case eEncodingT1: + case eEncodingA1: + // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', + // 32); + single_reg = false; + add = BitIsSet(opcode, 23); + imm32 = Bits32(opcode, 7, 0) << 2; + + // d = UInt(D:Vd); n = UInt(Rn); + d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + + break; + + case eEncodingT2: + case eEncodingA2: + // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); + single_reg = true; + add = BitIsSet(opcode, 23); + imm32 = Bits32(opcode, 7, 0) << 2; + + // d = UInt(Vd:D); n = UInt(Rn); + d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); + n = Bits32(opcode, 19, 16); + + break; + + default: + return false; } - return true; + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // base = if n == 15 then Align(PC,4) else R[n]; + uint32_t base; + if (n == 15) + base = AlignPC(Rn); + else + base = Rn; + + // address = if add then (base + imm32) else (base - imm32); + addr_t address; + if (add) + address = base + imm32; + else + address = base - imm32; + + const uint32_t addr_byte_size = GetAddressByteSize(); + uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; + + EmulateInstruction::Context context; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - base); + + if (single_reg) { + // S[d] = MemA[address,4]; + uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); + if (!success) + return false; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, + data)) + return false; + } else { + // word1 = MemA[address,4]; word2 = MemA[address+4,4]; + uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); + if (!success) + return false; + + context.SetRegisterPlusOffset(base_reg, (address + 4) - base); + uint32_t word2 = + MemARead(context, address + 4, addr_byte_size, 0, &success); + if (!success) + return false; + // // Combine the word-aligned words in the correct order for current + // endianness. + // D[d] = if BigEndian() then word1:word2 else word2:word1; + uint64_t data64; + if (GetByteOrder() == eByteOrderBig) { + data64 = word1; + data64 = (data64 << 32) | word2; + } else { + data64 = word2; + data64 = (data64 << 32) | word1; + } + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, + data64)) + return false; + } + } + return true; } // A8.6.400 VSTR -// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an +// This instruction stores a signle extension register to memory, using an +// address from an ARM core register, with an // optional offset. -bool -EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, + ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); @@ -11311,127 +11298,127 @@ EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; #endif - bool success = false; - - if (ConditionPassed (opcode)) - { - bool single_reg; - bool add; - uint32_t imm32; - uint32_t d; - uint32_t n; - - switch (encoding) - { - case eEncodingT1: - case eEncodingA1: - // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); - single_reg = false; - add = BitIsSet (opcode, 23); - imm32 = Bits32 (opcode, 7, 0) << 2; - - // d = UInt(D:Vd); n = UInt(Rn); - d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - - // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; - if ((n == 15) && (CurrentInstrSet() != eModeARM)) - return false; - - break; - - case eEncodingT2: - case eEncodingA2: - // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); - single_reg = true; - add = BitIsSet (opcode, 23); - imm32 = Bits32 (opcode, 7, 0) << 2; - - // d = UInt(Vd:D); n = UInt(Rn); - d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); - n = Bits32 (opcode, 19, 16); - - // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; - if ((n == 15) && (CurrentInstrSet() != eModeARM)) - return false; - - break; - - default: - return false; - } - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - // address = if add then (R[n] + imm32) else (R[n] - imm32); - addr_t address; - if (add) - address = Rn + imm32; - else - address = Rn - imm32; - - const uint32_t addr_byte_size = GetAddressByteSize(); - uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; + bool success = false; - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); - EmulateInstruction::Context context; - context.type = eContextRegisterStore; - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); - - if (single_reg) - { - // MemA[address,4] = S[d]; - uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); - if (!success) - return false; - - if (!MemAWrite (context, address, data, addr_byte_size)) - return false; - } - else - { - // // Store as two word-aligned words in the correct order for current endianness. - // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; - // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; - uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); - if (!success) - return false; - - if (GetByteOrder() == eByteOrderBig) - { - if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) - return false; - - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); - if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) - return false; - } - else - { - if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) - return false; - - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); - if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) - return false; - } - } + if (ConditionPassed(opcode)) { + bool single_reg; + bool add; + uint32_t imm32; + uint32_t d; + uint32_t n; + + switch (encoding) { + case eEncodingT1: + case eEncodingA1: + // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', + // 32); + single_reg = false; + add = BitIsSet(opcode, 23); + imm32 = Bits32(opcode, 7, 0) << 2; + + // d = UInt(D:Vd); n = UInt(Rn); + d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + + // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; + if ((n == 15) && (CurrentInstrSet() != eModeARM)) + return false; + + break; + + case eEncodingT2: + case eEncodingA2: + // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); + single_reg = true; + add = BitIsSet(opcode, 23); + imm32 = Bits32(opcode, 7, 0) << 2; + + // d = UInt(Vd:D); n = UInt(Rn); + d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); + n = Bits32(opcode, 19, 16); + + // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; + if ((n == 15) && (CurrentInstrSet() != eModeARM)) + return false; + + break; + + default: + return false; } - return true; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // address = if add then (R[n] + imm32) else (R[n] - imm32); + addr_t address; + if (add) + address = Rn + imm32; + else + address = Rn - imm32; + + const uint32_t addr_byte_size = GetAddressByteSize(); + uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); + EmulateInstruction::Context context; + context.type = eContextRegisterStore; + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); + + if (single_reg) { + // MemA[address,4] = S[d]; + uint32_t data = + ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); + if (!success) + return false; + + if (!MemAWrite(context, address, data, addr_byte_size)) + return false; + } else { + // // Store as two word-aligned words in the correct order for current + // endianness. + // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; + // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; + uint64_t data = + ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); + if (!success) + return false; + + if (GetByteOrder() == eByteOrderBig) { + if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) + return false; + + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + (address + 4) - Rn); + if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), + addr_byte_size)) + return false; + } else { + if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) + return false; + + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + (address + 4) - Rn); + if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), + addr_byte_size)) + return false; + } + } + } + return true; } // A8.6.307 VLDI1 (multiple single elements) -// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every +// This instruction loads elements from memory into one, two, three or four +// registers, without de-interleaving. Every // element of each register is loaded. -bool -EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, + ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); @@ -11443,337 +11430,332 @@ EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding e address = address + ebytes; #endif - bool success = false; - - if (ConditionPassed (opcode)) - { - uint32_t regs; - uint32_t alignment; - uint32_t ebytes; - uint32_t esize; - uint32_t elements; - uint32_t d; - uint32_t n; - uint32_t m; - bool wback; - bool register_index; - - switch (encoding) - { - case eEncodingT1: - case eEncodingA1: - { - // case type of - // when '0111' - // regs = 1; if align<1> == '1' then UNDEFINED; - // when '1010' - // regs = 2; if align == '11' then UNDEFINED; - // when '0110' - // regs = 3; if align<1> == '1' then UNDEFINED; - // when '0010' - // regs = 4; - // otherwise - // SEE 'Related encodings'; - uint32_t type = Bits32 (opcode, 11, 8); - uint32_t align = Bits32 (opcode, 5, 4); - if (type == 7) // '0111' - { - regs = 1; - if (BitIsSet (align, 1)) - return false; - } - else if (type == 10) // '1010' - { - regs = 2; - if (align == 3) - return false; - - } - else if (type == 6) // '0110' - { - regs = 3; - if (BitIsSet (align, 1)) - return false; - } - else if (type == 2) // '0010' - { - regs = 4; - } - else - return false; - - // alignment = if align == '00' then 1 else 4 << UInt(align); - if (align == 0) - alignment = 1; - else - alignment = 4 << align; - - // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; - ebytes = 1 << Bits32 (opcode, 7, 6); - esize = 8 * ebytes; - elements = 8 / ebytes; - - // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 15); - m = Bits32 (opcode, 3, 0); - - // wback = (m != 15); register_index = (m != 15 && m != 13); - wback = (m != 15); - register_index = ((m != 15) && (m != 13)); - - // if d+regs > 32 then UNPREDICTABLE; - if ((d + regs) > 32) - return false; - } - break; - - default: - return false; - } - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rn = ReadCoreReg (n, &success); + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t regs; + uint32_t alignment; + uint32_t ebytes; + uint32_t esize; + uint32_t elements; + uint32_t d; + uint32_t n; + uint32_t m; + bool wback; + bool register_index; + + switch (encoding) { + case eEncodingT1: + case eEncodingA1: { + // case type of + // when '0111' + // regs = 1; if align<1> == '1' then UNDEFINED; + // when '1010' + // regs = 2; if align == '11' then UNDEFINED; + // when '0110' + // regs = 3; if align<1> == '1' then UNDEFINED; + // when '0010' + // regs = 4; + // otherwise + // SEE 'Related encodings'; + uint32_t type = Bits32(opcode, 11, 8); + uint32_t align = Bits32(opcode, 5, 4); + if (type == 7) // '0111' + { + regs = 1; + if (BitIsSet(align, 1)) + return false; + } else if (type == 10) // '1010' + { + regs = 2; + if (align == 3) + return false; + + } else if (type == 6) // '0110' + { + regs = 3; + if (BitIsSet(align, 1)) + return false; + } else if (type == 2) // '0010' + { + regs = 4; + } else + return false; + + // alignment = if align == '00' then 1 else 4 << UInt(align); + if (align == 0) + alignment = 1; + else + alignment = 4 << align; + + // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; + ebytes = 1 << Bits32(opcode, 7, 6); + esize = 8 * ebytes; + elements = 8 / ebytes; + + // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); + d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 15); + m = Bits32(opcode, 3, 0); + + // wback = (m != 15); register_index = (m != 15 && m != 13); + wback = (m != 15); + register_index = ((m != 15) && (m != 13)); + + // if d+regs > 32 then UNPREDICTABLE; + if ((d + regs) > 32) + return false; + } break; + + default: + return false; + } + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // address = R[n]; if (address MOD alignment) != 0 then + // GenerateAlignmentException(); + addr_t address = Rn; + if ((address % alignment) != 0) + return false; + + EmulateInstruction::Context context; + // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); + if (wback) { + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + + uint32_t offset; + if (register_index) + offset = Rm; + else + offset = 8 * regs; + + uint32_t value = Rn + offset; + context.type = eContextAdjustBaseRegister; + context.SetRegisterPlusOffset(base_reg, offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + value)) + return false; + } + + // for r = 0 to regs-1 + for (uint32_t r = 0; r < regs; ++r) { + // for e = 0 to elements-1 + uint64_t assembled_data = 0; + for (uint32_t e = 0; e < elements; ++e) { + // Elem[D[d+r],e,esize] = MemU[address,ebytes]; + context.type = eContextRegisterLoad; + context.SetRegisterPlusOffset(base_reg, address - Rn); + uint64_t data = MemURead(context, address, ebytes, 0, &success); if (!success) - return false; - - // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); - addr_t address = Rn; - if ((address % alignment) != 0) - return false; - - EmulateInstruction::Context context; - // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); - if (wback) - { - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; - - uint32_t offset; - if (register_index) - offset = Rm; - else - offset = 8 * regs; - - uint32_t value = Rn + offset; - context.type = eContextAdjustBaseRegister; - context.SetRegisterPlusOffset (base_reg, offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) - return false; - - } - - // for r = 0 to regs-1 - for (uint32_t r = 0; r < regs; ++r) - { - // for e = 0 to elements-1 - uint64_t assembled_data = 0; - for (uint32_t e = 0; e < elements; ++e) - { - // Elem[D[d+r],e,esize] = MemU[address,ebytes]; - context.type = eContextRegisterLoad; - context.SetRegisterPlusOffset (base_reg, address - Rn); - uint64_t data = MemURead (context, address, ebytes, 0, &success); - if (!success) - return false; - - assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data - - // address = address + ebytes; - address = address + ebytes; - } - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) - return false; - } + return false; + + assembled_data = + (data << (e * esize)) | + assembled_data; // New data goes to the left of existing data + + // address = address + ebytes; + address = address + ebytes; + } + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, + assembled_data)) + return false; } - return true; + } + return true; } // A8.6.308 VLD1 (single element to one lane) // -bool -EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); - address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); - if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); - Elem[D[d],index,esize] = MemU[address,ebytes]; -#endif - - bool success = false; - - if (ConditionPassed (opcode)) - { - uint32_t ebytes; - uint32_t esize; - uint32_t index; - uint32_t alignment; - uint32_t d; - uint32_t n; - uint32_t m; - bool wback; - bool register_index; - - switch (encoding) - { - case eEncodingT1: - case eEncodingA1: - { - uint32_t size = Bits32 (opcode, 11, 10); - uint32_t index_align = Bits32 (opcode, 7, 4); - // if size == '11' then SEE VLD1 (single element to all lanes); - if (size == 3) - return EmulateVLD1SingleAll (opcode, encoding); - // case size of - if (size == 0) // when '00' - { - // if index_align<0> != '0' then UNDEFINED; - if (BitIsClear (index_align, 0)) - return false; - - // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; - ebytes = 1; - esize = 8; - index = Bits32 (index_align, 3, 1); - alignment = 1; - } - else if (size == 1) // when '01' - { - // if index_align<1> != '0' then UNDEFINED; - if (BitIsClear (index_align, 1)) - return false; - - // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); - ebytes = 2; - esize = 16; - index = Bits32 (index_align, 3, 2); - - // alignment = if index_align<0> == '0' then 1 else 2; - if (BitIsClear (index_align, 0)) - alignment = 1; - else - alignment = 2; - } - else if (size == 2) // when '10' - { - // if index_align<2> != '0' then UNDEFINED; - if (BitIsClear (index_align, 2)) - return false; - - // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; - if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) - return false; - - // ebytes = 4; esize = 32; index = UInt(index_align<3>); - ebytes = 4; - esize = 32; - index = Bit32 (index_align, 3); - - // alignment = if index_align<1:0> == '00' then 1 else 4; - if (Bits32 (index_align, 1, 0) == 0) - alignment = 1; - else - alignment = 4; - } - else - { - return false; - } - // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; - wback = (m != 15); - register_index = ((m != 15) && (m != 13)); - - if (n == 15) - return false; - - } - break; - - default: - return false; - } - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); - addr_t address = Rn; - if ((address % alignment) != 0) - return false; - - EmulateInstruction::Context context; - // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); - if (wback) - { - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; - - uint32_t offset; - if (register_index) - offset = Rm; - else - offset = ebytes; - - uint32_t value = Rn + offset; - - context.type = eContextAdjustBaseRegister; - context.SetRegisterPlusOffset (base_reg, offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) - return false; - } - - // Elem[D[d],index,esize] = MemU[address,ebytes]; - uint32_t element = MemURead (context, address, esize, 0, &success); - if (!success) - return false; - - element = element << (index * esize); - - uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); - if (!success) - return false; - - uint64_t all_ones = -1; - uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's - // at element & to the right of element. - if (index > 0) - mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. - // now mask should be 0's where element goes & 1's - // everywhere else. - - uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits - reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. - - context.type = eContextRegisterLoad; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) - return false; + address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); + if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); + Elem[D[d],index,esize] = MemU[address,ebytes]; +#endif + + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t ebytes; + uint32_t esize; + uint32_t index; + uint32_t alignment; + uint32_t d; + uint32_t n; + uint32_t m; + bool wback; + bool register_index; + + switch (encoding) { + case eEncodingT1: + case eEncodingA1: { + uint32_t size = Bits32(opcode, 11, 10); + uint32_t index_align = Bits32(opcode, 7, 4); + // if size == '11' then SEE VLD1 (single element to all lanes); + if (size == 3) + return EmulateVLD1SingleAll(opcode, encoding); + // case size of + if (size == 0) // when '00' + { + // if index_align<0> != '0' then UNDEFINED; + if (BitIsClear(index_align, 0)) + return false; + + // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; + ebytes = 1; + esize = 8; + index = Bits32(index_align, 3, 1); + alignment = 1; + } else if (size == 1) // when '01' + { + // if index_align<1> != '0' then UNDEFINED; + if (BitIsClear(index_align, 1)) + return false; + + // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); + ebytes = 2; + esize = 16; + index = Bits32(index_align, 3, 2); + + // alignment = if index_align<0> == '0' then 1 else 2; + if (BitIsClear(index_align, 0)) + alignment = 1; + else + alignment = 2; + } else if (size == 2) // when '10' + { + // if index_align<2> != '0' then UNDEFINED; + if (BitIsClear(index_align, 2)) + return false; + + // if index_align<1:0> != '00' && index_align<1:0> != '11' then + // UNDEFINED; + if ((Bits32(index_align, 1, 0) != 0) && + (Bits32(index_align, 1, 0) != 3)) + return false; + + // ebytes = 4; esize = 32; index = UInt(index_align<3>); + ebytes = 4; + esize = 32; + index = Bit32(index_align, 3); + + // alignment = if index_align<1:0> == '00' then 1 else 4; + if (Bits32(index_align, 1, 0) == 0) + alignment = 1; + else + alignment = 4; + } else { + return false; + } + // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); + d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 + // then UNPREDICTABLE; + wback = (m != 15); + register_index = ((m != 15) && (m != 13)); + + if (n == 15) + return false; + + } break; + + default: + return false; } - return true; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // address = R[n]; if (address MOD alignment) != 0 then + // GenerateAlignmentException(); + addr_t address = Rn; + if ((address % alignment) != 0) + return false; + + EmulateInstruction::Context context; + // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); + if (wback) { + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + + uint32_t offset; + if (register_index) + offset = Rm; + else + offset = ebytes; + + uint32_t value = Rn + offset; + + context.type = eContextAdjustBaseRegister; + context.SetRegisterPlusOffset(base_reg, offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + value)) + return false; + } + + // Elem[D[d],index,esize] = MemU[address,ebytes]; + uint32_t element = MemURead(context, address, esize, 0, &success); + if (!success) + return false; + + element = element << (index * esize); + + uint64_t reg_data = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); + if (!success) + return false; + + uint64_t all_ones = -1; + uint64_t mask = all_ones + << ((index + 1) * esize); // mask is all 1's to left of + // where 'element' goes, & all 0's + // at element & to the right of element. + if (index > 0) + mask = mask | Bits64(all_ones, (index * esize) - 1, + 0); // add 1's to the right of where 'element' goes. + // now mask should be 0's where element goes & 1's + // everywhere else. + + uint64_t masked_reg = + reg_data & mask; // Take original reg value & zero out 'element' bits + reg_data = + masked_reg & element; // Put 'element' into those bits in reg_data. + + context.type = eContextRegisterLoad; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, + reg_data)) + return false; + } + return true; } // A8.6.391 VST1 (multiple single elements) -// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without +// Vector Store (multiple single elements) stores elements to memory from one, +// two, three, or four registers, without // interleaving. Every element of each register is stored. -bool -EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) -{ +bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, + ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); @@ -11784,159 +11766,152 @@ EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding e MemU[address,ebytes] = Elem[D[d+r],e,esize]; address = address + ebytes; #endif - - bool success = false; - - if (ConditionPassed (opcode)) - { - uint32_t regs; - uint32_t alignment; - uint32_t ebytes; - uint32_t esize; - uint32_t elements; - uint32_t d; - uint32_t n; - uint32_t m; - bool wback; - bool register_index; - - switch (encoding) - { - case eEncodingT1: - case eEncodingA1: - { - uint32_t type = Bits32 (opcode, 11, 8); - uint32_t align = Bits32 (opcode, 5, 4); - - // case type of - if (type == 7) // when '0111' - { - // regs = 1; if align<1> == '1' then UNDEFINED; - regs = 1; - if (BitIsSet (align, 1)) - return false; - } - else if (type == 10) // when '1010' - { - // regs = 2; if align == '11' then UNDEFINED; - regs = 2; - if (align == 3) - return false; - } - else if (type == 6) // when '0110' - { - // regs = 3; if align<1> == '1' then UNDEFINED; - regs = 3; - if (BitIsSet (align, 1)) - return false; - } - else if (type == 2) // when '0010' - // regs = 4; - regs = 4; - else // otherwise - // SEE 'Related encodings'; - return false; - - // alignment = if align == '00' then 1 else 4 << UInt(align); - if (align == 0) - alignment = 1; - else - alignment = 4 << align; - - // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; - ebytes = 1 << Bits32 (opcode,7, 6); - esize = 8 * ebytes; - elements = 8 / ebytes; - - // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // wback = (m != 15); register_index = (m != 15 && m != 13); - wback = (m != 15); - register_index = ((m != 15) && (m != 13)); - - // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; - if ((d + regs) > 32) - return false; - - if (n == 15) - return false; - - } - break; - - default: - return false; - } - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); - addr_t address = Rn; - if ((address % alignment) != 0) - return false; - - EmulateInstruction::Context context; - // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); - if (wback) - { - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; - - uint32_t offset; - if (register_index) - offset = Rm; - else - offset = 8 * regs; - - context.type = eContextAdjustBaseRegister; - context.SetRegisterPlusOffset (base_reg, offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) - return false; - } - - RegisterInfo data_reg; - context.type = eContextRegisterStore; - // for r = 0 to regs-1 - for (uint32_t r = 0; r < regs; ++r) - { - GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); - uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); - if (!success) - return false; - // for e = 0 to elements-1 - for (uint32_t e = 0; e < elements; ++e) - { - // MemU[address,ebytes] = Elem[D[d+r],e,esize]; - uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); - - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); - if (!MemUWrite (context, address, word, ebytes)) - return false; - - // address = address + ebytes; - address = address + ebytes; - } - } + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t regs; + uint32_t alignment; + uint32_t ebytes; + uint32_t esize; + uint32_t elements; + uint32_t d; + uint32_t n; + uint32_t m; + bool wback; + bool register_index; + + switch (encoding) { + case eEncodingT1: + case eEncodingA1: { + uint32_t type = Bits32(opcode, 11, 8); + uint32_t align = Bits32(opcode, 5, 4); + + // case type of + if (type == 7) // when '0111' + { + // regs = 1; if align<1> == '1' then UNDEFINED; + regs = 1; + if (BitIsSet(align, 1)) + return false; + } else if (type == 10) // when '1010' + { + // regs = 2; if align == '11' then UNDEFINED; + regs = 2; + if (align == 3) + return false; + } else if (type == 6) // when '0110' + { + // regs = 3; if align<1> == '1' then UNDEFINED; + regs = 3; + if (BitIsSet(align, 1)) + return false; + } else if (type == 2) // when '0010' + // regs = 4; + regs = 4; + else // otherwise + // SEE 'Related encodings'; + return false; + + // alignment = if align == '00' then 1 else 4 << UInt(align); + if (align == 0) + alignment = 1; + else + alignment = 4 << align; + + // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; + ebytes = 1 << Bits32(opcode, 7, 6); + esize = 8 * ebytes; + elements = 8 / ebytes; + + // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); + d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // wback = (m != 15); register_index = (m != 15 && m != 13); + wback = (m != 15); + register_index = ((m != 15) && (m != 13)); + + // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; + if ((d + regs) > 32) + return false; + + if (n == 15) + return false; + + } break; + + default: + return false; } - return true; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // address = R[n]; if (address MOD alignment) != 0 then + // GenerateAlignmentException(); + addr_t address = Rn; + if ((address % alignment) != 0) + return false; + + EmulateInstruction::Context context; + // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); + if (wback) { + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + + uint32_t offset; + if (register_index) + offset = Rm; + else + offset = 8 * regs; + + context.type = eContextAdjustBaseRegister; + context.SetRegisterPlusOffset(base_reg, offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + Rn + offset)) + return false; + } + + RegisterInfo data_reg; + context.type = eContextRegisterStore; + // for r = 0 to regs-1 + for (uint32_t r = 0; r < regs; ++r) { + GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); + uint64_t register_data = ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); + if (!success) + return false; + + // for e = 0 to elements-1 + for (uint32_t e = 0; e < elements; ++e) { + // MemU[address,ebytes] = Elem[D[d+r],e,esize]; + uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); + + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, + address - Rn); + if (!MemUWrite(context, address, word, ebytes)) + return false; + + // address = address + ebytes; + address = address + ebytes; + } + } + } + return true; } // A8.6.392 VST1 (single element from one lane) -// This instruction stores one element to memory from one element of a register. -bool -EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) -{ +// This instruction stores one element to memory from one element of a register. +bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, + ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); @@ -11945,160 +11920,158 @@ EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding enc MemU[address,ebytes] = Elem[D[d],index,esize]; #endif - bool success = false; - - if (ConditionPassed (opcode)) - { - uint32_t ebytes; - uint32_t esize; - uint32_t index; - uint32_t alignment; - uint32_t d; - uint32_t n; - uint32_t m; - bool wback; - bool register_index; - - switch (encoding) - { - case eEncodingT1: - case eEncodingA1: - { - uint32_t size = Bits32 (opcode, 11, 10); - uint32_t index_align = Bits32 (opcode, 7, 4); - - // if size == '11' then UNDEFINED; - if (size == 3) - return false; - - // case size of - if (size == 0) // when '00' - { - // if index_align<0> != '0' then UNDEFINED; - if (BitIsClear (index_align, 0)) - return false; - // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; - ebytes = 1; - esize = 8; - index = Bits32 (index_align, 3, 1); - alignment = 1; - } - else if (size == 1) // when '01' - { - // if index_align<1> != '0' then UNDEFINED; - if (BitIsClear (index_align, 1)) - return false; - - // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); - ebytes = 2; - esize = 16; - index = Bits32 (index_align, 3, 2); - - // alignment = if index_align<0> == '0' then 1 else 2; - if (BitIsClear (index_align, 0)) - alignment = 1; - else - alignment = 2; - } - else if (size == 2) // when '10' - { - // if index_align<2> != '0' then UNDEFINED; - if (BitIsClear (index_align, 2)) - return false; - - // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; - if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) - return false; - - // ebytes = 4; esize = 32; index = UInt(index_align<3>); - ebytes = 4; - esize = 32; - index = Bit32 (index_align, 3); - - // alignment = if index_align<1:0> == '00' then 1 else 4; - if (Bits32 (index_align, 1, 0) == 0) - alignment = 1; - else - alignment = 4; - } - else - { - return false; - } - // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; - wback = (m != 15); - register_index = ((m != 15) && (m != 13)); - - if (n == 15) - return false; - } - break; - - default: - return false; - } - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); - addr_t address = Rn; - if ((address % alignment) != 0) - return false; - - EmulateInstruction::Context context; - // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); - if (wback) - { - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; - - uint32_t offset; - if (register_index) - offset = Rm; - else - offset = ebytes; - - context.type = eContextAdjustBaseRegister; - context.SetRegisterPlusOffset (base_reg, offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) - return false; - } - - // MemU[address,ebytes] = Elem[D[d],index,esize]; - uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); - if (!success) - return false; - - uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); - - RegisterInfo data_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); - context.type = eContextRegisterStore; - context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); - - if (!MemUWrite (context, address, word, ebytes)) - return false; + bool success = false; + + if (ConditionPassed(opcode)) { + uint32_t ebytes; + uint32_t esize; + uint32_t index; + uint32_t alignment; + uint32_t d; + uint32_t n; + uint32_t m; + bool wback; + bool register_index; + + switch (encoding) { + case eEncodingT1: + case eEncodingA1: { + uint32_t size = Bits32(opcode, 11, 10); + uint32_t index_align = Bits32(opcode, 7, 4); + + // if size == '11' then UNDEFINED; + if (size == 3) + return false; + + // case size of + if (size == 0) // when '00' + { + // if index_align<0> != '0' then UNDEFINED; + if (BitIsClear(index_align, 0)) + return false; + // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; + ebytes = 1; + esize = 8; + index = Bits32(index_align, 3, 1); + alignment = 1; + } else if (size == 1) // when '01' + { + // if index_align<1> != '0' then UNDEFINED; + if (BitIsClear(index_align, 1)) + return false; + + // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); + ebytes = 2; + esize = 16; + index = Bits32(index_align, 3, 2); + + // alignment = if index_align<0> == '0' then 1 else 2; + if (BitIsClear(index_align, 0)) + alignment = 1; + else + alignment = 2; + } else if (size == 2) // when '10' + { + // if index_align<2> != '0' then UNDEFINED; + if (BitIsClear(index_align, 2)) + return false; + + // if index_align<1:0> != '00' && index_align<1:0> != '11' then + // UNDEFINED; + if ((Bits32(index_align, 1, 0) != 0) && + (Bits32(index_align, 1, 0) != 3)) + return false; + + // ebytes = 4; esize = 32; index = UInt(index_align<3>); + ebytes = 4; + esize = 32; + index = Bit32(index_align, 3); + + // alignment = if index_align<1:0> == '00' then 1 else 4; + if (Bits32(index_align, 1, 0) == 0) + alignment = 1; + else + alignment = 4; + } else { + return false; + } + // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); + d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 + // then UNPREDICTABLE; + wback = (m != 15); + register_index = ((m != 15) && (m != 13)); + + if (n == 15) + return false; + } break; + + default: + return false; } - return true; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // address = R[n]; if (address MOD alignment) != 0 then + // GenerateAlignmentException(); + addr_t address = Rn; + if ((address % alignment) != 0) + return false; + + EmulateInstruction::Context context; + // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); + if (wback) { + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + + uint32_t offset; + if (register_index) + offset = Rm; + else + offset = ebytes; + + context.type = eContextAdjustBaseRegister; + context.SetRegisterPlusOffset(base_reg, offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + Rn + offset)) + return false; + } + + // MemU[address,ebytes] = Elem[D[d],index,esize]; + uint64_t register_data = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); + if (!success) + return false; + + uint64_t word = + Bits64(register_data, ((index + 1) * esize) - 1, index * esize); + + RegisterInfo data_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); + context.type = eContextRegisterStore; + context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); + + if (!MemUWrite(context, address, word, ebytes)) + return false; + } + return true; } // A8.6.309 VLD1 (single element to all lanes) -// This instruction loads one element from memory into every element of one or two vectors. -bool -EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) -{ +// This instruction loads one element from memory into every element of one or +// two vectors. +bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, + const ARMEncoding encoding) { #if 0 if ConditionPassed() then EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); @@ -12109,128 +12082,128 @@ EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEnc D[d+r] = replicated_element; #endif - bool success = false; - - if (ConditionPassed (opcode)) - { - uint32_t ebytes; - uint32_t elements; - uint32_t regs; - uint32_t alignment; - uint32_t d; - uint32_t n; - uint32_t m; - bool wback; - bool register_index; - - switch (encoding) - { - case eEncodingT1: - case eEncodingA1: - { - //if size == '11' || (size == '00' && a == '1') then UNDEFINED; - uint32_t size = Bits32 (opcode, 7, 6); - if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) - return false; - - //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' then 1 else 2; - ebytes = 1 << size; - elements = 8 / ebytes; - if (BitIsClear (opcode, 5)) - regs = 1; - else - regs = 2; - - //alignment = if a == '0' then 1 else ebytes; - if (BitIsClear (opcode, 4)) - alignment = 1; - else - alignment = ebytes; - - //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); - n = Bits32 (opcode, 19, 16); - m = Bits32 (opcode, 3, 0); - - //wback = (m != 15); register_index = (m != 15 && m != 13); - wback = (m != 15); - register_index = ((m != 15) && (m != 13)); - - //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; - if ((d + regs) > 32) - return false; - - if (n == 15) - return false; - } - break; - - default: - return false; - } - - RegisterInfo base_reg; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); - - uint32_t Rn = ReadCoreReg (n, &success); - if (!success) - return false; - - // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); - addr_t address = Rn; - if ((address % alignment) != 0) - return false; - - EmulateInstruction::Context context; - // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); - if (wback) - { - uint32_t Rm = ReadCoreReg (m, &success); - if (!success) - return false; - - uint32_t offset; - if (register_index) - offset = Rm; - else - offset = ebytes; - - context.type = eContextAdjustBaseRegister; - context.SetRegisterPlusOffset (base_reg, offset); - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) - return false; - } - - // replicated_element = Replicate(MemU[address,ebytes], elements); - - context.type = eContextRegisterLoad; - uint64_t word = MemURead (context, address, ebytes, 0, &success); - if (!success) - return false; - - uint64_t replicated_element = 0; - uint32_t esize = ebytes * 8; - for (uint32_t e = 0; e < elements; ++e) - replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); + bool success = false; - // for r = 0 to regs-1 - for (uint32_t r = 0; r < regs; ++r) - { - // D[d+r] = replicated_element; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) - return false; - } + if (ConditionPassed(opcode)) { + uint32_t ebytes; + uint32_t elements; + uint32_t regs; + uint32_t alignment; + uint32_t d; + uint32_t n; + uint32_t m; + bool wback; + bool register_index; + + switch (encoding) { + case eEncodingT1: + case eEncodingA1: { + // if size == '11' || (size == '00' && a == '1') then UNDEFINED; + uint32_t size = Bits32(opcode, 7, 6); + if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) + return false; + + // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' + // then 1 else 2; + ebytes = 1 << size; + elements = 8 / ebytes; + if (BitIsClear(opcode, 5)) + regs = 1; + else + regs = 2; + + // alignment = if a == '0' then 1 else ebytes; + if (BitIsClear(opcode, 4)) + alignment = 1; + else + alignment = ebytes; + + // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); + d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); + n = Bits32(opcode, 19, 16); + m = Bits32(opcode, 3, 0); + + // wback = (m != 15); register_index = (m != 15 && m != 13); + wback = (m != 15); + register_index = ((m != 15) && (m != 13)); + + // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; + if ((d + regs) > 32) + return false; + + if (n == 15) + return false; + } break; + + default: + return false; } - return true; + + RegisterInfo base_reg; + GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); + + uint32_t Rn = ReadCoreReg(n, &success); + if (!success) + return false; + + // address = R[n]; if (address MOD alignment) != 0 then + // GenerateAlignmentException(); + addr_t address = Rn; + if ((address % alignment) != 0) + return false; + + EmulateInstruction::Context context; + // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); + if (wback) { + uint32_t Rm = ReadCoreReg(m, &success); + if (!success) + return false; + + uint32_t offset; + if (register_index) + offset = Rm; + else + offset = ebytes; + + context.type = eContextAdjustBaseRegister; + context.SetRegisterPlusOffset(base_reg, offset); + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, + Rn + offset)) + return false; + } + + // replicated_element = Replicate(MemU[address,ebytes], elements); + + context.type = eContextRegisterLoad; + uint64_t word = MemURead(context, address, ebytes, 0, &success); + if (!success) + return false; + + uint64_t replicated_element = 0; + uint32_t esize = ebytes * 8; + for (uint32_t e = 0; e < elements; ++e) + replicated_element = + (replicated_element << esize) | Bits64(word, esize - 1, 0); + + // for r = 0 to regs-1 + for (uint32_t r = 0; r < regs; ++r) { + // D[d+r] = replicated_element; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, + replicated_element)) + return false; + } + } + return true; } // B6.2.13 SUBS PC, LR and related instructions -//The SUBS PC, LR, #" }, - { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push " }, - - // set r7 to point to a stack offset - { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #" }, - { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #"}, - // copy the stack pointer to ip - { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, - { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #" }, - { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #"}, - - // adjust the stack pointer - { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #"}, - { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s} , sp, {,}" }, - - // push one register - // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; - { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, - - // vector push consecutive extension register(s) - { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 "}, - { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 "}, - - //---------------------------------------------------------------------- - // Epilogue instructions - //---------------------------------------------------------------------- - - { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop "}, - { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop "}, - { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 "}, - { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 "}, - - //---------------------------------------------------------------------- - // Supervisor Call (previously Software Interrupt) - //---------------------------------------------------------------------- - { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, - - //---------------------------------------------------------------------- - // Branch instructions - //---------------------------------------------------------------------- - // To resolve ambiguity, "blx