aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Instruction
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Instruction')
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp22758
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.h1695
-rw-r--r--source/Plugins/Instruction/ARM/EmulationStateARM.cpp669
-rw-r--r--source/Plugins/Instruction/ARM/EmulationStateARM.h130
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp1896
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h418
-rw-r--r--source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp4990
-rw-r--r--source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h342
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp3811
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h284
10 files changed, 18643 insertions, 18350 deletions
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 884078b27175..99caca99074b 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/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<EmulateInstructionARM> 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<EmulateInstructionARM> 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<EmulateInstructionARM> 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<EmulateInstructionARM> 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 &reg_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 &reg_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;
}
+ }
- /* 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.
- */
+ 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.
+ */
- 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;
+ 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
-
- 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;
+
+ // 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
+// 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;
+ 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;
-
- 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,55 +1574,55 @@ 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;
+ 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;
}
- 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)
-{
+ 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())
@@ -1664,45 +1632,46 @@ EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding enc
}
#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<regs; ++i)
- {
- GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
- context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
- // uint64_t to accommodate 64-bit registers.
- uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
- if (!success)
- return false;
- if (!MemAWrite (context, addr, reg_value, reg_byte_size))
- return false;
- addr += reg_byte_size;
- }
-
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- context.SetImmediateSigned (-sp_offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
- return false;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextPushRegisterOnStack;
+
+ RegisterInfo dwarf_reg;
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+ for (i = 0; i < regs; ++i) {
+ GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
+ context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
+ // uint64_t to accommodate 64-bit registers.
+ uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
+ if (!success)
+ return false;
+ if (!MemAWrite(context, addr, reg_value, reg_byte_size))
+ return false;
+ addr += reg_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;
}
// Vector Pop loads multiple extension registers from the stack.
// It also updates SP to point just above the loaded data.
-bool
-EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -2163,80 +2118,78 @@ EmulateInstructionARM::EmulateVPOP (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;
- 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.
-
- 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<regs; ++i)
- {
- GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
- context.SetAddress(addr);
- data = MemARead(context, addr, reg_byte_size, 0, &success);
- if (!success)
- return false;
- if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
- return false;
- addr += reg_byte_size;
- }
-
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- context.SetImmediateSigned (sp_offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
- return false;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextPopRegisterOffStack;
+
+ RegisterInfo dwarf_reg;
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+ for (i = 0; i < regs; ++i) {
+ GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
+ context.SetAddress(addr);
+ data = MemARead(context, addr, reg_byte_size, 0, &success);
+ if (!success)
+ return false;
+ if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
+ return false;
+ addr += reg_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;
}
// SVC (previously SWI)
-bool
-EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -2246,65 +2199,62 @@ EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding enco
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- const uint32_t pc = ReadCoreReg(PC_REG, &success);
- addr_t lr; // next instruction address
- if (!success)
- return false;
- uint32_t imm32; // the immediate constant
- uint32_t mode; // ARM or Thumb mode
- switch (encoding) {
- case eEncodingT1:
- lr = (pc + 2) | 1u; // return address
- imm32 = Bits32(opcode, 7, 0);
- mode = eModeThumb;
- break;
- case eEncodingA1:
- lr = pc + 4; // return address
- imm32 = Bits32(opcode, 23, 0);
- mode = eModeARM;
- break;
- default:
- return false;
- }
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextSupervisorCall;
- context.SetISAAndImmediate (mode, imm32);
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
- return false;
+ if (ConditionPassed(opcode)) {
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ addr_t lr; // next instruction address
+ if (!success)
+ return false;
+ uint32_t imm32; // the immediate constant
+ uint32_t mode; // ARM or Thumb mode
+ switch (encoding) {
+ case eEncodingT1:
+ lr = (pc + 2) | 1u; // return address
+ imm32 = Bits32(opcode, 7, 0);
+ mode = eModeThumb;
+ break;
+ case eEncodingA1:
+ lr = pc + 4; // return address
+ imm32 = Bits32(opcode, 23, 0);
+ mode = eModeARM;
+ break;
+ default:
+ return false;
}
- return true;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextSupervisorCall;
+ context.SetISAAndImmediate(mode, imm32);
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_RA, lr))
+ return false;
+ }
+ return true;
}
// If Then makes up to four following instructions (the IT block) conditional.
-bool
-EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
EncodingSpecificOperations();
ITSTATE.IT<7:0> = 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;
+
+ 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);
- //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
- AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
+ break;
- RegisterInfo reg_n;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
+ 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;
- EmulateInstruction::Context context;
- context.type = eContextArithmetic;
- context.SetRegisterPlusOffset (reg_n, imm32);
+ 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;
- //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;
+ }
+ default:
+ return false;
}
- return true;
-}
-
-// This instruction adds an immediate value to a register value, and writes the result to the destination
+
+ 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<n> == '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<n> == '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<n> == '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<n> == '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<n> == '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<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
if wback && registers<n> == '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<i> == '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<n> == '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<n> == '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<i> == '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<n> == '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<n> == '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,128 +3672,130 @@ EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding en
if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
if wback && registers<n> == '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<n> == '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<n> == '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<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
- if (wback && BitIsSet (registers, n))
- return WriteBits32Unknown (n);
+
+ 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<n> == '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] - 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<n> == '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<n> == '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
+// 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)
-{
+bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -3838,105 +3810,105 @@ EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding en
if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
if wback && registers<n> == '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<n> == '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<n> == '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<n> == '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<n> == '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<n> == '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<i> == '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<n> == '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<i> == '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<i> == '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<i> == '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<n> == '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<i> == '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<n> == '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<i> == '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<i> == '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<i> == '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;
+ 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;
- }
+ 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 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;
+ // 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);
+ 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 ();
+ 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;
}
-// 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))
+
+ 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);
+ 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
{
- 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 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;
-
- 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;
+ return false;
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);
- 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);
- }
- }
+ 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))
+ 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
{
- 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);
- }
+ // R[t] = bits(32) UNKNOWN;
+ WriteBits32Unknown(t);
}
- return true;
+ }
+ 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)
-{
+
+ 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;
- }
-
- 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;
+
+ 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;
+ 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;
- 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;
- // 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;
}
-// 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);
+ bool success = false;
- 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;
+ 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;
-// 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)
-{
+ 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);
+
+ 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);
- AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
+ // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
+ // UNPREDICTABLE;
+ if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
+ return false;
- 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 d == 15 || BadReg(m) then UNPREDICTABLE;
+ if ((d == 15) || BadReg(m))
+ return false;
+ break;
- if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
- return false;
+ 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;
}
- 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();
@@ -9675,91 +9659,89 @@ EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncod
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;
- // (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 (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return 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;
}
- 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,184 +10774,185 @@ 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
+// 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)
-{
+bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
@@ -10986,189 +10967,198 @@ EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding enc
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);
+
+ 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,161 +11430,153 @@ 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);
@@ -11606,174 +11585,177 @@ EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncodi
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;
+ 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, #<const? instruction provides an exception return without the use of the stack. It subtracts the
-// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
-bool
-EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
-{
+// The SUBS PC, LR, #<const? instruction provides an exception return without
+// the use of the stack. It subtracts the
+// immediate constant from the LR, branches to the resulting address, and also
+// copies the SPSR to the CPSR.
+bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -12254,1240 +12227,1597 @@ EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncod
BranchWritePC(result);
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed (opcode))
- {
- uint32_t n;
- uint32_t m;
- uint32_t imm32;
- bool register_form;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
- uint32_t code;
-
- switch (encoding)
- {
- case eEncodingT1:
- // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
- // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; // = SUB
- n = 14;
- imm32 = Bits32 (opcode, 7, 0);
- register_form = false;
- code = 2;
-
- // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- if (InITBlock() && !LastInITBlock())
- return false;
-
- break;
-
- case eEncodingA1:
- // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
- n = Bits32 (opcode, 19, 16);
- imm32 = ARMExpandImm (opcode);
- register_form = false;
- code = Bits32 (opcode, 24, 21);
-
- break;
-
- case eEncodingA2:
- // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
- register_form = true;
-
- // (shift_t, shift_n) = DecodeImmShift(type, imm5);
- shift_n = DecodeImmShiftARM (opcode, shift_t);
-
- break;
-
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ uint32_t m;
+ uint32_t imm32;
+ bool register_form;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
+ uint32_t code;
- // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
- uint32_t operand2;
- if (register_form)
- {
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
- }
- else
- {
- operand2 = imm32;
- }
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- AddWithCarryResult result;
-
- // case opcode of
- switch (code)
- {
- case 0: // when '0000'
- // result = R[n] AND operand2; // AND
- result.result = Rn & operand2;
- break;
-
- case 1: // when '0001'
- // result = R[n] EOR operand2; // EOR
- result.result = Rn ^ operand2;
- break;
-
- case 2: // when '0010'
- // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
- result = AddWithCarry (Rn, ~(operand2), 1);
- break;
-
- case 3: // when '0011'
- // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
- result = AddWithCarry (~(Rn), operand2, 1);
- break;
-
- case 4: // when '0100'
- // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
- result = AddWithCarry (Rn, operand2, 0);
- break;
-
- case 5: // when '0101'
- // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
- result = AddWithCarry (Rn, operand2, APSR_C);
- break;
-
- case 6: // when '0110'
- // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
- result = AddWithCarry (Rn, ~(operand2), APSR_C);
- break;
-
- case 7: // when '0111'
- // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
- result = AddWithCarry (~(Rn), operand2, APSR_C);
- break;
-
- case 10: // when '1100'
- // result = R[n] OR operand2; // ORR
- result.result = Rn | operand2;
- break;
-
- case 11: // when '1101'
- // result = operand2; // MOV
- result.result = operand2;
- break;
-
- case 12: // when '1110'
- // result = R[n] AND NOT(operand2); // BIC
- result.result = Rn & ~(operand2);
- break;
-
- case 15: // when '1111'
- // result = NOT(operand2); // MVN
- result.result = ~(operand2);
- break;
-
- default:
- return false;
- }
- // CPSRWriteByInstr(SPSR[], '1111', TRUE);
-
- // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
- // the best.
- uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
- if (!success)
- return false;
-
- CPSRWriteByInstr (spsr, 15, true);
-
- // BranchWritePC(result);
- EmulateInstruction::Context context;
- context.type = eContextAdjustPC;
- context.SetImmediate (result.result);
-
- BranchWritePC (context, result.result);
- }
- return true;
-}
-
-EmulateInstructionARM::ARMOpcode*
-EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
-{
- static ARMOpcode
- g_arm_opcodes[] =
- {
- //----------------------------------------------------------------------
- // Prologue instructions
- //----------------------------------------------------------------------
-
- // push register(s)
- { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
- { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
-
- // set r7 to point to a stack offset
- { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
- { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
- // 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, #<const>" },
- { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
-
- // adjust the stack pointer
- { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
- { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
-
- // 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 <list>"},
- { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
-
- //----------------------------------------------------------------------
- // Epilogue instructions
- //----------------------------------------------------------------------
-
- { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
- { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
- { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
- { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
-
- //----------------------------------------------------------------------
- // Supervisor Call (previously Software Interrupt)
- //----------------------------------------------------------------------
- { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
-
- //----------------------------------------------------------------------
- // Branch instructions
- //----------------------------------------------------------------------
- // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>".
- { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
- { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
- { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
- { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
- // for example, "bx lr"
- { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
- // bxj
- { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
-
- //----------------------------------------------------------------------
- // Data-processing instructions
- //----------------------------------------------------------------------
- // adc (immediate)
- { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
- // adc (register)
- { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // add (immediate)
- { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
- // add (register)
- { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // add (register-shifted register)
- { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
- // adr
- { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
- { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
- // and (immediate)
- { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
- // and (register)
- { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // bic (immediate)
- { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
- // bic (register)
- { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // eor (immediate)
- { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
- // eor (register)
- { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // orr (immediate)
- { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
- // orr (register)
- { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // rsb (immediate)
- { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
- // rsb (register)
- { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // rsc (immediate)
- { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
- // rsc (register)
- { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // sbc (immediate)
- { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
- // sbc (register)
- { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // sub (immediate, ARM)
- { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
- // sub (sp minus immediate)
- { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
- // sub (register)
- { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
- // teq (immediate)
- { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
- // teq (register)
- { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
- // tst (immediate)
- { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
- // tst (register)
- { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
-
- // mov (immediate)
- { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
- { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
- // mov (register)
- { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
- // mvn (immediate)
- { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
- // mvn (register)
- { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
- // cmn (immediate)
- { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
- // cmn (register)
- { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
- // cmp (immediate)
- { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
- // cmp (register)
- { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
- // asr (immediate)
- { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
- // asr (register)
- { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
- // lsl (immediate)
- { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
- // lsl (register)
- { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
- // lsr (immediate)
- { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
- // lsr (register)
- { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
- // rrx is a special case encoding of ror (immediate)
- { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
- // ror (immediate)
- { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
- // ror (register)
- { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
- // mul
- { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
-
- // subs pc, lr and related instructions
- { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
- { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
-
- //----------------------------------------------------------------------
- // Load instructions
- //----------------------------------------------------------------------
- { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
- { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
- { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
- { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
- { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
- { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
- { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
- { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
- { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
- { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
- { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
- { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
- { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
- { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
- { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
- { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
- { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
- { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
- { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
- { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
- { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
- { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
-
- //----------------------------------------------------------------------
- // Store instructions
- //----------------------------------------------------------------------
- { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
- { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
- { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
- { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
- { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
- { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
- { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
- { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
- { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
- { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
- { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
- { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
- { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
- { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
-
- //----------------------------------------------------------------------
- // Other instructions
- //----------------------------------------------------------------------
- { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
- { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
- { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
- { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
- { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
-
- };
- static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
-
- for (size_t i=0; i<k_num_arm_opcodes; ++i)
- {
- if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
- (g_arm_opcodes[i].variants & arm_isa) != 0)
- return &g_arm_opcodes[i];
- }
- return NULL;
-}
+ switch (encoding) {
+ case eEncodingT1:
+ // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
+ // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode =
+ // '0010'; // = SUB
+ n = 14;
+ imm32 = Bits32(opcode, 7, 0);
+ register_form = false;
+ code = 2;
+
+ // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ if (InITBlock() && !LastInITBlock())
+ return false;
-
-EmulateInstructionARM::ARMOpcode*
-EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
-{
+ break;
- static ARMOpcode
- g_thumb_opcodes[] =
- {
- //----------------------------------------------------------------------
- // Prologue instructions
- //----------------------------------------------------------------------
-
- // push register(s)
- { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
- { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
- { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
-
- // set r7 to point to a stack offset
- { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
- // copy the stack pointer to r7
- { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
- // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
- { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
-
- // PC-relative load into register (see also EmulateADDSPRm)
- { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
-
- // adjust the stack pointer
- { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
- { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
- { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
- { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
- { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
-
- // vector push consecutive extension register(s)
- { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
- { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
-
- //----------------------------------------------------------------------
- // Epilogue instructions
- //----------------------------------------------------------------------
-
- { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
- { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
- { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
- { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
- { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
- { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
- { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
-
- //----------------------------------------------------------------------
- // Supervisor Call (previously Software Interrupt)
- //----------------------------------------------------------------------
- { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
-
- //----------------------------------------------------------------------
- // If Then makes up to four following instructions conditional.
- //----------------------------------------------------------------------
- // The next 5 opcode _must_ come before the if then instruction
- { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
- { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
- { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
- { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
- { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
- { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
-
- //----------------------------------------------------------------------
- // Branch instructions
- //----------------------------------------------------------------------
- // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
- { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
- { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
- { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
- { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
- // J1 == J2 == 1
- { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
- // J1 == J2 == 1
- { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
- { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
- // for example, "bx lr"
- { 0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
- // bxj
- { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
- // compare and branch
- { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
- // table branch byte
- { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
- // table branch halfword
- { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
-
- //----------------------------------------------------------------------
- // Data-processing instructions
- //----------------------------------------------------------------------
- // adc (immediate)
- { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
- // adc (register)
- { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // add (register)
- { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
- // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
- { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
- // adr
- { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
- { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
- { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
- // and (immediate)
- { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
- // and (register)
- { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // bic (immediate)
- { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
- // bic (register)
- { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // eor (immediate)
- { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
- // eor (register)
- { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // orr (immediate)
- { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
- // orr (register)
- { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // rsb (immediate)
- { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
- { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
- // rsb (register)
- { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // sbc (immediate)
- { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
- // sbc (register)
- { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // add (immediate, Thumb)
- { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
- { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
- { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
- { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
- // sub (immediate, Thumb)
- { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
- { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
- { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
- { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
- // sub (sp minus immediate)
- { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
- { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
- // sub (register)
- { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
- { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
- // teq (immediate)
- { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
- // teq (register)
- { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
- // tst (immediate)
- { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
- // tst (register)
- { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
- { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
-
-
- // move from high register to high register
- { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
- // move from low register to low register
- { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
- // mov{s}<c>.w <Rd>, <Rm>
- { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
- // move immediate
- { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
- { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
- { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
- // mvn (immediate)
- { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
- // mvn (register)
- { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
- { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
- // cmn (immediate)
- { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
- // cmn (register)
- { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
- { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
- // cmp (immediate)
- { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
- { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
- // cmp (register) (Rn and Rm both from r0-r7)
- { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
- // cmp (register) (Rn and Rm not both from r0-r7)
- { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
- { 0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
- // asr (immediate)
- { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
- { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
- // asr (register)
- { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
- { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
- // lsl (immediate)
- { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
- { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
- // lsl (register)
- { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
- { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
- // lsr (immediate)
- { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
- { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
- // lsr (register)
- { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
- { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
- // rrx is a special case encoding of ror (immediate)
- { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
- // ror (immediate)
- { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
- // ror (register)
- { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
- { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
- // mul
- { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
- // mul
- { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
-
- // subs pc, lr and related instructions
- { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
-
- //----------------------------------------------------------------------
- // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
- // otherwise the wrong instructions will be selected.
- //----------------------------------------------------------------------
-
- { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
- { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
-
- //----------------------------------------------------------------------
- // Load instructions
- //----------------------------------------------------------------------
- { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
- { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
- { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
- { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
- { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
- { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
- { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
- // Thumb2 PC-relative load into register
- { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
- { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
- { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
- { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
- { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
- { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
- { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
- { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
- { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
- { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" },
- { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
- { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" },
- { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
- { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
- { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
- { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
- { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
- { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
- { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
- { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
- { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
- { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
- { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
- { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
- { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
- { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
- { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
- { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
- { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
- { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
- { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
- { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
- { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
-
- //----------------------------------------------------------------------
- // Store instructions
- //----------------------------------------------------------------------
- { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
- { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
- { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
- { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
- { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
- { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
- { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
- { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
- { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
- { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
- { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
- { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
- { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
- { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
- { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
- { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
- { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
- { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
- { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
- { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
- { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
- { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
-
- //----------------------------------------------------------------------
- // Other instructions
- //----------------------------------------------------------------------
- { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
- { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
- { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
- { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
- { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
- { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
- { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
- { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
- };
-
- const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
- for (size_t i=0; i<k_num_thumb_opcodes; ++i)
- {
- if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
- (g_thumb_opcodes[i].variants & arm_isa) != 0)
- return &g_thumb_opcodes[i];
- }
- return NULL;
-}
+ case eEncodingA1:
+ // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
+ n = Bits32(opcode, 19, 16);
+ imm32 = ARMExpandImm(opcode);
+ register_form = false;
+ code = Bits32(opcode, 24, 21);
-bool
-EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
-{
- m_arch = arch;
- m_arm_isa = 0;
- const char *arch_cstr = arch.GetArchitectureName ();
- if (arch_cstr)
- {
- if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T;
- else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ;
- else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE;
- else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T;
- else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K;
- else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2;
- else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S;
- else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll;
- else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll;
- else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4;
- else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6;
- else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7;
- else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8;
- }
- return m_arm_isa != 0;
-}
-
-bool
-EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
-{
- if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
- {
- if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || m_arch.IsAlwaysThumbInstructions ())
- m_opcode_mode = eModeThumb;
- else
- {
- AddressClass addr_class = inst_addr.GetAddressClass();
+ break;
- if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
- m_opcode_mode = eModeARM;
- else if (addr_class == eAddressClassCodeAlternateISA)
- m_opcode_mode = eModeThumb;
- else
- return false;
- }
- if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions ())
- m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
- else
- m_opcode_cpsr = CPSR_MODE_USR;
- return true;
+ case eEncodingA2:
+ // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+ register_form = true;
+
+ // (shift_t, shift_n) = DecodeImmShift(type, imm5);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ break;
+
+ default:
+ return false;
}
- return false;
-}
-bool
-EmulateInstructionARM::ReadInstruction ()
-{
- bool success = false;
- m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
- if (success)
- {
- addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
- if (success)
- {
- Context read_inst_context;
- read_inst_context.type = eContextReadOpcode;
- read_inst_context.SetNoArgs ();
-
- if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions ())
- {
- m_opcode_mode = eModeThumb;
- uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
-
- if (success)
- {
- if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
- {
- m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
- }
- else
- {
- m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
- }
- }
- }
- else
- {
- m_opcode_mode = eModeARM;
- m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
- }
+ // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
+ // else imm32;
+ uint32_t operand2;
+ if (register_form) {
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
- if (!m_ignore_conditions)
- {
- // If we are not ignoreing the conditions then init the it session from the current
- // value of cpsr.
- uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | Bits32(m_opcode_cpsr, 26, 25);
- if (it != 0)
- m_it_session.InitIT(it);
- }
- }
+ operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+ } else {
+ operand2 = imm32;
}
+
+ uint32_t Rn = ReadCoreReg(n, &success);
if (!success)
- {
- m_opcode_mode = eModeInvalid;
- m_addr = LLDB_INVALID_ADDRESS;
+ return false;
+
+ AddWithCarryResult result;
+
+ // case opcode of
+ switch (code) {
+ case 0: // when '0000'
+ // result = R[n] AND operand2; // AND
+ result.result = Rn & operand2;
+ break;
+
+ case 1: // when '0001'
+ // result = R[n] EOR operand2; // EOR
+ result.result = Rn ^ operand2;
+ break;
+
+ case 2: // when '0010'
+ // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
+ result = AddWithCarry(Rn, ~(operand2), 1);
+ break;
+
+ case 3: // when '0011'
+ // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
+ result = AddWithCarry(~(Rn), operand2, 1);
+ break;
+
+ case 4: // when '0100'
+ // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
+ result = AddWithCarry(Rn, operand2, 0);
+ break;
+
+ case 5: // when '0101'
+ // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
+ result = AddWithCarry(Rn, operand2, APSR_C);
+ break;
+
+ case 6: // when '0110'
+ // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
+ result = AddWithCarry(Rn, ~(operand2), APSR_C);
+ break;
+
+ case 7: // when '0111'
+ // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
+ result = AddWithCarry(~(Rn), operand2, APSR_C);
+ break;
+
+ case 10: // when '1100'
+ // result = R[n] OR operand2; // ORR
+ result.result = Rn | operand2;
+ break;
+
+ case 11: // when '1101'
+ // result = operand2; // MOV
+ result.result = operand2;
+ break;
+
+ case 12: // when '1110'
+ // result = R[n] AND NOT(operand2); // BIC
+ result.result = Rn & ~(operand2);
+ break;
+
+ case 15: // when '1111'
+ // result = NOT(operand2); // MVN
+ result.result = ~(operand2);
+ break;
+
+ default:
+ return false;
}
- return success;
-}
+ // CPSRWriteByInstr(SPSR[], '1111', TRUE);
-uint32_t
-EmulateInstructionARM::ArchVersion ()
-{
- return m_arm_isa;
-}
+ // For now, in emulation mode, we don't have access to the SPSR, so we will
+ // use the CPSR instead, and hope for
+ // the best.
+ uint32_t spsr =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
+ if (!success)
+ return false;
-bool
-EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
-{
- // If we are ignoring conditions, then always return true.
- // this allows us to iterate over disassembly code and still
- // emulate an instruction even if we don't have all the right
- // bits set in the CPSR register...
- if (m_ignore_conditions)
- return true;
+ CPSRWriteByInstr(spsr, 15, true);
- const uint32_t cond = CurrentCond (opcode);
- if (cond == UINT32_MAX)
+ // BranchWritePC(result);
+ EmulateInstruction::Context context;
+ context.type = eContextAdjustPC;
+ context.SetImmediate(result.result);
+
+ BranchWritePC(context, result.result);
+ }
+ return true;
+}
+
+EmulateInstructionARM::ARMOpcode *
+EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
+ uint32_t arm_isa) {
+ static ARMOpcode g_arm_opcodes[] = {
+ //----------------------------------------------------------------------
+ // Prologue instructions
+ //----------------------------------------------------------------------
+
+ // push register(s)
+ {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
+ {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePUSH, "push <register>"},
+
+ // set r7 to point to a stack offset
+ {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
+ {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
+ // 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, #<const>"},
+ {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
+
+ // adjust the stack pointer
+ {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
+ {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPReg,
+ "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
+
+ // 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 <list>"},
+ {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
+
+ //----------------------------------------------------------------------
+ // Epilogue instructions
+ //----------------------------------------------------------------------
+
+ {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
+ {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePOP, "pop <register>"},
+ {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
+ {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
+
+ //----------------------------------------------------------------------
+ // Supervisor Call (previously Software Interrupt)
+ //----------------------------------------------------------------------
+ {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
+
+ //----------------------------------------------------------------------
+ // Branch instructions
+ //----------------------------------------------------------------------
+ // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
+ // "bl <label>".
+ {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
+ {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateB, "b #imm24"},
+ {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
+ {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
+ // for example, "bx lr"
+ {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
+ // bxj
+ {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
+
+ //----------------------------------------------------------------------
+ // Data-processing instructions
+ //----------------------------------------------------------------------
+ // adc (immediate)
+ {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
+ // adc (register)
+ {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADCReg,
+ "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // add (immediate)
+ {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDImmARM,
+ "add{s}<c> <Rd>, <Rn>, #const"},
+ // add (register)
+ {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDReg,
+ "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // add (register-shifted register)
+ {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDRegShift,
+ "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
+ // adr
+ {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
+ {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
+ // and (immediate)
+ {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
+ // and (register)
+ {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateANDReg,
+ "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // bic (immediate)
+ {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
+ // bic (register)
+ {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBICReg,
+ "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // eor (immediate)
+ {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
+ // eor (register)
+ {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateEORReg,
+ "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // orr (immediate)
+ {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
+ // orr (register)
+ {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateORRReg,
+ "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // rsb (immediate)
+ {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
+ // rsb (register)
+ {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSBReg,
+ "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // rsc (immediate)
+ {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
+ // rsc (register)
+ {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSCReg,
+ "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // sbc (immediate)
+ {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
+ // sbc (register)
+ {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSBCReg,
+ "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // sub (immediate, ARM)
+ {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBImmARM,
+ "sub{s}<c> <Rd>, <Rn>, #<const>"},
+ // sub (sp minus immediate)
+ {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
+ // sub (register)
+ {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBReg,
+ "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
+ // teq (immediate)
+ {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
+ // teq (register)
+ {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
+ // tst (immediate)
+ {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
+ // tst (register)
+ {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
+
+ // mov (immediate)
+ {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
+ {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
+ // mov (register)
+ {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
+ // mvn (immediate)
+ {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
+ // mvn (register)
+ {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMVNReg,
+ "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
+ // cmn (immediate)
+ {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
+ // cmn (register)
+ {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
+ // cmp (immediate)
+ {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
+ // cmp (register)
+ {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
+ // asr (immediate)
+ {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
+ // asr (register)
+ {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
+ // lsl (immediate)
+ {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
+ // lsl (register)
+ {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
+ // lsr (immediate)
+ {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
+ // lsr (register)
+ {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
+ // rrx is a special case encoding of ror (immediate)
+ {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
+ // ror (immediate)
+ {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
+ // ror (register)
+ {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
+ // mul
+ {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
+
+ // subs pc, lr and related instructions
+ {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPcLrEtc,
+ "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
+ {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPcLrEtc,
+ "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
+
+ //----------------------------------------------------------------------
+ // Load instructions
+ //----------------------------------------------------------------------
+ {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
+ {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRImmediateARM,
+ "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
+ {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRRegister,
+ "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
+ {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
+ {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBRegister,
+ "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
+ {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
+ {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHRegister,
+ "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
+ {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBImmediate,
+ "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
+ {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
+ {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBRegister,
+ "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
+ {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHImmediate,
+ "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
+ {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
+ {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHRegister,
+ "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
+ {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRDImmediate,
+ "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
+ {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRDRegister,
+ "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
+ {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
+ {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
+ {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
+ {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
+ {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1Multiple,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+ {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1Single,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+ {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1SingleAll,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+
+ //----------------------------------------------------------------------
+ // Store instructions
+ //----------------------------------------------------------------------
+ {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
+ {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRRegister,
+ "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
+ {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRHRegister,
+ "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
+ {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
+ {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRBImmARM,
+ "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
+ {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRImmARM,
+ "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
+ {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRDImm,
+ "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
+ {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRDReg,
+ "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
+ {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
+ {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
+ {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
+ {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
+ {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVST1Multiple,
+ "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+ {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVST1Single,
+ "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+
+ //----------------------------------------------------------------------
+ // Other instructions
+ //----------------------------------------------------------------------
+ {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
+ {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
+ {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
+ {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
+ {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
+
+ };
+ static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
+
+ for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
+ if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
+ (g_arm_opcodes[i].variants & arm_isa) != 0)
+ return &g_arm_opcodes[i];
+ }
+ return NULL;
+}
+
+EmulateInstructionARM::ARMOpcode *
+EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
+ uint32_t arm_isa) {
+
+ static ARMOpcode g_thumb_opcodes[] = {
+ //----------------------------------------------------------------------
+ // Prologue instructions
+ //----------------------------------------------------------------------
+
+ // push register(s)
+ {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
+ {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
+ {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
+
+ // set r7 to point to a stack offset
+ {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
+ // copy the stack pointer to r7
+ {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
+ // move from high register to low register (comes after "mov r7, sp" to
+ // resolve ambiguity)
+ {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
+
+ // PC-relative load into register (see also EmulateADDSPRm)
+ {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
+
+ // adjust the stack pointer
+ {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
+ {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
+ {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
+ {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
+ {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPReg,
+ "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
+
+ // vector push consecutive extension register(s)
+ {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
+ {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
+
+ //----------------------------------------------------------------------
+ // Epilogue instructions
+ //----------------------------------------------------------------------
+
+ {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
+ {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
+ {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
+ {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
+ {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
+ {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
+ {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
+
+ //----------------------------------------------------------------------
+ // Supervisor Call (previously Software Interrupt)
+ //----------------------------------------------------------------------
+ {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
+
+ //----------------------------------------------------------------------
+ // If Then makes up to four following instructions conditional.
+ //----------------------------------------------------------------------
+ // The next 5 opcode _must_ come before the if then instruction
+ {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateNop, "nop"},
+ {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
+ {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
+ {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
+ {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
+ {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
+
+ //----------------------------------------------------------------------
+ // Branch instructions
+ //----------------------------------------------------------------------
+ // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
+ {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
+ {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
+ {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
+ {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateB,
+ "b<c>.w #imm8 (outside or last in IT)"},
+ // J1 == J2 == 1
+ {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
+ // J1 == J2 == 1
+ {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
+ {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
+ // for example, "bx lr"
+ {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
+ // bxj
+ {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
+ // compare and branch
+ {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
+ // table branch byte
+ {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
+ // table branch halfword
+ {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
+
+ //----------------------------------------------------------------------
+ // Data-processing instructions
+ //----------------------------------------------------------------------
+ // adc (immediate)
+ {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
+ // adc (register)
+ {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADCReg,
+ "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // add (register)
+ {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
+ // Make sure "add sp, <Rm>" comes before this instruction, so there's no
+ // ambiguity decoding the two.
+ {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
+ // adr
+ {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
+ {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
+ {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
+ // and (immediate)
+ {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
+ // and (register)
+ {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateANDReg,
+ "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // bic (immediate)
+ {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
+ // bic (register)
+ {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBICReg,
+ "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // eor (immediate)
+ {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
+ // eor (register)
+ {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateEORReg,
+ "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // orr (immediate)
+ {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
+ // orr (register)
+ {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateORRReg,
+ "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // rsb (immediate)
+ {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
+ {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSBImm,
+ "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
+ // rsb (register)
+ {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSBReg,
+ "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // sbc (immediate)
+ {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
+ // sbc (register)
+ {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSBCReg,
+ "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // add (immediate, Thumb)
+ {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDImmThumb,
+ "adds|add<c> <Rd>,<Rn>,#<imm3>"},
+ {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
+ {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDImmThumb,
+ "add{s}<c>.w <Rd>,<Rn>,#<const>"},
+ {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDImmThumb,
+ "addw<c> <Rd>,<Rn>,#<imm12>"},
+ // sub (immediate, Thumb)
+ {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSUBImmThumb,
+ "subs|sub<c> <Rd>, <Rn> #imm3"},
+ {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
+ {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBImmThumb,
+ "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
+ {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBImmThumb,
+ "subw<c> <Rd>, <Rn>, #imm12"},
+ // sub (sp minus immediate)
+ {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
+ {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
+ // sub (register)
+ {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
+ {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBReg,
+ "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
+ // teq (immediate)
+ {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
+ // teq (register)
+ {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
+ // tst (immediate)
+ {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
+ // tst (register)
+ {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
+ {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
+
+ // move from high register to high register
+ {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
+ // move from low register to low register
+ {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
+ // mov{s}<c>.w <Rd>, <Rm>
+ {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
+ // move immediate
+ {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
+ {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
+ {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
+ // mvn (immediate)
+ {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
+ // mvn (register)
+ {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
+ {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMVNReg,
+ "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
+ // cmn (immediate)
+ {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
+ // cmn (register)
+ {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
+ {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
+ // cmp (immediate)
+ {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
+ {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
+ // cmp (register) (Rn and Rm both from r0-r7)
+ {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
+ // cmp (register) (Rn and Rm not both from r0-r7)
+ {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
+ {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCMPReg,
+ "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
+ // asr (immediate)
+ {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
+ {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
+ // asr (register)
+ {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
+ {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
+ // lsl (immediate)
+ {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
+ {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
+ // lsl (register)
+ {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
+ {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
+ // lsr (immediate)
+ {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
+ {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
+ // lsr (register)
+ {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
+ {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
+ // rrx is a special case encoding of ror (immediate)
+ {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
+ // ror (immediate)
+ {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
+ // ror (register)
+ {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
+ {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
+ // mul
+ {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
+ // mul
+ {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
+
+ // subs pc, lr and related instructions
+ {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
+
+ //----------------------------------------------------------------------
+ // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
+ // LDM.. Instructions in this table;
+ // otherwise the wrong instructions will be selected.
+ //----------------------------------------------------------------------
+
+ {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
+ {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
+
+ //----------------------------------------------------------------------
+ // Load instructions
+ //----------------------------------------------------------------------
+ {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
+ {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
+ {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
+ {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
+ {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
+ {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRRtRnImm,
+ "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
+ {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRRtRnImm,
+ "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
+ // Thumb2 PC-relative load into register
+ {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRRtPCRelative,
+ "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
+ {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
+ {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRRegister,
+ "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
+ {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRBImmediate,
+ "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
+ {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBImmediate,
+ "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
+ {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBImmediate,
+ "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
+ {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
+ {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
+ {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBRegister,
+ "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
+ {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRHImmediate,
+ "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
+ {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHImmediate,
+ "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
+ {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHImmediate,
+ "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
+ {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
+ {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRHRegister,
+ "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
+ {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHRegister,
+ "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
+ {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBImmediate,
+ "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
+ {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBImmediate,
+ "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
+ {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
+ {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRSBRegister,
+ "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
+ {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBRegister,
+ "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
+ {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHImmediate,
+ "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
+ {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHImmediate,
+ "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
+ {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
+ {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRSHRegister,
+ "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
+ {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHRegister,
+ "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
+ {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRDImmediate,
+ "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
+ {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
+ {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
+ {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
+ {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
+ {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1Multiple,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
+ {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1Single,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
+ {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1SingleAll,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+
+ //----------------------------------------------------------------------
+ // Store instructions
+ //----------------------------------------------------------------------
+ {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
+ {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
+ {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
+ {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
+ {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
+ {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRThumb,
+ "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
+ {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRThumb,
+ "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
+ {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
+ {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRRegister,
+ "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
+ {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTRBThumb,
+ "strb<c> <Rt>, [<Rn>, #<imm5>]"},
+ {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRBThumb,
+ "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
+ {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRBThumb,
+ "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
+ {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
+ {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRHRegister,
+ "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
+ {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTREX,
+ "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
+ {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRDImm,
+ "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
+ {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
+ {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
+ {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
+ {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
+ {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVST1Multiple,
+ "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+ {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVST1Single,
+ "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+
+ //----------------------------------------------------------------------
+ // Other instructions
+ //----------------------------------------------------------------------
+ {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
+ {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
+ {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
+ {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
+ {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
+ {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
+ {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
+ {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
+ };
+
+ const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
+ for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
+ if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
+ (g_thumb_opcodes[i].variants & arm_isa) != 0)
+ return &g_thumb_opcodes[i];
+ }
+ return NULL;
+}
+
+bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
+ m_arch = arch;
+ m_arm_isa = 0;
+ const char *arch_cstr = arch.GetArchitectureName();
+ if (arch_cstr) {
+ if (0 == ::strcasecmp(arch_cstr, "armv4t"))
+ m_arm_isa = ARMv4T;
+ else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))
+ m_arm_isa = ARMv5TEJ;
+ else if (0 == ::strcasecmp(arch_cstr, "armv5te"))
+ m_arm_isa = ARMv5TE;
+ else if (0 == ::strcasecmp(arch_cstr, "armv5t"))
+ m_arm_isa = ARMv5T;
+ else if (0 == ::strcasecmp(arch_cstr, "armv6k"))
+ m_arm_isa = ARMv6K;
+ else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))
+ m_arm_isa = ARMv6T2;
+ else if (0 == ::strcasecmp(arch_cstr, "armv7s"))
+ m_arm_isa = ARMv7S;
+ else if (0 == ::strcasecmp(arch_cstr, "arm"))
+ m_arm_isa = ARMvAll;
+ else if (0 == ::strcasecmp(arch_cstr, "thumb"))
+ m_arm_isa = ARMvAll;
+ else if (0 == ::strncasecmp(arch_cstr, "armv4", 5))
+ m_arm_isa = ARMv4;
+ else if (0 == ::strncasecmp(arch_cstr, "armv6", 5))
+ m_arm_isa = ARMv6;
+ else if (0 == ::strncasecmp(arch_cstr, "armv7", 5))
+ m_arm_isa = ARMv7;
+ else if (0 == ::strncasecmp(arch_cstr, "armv8", 5))
+ m_arm_isa = ARMv8;
+ }
+ return m_arm_isa != 0;
+}
+
+bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
+ const Address &inst_addr,
+ Target *target) {
+ if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
+ if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
+ m_arch.IsAlwaysThumbInstructions())
+ m_opcode_mode = eModeThumb;
+ else {
+ AddressClass addr_class = inst_addr.GetAddressClass();
+
+ if ((addr_class == eAddressClassCode) ||
+ (addr_class == eAddressClassUnknown))
+ m_opcode_mode = eModeARM;
+ else if (addr_class == eAddressClassCodeAlternateISA)
+ m_opcode_mode = eModeThumb;
+ else
return false;
-
- bool result = false;
- switch (UnsignedBits(cond, 3, 1))
- {
- case 0:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
- break;
- case 1:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
- break;
- case 2:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
- break;
- case 3:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
- break;
- case 4:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
- break;
- case 5:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- {
- bool n = (m_opcode_cpsr & MASK_CPSR_N);
- bool v = (m_opcode_cpsr & MASK_CPSR_V);
- result = n == v;
- }
- break;
- case 6:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- {
- bool n = (m_opcode_cpsr & MASK_CPSR_N);
- bool v = (m_opcode_cpsr & MASK_CPSR_V);
- result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
- }
- break;
- case 7:
- // Always execute (cond == 0b1110, or the special 0b1111 which gives
- // opcodes different meanings, but always means execution happens.
- return true;
}
+ if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
+ m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
+ else
+ m_opcode_cpsr = CPSR_MODE_USR;
+ return true;
+ }
+ return false;
+}
+
+bool EmulateInstructionARM::ReadInstruction() {
+ bool success = false;
+ m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
+ if (success) {
+ addr_t pc =
+ ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_ADDRESS, &success);
+ if (success) {
+ Context read_inst_context;
+ read_inst_context.type = eContextReadOpcode;
+ read_inst_context.SetNoArgs();
+
+ if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
+ m_opcode_mode = eModeThumb;
+ uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
+
+ if (success) {
+ if ((thumb_opcode & 0xe000) != 0xe000 ||
+ ((thumb_opcode & 0x1800u) == 0)) {
+ m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
+ } else {
+ m_opcode.SetOpcode32(
+ (thumb_opcode << 16) |
+ MemARead(read_inst_context, pc + 2, 2, 0, &success),
+ GetByteOrder());
+ }
+ }
+ } else {
+ m_opcode_mode = eModeARM;
+ m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
+ GetByteOrder());
+ }
+
+ if (!m_ignore_conditions) {
+ // If we are not ignoreing the conditions then init the it session from
+ // the current
+ // value of cpsr.
+ uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
+ Bits32(m_opcode_cpsr, 26, 25);
+ if (it != 0)
+ m_it_session.InitIT(it);
+ }
+ }
+ }
+ if (!success) {
+ m_opcode_mode = eModeInvalid;
+ m_addr = LLDB_INVALID_ADDRESS;
+ }
+ return success;
+}
+
+uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
+
+bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
+ // If we are ignoring conditions, then always return true.
+ // this allows us to iterate over disassembly code and still
+ // emulate an instruction even if we don't have all the right
+ // bits set in the CPSR register...
+ if (m_ignore_conditions)
+ return true;
+
+ const uint32_t cond = CurrentCond(opcode);
+ if (cond == UINT32_MAX)
+ return false;
- if (cond & 1)
- result = !result;
- return result;
+ bool result = false;
+ switch (UnsignedBits(cond, 3, 1)) {
+ case 0:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
+ break;
+ case 1:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
+ break;
+ case 2:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
+ break;
+ case 3:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
+ break;
+ case 4:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
+ ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
+ break;
+ case 5:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else {
+ bool n = (m_opcode_cpsr & MASK_CPSR_N);
+ bool v = (m_opcode_cpsr & MASK_CPSR_V);
+ result = n == v;
+ }
+ break;
+ case 6:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else {
+ bool n = (m_opcode_cpsr & MASK_CPSR_N);
+ bool v = (m_opcode_cpsr & MASK_CPSR_V);
+ result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
+ }
+ break;
+ case 7:
+ // Always execute (cond == 0b1110, or the special 0b1111 which gives
+ // opcodes different meanings, but always means execution happens.
+ return true;
+ }
+
+ if (cond & 1)
+ result = !result;
+ return result;
}
-uint32_t
-EmulateInstructionARM::CurrentCond (const uint32_t opcode)
-{
- switch (m_opcode_mode)
+uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
+ switch (m_opcode_mode) {
+ case eModeInvalid:
+ break;
+
+ case eModeARM:
+ return UnsignedBits(opcode, 31, 28);
+
+ case eModeThumb:
+ // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
+ // 'cond' field of the encoding.
{
- case eModeInvalid:
+ const uint32_t byte_size = m_opcode.GetByteSize();
+ if (byte_size == 2) {
+ if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
+ return Bits32(opcode, 11, 8);
+ } else if (byte_size == 4) {
+ if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
+ Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
+ return Bits32(opcode, 25, 22);
+ }
+ } else
+ // We have an invalid thumb instruction, let's bail out.
break;
- case eModeARM:
- return UnsignedBits(opcode, 31, 28);
-
- case eModeThumb:
- // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
- // 'cond' field of the encoding.
- {
- const uint32_t byte_size = m_opcode.GetByteSize();
- if (byte_size == 2)
- {
- if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
- return Bits32(opcode, 11, 8);
- }
- else if (byte_size == 4)
- {
- if (Bits32(opcode, 31, 27) == 0x1e &&
- Bits32(opcode, 15, 14) == 0x02 &&
- Bits32(opcode, 12, 12) == 0x00 &&
- Bits32(opcode, 25, 22) <= 0x0d)
- {
- return Bits32(opcode, 25, 22);
- }
- }
- else
- // We have an invalid thumb instruction, let's bail out.
- break;
-
- return m_it_session.GetCond();
- }
+ return m_it_session.GetCond();
}
- return UINT32_MAX; // Return invalid value
+ }
+ return UINT32_MAX; // Return invalid value
}
-bool
-EmulateInstructionARM::InITBlock()
-{
- return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
+bool EmulateInstructionARM::InITBlock() {
+ return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
}
-bool
-EmulateInstructionARM::LastInITBlock()
-{
- return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
+bool EmulateInstructionARM::LastInITBlock() {
+ return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
}
-bool
-EmulateInstructionARM::BadMode (uint32_t mode)
-{
-
- switch (mode)
- {
- case 16: return false; // '10000'
- case 17: return false; // '10001'
- case 18: return false; // '10010'
- case 19: return false; // '10011'
- case 22: return false; // '10110'
- case 23: return false; // '10111'
- case 27: return false; // '11011'
- case 31: return false; // '11111'
- default: return true;
- }
- return true;
-}
-
-bool
-EmulateInstructionARM::CurrentModeIsPrivileged ()
-{
- uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
-
- if (BadMode (mode))
- return false;
-
- if (mode == 16)
- return false;
-
+bool EmulateInstructionARM::BadMode(uint32_t mode) {
+
+ switch (mode) {
+ case 16:
+ return false; // '10000'
+ case 17:
+ return false; // '10001'
+ case 18:
+ return false; // '10010'
+ case 19:
+ return false; // '10011'
+ case 22:
+ return false; // '10110'
+ case 23:
+ return false; // '10111'
+ case 27:
+ return false; // '11011'
+ case 31:
+ return false; // '11111'
+ default:
return true;
+ }
+ return true;
}
-void
-EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
-{
- bool privileged = CurrentModeIsPrivileged();
+bool EmulateInstructionARM::CurrentModeIsPrivileged() {
+ uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
- uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
-
- if (BitIsSet (bytemask, 3))
- {
- tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
- if (affect_execstate)
- tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
- }
-
- if (BitIsSet (bytemask, 2))
- {
- tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
- }
-
- if (BitIsSet (bytemask, 1))
- {
- if (affect_execstate)
- tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
- tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
- if (privileged)
- tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
- }
-
- if (BitIsSet (bytemask, 0))
- {
- if (privileged)
- tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
- if (affect_execstate)
- tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
- if (privileged)
- tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
- }
-
- m_opcode_cpsr = tmp_cpsr;
+ if (BadMode(mode))
+ return false;
+
+ if (mode == 16)
+ return false;
+
+ return true;
}
-
-bool
-EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
-{
- addr_t target;
+void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
+ bool affect_execstate) {
+ bool privileged = CurrentModeIsPrivileged();
- // Check the current instruction set.
- if (CurrentInstrSet() == eModeARM)
- target = addr & 0xfffffffc;
- else
- target = addr & 0xfffffffe;
+ uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
- return false;
+ if (BitIsSet(bytemask, 3)) {
+ tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
+ if (affect_execstate)
+ tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
+ }
- return true;
+ if (BitIsSet(bytemask, 2)) {
+ tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
+ }
+
+ if (BitIsSet(bytemask, 1)) {
+ if (affect_execstate)
+ tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
+ tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
+ if (privileged)
+ tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
+ }
+
+ if (BitIsSet(bytemask, 0)) {
+ if (privileged)
+ tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
+ if (affect_execstate)
+ tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
+ if (privileged)
+ tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
+ }
+
+ m_opcode_cpsr = tmp_cpsr;
}
-// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
-bool
-EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
-{
- addr_t target;
- // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
- // we want to record it and issue a WriteRegister callback so the clients
- // can track the mode changes accordingly.
- bool cpsr_changed = false;
+bool EmulateInstructionARM::BranchWritePC(const Context &context,
+ uint32_t addr) {
+ addr_t target;
- if (BitIsSet(addr, 0))
- {
- if (CurrentInstrSet() != eModeThumb)
- {
- SelectInstrSet(eModeThumb);
- cpsr_changed = true;
- }
- target = addr & 0xfffffffe;
- context.SetISA (eModeThumb);
- }
- else if (BitIsClear(addr, 1))
- {
- if (CurrentInstrSet() != eModeARM)
- {
- SelectInstrSet(eModeARM);
- cpsr_changed = true;
- }
- target = addr & 0xfffffffc;
- context.SetISA (eModeARM);
- }
- else
- return false; // address<1:0> == '10' => UNPREDICTABLE
+ // Check the current instruction set.
+ if (CurrentInstrSet() == eModeARM)
+ target = addr & 0xfffffffc;
+ else
+ target = addr & 0xfffffffe;
- if (cpsr_changed)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
- return false;
- }
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, target))
+ return false;
- return true;
+ return true;
+}
+
+// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
+// inspecting addr.
+bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
+ addr_t target;
+ // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
+ // we want to record it and issue a WriteRegister callback so the clients
+ // can track the mode changes accordingly.
+ bool cpsr_changed = false;
+
+ if (BitIsSet(addr, 0)) {
+ if (CurrentInstrSet() != eModeThumb) {
+ SelectInstrSet(eModeThumb);
+ cpsr_changed = true;
+ }
+ target = addr & 0xfffffffe;
+ context.SetISA(eModeThumb);
+ } else if (BitIsClear(addr, 1)) {
+ if (CurrentInstrSet() != eModeARM) {
+ SelectInstrSet(eModeARM);
+ cpsr_changed = true;
+ }
+ target = addr & 0xfffffffc;
+ context.SetISA(eModeARM);
+ } else
+ return false; // address<1:0> == '10' => UNPREDICTABLE
+
+ if (cpsr_changed) {
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
+ return false;
+ }
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, target))
+ return false;
+
+ return true;
}
-// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
-bool
-EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
-{
- if (ArchVersion() >= ARMv5T)
- return BXWritePC(context, addr);
- else
- return BranchWritePC((const Context)context, addr);
+// Dispatches to either BXWritePC or BranchWritePC based on architecture
+// versions.
+bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
+ if (ArchVersion() >= ARMv5T)
+ return BXWritePC(context, addr);
+ else
+ return BranchWritePC((const Context)context, addr);
}
-// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
-bool
-EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
-{
- if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
- return BXWritePC(context, addr);
- else
- return BranchWritePC((const Context)context, addr);
+// Dispatches to either BXWritePC or BranchWritePC based on architecture
+// versions and current instruction set.
+bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
+ if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
+ return BXWritePC(context, addr);
+ else
+ return BranchWritePC((const Context)context, addr);
}
-EmulateInstructionARM::Mode
-EmulateInstructionARM::CurrentInstrSet ()
-{
- return m_opcode_mode;
+EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
+ return m_opcode_mode;
}
// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next
// ReadInstruction() is performed. This function has a side effect of updating
// the m_new_inst_cpsr member variable if necessary.
-bool
-EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
-{
- m_new_inst_cpsr = m_opcode_cpsr;
- switch (arm_or_thumb)
- {
- default:
- return false;
- case eModeARM:
- // Clear the T bit.
- m_new_inst_cpsr &= ~MASK_CPSR_T;
- break;
- case eModeThumb:
- // Set the T bit.
- m_new_inst_cpsr |= MASK_CPSR_T;
- break;
- }
- return true;
+bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
+ m_new_inst_cpsr = m_opcode_cpsr;
+ switch (arm_or_thumb) {
+ default:
+ return false;
+ case eModeARM:
+ // Clear the T bit.
+ m_new_inst_cpsr &= ~MASK_CPSR_T;
+ break;
+ case eModeThumb:
+ // Set the T bit.
+ m_new_inst_cpsr |= MASK_CPSR_T;
+ break;
+ }
+ return true;
}
// This function returns TRUE if the processor currently provides support for
// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
-bool
-EmulateInstructionARM::UnalignedSupport()
-{
- return (ArchVersion() >= ARMv7);
+bool EmulateInstructionARM::UnalignedSupport() {
+ return (ArchVersion() >= ARMv7);
}
// The main addition and subtraction instructions can produce status information
// about both unsigned carry and signed overflow conditions. This status
// information can be used to synthesize multi-word additions and subtractions.
EmulateInstructionARM::AddWithCarryResult
-EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
-{
- uint32_t result;
- uint8_t carry_out;
- uint8_t overflow;
-
- uint64_t unsigned_sum = x + y + carry_in;
- int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
-
- result = UnsignedBits(unsigned_sum, 31, 0);
-// carry_out = (result == unsigned_sum ? 0 : 1);
- overflow = ((int32_t)result == signed_sum ? 0 : 1);
-
- if (carry_in)
- carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
+EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
+ uint32_t result;
+ uint8_t carry_out;
+ uint8_t overflow;
+
+ uint64_t unsigned_sum = x + y + carry_in;
+ int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
+
+ result = UnsignedBits(unsigned_sum, 31, 0);
+ // carry_out = (result == unsigned_sum ? 0 : 1);
+ overflow = ((int32_t)result == signed_sum ? 0 : 1);
+
+ if (carry_in)
+ carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
+ else
+ carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
+
+ AddWithCarryResult res = {result, carry_out, overflow};
+ return res;
+}
+
+uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
+ lldb::RegisterKind reg_kind;
+ uint32_t reg_num;
+ switch (num) {
+ case SP_REG:
+ reg_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_SP;
+ break;
+ case LR_REG:
+ reg_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_RA;
+ break;
+ case PC_REG:
+ reg_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ default:
+ if (num < SP_REG) {
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_r0 + num;
+ } else {
+ // assert(0 && "Invalid register number");
+ *success = false;
+ return UINT32_MAX;
+ }
+ break;
+ }
+
+ // Read our register.
+ uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
+
+ // When executing an ARM instruction , PC reads as the address of the current
+ // instruction plus 8.
+ // When executing a Thumb instruction , PC reads as the address of the current
+ // instruction plus 4.
+ if (num == 15) {
+ if (CurrentInstrSet() == eModeARM)
+ val += 8;
else
- carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
-
- AddWithCarryResult res = { result, carry_out, overflow };
- return res;
-}
+ val += 4;
+ }
-uint32_t
-EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
-{
- lldb::RegisterKind reg_kind;
- uint32_t reg_num;
- switch (num)
- {
- case SP_REG:
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_SP;
- break;
- case LR_REG:
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_RA;
- break;
- case PC_REG:
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_PC;
- break;
- default:
- if (num < SP_REG)
- {
- reg_kind = eRegisterKindDWARF;
- reg_num = dwarf_r0 + num;
- }
- else
- {
- //assert(0 && "Invalid register number");
- *success = false;
- return UINT32_MAX;
- }
- break;
- }
-
- // Read our register.
- uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
-
- // When executing an ARM instruction , PC reads as the address of the current
- // instruction plus 8.
- // When executing a Thumb instruction , PC reads as the address of the current
- // instruction plus 4.
- if (num == 15)
- {
- if (CurrentInstrSet() == eModeARM)
- val += 8;
- else
- val += 4;
- }
-
- return val;
+ return val;
}
// Write the result to the ARM core register Rd, and optionally update the
@@ -13508,43 +13838,34 @@ EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
//
// In the above case, the API client does not pass in the overflow arg, which
// defaults to ~0u.
-bool
-EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
- const uint32_t result,
- const uint32_t Rd,
- bool setflags,
- const uint32_t carry,
- const uint32_t overflow)
-{
- if (Rd == 15)
- {
- if (!ALUWritePC (context, result))
- return false;
- }
- else
- {
- lldb::RegisterKind reg_kind;
- uint32_t reg_num;
- switch (Rd)
- {
- case SP_REG:
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_SP;
- break;
- case LR_REG:
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_RA;
- break;
- default:
- reg_kind = eRegisterKindDWARF;
- reg_num = dwarf_r0 + Rd;
- }
- if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
- return false;
- if (setflags)
- return WriteFlags (context, result, carry, overflow);
+bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
+ Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
+ const uint32_t carry, const uint32_t overflow) {
+ if (Rd == 15) {
+ if (!ALUWritePC(context, result))
+ return false;
+ } else {
+ lldb::RegisterKind reg_kind;
+ uint32_t reg_num;
+ switch (Rd) {
+ case SP_REG:
+ reg_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_SP;
+ break;
+ case LR_REG:
+ reg_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_RA;
+ break;
+ default:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_r0 + Rd;
}
- return true;
+ if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
+ return false;
+ if (setflags)
+ return WriteFlags(context, result, carry, overflow);
+ }
+ return true;
}
// This helper method tries to encapsulate the following pseudocode from the
@@ -13555,203 +13876,192 @@ EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
// APSR.C = carry;
// APSR.V = overflow
//
-// Default arguments can be specified for carry and overflow parameters, which means
+// Default arguments can be specified for carry and overflow parameters, which
+// means
// not to update the respective flags.
-bool
-EmulateInstructionARM::WriteFlags (Context &context,
- const uint32_t result,
- const uint32_t carry,
- const uint32_t overflow)
-{
- m_new_inst_cpsr = m_opcode_cpsr;
- SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
- SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
- if (carry != ~0u)
- SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
- if (overflow != ~0u)
- SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
- if (m_new_inst_cpsr != m_opcode_cpsr)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
- return false;
- }
- return true;
-}
+bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
+ const uint32_t carry,
+ const uint32_t overflow) {
+ m_new_inst_cpsr = m_opcode_cpsr;
+ SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
+ SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
+ if (carry != ~0u)
+ SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
+ if (overflow != ~0u)
+ SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
+ if (m_new_inst_cpsr != m_opcode_cpsr) {
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
+ return false;
+ }
+ return true;
+}
+
+bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
+ ARMOpcode *opcode_data = NULL;
+
+ if (m_opcode_mode == eModeThumb)
+ opcode_data =
+ GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
+ else if (m_opcode_mode == eModeARM)
+ opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
+
+ const bool auto_advance_pc =
+ evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+ m_ignore_conditions =
+ evaluate_options & eEmulateInstructionOptionIgnoreConditions;
+
+ bool success = false;
+ if (m_opcode_cpsr == 0 || m_ignore_conditions == false) {
+ m_opcode_cpsr =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
+ }
+
+ // Only return false if we are unable to read the CPSR if we care about
+ // conditions
+ if (success == false && m_ignore_conditions == false)
+ return false;
-bool
-EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
-{
- ARMOpcode *opcode_data = NULL;
-
- if (m_opcode_mode == eModeThumb)
- opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
- else if (m_opcode_mode == eModeARM)
- opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
+ uint32_t orig_pc_value = 0;
+ if (auto_advance_pc) {
+ orig_pc_value =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
+ if (!success)
+ return false;
+ }
- const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
- m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
-
- bool success = false;
- if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
- {
- m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
- dwarf_cpsr,
- 0,
- &success);
- }
+ // Call the Emulate... function if we managed to decode the opcode.
+ if (opcode_data) {
+ success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
+ opcode_data->encoding);
+ if (!success)
+ return false;
+ }
+
+ // Advance the ITSTATE bits to their values for the next instruction if we
+ // haven't just executed
+ // an IT instruction what initialized it.
+ if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
+ (opcode_data == nullptr ||
+ opcode_data->callback != &EmulateInstructionARM::EmulateIT))
+ m_it_session.ITAdvance();
+
+ if (auto_advance_pc) {
+ uint32_t after_pc_value =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
+ if (!success)
+ return false;
- // Only return false if we are unable to read the CPSR if we care about conditions
- if (success == false && m_ignore_conditions == false)
+ if (auto_advance_pc && (after_pc_value == orig_pc_value)) {
+ after_pc_value += m_opcode.GetByteSize();
+
+ EmulateInstruction::Context context;
+ context.type = eContextAdvancePC;
+ context.SetNoArgs();
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
+ after_pc_value))
return false;
-
- uint32_t orig_pc_value = 0;
- if (auto_advance_pc)
- {
- orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
- if (!success)
- return false;
}
+ }
+ return true;
+}
- // Call the Emulate... function if we managed to decode the opcode.
- if (opcode_data)
- {
- success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
- if (!success)
- return false;
- }
+EmulateInstruction::InstructionCondition
+EmulateInstructionARM::GetInstructionCondition() {
+ const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
+ if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
+ return EmulateInstruction::UnconditionalCondition;
+ return cond;
+}
- // Advance the ITSTATE bits to their values for the next instruction if we haven't just executed
- // an IT instruction what initialized it.
- if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
- (opcode_data == nullptr || opcode_data->callback != &EmulateInstructionARM::EmulateIT))
- m_it_session.ITAdvance();
+bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch,
+ OptionValueDictionary *test_data) {
+ if (!test_data) {
+ out_stream->Printf("TestEmulation: Missing test data.\n");
+ return false;
+ }
- if (auto_advance_pc)
- {
- uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
- if (!success)
- return false;
+ static ConstString opcode_key("opcode");
+ static ConstString before_key("before_state");
+ static ConstString after_key("after_state");
- if (auto_advance_pc && (after_pc_value == orig_pc_value))
- {
- after_pc_value += m_opcode.GetByteSize();
+ OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
- EmulateInstruction::Context context;
- context.type = eContextAdvancePC;
- context.SetNoArgs();
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
- return false;
- }
- }
- return true;
-}
+ uint32_t test_opcode;
+ if ((value_sp.get() == NULL) ||
+ (value_sp->GetType() != OptionValue::eTypeUInt64)) {
+ out_stream->Printf("TestEmulation: Error reading opcode from test file.\n");
+ return false;
+ }
+ test_opcode = value_sp->GetUInt64Value();
+
+ if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
+ arch.IsAlwaysThumbInstructions()) {
+ m_opcode_mode = eModeThumb;
+ if (test_opcode < 0x10000)
+ m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
+ else
+ m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
+ } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
+ m_opcode_mode = eModeARM;
+ m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
+ } else {
+ out_stream->Printf("TestEmulation: Invalid arch.\n");
+ return false;
+ }
-EmulateInstruction::InstructionCondition
-EmulateInstructionARM::GetInstructionCondition()
-{
- const uint32_t cond = CurrentCond (m_opcode.GetOpcode32());
- if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
- return EmulateInstruction::UnconditionalCondition;
- return cond;
-}
-
-bool
-EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
-{
- if (!test_data)
- {
- out_stream->Printf ("TestEmulation: Missing test data.\n");
- return false;
- }
-
- static ConstString opcode_key ("opcode");
- static ConstString before_key ("before_state");
- static ConstString after_key ("after_state");
-
- OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
-
- uint32_t test_opcode;
- if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
- {
- out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
- return false;
- }
- test_opcode = value_sp->GetUInt64Value ();
+ EmulationStateARM before_state;
+ EmulationStateARM after_state;
+ value_sp = test_data->GetValueForKey(before_key);
+ if ((value_sp.get() == NULL) ||
+ (value_sp->GetType() != OptionValue::eTypeDictionary)) {
+ out_stream->Printf("TestEmulation: Failed to find 'before' state.\n");
+ return false;
+ }
- if (arch.GetTriple().getArch() == llvm::Triple::thumb || arch.IsAlwaysThumbInstructions ())
- {
- m_opcode_mode = eModeThumb;
- if (test_opcode < 0x10000)
- m_opcode.SetOpcode16 (test_opcode, endian::InlHostByteOrder());
- else
- m_opcode.SetOpcode32 (test_opcode, endian::InlHostByteOrder());
- }
- else if (arch.GetTriple().getArch() == llvm::Triple::arm)
- {
- m_opcode_mode = eModeARM;
- m_opcode.SetOpcode32 (test_opcode, endian::InlHostByteOrder());
- }
- else
- {
- out_stream->Printf ("TestEmulation: Invalid arch.\n");
- return false;
- }
+ OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
+ if (!before_state.LoadStateFromDictionary(state_dictionary)) {
+ out_stream->Printf("TestEmulation: Failed loading 'before' state.\n");
+ return false;
+ }
- EmulationStateARM before_state;
- EmulationStateARM after_state;
-
- value_sp = test_data->GetValueForKey (before_key);
- if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
- {
- out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n");
- return false;
- }
-
- OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
- if (!before_state.LoadStateFromDictionary (state_dictionary))
- {
- out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n");
- return false;
- }
+ value_sp = test_data->GetValueForKey(after_key);
+ if ((value_sp.get() == NULL) ||
+ (value_sp->GetType() != OptionValue::eTypeDictionary)) {
+ out_stream->Printf("TestEmulation: Failed to find 'after' state.\n");
+ return false;
+ }
- value_sp = test_data->GetValueForKey (after_key);
- if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
- {
- out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n");
- return false;
- }
+ state_dictionary = value_sp->GetAsDictionary();
+ if (!after_state.LoadStateFromDictionary(state_dictionary)) {
+ out_stream->Printf("TestEmulation: Failed loading 'after' state.\n");
+ return false;
+ }
- state_dictionary = value_sp->GetAsDictionary ();
- if (!after_state.LoadStateFromDictionary (state_dictionary))
- {
- out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
- return false;
- }
+ SetBaton((void *)&before_state);
+ SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
+ &EmulationStateARM::WritePseudoMemory,
+ &EmulationStateARM::ReadPseudoRegister,
+ &EmulationStateARM::WritePseudoRegister);
- SetBaton ((void *) &before_state);
- SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
- &EmulationStateARM::WritePseudoMemory,
- &EmulationStateARM::ReadPseudoRegister,
- &EmulationStateARM::WritePseudoRegister);
-
- bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
- if (!success)
- {
- out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n");
- return false;
- }
-
- success = before_state.CompareState (after_state);
- if (!success)
- out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n");
-
- return success;
+ bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
+ if (!success) {
+ out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n");
+ return false;
+ }
+
+ success = before_state.CompareState(after_state);
+ if (!success)
+ out_stream->Printf(
+ "TestEmulation: 'before' and 'after' states do not match.\n");
+
+ return success;
}
//
-//
-//const char *
-//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
+//
+// const char *
+// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
//{
// if (reg_kind == eRegisterKindGeneric)
// {
@@ -13772,21 +14082,19 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option
// return NULL;
//}
//
-bool
-EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
-
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
-
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("EmulateInstructionARM");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
- unwind_plan.SetReturnAddressRegister (dwarf_lr);
- return true;
+bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("EmulateInstructionARM");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetReturnAddressRegister(dwarf_lr);
+ return true;
}
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
index 6e75a3db2eb5..1bfc4cb398fb 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
@@ -10,981 +10,778 @@
#ifndef lldb_EmulateInstructionARM_h_
#define lldb_EmulateInstructionARM_h_
-#include "lldb/Core/EmulateInstruction.h"
+#include "Plugins/Process/Utility/ARMDefines.h"
#include "lldb/Core/ConstString.h"
+#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Error.h"
-#include "Plugins/Process/Utility/ARMDefines.h"
namespace lldb_private {
// ITSession - Keep track of the IT Block progression.
-class ITSession
-{
+class ITSession {
public:
- ITSession() : ITCounter(0), ITState(0) {}
- ~ITSession() {}
+ ITSession() : ITCounter(0), ITState(0) {}
+ ~ITSession() {}
- // InitIT - Initializes ITCounter/ITState.
- bool InitIT(uint32_t bits7_0);
+ // InitIT - Initializes ITCounter/ITState.
+ bool InitIT(uint32_t bits7_0);
- // ITAdvance - Updates ITCounter/ITState as IT Block progresses.
- void ITAdvance();
+ // ITAdvance - Updates ITCounter/ITState as IT Block progresses.
+ void ITAdvance();
- // InITBlock - Returns true if we're inside an IT Block.
- bool InITBlock();
+ // InITBlock - Returns true if we're inside an IT Block.
+ bool InITBlock();
- // LastInITBlock - Returns true if we're the last instruction inside an IT Block.
- bool LastInITBlock();
+ // LastInITBlock - Returns true if we're the last instruction inside an IT
+ // Block.
+ bool LastInITBlock();
- // GetCond - Gets condition bits for the current thumb instruction.
- uint32_t GetCond();
+ // GetCond - Gets condition bits for the current thumb instruction.
+ uint32_t GetCond();
private:
- uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4.
- uint32_t ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
+ uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4.
+ uint32_t ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
};
-class EmulateInstructionARM : public EmulateInstruction
-{
-public:
- typedef enum
- {
- eEncodingA1,
- eEncodingA2,
- eEncodingA3,
- eEncodingA4,
- eEncodingA5,
- eEncodingT1,
- eEncodingT2,
- eEncodingT3,
- eEncodingT4,
- eEncodingT5
- } ARMEncoding;
-
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb_private::ConstString
- GetPluginNameStatic ();
-
- static const char *
- GetPluginDescriptionStatic ();
-
- static lldb_private::EmulateInstruction *
- CreateInstance (const lldb_private::ArchSpec &arch,
- InstructionType inst_type);
-
- static bool
- SupportsEmulatingInstructionsOfTypeStatic (InstructionType inst_type)
- {
- switch (inst_type)
- {
- case eInstructionTypeAny:
- case eInstructionTypePrologueEpilogue:
- case eInstructionTypePCModifying:
- return true;
-
- case eInstructionTypeAll:
- return false;
- }
- return false;
+class EmulateInstructionARM : public EmulateInstruction {
+public:
+ typedef enum {
+ eEncodingA1,
+ eEncodingA2,
+ eEncodingA3,
+ eEncodingA4,
+ eEncodingA5,
+ eEncodingT1,
+ eEncodingT2,
+ eEncodingT3,
+ eEncodingT4,
+ eEncodingT5
+ } ARMEncoding;
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::EmulateInstruction *
+ CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type);
+
+ static bool
+ SupportsEmulatingInstructionsOfTypeStatic(InstructionType inst_type) {
+ switch (inst_type) {
+ case eInstructionTypeAny:
+ case eInstructionTypePrologueEpilogue:
+ case eInstructionTypePCModifying:
+ return true;
+
+ case eInstructionTypeAll:
+ return false;
}
+ return false;
+ }
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ uint32_t GetPluginVersion() override { return 1; }
- bool
- SetTargetTriple (const ArchSpec &arch) override;
-
- enum Mode
- {
- eModeInvalid = -1,
- eModeARM,
- eModeThumb
- };
-
- EmulateInstructionARM (const ArchSpec &arch) :
- EmulateInstruction (arch),
- m_arm_isa (0),
- m_opcode_mode (eModeInvalid),
- m_opcode_cpsr (0),
- m_it_session (),
- m_ignore_conditions (false)
- {
- SetArchitecture (arch);
- }
+ bool SetTargetTriple(const ArchSpec &arch) override;
-// EmulateInstructionARM (const ArchSpec &arch,
-// bool ignore_conditions,
-// void *baton,
-// ReadMemory read_mem_callback,
-// WriteMemory write_mem_callback,
-// ReadRegister read_reg_callback,
-// WriteRegister write_reg_callback) :
-// EmulateInstruction (arch,
-// ignore_conditions,
-// baton,
-// read_mem_callback,
-// write_mem_callback,
-// read_reg_callback,
-// write_reg_callback),
-// m_arm_isa (0),
-// m_opcode_mode (eModeInvalid),
-// m_opcode_cpsr (0),
-// m_it_session ()
-// {
-// }
-
- bool
- SupportsEmulatingInstructionsOfType (InstructionType inst_type) override
- {
- return SupportsEmulatingInstructionsOfTypeStatic (inst_type);
- }
+ enum Mode { eModeInvalid = -1, eModeARM, eModeThumb };
- virtual bool
- SetArchitecture (const ArchSpec &arch);
-
- bool
- ReadInstruction () override;
-
- bool
- SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) override;
-
- bool
- EvaluateInstruction (uint32_t evaluate_options) override;
-
- InstructionCondition
- GetInstructionCondition() override;
-
- bool
- TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) override;
-
- bool
- GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info) override;
-
- bool
- CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) override;
-
- uint32_t
- ArchVersion();
-
- bool
- ConditionPassed (const uint32_t opcode);
-
- uint32_t
- CurrentCond (const uint32_t opcode);
-
- // InITBlock - Returns true if we're in Thumb mode and inside an IT Block.
- bool InITBlock();
-
- // LastInITBlock - Returns true if we're in Thumb mode and the last instruction inside an IT Block.
- bool LastInITBlock();
-
- bool
- BadMode (uint32_t mode);
-
- bool
- CurrentModeIsPrivileged ();
-
- void
- CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate);
-
- bool
- BranchWritePC(const Context &context, uint32_t addr);
-
- bool
- BXWritePC(Context &context, uint32_t addr);
-
- bool
- LoadWritePC(Context &context, uint32_t addr);
-
- bool
- ALUWritePC(Context &context, uint32_t addr);
-
- Mode
- CurrentInstrSet();
-
- bool
- SelectInstrSet(Mode arm_or_thumb);
-
- bool
- WriteBits32Unknown (int n);
-
- bool
- WriteBits32UnknownToMemory (lldb::addr_t address);
-
- bool
- UnalignedSupport();
-
- typedef struct
- {
- uint32_t result;
- uint8_t carry_out;
- uint8_t overflow;
- } AddWithCarryResult;
-
- AddWithCarryResult
- AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in);
-
- // Helper method to read the content of an ARM core register.
- uint32_t
- ReadCoreReg (uint32_t regnum, bool *success);
-
- // See A8.6.96 MOV (immediate) Operation.
- // Default arguments are specified for carry and overflow parameters, which means
- // not to update the respective flags even if setflags is true.
- bool
- WriteCoreRegOptionalFlags (Context &context,
- const uint32_t result,
- const uint32_t Rd,
- bool setflags,
- const uint32_t carry = ~0u,
- const uint32_t overflow = ~0u);
-
- bool
- WriteCoreReg (Context &context,
- const uint32_t result,
- const uint32_t Rd)
- {
- // Don't set the flags.
- return WriteCoreRegOptionalFlags(context, result, Rd, false);
- }
+ EmulateInstructionARM(const ArchSpec &arch)
+ : EmulateInstruction(arch), m_arm_isa(0), m_opcode_mode(eModeInvalid),
+ m_opcode_cpsr(0), m_it_session(), m_ignore_conditions(false) {
+ SetArchitecture(arch);
+ }
- // See A8.6.35 CMP (immediate) Operation.
- // Default arguments are specified for carry and overflow parameters, which means
- // not to update the respective flags.
- bool
- WriteFlags (Context &context,
- const uint32_t result,
- const uint32_t carry = ~0u,
- const uint32_t overflow = ~0u);
-
- inline uint64_t
- MemARead (EmulateInstruction::Context &context,
- lldb::addr_t address,
- uint32_t size,
- uint64_t fail_value,
- bool *success_ptr)
- {
- // This is a stub function corresponding to "MemA[]" in the ARM manual pseudocode, for
- // aligned reads from memory. Since we are not trying to write a full hardware simulator, and since
- // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the
- // system registers we would need in order to fully implement this function, we will just call
- // ReadMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of
- // the hardware, we can update this function appropriately.
-
- return ReadMemoryUnsigned (context, address, size, fail_value, success_ptr);
- }
-
- inline bool
- MemAWrite (EmulateInstruction::Context &context,
- lldb::addr_t address,
- uint64_t data_val,
- uint32_t size)
-
- {
- // This is a stub function corresponding to "MemA[]" in the ARM manual pseudocode, for
- // aligned writes to memory. Since we are not trying to write a full hardware simulator, and since
- // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the
- // system registers we would need in order to fully implement this function, we will just call
- // WriteMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of
- // the hardware, we can update this function appropriately.
-
- return WriteMemoryUnsigned (context, address, data_val, size);
- }
-
-
- inline uint64_t
- MemURead (EmulateInstruction::Context &context,
- lldb::addr_t address,
- uint32_t size,
- uint64_t fail_value,
- bool *success_ptr)
- {
- // This is a stub function corresponding to "MemU[]" in the ARM manual pseudocode, for
- // unaligned reads from memory. Since we are not trying to write a full hardware simulator, and since
- // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the
- // system registers we would need in order to fully implement this function, we will just call
- // ReadMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of
- // the hardware, we can update this function appropriately.
-
- return ReadMemoryUnsigned (context, address, size, fail_value, success_ptr);
- }
-
- inline bool
- MemUWrite (EmulateInstruction::Context &context,
- lldb::addr_t address,
- uint64_t data_val,
- uint32_t size)
-
- {
- // This is a stub function corresponding to "MemU[]" in the ARM manual pseudocode, for
- // unaligned writes to memory. Since we are not trying to write a full hardware simulator, and since
- // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the
- // system registers we would need in order to fully implement this function, we will just call
- // WriteMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of
- // the hardware, we can update this function appropriately.
-
- return WriteMemoryUnsigned (context, address, data_val, size);
- }
+ // EmulateInstructionARM (const ArchSpec &arch,
+ // bool ignore_conditions,
+ // void *baton,
+ // ReadMemory read_mem_callback,
+ // WriteMemory write_mem_callback,
+ // ReadRegister read_reg_callback,
+ // WriteRegister write_reg_callback) :
+ // EmulateInstruction (arch,
+ // ignore_conditions,
+ // baton,
+ // read_mem_callback,
+ // write_mem_callback,
+ // read_reg_callback,
+ // write_reg_callback),
+ // m_arm_isa (0),
+ // m_opcode_mode (eModeInvalid),
+ // m_opcode_cpsr (0),
+ // m_it_session ()
+ // {
+ // }
+
+ bool SupportsEmulatingInstructionsOfType(InstructionType inst_type) override {
+ return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
+ }
+
+ virtual bool SetArchitecture(const ArchSpec &arch);
+
+ bool ReadInstruction() override;
+
+ bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr,
+ Target *target) override;
+
+ bool EvaluateInstruction(uint32_t evaluate_options) override;
+
+ InstructionCondition GetInstructionCondition() override;
+
+ bool TestEmulation(Stream *out_stream, ArchSpec &arch,
+ OptionValueDictionary *test_data) override;
+
+ bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ RegisterInfo &reg_info) override;
+
+ bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) override;
+
+ uint32_t ArchVersion();
+
+ bool ConditionPassed(const uint32_t opcode);
+
+ uint32_t CurrentCond(const uint32_t opcode);
+
+ // InITBlock - Returns true if we're in Thumb mode and inside an IT Block.
+ bool InITBlock();
+
+ // LastInITBlock - Returns true if we're in Thumb mode and the last
+ // instruction inside an IT Block.
+ bool LastInITBlock();
+
+ bool BadMode(uint32_t mode);
+
+ bool CurrentModeIsPrivileged();
+
+ void CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
+ bool affect_execstate);
+
+ bool BranchWritePC(const Context &context, uint32_t addr);
+
+ bool BXWritePC(Context &context, uint32_t addr);
+
+ bool LoadWritePC(Context &context, uint32_t addr);
+
+ bool ALUWritePC(Context &context, uint32_t addr);
+
+ Mode CurrentInstrSet();
+
+ bool SelectInstrSet(Mode arm_or_thumb);
+
+ bool WriteBits32Unknown(int n);
+
+ bool WriteBits32UnknownToMemory(lldb::addr_t address);
+
+ bool UnalignedSupport();
+
+ typedef struct {
+ uint32_t result;
+ uint8_t carry_out;
+ uint8_t overflow;
+ } AddWithCarryResult;
+
+ AddWithCarryResult AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in);
+
+ // Helper method to read the content of an ARM core register.
+ uint32_t ReadCoreReg(uint32_t regnum, bool *success);
+
+ // See A8.6.96 MOV (immediate) Operation.
+ // Default arguments are specified for carry and overflow parameters, which
+ // means
+ // not to update the respective flags even if setflags is true.
+ bool WriteCoreRegOptionalFlags(Context &context, const uint32_t result,
+ const uint32_t Rd, bool setflags,
+ const uint32_t carry = ~0u,
+ const uint32_t overflow = ~0u);
+
+ bool WriteCoreReg(Context &context, const uint32_t result,
+ const uint32_t Rd) {
+ // Don't set the flags.
+ return WriteCoreRegOptionalFlags(context, result, Rd, false);
+ }
+
+ // See A8.6.35 CMP (immediate) Operation.
+ // Default arguments are specified for carry and overflow parameters, which
+ // means
+ // not to update the respective flags.
+ bool WriteFlags(Context &context, const uint32_t result,
+ const uint32_t carry = ~0u, const uint32_t overflow = ~0u);
+
+ inline uint64_t MemARead(EmulateInstruction::Context &context,
+ lldb::addr_t address, uint32_t size,
+ uint64_t fail_value, bool *success_ptr) {
+ // This is a stub function corresponding to "MemA[]" in the ARM manual
+ // pseudocode, for
+ // aligned reads from memory. Since we are not trying to write a full
+ // hardware simulator, and since
+ // we are running in User mode (rather than Kernel mode) and therefore won't
+ // have access to many of the
+ // system registers we would need in order to fully implement this function,
+ // we will just call
+ // ReadMemoryUnsigned from here. In the future, if we decide we do need to
+ // do more faithful emulation of
+ // the hardware, we can update this function appropriately.
+
+ return ReadMemoryUnsigned(context, address, size, fail_value, success_ptr);
+ }
+
+ inline bool MemAWrite(EmulateInstruction::Context &context,
+ lldb::addr_t address, uint64_t data_val, uint32_t size)
+
+ {
+ // This is a stub function corresponding to "MemA[]" in the ARM manual
+ // pseudocode, for
+ // aligned writes to memory. Since we are not trying to write a full
+ // hardware simulator, and since
+ // we are running in User mode (rather than Kernel mode) and therefore won't
+ // have access to many of the
+ // system registers we would need in order to fully implement this function,
+ // we will just call
+ // WriteMemoryUnsigned from here. In the future, if we decide we do need to
+ // do more faithful emulation of
+ // the hardware, we can update this function appropriately.
+
+ return WriteMemoryUnsigned(context, address, data_val, size);
+ }
+
+ inline uint64_t MemURead(EmulateInstruction::Context &context,
+ lldb::addr_t address, uint32_t size,
+ uint64_t fail_value, bool *success_ptr) {
+ // This is a stub function corresponding to "MemU[]" in the ARM manual
+ // pseudocode, for
+ // unaligned reads from memory. Since we are not trying to write a full
+ // hardware simulator, and since
+ // we are running in User mode (rather than Kernel mode) and therefore won't
+ // have access to many of the
+ // system registers we would need in order to fully implement this function,
+ // we will just call
+ // ReadMemoryUnsigned from here. In the future, if we decide we do need to
+ // do more faithful emulation of
+ // the hardware, we can update this function appropriately.
+
+ return ReadMemoryUnsigned(context, address, size, fail_value, success_ptr);
+ }
+
+ inline bool MemUWrite(EmulateInstruction::Context &context,
+ lldb::addr_t address, uint64_t data_val, uint32_t size)
+
+ {
+ // This is a stub function corresponding to "MemU[]" in the ARM manual
+ // pseudocode, for
+ // unaligned writes to memory. Since we are not trying to write a full
+ // hardware simulator, and since
+ // we are running in User mode (rather than Kernel mode) and therefore won't
+ // have access to many of the
+ // system registers we would need in order to fully implement this function,
+ // we will just call
+ // WriteMemoryUnsigned from here. In the future, if we decide we do need to
+ // do more faithful emulation of
+ // the hardware, we can update this function appropriately.
+
+ return WriteMemoryUnsigned(context, address, data_val, size);
+ }
protected:
+ // Typedef for the callback function used during the emulation.
+ // Pass along (ARMEncoding)encoding as the callback data.
+ typedef enum { eSize16, eSize32 } ARMInstrSize;
+
+ typedef struct {
+ uint32_t mask;
+ uint32_t value;
+ uint32_t variants;
+ EmulateInstructionARM::ARMEncoding encoding;
+ uint32_t vfp_variants;
+ ARMInstrSize size;
+ bool (EmulateInstructionARM::*callback)(
+ const uint32_t opcode,
+ const EmulateInstructionARM::ARMEncoding encoding);
+ const char *name;
+ } ARMOpcode;
+
+ uint32_t GetFramePointerRegisterNumber() const;
+
+ uint32_t GetFramePointerDWARFRegisterNumber() const;
+
+ static ARMOpcode *GetARMOpcodeForInstruction(const uint32_t opcode,
+ uint32_t isa_mask);
+
+ static ARMOpcode *GetThumbOpcodeForInstruction(const uint32_t opcode,
+ uint32_t isa_mask);
+
+ // A8.6.123 PUSH
+ bool EmulatePUSH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.122 POP
+ bool EmulatePOP(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.8 ADD (SP plus immediate)
+ bool EmulateADDRdSPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.97 MOV (register) -- Rd == r7|ip and Rm == sp
+ bool EmulateMOVRdSP(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.97 MOV (register) -- move from r8-r15 to r0-r7
+ bool EmulateMOVLowHigh(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.59 LDR (literal)
+ bool EmulateLDRRtPCRelative(const uint32_t opcode,
+ const ARMEncoding encoding);
+
+ // A8.6.8 ADD (SP plus immediate)
+ bool EmulateADDSPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.9 ADD (SP plus register)
+ bool EmulateADDSPRm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.23 BL, BLX (immediate)
+ bool EmulateBLXImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.24 BLX (register)
+ bool EmulateBLXRm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.25 BX
+ bool EmulateBXRm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.26 BXJ
+ bool EmulateBXJRm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.212 SUB (immediate, ARM) -- Rd == r7 and Rm == ip
+ bool EmulateSUBR7IPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.215 SUB (SP minus immediate) -- Rd == ip
+ bool EmulateSUBIPSPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.215 SUB (SP minus immediate)
+ bool EmulateSUBSPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.216 SUB (SP minus register)
+ bool EmulateSUBSPReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.194 STR (immediate, ARM) -- Rn == sp
+ bool EmulateSTRRtSP(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.355 VPUSH
+ bool EmulateVPUSH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.354 VPOP
+ bool EmulateVPOP(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.218 SVC (previously SWI)
+ bool EmulateSVC(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.50 IT
+ bool EmulateIT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // NOP
+ bool EmulateNop(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.16 B
+ bool EmulateB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.27 CBNZ, CBZ
+ bool EmulateCB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.226 TBB, TBH
+ bool EmulateTB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.4 ADD (immediate, Thumb)
+ bool EmulateADDImmThumb(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.5 ADD (immediate, ARM)
+ bool EmulateADDImmARM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.6 ADD (register)
+ bool EmulateADDReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.7 ADD (register-shifted register)
+ bool EmulateADDRegShift(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.97 MOV (register)
+ bool EmulateMOVRdRm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.96 MOV (immediate)
+ bool EmulateMOVRdImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.35 CMP (immediate)
+ bool EmulateCMPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.36 CMP (register)
+ bool EmulateCMPReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.14 ASR (immediate)
+ bool EmulateASRImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.15 ASR (register)
+ bool EmulateASRReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.88 LSL (immediate)
+ bool EmulateLSLImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.89 LSL (register)
+ bool EmulateLSLReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.90 LSR (immediate)
+ bool EmulateLSRImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.91 LSR (register)
+ bool EmulateLSRReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.139 ROR (immediate)
+ bool EmulateRORImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.140 ROR (register)
+ bool EmulateRORReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.141 RRX
+ bool EmulateRRX(const uint32_t opcode, const ARMEncoding encoding);
+
+ // Helper method for ASR, LSL, LSR, ROR (immediate), and RRX
+ bool EmulateShiftImm(const uint32_t opcode, const ARMEncoding encoding,
+ ARM_ShifterType shift_type);
+
+ // Helper method for ASR, LSL, LSR, and ROR (register)
+ bool EmulateShiftReg(const uint32_t opcode, const ARMEncoding encoding,
+ ARM_ShifterType shift_type);
+
+ // LOAD FUNCTIONS
+
+ // A8.6.53 LDM/LDMIA/LDMFD
+ bool EmulateLDM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.54 LDMDA/LDMFA
+ bool EmulateLDMDA(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.55 LDMDB/LDMEA
+ bool EmulateLDMDB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.56 LDMIB/LDMED
+ bool EmulateLDMIB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.57 LDR (immediate, Thumb) -- Encoding T1
+ bool EmulateLDRRtRnImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.58 LDR (immediate, ARM) - Encoding A1
+ bool EmulateLDRImmediateARM(const uint32_t opcode,
+ const ARMEncoding encoding);
+
+ // A8.6.59 LDR (literal)
+ bool EmulateLDRLiteral(const uint32_t, const ARMEncoding encoding);
+
+ // A8.6.60 LDR (register) - Encoding T1, T2, A1
+ bool EmulateLDRRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.61 LDRB (immediate, Thumb) - Encoding T1, T2, T3
+ bool EmulateLDRBImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.62 LDRB (immediate, ARM)
+ bool EmulateLDRBImmediateARM(const uint32_t opcode,
+ const ARMEncoding encoding);
+
+ // A8.6.63 LDRB (literal) - Encoding T1, A1
+ bool EmulateLDRBLiteral(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.64 LDRB (register) - Encoding T1, T2, A1
+ bool EmulateLDRBRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.65 LDRBT
+ bool EmulateLDRBT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.66 LDRD (immediate)
+ bool EmulateLDRDImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.67
+ bool EmulateLDRDLiteral(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.68 LDRD (register)
+ bool EmulateLDRDRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.69 LDREX
+ bool EmulateLDREX(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.70 LDREXB
+ bool EmulateLDREXB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.71 LDREXD
+ bool EmulateLDREXD(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.72 LDREXH
+ bool EmulateLDREXH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.73 LDRH (immediate, Thumb) - Encoding T1, T2, T3
+ bool EmulateLDRHImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.74 LDRS (immediate, ARM)
+ bool EmulateLDRHImmediateARM(const uint32_t opcode,
+ const ARMEncoding encoding);
+
+ // A8.6.75 LDRH (literal) - Encoding T1, A1
+ bool EmulateLDRHLiteral(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.76 LDRH (register) - Encoding T1, T2, A1
+ bool EmulateLDRHRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.77 LDRHT
+ bool EmulateLDRHT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.78 LDRSB (immediate) - Encoding T1, T2, A1
+ bool EmulateLDRSBImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.79 LDRSB (literal) - Encoding T1, A1
+ bool EmulateLDRSBLiteral(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.80 LDRSB (register) - Encoding T1, T2, A1
+ bool EmulateLDRSBRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.81 LDRSBT
+ bool EmulateLDRSBT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.82 LDRSH (immediate) - Encoding T1, T2, A1
+ bool EmulateLDRSHImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.83 LDRSH (literal) - Encoding T1, A1
+ bool EmulateLDRSHLiteral(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.84 LDRSH (register) - Encoding T1, T2, A1
+ bool EmulateLDRSHRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.85 LDRSHT
+ bool EmulateLDRSHT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.86
+ bool EmulateLDRT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // STORE FUNCTIONS
+
+ // A8.6.189 STM/STMIA/STMEA
+ bool EmulateSTM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.190 STMDA/STMED
+ bool EmulateSTMDA(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.191 STMDB/STMFD
+ bool EmulateSTMDB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.192 STMIB/STMFA
+ bool EmulateSTMIB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.193 STR (immediate, Thumb)
+ bool EmulateSTRThumb(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.194 STR (immediate, ARM)
+ bool EmulateSTRImmARM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.195 STR (register)
+ bool EmulateSTRRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.196 STRB (immediate, Thumb)
+ bool EmulateSTRBThumb(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.197 STRB (immediate, ARM)
+ bool EmulateSTRBImmARM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.198 STRB (register)
+ bool EmulateSTRBReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.199 STRBT
+ bool EmulateSTRBT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.200 STRD (immediate)
+ bool EmulateSTRDImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.201 STRD (register)
+ bool EmulateSTRDReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.202 STREX
+ bool EmulateSTREX(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.203 STREXB
+ bool EmulateSTREXB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.204 STREXD
+ bool EmulateSTREXD(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.205 STREXH
+ bool EmulateSTREXH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.206 STRH (immediate, Thumb)
+ bool EmulateSTRHImmThumb(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.207 STRH (immediate, ARM)
+ bool EmulateSTRHImmARM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.208 STRH (register)
+ bool EmulateSTRHRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.209 STRHT
+ bool EmulateSTRHT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.210 STRT
+ bool EmulateSTRT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.1 ADC (immediate)
+ bool EmulateADCImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.2 ADC (Register)
+ bool EmulateADCReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.10 ADR
+ bool EmulateADR(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.11 AND (immediate)
+ bool EmulateANDImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.12 AND (register)
+ bool EmulateANDReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.19 BIC (immediate)
+ bool EmulateBICImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.20 BIC (register)
+ bool EmulateBICReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.26 BXJ
+ bool EmulateBXJ(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.32 CMN (immediate)
+ bool EmulateCMNImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.33 CMN (register)
+ bool EmulateCMNReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.44 EOR (immediate)
+ bool EmulateEORImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.45 EOR (register)
+ bool EmulateEORReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.105 MUL
+ bool EmulateMUL(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.106 MVN (immediate)
+ bool EmulateMVNImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.107 MVN (register)
+ bool EmulateMVNReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.113 ORR (immediate)
+ bool EmulateORRImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.114 ORR (register)
+ bool EmulateORRReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.117 PLD (immediate, literal) - Encoding T1, T2, T3, A1
+ bool EmulatePLDImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.119 PLI (immediate,literal) - Encoding T3, A1
+ bool EmulatePLIImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.120 PLI (register) - Encoding T1, A1
+ bool EmulatePLIRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.141 RSB (immediate)
+ bool EmulateRSBImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.142 RSB (register)
+ bool EmulateRSBReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.144 RSC (immediate)
+ bool EmulateRSCImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.145 RSC (register)
+ bool EmulateRSCReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.150 SBC (immediate)
+ bool EmulateSBCImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.151 SBC (register)
+ bool EmulateSBCReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.211 SUB (immediate, Thumb)
+ bool EmulateSUBImmThumb(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.212 SUB (immediate, ARM)
+ bool EmulateSUBImmARM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.213 SUB (register)
+ bool EmulateSUBReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.214 SUB (register-shifted register)
+ bool EmulateSUBRegShift(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.222 SXTB - Encoding T1
+ bool EmulateSXTB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.224 SXTH - EncodingT1
+ bool EmulateSXTH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.227 TEQ (immediate) - Encoding A1
+ bool EmulateTEQImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.228 TEQ (register) - Encoding A1
+ bool EmulateTEQReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.230 TST (immediate) - Encoding A1
+ bool EmulateTSTImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.231 TST (register) - Encoding T1, A1
+ bool EmulateTSTReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.262 UXTB - Encoding T1
+ bool EmulateUXTB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.264 UXTH - Encoding T1
+ bool EmulateUXTH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // B6.1.8 RFE
+ bool EmulateRFE(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.319 VLDM
+ bool EmulateVLDM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.399 VSTM
+ bool EmulateVSTM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.307 VLD1 (multiple single elements)
+ bool EmulateVLD1Multiple(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.308 VLD1 (single element to one lane)
+ bool EmulateVLD1Single(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.309 VLD1 (single element to all lanes)
+ bool EmulateVLD1SingleAll(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.391 VST1 (multiple single elements)
+ bool EmulateVST1Multiple(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.392 VST1 (single element from one lane)
+ bool EmulateVST1Single(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.317 VLDR
+ bool EmulateVLDR(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.400 VSTR
+ bool EmulateVSTR(const uint32_t opcode, const ARMEncoding encoding);
+
+ // B6.2.13 SUBS PC, LR and related instructions
+ bool EmulateSUBSPcLrEtc(const uint32_t opcode, const ARMEncoding encoding);
- // Typedef for the callback function used during the emulation.
- // Pass along (ARMEncoding)encoding as the callback data.
- typedef enum
- {
- eSize16,
- eSize32
- } ARMInstrSize;
-
- typedef struct
- {
- uint32_t mask;
- uint32_t value;
- uint32_t variants;
- EmulateInstructionARM::ARMEncoding encoding;
- uint32_t vfp_variants;
- ARMInstrSize size;
- bool (EmulateInstructionARM::*callback) (const uint32_t opcode, const EmulateInstructionARM::ARMEncoding encoding);
- const char *name;
- } ARMOpcode;
-
- uint32_t
- GetFramePointerRegisterNumber () const;
-
- uint32_t
- GetFramePointerDWARFRegisterNumber () const;
-
- static ARMOpcode*
- GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t isa_mask);
-
- static ARMOpcode*
- GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t isa_mask);
-
- // A8.6.123 PUSH
- bool
- EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.122 POP
- bool
- EmulatePOP (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.8 ADD (SP plus immediate)
- bool
- EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.97 MOV (register) -- Rd == r7|ip and Rm == sp
- bool
- EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.97 MOV (register) -- move from r8-r15 to r0-r7
- bool
- EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.59 LDR (literal)
- bool
- EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.8 ADD (SP plus immediate)
- bool
- EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.9 ADD (SP plus register)
- bool
- EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.23 BL, BLX (immediate)
- bool
- EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.24 BLX (register)
- bool
- EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.25 BX
- bool
- EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.26 BXJ
- bool
- EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.212 SUB (immediate, ARM) -- Rd == r7 and Rm == ip
- bool
- EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.215 SUB (SP minus immediate) -- Rd == ip
- bool
- EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.215 SUB (SP minus immediate)
- bool
- EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.216 SUB (SP minus register)
- bool
- EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.194 STR (immediate, ARM) -- Rn == sp
- bool
- EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.355 VPUSH
- bool
- EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.354 VPOP
- bool
- EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.218 SVC (previously SWI)
- bool
- EmulateSVC (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.50 IT
- bool
- EmulateIT (const uint32_t opcode, const ARMEncoding encoding);
-
- // NOP
- bool
- EmulateNop (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.16 B
- bool
- EmulateB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.27 CBNZ, CBZ
- bool
- EmulateCB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.226 TBB, TBH
- bool
- EmulateTB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.4 ADD (immediate, Thumb)
- bool
- EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.5 ADD (immediate, ARM)
- bool
- EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.6 ADD (register)
- bool
- EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.7 ADD (register-shifted register)
- bool
- EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.97 MOV (register)
- bool
- EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.96 MOV (immediate)
- bool
- EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.35 CMP (immediate)
- bool
- EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.36 CMP (register)
- bool
- EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.14 ASR (immediate)
- bool
- EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.15 ASR (register)
- bool
- EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.88 LSL (immediate)
- bool
- EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.89 LSL (register)
- bool
- EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.90 LSR (immediate)
- bool
- EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.91 LSR (register)
- bool
- EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.139 ROR (immediate)
- bool
- EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.140 ROR (register)
- bool
- EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.141 RRX
- bool
- EmulateRRX (const uint32_t opcode, const ARMEncoding encoding);
-
- // Helper method for ASR, LSL, LSR, ROR (immediate), and RRX
- bool
- EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type);
-
- // Helper method for ASR, LSL, LSR, and ROR (register)
- bool
- EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type);
-
- // LOAD FUNCTIONS
-
- // A8.6.53 LDM/LDMIA/LDMFD
- bool
- EmulateLDM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.54 LDMDA/LDMFA
- bool
- EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.55 LDMDB/LDMEA
- bool
- EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.56 LDMIB/LDMED
- bool
- EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.57 LDR (immediate, Thumb) -- Encoding T1
- bool
- EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.58 LDR (immediate, ARM) - Encoding A1
- bool
- EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.59 LDR (literal)
- bool
- EmulateLDRLiteral (const uint32_t, const ARMEncoding encoding);
-
- // A8.6.60 LDR (register) - Encoding T1, T2, A1
- bool
- EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.61 LDRB (immediate, Thumb) - Encoding T1, T2, T3
- bool
- EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.62 LDRB (immediate, ARM)
- bool
- EmulateLDRBImmediateARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.63 LDRB (literal) - Encoding T1, A1
- bool
- EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.64 LDRB (register) - Encoding T1, T2, A1
- bool
- EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.65 LDRBT
- bool
- EmulateLDRBT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.66 LDRD (immediate)
- bool
- EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.67
- bool
- EmulateLDRDLiteral (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.68 LDRD (register)
- bool
- EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.69 LDREX
- bool
- EmulateLDREX (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.70 LDREXB
- bool
- EmulateLDREXB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.71 LDREXD
- bool
- EmulateLDREXD (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.72 LDREXH
- bool
- EmulateLDREXH (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.73 LDRH (immediate, Thumb) - Encoding T1, T2, T3
- bool
- EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.74 LDRS (immediate, ARM)
- bool
- EmulateLDRHImmediateARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.75 LDRH (literal) - Encoding T1, A1
- bool
- EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.76 LDRH (register) - Encoding T1, T2, A1
- bool
- EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.77 LDRHT
- bool
- EmulateLDRHT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.78 LDRSB (immediate) - Encoding T1, T2, A1
- bool
- EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.79 LDRSB (literal) - Encoding T1, A1
- bool
- EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.80 LDRSB (register) - Encoding T1, T2, A1
- bool
- EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.81 LDRSBT
- bool
- EmulateLDRSBT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.82 LDRSH (immediate) - Encoding T1, T2, A1
- bool
- EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.83 LDRSH (literal) - Encoding T1, A1
- bool
- EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.84 LDRSH (register) - Encoding T1, T2, A1
- bool
- EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.85 LDRSHT
- bool
- EmulateLDRSHT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.86
- bool
- EmulateLDRT (const uint32_t opcode, const ARMEncoding encoding);
-
-
- // STORE FUNCTIONS
-
- // A8.6.189 STM/STMIA/STMEA
- bool
- EmulateSTM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.190 STMDA/STMED
- bool
- EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.191 STMDB/STMFD
- bool
- EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.192 STMIB/STMFA
- bool
- EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.193 STR (immediate, Thumb)
- bool
- EmulateSTRThumb(const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.194 STR (immediate, ARM)
- bool
- EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.195 STR (register)
- bool
- EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.196 STRB (immediate, Thumb)
- bool
- EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.197 STRB (immediate, ARM)
- bool
- EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.198 STRB (register)
- bool
- EmulateSTRBReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.199 STRBT
- bool
- EmulateSTRBT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.200 STRD (immediate)
- bool
- EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.201 STRD (register)
- bool
- EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.202 STREX
- bool
- EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.203 STREXB
- bool
- EmulateSTREXB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.204 STREXD
- bool
- EmulateSTREXD (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.205 STREXH
- bool
- EmulateSTREXH (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.206 STRH (immediate, Thumb)
- bool
- EmulateSTRHImmThumb (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.207 STRH (immediate, ARM)
- bool
- EmulateSTRHImmARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.208 STRH (register)
- bool
- EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.209 STRHT
- bool
- EmulateSTRHT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.210 STRT
- bool
- EmulateSTRT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.1 ADC (immediate)
- bool
- EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.2 ADC (Register)
- bool
- EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.10 ADR
- bool
- EmulateADR (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.11 AND (immediate)
- bool
- EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.12 AND (register)
- bool
- EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.19 BIC (immediate)
- bool
- EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.20 BIC (register)
- bool
- EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.26 BXJ
- bool
- EmulateBXJ (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.32 CMN (immediate)
- bool
- EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.33 CMN (register)
- bool
- EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.44 EOR (immediate)
- bool
- EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.45 EOR (register)
- bool
- EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.105 MUL
- bool
- EmulateMUL (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.106 MVN (immediate)
- bool
- EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.107 MVN (register)
- bool
- EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.113 ORR (immediate)
- bool
- EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.114 ORR (register)
- bool
- EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.117 PLD (immediate, literal) - Encoding T1, T2, T3, A1
- bool
- EmulatePLDImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.119 PLI (immediate,literal) - Encoding T3, A1
- bool
- EmulatePLIImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.120 PLI (register) - Encoding T1, A1
- bool
- EmulatePLIRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.141 RSB (immediate)
- bool
- EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.142 RSB (register)
- bool
- EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.144 RSC (immediate)
- bool
- EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.145 RSC (register)
- bool
- EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.150 SBC (immediate)
- bool
- EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.151 SBC (register)
- bool
- EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.211 SUB (immediate, Thumb)
- bool
- EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.212 SUB (immediate, ARM)
- bool
- EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.213 SUB (register)
- bool
- EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.214 SUB (register-shifted register)
- bool
- EmulateSUBRegShift (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.222 SXTB - Encoding T1
- bool
- EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.224 SXTH - EncodingT1
- bool
- EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.227 TEQ (immediate) - Encoding A1
- bool
- EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.228 TEQ (register) - Encoding A1
- bool
- EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.230 TST (immediate) - Encoding A1
- bool
- EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.231 TST (register) - Encoding T1, A1
- bool
- EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.262 UXTB - Encoding T1
- bool
- EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.264 UXTH - Encoding T1
- bool
- EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding);
-
- // B6.1.8 RFE
- bool
- EmulateRFE (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.319 VLDM
- bool
- EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.399 VSTM
- bool
- EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.307 VLD1 (multiple single elements)
- bool
- EmulateVLD1Multiple (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.308 VLD1 (single element to one lane)
- bool
- EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.309 VLD1 (single element to all lanes)
- bool
- EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.391 VST1 (multiple single elements)
- bool
- EmulateVST1Multiple (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.392 VST1 (single element from one lane)
- bool
- EmulateVST1Single (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.317 VLDR
- bool
- EmulateVLDR (const uint32_t opcode, const ARMEncoding encoding);
-
-
- // A8.6.400 VSTR
- bool
- EmulateVSTR (const uint32_t opcode, const ARMEncoding encoding);
-
- // B6.2.13 SUBS PC, LR and related instructions
- bool
- EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding);
-
- uint32_t m_arm_isa;
- Mode m_opcode_mode;
- uint32_t m_opcode_cpsr;
- uint32_t m_new_inst_cpsr; // This can get updated by the opcode.
- ITSession m_it_session;
- bool m_ignore_conditions;
+ uint32_t m_arm_isa;
+ Mode m_opcode_mode;
+ uint32_t m_opcode_cpsr;
+ uint32_t m_new_inst_cpsr; // This can get updated by the opcode.
+ ITSession m_it_session;
+ bool m_ignore_conditions;
};
-} // namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_EmulateInstructionARM_h_
+#endif // lldb_EmulateInstructionARM_h_
diff --git a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
index 547db44ebfb2..9ceeb76c6f5e 100644
--- a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -13,406 +13,341 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
-#include "lldb/Target/StackFrame.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
#include "Utility/ARM_DWARF_Registers.h"
using namespace lldb;
using namespace lldb_private;
-EmulationStateARM::EmulationStateARM () :
- m_gpr (),
- m_vfp_regs (),
- m_memory ()
-{
- ClearPseudoRegisters();
+EmulationStateARM::EmulationStateARM() : m_gpr(), m_vfp_regs(), m_memory() {
+ ClearPseudoRegisters();
}
-EmulationStateARM::~EmulationStateARM ()
-{
-}
+EmulationStateARM::~EmulationStateARM() {}
-bool
-EmulationStateARM::LoadPseudoRegistersFromFrame (StackFrame &frame)
-{
- RegisterContext *reg_ctx = frame.GetRegisterContext().get();
- bool success = true;
- uint32_t reg_num;
-
- for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i)
- {
- reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i);
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister (reg_info, reg_value))
- {
- m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32();
- }
- else
- success = false;
- }
-
- for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i)
- {
- reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i);
- RegisterValue reg_value;
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
-
- if (reg_ctx->ReadRegister (reg_info, reg_value))
- {
- uint64_t value = reg_value.GetAsUInt64();
- uint32_t idx = i - dwarf_d0;
- if (i < 16)
- {
- m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
- m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
- }
- else
- m_vfp_regs.d_regs[idx - 16] = value;
- }
- else
- success = false;
- }
-
- return success;
+bool EmulationStateARM::LoadPseudoRegistersFromFrame(StackFrame &frame) {
+ RegisterContext *reg_ctx = frame.GetRegisterContext().get();
+ bool success = true;
+ uint32_t reg_num;
+
+ for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i) {
+ reg_num =
+ reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32();
+ } else
+ success = false;
+ }
+
+ for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i) {
+ reg_num =
+ reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
+ RegisterValue reg_value;
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ uint64_t value = reg_value.GetAsUInt64();
+ uint32_t idx = i - dwarf_d0;
+ if (i < 16) {
+ m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
+ m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
+ } else
+ m_vfp_regs.d_regs[idx - 16] = value;
+ } else
+ success = false;
+ }
+
+ return success;
}
-
-bool
-EmulationStateARM::StorePseudoRegisterValue (uint32_t reg_num, uint64_t value)
-{
- if ((dwarf_r0 <= reg_num) && (reg_num <= dwarf_cpsr))
- m_gpr[reg_num - dwarf_r0] = (uint32_t) value;
- else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31))
- {
- uint32_t idx = reg_num - dwarf_s0;
- m_vfp_regs.s_regs[idx] = (uint32_t)value;
- }
- else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31))
- {
- uint32_t idx = reg_num - dwarf_d0;
- if (idx < 16)
- {
- m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
- m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
- }
- else
- m_vfp_regs.d_regs[idx - 16] = value;
- }
- else
- return false;
-
- return true;
+
+bool EmulationStateARM::StorePseudoRegisterValue(uint32_t reg_num,
+ uint64_t value) {
+ if ((dwarf_r0 <= reg_num) && (reg_num <= dwarf_cpsr))
+ m_gpr[reg_num - dwarf_r0] = (uint32_t)value;
+ else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
+ uint32_t idx = reg_num - dwarf_s0;
+ m_vfp_regs.s_regs[idx] = (uint32_t)value;
+ } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
+ uint32_t idx = reg_num - dwarf_d0;
+ if (idx < 16) {
+ m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
+ m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
+ } else
+ m_vfp_regs.d_regs[idx - 16] = value;
+ } else
+ return false;
+
+ return true;
}
-
-uint64_t
-EmulationStateARM::ReadPseudoRegisterValue (uint32_t reg_num, bool &success)
-{
- uint64_t value = 0;
- success = true;
-
- if ((dwarf_r0 <= reg_num) && (reg_num <= dwarf_cpsr))
- value = m_gpr[reg_num - dwarf_r0];
- else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31))
- {
- uint32_t idx = reg_num - dwarf_s0;
- value = m_vfp_regs.d_regs[idx];
- }
- else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31))
- {
- uint32_t idx = reg_num - dwarf_d0;
- if (idx < 16)
- value = (uint64_t)m_vfp_regs.s_regs[idx * 2] | ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] >> 32);
- else
- value = m_vfp_regs.d_regs[idx - 16];
- }
+
+uint64_t EmulationStateARM::ReadPseudoRegisterValue(uint32_t reg_num,
+ bool &success) {
+ uint64_t value = 0;
+ success = true;
+
+ if ((dwarf_r0 <= reg_num) && (reg_num <= dwarf_cpsr))
+ value = m_gpr[reg_num - dwarf_r0];
+ else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
+ uint32_t idx = reg_num - dwarf_s0;
+ value = m_vfp_regs.d_regs[idx];
+ } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
+ uint32_t idx = reg_num - dwarf_d0;
+ if (idx < 16)
+ value = (uint64_t)m_vfp_regs.s_regs[idx * 2] |
+ ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] >> 32);
else
- success = false;
-
- return value;
-}
-
-void
-EmulationStateARM::ClearPseudoRegisters ()
-{
- for (int i = 0; i < 17; ++i)
- m_gpr[i] = 0;
-
- for (int i = 0; i < 32; ++i)
- m_vfp_regs.s_regs[i] = 0;
-
- for (int i = 0; i < 16; ++i)
- m_vfp_regs.d_regs[i] = 0;
+ value = m_vfp_regs.d_regs[idx - 16];
+ } else
+ success = false;
+
+ return value;
}
-void
-EmulationStateARM::ClearPseudoMemory ()
-{
- m_memory.clear();
+void EmulationStateARM::ClearPseudoRegisters() {
+ for (int i = 0; i < 17; ++i)
+ m_gpr[i] = 0;
+
+ for (int i = 0; i < 32; ++i)
+ m_vfp_regs.s_regs[i] = 0;
+
+ for (int i = 0; i < 16; ++i)
+ m_vfp_regs.d_regs[i] = 0;
}
-
-bool
-EmulationStateARM::StoreToPseudoAddress (lldb::addr_t p_address, uint32_t value)
-{
- m_memory[p_address] = value;
- return true;
+
+void EmulationStateARM::ClearPseudoMemory() { m_memory.clear(); }
+
+bool EmulationStateARM::StoreToPseudoAddress(lldb::addr_t p_address,
+ uint32_t value) {
+ m_memory[p_address] = value;
+ return true;
}
-
-uint32_t
-EmulationStateARM::ReadFromPseudoAddress (lldb::addr_t p_address, bool &success)
-{
- std::map<lldb::addr_t,uint32_t>::iterator pos;
- uint32_t ret_val = 0;
-
- success = true;
- pos = m_memory.find(p_address);
- if (pos != m_memory.end())
- ret_val = pos->second;
- else
- success = false;
-
- return ret_val;
+
+uint32_t EmulationStateARM::ReadFromPseudoAddress(lldb::addr_t p_address,
+ bool &success) {
+ std::map<lldb::addr_t, uint32_t>::iterator pos;
+ uint32_t ret_val = 0;
+
+ success = true;
+ pos = m_memory.find(p_address);
+ if (pos != m_memory.end())
+ ret_val = pos->second;
+ else
+ success = false;
+
+ return ret_val;
}
-size_t
-EmulationStateARM::ReadPseudoMemory (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t length)
-{
- if (!baton)
- return 0;
-
- bool success = true;
- EmulationStateARM *pseudo_state = (EmulationStateARM *) baton;
- if (length <= 4)
- {
- uint32_t value = pseudo_state->ReadFromPseudoAddress (addr, success);
- if (!success)
- return 0;
-
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- value = llvm::ByteSwap_32 (value);
- *((uint32_t *) dst) = value;
- }
- else if (length == 8)
- {
- uint32_t value1 = pseudo_state->ReadFromPseudoAddress (addr, success);
- if (!success)
- return 0;
-
- uint32_t value2 = pseudo_state->ReadFromPseudoAddress (addr + 4, success);
- if (!success)
- return 0;
-
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- {
- value1 = llvm::ByteSwap_32 (value1);
- value2 = llvm::ByteSwap_32 (value2);
- }
- ((uint32_t *) dst)[0] = value1;
- ((uint32_t *) dst)[1] = value2;
- }
- else
- success = false;
-
- if (success)
- return length;
-
+size_t EmulationStateARM::ReadPseudoMemory(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
+ size_t length) {
+ if (!baton)
return 0;
-}
-
-size_t
-EmulationStateARM::WritePseudoMemory (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length)
-{
- if (!baton)
- return 0;
-
- EmulationStateARM *pseudo_state = (EmulationStateARM *) baton;
-
- if (length <= 4)
- {
- uint32_t value = *((const uint32_t *) dst);
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- value = llvm::ByteSwap_32 (value);
-
- pseudo_state->StoreToPseudoAddress (addr, value);
- return length;
- }
- else if (length == 8)
- {
- uint32_t value1 = ((const uint32_t *) dst)[0];
- uint32_t value2 = ((const uint32_t *) dst)[1];
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- {
- value1 = llvm::ByteSwap_32 (value1);
- value2 = llvm::ByteSwap_32 (value2);
- }
-
- pseudo_state->StoreToPseudoAddress (addr, value1);
- pseudo_state->StoreToPseudoAddress (addr + 4, value2);
- return length;
+
+ bool success = true;
+ EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
+ if (length <= 4) {
+ uint32_t value = pseudo_state->ReadFromPseudoAddress(addr, success);
+ if (!success)
+ return 0;
+
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ value = llvm::ByteSwap_32(value);
+ *((uint32_t *)dst) = value;
+ } else if (length == 8) {
+ uint32_t value1 = pseudo_state->ReadFromPseudoAddress(addr, success);
+ if (!success)
+ return 0;
+
+ uint32_t value2 = pseudo_state->ReadFromPseudoAddress(addr + 4, success);
+ if (!success)
+ return 0;
+
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
+ value1 = llvm::ByteSwap_32(value1);
+ value2 = llvm::ByteSwap_32(value2);
}
+ ((uint32_t *)dst)[0] = value1;
+ ((uint32_t *)dst)[1] = value2;
+ } else
+ success = false;
+
+ if (success)
+ return length;
+
+ return 0;
+}
+size_t EmulationStateARM::WritePseudoMemory(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context, lldb::addr_t addr,
+ const void *dst, size_t length) {
+ if (!baton)
return 0;
+
+ EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
+
+ if (length <= 4) {
+ uint32_t value = *((const uint32_t *)dst);
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ value = llvm::ByteSwap_32(value);
+
+ pseudo_state->StoreToPseudoAddress(addr, value);
+ return length;
+ } else if (length == 8) {
+ uint32_t value1 = ((const uint32_t *)dst)[0];
+ uint32_t value2 = ((const uint32_t *)dst)[1];
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
+ value1 = llvm::ByteSwap_32(value1);
+ value2 = llvm::ByteSwap_32(value2);
+ }
+
+ pseudo_state->StoreToPseudoAddress(addr, value1);
+ pseudo_state->StoreToPseudoAddress(addr + 4, value2);
+ return length;
+ }
+
+ return 0;
}
-
-bool
-EmulationStateARM::ReadPseudoRegister (EmulateInstruction *instruction,
- void *baton,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value)
-{
- if (!baton || !reg_info)
- return false;
-
- bool success = true;
- EmulationStateARM *pseudo_state = (EmulationStateARM *) baton;
- const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
- assert (dwarf_reg_num != LLDB_INVALID_REGNUM);
- uint64_t reg_uval = pseudo_state->ReadPseudoRegisterValue (dwarf_reg_num, success);
-
- if (success)
- success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
- return success;
-
+
+bool EmulationStateARM::ReadPseudoRegister(
+ EmulateInstruction *instruction, void *baton,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value) {
+ if (!baton || !reg_info)
+ return false;
+
+ bool success = true;
+ EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
+ const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
+ assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
+ uint64_t reg_uval =
+ pseudo_state->ReadPseudoRegisterValue(dwarf_reg_num, success);
+
+ if (success)
+ success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
+ return success;
}
-
-bool
-EmulationStateARM::WritePseudoRegister (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value)
-{
- if (!baton || !reg_info)
- return false;
- EmulationStateARM *pseudo_state = (EmulationStateARM *) baton;
- const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
- assert (dwarf_reg_num != LLDB_INVALID_REGNUM);
- return pseudo_state->StorePseudoRegisterValue (dwarf_reg_num, reg_value.GetAsUInt64());
+bool EmulationStateARM::WritePseudoRegister(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value) {
+ if (!baton || !reg_info)
+ return false;
+
+ EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
+ const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
+ assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
+ return pseudo_state->StorePseudoRegisterValue(dwarf_reg_num,
+ reg_value.GetAsUInt64());
}
-
-bool
-EmulationStateARM::CompareState (EmulationStateARM &other_state)
-{
- bool match = true;
-
- for (int i = 0; match && i < 17; ++i)
- {
- if (m_gpr[i] != other_state.m_gpr[i])
- match = false;
- }
-
- for (int i = 0; match && i < 32; ++i)
- {
- if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
- match = false;
- }
-
- for (int i = 0; match && i < 16; ++i)
- {
- if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
- match = false;
- }
-
- return match;
+
+bool EmulationStateARM::CompareState(EmulationStateARM &other_state) {
+ bool match = true;
+
+ for (int i = 0; match && i < 17; ++i) {
+ if (m_gpr[i] != other_state.m_gpr[i])
+ match = false;
+ }
+
+ for (int i = 0; match && i < 32; ++i) {
+ if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
+ match = false;
+ }
+
+ for (int i = 0; match && i < 16; ++i) {
+ if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
+ match = false;
+ }
+
+ return match;
}
-bool
-EmulationStateARM::LoadStateFromDictionary (OptionValueDictionary *test_data)
-{
- static ConstString memory_key ("memory");
- static ConstString registers_key ("registers");
-
- if (!test_data)
+bool EmulationStateARM::LoadStateFromDictionary(
+ OptionValueDictionary *test_data) {
+ static ConstString memory_key("memory");
+ static ConstString registers_key("registers");
+
+ if (!test_data)
+ return false;
+
+ OptionValueSP value_sp = test_data->GetValueForKey(memory_key);
+
+ // Load memory, if present.
+
+ if (value_sp.get() != NULL) {
+ static ConstString address_key("address");
+ static ConstString data_key("data");
+ uint64_t start_address = 0;
+
+ OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
+ value_sp = mem_dict->GetValueForKey(address_key);
+ if (value_sp.get() == NULL)
+ return false;
+ else
+ start_address = value_sp->GetUInt64Value();
+
+ value_sp = mem_dict->GetValueForKey(data_key);
+ OptionValueArray *mem_array = value_sp->GetAsArray();
+ if (!mem_array)
+ return false;
+
+ uint32_t num_elts = mem_array->GetSize();
+ uint32_t address = (uint32_t)start_address;
+
+ for (uint32_t i = 0; i < num_elts; ++i) {
+ value_sp = mem_array->GetValueAtIndex(i);
+ if (value_sp.get() == NULL)
return false;
-
- OptionValueSP value_sp = test_data->GetValueForKey (memory_key);
-
- // Load memory, if present.
-
- if (value_sp.get() != NULL)
- {
- static ConstString address_key ("address");
- static ConstString data_key ("data");
- uint64_t start_address = 0;
-
- OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
- value_sp = mem_dict->GetValueForKey (address_key);
- if (value_sp.get() == NULL)
- return false;
- else
- start_address = value_sp->GetUInt64Value ();
-
- value_sp = mem_dict->GetValueForKey (data_key);
- OptionValueArray *mem_array = value_sp->GetAsArray();
- if (!mem_array)
- return false;
-
- uint32_t num_elts = mem_array->GetSize();
- uint32_t address = (uint32_t) start_address;
-
- for (uint32_t i = 0; i < num_elts; ++i)
- {
- value_sp = mem_array->GetValueAtIndex (i);
- if (value_sp.get() == NULL)
- return false;
- uint64_t value = value_sp->GetUInt64Value();
- StoreToPseudoAddress (address, value);
- address = address + 4;
- }
+ uint64_t value = value_sp->GetUInt64Value();
+ StoreToPseudoAddress(address, value);
+ address = address + 4;
}
-
- value_sp = test_data->GetValueForKey (registers_key);
+ }
+
+ value_sp = test_data->GetValueForKey(registers_key);
+ if (value_sp.get() == NULL)
+ return false;
+
+ // Load General Registers
+
+ OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
+
+ StreamString sstr;
+ for (int i = 0; i < 16; ++i) {
+ sstr.Clear();
+ sstr.Printf("r%d", i);
+ ConstString reg_name(sstr.GetString());
+ value_sp = reg_dict->GetValueForKey(reg_name);
if (value_sp.get() == NULL)
- return false;
+ return false;
+ uint64_t reg_value = value_sp->GetUInt64Value();
+ StorePseudoRegisterValue(dwarf_r0 + i, reg_value);
+ }
-
- // Load General Registers
-
- OptionValueDictionary *reg_dict = value_sp->GetAsDictionary ();
-
- StreamString sstr;
- for (int i = 0; i < 16; ++i)
- {
- sstr.Clear();
- sstr.Printf ("r%d", i);
- ConstString reg_name (sstr.GetData());
- value_sp = reg_dict->GetValueForKey (reg_name);
- if (value_sp.get() == NULL)
- return false;
- uint64_t reg_value = value_sp->GetUInt64Value();
- StorePseudoRegisterValue (dwarf_r0 + i, reg_value);
- }
-
- static ConstString cpsr_name ("cpsr");
- value_sp = reg_dict->GetValueForKey (cpsr_name);
+ static ConstString cpsr_name("cpsr");
+ value_sp = reg_dict->GetValueForKey(cpsr_name);
+ if (value_sp.get() == NULL)
+ return false;
+ StorePseudoRegisterValue(dwarf_cpsr, value_sp->GetUInt64Value());
+
+ // Load s/d Registers
+ for (int i = 0; i < 32; ++i) {
+ sstr.Clear();
+ sstr.Printf("s%d", i);
+ ConstString reg_name(sstr.GetString());
+ value_sp = reg_dict->GetValueForKey(reg_name);
if (value_sp.get() == NULL)
- return false;
- StorePseudoRegisterValue (dwarf_cpsr, value_sp->GetUInt64Value());
-
- // Load s/d Registers
- for (int i = 0; i < 32; ++i)
- {
- sstr.Clear();
- sstr.Printf ("s%d", i);
- ConstString reg_name (sstr.GetData());
- value_sp = reg_dict->GetValueForKey (reg_name);
- if (value_sp.get() == NULL)
- return false;
- uint64_t reg_value = value_sp->GetUInt64Value();
- StorePseudoRegisterValue (dwarf_s0 + i, reg_value);
- }
+ return false;
+ uint64_t reg_value = value_sp->GetUInt64Value();
+ StorePseudoRegisterValue(dwarf_s0 + i, reg_value);
+ }
- return true;
+ return true;
}
-
diff --git a/source/Plugins/Instruction/ARM/EmulationStateARM.h b/source/Plugins/Instruction/ARM/EmulationStateARM.h
index e82ef94b5a01..f27f4755a177 100644
--- a/source/Plugins/Instruction/ARM/EmulationStateARM.h
+++ b/source/Plugins/Instruction/ARM/EmulationStateARM.h
@@ -16,81 +16,65 @@
#include "lldb/Core/Opcode.h"
class EmulationStateARM {
-public:
-
- EmulationStateARM ();
-
- virtual
- ~EmulationStateARM ();
-
- bool
- StorePseudoRegisterValue (uint32_t reg_num, uint64_t value);
-
- uint64_t
- ReadPseudoRegisterValue (uint32_t reg_num, bool &success);
-
- bool
- StoreToPseudoAddress (lldb::addr_t p_address, uint32_t value);
-
- uint32_t
- ReadFromPseudoAddress (lldb::addr_t p_address, bool &success);
-
- void
- ClearPseudoRegisters ();
-
- void
- ClearPseudoMemory ();
-
- bool
- LoadPseudoRegistersFromFrame (lldb_private::StackFrame &frame);
-
- bool
- LoadStateFromDictionary (lldb_private::OptionValueDictionary *test_data);
-
- bool
- CompareState (EmulationStateARM &other_state);
-
- static size_t
- ReadPseudoMemory (lldb_private::EmulateInstruction *instruction,
+public:
+ EmulationStateARM();
+
+ virtual ~EmulationStateARM();
+
+ bool StorePseudoRegisterValue(uint32_t reg_num, uint64_t value);
+
+ uint64_t ReadPseudoRegisterValue(uint32_t reg_num, bool &success);
+
+ bool StoreToPseudoAddress(lldb::addr_t p_address, uint32_t value);
+
+ uint32_t ReadFromPseudoAddress(lldb::addr_t p_address, bool &success);
+
+ void ClearPseudoRegisters();
+
+ void ClearPseudoMemory();
+
+ bool LoadPseudoRegistersFromFrame(lldb_private::StackFrame &frame);
+
+ bool LoadStateFromDictionary(lldb_private::OptionValueDictionary *test_data);
+
+ bool CompareState(EmulationStateARM &other_state);
+
+ static size_t
+ ReadPseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length);
+
+ static size_t
+ WritePseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst, size_t length);
+
+ static bool ReadPseudoRegister(lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value);
+
+ static bool
+ WritePseudoRegister(lldb_private::EmulateInstruction *instruction,
void *baton,
const lldb_private::EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t length);
-
- static size_t
- WritePseudoMemory (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length);
-
- static bool
- ReadPseudoRegister (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value);
-
- static bool
- WritePseudoRegister (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::EmulateInstruction::Context &context,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value);
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value);
+
private:
- uint32_t m_gpr[17];
- struct _sd_regs
- {
- uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15
-
- uint64_t d_regs[16]; // dregs 16-31
-
- } m_vfp_regs;
-
- std::map<lldb::addr_t, uint32_t> m_memory; // Eventually will want to change uint32_t to a data buffer heap type.
-
- DISALLOW_COPY_AND_ASSIGN (EmulationStateARM);
+ uint32_t m_gpr[17];
+ struct _sd_regs {
+ uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15
+
+ uint64_t d_regs[16]; // dregs 16-31
+
+ } m_vfp_regs;
+
+ std::map<lldb::addr_t, uint32_t> m_memory; // Eventually will want to change
+ // uint32_t to a data buffer heap
+ // type.
+
+ DISALLOW_COPY_AND_ASSIGN(EmulationStateARM);
};
-#endif // lldb_EmulationStateARM_h_
+#endif // lldb_EmulationStateARM_h_
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
index ea67928280d3..43f23097c0d9 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
@@ -1,4 +1,4 @@
-//===-- EmulateInstructionARM64.cpp -------------------------------*- C++ -*-===//
+//===-- EmulateInstructionARM64.cpp ------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,8 +11,8 @@
#include <stdlib.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"
@@ -20,7 +20,24 @@
#include "Plugins/Process/Utility/ARMDefines.h"
#include "Plugins/Process/Utility/ARMUtils.h"
-#include "Utility/ARM64_DWARF_Registers.h"
+#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
+
+#define GPR_OFFSET(idx) ((idx)*8)
+#define GPR_OFFSET_NAME(reg) 0
+#define FPU_OFFSET(idx) ((idx)*16)
+#define FPU_OFFSET_NAME(reg) 0
+#define EXC_OFFSET_NAME(reg) 0
+#define DBG_OFFSET_NAME(reg) 0
+#define DBG_OFFSET_NAME(reg) 0
+#define DEFINE_DBG(re, y) \
+ "na", nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, \
+ nullptr, nullptr, nullptr, 0
+
+#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
+
+#include "Plugins/Process/Utility/RegisterInfos_arm64.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
@@ -31,15 +48,22 @@
using namespace lldb;
using namespace lldb_private;
-#define No_VFP 0
-#define VFPv1 (1u << 1)
-#define VFPv2 (1u << 2)
-#define VFPv3 (1u << 3)
+static bool LLDBTableGetRegisterInfo(uint32_t reg_num, RegisterInfo &reg_info) {
+ if (reg_num >= llvm::array_lengthof(g_register_infos_arm64_le))
+ return false;
+ reg_info = g_register_infos_arm64_le[reg_num];
+ return true;
+}
+
+#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)
#define UInt(x) ((uint64_t)x)
#define SInt(x) ((int64_t)x)
@@ -47,17 +71,9 @@ using namespace lldb_private;
#define boolean bool
#define integer int64_t
-static inline bool
-IsZero(uint64_t x)
-{
- return x == 0;
-}
+static inline bool IsZero(uint64_t x) { return x == 0; }
-static inline uint64_t
-NOT(uint64_t x)
-{
- return ~x;
-}
+static inline uint64_t NOT(uint64_t x) { return ~x; }
#if 0
// LSL_C()
@@ -75,354 +91,435 @@ LSL_C (uint64_t x, integer shift, bool &carry_out)
// LSL()
// =====
-static inline uint64_t
-LSL(uint64_t x, integer shift)
-{
- if (shift == 0)
- return x;
- return x << shift;
+static inline uint64_t LSL(uint64_t x, integer shift) {
+ if (shift == 0)
+ return x;
+ return x << shift;
}
// AddWithCarry()
// ===============
static inline uint64_t
-AddWithCarry (uint32_t N, uint64_t x, uint64_t y, bit carry_in, EmulateInstructionARM64::ProcState &proc_state)
-{
- uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
- int64_t signed_sum = SInt(x) + SInt(y) + UInt(carry_in);
- uint64_t result = unsigned_sum;
- if (N < 64)
- result = Bits64 (result, N-1, 0);
- proc_state.N = Bit64(result, N-1);
- proc_state.Z = IsZero(result);
- proc_state.C = UInt(result) == unsigned_sum;
- proc_state.V = SInt(result) == signed_sum;
- return result;
+AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bit carry_in,
+ EmulateInstructionARM64::ProcState &proc_state) {
+ uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
+ int64_t signed_sum = SInt(x) + SInt(y) + UInt(carry_in);
+ uint64_t result = unsigned_sum;
+ if (N < 64)
+ result = Bits64(result, N - 1, 0);
+ proc_state.N = Bit64(result, N - 1);
+ proc_state.Z = IsZero(result);
+ proc_state.C = UInt(result) == unsigned_sum;
+ proc_state.V = SInt(result) == signed_sum;
+ return result;
}
// ConstrainUnpredictable()
// ========================
EmulateInstructionARM64::ConstraintType
-ConstrainUnpredictable (EmulateInstructionARM64::Unpredictable which)
-{
- EmulateInstructionARM64::ConstraintType result = EmulateInstructionARM64::Constraint_UNKNOWN;
- switch (which)
- {
- case EmulateInstructionARM64::Unpredictable_WBOVERLAP:
- case EmulateInstructionARM64::Unpredictable_LDPOVERLAP:
- // TODO: don't know what to really do here? Pseudo code says:
- // set result to one of above Constraint behaviours or UNDEFINED
- break;
- }
- return result;
+ConstrainUnpredictable(EmulateInstructionARM64::Unpredictable which) {
+ EmulateInstructionARM64::ConstraintType result =
+ EmulateInstructionARM64::Constraint_UNKNOWN;
+ switch (which) {
+ case EmulateInstructionARM64::Unpredictable_WBOVERLAP:
+ case EmulateInstructionARM64::Unpredictable_LDPOVERLAP:
+ // TODO: don't know what to really do here? Pseudo code says:
+ // set result to one of above Constraint behaviours or UNDEFINED
+ break;
+ }
+ return result;
}
-
-
//----------------------------------------------------------------------
//
// EmulateInstructionARM implementation
//
//----------------------------------------------------------------------
-void
-EmulateInstructionARM64::Initialize ()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic (),
- GetPluginDescriptionStatic (),
- CreateInstance);
+void EmulateInstructionARM64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-EmulateInstructionARM64::Terminate ()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void EmulateInstructionARM64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-ConstString
-EmulateInstructionARM64::GetPluginNameStatic ()
-{
- ConstString g_plugin_name ("lldb.emulate-instruction.arm64");
- return g_plugin_name;
+ConstString EmulateInstructionARM64::GetPluginNameStatic() {
+ ConstString g_plugin_name("lldb.emulate-instruction.arm64");
+ return g_plugin_name;
}
-lldb_private::ConstString
-EmulateInstructionARM64::GetPluginName()
-{
- static ConstString g_plugin_name ("EmulateInstructionARM64");
- return g_plugin_name;
+lldb_private::ConstString EmulateInstructionARM64::GetPluginName() {
+ static ConstString g_plugin_name("EmulateInstructionARM64");
+ return g_plugin_name;
}
-const char *
-EmulateInstructionARM64::GetPluginDescriptionStatic ()
-{
- return "Emulate instructions for the ARM64 architecture.";
+const char *EmulateInstructionARM64::GetPluginDescriptionStatic() {
+ return "Emulate instructions for the ARM64 architecture.";
}
EmulateInstruction *
-EmulateInstructionARM64::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
-{
- if (EmulateInstructionARM64::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
- {
- if (arch.GetTriple().getArch() == llvm::Triple::aarch64)
- {
- std::auto_ptr<EmulateInstructionARM64> emulate_insn_ap (new EmulateInstructionARM64 (arch));
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
- }
+EmulateInstructionARM64::CreateInstance(const ArchSpec &arch,
+ InstructionType inst_type) {
+ if (EmulateInstructionARM64::SupportsEmulatingInstructionsOfTypeStatic(
+ inst_type)) {
+ if (arch.GetTriple().getArch() == llvm::Triple::aarch64) {
+ std::auto_ptr<EmulateInstructionARM64> emulate_insn_ap(
+ new EmulateInstructionARM64(arch));
+ if (emulate_insn_ap.get())
+ return emulate_insn_ap.release();
}
-
- return NULL;
+ }
+
+ return NULL;
}
-bool
-EmulateInstructionARM64::SetTargetTriple (const ArchSpec &arch)
-{
- if (arch.GetTriple().getArch () == llvm::Triple::arm)
- return true;
- else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
- return true;
+bool EmulateInstructionARM64::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 false;
}
-bool
-EmulateInstructionARM64::GetRegisterInfo (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
-{
- if (reg_kind == eRegisterKindGeneric)
- {
- switch (reg_num)
- {
- case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::pc; break;
- case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::sp; break;
- case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::fp; break;
- case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::lr; break;
- case LLDB_REGNUM_GENERIC_FLAGS:
- // There is no DWARF register number for the CPSR right now...
- reg_info.name = "cpsr";
- reg_info.alt_name = NULL;
- reg_info.byte_size = 4;
- reg_info.byte_offset = 0;
- reg_info.encoding = eEncodingUint;
- reg_info.format = eFormatHex;
- for (uint32_t i=0; i<lldb::kNumRegisterKinds; ++i)
- reg_info.kinds[reg_kind] = LLDB_INVALID_REGNUM;
- reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- return true;
-
- default: return false;
- }
+bool EmulateInstructionARM64::GetRegisterInfo(RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterInfo &reg_info) {
+ if (reg_kind == eRegisterKindGeneric) {
+ switch (reg_num) {
+ case LLDB_REGNUM_GENERIC_PC:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_pc_arm64;
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_sp_arm64;
+ break;
+ case LLDB_REGNUM_GENERIC_FP:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_fp_arm64;
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_lr_arm64;
+ break;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_cpsr_arm64;
+ break;
+
+ default:
+ return false;
}
-
- if (reg_kind == eRegisterKindDWARF)
- return arm64_dwarf::GetRegisterInfo(reg_num, reg_info);
- return false;
+ }
+
+ if (reg_kind == eRegisterKindLLDB)
+ return LLDBTableGetRegisterInfo(reg_num, reg_info);
+ return false;
}
-EmulateInstructionARM64::Opcode*
-EmulateInstructionARM64::GetOpcodeForInstruction (const uint32_t opcode)
-{
- static EmulateInstructionARM64::Opcode
- g_opcodes[] =
- {
- //----------------------------------------------------------------------
- // Prologue instructions
- //----------------------------------------------------------------------
-
- // push register(s)
- { 0xff000000, 0xd1000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "SUB <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}" },
- { 0xff000000, 0xf1000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "SUBS <Xd>, <Xn|SP>, #<imm> {, <shift>}" },
- { 0xff000000, 0x91000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "ADD <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}" },
- { 0xff000000, 0xb1000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "ADDS <Xd>, <Xn|SP>, #<imm> {, <shift>}" },
-
- { 0xff000000, 0x51000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "SUB <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}" },
- { 0xff000000, 0x71000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}" },
- { 0xff000000, 0x11000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "ADD <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}" },
- { 0xff000000, 0x31000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "ADDS <Wd>, <Wn|WSP>, #<imm> {, <shift>}" },
-
- { 0xffc00000, 0x29000000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "STP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0xa9000000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "STP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0x2d000000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "STP <St>, <St2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0x6d000000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "STP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0xad000000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "STP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]" },
-
- { 0xffc00000, 0x29800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xa9800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x2d800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "STP <St>, <St2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x6d800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xad800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!" },
-
- { 0xffc00000, 0x28800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xa8800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x2c800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "STP <St>, <St2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x6c800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xac800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!" },
-
- { 0xffc00000, 0x29400000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "LDP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0xa9400000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "LDP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0x2d400000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "LDP <St>, <St2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0x6d400000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "LDP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0xad400000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "LDP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]" },
-
- { 0xffc00000, 0x29c00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xa9c00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x2dc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x6dc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xadc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!" },
-
- { 0xffc00000, 0x28c00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xa8c00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x2cc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x6cc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xacc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!" },
-
- { 0xffe00c00, 0xb8000400, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>, "STR <Wt>, [<Xn|SP>], #<simm>" },
- { 0xffe00c00, 0xf8000400, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>, "STR <Xt>, [<Xn|SP>], #<simm>" },
- { 0xffe00c00, 0xb8000c00, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>, "STR <Wt>, [<Xn|SP>, #<simm>]!" },
- { 0xffe00c00, 0xf8000c00, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>, "STR <Xt>, [<Xn|SP>, #<simm>]!" },
- { 0xffc00000, 0xb9000000, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>, "STR <Wt>, [<Xn|SP>{, #<pimm>}]" },
- { 0xffc00000, 0xf9000000, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>, "STR <Xt>, [<Xn|SP>{, #<pimm>}]" },
-
- { 0xffe00c00, 0xb8400400, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>, "LDR <Wt>, [<Xn|SP>], #<simm>" },
- { 0xffe00c00, 0xf8400400, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>, "LDR <Xt>, [<Xn|SP>], #<simm>" },
- { 0xffe00c00, 0xb8400c00, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>, "LDR <Wt>, [<Xn|SP>, #<simm>]!" },
- { 0xffe00c00, 0xf8400c00, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>, "LDR <Xt>, [<Xn|SP>, #<simm>]!" },
- { 0xffc00000, 0xb9400000, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>, "LDR <Wt>, [<Xn|SP>{, #<pimm>}]" },
- { 0xffc00000, 0xf9400000, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>, "LDR <Xt>, [<Xn|SP>{, #<pimm>}]" },
-
- { 0xfc000000, 0x14000000, No_VFP, &EmulateInstructionARM64::EmulateB, "B <label>" },
- { 0xff000010, 0x54000000, No_VFP, &EmulateInstructionARM64::EmulateBcond, "B.<cond> <label>" },
- { 0x7f000000, 0x34000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ, "CBZ <Wt>, <label>" },
- { 0x7f000000, 0x35000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ, "CBNZ <Wt>, <label>" },
- { 0x7f000000, 0x36000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ, "TBZ <R><t>, #<imm>, <label>" },
- { 0x7f000000, 0x37000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ, "TBNZ <R><t>, #<imm>, <label>" },
-
- };
- static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_opcodes);
-
- for (size_t i=0; i<k_num_arm_opcodes; ++i)
- {
- if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
- return &g_opcodes[i];
- }
- return nullptr;
+EmulateInstructionARM64::Opcode *
+EmulateInstructionARM64::GetOpcodeForInstruction(const uint32_t opcode) {
+ static EmulateInstructionARM64::Opcode g_opcodes[] = {
+ //----------------------------------------------------------------------
+ // Prologue instructions
+ //----------------------------------------------------------------------
+
+ // push register(s)
+ {0xff000000, 0xd1000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "SUB <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}"},
+ {0xff000000, 0xf1000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "SUBS <Xd>, <Xn|SP>, #<imm> {, <shift>}"},
+ {0xff000000, 0x91000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "ADD <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}"},
+ {0xff000000, 0xb1000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "ADDS <Xd>, <Xn|SP>, #<imm> {, <shift>}"},
+
+ {0xff000000, 0x51000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "SUB <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}"},
+ {0xff000000, 0x71000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}"},
+ {0xff000000, 0x11000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "ADD <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}"},
+ {0xff000000, 0x31000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "ADDS <Wd>, <Wn|WSP>, #<imm> {, <shift>}"},
+
+ {0xffc00000, 0x29000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "STP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0xa9000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "STP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0x2d000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "STP <St>, <St2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0x6d000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "STP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0xad000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "STP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]"},
+
+ {0xffc00000, 0x29800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xa9800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x2d800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "STP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x6d800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xad800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
+
+ {0xffc00000, 0x28800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xa8800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x2c800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "STP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x6c800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xac800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
+
+ {0xffc00000, 0x29400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "LDP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0xa9400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "LDP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0x2d400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "LDP <St>, <St2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0x6d400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "LDP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0xad400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "LDP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]"},
+
+ {0xffc00000, 0x29c00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xa9c00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x2dc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x6dc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xadc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
+
+ {0xffc00000, 0x28c00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xa8c00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x2cc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x6cc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xacc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
+
+ {0xffe00c00, 0xb8000400, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
+ "STR <Wt>, [<Xn|SP>], #<simm>"},
+ {0xffe00c00, 0xf8000400, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
+ "STR <Xt>, [<Xn|SP>], #<simm>"},
+ {0xffe00c00, 0xb8000c00, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
+ "STR <Wt>, [<Xn|SP>, #<simm>]!"},
+ {0xffe00c00, 0xf8000c00, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
+ "STR <Xt>, [<Xn|SP>, #<simm>]!"},
+ {0xffc00000, 0xb9000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
+ "STR <Wt>, [<Xn|SP>{, #<pimm>}]"},
+ {0xffc00000, 0xf9000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
+ "STR <Xt>, [<Xn|SP>{, #<pimm>}]"},
+
+ {0xffe00c00, 0xb8400400, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
+ "LDR <Wt>, [<Xn|SP>], #<simm>"},
+ {0xffe00c00, 0xf8400400, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
+ "LDR <Xt>, [<Xn|SP>], #<simm>"},
+ {0xffe00c00, 0xb8400c00, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
+ "LDR <Wt>, [<Xn|SP>, #<simm>]!"},
+ {0xffe00c00, 0xf8400c00, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
+ "LDR <Xt>, [<Xn|SP>, #<simm>]!"},
+ {0xffc00000, 0xb9400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
+ "LDR <Wt>, [<Xn|SP>{, #<pimm>}]"},
+ {0xffc00000, 0xf9400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
+ "LDR <Xt>, [<Xn|SP>{, #<pimm>}]"},
+
+ {0xfc000000, 0x14000000, No_VFP, &EmulateInstructionARM64::EmulateB,
+ "B <label>"},
+ {0xff000010, 0x54000000, No_VFP, &EmulateInstructionARM64::EmulateBcond,
+ "B.<cond> <label>"},
+ {0x7f000000, 0x34000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ,
+ "CBZ <Wt>, <label>"},
+ {0x7f000000, 0x35000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ,
+ "CBNZ <Wt>, <label>"},
+ {0x7f000000, 0x36000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ,
+ "TBZ <R><t>, #<imm>, <label>"},
+ {0x7f000000, 0x37000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ,
+ "TBNZ <R><t>, #<imm>, <label>"},
+
+ };
+ static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_opcodes);
+
+ for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
+ if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
+ return &g_opcodes[i];
+ }
+ return nullptr;
}
-bool
-EmulateInstructionARM64::ReadInstruction ()
-{
- bool success = false;
- m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
- if (success)
- {
- Context read_inst_context;
- read_inst_context.type = eContextReadOpcode;
- read_inst_context.SetNoArgs ();
- m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder());
- }
- if (!success)
- m_addr = LLDB_INVALID_ADDRESS;
- return success;
+bool EmulateInstructionARM64::ReadInstruction() {
+ bool success = false;
+ m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_ADDRESS, &success);
+ if (success) {
+ Context read_inst_context;
+ read_inst_context.type = eContextReadOpcode;
+ read_inst_context.SetNoArgs();
+ m_opcode.SetOpcode32(
+ ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
+ GetByteOrder());
+ }
+ if (!success)
+ m_addr = LLDB_INVALID_ADDRESS;
+ return success;
}
+bool EmulateInstructionARM64::EvaluateInstruction(uint32_t evaluate_options) {
+ const uint32_t opcode = m_opcode.GetOpcode32();
+ Opcode *opcode_data = GetOpcodeForInstruction(opcode);
+ if (opcode_data == NULL)
+ return false;
-bool
-EmulateInstructionARM64::EvaluateInstruction (uint32_t evaluate_options)
-{
- const uint32_t opcode = m_opcode.GetOpcode32();
- Opcode *opcode_data = GetOpcodeForInstruction(opcode);
- if (opcode_data == NULL)
- return false;
-
- //printf ("opcode template for 0x%8.8x: %s\n", opcode, opcode_data->name);
- const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
- m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
-
- bool success = false;
-// if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
-// {
-// m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, // use eRegisterKindDWARF is we ever get a cpsr DWARF register number
-// LLDB_REGNUM_GENERIC_FLAGS, // use arm64_dwarf::cpsr if we ever get one
-// 0,
-// &success);
-// }
-
- // Only return false if we are unable to read the CPSR if we care about conditions
- if (success == false && m_ignore_conditions == false)
- return false;
-
- uint32_t orig_pc_value = 0;
- if (auto_advance_pc)
- {
- orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::pc, 0, &success);
- if (!success)
- return false;
- }
-
- // Call the Emulate... function.
- success = (this->*opcode_data->callback) (opcode);
+ // printf ("opcode template for 0x%8.8x: %s\n", opcode, opcode_data->name);
+ const bool auto_advance_pc =
+ evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+ m_ignore_conditions =
+ evaluate_options & eEmulateInstructionOptionIgnoreConditions;
+
+ bool success = false;
+ // if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
+ // {
+ // m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindLLDB,
+ // gpr_cpsr_arm64,
+ // 0,
+ // &success);
+ // }
+
+ // Only return false if we are unable to read the CPSR if we care about
+ // conditions
+ if (success == false && m_ignore_conditions == false)
+ return false;
+
+ uint32_t orig_pc_value = 0;
+ if (auto_advance_pc) {
+ orig_pc_value =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_arm64, 0, &success);
if (!success)
+ return false;
+ }
+
+ // Call the Emulate... function.
+ success = (this->*opcode_data->callback)(opcode);
+ if (!success)
+ return false;
+
+ if (auto_advance_pc) {
+ uint32_t new_pc_value =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_arm64, 0, &success);
+ if (!success)
+ return false;
+
+ if (auto_advance_pc && (new_pc_value == orig_pc_value)) {
+ EmulateInstruction::Context context;
+ context.type = eContextAdvancePC;
+ context.SetNoArgs();
+ if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_pc_arm64,
+ orig_pc_value + 4))
return false;
-
- if (auto_advance_pc)
- {
- uint32_t new_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::pc, 0, &success);
- if (!success)
- return false;
-
- if (auto_advance_pc && (new_pc_value == orig_pc_value))
- {
- EmulateInstruction::Context context;
- context.type = eContextAdvancePC;
- context.SetNoArgs();
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, arm64_dwarf::pc, orig_pc_value + 4))
- return false;
- }
}
- return true;
+ }
+ return true;
}
-bool
-EmulateInstructionARM64::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool EmulateInstructionARM64::CreateFunctionEntryUnwind(
+ UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindLLDB);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset(arm64_dwarf::sp, 0);
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_arm64, 0);
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("EmulateInstructionARM64");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
- unwind_plan.SetReturnAddressRegister (arm64_dwarf::lr);
- return true;
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("EmulateInstructionARM64");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetReturnAddressRegister(gpr_lr_arm64);
+ return true;
}
-uint32_t
-EmulateInstructionARM64::GetFramePointerRegisterNumber () const
-{
- if (m_arch.GetTriple().isAndroid())
- return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
+uint32_t EmulateInstructionARM64::GetFramePointerRegisterNumber() const {
+ if (m_arch.GetTriple().isAndroid())
+ return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
- return arm64_dwarf::sp;
+ return gpr_fp_arm64;
}
-bool
-EmulateInstructionARM64::UsingAArch32()
-{
- bool aarch32 = m_opcode_pstate.RW == 1;
- // if !HaveAnyAArch32() then assert !aarch32;
- // if HighestELUsingAArch32() then assert aarch32;
- return aarch32;
+bool EmulateInstructionARM64::UsingAArch32() {
+ bool aarch32 = m_opcode_pstate.RW == 1;
+ // if !HaveAnyAArch32() then assert !aarch32;
+ // if HighestELUsingAArch32() then assert aarch32;
+ return aarch32;
}
-bool
-EmulateInstructionARM64::BranchTo (const Context &context, uint32_t N, addr_t target)
-{
+bool EmulateInstructionARM64::BranchTo(const Context &context, uint32_t N,
+ addr_t target) {
#if 0
// Set program counter to a new address, with a branch reason hint
// for possible use by hardware fetching the next instruction.
@@ -450,603 +547,578 @@ EmulateInstructionARM64::BranchTo (const Context &context, uint32_t N, addr_t ta
return;
#endif
- addr_t addr;
+ addr_t addr;
+
+ // Hint_Branch(branch_type);
+ if (N == 32) {
+ if (!UsingAArch32())
+ return false;
+ addr = target;
+ } else if (N == 64) {
+ if (UsingAArch32())
+ return false;
+ // TODO: Remove the tag bits from a tagged target
+ addr = target;
+ } else
+ return false;
- //Hint_Branch(branch_type);
- if (N == 32)
- {
- if (!UsingAArch32())
- return false;
- addr = target;
- }
- else if (N == 64)
- {
- if (UsingAArch32())
- return false;
- // TODO: Remove the tag bits from a tagged target
- addr = target;
- }
- else
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, addr))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, addr))
- return false;
+ return true;
+}
+bool EmulateInstructionARM64::ConditionHolds(const uint32_t cond) {
+ // If we are ignoring conditions, then always return true.
+ // this allows us to iterate over disassembly code and still
+ // emulate an instruction even if we don't have all the right
+ // bits set in the CPSR register...
+ if (m_ignore_conditions)
return true;
-}
-bool
-EmulateInstructionARM64::ConditionHolds (const uint32_t cond)
-{
- // If we are ignoring conditions, then always return true.
- // this allows us to iterate over disassembly code and still
- // emulate an instruction even if we don't have all the right
- // bits set in the CPSR register...
- if (m_ignore_conditions)
- return true;
-
- bool result = false;
- switch (UnsignedBits(cond, 3, 1))
- {
- case 0:
- result = (m_opcode_pstate.Z == 1);
- break;
- case 1:
- result = (m_opcode_pstate.C == 1);
- break;
- case 2:
- result = (m_opcode_pstate.N == 1);
- break;
- case 3:
- result = (m_opcode_pstate.V == 1);
- break;
- case 4:
- result = (m_opcode_pstate.C == 1 && m_opcode_pstate.Z == 0);
- break;
- case 5:
- result = (m_opcode_pstate.N == m_opcode_pstate.V);
- break;
- case 6:
- result = (m_opcode_pstate.N == m_opcode_pstate.V && m_opcode_pstate.Z == 0);
- break;
- case 7:
- // Always execute (cond == 0b1110, or the special 0b1111 which gives
- // opcodes different meanings, but always means execution happens.
- return true;
- }
+ bool result = false;
+ switch (UnsignedBits(cond, 3, 1)) {
+ case 0:
+ result = (m_opcode_pstate.Z == 1);
+ break;
+ case 1:
+ result = (m_opcode_pstate.C == 1);
+ break;
+ case 2:
+ result = (m_opcode_pstate.N == 1);
+ break;
+ case 3:
+ result = (m_opcode_pstate.V == 1);
+ break;
+ case 4:
+ result = (m_opcode_pstate.C == 1 && m_opcode_pstate.Z == 0);
+ break;
+ case 5:
+ result = (m_opcode_pstate.N == m_opcode_pstate.V);
+ break;
+ case 6:
+ result = (m_opcode_pstate.N == m_opcode_pstate.V && m_opcode_pstate.Z == 0);
+ break;
+ case 7:
+ // Always execute (cond == 0b1110, or the special 0b1111 which gives
+ // opcodes different meanings, but always means execution happens.
+ return true;
+ }
- if (cond & 1)
- result = !result;
- return result;
+ if (cond & 1)
+ result = !result;
+ return result;
}
-bool
-EmulateInstructionARM64::EmulateADDSUBImm (const uint32_t opcode)
-{
- // integer d = UInt(Rd);
- // integer n = UInt(Rn);
- // integer datasize = if sf == 1 then 64 else 32;
- // boolean sub_op = (op == 1);
- // boolean setflags = (S == 1);
- // bits(datasize) imm;
- //
- // case shift of
- // when '00' imm = ZeroExtend(imm12, datasize);
- // when '01' imm = ZeroExtend(imm12 : Zeros(12), datasize);
- // when '1x' UNDEFINED;
- //
- //
- // bits(datasize) result;
- // bits(datasize) operand1 = if n == 31 then SP[] else X[n];
- // bits(datasize) operand2 = imm;
- // bits(4) nzcv;
- // bit carry_in;
- //
- // if sub_op then
- // operand2 = NOT(operand2);
- // carry_in = 1;
- // else
- // carry_in = 0;
- //
- // (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);
- //
- // if setflags then
- // PSTATE.NZCV = nzcv;
- //
- // if d == 31 && !setflags then
- // SP[] = result;
- // else
- // X[d] = result;
-
- const uint32_t sf = Bit32(opcode, 31);
- const uint32_t op = Bit32(opcode, 30);
- const uint32_t S = Bit32(opcode, 29);
- const uint32_t shift = Bits32(opcode, 23, 22);
- const uint32_t imm12 = Bits32(opcode, 21, 10);
- const uint32_t Rn = Bits32(opcode, 9, 5);
- const uint32_t Rd = Bits32(opcode, 4, 0);
-
- bool success = false;
-
- const uint32_t d = UInt(Rd);
- const uint32_t n = UInt(Rn);
- const uint32_t datasize = (sf == 1) ? 64 : 32;
- boolean sub_op = op == 1;
- boolean setflags = S == 1;
- uint64_t imm;
-
- switch (shift)
- {
- case 0: imm = imm12; break;
- case 1: imm = imm12 << 12; break;
- default: return false; // UNDEFINED;
- }
- uint64_t result;
- uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::x0 + n, 0, &success);
- uint64_t operand2 = imm;
- bit carry_in;
-
- if (sub_op)
- {
- operand2 = NOT(operand2);
- carry_in = 1;
- imm = -imm; // For the Register plug offset context below
- }
- else
- {
- carry_in = 0;
- }
-
- ProcState proc_state;
-
- result = AddWithCarry (datasize, operand1, operand2, carry_in, proc_state);
+bool EmulateInstructionARM64::EmulateADDSUBImm(const uint32_t opcode) {
+ // integer d = UInt(Rd);
+ // integer n = UInt(Rn);
+ // integer datasize = if sf == 1 then 64 else 32;
+ // boolean sub_op = (op == 1);
+ // boolean setflags = (S == 1);
+ // bits(datasize) imm;
+ //
+ // case shift of
+ // when '00' imm = ZeroExtend(imm12, datasize);
+ // when '01' imm = ZeroExtend(imm12 : Zeros(12), datasize);
+ // when '1x' UNDEFINED;
+ //
+ //
+ // bits(datasize) result;
+ // bits(datasize) operand1 = if n == 31 then SP[] else X[n];
+ // bits(datasize) operand2 = imm;
+ // bits(4) nzcv;
+ // bit carry_in;
+ //
+ // if sub_op then
+ // operand2 = NOT(operand2);
+ // carry_in = 1;
+ // else
+ // carry_in = 0;
+ //
+ // (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);
+ //
+ // if setflags then
+ // PSTATE.NZCV = nzcv;
+ //
+ // if d == 31 && !setflags then
+ // SP[] = result;
+ // else
+ // X[d] = result;
+
+ const uint32_t sf = Bit32(opcode, 31);
+ const uint32_t op = Bit32(opcode, 30);
+ const uint32_t S = Bit32(opcode, 29);
+ const uint32_t shift = Bits32(opcode, 23, 22);
+ const uint32_t imm12 = Bits32(opcode, 21, 10);
+ const uint32_t Rn = Bits32(opcode, 9, 5);
+ const uint32_t Rd = Bits32(opcode, 4, 0);
+
+ bool success = false;
+
+ const uint32_t d = UInt(Rd);
+ const uint32_t n = UInt(Rn);
+ const uint32_t datasize = (sf == 1) ? 64 : 32;
+ boolean sub_op = op == 1;
+ boolean setflags = S == 1;
+ uint64_t imm;
+
+ switch (shift) {
+ case 0:
+ imm = imm12;
+ break;
+ case 1:
+ imm = imm12 << 12;
+ break;
+ default:
+ return false; // UNDEFINED;
+ }
+ uint64_t result;
+ uint64_t operand1 =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
+ uint64_t operand2 = imm;
+ bit carry_in;
+
+ if (sub_op) {
+ operand2 = NOT(operand2);
+ carry_in = 1;
+ imm = -imm; // For the Register plug offset context below
+ } else {
+ carry_in = 0;
+ }
+
+ ProcState proc_state;
+
+ result = AddWithCarry(datasize, operand1, operand2, carry_in, proc_state);
+
+ if (setflags) {
+ m_emulated_pstate.N = proc_state.N;
+ m_emulated_pstate.Z = proc_state.Z;
+ m_emulated_pstate.C = proc_state.C;
+ m_emulated_pstate.V = proc_state.V;
+ }
+
+ Context context;
+ RegisterInfo reg_info_Rn;
+ if (GetRegisterInfo(eRegisterKindLLDB, n, reg_info_Rn))
+ context.SetRegisterPlusOffset(reg_info_Rn, imm);
+
+ if (n == GetFramePointerRegisterNumber() && d == gpr_sp_arm64 && !setflags) {
+ // 'mov sp, fp' - common epilogue instruction, CFA is now in terms
+ // of the stack pointer, instead of frame pointer.
+ context.type = EmulateInstruction::eContextRestoreStackPointer;
+ } else if ((n == gpr_sp_arm64 || n == GetFramePointerRegisterNumber()) &&
+ d == gpr_sp_arm64 && !setflags) {
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ } else if (d == GetFramePointerRegisterNumber() && n == gpr_sp_arm64 &&
+ !setflags) {
+ context.type = EmulateInstruction::eContextSetFramePointer;
+ } else {
+ context.type = EmulateInstruction::eContextImmediate;
+ }
+
+ // If setflags && d == gpr_sp_arm64 then d = WZR/XZR. See CMN, CMP
+ if (!setflags || d != gpr_sp_arm64)
+ WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_x0_arm64 + d, result);
+
+ return false;
+}
- if (setflags)
- {
- m_emulated_pstate.N = proc_state.N;
- m_emulated_pstate.Z = proc_state.Z;
- m_emulated_pstate.C = proc_state.C;
- m_emulated_pstate.V = proc_state.V;
+template <EmulateInstructionARM64::AddrMode a_mode>
+bool EmulateInstructionARM64::EmulateLDPSTP(const uint32_t opcode) {
+ uint32_t opc = Bits32(opcode, 31, 30);
+ uint32_t V = Bit32(opcode, 26);
+ uint32_t L = Bit32(opcode, 22);
+ uint32_t imm7 = Bits32(opcode, 21, 15);
+ uint32_t Rt2 = Bits32(opcode, 14, 10);
+ uint32_t Rn = Bits32(opcode, 9, 5);
+ uint32_t Rt = Bits32(opcode, 4, 0);
+
+ integer n = UInt(Rn);
+ integer t = UInt(Rt);
+ integer t2 = UInt(Rt2);
+ uint64_t idx;
+
+ MemOp memop = L == 1 ? MemOp_LOAD : MemOp_STORE;
+ boolean vector = (V == 1);
+ // AccType acctype = AccType_NORMAL;
+ boolean is_signed = false;
+ boolean wback = a_mode != AddrMode_OFF;
+ boolean wb_unknown = false;
+ boolean rt_unknown = false;
+ integer scale;
+ integer size;
+
+ if (opc == 3)
+ return false; // UNDEFINED
+
+ if (vector) {
+ scale = 2 + UInt(opc);
+ } else {
+ scale = (opc & 2) ? 3 : 2;
+ is_signed = (opc & 1) != 0;
+ if (is_signed && memop == MemOp_STORE)
+ return false; // UNDEFINED
+ }
+
+ if (!vector && wback && ((t == n) || (t2 == n))) {
+ switch (ConstrainUnpredictable(Unpredictable_WBOVERLAP)) {
+ case Constraint_UNKNOWN:
+ wb_unknown = true; // writeback is UNKNOWN
+ break;
+
+ case Constraint_SUPPRESSWB:
+ wback = false; // writeback is suppressed
+ break;
+
+ case Constraint_NOP:
+ memop = MemOp_NOP; // do nothing
+ wback = false;
+ break;
+
+ case Constraint_NONE:
+ break;
}
-
- Context context;
- RegisterInfo reg_info_Rn;
- if (arm64_dwarf::GetRegisterInfo (n, reg_info_Rn))
- context.SetRegisterPlusOffset (reg_info_Rn, imm);
+ }
- if ((n == arm64_dwarf::sp || n == GetFramePointerRegisterNumber()) &&
- d == arm64_dwarf::sp &&
- !setflags)
- {
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- }
- else if (d == GetFramePointerRegisterNumber() &&
- n == arm64_dwarf::sp &&
- !setflags)
- {
- context.type = EmulateInstruction::eContextSetFramePointer;
- }
- else
- {
- context.type = EmulateInstruction::eContextImmediate;
+ if (memop == MemOp_LOAD && t == t2) {
+ switch (ConstrainUnpredictable(Unpredictable_LDPOVERLAP)) {
+ case Constraint_UNKNOWN:
+ rt_unknown = true; // result is UNKNOWN
+ break;
+
+ case Constraint_NOP:
+ memop = MemOp_NOP; // do nothing
+ wback = false;
+ break;
+
+ default:
+ break;
}
+ }
+
+ idx = LSL(llvm::SignExtend64<7>(imm7), scale);
+ size = (integer)1 << scale;
+ uint64_t datasize = size * 8;
+ uint64_t address;
+ uint64_t wb_address;
- // If setflags && d == arm64_dwarf::sp then d = WZR/XZR. See CMN, CMP
- if (!setflags || d != arm64_dwarf::sp)
- WriteRegisterUnsigned (context, eRegisterKindDWARF, arm64_dwarf::x0 + d, result);
+ RegisterValue data_Rt;
+ RegisterValue data_Rt2;
+ // if (vector)
+ // CheckFPEnabled(false);
+
+ RegisterInfo reg_info_base;
+ RegisterInfo reg_info_Rt;
+ RegisterInfo reg_info_Rt2;
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + n, reg_info_base))
return false;
-}
-template <EmulateInstructionARM64::AddrMode a_mode> bool
-EmulateInstructionARM64::EmulateLDPSTP (const uint32_t opcode)
-{
- uint32_t opc = Bits32(opcode, 31, 30);
- uint32_t V = Bit32(opcode, 26);
- uint32_t L = Bit32(opcode, 22);
- uint32_t imm7 = Bits32(opcode, 21, 15);
- uint32_t Rt2 = Bits32(opcode, 14, 10);
- uint32_t Rn = Bits32(opcode, 9, 5);
- uint32_t Rt = Bits32(opcode, 4, 0);
-
- integer n = UInt(Rn);
- integer t = UInt(Rt);
- integer t2 = UInt(Rt2);
- uint64_t idx;
-
- MemOp memop = L == 1 ? MemOp_LOAD : MemOp_STORE;
- boolean vector = (V == 1);
- //AccType acctype = AccType_NORMAL;
- boolean is_signed = false;
- boolean wback = a_mode != AddrMode_OFF;
- boolean wb_unknown = false;
- boolean rt_unknown = false;
- integer scale;
- integer size;
-
- if (opc == 3)
- return false; // UNDEFINED
-
- if (vector)
- {
- scale = 2 + UInt(opc);
- }
- else
+ if (vector) {
+ if (!GetRegisterInfo(eRegisterKindLLDB, fpu_d0_arm64 + t, reg_info_Rt))
+ return false;
+ if (!GetRegisterInfo(eRegisterKindLLDB, fpu_d0_arm64 + t2, reg_info_Rt2))
+ return false;
+ } else {
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t, reg_info_Rt))
+ return false;
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t2, reg_info_Rt2))
+ return false;
+ }
+
+ bool success = false;
+ if (n == 31) {
+ // CheckSPAlignment();
+ address =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_sp_arm64, 0, &success);
+ } else
+ address =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
+
+ wb_address = address + idx;
+ if (a_mode != AddrMode_POST)
+ address = wb_address;
+
+ Context context_t;
+ Context context_t2;
+
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ Error error;
+
+ switch (memop) {
+ case MemOp_STORE: {
+ if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
+ // based off of the sp
+ // or fp register
{
- scale = (opc & 2) ? 3 : 2;
- is_signed = (opc & 1) != 0;
- if (is_signed && memop == MemOp_STORE)
- return false; // UNDEFINED
- }
-
- if (!vector && wback && ((t == n) || (t2 == n)))
- {
- switch (ConstrainUnpredictable(Unpredictable_WBOVERLAP))
- {
- case Constraint_UNKNOWN:
- wb_unknown = true; // writeback is UNKNOWN
- break;
-
- case Constraint_SUPPRESSWB:
- wback = false; // writeback is suppressed
- break;
-
- case Constraint_NOP:
- memop = MemOp_NOP; // do nothing
- wback = false;
- break;
-
- case Constraint_NONE:
- break;
- }
+ context_t.type = eContextPushRegisterOnStack;
+ context_t2.type = eContextPushRegisterOnStack;
+ } else {
+ context_t.type = eContextRegisterStore;
+ context_t2.type = eContextRegisterStore;
}
+ context_t.SetRegisterToRegisterPlusOffset(reg_info_Rt, reg_info_base, 0);
+ context_t2.SetRegisterToRegisterPlusOffset(reg_info_Rt2, reg_info_base,
+ size);
+
+ if (!ReadRegister(&reg_info_Rt, data_Rt))
+ return false;
+
+ if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
+
+ if (!WriteMemory(context_t, address + 0, buffer, reg_info_Rt.byte_size))
+ return false;
+
+ if (!ReadRegister(&reg_info_Rt2, data_Rt2))
+ return false;
+
+ if (data_Rt2.GetAsMemoryData(&reg_info_Rt2, buffer, reg_info_Rt2.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- if (memop == MemOp_LOAD && t == t2)
+ if (!WriteMemory(context_t2, address + size, buffer,
+ reg_info_Rt2.byte_size))
+ return false;
+ } break;
+
+ case MemOp_LOAD: {
+ if (n == 31 || n == GetFramePointerRegisterNumber()) // if this load is
+ // based off of the sp
+ // or fp register
{
- switch (ConstrainUnpredictable(Unpredictable_LDPOVERLAP))
- {
- case Constraint_UNKNOWN:
- rt_unknown = true; // result is UNKNOWN
- break;
-
- case Constraint_NOP:
- memop = MemOp_NOP; // do nothing
- wback = false;
- break;
-
- default:
- break;
- }
+ context_t.type = eContextPopRegisterOffStack;
+ context_t2.type = eContextPopRegisterOffStack;
+ } else {
+ context_t.type = eContextRegisterLoad;
+ context_t2.type = eContextRegisterLoad;
}
-
- idx = LSL(llvm::SignExtend64<7>(imm7), scale);
- size = (integer)1 << scale;
- uint64_t datasize = size * 8;
- uint64_t address;
- uint64_t wb_address;
-
- RegisterValue data_Rt;
- RegisterValue data_Rt2;
-
- // if (vector)
- // CheckFPEnabled(false);
-
- RegisterInfo reg_info_base;
- RegisterInfo reg_info_Rt;
- RegisterInfo reg_info_Rt2;
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + n, reg_info_base))
+ context_t.SetAddress(address);
+ context_t2.SetAddress(address + size);
+
+ if (rt_unknown)
+ memset(buffer, 'U', reg_info_Rt.byte_size);
+ else {
+ if (!ReadMemory(context_t, address, buffer, reg_info_Rt.byte_size))
return false;
-
- if (vector)
- {
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::v0 + n, reg_info_Rt))
- return false;
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::v0 + n, reg_info_Rt2))
- return false;
- }
- else
- {
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + t, reg_info_Rt))
- return false;
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + t2, reg_info_Rt2))
- return false;
- }
-
- bool success = false;
- if (n == 31)
- {
- //CheckSPAlignment();
- address = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::sp, 0, &success);
}
- else
- address = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::x0 + n, 0, &success);
-
- wb_address = address + idx;
- if (a_mode != AddrMode_POST)
- address = wb_address;
-
- Context context_t;
- Context context_t2;
-
- uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
- Error error;
-
- switch (memop)
- {
- case MemOp_STORE:
- {
- if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is based off of the sp or fp register
- {
- context_t.type = eContextPushRegisterOnStack;
- context_t2.type = eContextPushRegisterOnStack;
- }
- else
- {
- context_t.type = eContextRegisterStore;
- context_t2.type = eContextRegisterStore;
- }
- context_t.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, 0);
- context_t2.SetRegisterToRegisterPlusOffset (reg_info_Rt2, reg_info_base, size);
-
- if (!ReadRegister (&reg_info_Rt, data_Rt))
- return false;
-
- if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!WriteMemory(context_t, address + 0, buffer, reg_info_Rt.byte_size))
- return false;
-
- if (!ReadRegister (&reg_info_Rt2, data_Rt2))
- return false;
-
- if (data_Rt2.GetAsMemoryData(&reg_info_Rt2, buffer, reg_info_Rt2.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!WriteMemory(context_t2, address + size, buffer, reg_info_Rt2.byte_size))
- return false;
- }
- break;
-
- case MemOp_LOAD:
- {
- if (n == 31 || n == GetFramePointerRegisterNumber()) // if this load is based off of the sp or fp register
- {
- context_t.type = eContextPopRegisterOffStack;
- context_t2.type = eContextPopRegisterOffStack;
- }
- else
- {
- context_t.type = eContextRegisterLoad;
- context_t2.type = eContextRegisterLoad;
- }
- context_t.SetAddress(address);
- context_t2.SetAddress(address + size);
-
- if (rt_unknown)
- memset (buffer, 'U', reg_info_Rt.byte_size);
- else
- {
- if (!ReadMemory (context_t, address, buffer, reg_info_Rt.byte_size))
- return false;
- }
-
- if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!vector && is_signed && !data_Rt.SignExtend (datasize))
- return false;
-
- if (!WriteRegister (context_t, &reg_info_Rt, data_Rt))
- return false;
-
- if (!rt_unknown)
- {
- if (!ReadMemory (context_t2, address + size, buffer, reg_info_Rt2.byte_size))
- return false;
- }
-
- if (data_Rt2.SetFromMemoryData(&reg_info_Rt2, buffer, reg_info_Rt2.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!vector && is_signed && !data_Rt2.SignExtend (datasize))
- return false;
-
- if (!WriteRegister (context_t2, &reg_info_Rt2, data_Rt2))
- return false;
- }
- break;
-
- default:
- break;
- }
-
- if (wback)
- {
- if (wb_unknown)
- wb_address = LLDB_INVALID_ADDRESS;
- Context context;
- context.SetImmediateSigned (idx);
- if (n == 31)
- context.type = eContextAdjustStackPointer;
- else
- context.type = eContextAdjustBaseRegister;
- WriteRegisterUnsigned (context, &reg_info_base, wb_address);
- }
- return true;
-}
-template <EmulateInstructionARM64::AddrMode a_mode> bool
-EmulateInstructionARM64::EmulateLDRSTRImm (const uint32_t opcode)
-{
- uint32_t size = Bits32(opcode, 31, 30);
- uint32_t opc = Bits32(opcode, 23, 22);
- uint32_t n = Bits32(opcode, 9, 5);
- uint32_t t = Bits32(opcode, 4, 0);
+ if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- bool wback;
- bool postindex;
- uint64_t offset;
+ if (!vector && is_signed && !data_Rt.SignExtend(datasize))
+ return false;
- switch (a_mode)
- {
- case AddrMode_POST:
- wback = true;
- postindex = true;
- offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
- break;
- case AddrMode_PRE:
- wback = true;
- postindex = false;
- offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
- break;
- case AddrMode_OFF:
- wback = false;
- postindex = false;
- offset = LSL(Bits32(opcode, 21, 10), size);
- break;
+ if (!WriteRegister(context_t, &reg_info_Rt, data_Rt))
+ return false;
+
+ if (!rt_unknown) {
+ if (!ReadMemory(context_t2, address + size, buffer,
+ reg_info_Rt2.byte_size))
+ return false;
}
- MemOp memop;
+ if (data_Rt2.SetFromMemoryData(&reg_info_Rt2, buffer,
+ reg_info_Rt2.byte_size, eByteOrderLittle,
+ error) == 0)
+ return false;
- if (Bit32(opc, 1) == 0)
- {
- memop = Bit32(opc, 0) == 1 ? MemOp_LOAD : MemOp_STORE;
- }
- else
- {
- memop = MemOp_LOAD;
- if (size == 2 && Bit32(opc, 0) == 1)
- return false;
- }
+ if (!vector && is_signed && !data_Rt2.SignExtend(datasize))
+ return false;
- Error error;
- bool success = false;
- uint64_t address;
- uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
- RegisterValue data_Rt;
+ if (!WriteRegister(context_t2, &reg_info_Rt2, data_Rt2))
+ return false;
+ } break;
+
+ default:
+ break;
+ }
+ if (wback) {
+ if (wb_unknown)
+ wb_address = LLDB_INVALID_ADDRESS;
+ Context context;
+ context.SetImmediateSigned(idx);
if (n == 31)
- address = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::sp, 0, &success);
+ context.type = eContextAdjustStackPointer;
else
- address = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::x0 + n, 0, &success);
+ context.type = eContextAdjustBaseRegister;
+ WriteRegisterUnsigned(context, &reg_info_base, wb_address);
+ }
+ return true;
+}
- if (!success)
- return false;
+template <EmulateInstructionARM64::AddrMode a_mode>
+bool EmulateInstructionARM64::EmulateLDRSTRImm(const uint32_t opcode) {
+ uint32_t size = Bits32(opcode, 31, 30);
+ uint32_t opc = Bits32(opcode, 23, 22);
+ uint32_t n = Bits32(opcode, 9, 5);
+ uint32_t t = Bits32(opcode, 4, 0);
+
+ bool wback;
+ bool postindex;
+ uint64_t offset;
+
+ switch (a_mode) {
+ case AddrMode_POST:
+ wback = true;
+ postindex = true;
+ offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
+ break;
+ case AddrMode_PRE:
+ wback = true;
+ postindex = false;
+ offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
+ break;
+ case AddrMode_OFF:
+ wback = false;
+ postindex = false;
+ offset = LSL(Bits32(opcode, 21, 10), size);
+ break;
+ }
+
+ MemOp memop;
+
+ if (Bit32(opc, 1) == 0) {
+ memop = Bit32(opc, 0) == 1 ? MemOp_LOAD : MemOp_STORE;
+ } else {
+ memop = MemOp_LOAD;
+ if (size == 2 && Bit32(opc, 0) == 1)
+ return false;
+ }
+
+ Error error;
+ bool success = false;
+ uint64_t address;
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ RegisterValue data_Rt;
+
+ if (n == 31)
+ address =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_sp_arm64, 0, &success);
+ else
+ address =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
+
+ if (!success)
+ return false;
- if (!postindex)
- address += offset;
+ if (!postindex)
+ address += offset;
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + n, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + n, reg_info_base))
+ return false;
- RegisterInfo reg_info_Rt;
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + t, reg_info_Rt))
- return false;
+ RegisterInfo reg_info_Rt;
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t, reg_info_Rt))
+ return false;
- Context context;
- switch (memop)
- {
- case MemOp_STORE:
- if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is based off of the sp or fp register
- context.type = eContextPushRegisterOnStack;
- else
- context.type = eContextRegisterStore;
- context.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, postindex ? 0 : offset);
-
- if (!ReadRegister (&reg_info_Rt, data_Rt))
- return false;
-
- if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!WriteMemory(context, address, buffer, reg_info_Rt.byte_size))
- return false;
- break;
-
- case MemOp_LOAD:
- if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is based off of the sp or fp register
- context.type = eContextPopRegisterOffStack;
- else
- context.type = eContextRegisterLoad;
- context.SetAddress(address);
-
- if (!ReadMemory (context, address, buffer, reg_info_Rt.byte_size))
- return false;
-
- if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!WriteRegister (context, &reg_info_Rt, data_Rt))
- return false;
- break;
- default:
- return false;
- }
+ Context context;
+ switch (memop) {
+ case MemOp_STORE:
+ if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
+ // based off of the sp
+ // or fp register
+ context.type = eContextPushRegisterOnStack;
+ else
+ context.type = eContextRegisterStore;
+ context.SetRegisterToRegisterPlusOffset(reg_info_Rt, reg_info_base,
+ postindex ? 0 : offset);
+
+ if (!ReadRegister(&reg_info_Rt, data_Rt))
+ return false;
+
+ if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
+
+ if (!WriteMemory(context, address, buffer, reg_info_Rt.byte_size))
+ return false;
+ break;
+
+ case MemOp_LOAD:
+ if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
+ // based off of the sp
+ // or fp register
+ context.type = eContextPopRegisterOffStack;
+ else
+ context.type = eContextRegisterLoad;
+ context.SetAddress(address);
- if (wback)
- {
- if (postindex)
- address += offset;
+ if (!ReadMemory(context, address, buffer, reg_info_Rt.byte_size))
+ return false;
- if (n == 31)
- context.type = eContextAdjustStackPointer;
- else
- context.type = eContextAdjustBaseRegister;
- context.SetImmediateSigned (offset);
+ if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- if (!WriteRegisterUnsigned (context, &reg_info_base, address))
- return false;
- }
- return true;
+ if (!WriteRegister(context, &reg_info_Rt, data_Rt))
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ if (wback) {
+ if (postindex)
+ address += offset;
+
+ if (n == 31)
+ context.type = eContextAdjustStackPointer;
+ else
+ context.type = eContextAdjustBaseRegister;
+ context.SetImmediateSigned(offset);
+
+ if (!WriteRegisterUnsigned(context, &reg_info_base, address))
+ return false;
+ }
+ return true;
}
-bool
-EmulateInstructionARM64::EmulateB (const uint32_t opcode)
-{
+bool EmulateInstructionARM64::EmulateB(const uint32_t opcode) {
#if 0
// ARM64 pseudo code...
if branch_type == BranchType_CALL then X[30] = PC[] + 4;
BranchTo(PC[] + offset, branch_type);
#endif
- bool success = false;
+ bool success = false;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
- if (!success)
- return false;
-
- int64_t offset = llvm::SignExtend64<28>(Bits32(opcode, 25, 0) << 2);
- BranchType branch_type = Bit32(opcode, 31) ? BranchType_CALL : BranchType_JMP;
- addr_t target = pc + offset;
- context.SetImmediateSigned(offset);
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, 0, &success);
+ if (!success)
+ return false;
- switch (branch_type)
- {
- case BranchType_CALL:
- {
- addr_t x30 = pc + 4;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, arm64_dwarf::x30, x30))
- return false;
- }
- break;
- case BranchType_JMP:
- break;
- default:
- return false;
- }
+ int64_t offset = llvm::SignExtend64<28>(Bits32(opcode, 25, 0) << 2);
+ BranchType branch_type = Bit32(opcode, 31) ? BranchType_CALL : BranchType_JMP;
+ addr_t target = pc + offset;
+ context.SetImmediateSigned(offset);
+
+ switch (branch_type) {
+ case BranchType_CALL: {
+ addr_t x30 = pc + 4;
+ if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_lr_arm64, x30))
+ return false;
+ } break;
+ case BranchType_JMP:
+ break;
+ default:
+ return false;
+ }
- if (!BranchTo(context, 64, target))
- return false;
- return true;
+ if (!BranchTo(context, 64, target))
+ return false;
+ return true;
}
-bool
-EmulateInstructionARM64::EmulateBcond (const uint32_t opcode)
-{
+bool EmulateInstructionARM64::EmulateBcond(const uint32_t opcode) {
#if 0
// ARM64 pseudo code...
bits(64) offset = SignExtend(imm19:'00', 64);
@@ -1055,29 +1127,27 @@ EmulateInstructionARM64::EmulateBcond (const uint32_t opcode)
BranchTo(PC[] + offset, BranchType_JMP);
#endif
- if (ConditionHolds(Bits32(opcode, 3, 0)))
- {
- bool success = false;
-
- const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
- if (!success)
- return false;
-
- int64_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
- addr_t target = pc + offset;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- context.SetImmediateSigned(offset);
- if (!BranchTo(context, 64, target))
- return false;
- }
- return true;
+ if (ConditionHolds(Bits32(opcode, 3, 0))) {
+ bool success = false;
+
+ const uint64_t pc = ReadRegisterUnsigned(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ if (!success)
+ return false;
+
+ int64_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
+ addr_t target = pc + offset;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ context.SetImmediateSigned(offset);
+ if (!BranchTo(context, 64, target))
+ return false;
+ }
+ return true;
}
-bool
-EmulateInstructionARM64::EmulateCBZ (const uint32_t opcode)
-{
+bool EmulateInstructionARM64::EmulateCBZ(const uint32_t opcode) {
#if 0
integer t = UInt(Rt);
integer datasize = if sf == '1' then 64 else 32;
@@ -1089,34 +1159,33 @@ EmulateInstructionARM64::EmulateCBZ (const uint32_t opcode)
BranchTo(PC[] + offset, BranchType_JMP);
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t t = Bits32(opcode, 4, 0);
+ bool is_zero = Bit32(opcode, 24) == 0;
+ int32_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
- uint32_t t = Bits32(opcode, 4, 0);
- bool is_zero = Bit32(opcode, 24) == 0;
- int32_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
+ const uint64_t operand =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + t, 0, &success);
+ if (!success)
+ return false;
- const uint64_t operand = ReadRegisterUnsigned(eRegisterKindDWARF, arm64_dwarf::x0 + t, 0, &success);
+ if (m_ignore_conditions || ((operand == 0) == is_zero)) {
+ const uint64_t pc = ReadRegisterUnsigned(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
if (!success)
- return false;
+ return false;
- if (m_ignore_conditions || ((operand == 0) == is_zero))
- {
- const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
- if (!success)
- return false;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- context.SetImmediateSigned(offset);
- if (!BranchTo(context, 64, pc + offset))
- return false;
- }
- return true;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ context.SetImmediateSigned(offset);
+ if (!BranchTo(context, 64, pc + offset))
+ return false;
+ }
+ return true;
}
-bool
-EmulateInstructionARM64::EmulateTBZ (const uint32_t opcode)
-{
+bool EmulateInstructionARM64::EmulateTBZ(const uint32_t opcode) {
#if 0
integer t = UInt(Rt);
integer datasize = if b5 == '1' then 64 else 32;
@@ -1125,28 +1194,29 @@ EmulateInstructionARM64::EmulateTBZ (const uint32_t opcode)
bits(64) offset = SignExtend(imm14:'00', 64);
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t t = Bits32(opcode, 4, 0);
+ uint32_t bit_pos = (Bit32(opcode, 31) << 6) | (Bits32(opcode, 23, 19));
+ uint32_t bit_val = Bit32(opcode, 24);
+ int64_t offset = llvm::SignExtend64<16>(Bits32(opcode, 18, 5) << 2);
- uint32_t t = Bits32(opcode, 4, 0);
- uint32_t bit_pos = (Bit32(opcode, 31) << 6) | (Bits32(opcode, 23, 19));
- uint32_t bit_val = Bit32(opcode, 24);
- int64_t offset = llvm::SignExtend64<16>(Bits32(opcode, 18, 5) << 2);
+ const uint64_t operand =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + t, 0, &success);
+ if (!success)
+ return false;
- const uint64_t operand = ReadRegisterUnsigned(eRegisterKindDWARF, arm64_dwarf::x0 + t, 0, &success);
+ if (m_ignore_conditions || Bit32(operand, bit_pos) == bit_val) {
+ const uint64_t pc = ReadRegisterUnsigned(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
if (!success)
- return false;
+ return false;
- if (m_ignore_conditions || Bit32(operand, bit_pos) == bit_val)
- {
- const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
- if (!success)
- return false;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- context.SetImmediateSigned(offset);
- if (!BranchTo(context, 64, pc + offset))
- return false;
- }
- return true;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ context.SetImmediateSigned(offset);
+ if (!BranchTo(context, 64, pc + offset))
+ return false;
+ }
+ return true;
}
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
index d9333c2824d2..1da330497b33 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
@@ -14,288 +14,192 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "Plugins/Process/Utility/ARMDefines.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Error.h"
#include "lldb/Interpreter/OptionValue.h"
-#include "Plugins/Process/Utility/ARMDefines.h"
-class EmulateInstructionARM64 : public lldb_private::EmulateInstruction
-{
-public:
- EmulateInstructionARM64 (const lldb_private::ArchSpec &arch) :
- EmulateInstruction (arch),
- m_opcode_pstate (),
- m_emulated_pstate (),
- m_ignore_conditions (false)
- {
- }
+class EmulateInstructionARM64 : public lldb_private::EmulateInstruction {
+public:
+ EmulateInstructionARM64(const lldb_private::ArchSpec &arch)
+ : EmulateInstruction(arch), m_opcode_pstate(), m_emulated_pstate(),
+ m_ignore_conditions(false) {}
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb_private::ConstString
- GetPluginNameStatic ();
-
- static const char *
- GetPluginDescriptionStatic ();
-
- static lldb_private::EmulateInstruction *
- CreateInstance (const lldb_private::ArchSpec &arch,
- lldb_private::InstructionType inst_type);
-
- static bool
- SupportsEmulatingInstructionsOfTypeStatic (lldb_private::InstructionType inst_type)
- {
- switch (inst_type)
- {
- case lldb_private::eInstructionTypeAny:
- case lldb_private::eInstructionTypePrologueEpilogue:
- return true;
-
- case lldb_private::eInstructionTypePCModifying:
- case lldb_private::eInstructionTypeAll:
- return false;
- }
- return false;
- }
+ static void Initialize();
- lldb_private::ConstString
- GetPluginName() override;
+ static void Terminate();
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ static lldb_private::ConstString GetPluginNameStatic();
- bool
- SetTargetTriple(const lldb_private::ArchSpec &arch) override;
-
- bool
- SupportsEmulatingInstructionsOfType(lldb_private::InstructionType inst_type) override
- {
- return SupportsEmulatingInstructionsOfTypeStatic (inst_type);
- }
+ static const char *GetPluginDescriptionStatic();
- bool
- ReadInstruction() override;
-
- bool
- EvaluateInstruction(uint32_t evaluate_options) override;
-
- bool
- TestEmulation(lldb_private::Stream *out_stream,
- lldb_private::ArchSpec &arch,
- lldb_private::OptionValueDictionary *test_data) override
- {
- return false;
+ static lldb_private::EmulateInstruction *
+ CreateInstance(const lldb_private::ArchSpec &arch,
+ lldb_private::InstructionType inst_type);
+
+ static bool SupportsEmulatingInstructionsOfTypeStatic(
+ lldb_private::InstructionType inst_type) {
+ switch (inst_type) {
+ case lldb_private::eInstructionTypeAny:
+ case lldb_private::eInstructionTypePrologueEpilogue:
+ return true;
+
+ case lldb_private::eInstructionTypePCModifying:
+ case lldb_private::eInstructionTypeAll:
+ return false;
}
+ return false;
+ }
+
+ lldb_private::ConstString GetPluginName() override;
- bool
- GetRegisterInfo(lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- lldb_private::RegisterInfo &reg_info) override;
-
- bool
- CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
-
- typedef enum
- {
- AddrMode_OFF,
- AddrMode_PRE,
- AddrMode_POST
- } AddrMode;
-
- typedef enum
- {
- BranchType_CALL,
- BranchType_ERET,
- BranchType_DRET,
- BranchType_RET,
- BranchType_JMP
- } BranchType;
-
- typedef enum
- {
- CountOp_CLZ,
- CountOp_CLS,
- CountOp_CNT
- } CountOp;
-
- typedef enum
- {
- RevOp_RBIT,
- RevOp_REV16,
- RevOp_REV32,
- RevOp_REV64
- } RevOp;
-
- typedef enum
- {
- BitwiseOp_NOT,
- BitwiseOp_RBIT
- } BitwiseOp;
-
- typedef enum
- {
- EL0 = 0,
- EL1 = 1,
- EL2 = 2,
- EL3 = 3
- } ExceptionLevel;
-
- typedef enum
- {
- ExtendType_SXTB,
- ExtendType_SXTH,
- ExtendType_SXTW,
- ExtendType_SXTX,
- ExtendType_UXTB,
- ExtendType_UXTH,
- ExtendType_UXTW,
- ExtendType_UXTX
- } ExtendType;
-
- typedef enum
- {
- ExtractType_LEFT,
- ExtractType_RIGHT
- } ExtractType;
-
- typedef enum
- {
- LogicalOp_AND,
- LogicalOp_EOR,
- LogicalOp_ORR
- } LogicalOp;
-
- typedef enum
- {
- MemOp_LOAD,
- MemOp_STORE,
- MemOp_PREFETCH,
- MemOp_NOP
- } MemOp;
-
- typedef enum
- {
- MoveWideOp_N,
- MoveWideOp_Z,
- MoveWideOp_K
- } MoveWideOp;
-
- typedef enum {
- ShiftType_LSL,
- ShiftType_LSR,
- ShiftType_ASR,
- ShiftType_ROR
- } ShiftType;
-
- typedef enum
- {
- SP0 = 0,
- SPx = 1
- } StackPointerSelection;
-
- typedef enum
- {
- Unpredictable_WBOVERLAP,
- Unpredictable_LDPOVERLAP
- } Unpredictable;
-
- typedef enum
- {
- Constraint_NONE,
- Constraint_UNKNOWN,
- Constraint_SUPPRESSWB,
- Constraint_NOP
- } ConstraintType;
-
- typedef enum
- {
- AccType_NORMAL,
- AccType_UNPRIV,
- AccType_STREAM,
- AccType_ALIGNED,
- AccType_ORDERED
- } AccType;
-
- typedef struct
- {
- uint32_t
- N:1,
- V:1,
- C:1,
- Z:1, // condition code flags – can also be accessed as PSTATE.[N,Z,C,V]
- Q:1, // AArch32 only – CSPR.Q bit
- IT:8, // AArch32 only – CPSR.IT bits
- J:1, // AArch32 only – CSPR.J bit
- T:1, // AArch32 only – CPSR.T bit
- SS:1, // Single step process state bit
- IL:1, // Illegal state bit
- D:1,
- A:1,
- I:1,
- F:1, // Interrupt masks – can also be accessed as PSTATE.[D,A,I,F]
- E:1, // AArch32 only – CSPR.E bit
- M:5, // AArch32 only – mode encodings
- RW:1, // Current register width – 0 is AArch64, 1 is AArch32
- EL:2, // Current exception level (see ExceptionLevel enum)
- SP:1; // AArch64 only - Stack Pointer selection (see StackPointerSelection enum)
- } ProcState;
+ uint32_t GetPluginVersion() override { return 1; }
+
+ bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
+
+ bool SupportsEmulatingInstructionsOfType(
+ lldb_private::InstructionType inst_type) override {
+ return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
+ }
+
+ bool ReadInstruction() override;
+
+ bool EvaluateInstruction(uint32_t evaluate_options) override;
+
+ bool TestEmulation(lldb_private::Stream *out_stream,
+ lldb_private::ArchSpec &arch,
+ lldb_private::OptionValueDictionary *test_data) override {
+ return false;
+ }
+
+ bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ lldb_private::RegisterInfo &reg_info) override;
+
+ bool
+ CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
+
+ typedef enum { AddrMode_OFF, AddrMode_PRE, AddrMode_POST } AddrMode;
+
+ typedef enum {
+ BranchType_CALL,
+ BranchType_ERET,
+ BranchType_DRET,
+ BranchType_RET,
+ BranchType_JMP
+ } BranchType;
+
+ typedef enum { CountOp_CLZ, CountOp_CLS, CountOp_CNT } CountOp;
+
+ typedef enum { RevOp_RBIT, RevOp_REV16, RevOp_REV32, RevOp_REV64 } RevOp;
+
+ typedef enum { BitwiseOp_NOT, BitwiseOp_RBIT } BitwiseOp;
+
+ typedef enum { EL0 = 0, EL1 = 1, EL2 = 2, EL3 = 3 } ExceptionLevel;
+
+ typedef enum {
+ ExtendType_SXTB,
+ ExtendType_SXTH,
+ ExtendType_SXTW,
+ ExtendType_SXTX,
+ ExtendType_UXTB,
+ ExtendType_UXTH,
+ ExtendType_UXTW,
+ ExtendType_UXTX
+ } ExtendType;
+
+ typedef enum { ExtractType_LEFT, ExtractType_RIGHT } ExtractType;
+
+ typedef enum { LogicalOp_AND, LogicalOp_EOR, LogicalOp_ORR } LogicalOp;
+
+ typedef enum { MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH, MemOp_NOP } MemOp;
+
+ typedef enum { MoveWideOp_N, MoveWideOp_Z, MoveWideOp_K } MoveWideOp;
+
+ typedef enum {
+ ShiftType_LSL,
+ ShiftType_LSR,
+ ShiftType_ASR,
+ ShiftType_ROR
+ } ShiftType;
+
+ typedef enum { SP0 = 0, SPx = 1 } StackPointerSelection;
+
+ typedef enum {
+ Unpredictable_WBOVERLAP,
+ Unpredictable_LDPOVERLAP
+ } Unpredictable;
+
+ typedef enum {
+ Constraint_NONE,
+ Constraint_UNKNOWN,
+ Constraint_SUPPRESSWB,
+ Constraint_NOP
+ } ConstraintType;
+
+ typedef enum {
+ AccType_NORMAL,
+ AccType_UNPRIV,
+ AccType_STREAM,
+ AccType_ALIGNED,
+ AccType_ORDERED
+ } AccType;
+
+ typedef struct {
+ uint32_t N : 1, V : 1, C : 1,
+ Z : 1, // condition code flags – can also be accessed as
+ // PSTATE.[N,Z,C,V]
+ Q : 1, // AArch32 only – CSPR.Q bit
+ IT : 8, // AArch32 only – CPSR.IT bits
+ J : 1, // AArch32 only – CSPR.J bit
+ T : 1, // AArch32 only – CPSR.T bit
+ SS : 1, // Single step process state bit
+ IL : 1, // Illegal state bit
+ D : 1, A : 1, I : 1,
+ F : 1, // Interrupt masks – can also be accessed as PSTATE.[D,A,I,F]
+ E : 1, // AArch32 only – CSPR.E bit
+ M : 5, // AArch32 only – mode encodings
+ RW : 1, // Current register width – 0 is AArch64, 1 is AArch32
+ EL : 2, // Current exception level (see ExceptionLevel enum)
+ SP : 1; // AArch64 only - Stack Pointer selection (see
+ // StackPointerSelection enum)
+ } ProcState;
protected:
- typedef struct
- {
- uint32_t mask;
- uint32_t value;
- uint32_t vfp_variants;
- bool (EmulateInstructionARM64::*callback) (const uint32_t opcode);
- const char *name;
- } Opcode;
-
- static Opcode*
- GetOpcodeForInstruction (const uint32_t opcode);
+ typedef struct {
+ uint32_t mask;
+ uint32_t value;
+ uint32_t vfp_variants;
+ bool (EmulateInstructionARM64::*callback)(const uint32_t opcode);
+ const char *name;
+ } Opcode;
+
+ static Opcode *GetOpcodeForInstruction(const uint32_t opcode);
- uint32_t
- GetFramePointerRegisterNumber() const;
+ uint32_t GetFramePointerRegisterNumber() const;
- bool
- BranchTo (const Context &context, uint32_t N, lldb::addr_t target);
+ bool BranchTo(const Context &context, uint32_t N, lldb::addr_t target);
- bool
- ConditionHolds (const uint32_t cond);
+ bool ConditionHolds(const uint32_t cond);
- bool
- UsingAArch32 ();
+ bool UsingAArch32();
- bool
- EmulateADDSUBImm (const uint32_t opcode);
+ bool EmulateADDSUBImm(const uint32_t opcode);
- template <AddrMode a_mode> bool
- EmulateLDPSTP (const uint32_t opcode);
+ template <AddrMode a_mode> bool EmulateLDPSTP(const uint32_t opcode);
- template <AddrMode a_mode> bool
- EmulateLDRSTRImm (const uint32_t opcode);
+ template <AddrMode a_mode> bool EmulateLDRSTRImm(const uint32_t opcode);
- bool
- EmulateB (const uint32_t opcode);
+ bool EmulateB(const uint32_t opcode);
- bool
- EmulateBcond (const uint32_t opcode);
+ bool EmulateBcond(const uint32_t opcode);
- bool
- EmulateCBZ (const uint32_t opcode);
+ bool EmulateCBZ(const uint32_t opcode);
- bool
- EmulateTBZ (const uint32_t opcode);
+ bool EmulateTBZ(const uint32_t opcode);
- ProcState m_opcode_pstate;
- ProcState m_emulated_pstate; // This can get updated by the opcode.
- bool m_ignore_conditions;
+ ProcState m_opcode_pstate;
+ ProcState m_emulated_pstate; // This can get updated by the opcode.
+ bool m_ignore_conditions;
};
#endif // EmulateInstructionARM64_h_
diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index 47b98ca85b78..8cc34c171c72 100644
--- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -1,4 +1,5 @@
-//===-- EmulateInstructionMIPS.cpp -------------------------------*- C++ -*-===//
+//===-- EmulateInstructionMIPS.cpp -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,30 +12,30 @@
#include <stdlib.h>
-#include "llvm-c/Disassembler.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCDisassembler/MCDisassembler.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCContext.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/Opcode.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/PluginManager.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Opcode.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Target.h"
+#include "llvm-c/Disassembler.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/ADT/STLExtras.h"
#include "Plugins/Process/Utility/InstructionUtils.h"
-#include "Plugins/Process/Utility/RegisterContext_mips.h" //mips32 has same registers nos as mips64
+#include "Plugins/Process/Utility/RegisterContext_mips.h" //mips32 has same registers nos as mips64
using namespace lldb;
using namespace lldb_private;
@@ -42,7 +43,6 @@ using namespace lldb_private;
#define UInt(x) ((uint64_t)x)
#define integer int64_t
-
//----------------------------------------------------------------------
//
// EmulateInstructionMIPS implementation
@@ -51,1926 +51,2180 @@ using namespace lldb_private;
#ifdef __mips__
extern "C" {
- void LLVMInitializeMipsTargetInfo ();
- void LLVMInitializeMipsTarget ();
- void LLVMInitializeMipsAsmPrinter ();
- void LLVMInitializeMipsTargetMC ();
- void LLVMInitializeMipsDisassembler ();
+void LLVMInitializeMipsTargetInfo();
+void LLVMInitializeMipsTarget();
+void LLVMInitializeMipsAsmPrinter();
+void LLVMInitializeMipsTargetMC();
+void LLVMInitializeMipsDisassembler();
}
#endif
-EmulateInstructionMIPS::EmulateInstructionMIPS (const lldb_private::ArchSpec &arch) :
- EmulateInstruction (arch)
-{
- /* Create instance of llvm::MCDisassembler */
- std::string Error;
- llvm::Triple triple = arch.GetTriple();
- const llvm::Target *target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
+EmulateInstructionMIPS::EmulateInstructionMIPS(
+ const lldb_private::ArchSpec &arch)
+ : EmulateInstruction(arch) {
+ /* Create instance of llvm::MCDisassembler */
+ std::string Error;
+ llvm::Triple triple = arch.GetTriple();
+ const llvm::Target *target =
+ llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error);
- /*
- * If we fail to get the target then we haven't registered it. The SystemInitializerCommon
- * does not initialize targets, MCs and disassemblers. However we need the MCDisassembler
- * to decode the instructions so that the decoding complexity stays with LLVM.
- * Initialize the MIPS targets and disassemblers.
- */
+/*
+ * If we fail to get the target then we haven't registered it. The
+ * SystemInitializerCommon
+ * does not initialize targets, MCs and disassemblers. However we need the
+ * MCDisassembler
+ * to decode the instructions so that the decoding complexity stays with LLVM.
+ * Initialize the MIPS targets and disassemblers.
+*/
#ifdef __mips__
- if (!target)
- {
- LLVMInitializeMipsTargetInfo ();
- LLVMInitializeMipsTarget ();
- LLVMInitializeMipsAsmPrinter ();
- LLVMInitializeMipsTargetMC ();
- LLVMInitializeMipsDisassembler ();
- target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
- }
+ if (!target) {
+ LLVMInitializeMipsTargetInfo();
+ LLVMInitializeMipsTarget();
+ LLVMInitializeMipsAsmPrinter();
+ LLVMInitializeMipsTargetMC();
+ LLVMInitializeMipsDisassembler();
+ target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error);
+ }
#endif
- assert (target);
-
- llvm::StringRef cpu;
-
- switch (arch.GetCore())
- {
- case ArchSpec::eCore_mips32:
- case ArchSpec::eCore_mips32el:
- cpu = "mips32"; break;
- case ArchSpec::eCore_mips32r2:
- case ArchSpec::eCore_mips32r2el:
- cpu = "mips32r2"; break;
- case ArchSpec::eCore_mips32r3:
- case ArchSpec::eCore_mips32r3el:
- cpu = "mips32r3"; break;
- case ArchSpec::eCore_mips32r5:
- case ArchSpec::eCore_mips32r5el:
- cpu = "mips32r5"; break;
- case ArchSpec::eCore_mips32r6:
- case ArchSpec::eCore_mips32r6el:
- cpu = "mips32r6"; break;
- case ArchSpec::eCore_mips64:
- case ArchSpec::eCore_mips64el:
- cpu = "mips64"; break;
- case ArchSpec::eCore_mips64r2:
- case ArchSpec::eCore_mips64r2el:
- cpu = "mips64r2"; break;
- case ArchSpec::eCore_mips64r3:
- case ArchSpec::eCore_mips64r3el:
- cpu = "mips64r3"; break;
- case ArchSpec::eCore_mips64r5:
- case ArchSpec::eCore_mips64r5el:
- cpu = "mips64r5"; break;
- case ArchSpec::eCore_mips64r6:
- case ArchSpec::eCore_mips64r6el:
- cpu = "mips64r6"; break;
- default:
- cpu = "generic"; break;
- }
-
- std::string features = "";
- uint32_t arch_flags = arch.GetFlags ();
- if (arch_flags & ArchSpec::eMIPSAse_msa)
- features += "+msa,";
- if (arch_flags & ArchSpec::eMIPSAse_dsp)
- features += "+dsp,";
- if (arch_flags & ArchSpec::eMIPSAse_dspr2)
- features += "+dspr2,";
-
- m_reg_info.reset (target->createMCRegInfo (triple.getTriple()));
- assert (m_reg_info.get());
-
- m_insn_info.reset (target->createMCInstrInfo());
- assert (m_insn_info.get());
-
- m_asm_info.reset (target->createMCAsmInfo (*m_reg_info, triple.getTriple()));
- m_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features));
- assert (m_asm_info.get() && m_subtype_info.get());
-
- m_context.reset (new llvm::MCContext (m_asm_info.get(), m_reg_info.get(), nullptr));
- assert (m_context.get());
-
- m_disasm.reset (target->createMCDisassembler (*m_subtype_info, *m_context));
- assert (m_disasm.get());
-
- /* Create alternate disassembler for microMIPS */
- if (arch_flags & ArchSpec::eMIPSAse_mips16)
- features += "+mips16,";
- else if (arch_flags & ArchSpec::eMIPSAse_micromips)
- features += "+micromips,";
-
- m_alt_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features));
- assert (m_alt_subtype_info.get());
-
- m_alt_disasm.reset (target->createMCDisassembler (*m_alt_subtype_info, *m_context));
- assert (m_alt_disasm.get());
-
- m_next_inst_size = 0;
- m_use_alt_disaasm = false;
+ assert(target);
+
+ llvm::StringRef cpu;
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_mips32:
+ case ArchSpec::eCore_mips32el:
+ cpu = "mips32";
+ break;
+ case ArchSpec::eCore_mips32r2:
+ case ArchSpec::eCore_mips32r2el:
+ cpu = "mips32r2";
+ break;
+ case ArchSpec::eCore_mips32r3:
+ case ArchSpec::eCore_mips32r3el:
+ cpu = "mips32r3";
+ break;
+ case ArchSpec::eCore_mips32r5:
+ case ArchSpec::eCore_mips32r5el:
+ cpu = "mips32r5";
+ break;
+ case ArchSpec::eCore_mips32r6:
+ case ArchSpec::eCore_mips32r6el:
+ cpu = "mips32r6";
+ break;
+ case ArchSpec::eCore_mips64:
+ case ArchSpec::eCore_mips64el:
+ cpu = "mips64";
+ break;
+ case ArchSpec::eCore_mips64r2:
+ case ArchSpec::eCore_mips64r2el:
+ cpu = "mips64r2";
+ break;
+ case ArchSpec::eCore_mips64r3:
+ case ArchSpec::eCore_mips64r3el:
+ cpu = "mips64r3";
+ break;
+ case ArchSpec::eCore_mips64r5:
+ case ArchSpec::eCore_mips64r5el:
+ cpu = "mips64r5";
+ break;
+ case ArchSpec::eCore_mips64r6:
+ case ArchSpec::eCore_mips64r6el:
+ cpu = "mips64r6";
+ break;
+ default:
+ cpu = "generic";
+ break;
+ }
+
+ std::string features = "";
+ uint32_t arch_flags = arch.GetFlags();
+ if (arch_flags & ArchSpec::eMIPSAse_msa)
+ features += "+msa,";
+ if (arch_flags & ArchSpec::eMIPSAse_dsp)
+ features += "+dsp,";
+ if (arch_flags & ArchSpec::eMIPSAse_dspr2)
+ features += "+dspr2,";
+
+ m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
+ assert(m_reg_info.get());
+
+ m_insn_info.reset(target->createMCInstrInfo());
+ assert(m_insn_info.get());
+
+ m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple()));
+ m_subtype_info.reset(
+ target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
+ assert(m_asm_info.get() && m_subtype_info.get());
+
+ m_context.reset(
+ new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
+ assert(m_context.get());
+
+ m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
+ assert(m_disasm.get());
+
+ /* Create alternate disassembler for microMIPS */
+ if (arch_flags & ArchSpec::eMIPSAse_mips16)
+ features += "+mips16,";
+ else if (arch_flags & ArchSpec::eMIPSAse_micromips)
+ features += "+micromips,";
+
+ m_alt_subtype_info.reset(
+ target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
+ assert(m_alt_subtype_info.get());
+
+ m_alt_disasm.reset(
+ target->createMCDisassembler(*m_alt_subtype_info, *m_context));
+ assert(m_alt_disasm.get());
+
+ m_next_inst_size = 0;
+ m_use_alt_disaasm = false;
+}
+
+void EmulateInstructionMIPS::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void EmulateInstructionMIPS::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString EmulateInstructionMIPS::GetPluginNameStatic() {
+ ConstString g_plugin_name("lldb.emulate-instruction.mips32");
+ return g_plugin_name;
+}
+
+lldb_private::ConstString EmulateInstructionMIPS::GetPluginName() {
+ static ConstString g_plugin_name("EmulateInstructionMIPS");
+ return g_plugin_name;
+}
+
+const char *EmulateInstructionMIPS::GetPluginDescriptionStatic() {
+ return "Emulate instructions for the MIPS32 architecture.";
}
-void
-EmulateInstructionMIPS::Initialize ()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic (),
- GetPluginDescriptionStatic (),
- CreateInstance);
-}
-
-void
-EmulateInstructionMIPS::Terminate ()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-ConstString
-EmulateInstructionMIPS::GetPluginNameStatic ()
-{
- ConstString g_plugin_name ("lldb.emulate-instruction.mips32");
- return g_plugin_name;
-}
-
-lldb_private::ConstString
-EmulateInstructionMIPS::GetPluginName()
-{
- static ConstString g_plugin_name ("EmulateInstructionMIPS");
- return g_plugin_name;
-}
+EmulateInstruction *
+EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch,
+ InstructionType inst_type) {
+ if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(
+ inst_type)) {
+ if (arch.GetTriple().getArch() == llvm::Triple::mips ||
+ arch.GetTriple().getArch() == llvm::Triple::mipsel) {
+ std::auto_ptr<EmulateInstructionMIPS> emulate_insn_ap(
+ new EmulateInstructionMIPS(arch));
+ if (emulate_insn_ap.get())
+ return emulate_insn_ap.release();
+ }
+ }
-const char *
-EmulateInstructionMIPS::GetPluginDescriptionStatic ()
-{
- return "Emulate instructions for the MIPS32 architecture.";
+ return NULL;
}
-EmulateInstruction *
-EmulateInstructionMIPS::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
-{
- if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
- {
- if (arch.GetTriple().getArch() == llvm::Triple::mips
- || arch.GetTriple().getArch() == llvm::Triple::mipsel)
- {
- std::auto_ptr<EmulateInstructionMIPS> emulate_insn_ap (new EmulateInstructionMIPS (arch));
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
- }
+bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) {
+ if (arch.GetTriple().getArch() == llvm::Triple::mips ||
+ arch.GetTriple().getArch() == llvm::Triple::mipsel)
+ return true;
+ return false;
+}
+
+const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num,
+ bool alternate_name) {
+ if (alternate_name) {
+ switch (reg_num) {
+ case dwarf_sp_mips:
+ return "r29";
+ case dwarf_r30_mips:
+ return "r30";
+ case dwarf_ra_mips:
+ return "r31";
+ case dwarf_f0_mips:
+ return "f0";
+ case dwarf_f1_mips:
+ return "f1";
+ case dwarf_f2_mips:
+ return "f2";
+ case dwarf_f3_mips:
+ return "f3";
+ case dwarf_f4_mips:
+ return "f4";
+ case dwarf_f5_mips:
+ return "f5";
+ case dwarf_f6_mips:
+ return "f6";
+ case dwarf_f7_mips:
+ return "f7";
+ case dwarf_f8_mips:
+ return "f8";
+ case dwarf_f9_mips:
+ return "f9";
+ case dwarf_f10_mips:
+ return "f10";
+ case dwarf_f11_mips:
+ return "f11";
+ case dwarf_f12_mips:
+ return "f12";
+ case dwarf_f13_mips:
+ return "f13";
+ case dwarf_f14_mips:
+ return "f14";
+ case dwarf_f15_mips:
+ return "f15";
+ case dwarf_f16_mips:
+ return "f16";
+ case dwarf_f17_mips:
+ return "f17";
+ case dwarf_f18_mips:
+ return "f18";
+ case dwarf_f19_mips:
+ return "f19";
+ case dwarf_f20_mips:
+ return "f20";
+ case dwarf_f21_mips:
+ return "f21";
+ case dwarf_f22_mips:
+ return "f22";
+ case dwarf_f23_mips:
+ return "f23";
+ case dwarf_f24_mips:
+ return "f24";
+ case dwarf_f25_mips:
+ return "f25";
+ case dwarf_f26_mips:
+ return "f26";
+ case dwarf_f27_mips:
+ return "f27";
+ case dwarf_f28_mips:
+ return "f28";
+ case dwarf_f29_mips:
+ return "f29";
+ case dwarf_f30_mips:
+ return "f30";
+ case dwarf_f31_mips:
+ return "f31";
+ case dwarf_w0_mips:
+ return "w0";
+ case dwarf_w1_mips:
+ return "w1";
+ case dwarf_w2_mips:
+ return "w2";
+ case dwarf_w3_mips:
+ return "w3";
+ case dwarf_w4_mips:
+ return "w4";
+ case dwarf_w5_mips:
+ return "w5";
+ case dwarf_w6_mips:
+ return "w6";
+ case dwarf_w7_mips:
+ return "w7";
+ case dwarf_w8_mips:
+ return "w8";
+ case dwarf_w9_mips:
+ return "w9";
+ case dwarf_w10_mips:
+ return "w10";
+ case dwarf_w11_mips:
+ return "w11";
+ case dwarf_w12_mips:
+ return "w12";
+ case dwarf_w13_mips:
+ return "w13";
+ case dwarf_w14_mips:
+ return "w14";
+ case dwarf_w15_mips:
+ return "w15";
+ case dwarf_w16_mips:
+ return "w16";
+ case dwarf_w17_mips:
+ return "w17";
+ case dwarf_w18_mips:
+ return "w18";
+ case dwarf_w19_mips:
+ return "w19";
+ case dwarf_w20_mips:
+ return "w20";
+ case dwarf_w21_mips:
+ return "w21";
+ case dwarf_w22_mips:
+ return "w22";
+ case dwarf_w23_mips:
+ return "w23";
+ case dwarf_w24_mips:
+ return "w24";
+ case dwarf_w25_mips:
+ return "w25";
+ case dwarf_w26_mips:
+ return "w26";
+ case dwarf_w27_mips:
+ return "w27";
+ case dwarf_w28_mips:
+ return "w28";
+ case dwarf_w29_mips:
+ return "w29";
+ case dwarf_w30_mips:
+ return "w30";
+ case dwarf_w31_mips:
+ return "w31";
+ case dwarf_mir_mips:
+ return "mir";
+ case dwarf_mcsr_mips:
+ return "mcsr";
+ case dwarf_config5_mips:
+ return "config5";
+ default:
+ break;
+ }
+ return nullptr;
+ }
+
+ switch (reg_num) {
+ case dwarf_zero_mips:
+ return "r0";
+ case dwarf_r1_mips:
+ return "r1";
+ case dwarf_r2_mips:
+ return "r2";
+ case dwarf_r3_mips:
+ return "r3";
+ case dwarf_r4_mips:
+ return "r4";
+ case dwarf_r5_mips:
+ return "r5";
+ case dwarf_r6_mips:
+ return "r6";
+ case dwarf_r7_mips:
+ return "r7";
+ case dwarf_r8_mips:
+ return "r8";
+ case dwarf_r9_mips:
+ return "r9";
+ case dwarf_r10_mips:
+ return "r10";
+ case dwarf_r11_mips:
+ return "r11";
+ case dwarf_r12_mips:
+ return "r12";
+ case dwarf_r13_mips:
+ return "r13";
+ case dwarf_r14_mips:
+ return "r14";
+ case dwarf_r15_mips:
+ return "r15";
+ case dwarf_r16_mips:
+ return "r16";
+ case dwarf_r17_mips:
+ return "r17";
+ case dwarf_r18_mips:
+ return "r18";
+ case dwarf_r19_mips:
+ return "r19";
+ case dwarf_r20_mips:
+ return "r20";
+ case dwarf_r21_mips:
+ return "r21";
+ case dwarf_r22_mips:
+ return "r22";
+ case dwarf_r23_mips:
+ return "r23";
+ case dwarf_r24_mips:
+ return "r24";
+ case dwarf_r25_mips:
+ return "r25";
+ case dwarf_r26_mips:
+ return "r26";
+ case dwarf_r27_mips:
+ return "r27";
+ case dwarf_gp_mips:
+ return "gp";
+ case dwarf_sp_mips:
+ return "sp";
+ case dwarf_r30_mips:
+ return "fp";
+ case dwarf_ra_mips:
+ return "ra";
+ case dwarf_sr_mips:
+ return "sr";
+ case dwarf_lo_mips:
+ return "lo";
+ case dwarf_hi_mips:
+ return "hi";
+ case dwarf_bad_mips:
+ return "bad";
+ case dwarf_cause_mips:
+ return "cause";
+ case dwarf_pc_mips:
+ return "pc";
+ case dwarf_f0_mips:
+ return "f0";
+ case dwarf_f1_mips:
+ return "f1";
+ case dwarf_f2_mips:
+ return "f2";
+ case dwarf_f3_mips:
+ return "f3";
+ case dwarf_f4_mips:
+ return "f4";
+ case dwarf_f5_mips:
+ return "f5";
+ case dwarf_f6_mips:
+ return "f6";
+ case dwarf_f7_mips:
+ return "f7";
+ case dwarf_f8_mips:
+ return "f8";
+ case dwarf_f9_mips:
+ return "f9";
+ case dwarf_f10_mips:
+ return "f10";
+ case dwarf_f11_mips:
+ return "f11";
+ case dwarf_f12_mips:
+ return "f12";
+ case dwarf_f13_mips:
+ return "f13";
+ case dwarf_f14_mips:
+ return "f14";
+ case dwarf_f15_mips:
+ return "f15";
+ case dwarf_f16_mips:
+ return "f16";
+ case dwarf_f17_mips:
+ return "f17";
+ case dwarf_f18_mips:
+ return "f18";
+ case dwarf_f19_mips:
+ return "f19";
+ case dwarf_f20_mips:
+ return "f20";
+ case dwarf_f21_mips:
+ return "f21";
+ case dwarf_f22_mips:
+ return "f22";
+ case dwarf_f23_mips:
+ return "f23";
+ case dwarf_f24_mips:
+ return "f24";
+ case dwarf_f25_mips:
+ return "f25";
+ case dwarf_f26_mips:
+ return "f26";
+ case dwarf_f27_mips:
+ return "f27";
+ case dwarf_f28_mips:
+ return "f28";
+ case dwarf_f29_mips:
+ return "f29";
+ case dwarf_f30_mips:
+ return "f30";
+ case dwarf_f31_mips:
+ return "f31";
+ case dwarf_fcsr_mips:
+ return "fcsr";
+ case dwarf_fir_mips:
+ return "fir";
+ case dwarf_w0_mips:
+ return "w0";
+ case dwarf_w1_mips:
+ return "w1";
+ case dwarf_w2_mips:
+ return "w2";
+ case dwarf_w3_mips:
+ return "w3";
+ case dwarf_w4_mips:
+ return "w4";
+ case dwarf_w5_mips:
+ return "w5";
+ case dwarf_w6_mips:
+ return "w6";
+ case dwarf_w7_mips:
+ return "w7";
+ case dwarf_w8_mips:
+ return "w8";
+ case dwarf_w9_mips:
+ return "w9";
+ case dwarf_w10_mips:
+ return "w10";
+ case dwarf_w11_mips:
+ return "w11";
+ case dwarf_w12_mips:
+ return "w12";
+ case dwarf_w13_mips:
+ return "w13";
+ case dwarf_w14_mips:
+ return "w14";
+ case dwarf_w15_mips:
+ return "w15";
+ case dwarf_w16_mips:
+ return "w16";
+ case dwarf_w17_mips:
+ return "w17";
+ case dwarf_w18_mips:
+ return "w18";
+ case dwarf_w19_mips:
+ return "w19";
+ case dwarf_w20_mips:
+ return "w20";
+ case dwarf_w21_mips:
+ return "w21";
+ case dwarf_w22_mips:
+ return "w22";
+ case dwarf_w23_mips:
+ return "w23";
+ case dwarf_w24_mips:
+ return "w24";
+ case dwarf_w25_mips:
+ return "w25";
+ case dwarf_w26_mips:
+ return "w26";
+ case dwarf_w27_mips:
+ return "w27";
+ case dwarf_w28_mips:
+ return "w28";
+ case dwarf_w29_mips:
+ return "w29";
+ case dwarf_w30_mips:
+ return "w30";
+ case dwarf_w31_mips:
+ return "w31";
+ case dwarf_mcsr_mips:
+ return "mcsr";
+ case dwarf_mir_mips:
+ return "mir";
+ case dwarf_config5_mips:
+ return "config5";
+ }
+ return nullptr;
+}
+
+bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterInfo &reg_info) {
+ if (reg_kind == eRegisterKindGeneric) {
+ switch (reg_num) {
+ case LLDB_REGNUM_GENERIC_PC:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_pc_mips;
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_sp_mips;
+ break;
+ case LLDB_REGNUM_GENERIC_FP:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_r30_mips;
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_ra_mips;
+ break;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_sr_mips;
+ break;
+ default:
+ return false;
+ }
+ }
+
+ if (reg_kind == eRegisterKindDWARF) {
+ ::memset(&reg_info, 0, sizeof(RegisterInfo));
+ ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
+
+ if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips ||
+ reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips ||
+ reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) {
+ reg_info.byte_size = 4;
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ } else if ((int)reg_num >= dwarf_zero_mips &&
+ (int)reg_num <= dwarf_f31_mips) {
+ reg_info.byte_size = 4;
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ } else if ((int)reg_num >= dwarf_w0_mips &&
+ (int)reg_num <= dwarf_w31_mips) {
+ reg_info.byte_size = 16;
+ reg_info.format = eFormatVectorOfUInt8;
+ reg_info.encoding = eEncodingVector;
+ } else {
+ return false;
+ }
+
+ reg_info.name = GetRegisterName(reg_num, false);
+ reg_info.alt_name = GetRegisterName(reg_num, true);
+ reg_info.kinds[eRegisterKindDWARF] = reg_num;
+
+ switch (reg_num) {
+ case dwarf_r30_mips:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ break;
+ case dwarf_ra_mips:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+ break;
+ case dwarf_sp_mips:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ break;
+ case dwarf_pc_mips:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ break;
+ case dwarf_sr_mips:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ break;
+ default:
+ break;
}
-
- return NULL;
+ return true;
+ }
+ return false;
+}
+
+EmulateInstructionMIPS::MipsOpcode *
+EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) {
+ static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = {
+ //----------------------------------------------------------------------
+ // Prologue/Epilogue instructions
+ //----------------------------------------------------------------------
+ {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu,
+ "ADDIU rt, rs, immediate"},
+ {"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"},
+ {"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"},
+ {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"},
+ {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"},
+ {"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"},
+
+ //----------------------------------------------------------------------
+ // MicroMIPS Prologue/Epilogue instructions
+ //----------------------------------------------------------------------
+ {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP,
+ "ADDIU immediate"},
+ {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5,
+ "ADDIUS5 rd,immediate"},
+ {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"},
+ {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
+ "SWM16 reglist,offset(sp)"},
+ {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
+ "SWM32 reglist,offset(base)"},
+ {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
+ "SWP rs1,offset(base)"},
+ {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"},
+ {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
+ "LWM16 reglist,offset(sp)"},
+ {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
+ "LWM32 reglist,offset(base)"},
+ {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
+ "LWP rd,offset(base)"},
+ {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP,
+ "JRADDIUSP immediate"},
+ //----------------------------------------------------------------------
+
+ // Load/Store instructions
+ //----------------------------------------------------------------------
+ /* Following list of emulated instructions are required by implementation
+ of hardware watchpoint
+ for MIPS in lldb. As we just need the address accessed by instructions,
+ we have generalised
+ all these instructions in 2 functions depending on their addressing
+ modes */
+
+ {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LB rt, offset(base)"},
+ {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LBE rt, offset(base)"},
+ {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LBU rt, offset(base)"},
+ {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LBUE rt, offset(base)"},
+ {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LDC1 ft, offset(base)"},
+ {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LD rt, offset(base)"},
+ {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LDL rt, offset(base)"},
+ {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LDR rt, offset(base)"},
+ {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LLD rt, offset(base)"},
+ {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LDC2 rt, offset(base)"},
+ {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "LDXC1 fd, index (base)"},
+ {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LH rt, offset(base)"},
+ {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LHE rt, offset(base)"},
+ {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LHU rt, offset(base)"},
+ {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LHUE rt, offset(base)"},
+ {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LL rt, offset(base)"},
+ {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LLE rt, offset(base)"},
+ {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "LUXC1 fd, index (base)"},
+ {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LW rt, offset(base)"},
+ {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWC1 ft, offset(base)"},
+ {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWC2 rt, offset(base)"},
+ {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWE rt, offset(base)"},
+ {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWL rt, offset(base)"},
+ {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWLE rt, offset(base)"},
+ {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWR rt, offset(base)"},
+ {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWRE rt, offset(base)"},
+ {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "LWXC1 fd, index (base)"},
+ {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LLX rt, offset(base)"},
+ {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LLXE rt, offset(base)"},
+ {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LLDX rt, offset(base)"},
+
+ {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SB rt, offset(base)"},
+ {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SBE rt, offset(base)"},
+ {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SC rt, offset(base)"},
+ {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SCE rt, offset(base)"},
+ {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SCD rt, offset(base)"},
+ {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SD rt, offset(base)"},
+ {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SDL rt, offset(base)"},
+ {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SDR rt, offset(base)"},
+ {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SDC1 ft, offset(base)"},
+ {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SDC2 rt, offset(base)"},
+ {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "SDXC1 fs, index(base)"},
+ {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SH rt, offset(base)"},
+ {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SHE rt, offset(base)"},
+ {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "SUXC1 fs, index (base)"},
+ {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWC1 ft, offset(base)"},
+ {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWC2 rt, offset(base)"},
+ {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWE rt, offset(base)"},
+ {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWL rt, offset(base)"},
+ {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWLE rt, offset(base)"},
+ {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWR rt, offset(base)"},
+ {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWRE rt, offset(base)"},
+ {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "SWXC1 fs, index (base)"},
+ {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SCX rt, offset(base)"},
+ {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SCXE rt, offset(base)"},
+ {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SCDX rt, offset(base)"},
+
+ //----------------------------------------------------------------------
+ // MicroMIPS Load/Store instructions
+ //----------------------------------------------------------------------
+ {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LBU16 rt, decoded_offset(base)"},
+ {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LHU16 rt, left_shifted_offset(base)"},
+ {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LW16 rt, left_shifted_offset(base)"},
+ {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWGP rt, left_shifted_offset(gp)"},
+ {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SH16 rt, left_shifted_offset(base)"},
+ {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SW16 rt, left_shifted_offset(base)"},
+ {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWSP rt, left_shifted_offset(base)"},
+ {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SB16 rt, offset(base)"},
+
+ //----------------------------------------------------------------------
+ // Branch instructions
+ //----------------------------------------------------------------------
+ {"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
+ {"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset"},
+ {"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset"},
+ {"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset"},
+ {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
+ "BGEZALL rt,offset"},
+ {"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"},
+ {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
+ "BGEZAL rs,offset"},
+ {"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"},
+ {"BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset"},
+ {"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset"},
+ {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BLEZALC rs,offset"},
+ {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BGEZALC rs,offset"},
+ {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BLTZALC rs,offset"},
+ {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BGTZALC rs,offset"},
+ {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BEQZALC rs,offset"},
+ {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BNEZALC rs,offset"},
+ {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BEQC rs,rt,offset"},
+ {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BNEC rs,rt,offset"},
+ {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BLTC rs,rt,offset"},
+ {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BGEC rs,rt,offset"},
+ {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BLTUC rs,rt,offset"},
+ {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BGEUC rs,rt,offset"},
+ {"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset"},
+ {"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset"},
+ {"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset"},
+ {"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset"},
+ {"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset"},
+ {"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset"},
+ {"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset"},
+ {"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset"},
+ {"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset"},
+ {"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset"},
+ {"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset"},
+ {"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset"},
+ {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
+ "BLTZAL rt,offset"},
+ {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
+ "BLTZALL rt,offset"},
+ {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"},
+ {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BOVC rs,rt,offset"},
+ {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BNVC rs,rt,offset"},
+ {"J", &EmulateInstructionMIPS::Emulate_J, "J target"},
+ {"JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target"},
+ {"JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target"},
+ {"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"},
+ {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"},
+ {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"},
+ {"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"},
+ {"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"},
+ {"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"},
+ {"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset"},
+ {"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset"},
+ {"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset"},
+ {"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset"},
+ {"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset"},
+ {"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset"},
+ {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch,
+ "BC1ANY2F cc, offset"},
+ {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch,
+ "BC1ANY2T cc, offset"},
+ {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch,
+ "BC1ANY4F cc, offset"},
+ {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch,
+ "BC1ANY4T cc, offset"},
+ {"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16"},
+ {"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16"},
+ {"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16"},
+ {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"},
+ {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"},
+ {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"},
+ {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"},
+ {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"},
+ {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"},
+ {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"},
+
+ //----------------------------------------------------------------------
+ // MicroMIPS Branch instructions
+ //----------------------------------------------------------------------
+ {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"},
+ {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BEQZ16 rs, offset"},
+ {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BNEZ16 rs, offset"},
+ {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BEQZC rs, offset"},
+ {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BNEZC rs, offset"},
+ {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BGEZALS rs, offset"},
+ {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BLTZALS rs, offset"},
+ {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"},
+ {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"},
+ {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"},
+ {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"},
+ {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"},
+ {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"},
+ {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"},
+ };
+
+ static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
+
+ for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
+ if (!strcasecmp(g_opcodes[i].op_name, op_name))
+ return &g_opcodes[i];
+ }
+
+ return NULL;
}
-bool
-EmulateInstructionMIPS::SetTargetTriple (const ArchSpec &arch)
-{
- if (arch.GetTriple().getArch () == llvm::Triple::mips
- || arch.GetTriple().getArch () == llvm::Triple::mipsel)
- return true;
+uint32_t
+EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data,
+ uint64_t inst_addr) {
+ uint64_t next_inst_size = 0;
+ llvm::MCInst mc_insn;
+ llvm::MCDisassembler::DecodeStatus decode_status;
+ llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
+
+ if (m_use_alt_disaasm)
+ decode_status =
+ m_alt_disasm->getInstruction(mc_insn, next_inst_size, raw_insn,
+ inst_addr, llvm::nulls(), llvm::nulls());
+ else
+ decode_status =
+ m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, inst_addr,
+ llvm::nulls(), llvm::nulls());
+
+ if (decode_status != llvm::MCDisassembler::Success)
return false;
+
+ return m_insn_info->get(mc_insn.getOpcode()).getSize();
}
-const char *
-EmulateInstructionMIPS::GetRegisterName (unsigned reg_num, bool alternate_name)
-{
- if (alternate_name)
- {
- switch (reg_num)
- {
- case dwarf_sp_mips: return "r29";
- case dwarf_r30_mips: return "r30";
- case dwarf_ra_mips: return "r31";
- case dwarf_f0_mips: return "f0";
- case dwarf_f1_mips: return "f1";
- case dwarf_f2_mips: return "f2";
- case dwarf_f3_mips: return "f3";
- case dwarf_f4_mips: return "f4";
- case dwarf_f5_mips: return "f5";
- case dwarf_f6_mips: return "f6";
- case dwarf_f7_mips: return "f7";
- case dwarf_f8_mips: return "f8";
- case dwarf_f9_mips: return "f9";
- case dwarf_f10_mips: return "f10";
- case dwarf_f11_mips: return "f11";
- case dwarf_f12_mips: return "f12";
- case dwarf_f13_mips: return "f13";
- case dwarf_f14_mips: return "f14";
- case dwarf_f15_mips: return "f15";
- case dwarf_f16_mips: return "f16";
- case dwarf_f17_mips: return "f17";
- case dwarf_f18_mips: return "f18";
- case dwarf_f19_mips: return "f19";
- case dwarf_f20_mips: return "f20";
- case dwarf_f21_mips: return "f21";
- case dwarf_f22_mips: return "f22";
- case dwarf_f23_mips: return "f23";
- case dwarf_f24_mips: return "f24";
- case dwarf_f25_mips: return "f25";
- case dwarf_f26_mips: return "f26";
- case dwarf_f27_mips: return "f27";
- case dwarf_f28_mips: return "f28";
- case dwarf_f29_mips: return "f29";
- case dwarf_f30_mips: return "f30";
- case dwarf_f31_mips: return "f31";
- case dwarf_w0_mips: return "w0";
- case dwarf_w1_mips: return "w1";
- case dwarf_w2_mips: return "w2";
- case dwarf_w3_mips: return "w3";
- case dwarf_w4_mips: return "w4";
- case dwarf_w5_mips: return "w5";
- case dwarf_w6_mips: return "w6";
- case dwarf_w7_mips: return "w7";
- case dwarf_w8_mips: return "w8";
- case dwarf_w9_mips: return "w9";
- case dwarf_w10_mips: return "w10";
- case dwarf_w11_mips: return "w11";
- case dwarf_w12_mips: return "w12";
- case dwarf_w13_mips: return "w13";
- case dwarf_w14_mips: return "w14";
- case dwarf_w15_mips: return "w15";
- case dwarf_w16_mips: return "w16";
- case dwarf_w17_mips: return "w17";
- case dwarf_w18_mips: return "w18";
- case dwarf_w19_mips: return "w19";
- case dwarf_w20_mips: return "w20";
- case dwarf_w21_mips: return "w21";
- case dwarf_w22_mips: return "w22";
- case dwarf_w23_mips: return "w23";
- case dwarf_w24_mips: return "w24";
- case dwarf_w25_mips: return "w25";
- case dwarf_w26_mips: return "w26";
- case dwarf_w27_mips: return "w27";
- case dwarf_w28_mips: return "w28";
- case dwarf_w29_mips: return "w29";
- case dwarf_w30_mips: return "w30";
- case dwarf_w31_mips: return "w31";
- case dwarf_mir_mips: return "mir";
- case dwarf_mcsr_mips: return "mcsr";
- case dwarf_config5_mips: return "config5";
- default:
- break;
- }
- return nullptr;
- }
+bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
+ const Address &inst_addr,
+ Target *target) {
+ m_use_alt_disaasm = false;
- switch (reg_num)
- {
- case dwarf_zero_mips: return "r0";
- case dwarf_r1_mips: return "r1";
- case dwarf_r2_mips: return "r2";
- case dwarf_r3_mips: return "r3";
- case dwarf_r4_mips: return "r4";
- case dwarf_r5_mips: return "r5";
- case dwarf_r6_mips: return "r6";
- case dwarf_r7_mips: return "r7";
- case dwarf_r8_mips: return "r8";
- case dwarf_r9_mips: return "r9";
- case dwarf_r10_mips: return "r10";
- case dwarf_r11_mips: return "r11";
- case dwarf_r12_mips: return "r12";
- case dwarf_r13_mips: return "r13";
- case dwarf_r14_mips: return "r14";
- case dwarf_r15_mips: return "r15";
- case dwarf_r16_mips: return "r16";
- case dwarf_r17_mips: return "r17";
- case dwarf_r18_mips: return "r18";
- case dwarf_r19_mips: return "r19";
- case dwarf_r20_mips: return "r20";
- case dwarf_r21_mips: return "r21";
- case dwarf_r22_mips: return "r22";
- case dwarf_r23_mips: return "r23";
- case dwarf_r24_mips: return "r24";
- case dwarf_r25_mips: return "r25";
- case dwarf_r26_mips: return "r26";
- case dwarf_r27_mips: return "r27";
- case dwarf_gp_mips: return "gp";
- case dwarf_sp_mips: return "sp";
- case dwarf_r30_mips: return "fp";
- case dwarf_ra_mips: return "ra";
- case dwarf_sr_mips: return "sr";
- case dwarf_lo_mips: return "lo";
- case dwarf_hi_mips: return "hi";
- case dwarf_bad_mips: return "bad";
- case dwarf_cause_mips: return "cause";
- case dwarf_pc_mips: return "pc";
- case dwarf_f0_mips: return "f0";
- case dwarf_f1_mips: return "f1";
- case dwarf_f2_mips: return "f2";
- case dwarf_f3_mips: return "f3";
- case dwarf_f4_mips: return "f4";
- case dwarf_f5_mips: return "f5";
- case dwarf_f6_mips: return "f6";
- case dwarf_f7_mips: return "f7";
- case dwarf_f8_mips: return "f8";
- case dwarf_f9_mips: return "f9";
- case dwarf_f10_mips: return "f10";
- case dwarf_f11_mips: return "f11";
- case dwarf_f12_mips: return "f12";
- case dwarf_f13_mips: return "f13";
- case dwarf_f14_mips: return "f14";
- case dwarf_f15_mips: return "f15";
- case dwarf_f16_mips: return "f16";
- case dwarf_f17_mips: return "f17";
- case dwarf_f18_mips: return "f18";
- case dwarf_f19_mips: return "f19";
- case dwarf_f20_mips: return "f20";
- case dwarf_f21_mips: return "f21";
- case dwarf_f22_mips: return "f22";
- case dwarf_f23_mips: return "f23";
- case dwarf_f24_mips: return "f24";
- case dwarf_f25_mips: return "f25";
- case dwarf_f26_mips: return "f26";
- case dwarf_f27_mips: return "f27";
- case dwarf_f28_mips: return "f28";
- case dwarf_f29_mips: return "f29";
- case dwarf_f30_mips: return "f30";
- case dwarf_f31_mips: return "f31";
- case dwarf_fcsr_mips: return "fcsr";
- case dwarf_fir_mips: return "fir";
- case dwarf_w0_mips: return "w0";
- case dwarf_w1_mips: return "w1";
- case dwarf_w2_mips: return "w2";
- case dwarf_w3_mips: return "w3";
- case dwarf_w4_mips: return "w4";
- case dwarf_w5_mips: return "w5";
- case dwarf_w6_mips: return "w6";
- case dwarf_w7_mips: return "w7";
- case dwarf_w8_mips: return "w8";
- case dwarf_w9_mips: return "w9";
- case dwarf_w10_mips: return "w10";
- case dwarf_w11_mips: return "w11";
- case dwarf_w12_mips: return "w12";
- case dwarf_w13_mips: return "w13";
- case dwarf_w14_mips: return "w14";
- case dwarf_w15_mips: return "w15";
- case dwarf_w16_mips: return "w16";
- case dwarf_w17_mips: return "w17";
- case dwarf_w18_mips: return "w18";
- case dwarf_w19_mips: return "w19";
- case dwarf_w20_mips: return "w20";
- case dwarf_w21_mips: return "w21";
- case dwarf_w22_mips: return "w22";
- case dwarf_w23_mips: return "w23";
- case dwarf_w24_mips: return "w24";
- case dwarf_w25_mips: return "w25";
- case dwarf_w26_mips: return "w26";
- case dwarf_w27_mips: return "w27";
- case dwarf_w28_mips: return "w28";
- case dwarf_w29_mips: return "w29";
- case dwarf_w30_mips: return "w30";
- case dwarf_w31_mips: return "w31";
- case dwarf_mcsr_mips: return "mcsr";
- case dwarf_mir_mips: return "mir";
- case dwarf_config5_mips: return "config5";
- }
- return nullptr;
-}
+ if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
+ if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA) {
+ Error error;
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
-bool
-EmulateInstructionMIPS::GetRegisterInfo (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
-{
- if (reg_kind == eRegisterKindGeneric)
- {
- switch (reg_num)
- {
- case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc_mips; break;
- case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp_mips; break;
- case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r30_mips; break;
- case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_ra_mips; break;
- case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sr_mips; break;
- default:
- return false;
- }
- }
+ /*
+ * The address belongs to microMIPS function. To find the size of
+ * next instruction use microMIPS disassembler.
+ */
+ m_use_alt_disaasm = true;
- if (reg_kind == eRegisterKindDWARF)
- {
- ::memset (&reg_info, 0, sizeof(RegisterInfo));
- ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
-
- if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips || reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips || reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips)
- {
- reg_info.byte_size = 4;
- reg_info.format = eFormatHex;
- reg_info.encoding = eEncodingUint;
- }
- else if ((int)reg_num >= dwarf_zero_mips && (int)reg_num <= dwarf_f31_mips)
- {
- reg_info.byte_size = 4;
- reg_info.format = eFormatHex;
- reg_info.encoding = eEncodingUint;
- }
- else if ((int)reg_num >= dwarf_w0_mips && (int)reg_num <= dwarf_w31_mips)
- {
- reg_info.byte_size = 16;
- reg_info.format = eFormatVectorOfUInt8;
- reg_info.encoding = eEncodingVector;
- }
- else
- {
- return false;
- }
-
- reg_info.name = GetRegisterName (reg_num, false);
- reg_info.alt_name = GetRegisterName (reg_num, true);
- reg_info.kinds[eRegisterKindDWARF] = reg_num;
-
- switch (reg_num)
- {
- case dwarf_r30_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break;
- case dwarf_ra_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break;
- case dwarf_sp_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break;
- case dwarf_pc_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break;
- case dwarf_sr_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; break;
- default: break;
- }
- return true;
- }
- return false;
-}
+ uint32_t current_inst_size = insn_opcode.GetByteSize();
+ uint8_t buf[sizeof(uint32_t)];
+ uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
+ Address next_addr(next_inst_addr);
-EmulateInstructionMIPS::MipsOpcode*
-EmulateInstructionMIPS::GetOpcodeForInstruction (const char *op_name)
-{
- static EmulateInstructionMIPS::MipsOpcode
- g_opcodes[] =
- {
- //----------------------------------------------------------------------
- // Prologue/Epilogue instructions
- //----------------------------------------------------------------------
- { "ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu, "ADDIU rt, rs, immediate" },
- { "SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)" },
- { "LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)" },
- { "SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt" },
- { "ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt" },
- { "LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate" },
-
- //----------------------------------------------------------------------
- // MicroMIPS Prologue/Epilogue instructions
- //----------------------------------------------------------------------
- { "ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP, "ADDIU immediate" },
- { "ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5, "ADDIUS5 rd,immediate" },
- { "SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)" },
- { "SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWM16 reglist,offset(sp)" },
- { "SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWM32 reglist,offset(base)" },
- { "SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWP rs1,offset(base)" },
- { "LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)" },
- { "LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWM16 reglist,offset(sp)" },
- { "LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWM32 reglist,offset(base)" },
- { "LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWP rd,offset(base)" },
- { "JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP, "JRADDIUSP immediate" },
- //----------------------------------------------------------------------
-
- // Load/Store instructions
- //----------------------------------------------------------------------
- /* Following list of emulated instructions are required by implementation of hardware watchpoint
- for MIPS in lldb. As we just need the address accessed by instructions, we have generalised
- all these instructions in 2 functions depending on their addressing modes */
-
- { "LB", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LB rt, offset(base)" },
- { "LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBE rt, offset(base)" },
- { "LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBU rt, offset(base)" },
- { "LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBUE rt, offset(base)" },
- { "LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDC1 ft, offset(base)" },
- { "LD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LD rt, offset(base)" },
- { "LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDL rt, offset(base)" },
- { "LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDR rt, offset(base)" },
- { "LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLD rt, offset(base)" },
- { "LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDC2 rt, offset(base)" },
- { "LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LDXC1 fd, index (base)" },
- { "LH", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LH rt, offset(base)" },
- { "LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHE rt, offset(base)" },
- { "LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHU rt, offset(base)" },
- { "LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHUE rt, offset(base)" },
- { "LL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LL rt, offset(base)" },
- { "LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLE rt, offset(base)" },
- { "LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LUXC1 fd, index (base)" },
- { "LW", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LW rt, offset(base)" },
- { "LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWC1 ft, offset(base)" },
- { "LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWC2 rt, offset(base)" },
- { "LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWE rt, offset(base)" },
- { "LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWL rt, offset(base)" },
- { "LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWLE rt, offset(base)" },
- { "LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWR rt, offset(base)" },
- { "LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWRE rt, offset(base)" },
- { "LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LWXC1 fd, index (base)" },
- { "LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLX rt, offset(base)" },
- { "LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLXE rt, offset(base)" },
- { "LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLDX rt, offset(base)" },
-
- { "SB", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SB rt, offset(base)" },
- { "SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SBE rt, offset(base)" },
- { "SC", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SC rt, offset(base)" },
- { "SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCE rt, offset(base)" },
- { "SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCD rt, offset(base)" },
- { "SD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SD rt, offset(base)" },
- { "SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDL rt, offset(base)" },
- { "SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDR rt, offset(base)" },
- { "SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDC1 ft, offset(base)" },
- { "SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDC2 rt, offset(base)" },
- { "SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SDXC1 fs, index(base)" },
- { "SH", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SH rt, offset(base)" },
- { "SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SHE rt, offset(base)" },
- { "SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SUXC1 fs, index (base)" },
- { "SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWC1 ft, offset(base)" },
- { "SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWC2 rt, offset(base)" },
- { "SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWE rt, offset(base)" },
- { "SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWL rt, offset(base)" },
- { "SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWLE rt, offset(base)" },
- { "SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWR rt, offset(base)" },
- { "SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWRE rt, offset(base)" },
- { "SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SWXC1 fs, index (base)" },
- { "SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCX rt, offset(base)" },
- { "SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCXE rt, offset(base)" },
- { "SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCDX rt, offset(base)" },
-
- //----------------------------------------------------------------------
- // MicroMIPS Load/Store instructions
- //----------------------------------------------------------------------
- { "LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBU16 rt, decoded_offset(base)" },
- { "LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHU16 rt, left_shifted_offset(base)" },
- { "LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LW16 rt, left_shifted_offset(base)" },
- { "LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWGP rt, left_shifted_offset(gp)" },
- { "SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SH16 rt, left_shifted_offset(base)" },
- { "SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SW16 rt, left_shifted_offset(base)" },
- { "SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWSP rt, left_shifted_offset(base)" },
- { "SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SB16 rt, offset(base)" },
-
- //----------------------------------------------------------------------
- // Branch instructions
- //----------------------------------------------------------------------
- { "BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset" },
- { "BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset" },
- { "BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset" },
- { "BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset" },
- { "BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BGEZALL rt,offset" },
- { "BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset" },
- { "BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BGEZAL rs,offset" },
- { "BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset" },
- { "BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset" },
- { "BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset" },
- { "BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BLEZALC rs,offset" },
- { "BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BGEZALC rs,offset" },
- { "BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BLTZALC rs,offset" },
- { "BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BGTZALC rs,offset" },
- { "BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BEQZALC rs,offset" },
- { "BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BNEZALC rs,offset" },
- { "BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BEQC rs,rt,offset" },
- { "BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BNEC rs,rt,offset" },
- { "BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BLTC rs,rt,offset" },
- { "BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BGEC rs,rt,offset" },
- { "BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BLTUC rs,rt,offset" },
- { "BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BGEUC rs,rt,offset" },
- { "BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset" },
- { "BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset" },
- { "BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset" },
- { "BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset" },
- { "BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset" },
- { "BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset" },
- { "BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset" },
- { "BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset" },
- { "BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset" },
- { "BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset" },
- { "BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset" },
- { "BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset" },
- { "BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BLTZAL rt,offset" },
- { "BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BLTZALL rt,offset" },
- { "BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset" },
- { "BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BOVC rs,rt,offset" },
- { "BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BNVC rs,rt,offset" },
- { "J", &EmulateInstructionMIPS::Emulate_J, "J target" },
- { "JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target" },
- { "JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target" },
- { "JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target" },
- { "JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target" },
- { "JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset" },
- { "JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset" },
- { "JR", &EmulateInstructionMIPS::Emulate_JR, "JR target" },
- { "JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target" },
- { "BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset" },
- { "BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset" },
- { "BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset" },
- { "BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset" },
- { "BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset" },
- { "BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset" },
- { "BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY2F cc, offset" },
- { "BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY2T cc, offset" },
- { "BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY4F cc, offset" },
- { "BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY4T cc, offset" },
- { "BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16" },
- { "BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16" },
- { "BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16" },
- { "BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16" },
- { "BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16" },
- { "BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16" },
- { "BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16" },
- { "BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16" },
- { "BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16" },
- { "BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16" },
-
- //----------------------------------------------------------------------
- // MicroMIPS Branch instructions
- //----------------------------------------------------------------------
- { "B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset" },
- { "BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BEQZ16 rs, offset" },
- { "BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BNEZ16 rs, offset" },
- { "BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BEQZC rs, offset" },
- { "BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BNEZC rs, offset" },
- { "BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BGEZALS rs, offset" },
- { "BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BLTZALS rs, offset" },
- { "JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs" },
- { "JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs" },
- { "JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs" },
- { "JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs" },
- { "JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target" },
- { "JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target" },
- { "JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs" },
- };
-
- static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
-
- for (size_t i = 0; i < k_num_mips_opcodes; ++i)
- {
- if (! strcasecmp (g_opcodes[i].op_name, op_name))
- return &g_opcodes[i];
- }
+ const size_t bytes_read =
+ target->ReadMemory(next_addr, /* Address of next instruction */
+ true, /* prefer_file_cache */
+ buf, sizeof(uint32_t), error, &load_addr);
- return NULL;
-}
+ if (bytes_read == 0)
+ return true;
-uint32_t
-EmulateInstructionMIPS::GetSizeOfInstruction (lldb_private::DataExtractor& data, uint64_t inst_addr)
-{
- uint64_t next_inst_size = 0;
- llvm::MCInst mc_insn;
+ DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(),
+ GetAddressByteSize());
+ m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr);
+ return true;
+ } else {
+ /*
+ * If the address class is not eAddressClassCodeAlternateISA then
+ * the function is not microMIPS. In this case instruction size is
+ * always 4 bytes.
+ */
+ m_next_inst_size = 4;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool EmulateInstructionMIPS::ReadInstruction() {
+ bool success = false;
+ m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_ADDRESS, &success);
+ if (success) {
+ Context read_inst_context;
+ read_inst_context.type = eContextReadOpcode;
+ read_inst_context.SetNoArgs();
+ m_opcode.SetOpcode32(
+ ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
+ GetByteOrder());
+ }
+ if (!success)
+ m_addr = LLDB_INVALID_ADDRESS;
+ return success;
+}
+
+bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) {
+ bool success = false;
+ llvm::MCInst mc_insn;
+ uint64_t insn_size;
+ DataExtractor data;
+
+ /* Keep the complexity of the decode logic with the llvm::MCDisassembler
+ * class. */
+ if (m_opcode.GetData(data)) {
llvm::MCDisassembler::DecodeStatus decode_status;
- llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize());
-
+ llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
if (m_use_alt_disaasm)
- decode_status = m_alt_disasm->getInstruction (mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls(), llvm::nulls());
+ decode_status = m_alt_disasm->getInstruction(
+ mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
else
- decode_status = m_disasm->getInstruction (mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls(), llvm::nulls());
+ decode_status = m_disasm->getInstruction(
+ mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
if (decode_status != llvm::MCDisassembler::Success)
- return false;
-
- return m_insn_info->get(mc_insn.getOpcode()).getSize();
-}
-
-bool
-EmulateInstructionMIPS::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
-{
- m_use_alt_disaasm = false;
-
- if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
- {
- if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA)
- {
- Error error;
- lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
-
- /*
- * The address belongs to microMIPS function. To find the size of
- * next instruction use microMIPS disassembler.
- */
- m_use_alt_disaasm = true;
-
- uint32_t current_inst_size = insn_opcode.GetByteSize();
- uint8_t buf[sizeof(uint32_t)];
- uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
- Address next_addr (next_inst_addr);
-
- const size_t bytes_read = target->ReadMemory (next_addr, /* Address of next instruction */
- true, /* prefer_file_cache */
- buf,
- sizeof(uint32_t),
- error,
- &load_addr);
-
- if (bytes_read == 0)
- return true;
-
- DataExtractor data (buf, sizeof(uint32_t), GetByteOrder(), GetAddressByteSize());
- m_next_inst_size = GetSizeOfInstruction (data, next_inst_addr);
- return true;
- }
- else
- {
- /*
- * If the address class is not eAddressClassCodeAlternateISA then
- * the function is not microMIPS. In this case instruction size is
- * always 4 bytes.
- */
- m_next_inst_size = 4;
- return true;
- }
- }
- return false;
-}
+ return false;
+ }
-bool
-EmulateInstructionMIPS::ReadInstruction ()
-{
- bool success = false;
- m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
- if (success)
- {
- Context read_inst_context;
- read_inst_context.type = eContextReadOpcode;
- read_inst_context.SetNoArgs ();
- m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder());
- }
- if (!success)
- m_addr = LLDB_INVALID_ADDRESS;
- return success;
-}
-
-bool
-EmulateInstructionMIPS::EvaluateInstruction (uint32_t evaluate_options)
-{
- bool success = false;
- llvm::MCInst mc_insn;
- uint64_t insn_size;
- DataExtractor data;
-
- /* Keep the complexity of the decode logic with the llvm::MCDisassembler class. */
- if (m_opcode.GetData (data))
- {
- llvm::MCDisassembler::DecodeStatus decode_status;
- llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize());
- if (m_use_alt_disaasm)
- decode_status = m_alt_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
- else
- decode_status = m_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
-
- if (decode_status != llvm::MCDisassembler::Success)
- return false;
- }
+ /*
+ * mc_insn.getOpcode() returns decoded opcode. However to make use
+ * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
+ */
+ const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
- /*
- * mc_insn.getOpcode() returns decoded opcode. However to make use
- * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
- */
- const char *op_name = m_insn_info->getName (mc_insn.getOpcode ());
+ if (op_name == NULL)
+ return false;
- if (op_name == NULL)
- return false;
+ /*
+ * Decoding has been done already. Just get the call-back function
+ * and emulate the instruction.
+ */
+ MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
- /*
- * Decoding has been done already. Just get the call-back function
- * and emulate the instruction.
- */
- MipsOpcode *opcode_data = GetOpcodeForInstruction (op_name);
+ if (opcode_data == NULL)
+ return false;
- if (opcode_data == NULL)
- return false;
+ uint64_t old_pc = 0, new_pc = 0;
+ const bool auto_advance_pc =
+ evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
- uint64_t old_pc = 0, new_pc = 0;
- const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+ if (auto_advance_pc) {
+ old_pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
+ }
- if (auto_advance_pc)
- {
- old_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
- }
+ /* emulate instruction */
+ success = (this->*opcode_data->callback)(mc_insn);
+ if (!success)
+ return false;
- /* emulate instruction */
- success = (this->*opcode_data->callback) (mc_insn);
+ if (auto_advance_pc) {
+ new_pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
- return false;
+ return false;
- if (auto_advance_pc)
- {
- new_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- /* If we haven't changed the PC, change it here */
- if (old_pc == new_pc)
- {
- new_pc += 4;
- Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, new_pc))
- return false;
- }
+ /* If we haven't changed the PC, change it here */
+ if (old_pc == new_pc) {
+ new_pc += 4;
+ Context context;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ new_pc))
+ return false;
}
+ }
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
+ UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const bool can_replace = false;
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const bool can_replace = false;
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
- // Our previous PC is in the RA
- row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
+ // Our previous PC is in the RA
+ row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
- unwind_plan.AppendRow (row);
+ unwind_plan.AppendRow(row);
- // All other registers are the same.
- unwind_plan.SetSourceName ("EmulateInstructionMIPS");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
- unwind_plan.SetReturnAddressRegister (dwarf_ra_mips);
+ // All other registers are the same.
+ unwind_plan.SetSourceName("EmulateInstructionMIPS");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::nonvolatile_reg_p (uint32_t regnum)
-{
- switch (regnum)
- {
- case dwarf_r16_mips:
- case dwarf_r17_mips:
- case dwarf_r18_mips:
- case dwarf_r19_mips:
- case dwarf_r20_mips:
- case dwarf_r21_mips:
- case dwarf_r22_mips:
- case dwarf_r23_mips:
- case dwarf_gp_mips:
- case dwarf_sp_mips:
- case dwarf_r30_mips:
- case dwarf_ra_mips:
- return true;
- default:
- return false;
- }
+bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) {
+ switch (regnum) {
+ case dwarf_r16_mips:
+ case dwarf_r17_mips:
+ case dwarf_r18_mips:
+ case dwarf_r19_mips:
+ case dwarf_r20_mips:
+ case dwarf_r21_mips:
+ case dwarf_r22_mips:
+ case dwarf_r23_mips:
+ case dwarf_gp_mips:
+ case dwarf_sp_mips:
+ case dwarf_r30_mips:
+ case dwarf_ra_mips:
+ return true;
+ default:
return false;
-}
-
-bool
-EmulateInstructionMIPS::Emulate_ADDiu (llvm::MCInst& insn)
-{
- // ADDIU rt, rs, immediate
- // GPR[rt] <- GPR[rs] + sign_extend(immediate)
-
- uint8_t dst, src;
- bool success = false;
- const uint32_t imm16 = insn.getOperand(2).getImm();
- int64_t imm = SignedBits(imm16, 15, 0);
-
- dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
-
- // If immediate value is greater then 2^16 - 1 then clang generate
- // LUI, ADDIU, SUBU instructions in prolog.
- // Example
- // lui $1, 0x2
- // addiu $1, $1, -0x5920
- // subu $sp, $sp, $1
- // In this case, ADDIU dst and src will be same and not equal to sp
- if (dst == src)
- {
- Context context;
+ }
+ return false;
+}
+
+bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
+ // ADDIU rt, rs, immediate
+ // GPR[rt] <- GPR[rs] + sign_extend(immediate)
+
+ uint8_t dst, src;
+ bool success = false;
+ const uint32_t imm16 = insn.getOperand(2).getImm();
+ int64_t imm = SignedBits(imm16, 15, 0);
+
+ dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+
+ // If immediate value is greater then 2^16 - 1 then clang generate
+ // LUI, ADDIU, SUBU instructions in prolog.
+ // Example
+ // lui $1, 0x2
+ // addiu $1, $1, -0x5920
+ // subu $sp, $sp, $1
+ // In this case, ADDIU dst and src will be same and not equal to sp
+ if (dst == src) {
+ Context context;
- /* read <src> register */
- const int64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
- if (!success)
- return false;
+ /* read <src> register */
+ const int64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
+ if (!success)
+ return false;
- /* Check if this is daddiu sp, sp, imm16 */
- if (dst == dwarf_sp_mips)
- {
- uint64_t result = src_opd_val + imm;
- RegisterInfo reg_info_sp;
+ /* Check if this is daddiu sp, sp, imm16 */
+ if (dst == dwarf_sp_mips) {
+ uint64_t result = src_opd_val + imm;
+ RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, imm);
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, imm);
- /* We are allocating bytes on stack */
- context.type = eContextAdjustStackPointer;
+ /* We are allocating bytes on stack */
+ context.type = eContextAdjustStackPointer;
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
- return true;
- }
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
+ return true;
+ }
- imm += src_opd_val;
- context.SetImmediateSigned (imm);
- context.type = eContextImmediate;
+ imm += src_opd_val;
+ context.SetImmediateSigned(imm);
+ context.type = eContextImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + dst, imm))
- return false;
- }
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips + dst, imm))
+ return false;
+ }
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_SW (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t imm16 = insn.getOperand(2).getImm();
- uint32_t imm = SignedBits(imm16, 15, 0);
- uint32_t src, base;
- int32_t address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t imm16 = insn.getOperand(2).getImm();
+ uint32_t imm = SignedBits(imm16, 15, 0);
+ uint32_t src, base;
+ int32_t address;
+ Context bad_vaddr_context;
- RegisterInfo reg_info_base;
+ RegisterInfo reg_info_base;
- src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- /* read base register */
- address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- /* We look for sp based non-volatile register stores */
- if (nonvolatile_reg_p (src))
- {
+ /* We look for sp based non-volatile register stores */
+ if (nonvolatile_reg_p(src)) {
- RegisterInfo reg_info_src;
+ RegisterInfo reg_info_src;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
+ reg_info_src))
+ return false;
- Context context;
- RegisterValue data_src;
- context.type = eContextPushRegisterOnStack;
- context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
+ Context context;
+ RegisterValue data_src;
+ context.type = eContextPushRegisterOnStack;
+ context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
- uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
- Error error;
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ Error error;
- if (!ReadRegister (&reg_info_base, data_src))
- return false;
+ if (!ReadRegister(&reg_info_base, data_src))
+ return false;
- if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
- return false;
+ if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- if (!WriteMemory (context, address, buffer, reg_info_src.byte_size))
- return false;
+ if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
-bool
-EmulateInstructionMIPS::Emulate_LW (llvm::MCInst& insn)
-{
- bool success =false;
- uint32_t src, base;
- int32_t imm, address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t src, base;
+ int32_t imm, address;
+ Context bad_vaddr_context;
- src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- imm = insn.getOperand(2).getImm();
+ src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ imm = insn.getOperand(2).getImm();
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- /* read base register */
- address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- if (nonvolatile_reg_p (src))
- {
- RegisterValue data_src;
- RegisterInfo reg_info_src;
+ if (nonvolatile_reg_p(src)) {
+ RegisterValue data_src;
+ RegisterInfo reg_info_src;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
+ reg_info_src))
+ return false;
- Context context;
- context.type = eContextPopRegisterOffStack;
- context.SetAddress (address);
+ Context context;
+ context.type = eContextPopRegisterOffStack;
+ context.SetAddress(address);
- if (!WriteRegister (context, &reg_info_src, data_src))
- return false;
+ if (!WriteRegister(context, &reg_info_src, data_src))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
-bool
-EmulateInstructionMIPS::Emulate_SUBU_ADDU (llvm::MCInst& insn)
-{
- // SUBU sp, <src>, <rt>
- // ADDU sp, <src>, <rt>
- // ADDU dst, sp, <rt>
+bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) {
+ // SUBU sp, <src>, <rt>
+ // ADDU sp, <src>, <rt>
+ // ADDU dst, sp, <rt>
- bool success = false;
- uint64_t result;
- uint8_t src, dst, rt;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ bool success = false;
+ uint64_t result;
+ uint8_t src, dst, rt;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- /* Check if sp is destination register */
- if (dst == dwarf_sp_mips)
- {
- rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg());
+ dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- /* read <src> register */
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
- if (!success)
- return false;
+ /* Check if sp is destination register */
+ if (dst == dwarf_sp_mips) {
+ rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
- /* read <rt > register */
- uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ /* read <src> register */
+ uint64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "SUBU"))
- result = src_opd_val - rt_opd_val;
- else
- result = src_opd_val + rt_opd_val;
+ /* read <rt > register */
+ uint64_t rt_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- Context context;
- RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, rt_opd_val);
+ if (!strcasecmp(op_name, "SUBU"))
+ result = src_opd_val - rt_opd_val;
+ else
+ result = src_opd_val + rt_opd_val;
- /* We are allocating bytes on stack */
- context.type = eContextAdjustStackPointer;
+ Context context;
+ RegisterInfo reg_info_sp;
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
+ /* We are allocating bytes on stack */
+ context.type = eContextAdjustStackPointer;
- return true;
- }
- else if (src == dwarf_sp_mips)
- {
- rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg());
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
- /* read <src> register */
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
- if (!success)
- return false;
+ return true;
+ } else if (src == dwarf_sp_mips) {
+ rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
- /* read <rt> register */
- uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ /* read <src> register */
+ uint64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
+ if (!success)
+ return false;
- Context context;
+ /* read <rt> register */
+ uint64_t rt_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "SUBU"))
- result = src_opd_val - rt_opd_val;
- else
- result = src_opd_val + rt_opd_val;
+ Context context;
- context.SetImmediateSigned (result);
- context.type = eContextImmediate;
+ if (!strcasecmp(op_name, "SUBU"))
+ result = src_opd_val - rt_opd_val;
+ else
+ result = src_opd_val + rt_opd_val;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + dst, result))
- return false;
- }
+ context.SetImmediateSigned(result);
+ context.type = eContextImmediate;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips + dst, result))
+ return false;
+ }
+
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_LUI (llvm::MCInst& insn)
-{
- // LUI rt, immediate
- // GPR[rt] <- sign_extend(immediate << 16)
+bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) {
+ // LUI rt, immediate
+ // GPR[rt] <- sign_extend(immediate << 16)
- const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
- int64_t imm = SignedBits(imm32, 31, 0);
- uint8_t rt;
- Context context;
-
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- context.SetImmediateSigned (imm);
- context.type = eContextImmediate;
+ const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
+ int64_t imm = SignedBits(imm32, 31, 0);
+ uint8_t rt;
+ Context context;
- if (WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, imm))
- return true;
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ context.SetImmediateSigned(imm);
+ context.type = eContextImmediate;
- return false;
+ if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
+ imm))
+ return true;
+
+ return false;
}
-bool
-EmulateInstructionMIPS::Emulate_ADDIUSP (llvm::MCInst& insn)
-{
- bool success = false;
- const uint32_t imm9 = insn.getOperand(0).getImm();
- uint64_t result;
+bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
+ bool success = false;
+ const uint32_t imm9 = insn.getOperand(0).getImm();
+ uint64_t result;
- // This instruction operates implicitly on stack pointer, so read <sp> register.
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
- if (!success)
- return false;
+ // This instruction operates implicitly on stack pointer, so read <sp>
+ // register.
+ uint64_t src_opd_val =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
+ if (!success)
+ return false;
- result = src_opd_val + imm9;
+ result = src_opd_val + imm9;
- Context context;
- RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, imm9);
+ Context context;
+ RegisterInfo reg_info_sp;
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, imm9);
- // We are adjusting the stack.
- context.type = eContextAdjustStackPointer;
+ // We are adjusting the stack.
+ context.type = eContextAdjustStackPointer;
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
- return true;
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_ADDIUS5 (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t base;
- const uint32_t imm4 = insn.getOperand(2).getImm();
- uint64_t result;
+bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t base;
+ const uint32_t imm4 = insn.getOperand(2).getImm();
+ uint64_t result;
- // The source and destination register is same for this instruction.
- base = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ // The source and destination register is same for this instruction.
+ base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
- // We are looking for stack adjustment only
- if (base == dwarf_sp_mips)
- {
- // Read stack pointer register
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ // We are looking for stack adjustment only
+ if (base == dwarf_sp_mips) {
+ // Read stack pointer register
+ uint64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- result = src_opd_val + imm4;
+ result = src_opd_val + imm4;
- Context context;
- RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, imm4);
+ Context context;
+ RegisterInfo reg_info_sp;
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, imm4);
- // We are adjusting the stack.
- context.type = eContextAdjustStackPointer;
+ // We are adjusting the stack.
+ context.type = eContextAdjustStackPointer;
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
- }
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
+ }
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_SWSP (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t imm5 = insn.getOperand(2).getImm();
- uint32_t src, base;
- Context bad_vaddr_context;
- uint32_t address;
+bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t imm5 = insn.getOperand(2).getImm();
+ uint32_t src, base;
+ Context bad_vaddr_context;
+ uint32_t address;
- src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- RegisterInfo reg_info_base;
+ RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- // read base register
- address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ // read base register
+ address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
+ &success);
+ if (!success)
+ return false;
- // destination address
- address = address + imm5;
+ // destination address
+ address = address + imm5;
- // We use bad_vaddr_context to store base address which is used by H/W watchpoint
- // Set the bad_vaddr register with base address used in the instruction
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ // We use bad_vaddr_context to store base address which is used by H/W
+ // watchpoint
+ // Set the bad_vaddr register with base address used in the instruction
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- // We look for sp based non-volatile register stores.
- if (base == dwarf_sp_mips && nonvolatile_reg_p (src))
- {
- RegisterInfo reg_info_src = {};
- Context context;
- RegisterValue data_src;
- context.type = eContextPushRegisterOnStack;
- context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
+ // We look for sp based non-volatile register stores.
+ if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
+ RegisterInfo reg_info_src = {};
+ Context context;
+ RegisterValue data_src;
+ context.type = eContextPushRegisterOnStack;
+ context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
- uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
- Error error;
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ Error error;
- if (!ReadRegister (&reg_info_base, data_src))
- return false;
+ if (!ReadRegister(&reg_info_base, data_src))
+ return false;
- if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
- return false;
+ if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- if (!WriteMemory (context, address, buffer, reg_info_src.byte_size))
- return false;
+ if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
/* Emulate SWM16,SWM32 and SWP instruction.
- SWM16 always has stack pointer as a base register (but it is still available in MCInst as an operand).
+ SWM16 always has stack pointer as a base register (but it is still available
+ in MCInst as an operand).
SWM32 and SWP can have base register other than stack pointer.
*/
-bool
-EmulateInstructionMIPS::Emulate_SWM16_32 (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t src, base;
- uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on no of regs to store.
-
- // Base register is second last operand of the instruction.
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
-
- // We are looking for sp based stores so if base is not a stack pointer then don't proceed.
- if (base != dwarf_sp_mips)
- return false;
+bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t src, base;
+ uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
+ // no of regs to store.
+
+ // Base register is second last operand of the instruction.
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+
+ // We are looking for sp based stores so if base is not a stack pointer then
+ // don't proceed.
+ if (base != dwarf_sp_mips)
+ return false;
- // offset is always the last operand.
- uint32_t offset = insn.getOperand(num_operands-1).getImm();
+ // offset is always the last operand.
+ uint32_t offset = insn.getOperand(num_operands - 1).getImm();
- RegisterInfo reg_info_base;
- RegisterInfo reg_info_src;
-
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ RegisterInfo reg_info_src;
- // read SP
- uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- // Resulting base addrss
- base_address = base_address + offset;
+ // read SP
+ uint32_t base_address = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- // Total no of registers to be stored are num_operands-2.
- for (uint32_t i = 0; i < num_operands - 2; i++)
- {
- // Get the register number to be stored.
- src = m_reg_info->getEncodingValue (insn.getOperand(i).getReg());
+ // Resulting base addrss
+ base_address = base_address + offset;
- /*
- Record only non-volatile stores.
- This check is required for SWP instruction because source operand could be any register.
- SWM16 and SWM32 instruction always has saved registers as source operands.
- */
- if (!nonvolatile_reg_p (src))
- return false;
+ // Total no of registers to be stored are num_operands-2.
+ for (uint32_t i = 0; i < num_operands - 2; i++) {
+ // Get the register number to be stored.
+ src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
- return false;
+ /*
+ Record only non-volatile stores.
+ This check is required for SWP instruction because source operand could
+ be any register.
+ SWM16 and SWM32 instruction always has saved registers as source
+ operands.
+ */
+ if (!nonvolatile_reg_p(src))
+ return false;
- Context context;
- RegisterValue data_src;
- context.type = eContextPushRegisterOnStack;
- context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
+ reg_info_src))
+ return false;
- uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
- Error error;
+ Context context;
+ RegisterValue data_src;
+ context.type = eContextPushRegisterOnStack;
+ context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
- if (!ReadRegister (&reg_info_base, data_src))
- return false;
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ Error error;
- if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
- return false;
+ if (!ReadRegister(&reg_info_base, data_src))
+ return false;
- if (!WriteMemory (context, base_address, buffer, reg_info_src.byte_size))
- return false;
+ if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- // Stack address for next register
- base_address = base_address + reg_info_src.byte_size;
- }
- return true;
+ if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size))
+ return false;
+
+ // Stack address for next register
+ base_address = base_address + reg_info_src.byte_size;
+ }
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_LWSP (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- uint32_t base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- uint32_t imm5 = insn.getOperand(2).getImm();
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ uint32_t imm5 = insn.getOperand(2).getImm();
+ Context bad_vaddr_context;
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- // read base register
- uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ // read base register
+ uint32_t base_address = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- base_address = base_address + imm5;
+ base_address = base_address + imm5;
- // We use bad_vaddr_context to store base address which is used by H/W watchpoint
- // Set the bad_vaddr register with base address used in the instruction
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, base_address);
+ // We use bad_vaddr_context to store base address which is used by H/W
+ // watchpoint
+ // Set the bad_vaddr register with base address used in the instruction
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ base_address);
- if (base == dwarf_sp_mips && nonvolatile_reg_p (src))
- {
- RegisterValue data_src;
- RegisterInfo reg_info_src;
+ if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
+ RegisterValue data_src;
+ RegisterInfo reg_info_src;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
+ reg_info_src))
+ return false;
- Context context;
- context.type = eContextPopRegisterOffStack;
- context.SetAddress (base_address);
+ Context context;
+ context.type = eContextPopRegisterOffStack;
+ context.SetAddress(base_address);
- if (!WriteRegister (context, &reg_info_src, data_src))
- return false;
+ if (!WriteRegister(context, &reg_info_src, data_src))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
/* Emulate LWM16, LWM32 and LWP instructions.
- LWM16 always has stack pointer as a base register (but it is still available in MCInst as an operand).
+ LWM16 always has stack pointer as a base register (but it is still available
+ in MCInst as an operand).
LWM32 and LWP can have base register other than stack pointer.
*/
-bool
-EmulateInstructionMIPS::Emulate_LWM16_32 (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t dst, base;
- uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on no of regs to store.
- uint32_t imm = insn.getOperand(num_operands-1).getImm(); // imm is the last operand in the instruction.
-
- // Base register is second last operand of the instruction.
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
-
- // We are looking for sp based loads so if base is not a stack pointer then don't proceed.
- if (base != dwarf_sp_mips)
- return false;
+bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t dst, base;
+ uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
+ // no of regs to store.
+ uint32_t imm = insn.getOperand(num_operands - 1)
+ .getImm(); // imm is the last operand in the instruction.
+
+ // Base register is second last operand of the instruction.
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+
+ // We are looking for sp based loads so if base is not a stack pointer then
+ // don't proceed.
+ if (base != dwarf_sp_mips)
+ return false;
- uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ uint32_t base_address = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- base_address = base_address + imm;
-
- RegisterValue data_dst;
- RegisterInfo reg_info_dst;
-
- // Total no of registers to be re-stored are num_operands-2.
- for (uint32_t i = 0; i < num_operands - 2; i++)
- {
- // Get the register number to be re-stored.
- dst = m_reg_info->getEncodingValue (insn.getOperand(i).getReg());
-
- /*
- Record only non-volatile loads.
- This check is required for LWP instruction because destination operand could be any register.
- LWM16 and LWM32 instruction always has saved registers as destination operands.
- */
- if (!nonvolatile_reg_p (dst))
- return false;
-
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + dst, reg_info_dst))
- return false;
-
- Context context;
- context.type = eContextPopRegisterOffStack;
- context.SetAddress (base_address + (i*4));
-
- if (!WriteRegister (context, &reg_info_dst, data_dst))
- return false;
- }
+ base_address = base_address + imm;
- return true;
-}
+ RegisterValue data_dst;
+ RegisterInfo reg_info_dst;
-bool
-EmulateInstructionMIPS::Emulate_JRADDIUSP (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t imm5 = insn.getOperand(0).getImm();
+ // Total no of registers to be re-stored are num_operands-2.
+ for (uint32_t i = 0; i < num_operands - 2; i++) {
+ // Get the register number to be re-stored.
+ dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
- /* JRADDIUSP immediate
- * PC <- RA
- * SP <- SP + zero_extend(Immediate << 2)
+ /*
+ Record only non-volatile loads.
+ This check is required for LWP instruction because destination operand
+ could be any register.
+ LWM16 and LWM32 instruction always has saved registers as destination
+ operands.
*/
-
- // This instruction operates implicitly on stack pointer, so read <sp> register.
- int32_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
- if (!success)
- return false;
+ if (!nonvolatile_reg_p(dst))
+ return false;
- int32_t ra_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
- if (!success)
- return false;
-
- int32_t result = src_opd_val + imm5;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst,
+ reg_info_dst))
+ return false;
Context context;
+ context.type = eContextPopRegisterOffStack;
+ context.SetAddress(base_address + (i * 4));
- // Update the PC
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, ra_val))
- return false;
-
- RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, imm5);
+ if (!WriteRegister(context, &reg_info_dst, data_dst))
+ return false;
+ }
- // We are adjusting stack
- context.type = eContextAdjustStackPointer;
+ return true;
+}
- // update SP
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result))
- return false;
+bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t imm5 = insn.getOperand(0).getImm();
- return true;
+ /* JRADDIUSP immediate
+ * PC <- RA
+ * SP <- SP + zero_extend(Immediate << 2)
+ */
+
+ // This instruction operates implicitly on stack pointer, so read <sp>
+ // register.
+ int32_t src_opd_val =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
+ if (!success)
+ return false;
+
+ int32_t ra_val =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
+ if (!success)
+ return false;
+
+ int32_t result = src_opd_val + imm5;
+
+ Context context;
+
+ // Update the PC
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ ra_val))
+ return false;
+
+ RegisterInfo reg_info_sp;
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, imm5);
+
+ // We are adjusting stack
+ context.type = eContextAdjustStackPointer;
+
+ // update SP
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
+ result))
+ return false;
+
+ return true;
}
-static int
-IsAdd64bitOverflow (int32_t a, int32_t b)
-{
- int32_t r = (uint32_t) a + (uint32_t) b;
+static int IsAdd64bitOverflow(int32_t a, int32_t b) {
+ int32_t r = (uint32_t)a + (uint32_t)b;
return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
}
-/*
+/*
Emulate below MIPS branch instructions.
BEQ, BNE : Branch on condition
BEQL, BNEL : Branch likely
*/
-bool
-EmulateInstructionMIPS::Emulate_BXX_3ops (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- int32_t offset, pc, target = 0, rs_val, rt_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- offset = insn.getOperand(2).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ int32_t offset, pc, target = 0, rs_val, rt_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ offset = insn.getOperand(2).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BEQ") ||
- !strcasecmp (op_name, "BEQL"))
- {
- if (rs_val == rt_val)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BNE") ||
- !strcasecmp (op_name, "BNEL"))
- {
- if (rs_val != rt_val)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
+ if (rs_val == rt_val)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
+ if (rs_val != rt_val)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
-
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
-/*
+/*
Emulate below MIPS branch instructions.
- BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch instructions with no delay slot
+ BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
+ instructions with no delay slot
*/
-bool
-EmulateInstructionMIPS::Emulate_BXX_3ops_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- int32_t offset, pc, target = 0, rs_val, rt_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- offset = insn.getOperand(2).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ int32_t offset, pc, target = 0, rs_val, rt_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ offset = insn.getOperand(2).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BEQC"))
- {
- if (rs_val == rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEC"))
- {
- if (rs_val != rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTC"))
- {
- if (rs_val < rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEC"))
- {
- if (rs_val >= rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTUC"))
- {
- if (rs_val < rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEUC"))
- {
- if ((uint32_t)rs_val >= (uint32_t)rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BOVC"))
- {
- if (IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNVC"))
- {
- if (!IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + offset;
- else
- target = pc + 4;
- }
+ if (!strcasecmp(op_name, "BEQC")) {
+ if (rs_val == rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEC")) {
+ if (rs_val != rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTC")) {
+ if (rs_val < rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEC")) {
+ if (rs_val >= rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTUC")) {
+ if (rs_val < rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEUC")) {
+ if ((uint32_t)rs_val >= (uint32_t)rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BOVC")) {
+ if (IsAdd64bitOverflow(rs_val, rt_val))
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNVC")) {
+ if (!IsAdd64bitOverflow(rs_val, rt_val))
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
-
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
-/*
+/*
Emulate below MIPS conditional branch and link instructions.
BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
*/
-bool
-EmulateInstructionMIPS::Emulate_Bcond_Link_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int32_t offset, pc, target = 0;
- int32_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int32_t offset, pc, target = 0;
+ int32_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLEZALC"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEZALC"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTZALC"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGTZALC"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BEQZALC"))
- {
- if (rs_val == 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEZALC"))
- {
- if (rs_val != 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
+ if (!strcasecmp(op_name, "BLEZALC")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEZALC")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTZALC")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGTZALC")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BEQZALC")) {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEZALC")) {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- Context context;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 4))
+ return false;
+
+ return true;
}
-/*
+/*
Emulate below MIPS Non-Compact conditional branch and link instructions.
BLTZAL, BGEZAL :
BLTZALL, BGEZALL : Branch likely
*/
-bool
-EmulateInstructionMIPS::Emulate_Bcond_Link (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int32_t offset, pc, target = 0;
- int32_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int32_t offset, pc, target = 0;
+ int32_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLTZAL") ||
- !strcasecmp (op_name, "BLTZALL"))
- {
- if ((int32_t) rs_val < 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGEZAL") ||
- !strcasecmp (op_name, "BGEZALL"))
- {
- if ((int32_t) rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
+ if ((int32_t)rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGEZAL") ||
+ !strcasecmp(op_name, "BGEZALL")) {
+ if ((int32_t)rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-/*
+/*
Emulate below MIPS branch instructions.
BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
*/
-bool
-EmulateInstructionMIPS::Emulate_BXX_2ops (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int32_t offset, pc, target = 0;
- int32_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int32_t offset, pc, target = 0;
+ int32_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLTZL") ||
- !strcasecmp (op_name, "BLTZ"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGEZL") ||
- !strcasecmp (op_name, "BGEZ"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGTZL") ||
- !strcasecmp (op_name, "BGTZ"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BLEZL") ||
- !strcasecmp (op_name, "BLEZ"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-/*
+/*
Emulate below MIPS branch instructions.
BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
*/
-bool
-EmulateInstructionMIPS::Emulate_BXX_2ops_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int32_t offset, pc, target = 0;
- int32_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int32_t offset, pc, target = 0;
+ int32_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLTZC"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLEZC"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEZC"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGTZC"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BEQZC"))
- {
- if (rs_val == 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEZC"))
- {
- if (rs_val != 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
+ if (!strcasecmp(op_name, "BLTZC")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLEZC")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEZC")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGTZC")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BEQZC")) {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEZC")) {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_B16_MM (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t offset, pc, target;
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t offset, pc, target;
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
- offset = insn.getOperand(0).getImm();
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- // unconditional branch
- target = pc + offset;
+ // unconditional branch
+ target = pc + offset;
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
/*
@@ -1978,503 +2232,498 @@ EmulateInstructionMIPS::Emulate_B16_MM (llvm::MCInst& insn)
BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
*/
-bool
-EmulateInstructionMIPS::Emulate_Branch_MM (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t target = 0;
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
- bool update_ra = false;
- uint32_t ra_offset = 0;
-
- /*
- * BEQZ16 rs, offset
- * condition <- (GPR[rs] = 0)
- * if condition then
- * PC = PC + sign_ext (offset || 0)
- *
- * BNEZ16 rs, offset
- * condition <- (GPR[rs] != 0)
- * if condition then
- * PC = PC + sign_ext (offset || 0)
- *
- * BEQZC rs, offset (compact instruction: No delay slot)
- * condition <- (GPR[rs] == 0)
- * if condition then
- * PC = PC + 4 + sign_ext (offset || 0)
- */
+bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t target = 0;
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+ bool update_ra = false;
+ uint32_t ra_offset = 0;
+
+ /*
+ * BEQZ16 rs, offset
+ * condition <- (GPR[rs] = 0)
+ * if condition then
+ * PC = PC + sign_ext (offset || 0)
+ *
+ * BNEZ16 rs, offset
+ * condition <- (GPR[rs] != 0)
+ * if condition then
+ * PC = PC + sign_ext (offset || 0)
+ *
+ * BEQZC rs, offset (compact instruction: No delay slot)
+ * condition <- (GPR[rs] == 0)
+ * if condition then
+ * PC = PC + 4 + sign_ext (offset || 0)
+ */
+
+ uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ int32_t offset = insn.getOperand(1).getImm();
+
+ int32_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int32_t offset = insn.getOperand(1).getImm();
+ int32_t rs_val = (int32_t)ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ if (!strcasecmp(op_name, "BEQZ16_MM")) {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + current_inst_size +
+ m_next_inst_size; // Skip delay slot instruction.
+ } else if (!strcasecmp(op_name, "BNEZ16_MM")) {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + current_inst_size +
+ m_next_inst_size; // Skip delay slot instruction.
+ } else if (!strcasecmp(op_name, "BEQZC_MM")) {
+ if (rs_val == 0)
+ target = pc + 4 + offset;
+ else
+ target =
+ pc +
+ 4; // 32 bit instruction and does not have delay slot instruction.
+ } else if (!strcasecmp(op_name, "BNEZC_MM")) {
+ if (rs_val != 0)
+ target = pc + 4 + offset;
+ else
+ target =
+ pc +
+ 4; // 32 bit instruction and does not have delay slot instruction.
+ } else if (!strcasecmp(op_name, "BGEZALS_MM")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
- int32_t rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ update_ra = true;
+ ra_offset = 6;
+ } else if (!strcasecmp(op_name, "BLTZALS_MM")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
- if (!strcasecmp (op_name, "BEQZ16_MM"))
- {
- if (rs_val == 0)
- target = pc + offset;
- else
- target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction.
- }
- else if (!strcasecmp (op_name, "BNEZ16_MM"))
- {
- if (rs_val != 0)
- target = pc + offset;
- else
- target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction.
- }
- else if (!strcasecmp (op_name, "BEQZC_MM"))
- {
- if (rs_val == 0)
- target = pc + 4 + offset;
- else
- target = pc + 4; // 32 bit instruction and does not have delay slot instruction.
- }
- else if (!strcasecmp (op_name, "BNEZC_MM"))
- {
- if (rs_val != 0)
- target = pc + 4 + offset;
- else
- target = pc + 4; // 32 bit instruction and does not have delay slot instruction.
- }
- else if (!strcasecmp (op_name, "BGEZALS_MM"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
-
- update_ra = true;
- ra_offset = 6;
- }
- else if (!strcasecmp (op_name, "BLTZALS_MM"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
-
- update_ra = true;
- ra_offset = 6;
- }
+ update_ra = true;
+ ra_offset = 6;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (update_ra)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
- return false;
- }
- return true;
+ if (update_ra) {
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + ra_offset))
+ return false;
+ }
+ return true;
}
/* Emulate micromips jump instructions.
JALR16,JALRS16
*/
-bool
-EmulateInstructionMIPS::Emulate_JALRx16_MM (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t ra_offset = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
+bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t ra_offset = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
- uint32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ uint32_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- uint32_t rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "JALR16_MM"))
- ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
- else if (!strcasecmp (op_name, "JALRS16_MM"))
- ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
+ if (!strcasecmp(op_name, "JALR16_MM"))
+ ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
+ else if (!strcasecmp(op_name, "JALRS16_MM"))
+ ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ rs_val))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + ra_offset))
+ return false;
- return true;
+ return true;
}
/* Emulate JALS and JALX instructions.
JALS 32 bit instruction with short (2-byte) delay slot.
JALX 32 bit instruction with 4-byte delay slot.
*/
-bool
-EmulateInstructionMIPS::Emulate_JALx (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t offset=0, target=0, pc=0, ra_offset=0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- /*
- * JALS target
- * RA = PC + 6
- * offset = sign_ext (offset << 1)
- * PC = PC[31-27] | offset
- * JALX target
- * RA = PC + 8
- * offset = sign_ext (offset << 2)
- * PC = PC[31-28] | offset
- */
- offset = insn.getOperand(0).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ /*
+ * JALS target
+ * RA = PC + 6
+ * offset = sign_ext (offset << 1)
+ * PC = PC[31-27] | offset
+ * JALX target
+ * RA = PC + 8
+ * offset = sign_ext (offset << 2)
+ * PC = PC[31-28] | offset
+ */
+ offset = insn.getOperand(0).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- // These are PC-region branches and not PC-relative.
- if (!strcasecmp (op_name, "JALS_MM"))
- {
- // target address is in the “current” 128 MB-aligned region
- target = (pc & 0xF8000000UL) | offset;
- ra_offset = 6;
- }
- else if (!strcasecmp (op_name, "JALX_MM"))
- {
- // target address is in the “current” 256 MB-aligned region
- target = (pc & 0xF0000000UL) | offset;
- ra_offset = 8;
- }
+ // These are PC-region branches and not PC-relative.
+ if (!strcasecmp(op_name, "JALS_MM")) {
+ // target address is in the “current” 128 MB-aligned region
+ target = (pc & 0xF8000000UL) | offset;
+ ra_offset = 6;
+ } else if (!strcasecmp(op_name, "JALX_MM")) {
+ // target address is in the “current” 256 MB-aligned region
+ target = (pc & 0xF0000000UL) | offset;
+ ra_offset = 8;
+ }
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + ra_offset))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JALRS (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs=0, rt=0;
- int32_t pc=0, rs_val=0;
-
- /*
- JALRS rt, rs
- GPR[rt] <- PC + 6
- PC <- GPR[rs]
- */
+bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs = 0, rt = 0;
+ int32_t pc = 0, rs_val = 0;
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ /*
+ JALRS rt, rs
+ GPR[rt] <- PC + 6
+ PC <- GPR[rs]
+ */
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- Context context;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- // This is 4-byte instruction with 2-byte delay slot.
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 6))
- return false;
-
- return true;
+ Context context;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ rs_val))
+ return false;
+
+ // This is 4-byte instruction with 2-byte delay slot.
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
+ pc + 6))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BAL (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t offset, pc, target;
+bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t offset, pc, target;
- /*
- * BAL offset
- * offset = sign_ext (offset << 2)
- * RA = PC + 8
- * PC = PC + offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * BAL offset
+ * offset = sign_ext (offset << 2)
+ * RA = PC + 8
+ * PC = PC + offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- target = pc + offset;
+ target = pc + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BALC (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t offset, pc, target;
+bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t offset, pc, target;
- /*
- * BALC offset
- * offset = sign_ext (offset << 2)
- * RA = PC + 4
- * PC = PC + 4 + offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * BALC offset
+ * offset = sign_ext (offset << 2)
+ * RA = PC + 4
+ * PC = PC + 4 + offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- target = pc + offset;
+ target = pc + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 4))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BC (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t offset, pc, target;
+bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t offset, pc, target;
- /*
- * BC offset
- * offset = sign_ext (offset << 2)
- * PC = PC + 4 + offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * BC offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC + 4 + offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- target = pc + offset;
+ target = pc + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_J (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t offset, pc;
+bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t offset, pc;
- /*
- * J offset
- * offset = sign_ext (offset << 2)
- * PC = PC[63-28] | offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * J offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC[63-28] | offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- /* This is a PC-region branch and not PC-relative */
- pc = (pc & 0xF0000000UL) | offset;
+ /* This is a PC-region branch and not PC-relative */
+ pc = (pc & 0xF0000000UL) | offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, pc))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JAL (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t offset, target, pc;
+bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t offset, target, pc;
- /*
- * JAL offset
- * offset = sign_ext (offset << 2)
- * PC = PC[63-28] | offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * JAL offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC[63-28] | offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- /* This is a PC-region branch and not PC-relative */
- target = (pc & 0xF0000000UL) | offset;
+ /* This is a PC-region branch and not PC-relative */
+ target = (pc & 0xF0000000UL) | offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JALR (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- uint32_t pc, rs_val;
+bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ uint32_t pc, rs_val;
- /*
- * JALR rt, rs
- * GPR[rt] = PC + 8
- * PC = GPR[rs]
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ /*
+ * JALR rt, rs
+ * GPR[rt] = PC + 8
+ * PC = GPR[rs]
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
+ &success);
+ if (!success)
+ return false;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ rs_val))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JIALC (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rt;
- int32_t target, offset, pc, rt_val;
+bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rt;
+ int32_t target, offset, pc, rt_val;
- /*
- * JIALC rt, offset
- * offset = sign_ext (offset)
- * PC = GPR[rt] + offset
- * RA = PC + 4
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
+ /*
+ * JIALC rt, offset
+ * offset = sign_ext (offset)
+ * PC = GPR[rt] + offset
+ * RA = PC + 4
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- target = rt_val + offset;
+ target = rt_val + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 4))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JIC (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rt;
- int32_t target, offset, rt_val;
+bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rt;
+ int32_t target, offset, rt_val;
- /*
- * JIC rt, offset
- * offset = sign_ext (offset)
- * PC = GPR[rt] + offset
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
+ /*
+ * JIC rt, offset
+ * offset = sign_ext (offset)
+ * PC = GPR[rt] + offset
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- target = rt_val + offset;
+ target = rt_val + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JR (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- uint32_t rs_val;
+bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ uint32_t rs_val;
- /*
- * JR rs
- * PC = GPR[rs]
- */
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ /*
+ * JR rs
+ * PC = GPR[rs]
+ */
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
+ &success);
+ if (!success)
+ return false;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ rs_val))
+ return false;
- return true;
+ return true;
}
/*
@@ -2482,419 +2731,400 @@ EmulateInstructionMIPS::Emulate_JR (llvm::MCInst& insn)
BC1F, BC1FL : Branch on FP False (L stands for branch likely)
BC1T, BC1TL : Branch on FP True (L stands for branch likely)
*/
-bool
-EmulateInstructionMIPS::Emulate_FP_branch (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t cc, fcsr;
- int32_t pc, offset, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t cc, fcsr;
+ int32_t pc, offset, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
- if (!success)
- return false;
+ cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- /* fcsr[23], fcsr[25-31] are vaild condition bits */
- fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BC1F") ||
- !strcasecmp (op_name, "BC1FL"))
- {
- if ((fcsr & (1 << cc)) == 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1T") ||
- !strcasecmp (op_name, "BC1TL"))
- {
- if ((fcsr & (1 << cc)) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- Context context;
+ fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ /* fcsr[23], fcsr[25-31] are vaild condition bits */
+ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
- return true;
+ if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
+ if ((fcsr & (1 << cc)) == 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
+ if ((fcsr & (1 << cc)) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ Context context;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BC1EQZ (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t ft;
- uint32_t ft_val;
- int32_t target, pc, offset;
-
- /*
- * BC1EQZ ft, offset
- * condition <- (FPR[ft].bit0 == 0)
- * if condition then
- * offset = sign_ext (offset)
- * PC = PC + 4 + offset
- */
- ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t ft;
+ uint32_t ft_val;
+ int32_t target, pc, offset;
- ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + ft, 0, &success);
- if (!success)
- return false;
+ /*
+ * BC1EQZ ft, offset
+ * condition <- (FPR[ft].bit0 == 0)
+ * if condition then
+ * offset = sign_ext (offset)
+ * PC = PC + 4 + offset
+ */
+ ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- if ((ft_val & 1) == 0)
- target = pc + 4 + offset;
- else
- target = pc + 8;
-
- Context context;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
+ &success);
+ if (!success)
+ return false;
- return true;
+ if ((ft_val & 1) == 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 8;
+
+ Context context;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BC1NEZ (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t ft;
- uint32_t ft_val;
- int32_t target, pc, offset;
-
- /*
- * BC1NEZ ft, offset
- * condition <- (FPR[ft].bit0 != 0)
- * if condition then
- * offset = sign_ext (offset)
- * PC = PC + 4 + offset
- */
- ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t ft;
+ uint32_t ft_val;
+ int32_t target, pc, offset;
- ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + ft, 0, &success);
- if (!success)
- return false;
+ /*
+ * BC1NEZ ft, offset
+ * condition <- (FPR[ft].bit0 != 0)
+ * if condition then
+ * offset = sign_ext (offset)
+ * PC = PC + 4 + offset
+ */
+ ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- if ((ft_val & 1) != 0)
- target = pc + 4 + offset;
- else
- target = pc + 8;
-
- Context context;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
+ &success);
+ if (!success)
+ return false;
- return true;
+ if ((ft_val & 1) != 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 8;
+
+ Context context;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
/*
Emulate MIPS-3D Branch instructions
- BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes False/True
- BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes False/True
+ BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
+ False/True
+ BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
+ False/True
*/
-bool
-EmulateInstructionMIPS::Emulate_3D_branch (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t cc, fcsr;
- int32_t pc, offset, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t cc, fcsr;
+ int32_t pc, offset, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
- if (!success)
- return false;
+ cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- /* fcsr[23], fcsr[25-31] are vaild condition bits */
- fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BC1ANY2F"))
- {
- /* if any one bit is 0 */
- if (((fcsr >> cc) & 3) != 3)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY2T"))
- {
- /* if any one bit is 1 */
- if (((fcsr >> cc) & 3) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY4F"))
- {
- /* if any one bit is 0 */
- if (((fcsr >> cc) & 0xf) != 0xf)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY4T"))
- {
- /* if any one bit is 1 */
- if (((fcsr >> cc) & 0xf) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- Context context;
+ fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0,
+ &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ /* fcsr[23], fcsr[25-31] are vaild condition bits */
+ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
- return true;
-}
+ if (!strcasecmp(op_name, "BC1ANY2F")) {
+ /* if any one bit is 0 */
+ if (((fcsr >> cc) & 3) != 3)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY2T")) {
+ /* if any one bit is 1 */
+ if (((fcsr >> cc) & 3) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY4F")) {
+ /* if any one bit is 0 */
+ if (((fcsr >> cc) & 0xf) != 0xf)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY4T")) {
+ /* if any one bit is 1 */
+ if (((fcsr >> cc) & 0xf) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ Context context;
-bool
-EmulateInstructionMIPS::Emulate_BNZB (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 1, true);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BNZH (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 2, true);
+bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 1, true);
}
-bool
-EmulateInstructionMIPS::Emulate_BNZW (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 4, true);
+bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 2, true);
}
-bool
-EmulateInstructionMIPS::Emulate_BNZD (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 8, true);
+bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 4, true);
}
-bool
-EmulateInstructionMIPS::Emulate_BZB (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 1, false);
+bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 8, true);
}
-bool
-EmulateInstructionMIPS::Emulate_BZH (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 2, false);
+bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 1, false);
}
-bool
-EmulateInstructionMIPS::Emulate_BZW (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 4, false);
+bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 2, false);
}
-bool
-EmulateInstructionMIPS::Emulate_BZD (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 8, false);
+bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 4, false);
}
-bool
-EmulateInstructionMIPS::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz)
-{
- bool success = false, branch_hit = true;
- int32_t target = 0;
- RegisterValue reg_value;
- const uint8_t *ptr = NULL;
+bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 8, false);
+}
- uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int32_t offset = insn.getOperand(1).getImm();
+bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
+ int element_byte_size,
+ bool bnz) {
+ bool success = false, branch_hit = true;
+ int32_t target = 0;
+ RegisterValue reg_value;
+ const uint8_t *ptr = NULL;
- int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ int32_t offset = insn.getOperand(1).getImm();
- if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
- ptr = (const uint8_t *)reg_value.GetBytes();
- else
- return false;
+ int32_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- for(int i = 0; i < 16 / element_byte_size; i++)
- {
- switch(element_byte_size)
- {
- case 1:
- if((*ptr == 0 && bnz) || (*ptr != 0 && !bnz) )
- branch_hit = false;
- break;
- case 2:
- if ((*(const uint16_t *)ptr == 0 && bnz) || (*(const uint16_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- case 4:
- if ((*(const uint32_t *)ptr == 0 && bnz) || (*(const uint32_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- case 8:
- if ((*(const uint64_t *)ptr == 0 && bnz) || (*(const uint64_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- }
- if(!branch_hit)
- break;
- ptr = ptr + element_byte_size;
- }
+ if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
+ ptr = (const uint8_t *)reg_value.GetBytes();
+ else
+ return false;
- if(branch_hit)
- target = pc + offset;
- else
- target = pc + 8;
+ for (int i = 0; i < 16 / element_byte_size; i++) {
+ switch (element_byte_size) {
+ case 1:
+ if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 2:
+ if ((*(const uint16_t *)ptr == 0 && bnz) ||
+ (*(const uint16_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 4:
+ if ((*(const uint32_t *)ptr == 0 && bnz) ||
+ (*(const uint32_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 8:
+ if ((*(const uint64_t *)ptr == 0 && bnz) ||
+ (*(const uint64_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ }
+ if (!branch_hit)
+ break;
+ ptr = ptr + element_byte_size;
+ }
+
+ if (branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 8;
- Context context;
- context.type = eContextRelativeBranchImmediate;
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BNZV (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_V (insn, true);
+bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_V(insn, true);
}
-bool
-EmulateInstructionMIPS::Emulate_BZV (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_V (insn, false);
+bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_V(insn, false);
}
-bool
-EmulateInstructionMIPS::Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz)
-{
- bool success = false;
- int32_t target = 0;
- llvm::APInt wr_val = llvm::APInt::getNullValue(128);
- llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
- llvm::APInt zero_value = llvm::APInt::getNullValue(128);
- RegisterValue reg_value;
+bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
+ bool bnz) {
+ bool success = false;
+ int32_t target = 0;
+ llvm::APInt wr_val = llvm::APInt::getNullValue(128);
+ llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
+ llvm::APInt zero_value = llvm::APInt::getNullValue(128);
+ RegisterValue reg_value;
- uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int32_t offset = insn.getOperand(1).getImm();
+ uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ int32_t offset = insn.getOperand(1).getImm();
- int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ int32_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
- wr_val = reg_value.GetAsUInt128(fail_value);
- else
- return false;
+ if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
+ wr_val = reg_value.GetAsUInt128(fail_value);
+ else
+ return false;
- if((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
- target = pc + offset;
- else
- target = pc + 8;
+ if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
+ (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
+ target = pc + offset;
+ else
+ target = pc + 8;
- Context context;
- context.type = eContextRelativeBranchImmediate;
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_LDST_Imm (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t base;
- int32_t imm, address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t base;
+ int32_t imm, address;
+ Context bad_vaddr_context;
- uint32_t num_operands = insn.getNumOperands();
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
- imm = insn.getOperand(num_operands-1).getImm();
+ uint32_t num_operands = insn.getNumOperands();
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+ imm = insn.getOperand(num_operands - 1).getImm();
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- /* read base register */
- address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_LDST_Reg (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t base, index;
- int32_t address, index_address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t base, index;
+ int32_t address, index_address;
+ Context bad_vaddr_context;
- uint32_t num_operands = insn.getNumOperands();
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
- index = m_reg_info->getEncodingValue (insn.getOperand(num_operands-1).getReg());
+ uint32_t num_operands = insn.getNumOperands();
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+ index =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
- RegisterInfo reg_info_base, reg_info_index;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base, reg_info_index;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + index, reg_info_index))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
+ reg_info_index))
+ return false;
- /* read base register */
- address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- /* read index register */
- index_address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
- if (!success)
- return false;
+ /* read index register */
+ index_address = (int32_t)ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + index_address;
+ /* destination address */
+ address = address + index_address;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- return true;
+ return true;
}
diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
index f1f92a065956..82c6a0a31e81 100644
--- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
+++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
@@ -1,4 +1,5 @@
-//===-- EmulateInstructionMIPS.h ------------------------------------*- C++ -*-===//
+//===-- EmulateInstructionMIPS.h ------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,286 +11,209 @@
#ifndef EmulateInstructionMIPS_h_
#define EmulateInstructionMIPS_h_
-namespace llvm
-{
- class MCDisassembler;
- class MCSubtargetInfo;
- class MCRegisterInfo;
- class MCAsmInfo;
- class MCContext;
- class MCInstrInfo;
- class MCInst;
+namespace llvm {
+class MCDisassembler;
+class MCSubtargetInfo;
+class MCRegisterInfo;
+class MCAsmInfo;
+class MCContext;
+class MCInstrInfo;
+class MCInst;
}
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Error.h"
#include "lldb/Interpreter/OptionValue.h"
-class EmulateInstructionMIPS : public lldb_private::EmulateInstruction
-{
-public:
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb_private::ConstString
- GetPluginNameStatic ();
-
- static const char *
- GetPluginDescriptionStatic ();
-
- static lldb_private::EmulateInstruction *
- CreateInstance (const lldb_private::ArchSpec &arch,
- lldb_private::InstructionType inst_type);
-
- static bool
- SupportsEmulatingInstructionsOfTypeStatic (lldb_private::InstructionType inst_type)
- {
- switch (inst_type)
- {
- case lldb_private::eInstructionTypeAny:
- case lldb_private::eInstructionTypePrologueEpilogue:
- case lldb_private::eInstructionTypePCModifying:
- return true;
-
- case lldb_private::eInstructionTypeAll:
- return false;
- }
- return false;
- }
+class EmulateInstructionMIPS : public lldb_private::EmulateInstruction {
+public:
+ static void Initialize();
- lldb_private::ConstString
- GetPluginName() override;
+ static void Terminate();
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ static lldb_private::ConstString GetPluginNameStatic();
- bool
- SetTargetTriple (const lldb_private::ArchSpec &arch) override;
-
- EmulateInstructionMIPS (const lldb_private::ArchSpec &arch);
+ static const char *GetPluginDescriptionStatic();
- bool
- SupportsEmulatingInstructionsOfType (lldb_private::InstructionType inst_type) override
- {
- return SupportsEmulatingInstructionsOfTypeStatic (inst_type);
- }
+ static lldb_private::EmulateInstruction *
+ CreateInstance(const lldb_private::ArchSpec &arch,
+ lldb_private::InstructionType inst_type);
- bool
- ReadInstruction () override;
-
- bool
- EvaluateInstruction (uint32_t evaluate_options) override;
-
- bool
- SetInstruction (const lldb_private::Opcode &insn_opcode,
- const lldb_private::Address &inst_addr,
- lldb_private::Target *target) override;
-
- bool
- TestEmulation (lldb_private::Stream *out_stream,
- lldb_private::ArchSpec &arch,
- lldb_private::OptionValueDictionary *test_data) override
- {
- return false;
+ static bool SupportsEmulatingInstructionsOfTypeStatic(
+ lldb_private::InstructionType inst_type) {
+ switch (inst_type) {
+ case lldb_private::eInstructionTypeAny:
+ case lldb_private::eInstructionTypePrologueEpilogue:
+ case lldb_private::eInstructionTypePCModifying:
+ return true;
+
+ case lldb_private::eInstructionTypeAll:
+ return false;
}
+ return false;
+ }
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
+
+ EmulateInstructionMIPS(const lldb_private::ArchSpec &arch);
+
+ bool SupportsEmulatingInstructionsOfType(
+ lldb_private::InstructionType inst_type) override {
+ return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
+ }
+
+ bool ReadInstruction() override;
+
+ bool EvaluateInstruction(uint32_t evaluate_options) override;
+
+ bool SetInstruction(const lldb_private::Opcode &insn_opcode,
+ const lldb_private::Address &inst_addr,
+ lldb_private::Target *target) override;
- bool
- GetRegisterInfo (lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- lldb_private::RegisterInfo &reg_info) override;
+ bool TestEmulation(lldb_private::Stream *out_stream,
+ lldb_private::ArchSpec &arch,
+ lldb_private::OptionValueDictionary *test_data) override {
+ return false;
+ }
- bool
- CreateFunctionEntryUnwind (lldb_private::UnwindPlan &unwind_plan) override;
+ bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ lldb_private::RegisterInfo &reg_info) override;
+ bool
+ CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
protected:
+ typedef struct {
+ const char *op_name;
+ bool (EmulateInstructionMIPS::*callback)(llvm::MCInst &insn);
+ const char *insn_name;
+ } MipsOpcode;
- typedef struct
- {
- const char *op_name;
- bool (EmulateInstructionMIPS::*callback) (llvm::MCInst& insn);
- const char *insn_name;
- } MipsOpcode;
-
- static MipsOpcode*
- GetOpcodeForInstruction (const char *op_name);
+ static MipsOpcode *GetOpcodeForInstruction(const char *op_name);
- uint32_t
- GetSizeOfInstruction (lldb_private::DataExtractor& data, uint64_t inst_addr);
+ uint32_t GetSizeOfInstruction(lldb_private::DataExtractor &data,
+ uint64_t inst_addr);
- bool
- Emulate_ADDiu (llvm::MCInst& insn);
+ bool Emulate_ADDiu(llvm::MCInst &insn);
- bool
- Emulate_SUBU_ADDU (llvm::MCInst& insn);
+ bool Emulate_SUBU_ADDU(llvm::MCInst &insn);
- bool
- Emulate_LUI (llvm::MCInst& insn);
+ bool Emulate_LUI(llvm::MCInst &insn);
- bool
- Emulate_SW (llvm::MCInst& insn);
+ bool Emulate_SW(llvm::MCInst &insn);
- bool
- Emulate_LW (llvm::MCInst& insn);
+ bool Emulate_LW(llvm::MCInst &insn);
- bool
- Emulate_ADDIUSP (llvm::MCInst& insn);
+ bool Emulate_ADDIUSP(llvm::MCInst &insn);
- bool
- Emulate_ADDIUS5 (llvm::MCInst& insn);
+ bool Emulate_ADDIUS5(llvm::MCInst &insn);
- bool
- Emulate_SWSP (llvm::MCInst& insn);
+ bool Emulate_SWSP(llvm::MCInst &insn);
- bool
- Emulate_SWM16_32 (llvm::MCInst& insn);
+ bool Emulate_SWM16_32(llvm::MCInst &insn);
- bool
- Emulate_LWSP (llvm::MCInst& insn);
+ bool Emulate_LWSP(llvm::MCInst &insn);
- bool
- Emulate_LWM16_32 (llvm::MCInst& insn);
+ bool Emulate_LWM16_32(llvm::MCInst &insn);
- bool
- Emulate_JRADDIUSP (llvm::MCInst& insn);
+ bool Emulate_JRADDIUSP(llvm::MCInst &insn);
- bool
- Emulate_LDST_Imm (llvm::MCInst& insn);
+ bool Emulate_LDST_Imm(llvm::MCInst &insn);
- bool
- Emulate_LDST_Reg (llvm::MCInst& insn);
+ bool Emulate_LDST_Reg(llvm::MCInst &insn);
- bool
- Emulate_BXX_3ops (llvm::MCInst& insn);
+ bool Emulate_BXX_3ops(llvm::MCInst &insn);
- bool
- Emulate_BXX_3ops_C (llvm::MCInst& insn);
+ bool Emulate_BXX_3ops_C(llvm::MCInst &insn);
- bool
- Emulate_BXX_2ops (llvm::MCInst& insn);
+ bool Emulate_BXX_2ops(llvm::MCInst &insn);
- bool
- Emulate_BXX_2ops_C (llvm::MCInst& insn);
+ bool Emulate_BXX_2ops_C(llvm::MCInst &insn);
- bool
- Emulate_Bcond_Link_C (llvm::MCInst& insn);
+ bool Emulate_Bcond_Link_C(llvm::MCInst &insn);
- bool
- Emulate_Bcond_Link (llvm::MCInst& insn);
+ bool Emulate_Bcond_Link(llvm::MCInst &insn);
- bool
- Emulate_FP_branch (llvm::MCInst& insn);
+ bool Emulate_FP_branch(llvm::MCInst &insn);
- bool
- Emulate_3D_branch (llvm::MCInst& insn);
+ bool Emulate_3D_branch(llvm::MCInst &insn);
- bool
- Emulate_BAL (llvm::MCInst& insn);
+ bool Emulate_BAL(llvm::MCInst &insn);
- bool
- Emulate_BALC (llvm::MCInst& insn);
+ bool Emulate_BALC(llvm::MCInst &insn);
- bool
- Emulate_BC (llvm::MCInst& insn);
+ bool Emulate_BC(llvm::MCInst &insn);
- bool
- Emulate_J (llvm::MCInst& insn);
+ bool Emulate_J(llvm::MCInst &insn);
- bool
- Emulate_JAL (llvm::MCInst& insn);
+ bool Emulate_JAL(llvm::MCInst &insn);
- bool
- Emulate_JALR (llvm::MCInst& insn);
+ bool Emulate_JALR(llvm::MCInst &insn);
- bool
- Emulate_JIALC (llvm::MCInst& insn);
+ bool Emulate_JIALC(llvm::MCInst &insn);
- bool
- Emulate_JIC (llvm::MCInst& insn);
+ bool Emulate_JIC(llvm::MCInst &insn);
- bool
- Emulate_JR (llvm::MCInst& insn);
+ bool Emulate_JR(llvm::MCInst &insn);
- bool
- Emulate_BC1EQZ (llvm::MCInst& insn);
+ bool Emulate_BC1EQZ(llvm::MCInst &insn);
- bool
- Emulate_BC1NEZ (llvm::MCInst& insn);
+ bool Emulate_BC1NEZ(llvm::MCInst &insn);
- bool
- Emulate_BNZB (llvm::MCInst& insn);
+ bool Emulate_BNZB(llvm::MCInst &insn);
- bool
- Emulate_BNZH (llvm::MCInst& insn);
+ bool Emulate_BNZH(llvm::MCInst &insn);
- bool
- Emulate_BNZW (llvm::MCInst& insn);
+ bool Emulate_BNZW(llvm::MCInst &insn);
- bool
- Emulate_BNZD (llvm::MCInst& insn);
+ bool Emulate_BNZD(llvm::MCInst &insn);
- bool
- Emulate_BZB (llvm::MCInst& insn);
+ bool Emulate_BZB(llvm::MCInst &insn);
- bool
- Emulate_BZH (llvm::MCInst& insn);
+ bool Emulate_BZH(llvm::MCInst &insn);
- bool
- Emulate_BZW (llvm::MCInst& insn);
+ bool Emulate_BZW(llvm::MCInst &insn);
- bool
- Emulate_BZD (llvm::MCInst& insn);
+ bool Emulate_BZD(llvm::MCInst &insn);
- bool
- Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz);
+ bool Emulate_MSA_Branch_DF(llvm::MCInst &insn, int element_byte_size,
+ bool bnz);
- bool
- Emulate_BNZV (llvm::MCInst& insn);
+ bool Emulate_BNZV(llvm::MCInst &insn);
- bool
- Emulate_BZV (llvm::MCInst& insn);
+ bool Emulate_BZV(llvm::MCInst &insn);
- bool
- Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz);
+ bool Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz);
- bool
- Emulate_B16_MM (llvm::MCInst& insn);
+ bool Emulate_B16_MM(llvm::MCInst &insn);
- bool
- Emulate_Branch_MM (llvm::MCInst& insn);
+ bool Emulate_Branch_MM(llvm::MCInst &insn);
- bool
- Emulate_JALRx16_MM (llvm::MCInst& insn);
+ bool Emulate_JALRx16_MM(llvm::MCInst &insn);
- bool
- Emulate_JALx (llvm::MCInst& insn);
+ bool Emulate_JALx(llvm::MCInst &insn);
- bool
- Emulate_JALRS (llvm::MCInst& insn);
+ bool Emulate_JALRS(llvm::MCInst &insn);
- bool
- nonvolatile_reg_p (uint32_t regnum);
+ bool nonvolatile_reg_p(uint32_t regnum);
- const char *
- GetRegisterName (unsigned reg_num, bool altnernate_name);
+ const char *GetRegisterName(unsigned reg_num, bool altnernate_name);
private:
- std::unique_ptr<llvm::MCDisassembler> m_disasm;
- std::unique_ptr<llvm::MCDisassembler> m_alt_disasm;
- std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
- std::unique_ptr<llvm::MCSubtargetInfo> m_alt_subtype_info;
- std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
- std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
- std::unique_ptr<llvm::MCContext> m_context;
- std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
- uint32_t m_next_inst_size;
- bool m_use_alt_disaasm;
+ std::unique_ptr<llvm::MCDisassembler> m_disasm;
+ std::unique_ptr<llvm::MCDisassembler> m_alt_disasm;
+ std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
+ std::unique_ptr<llvm::MCSubtargetInfo> m_alt_subtype_info;
+ std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
+ std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
+ std::unique_ptr<llvm::MCContext> m_context;
+ std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
+ uint32_t m_next_inst_size;
+ bool m_use_alt_disaasm;
};
-#endif // EmulateInstructionMIPS_h_
+#endif // EmulateInstructionMIPS_h_
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 7b4b6aa0100e..c054760be8a0 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -1,4 +1,5 @@
-//===-- EmulateInstructionMIPS64.cpp -------------------------------*- C++ -*-===//
+//===-- EmulateInstructionMIPS64.cpp -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,24 +12,25 @@
#include <stdlib.h>
-#include "llvm-c/Disassembler.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCDisassembler/MCDisassembler.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCContext.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/Opcode.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/PluginManager.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Opcode.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Host/PosixApi.h"
#include "lldb/Symbol/UnwindPlan.h"
+#include "llvm-c/Disassembler.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/ADT/STLExtras.h"
@@ -41,7 +43,6 @@ using namespace lldb_private;
#define UInt(x) ((uint64_t)x)
#define integer int64_t
-
//----------------------------------------------------------------------
//
// EmulateInstructionMIPS64 implementation
@@ -50,987 +51,1262 @@ using namespace lldb_private;
#ifdef __mips__
extern "C" {
- void LLVMInitializeMipsTargetInfo ();
- void LLVMInitializeMipsTarget ();
- void LLVMInitializeMipsAsmPrinter ();
- void LLVMInitializeMipsTargetMC ();
- void LLVMInitializeMipsDisassembler ();
+void LLVMInitializeMipsTargetInfo();
+void LLVMInitializeMipsTarget();
+void LLVMInitializeMipsAsmPrinter();
+void LLVMInitializeMipsTargetMC();
+void LLVMInitializeMipsDisassembler();
}
#endif
-EmulateInstructionMIPS64::EmulateInstructionMIPS64 (const lldb_private::ArchSpec &arch) :
- EmulateInstruction (arch)
-{
- /* Create instance of llvm::MCDisassembler */
- std::string Error;
- llvm::Triple triple = arch.GetTriple();
- const llvm::Target *target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
-
- /*
- * If we fail to get the target then we haven't registered it. The SystemInitializerCommon
- * does not initialize targets, MCs and disassemblers. However we need the MCDisassembler
- * to decode the instructions so that the decoding complexity stays with LLVM.
- * Initialize the MIPS targets and disassemblers.
- */
+EmulateInstructionMIPS64::EmulateInstructionMIPS64(
+ const lldb_private::ArchSpec &arch)
+ : EmulateInstruction(arch) {
+ /* Create instance of llvm::MCDisassembler */
+ std::string Error;
+ llvm::Triple triple = arch.GetTriple();
+ const llvm::Target *target =
+ llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error);
+
+/*
+ * If we fail to get the target then we haven't registered it. The
+ * SystemInitializerCommon
+ * does not initialize targets, MCs and disassemblers. However we need the
+ * MCDisassembler
+ * to decode the instructions so that the decoding complexity stays with LLVM.
+ * Initialize the MIPS targets and disassemblers.
+*/
#ifdef __mips__
- if (!target)
- {
- LLVMInitializeMipsTargetInfo ();
- LLVMInitializeMipsTarget ();
- LLVMInitializeMipsAsmPrinter ();
- LLVMInitializeMipsTargetMC ();
- LLVMInitializeMipsDisassembler ();
- target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
- }
+ if (!target) {
+ LLVMInitializeMipsTargetInfo();
+ LLVMInitializeMipsTarget();
+ LLVMInitializeMipsAsmPrinter();
+ LLVMInitializeMipsTargetMC();
+ LLVMInitializeMipsDisassembler();
+ target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error);
+ }
#endif
- assert (target);
-
- llvm::StringRef cpu;
-
- switch (arch.GetCore())
- {
- case ArchSpec::eCore_mips32:
- case ArchSpec::eCore_mips32el:
- cpu = "mips32"; break;
- case ArchSpec::eCore_mips32r2:
- case ArchSpec::eCore_mips32r2el:
- cpu = "mips32r2"; break;
- case ArchSpec::eCore_mips32r3:
- case ArchSpec::eCore_mips32r3el:
- cpu = "mips32r3"; break;
- case ArchSpec::eCore_mips32r5:
- case ArchSpec::eCore_mips32r5el:
- cpu = "mips32r5"; break;
- case ArchSpec::eCore_mips32r6:
- case ArchSpec::eCore_mips32r6el:
- cpu = "mips32r6"; break;
- case ArchSpec::eCore_mips64:
- case ArchSpec::eCore_mips64el:
- cpu = "mips64"; break;
- case ArchSpec::eCore_mips64r2:
- case ArchSpec::eCore_mips64r2el:
- cpu = "mips64r2"; break;
- case ArchSpec::eCore_mips64r3:
- case ArchSpec::eCore_mips64r3el:
- cpu = "mips64r3"; break;
- case ArchSpec::eCore_mips64r5:
- case ArchSpec::eCore_mips64r5el:
- cpu = "mips64r5"; break;
- case ArchSpec::eCore_mips64r6:
- case ArchSpec::eCore_mips64r6el:
- cpu = "mips64r6"; break;
- default:
- cpu = "generic"; break;
- }
-
- std::string features = "";
- uint32_t arch_flags = arch.GetFlags ();
- if (arch_flags & ArchSpec::eMIPSAse_msa)
- features += "+msa,";
- if (arch_flags & ArchSpec::eMIPSAse_dsp)
- features += "+dsp,";
- if (arch_flags & ArchSpec::eMIPSAse_dspr2)
- features += "+dspr2,";
- if (arch_flags & ArchSpec::eMIPSAse_mips16)
- features += "+mips16,";
- if (arch_flags & ArchSpec::eMIPSAse_micromips)
- features += "+micromips,";
-
- m_reg_info.reset (target->createMCRegInfo (triple.getTriple()));
- assert (m_reg_info.get());
-
- m_insn_info.reset (target->createMCInstrInfo());
- assert (m_insn_info.get());
-
- m_asm_info.reset (target->createMCAsmInfo (*m_reg_info, triple.getTriple()));
- m_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features));
- assert (m_asm_info.get() && m_subtype_info.get());
-
- m_context.reset (new llvm::MCContext (m_asm_info.get(), m_reg_info.get(), nullptr));
- assert (m_context.get());
-
- m_disasm.reset (target->createMCDisassembler (*m_subtype_info, *m_context));
- assert (m_disasm.get());
+ assert(target);
+
+ llvm::StringRef cpu;
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_mips32:
+ case ArchSpec::eCore_mips32el:
+ cpu = "mips32";
+ break;
+ case ArchSpec::eCore_mips32r2:
+ case ArchSpec::eCore_mips32r2el:
+ cpu = "mips32r2";
+ break;
+ case ArchSpec::eCore_mips32r3:
+ case ArchSpec::eCore_mips32r3el:
+ cpu = "mips32r3";
+ break;
+ case ArchSpec::eCore_mips32r5:
+ case ArchSpec::eCore_mips32r5el:
+ cpu = "mips32r5";
+ break;
+ case ArchSpec::eCore_mips32r6:
+ case ArchSpec::eCore_mips32r6el:
+ cpu = "mips32r6";
+ break;
+ case ArchSpec::eCore_mips64:
+ case ArchSpec::eCore_mips64el:
+ cpu = "mips64";
+ break;
+ case ArchSpec::eCore_mips64r2:
+ case ArchSpec::eCore_mips64r2el:
+ cpu = "mips64r2";
+ break;
+ case ArchSpec::eCore_mips64r3:
+ case ArchSpec::eCore_mips64r3el:
+ cpu = "mips64r3";
+ break;
+ case ArchSpec::eCore_mips64r5:
+ case ArchSpec::eCore_mips64r5el:
+ cpu = "mips64r5";
+ break;
+ case ArchSpec::eCore_mips64r6:
+ case ArchSpec::eCore_mips64r6el:
+ cpu = "mips64r6";
+ break;
+ default:
+ cpu = "generic";
+ break;
+ }
+
+ std::string features = "";
+ uint32_t arch_flags = arch.GetFlags();
+ if (arch_flags & ArchSpec::eMIPSAse_msa)
+ features += "+msa,";
+ if (arch_flags & ArchSpec::eMIPSAse_dsp)
+ features += "+dsp,";
+ if (arch_flags & ArchSpec::eMIPSAse_dspr2)
+ features += "+dspr2,";
+ if (arch_flags & ArchSpec::eMIPSAse_mips16)
+ features += "+mips16,";
+ if (arch_flags & ArchSpec::eMIPSAse_micromips)
+ features += "+micromips,";
+
+ m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
+ assert(m_reg_info.get());
+
+ m_insn_info.reset(target->createMCInstrInfo());
+ assert(m_insn_info.get());
+
+ m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple()));
+ m_subtype_info.reset(
+ target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
+ assert(m_asm_info.get() && m_subtype_info.get());
+
+ m_context.reset(
+ new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
+ assert(m_context.get());
+
+ m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
+ assert(m_disasm.get());
}
-void
-EmulateInstructionMIPS64::Initialize ()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic (),
- GetPluginDescriptionStatic (),
- CreateInstance);
+void EmulateInstructionMIPS64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-EmulateInstructionMIPS64::Terminate ()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void EmulateInstructionMIPS64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-ConstString
-EmulateInstructionMIPS64::GetPluginNameStatic ()
-{
- ConstString g_plugin_name ("lldb.emulate-instruction.mips64");
- return g_plugin_name;
+ConstString EmulateInstructionMIPS64::GetPluginNameStatic() {
+ ConstString g_plugin_name("lldb.emulate-instruction.mips64");
+ return g_plugin_name;
}
-lldb_private::ConstString
-EmulateInstructionMIPS64::GetPluginName()
-{
- static ConstString g_plugin_name ("EmulateInstructionMIPS64");
- return g_plugin_name;
+lldb_private::ConstString EmulateInstructionMIPS64::GetPluginName() {
+ static ConstString g_plugin_name("EmulateInstructionMIPS64");
+ return g_plugin_name;
}
-const char *
-EmulateInstructionMIPS64::GetPluginDescriptionStatic ()
-{
- return "Emulate instructions for the MIPS64 architecture.";
+const char *EmulateInstructionMIPS64::GetPluginDescriptionStatic() {
+ return "Emulate instructions for the MIPS64 architecture.";
}
EmulateInstruction *
-EmulateInstructionMIPS64::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
-{
- if (EmulateInstructionMIPS64::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
- {
- if (arch.GetTriple().getArch() == llvm::Triple::mips64
- || arch.GetTriple().getArch() == llvm::Triple::mips64el)
- {
- std::auto_ptr<EmulateInstructionMIPS64> emulate_insn_ap (new EmulateInstructionMIPS64 (arch));
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
- }
+EmulateInstructionMIPS64::CreateInstance(const ArchSpec &arch,
+ InstructionType inst_type) {
+ if (EmulateInstructionMIPS64::SupportsEmulatingInstructionsOfTypeStatic(
+ inst_type)) {
+ if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
+ arch.GetTriple().getArch() == llvm::Triple::mips64el) {
+ std::auto_ptr<EmulateInstructionMIPS64> emulate_insn_ap(
+ new EmulateInstructionMIPS64(arch));
+ if (emulate_insn_ap.get())
+ return emulate_insn_ap.release();
}
-
- return NULL;
-}
+ }
-bool
-EmulateInstructionMIPS64::SetTargetTriple (const ArchSpec &arch)
-{
- if (arch.GetTriple().getArch () == llvm::Triple::mips64
- || arch.GetTriple().getArch () == llvm::Triple::mips64el)
- return true;
- return false;
+ return NULL;
}
-const char *
-EmulateInstructionMIPS64::GetRegisterName (unsigned reg_num, bool alternate_name)
-{
- if (alternate_name)
- {
- switch (reg_num)
- {
- case dwarf_sp_mips64: return "r29";
- case dwarf_r30_mips64: return "r30";
- case dwarf_ra_mips64: return "r31";
- case dwarf_f0_mips64: return "f0";
- case dwarf_f1_mips64: return "f1";
- case dwarf_f2_mips64: return "f2";
- case dwarf_f3_mips64: return "f3";
- case dwarf_f4_mips64: return "f4";
- case dwarf_f5_mips64: return "f5";
- case dwarf_f6_mips64: return "f6";
- case dwarf_f7_mips64: return "f7";
- case dwarf_f8_mips64: return "f8";
- case dwarf_f9_mips64: return "f9";
- case dwarf_f10_mips64: return "f10";
- case dwarf_f11_mips64: return "f11";
- case dwarf_f12_mips64: return "f12";
- case dwarf_f13_mips64: return "f13";
- case dwarf_f14_mips64: return "f14";
- case dwarf_f15_mips64: return "f15";
- case dwarf_f16_mips64: return "f16";
- case dwarf_f17_mips64: return "f17";
- case dwarf_f18_mips64: return "f18";
- case dwarf_f19_mips64: return "f19";
- case dwarf_f20_mips64: return "f20";
- case dwarf_f21_mips64: return "f21";
- case dwarf_f22_mips64: return "f22";
- case dwarf_f23_mips64: return "f23";
- case dwarf_f24_mips64: return "f24";
- case dwarf_f25_mips64: return "f25";
- case dwarf_f26_mips64: return "f26";
- case dwarf_f27_mips64: return "f27";
- case dwarf_f28_mips64: return "f28";
- case dwarf_f29_mips64: return "f29";
- case dwarf_f30_mips64: return "f30";
- case dwarf_f31_mips64: return "f31";
- case dwarf_w0_mips64: return "w0";
- case dwarf_w1_mips64: return "w1";
- case dwarf_w2_mips64: return "w2";
- case dwarf_w3_mips64: return "w3";
- case dwarf_w4_mips64: return "w4";
- case dwarf_w5_mips64: return "w5";
- case dwarf_w6_mips64: return "w6";
- case dwarf_w7_mips64: return "w7";
- case dwarf_w8_mips64: return "w8";
- case dwarf_w9_mips64: return "w9";
- case dwarf_w10_mips64: return "w10";
- case dwarf_w11_mips64: return "w11";
- case dwarf_w12_mips64: return "w12";
- case dwarf_w13_mips64: return "w13";
- case dwarf_w14_mips64: return "w14";
- case dwarf_w15_mips64: return "w15";
- case dwarf_w16_mips64: return "w16";
- case dwarf_w17_mips64: return "w17";
- case dwarf_w18_mips64: return "w18";
- case dwarf_w19_mips64: return "w19";
- case dwarf_w20_mips64: return "w20";
- case dwarf_w21_mips64: return "w21";
- case dwarf_w22_mips64: return "w22";
- case dwarf_w23_mips64: return "w23";
- case dwarf_w24_mips64: return "w24";
- case dwarf_w25_mips64: return "w25";
- case dwarf_w26_mips64: return "w26";
- case dwarf_w27_mips64: return "w27";
- case dwarf_w28_mips64: return "w28";
- case dwarf_w29_mips64: return "w29";
- case dwarf_w30_mips64: return "w30";
- case dwarf_w31_mips64: return "w31";
- case dwarf_mir_mips64: return "mir";
- case dwarf_mcsr_mips64: return "mcsr";
- case dwarf_config5_mips64: return "config5";
- default:
- break;
- }
- return nullptr;
- }
+bool EmulateInstructionMIPS64::SetTargetTriple(const ArchSpec &arch) {
+ if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
+ arch.GetTriple().getArch() == llvm::Triple::mips64el)
+ return true;
+ return false;
+}
- switch (reg_num)
- {
- case dwarf_zero_mips64: return "r0";
- case dwarf_r1_mips64: return "r1";
- case dwarf_r2_mips64: return "r2";
- case dwarf_r3_mips64: return "r3";
- case dwarf_r4_mips64: return "r4";
- case dwarf_r5_mips64: return "r5";
- case dwarf_r6_mips64: return "r6";
- case dwarf_r7_mips64: return "r7";
- case dwarf_r8_mips64: return "r8";
- case dwarf_r9_mips64: return "r9";
- case dwarf_r10_mips64: return "r10";
- case dwarf_r11_mips64: return "r11";
- case dwarf_r12_mips64: return "r12";
- case dwarf_r13_mips64: return "r13";
- case dwarf_r14_mips64: return "r14";
- case dwarf_r15_mips64: return "r15";
- case dwarf_r16_mips64: return "r16";
- case dwarf_r17_mips64: return "r17";
- case dwarf_r18_mips64: return "r18";
- case dwarf_r19_mips64: return "r19";
- case dwarf_r20_mips64: return "r20";
- case dwarf_r21_mips64: return "r21";
- case dwarf_r22_mips64: return "r22";
- case dwarf_r23_mips64: return "r23";
- case dwarf_r24_mips64: return "r24";
- case dwarf_r25_mips64: return "r25";
- case dwarf_r26_mips64: return "r26";
- case dwarf_r27_mips64: return "r27";
- case dwarf_gp_mips64: return "gp";
- case dwarf_sp_mips64: return "sp";
- case dwarf_r30_mips64: return "fp";
- case dwarf_ra_mips64: return "ra";
- case dwarf_sr_mips64: return "sr";
- case dwarf_lo_mips64: return "lo";
- case dwarf_hi_mips64: return "hi";
- case dwarf_bad_mips64: return "bad";
- case dwarf_cause_mips64: return "cause";
- case dwarf_pc_mips64: return "pc";
- case dwarf_f0_mips64: return "f0";
- case dwarf_f1_mips64: return "f1";
- case dwarf_f2_mips64: return "f2";
- case dwarf_f3_mips64: return "f3";
- case dwarf_f4_mips64: return "f4";
- case dwarf_f5_mips64: return "f5";
- case dwarf_f6_mips64: return "f6";
- case dwarf_f7_mips64: return "f7";
- case dwarf_f8_mips64: return "f8";
- case dwarf_f9_mips64: return "f9";
- case dwarf_f10_mips64: return "f10";
- case dwarf_f11_mips64: return "f11";
- case dwarf_f12_mips64: return "f12";
- case dwarf_f13_mips64: return "f13";
- case dwarf_f14_mips64: return "f14";
- case dwarf_f15_mips64: return "f15";
- case dwarf_f16_mips64: return "f16";
- case dwarf_f17_mips64: return "f17";
- case dwarf_f18_mips64: return "f18";
- case dwarf_f19_mips64: return "f19";
- case dwarf_f20_mips64: return "f20";
- case dwarf_f21_mips64: return "f21";
- case dwarf_f22_mips64: return "f22";
- case dwarf_f23_mips64: return "f23";
- case dwarf_f24_mips64: return "f24";
- case dwarf_f25_mips64: return "f25";
- case dwarf_f26_mips64: return "f26";
- case dwarf_f27_mips64: return "f27";
- case dwarf_f28_mips64: return "f28";
- case dwarf_f29_mips64: return "f29";
- case dwarf_f30_mips64: return "f30";
- case dwarf_f31_mips64: return "f31";
- case dwarf_fcsr_mips64: return "fcsr";
- case dwarf_fir_mips64: return "fir";
- case dwarf_w0_mips64: return "w0";
- case dwarf_w1_mips64: return "w1";
- case dwarf_w2_mips64: return "w2";
- case dwarf_w3_mips64: return "w3";
- case dwarf_w4_mips64: return "w4";
- case dwarf_w5_mips64: return "w5";
- case dwarf_w6_mips64: return "w6";
- case dwarf_w7_mips64: return "w7";
- case dwarf_w8_mips64: return "w8";
- case dwarf_w9_mips64: return "w9";
- case dwarf_w10_mips64: return "w10";
- case dwarf_w11_mips64: return "w11";
- case dwarf_w12_mips64: return "w12";
- case dwarf_w13_mips64: return "w13";
- case dwarf_w14_mips64: return "w14";
- case dwarf_w15_mips64: return "w15";
- case dwarf_w16_mips64: return "w16";
- case dwarf_w17_mips64: return "w17";
- case dwarf_w18_mips64: return "w18";
- case dwarf_w19_mips64: return "w19";
- case dwarf_w20_mips64: return "w20";
- case dwarf_w21_mips64: return "w21";
- case dwarf_w22_mips64: return "w22";
- case dwarf_w23_mips64: return "w23";
- case dwarf_w24_mips64: return "w24";
- case dwarf_w25_mips64: return "w25";
- case dwarf_w26_mips64: return "w26";
- case dwarf_w27_mips64: return "w27";
- case dwarf_w28_mips64: return "w28";
- case dwarf_w29_mips64: return "w29";
- case dwarf_w30_mips64: return "w30";
- case dwarf_w31_mips64: return "w31";
- case dwarf_mcsr_mips64: return "mcsr";
- case dwarf_mir_mips64: return "mir";
- case dwarf_config5_mips64: return "config5";
+const char *EmulateInstructionMIPS64::GetRegisterName(unsigned reg_num,
+ bool alternate_name) {
+ if (alternate_name) {
+ switch (reg_num) {
+ case dwarf_sp_mips64:
+ return "r29";
+ case dwarf_r30_mips64:
+ return "r30";
+ case dwarf_ra_mips64:
+ return "r31";
+ case dwarf_f0_mips64:
+ return "f0";
+ case dwarf_f1_mips64:
+ return "f1";
+ case dwarf_f2_mips64:
+ return "f2";
+ case dwarf_f3_mips64:
+ return "f3";
+ case dwarf_f4_mips64:
+ return "f4";
+ case dwarf_f5_mips64:
+ return "f5";
+ case dwarf_f6_mips64:
+ return "f6";
+ case dwarf_f7_mips64:
+ return "f7";
+ case dwarf_f8_mips64:
+ return "f8";
+ case dwarf_f9_mips64:
+ return "f9";
+ case dwarf_f10_mips64:
+ return "f10";
+ case dwarf_f11_mips64:
+ return "f11";
+ case dwarf_f12_mips64:
+ return "f12";
+ case dwarf_f13_mips64:
+ return "f13";
+ case dwarf_f14_mips64:
+ return "f14";
+ case dwarf_f15_mips64:
+ return "f15";
+ case dwarf_f16_mips64:
+ return "f16";
+ case dwarf_f17_mips64:
+ return "f17";
+ case dwarf_f18_mips64:
+ return "f18";
+ case dwarf_f19_mips64:
+ return "f19";
+ case dwarf_f20_mips64:
+ return "f20";
+ case dwarf_f21_mips64:
+ return "f21";
+ case dwarf_f22_mips64:
+ return "f22";
+ case dwarf_f23_mips64:
+ return "f23";
+ case dwarf_f24_mips64:
+ return "f24";
+ case dwarf_f25_mips64:
+ return "f25";
+ case dwarf_f26_mips64:
+ return "f26";
+ case dwarf_f27_mips64:
+ return "f27";
+ case dwarf_f28_mips64:
+ return "f28";
+ case dwarf_f29_mips64:
+ return "f29";
+ case dwarf_f30_mips64:
+ return "f30";
+ case dwarf_f31_mips64:
+ return "f31";
+ case dwarf_w0_mips64:
+ return "w0";
+ case dwarf_w1_mips64:
+ return "w1";
+ case dwarf_w2_mips64:
+ return "w2";
+ case dwarf_w3_mips64:
+ return "w3";
+ case dwarf_w4_mips64:
+ return "w4";
+ case dwarf_w5_mips64:
+ return "w5";
+ case dwarf_w6_mips64:
+ return "w6";
+ case dwarf_w7_mips64:
+ return "w7";
+ case dwarf_w8_mips64:
+ return "w8";
+ case dwarf_w9_mips64:
+ return "w9";
+ case dwarf_w10_mips64:
+ return "w10";
+ case dwarf_w11_mips64:
+ return "w11";
+ case dwarf_w12_mips64:
+ return "w12";
+ case dwarf_w13_mips64:
+ return "w13";
+ case dwarf_w14_mips64:
+ return "w14";
+ case dwarf_w15_mips64:
+ return "w15";
+ case dwarf_w16_mips64:
+ return "w16";
+ case dwarf_w17_mips64:
+ return "w17";
+ case dwarf_w18_mips64:
+ return "w18";
+ case dwarf_w19_mips64:
+ return "w19";
+ case dwarf_w20_mips64:
+ return "w20";
+ case dwarf_w21_mips64:
+ return "w21";
+ case dwarf_w22_mips64:
+ return "w22";
+ case dwarf_w23_mips64:
+ return "w23";
+ case dwarf_w24_mips64:
+ return "w24";
+ case dwarf_w25_mips64:
+ return "w25";
+ case dwarf_w26_mips64:
+ return "w26";
+ case dwarf_w27_mips64:
+ return "w27";
+ case dwarf_w28_mips64:
+ return "w28";
+ case dwarf_w29_mips64:
+ return "w29";
+ case dwarf_w30_mips64:
+ return "w30";
+ case dwarf_w31_mips64:
+ return "w31";
+ case dwarf_mir_mips64:
+ return "mir";
+ case dwarf_mcsr_mips64:
+ return "mcsr";
+ case dwarf_config5_mips64:
+ return "config5";
+ default:
+ break;
}
return nullptr;
+ }
+
+ switch (reg_num) {
+ case dwarf_zero_mips64:
+ return "r0";
+ case dwarf_r1_mips64:
+ return "r1";
+ case dwarf_r2_mips64:
+ return "r2";
+ case dwarf_r3_mips64:
+ return "r3";
+ case dwarf_r4_mips64:
+ return "r4";
+ case dwarf_r5_mips64:
+ return "r5";
+ case dwarf_r6_mips64:
+ return "r6";
+ case dwarf_r7_mips64:
+ return "r7";
+ case dwarf_r8_mips64:
+ return "r8";
+ case dwarf_r9_mips64:
+ return "r9";
+ case dwarf_r10_mips64:
+ return "r10";
+ case dwarf_r11_mips64:
+ return "r11";
+ case dwarf_r12_mips64:
+ return "r12";
+ case dwarf_r13_mips64:
+ return "r13";
+ case dwarf_r14_mips64:
+ return "r14";
+ case dwarf_r15_mips64:
+ return "r15";
+ case dwarf_r16_mips64:
+ return "r16";
+ case dwarf_r17_mips64:
+ return "r17";
+ case dwarf_r18_mips64:
+ return "r18";
+ case dwarf_r19_mips64:
+ return "r19";
+ case dwarf_r20_mips64:
+ return "r20";
+ case dwarf_r21_mips64:
+ return "r21";
+ case dwarf_r22_mips64:
+ return "r22";
+ case dwarf_r23_mips64:
+ return "r23";
+ case dwarf_r24_mips64:
+ return "r24";
+ case dwarf_r25_mips64:
+ return "r25";
+ case dwarf_r26_mips64:
+ return "r26";
+ case dwarf_r27_mips64:
+ return "r27";
+ case dwarf_gp_mips64:
+ return "gp";
+ case dwarf_sp_mips64:
+ return "sp";
+ case dwarf_r30_mips64:
+ return "fp";
+ case dwarf_ra_mips64:
+ return "ra";
+ case dwarf_sr_mips64:
+ return "sr";
+ case dwarf_lo_mips64:
+ return "lo";
+ case dwarf_hi_mips64:
+ return "hi";
+ case dwarf_bad_mips64:
+ return "bad";
+ case dwarf_cause_mips64:
+ return "cause";
+ case dwarf_pc_mips64:
+ return "pc";
+ case dwarf_f0_mips64:
+ return "f0";
+ case dwarf_f1_mips64:
+ return "f1";
+ case dwarf_f2_mips64:
+ return "f2";
+ case dwarf_f3_mips64:
+ return "f3";
+ case dwarf_f4_mips64:
+ return "f4";
+ case dwarf_f5_mips64:
+ return "f5";
+ case dwarf_f6_mips64:
+ return "f6";
+ case dwarf_f7_mips64:
+ return "f7";
+ case dwarf_f8_mips64:
+ return "f8";
+ case dwarf_f9_mips64:
+ return "f9";
+ case dwarf_f10_mips64:
+ return "f10";
+ case dwarf_f11_mips64:
+ return "f11";
+ case dwarf_f12_mips64:
+ return "f12";
+ case dwarf_f13_mips64:
+ return "f13";
+ case dwarf_f14_mips64:
+ return "f14";
+ case dwarf_f15_mips64:
+ return "f15";
+ case dwarf_f16_mips64:
+ return "f16";
+ case dwarf_f17_mips64:
+ return "f17";
+ case dwarf_f18_mips64:
+ return "f18";
+ case dwarf_f19_mips64:
+ return "f19";
+ case dwarf_f20_mips64:
+ return "f20";
+ case dwarf_f21_mips64:
+ return "f21";
+ case dwarf_f22_mips64:
+ return "f22";
+ case dwarf_f23_mips64:
+ return "f23";
+ case dwarf_f24_mips64:
+ return "f24";
+ case dwarf_f25_mips64:
+ return "f25";
+ case dwarf_f26_mips64:
+ return "f26";
+ case dwarf_f27_mips64:
+ return "f27";
+ case dwarf_f28_mips64:
+ return "f28";
+ case dwarf_f29_mips64:
+ return "f29";
+ case dwarf_f30_mips64:
+ return "f30";
+ case dwarf_f31_mips64:
+ return "f31";
+ case dwarf_fcsr_mips64:
+ return "fcsr";
+ case dwarf_fir_mips64:
+ return "fir";
+ case dwarf_w0_mips64:
+ return "w0";
+ case dwarf_w1_mips64:
+ return "w1";
+ case dwarf_w2_mips64:
+ return "w2";
+ case dwarf_w3_mips64:
+ return "w3";
+ case dwarf_w4_mips64:
+ return "w4";
+ case dwarf_w5_mips64:
+ return "w5";
+ case dwarf_w6_mips64:
+ return "w6";
+ case dwarf_w7_mips64:
+ return "w7";
+ case dwarf_w8_mips64:
+ return "w8";
+ case dwarf_w9_mips64:
+ return "w9";
+ case dwarf_w10_mips64:
+ return "w10";
+ case dwarf_w11_mips64:
+ return "w11";
+ case dwarf_w12_mips64:
+ return "w12";
+ case dwarf_w13_mips64:
+ return "w13";
+ case dwarf_w14_mips64:
+ return "w14";
+ case dwarf_w15_mips64:
+ return "w15";
+ case dwarf_w16_mips64:
+ return "w16";
+ case dwarf_w17_mips64:
+ return "w17";
+ case dwarf_w18_mips64:
+ return "w18";
+ case dwarf_w19_mips64:
+ return "w19";
+ case dwarf_w20_mips64:
+ return "w20";
+ case dwarf_w21_mips64:
+ return "w21";
+ case dwarf_w22_mips64:
+ return "w22";
+ case dwarf_w23_mips64:
+ return "w23";
+ case dwarf_w24_mips64:
+ return "w24";
+ case dwarf_w25_mips64:
+ return "w25";
+ case dwarf_w26_mips64:
+ return "w26";
+ case dwarf_w27_mips64:
+ return "w27";
+ case dwarf_w28_mips64:
+ return "w28";
+ case dwarf_w29_mips64:
+ return "w29";
+ case dwarf_w30_mips64:
+ return "w30";
+ case dwarf_w31_mips64:
+ return "w31";
+ case dwarf_mcsr_mips64:
+ return "mcsr";
+ case dwarf_mir_mips64:
+ return "mir";
+ case dwarf_config5_mips64:
+ return "config5";
+ }
+ return nullptr;
}
-bool
-EmulateInstructionMIPS64::GetRegisterInfo (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
-{
- if (reg_kind == eRegisterKindGeneric)
- {
- switch (reg_num)
- {
- case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc_mips64; break;
- case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp_mips64; break;
- case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r30_mips64; break;
- case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_ra_mips64; break;
- case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sr_mips64; break;
- default:
- return false;
- }
+bool EmulateInstructionMIPS64::GetRegisterInfo(RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterInfo &reg_info) {
+ if (reg_kind == eRegisterKindGeneric) {
+ switch (reg_num) {
+ case LLDB_REGNUM_GENERIC_PC:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_pc_mips64;
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_sp_mips64;
+ break;
+ case LLDB_REGNUM_GENERIC_FP:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_r30_mips64;
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_ra_mips64;
+ break;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_sr_mips64;
+ break;
+ default:
+ return false;
}
-
- if (reg_kind == eRegisterKindDWARF)
- {
- ::memset (&reg_info, 0, sizeof(RegisterInfo));
- ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
-
- if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 || reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 || reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64)
- {
- reg_info.byte_size = 4;
- reg_info.format = eFormatHex;
- reg_info.encoding = eEncodingUint;
- }
- else if ((int)reg_num >= dwarf_zero_mips64 && (int)reg_num <= dwarf_f31_mips64)
- {
- reg_info.byte_size = 8;
- reg_info.format = eFormatHex;
- reg_info.encoding = eEncodingUint;
- }
- else if ((int)reg_num >= dwarf_w0_mips64 && (int)reg_num <= dwarf_w31_mips64)
- {
- reg_info.byte_size = 16;
- reg_info.format = eFormatVectorOfUInt8;
- reg_info.encoding = eEncodingVector;
- }
- else
- {
- return false;
- }
-
- reg_info.name = GetRegisterName (reg_num, false);
- reg_info.alt_name = GetRegisterName (reg_num, true);
- reg_info.kinds[eRegisterKindDWARF] = reg_num;
-
- switch (reg_num)
- {
- case dwarf_r30_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break;
- case dwarf_ra_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break;
- case dwarf_sp_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break;
- case dwarf_pc_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break;
- case dwarf_sr_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; break;
- default: break;
- }
- return true;
+ }
+
+ if (reg_kind == eRegisterKindDWARF) {
+ ::memset(&reg_info, 0, sizeof(RegisterInfo));
+ ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
+
+ if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 ||
+ reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 ||
+ reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64) {
+ reg_info.byte_size = 4;
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ } else if ((int)reg_num >= dwarf_zero_mips64 &&
+ (int)reg_num <= dwarf_f31_mips64) {
+ reg_info.byte_size = 8;
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ } else if ((int)reg_num >= dwarf_w0_mips64 &&
+ (int)reg_num <= dwarf_w31_mips64) {
+ reg_info.byte_size = 16;
+ reg_info.format = eFormatVectorOfUInt8;
+ reg_info.encoding = eEncodingVector;
+ } else {
+ return false;
}
- return false;
-}
-EmulateInstructionMIPS64::MipsOpcode*
-EmulateInstructionMIPS64::GetOpcodeForInstruction (const char *op_name)
-{
- static EmulateInstructionMIPS64::MipsOpcode
- g_opcodes[] =
- {
- //----------------------------------------------------------------------
- // Prologue/Epilogue instructions
- //----------------------------------------------------------------------
- { "DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, "DADDIU rt, rs, immediate" },
- { "ADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, "ADDIU rt, rs, immediate" },
- { "SD", &EmulateInstructionMIPS64::Emulate_SD, "SD rt, offset(rs)" },
- { "LD", &EmulateInstructionMIPS64::Emulate_LD, "LD rt, offset(base)" },
- { "DSUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, "DSUBU rd, rs, rt" },
- { "SUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, "SUBU rd, rs, rt" },
- { "DADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, "DADDU rd, rs, rt" },
- { "ADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, "ADDU rd, rs, rt" },
- { "LUI", &EmulateInstructionMIPS64::Emulate_LUI, "LUI rt, immediate" },
-
-
-
-
- //----------------------------------------------------------------------
- // Load/Store instructions
- //----------------------------------------------------------------------
- /* Following list of emulated instructions are required by implementation of hardware watchpoint
- for MIPS in lldb. As we just need the address accessed by instructions, we have generalised
- all these instructions in 2 functions depending on their addressing modes */
-
- { "LB", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LB rt, offset(base)" },
- { "LBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LBE rt, offset(base)" },
- { "LBU", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LBU rt, offset(base)" },
- { "LBUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LBUE rt, offset(base)" },
- { "LDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LDC1 ft, offset(base)" },
- { "LDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LDL rt, offset(base)" },
- { "LDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LDR rt, offset(base)" },
- { "LLD", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LLD rt, offset(base)" },
- { "LDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LDC2 rt, offset(base)" },
- { "LDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "LDXC1 fd, index (base)" },
- { "LH", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LH rt, offset(base)" },
- { "LHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LHE rt, offset(base)" },
- { "LHU", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LHU rt, offset(base)" },
- { "LHUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LHUE rt, offset(base)" },
- { "LL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LL rt, offset(base)" },
- { "LLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LLE rt, offset(base)" },
- { "LUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "LUXC1 fd, index (base)" },
- { "LW", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LW rt, offset(rs)" },
- { "LWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWC1 ft, offset(base)" },
- { "LWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWC2 rt, offset(base)" },
- { "LWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWE rt, offset(base)" },
- { "LWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWL rt, offset(base)" },
- { "LWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWLE rt, offset(base)" },
- { "LWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWR rt, offset(base)" },
- { "LWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWRE rt, offset(base)" },
- { "LWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "LWXC1 fd, index (base)" },
-
- { "SB", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SB rt, offset(base)" },
- { "SBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SBE rt, offset(base)" },
- { "SC", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SC rt, offset(base)" },
- { "SCE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SCE rt, offset(base)" },
- { "SCD", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SCD rt, offset(base)" },
- { "SDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SDL rt, offset(base)" },
- { "SDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SDR rt, offset(base)" },
- { "SDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SDC1 ft, offset(base)" },
- { "SDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SDC2 rt, offset(base)" },
- { "SDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "SDXC1 fs, index (base)" },
- { "SH", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SH rt, offset(base)" },
- { "SHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SHE rt, offset(base)" },
- { "SUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "SUXC1 fs, index (base)" },
- { "SW", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SW rt, offset(rs)" },
- { "SWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWC1 ft, offset(base)" },
- { "SWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWC2 rt, offset(base)" },
- { "SWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWE rt, offset(base)" },
- { "SWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWL rt, offset(base)" },
- { "SWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWLE rt, offset(base)" },
- { "SWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWR rt, offset(base)" },
- { "SWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWRE rt, offset(base)" },
- { "SWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "SWXC1 fs, index (base)" },
-
- //----------------------------------------------------------------------
- // Branch instructions
- //----------------------------------------------------------------------
- { "BEQ", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset" },
- { "BNE", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset" },
- { "BEQL", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQL rs,rt,offset" },
- { "BNEL", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNEL rs,rt,offset" },
- { "BGEZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, "BGEZALL rt,offset" },
- { "BAL", &EmulateInstructionMIPS64::Emulate_BAL, "BAL offset" },
- { "BGEZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, "BGEZAL rs,offset" },
- { "BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset" },
- { "BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset" },
- { "BGEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset" },
- { "BLEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BLEZALC rs,offset" },
- { "BGEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BGEZALC rs,offset" },
- { "BLTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BLTZALC rs,offset" },
- { "BGTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BGTZALC rs,offset" },
- { "BEQZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BEQZALC rs,offset" },
- { "BNEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BNEZALC rs,offset" },
- { "BEQC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BEQC rs,rt,offset" },
- { "BNEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BNEC rs,rt,offset" },
- { "BLTC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BLTC rs,rt,offset" },
- { "BGEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BGEC rs,rt,offset" },
- { "BLTUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BLTUC rs,rt,offset" },
- { "BGEUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BGEUC rs,rt,offset" },
- { "BLTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BLTZC rt,offset" },
- { "BLEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BLEZC rt,offset" },
- { "BGEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BGEZC rt,offset" },
- { "BGTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BGTZC rt,offset" },
- { "BEQZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BEQZC rt,offset" },
- { "BNEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BNEZC rt,offset" },
- { "BGEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZL rt,offset" },
- { "BGTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset" },
- { "BGTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZL rt,offset" },
- { "BLEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset" },
- { "BLEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZL rt,offset" },
- { "BLTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset" },
- { "BLTZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, "BLTZAL rt,offset" },
- { "BLTZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, "BLTZALL rt,offset" },
- { "BLTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZL rt,offset" },
- { "BOVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BOVC rs,rt,offset" },
- { "BNVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BNVC rs,rt,offset" },
- { "J", &EmulateInstructionMIPS64::Emulate_J, "J target" },
- { "JAL", &EmulateInstructionMIPS64::Emulate_JAL, "JAL target" },
- { "JALX", &EmulateInstructionMIPS64::Emulate_JAL, "JALX target" },
- { "JALR", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target" },
- { "JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target" },
- { "JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset" },
- { "JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset" },
- { "JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target" },
- { "JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target" },
- { "BC1F", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1F cc, offset" },
- { "BC1T", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1T cc, offset" },
- { "BC1FL", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1FL cc, offset" },
- { "BC1TL", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1TL cc, offset" },
- { "BC1EQZ", &EmulateInstructionMIPS64::Emulate_BC1EQZ, "BC1EQZ ft, offset" },
- { "BC1NEZ", &EmulateInstructionMIPS64::Emulate_BC1NEZ, "BC1NEZ ft, offset" },
- { "BC1ANY2F", &EmulateInstructionMIPS64::Emulate_3D_branch, "BC1ANY2F cc, offset" },
- { "BC1ANY2T", &EmulateInstructionMIPS64::Emulate_3D_branch, "BC1ANY2T cc, offset" },
- { "BC1ANY4F", &EmulateInstructionMIPS64::Emulate_3D_branch, "BC1ANY4F cc, offset" },
- { "BC1ANY4T", &EmulateInstructionMIPS64::Emulate_3D_branch, "BC1ANY4T cc, offset" },
- { "BNZ_B", &EmulateInstructionMIPS64::Emulate_BNZB, "BNZ.b wt,s16" },
- { "BNZ_H", &EmulateInstructionMIPS64::Emulate_BNZH, "BNZ.h wt,s16" },
- { "BNZ_W", &EmulateInstructionMIPS64::Emulate_BNZW, "BNZ.w wt,s16" },
- { "BNZ_D", &EmulateInstructionMIPS64::Emulate_BNZD, "BNZ.d wt,s16" },
- { "BZ_B", &EmulateInstructionMIPS64::Emulate_BZB, "BZ.b wt,s16" },
- { "BZ_H", &EmulateInstructionMIPS64::Emulate_BZH, "BZ.h wt,s16" },
- { "BZ_W", &EmulateInstructionMIPS64::Emulate_BZW, "BZ.w wt,s16" },
- { "BZ_D", &EmulateInstructionMIPS64::Emulate_BZD, "BZ.d wt,s16" },
- { "BNZ_V", &EmulateInstructionMIPS64::Emulate_BNZV, "BNZ.V wt,s16" },
- { "BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16" },
- };
-
- static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
-
- for (size_t i = 0; i < k_num_mips_opcodes; ++i)
- {
- if (! strcasecmp (g_opcodes[i].op_name, op_name))
- return &g_opcodes[i];
+ reg_info.name = GetRegisterName(reg_num, false);
+ reg_info.alt_name = GetRegisterName(reg_num, true);
+ reg_info.kinds[eRegisterKindDWARF] = reg_num;
+
+ switch (reg_num) {
+ case dwarf_r30_mips64:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ break;
+ case dwarf_ra_mips64:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+ break;
+ case dwarf_sp_mips64:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ break;
+ case dwarf_pc_mips64:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ break;
+ case dwarf_sr_mips64:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ break;
+ default:
+ break;
}
-
- return NULL;
+ return true;
+ }
+ return false;
}
-bool
-EmulateInstructionMIPS64::ReadInstruction ()
-{
- bool success = false;
- m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
- if (success)
- {
- Context read_inst_context;
- read_inst_context.type = eContextReadOpcode;
- read_inst_context.SetNoArgs ();
- m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder());
- }
- if (!success)
- m_addr = LLDB_INVALID_ADDRESS;
- return success;
+EmulateInstructionMIPS64::MipsOpcode *
+EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) {
+ static EmulateInstructionMIPS64::MipsOpcode g_opcodes[] = {
+ //----------------------------------------------------------------------
+ // Prologue/Epilogue instructions
+ //----------------------------------------------------------------------
+ {"DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu,
+ "DADDIU rt, rs, immediate"},
+ {"ADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu,
+ "ADDIU rt, rs, immediate"},
+ {"SD", &EmulateInstructionMIPS64::Emulate_SD, "SD rt, offset(rs)"},
+ {"LD", &EmulateInstructionMIPS64::Emulate_LD, "LD rt, offset(base)"},
+ {"DSUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
+ "DSUBU rd, rs, rt"},
+ {"SUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
+ "SUBU rd, rs, rt"},
+ {"DADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
+ "DADDU rd, rs, rt"},
+ {"ADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
+ "ADDU rd, rs, rt"},
+ {"LUI", &EmulateInstructionMIPS64::Emulate_LUI, "LUI rt, immediate"},
+
+ //----------------------------------------------------------------------
+ // Load/Store instructions
+ //----------------------------------------------------------------------
+ /* Following list of emulated instructions are required by implementation
+ of hardware watchpoint
+ for MIPS in lldb. As we just need the address accessed by instructions,
+ we have generalised
+ all these instructions in 2 functions depending on their addressing
+ modes */
+
+ {"LB", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LB rt, offset(base)"},
+ {"LBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LBE rt, offset(base)"},
+ {"LBU", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LBU rt, offset(base)"},
+ {"LBUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LBUE rt, offset(base)"},
+ {"LDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LDC1 ft, offset(base)"},
+ {"LDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LDL rt, offset(base)"},
+ {"LDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LDR rt, offset(base)"},
+ {"LLD", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LLD rt, offset(base)"},
+ {"LDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LDC2 rt, offset(base)"},
+ {"LDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "LDXC1 fd, index (base)"},
+ {"LH", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LH rt, offset(base)"},
+ {"LHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LHE rt, offset(base)"},
+ {"LHU", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LHU rt, offset(base)"},
+ {"LHUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LHUE rt, offset(base)"},
+ {"LL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LL rt, offset(base)"},
+ {"LLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LLE rt, offset(base)"},
+ {"LUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "LUXC1 fd, index (base)"},
+ {"LW", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LW rt, offset(rs)"},
+ {"LWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWC1 ft, offset(base)"},
+ {"LWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWC2 rt, offset(base)"},
+ {"LWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWE rt, offset(base)"},
+ {"LWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWL rt, offset(base)"},
+ {"LWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWLE rt, offset(base)"},
+ {"LWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWR rt, offset(base)"},
+ {"LWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWRE rt, offset(base)"},
+ {"LWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "LWXC1 fd, index (base)"},
+
+ {"SB", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SB rt, offset(base)"},
+ {"SBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SBE rt, offset(base)"},
+ {"SC", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SC rt, offset(base)"},
+ {"SCE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SCE rt, offset(base)"},
+ {"SCD", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SCD rt, offset(base)"},
+ {"SDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SDL rt, offset(base)"},
+ {"SDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SDR rt, offset(base)"},
+ {"SDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SDC1 ft, offset(base)"},
+ {"SDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SDC2 rt, offset(base)"},
+ {"SDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "SDXC1 fs, index (base)"},
+ {"SH", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SH rt, offset(base)"},
+ {"SHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SHE rt, offset(base)"},
+ {"SUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "SUXC1 fs, index (base)"},
+ {"SW", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SW rt, offset(rs)"},
+ {"SWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWC1 ft, offset(base)"},
+ {"SWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWC2 rt, offset(base)"},
+ {"SWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWE rt, offset(base)"},
+ {"SWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWL rt, offset(base)"},
+ {"SWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWLE rt, offset(base)"},
+ {"SWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWR rt, offset(base)"},
+ {"SWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWRE rt, offset(base)"},
+ {"SWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "SWXC1 fs, index (base)"},
+
+ //----------------------------------------------------------------------
+ // Branch instructions
+ //----------------------------------------------------------------------
+ {"BEQ", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
+ {"BNE", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"},
+ {"BEQL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
+ "BEQL rs,rt,offset"},
+ {"BNEL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
+ "BNEL rs,rt,offset"},
+ {"BGEZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
+ "BGEZALL rt,offset"},
+ {"BAL", &EmulateInstructionMIPS64::Emulate_BAL, "BAL offset"},
+ {"BGEZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
+ "BGEZAL rs,offset"},
+ {"BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset"},
+ {"BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset"},
+ {"BGEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"},
+ {"BLEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BLEZALC rs,offset"},
+ {"BGEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BGEZALC rs,offset"},
+ {"BLTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BLTZALC rs,offset"},
+ {"BGTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BGTZALC rs,offset"},
+ {"BEQZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BEQZALC rs,offset"},
+ {"BNEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BNEZALC rs,offset"},
+ {"BEQC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BEQC rs,rt,offset"},
+ {"BNEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BNEC rs,rt,offset"},
+ {"BLTC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BLTC rs,rt,offset"},
+ {"BGEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BGEC rs,rt,offset"},
+ {"BLTUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BLTUC rs,rt,offset"},
+ {"BGEUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BGEUC rs,rt,offset"},
+ {"BLTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BLTZC rt,offset"},
+ {"BLEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BLEZC rt,offset"},
+ {"BGEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BGEZC rt,offset"},
+ {"BGTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BGTZC rt,offset"},
+ {"BEQZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BEQZC rt,offset"},
+ {"BNEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BNEZC rt,offset"},
+ {"BGEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZL rt,offset"},
+ {"BGTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"},
+ {"BGTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZL rt,offset"},
+ {"BLEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"},
+ {"BLEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZL rt,offset"},
+ {"BLTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"},
+ {"BLTZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
+ "BLTZAL rt,offset"},
+ {"BLTZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
+ "BLTZALL rt,offset"},
+ {"BLTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZL rt,offset"},
+ {"BOVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BOVC rs,rt,offset"},
+ {"BNVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BNVC rs,rt,offset"},
+ {"J", &EmulateInstructionMIPS64::Emulate_J, "J target"},
+ {"JAL", &EmulateInstructionMIPS64::Emulate_JAL, "JAL target"},
+ {"JALX", &EmulateInstructionMIPS64::Emulate_JAL, "JALX target"},
+ {"JALR", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
+ {"JALR64", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
+ {"JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target"},
+ {"JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"},
+ {"JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"},
+ {"JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target"},
+ {"JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target"},
+ {"BC1F", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1F cc, offset"},
+ {"BC1T", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1T cc, offset"},
+ {"BC1FL", &EmulateInstructionMIPS64::Emulate_FP_branch,
+ "BC1FL cc, offset"},
+ {"BC1TL", &EmulateInstructionMIPS64::Emulate_FP_branch,
+ "BC1TL cc, offset"},
+ {"BC1EQZ", &EmulateInstructionMIPS64::Emulate_BC1EQZ,
+ "BC1EQZ ft, offset"},
+ {"BC1NEZ", &EmulateInstructionMIPS64::Emulate_BC1NEZ,
+ "BC1NEZ ft, offset"},
+ {"BC1ANY2F", &EmulateInstructionMIPS64::Emulate_3D_branch,
+ "BC1ANY2F cc, offset"},
+ {"BC1ANY2T", &EmulateInstructionMIPS64::Emulate_3D_branch,
+ "BC1ANY2T cc, offset"},
+ {"BC1ANY4F", &EmulateInstructionMIPS64::Emulate_3D_branch,
+ "BC1ANY4F cc, offset"},
+ {"BC1ANY4T", &EmulateInstructionMIPS64::Emulate_3D_branch,
+ "BC1ANY4T cc, offset"},
+ {"BNZ_B", &EmulateInstructionMIPS64::Emulate_BNZB, "BNZ.b wt,s16"},
+ {"BNZ_H", &EmulateInstructionMIPS64::Emulate_BNZH, "BNZ.h wt,s16"},
+ {"BNZ_W", &EmulateInstructionMIPS64::Emulate_BNZW, "BNZ.w wt,s16"},
+ {"BNZ_D", &EmulateInstructionMIPS64::Emulate_BNZD, "BNZ.d wt,s16"},
+ {"BZ_B", &EmulateInstructionMIPS64::Emulate_BZB, "BZ.b wt,s16"},
+ {"BZ_H", &EmulateInstructionMIPS64::Emulate_BZH, "BZ.h wt,s16"},
+ {"BZ_W", &EmulateInstructionMIPS64::Emulate_BZW, "BZ.w wt,s16"},
+ {"BZ_D", &EmulateInstructionMIPS64::Emulate_BZD, "BZ.d wt,s16"},
+ {"BNZ_V", &EmulateInstructionMIPS64::Emulate_BNZV, "BNZ.V wt,s16"},
+ {"BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16"},
+ };
+
+ static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
+
+ for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
+ if (!strcasecmp(g_opcodes[i].op_name, op_name))
+ return &g_opcodes[i];
+ }
+
+ return NULL;
}
-bool
-EmulateInstructionMIPS64::EvaluateInstruction (uint32_t evaluate_options)
-{
- bool success = false;
- llvm::MCInst mc_insn;
- uint64_t insn_size;
- DataExtractor data;
-
- /* Keep the complexity of the decode logic with the llvm::MCDisassembler class. */
- if (m_opcode.GetData (data))
- {
- llvm::MCDisassembler::DecodeStatus decode_status;
- llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize());
- decode_status = m_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
- if (decode_status != llvm::MCDisassembler::Success)
- return false;
- }
+bool EmulateInstructionMIPS64::ReadInstruction() {
+ bool success = false;
+ m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_ADDRESS, &success);
+ if (success) {
+ Context read_inst_context;
+ read_inst_context.type = eContextReadOpcode;
+ read_inst_context.SetNoArgs();
+ m_opcode.SetOpcode32(
+ ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
+ GetByteOrder());
+ }
+ if (!success)
+ m_addr = LLDB_INVALID_ADDRESS;
+ return success;
+}
- /*
- * mc_insn.getOpcode() returns decoded opcode. However to make use
- * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
- */
- const char *op_name = m_insn_info->getName (mc_insn.getOpcode ());
+bool EmulateInstructionMIPS64::EvaluateInstruction(uint32_t evaluate_options) {
+ bool success = false;
+ llvm::MCInst mc_insn;
+ uint64_t insn_size;
+ DataExtractor data;
+
+ /* Keep the complexity of the decode logic with the llvm::MCDisassembler
+ * class. */
+ if (m_opcode.GetData(data)) {
+ llvm::MCDisassembler::DecodeStatus decode_status;
+ llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
+ decode_status = m_disasm->getInstruction(
+ mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
+ if (decode_status != llvm::MCDisassembler::Success)
+ return false;
+ }
+
+ /*
+ * mc_insn.getOpcode() returns decoded opcode. However to make use
+ * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
+ */
+ const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
+
+ if (op_name == NULL)
+ return false;
- if (op_name == NULL)
- return false;
+ /*
+ * Decoding has been done already. Just get the call-back function
+ * and emulate the instruction.
+ */
+ MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
- /*
- * Decoding has been done already. Just get the call-back function
- * and emulate the instruction.
- */
- MipsOpcode *opcode_data = GetOpcodeForInstruction (op_name);
+ if (opcode_data == NULL)
+ return false;
- if (opcode_data == NULL)
- return false;
+ uint64_t old_pc = 0, new_pc = 0;
+ const bool auto_advance_pc =
+ evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
- uint64_t old_pc = 0, new_pc = 0;
- const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+ if (auto_advance_pc) {
+ old_pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+ }
- if (auto_advance_pc)
- {
- old_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
- }
+ /* emulate instruction */
+ success = (this->*opcode_data->callback)(mc_insn);
+ if (!success)
+ return false;
- /* emulate instruction */
- success = (this->*opcode_data->callback) (mc_insn);
+ if (auto_advance_pc) {
+ new_pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
if (!success)
- return false;
+ return false;
- if (auto_advance_pc)
- {
- new_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
-
- /* If we haven't changed the PC, change it here */
- if (old_pc == new_pc)
- {
- new_pc += 4;
- Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, new_pc))
- return false;
- }
+ /* If we haven't changed the PC, change it here */
+ if (old_pc == new_pc) {
+ new_pc += 4;
+ Context context;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ new_pc))
+ return false;
}
+ }
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind(
+ UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const bool can_replace = false;
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const bool can_replace = false;
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips64, 0);
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips64, 0);
- // Our previous PC is in the RA
- row->SetRegisterLocationToRegister(dwarf_pc_mips64, dwarf_ra_mips64, can_replace);
+ // Our previous PC is in the RA
+ row->SetRegisterLocationToRegister(dwarf_pc_mips64, dwarf_ra_mips64,
+ can_replace);
- unwind_plan.AppendRow (row);
+ unwind_plan.AppendRow(row);
- // All other registers are the same.
- unwind_plan.SetSourceName ("EmulateInstructionMIPS64");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
- unwind_plan.SetReturnAddressRegister (dwarf_ra_mips64);
+ // All other registers are the same.
+ unwind_plan.SetSourceName("EmulateInstructionMIPS64");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64);
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::nonvolatile_reg_p (uint64_t regnum)
-{
- switch (regnum)
- {
- case dwarf_r16_mips64:
- case dwarf_r17_mips64:
- case dwarf_r18_mips64:
- case dwarf_r19_mips64:
- case dwarf_r20_mips64:
- case dwarf_r21_mips64:
- case dwarf_r22_mips64:
- case dwarf_r23_mips64:
- case dwarf_gp_mips64:
- case dwarf_sp_mips64:
- case dwarf_r30_mips64:
- case dwarf_ra_mips64:
- return true;
- default:
- return false;
- }
+bool EmulateInstructionMIPS64::nonvolatile_reg_p(uint64_t regnum) {
+ switch (regnum) {
+ case dwarf_r16_mips64:
+ case dwarf_r17_mips64:
+ case dwarf_r18_mips64:
+ case dwarf_r19_mips64:
+ case dwarf_r20_mips64:
+ case dwarf_r21_mips64:
+ case dwarf_r22_mips64:
+ case dwarf_r23_mips64:
+ case dwarf_gp_mips64:
+ case dwarf_sp_mips64:
+ case dwarf_r30_mips64:
+ case dwarf_ra_mips64:
+ return true;
+ default:
return false;
+ }
+ return false;
}
-bool
-EmulateInstructionMIPS64::Emulate_DADDiu (llvm::MCInst& insn)
-{
- // DADDIU rt, rs, immediate
- // GPR[rt] <- GPR[rs] + sign_extend(immediate)
-
- uint8_t dst, src;
- bool success = false;
- const uint32_t imm16 = insn.getOperand(2).getImm();
- int64_t imm = SignedBits(imm16, 15, 0);
-
- dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
-
- // If immediate is greater than 2^16 - 1 then clang generate
- // LUI, (D)ADDIU,(D)SUBU instructions in prolog.
- // Example
- // lui $1, 0x2
- // daddiu $1, $1, -0x5920
- // dsubu $sp, $sp, $1
- // In this case, (D)ADDIU dst and src will be same and not equal to sp
- if (dst == src)
- {
- Context context;
-
- /* read <src> register */
- const int64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
- if (!success)
- return false;
-
- /* Check if this is daddiu sp, sp, imm16 */
- if (dst == dwarf_sp_mips64)
- {
- uint64_t result = src_opd_val + imm;
- RegisterInfo reg_info_sp;
-
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, imm);
-
- /* We are allocating bytes on stack */
- context.type = eContextAdjustStackPointer;
-
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips64, result);
- return true;
- }
-
- imm += src_opd_val;
- context.SetImmediateSigned (imm);
- context.type = eContextImmediate;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips64 + dst, imm))
- return false;
+bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) {
+ // DADDIU rt, rs, immediate
+ // GPR[rt] <- GPR[rs] + sign_extend(immediate)
+
+ uint8_t dst, src;
+ bool success = false;
+ const uint32_t imm16 = insn.getOperand(2).getImm();
+ int64_t imm = SignedBits(imm16, 15, 0);
+
+ dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+
+ // If immediate is greater than 2^16 - 1 then clang generate
+ // LUI, (D)ADDIU,(D)SUBU instructions in prolog.
+ // Example
+ // lui $1, 0x2
+ // daddiu $1, $1, -0x5920
+ // dsubu $sp, $sp, $1
+ // In this case, (D)ADDIU dst and src will be same and not equal to sp
+ if (dst == src) {
+ Context context;
+
+ /* read <src> register */
+ const int64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
+ if (!success)
+ return false;
+
+ /* Check if this is daddiu sp, sp, imm16 */
+ if (dst == dwarf_sp_mips64) {
+ uint64_t result = src_opd_val + imm;
+ RegisterInfo reg_info_sp;
+
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, imm);
+
+ /* We are allocating bytes on stack */
+ context.type = eContextAdjustStackPointer;
+
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64,
+ result);
+ return true;
}
- return true;
-}
+ imm += src_opd_val;
+ context.SetImmediateSigned(imm);
+ context.type = eContextImmediate;
-bool
-EmulateInstructionMIPS64::Emulate_SD (llvm::MCInst& insn)
-{
- uint64_t address;
- RegisterInfo reg_info_base;
- RegisterInfo reg_info_src;
- bool success = false;
- uint32_t imm16 = insn.getOperand(2).getImm();
- uint64_t imm = SignedBits(imm16, 15, 0);
- uint32_t src, base;
- Context bad_vaddr_context;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips64 + dst, imm))
+ return false;
+ }
- src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ return true;
+}
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips64 + base, reg_info_base)
- || !GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips64 + src, reg_info_src))
- return false;
+bool EmulateInstructionMIPS64::Emulate_SD(llvm::MCInst &insn) {
+ uint64_t address;
+ RegisterInfo reg_info_base;
+ RegisterInfo reg_info_src;
+ bool success = false;
+ uint32_t imm16 = insn.getOperand(2).getImm();
+ uint64_t imm = SignedBits(imm16, 15, 0);
+ uint32_t src, base;
+ Context bad_vaddr_context;
+
+ src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
+ reg_info_base) ||
+ !GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
+ reg_info_src))
+ return false;
- /* read SP */
- address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + base, 0, &success);
- if (!success)
- return false;
+ /* read SP */
+ address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
+ 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
- /* We look for sp based non-volatile register stores */
- if (nonvolatile_reg_p (src))
- {
- Context context;
- RegisterValue data_src;
- context.type = eContextPushRegisterOnStack;
- context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
+ /* We look for sp based non-volatile register stores */
+ if (nonvolatile_reg_p(src)) {
+ Context context;
+ RegisterValue data_src;
+ context.type = eContextPushRegisterOnStack;
+ context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
- uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
- Error error;
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ Error error;
- if (!ReadRegister (&reg_info_base, data_src))
- return false;
+ if (!ReadRegister(&reg_info_base, data_src))
+ return false;
- if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
- return false;
+ if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- if (!WriteMemory (context, address, buffer, reg_info_src.byte_size))
- return false;
- }
+ if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
+ return false;
+ }
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
+ address);
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_LD (llvm::MCInst& insn)
-{
- bool success =false;
- uint32_t src, base;
- int64_t imm, address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS64::Emulate_LD(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t src, base;
+ int64_t imm, address;
+ Context bad_vaddr_context;
- src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- imm = insn.getOperand(2).getImm();
-
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips64 + base, reg_info_base))
- return false;
+ src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ imm = insn.getOperand(2).getImm();
- /* read base register */
- address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + base, 0, &success);
- if (!success)
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
+ reg_info_base))
+ return false;
- /* destination address */
- address = address + imm;
+ /* read base register */
+ address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
+ 0, &success);
+ if (!success)
+ return false;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64, address);
+ /* destination address */
+ address = address + imm;
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
+ address);
- if (nonvolatile_reg_p (src))
- {
- RegisterValue data_src;
- RegisterInfo reg_info_src;
+ if (nonvolatile_reg_p(src)) {
+ RegisterValue data_src;
+ RegisterInfo reg_info_src;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips64 + src, reg_info_src))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
+ reg_info_src))
+ return false;
- Context context;
- context.type = eContextRegisterLoad;
+ Context context;
+ context.type = eContextRegisterLoad;
- if (!WriteRegister (context, &reg_info_src, data_src))
- return false;
+ if (!WriteRegister(context, &reg_info_src, data_src))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
-bool
-EmulateInstructionMIPS64::Emulate_LUI (llvm::MCInst& insn)
-{
- // LUI rt, immediate
- // GPR[rt] <- sign_extend(immediate << 16)
+bool EmulateInstructionMIPS64::Emulate_LUI(llvm::MCInst &insn) {
+ // LUI rt, immediate
+ // GPR[rt] <- sign_extend(immediate << 16)
- const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
- int64_t imm = SignedBits(imm32, 31, 0);
- uint8_t rt;
- Context context;
-
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- context.SetImmediateSigned (imm);
- context.type = eContextImmediate;
+ const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
+ int64_t imm = SignedBits(imm32, 31, 0);
+ uint8_t rt;
+ Context context;
- if (WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips64 + rt, imm))
- return true;
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ context.SetImmediateSigned(imm);
+ context.type = eContextImmediate;
- return false;
+ if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips64 + rt,
+ imm))
+ return true;
+
+ return false;
}
-bool
-EmulateInstructionMIPS64::Emulate_DSUBU_DADDU (llvm::MCInst& insn)
-{
- // DSUBU sp, <src>, <rt>
- // DADDU sp, <src>, <rt>
- // DADDU dst, sp, <rt>
-
- bool success = false;
- uint64_t result;
- uint8_t src, dst, rt;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
-
- /* Check if sp is destination register */
- if (dst == dwarf_sp_mips64)
- {
- rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg());
-
- /* read <src> register */
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
- if (!success)
- return false;
-
- /* read <rt > register */
- uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
-
- if (!strcasecmp (op_name, "DSUBU") || !strcasecmp (op_name, "SUBU"))
- result = src_opd_val - rt_opd_val;
- else
- result = src_opd_val + rt_opd_val;
-
- Context context;
- RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, rt_opd_val);
-
- /* We are allocating bytes on stack */
- context.type = eContextAdjustStackPointer;
-
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips64, result);
-
- return true;
- }
- else if (src == dwarf_sp_mips64)
- {
- rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg());
+bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) {
+ // DSUBU sp, <src>, <rt>
+ // DADDU sp, <src>, <rt>
+ // DADDU dst, sp, <rt>
- /* read <src> register */
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
- if (!success)
- return false;
+ bool success = false;
+ uint64_t result;
+ uint8_t src, dst, rt;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- /* read <rt> register */
- uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
+ dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- Context context;
+ /* Check if sp is destination register */
+ if (dst == dwarf_sp_mips64) {
+ rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
- if (!strcasecmp (op_name, "DSUBU") || !strcasecmp (op_name, "SUBU"))
- result = src_opd_val - rt_opd_val;
- else
- result = src_opd_val + rt_opd_val;
+ /* read <src> register */
+ uint64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
+ if (!success)
+ return false;
- context.SetImmediateSigned (result);
- context.type = eContextImmediate;
+ /* read <rt > register */
+ uint64_t rt_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips64 + dst, result))
- return false;
- }
+ if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU"))
+ result = src_opd_val - rt_opd_val;
+ else
+ result = src_opd_val + rt_opd_val;
+
+ Context context;
+ RegisterInfo reg_info_sp;
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
+
+ /* We are allocating bytes on stack */
+ context.type = eContextAdjustStackPointer;
+
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64, result);
return true;
+ } else if (src == dwarf_sp_mips64) {
+ rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
+
+ /* read <src> register */
+ uint64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
+ if (!success)
+ return false;
+
+ /* read <rt> register */
+ uint64_t rt_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
+
+ Context context;
+
+ if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU"))
+ result = src_opd_val - rt_opd_val;
+ else
+ result = src_opd_val + rt_opd_val;
+
+ context.SetImmediateSigned(result);
+ context.type = eContextImmediate;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips64 + dst, result))
+ return false;
+ }
+
+ return true;
}
/*
@@ -1038,706 +1314,651 @@ EmulateInstructionMIPS64::Emulate_DSUBU_DADDU (llvm::MCInst& insn)
BEQ, BNE : Branch on condition
BEQL, BNEL : Branch likely
*/
-bool
-EmulateInstructionMIPS64::Emulate_BXX_3ops (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- int64_t offset, pc, rs_val, rt_val, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- offset = insn.getOperand(2).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ int64_t offset, pc, rs_val, rt_val, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ offset = insn.getOperand(2).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BEQ") ||
- !strcasecmp (op_name, "BEQL"))
- {
- if (rs_val == rt_val)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BNE") ||
- !strcasecmp (op_name, "BNEL"))
- {
- if (rs_val != rt_val)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
+ if (rs_val == rt_val)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
+ if (rs_val != rt_val)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-/*
+/*
Emulate below MIPS Non-Compact conditional branch and link instructions.
BLTZAL, BGEZAL :
BLTZALL, BGEZALL : Branch likely
*/
-bool
-EmulateInstructionMIPS64::Emulate_Bcond_Link (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int64_t offset, pc, target = 0;
- int64_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_Bcond_Link(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target = 0;
+ int64_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLTZAL") ||
- !strcasecmp (op_name, "BLTZALL"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGEZAL") ||
- !strcasecmp (op_name, "BGEZALL"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGEZAL") ||
+ !strcasecmp(op_name, "BGEZALL")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BAL (llvm::MCInst& insn)
-{
- bool success = false;
- int64_t offset, pc, target;
-
- /*
- * BAL offset
- * offset = sign_ext (offset << 2)
- * RA = PC + 8
- * PC = PC + offset
- */
- offset = insn.getOperand(0).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BAL(llvm::MCInst &insn) {
+ bool success = false;
+ int64_t offset, pc, target;
- target = pc + offset;
+ /*
+ * BAL offset
+ * offset = sign_ext (offset << 2)
+ * RA = PC + 8
+ * PC = PC + offset
+ */
+ offset = insn.getOperand(0).getImm();
- Context context;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ target = pc + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 8))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 8))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BALC (llvm::MCInst& insn)
-{
- bool success = false;
- int64_t offset, pc, target;
-
- /*
- * BALC offset
- * offset = sign_ext (offset << 2)
- * RA = PC + 4
- * PC = PC + 4 + offset
- */
- offset = insn.getOperand(0).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BALC(llvm::MCInst &insn) {
+ bool success = false;
+ int64_t offset, pc, target;
- target = pc + offset;
+ /*
+ * BALC offset
+ * offset = sign_ext (offset << 2)
+ * RA = PC + 4
+ * PC = PC + 4 + offset
+ */
+ offset = insn.getOperand(0).getImm();
- Context context;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ target = pc + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 4))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 4))
+ return false;
+
+ return true;
}
-/*
+/*
Emulate below MIPS conditional branch and link instructions.
BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
*/
-bool
-EmulateInstructionMIPS64::Emulate_Bcond_Link_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int64_t offset, pc, rs_val, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, rs_val, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- if (!strcasecmp (op_name, "BLEZALC"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEZALC"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTZALC"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGTZALC"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BEQZALC"))
- {
- if (rs_val == 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEZALC"))
- {
- if (rs_val != 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- Context context;
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!strcasecmp(op_name, "BLEZALC")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEZALC")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTZALC")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGTZALC")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BEQZALC")) {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEZALC")) {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 4))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 4))
+ return false;
+
+ return true;
}
-/*
+/*
Emulate below MIPS branch instructions.
BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
*/
-bool
-EmulateInstructionMIPS64::Emulate_BXX_2ops (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int64_t offset, pc, rs_val, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, rs_val, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- if (!strcasecmp (op_name, "BLTZL") ||
- !strcasecmp (op_name, "BLTZ"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGEZL") ||
- !strcasecmp (op_name, "BGEZ"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGTZL") ||
- !strcasecmp (op_name, "BGTZ"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BLEZL") ||
- !strcasecmp (op_name, "BLEZ"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (offset);
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- return true;
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BC (llvm::MCInst& insn)
-{
- bool success = false;
- int64_t offset, pc, target;
+bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) {
+ bool success = false;
+ int64_t offset, pc, target;
- /*
- * BC offset
- * offset = sign_ext (offset << 2)
- * PC = PC + 4 + offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * BC offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC + 4 + offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- target = pc + offset;
+ target = pc + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-static int
-IsAdd64bitOverflow (int64_t a, int64_t b)
-{
- int64_t r = (uint64_t) a + (uint64_t) b;
+static int IsAdd64bitOverflow(int64_t a, int64_t b) {
+ int64_t r = (uint64_t)a + (uint64_t)b;
return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
}
/*
Emulate below MIPS branch instructions.
- BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch instructions with no delay slot
+ BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
+ instructions with no delay slot
*/
-bool
-EmulateInstructionMIPS64::Emulate_BXX_3ops_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- int64_t offset, pc, rs_val, rt_val, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- offset = insn.getOperand(2).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ int64_t offset, pc, rs_val, rt_val, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ offset = insn.getOperand(2).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BEQC"))
- {
- if (rs_val == rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEC"))
- {
- if (rs_val != rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTC"))
- {
- if (rs_val < rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEC"))
- {
- if (rs_val >= rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTUC"))
- {
- if (rs_val < rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEUC"))
- {
- if ((uint32_t)rs_val >= (uint32_t)rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BOVC"))
- {
- if (IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNVC"))
- {
- if (!IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + offset;
- else
- target = pc + 4;
- }
+ if (!strcasecmp(op_name, "BEQC")) {
+ if (rs_val == rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEC")) {
+ if (rs_val != rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTC")) {
+ if (rs_val < rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEC")) {
+ if (rs_val >= rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTUC")) {
+ if (rs_val < rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEUC")) {
+ if ((uint32_t)rs_val >= (uint32_t)rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BOVC")) {
+ if (IsAdd64bitOverflow(rs_val, rt_val))
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNVC")) {
+ if (!IsAdd64bitOverflow(rs_val, rt_val))
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-/*
+/*
Emulate below MIPS branch instructions.
BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
*/
-bool
-EmulateInstructionMIPS64::Emulate_BXX_2ops_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int64_t offset, pc, target = 0;
- int64_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target = 0;
+ int64_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLTZC"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLEZC"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEZC"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGTZC"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BEQZC"))
- {
- if (rs_val == 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEZC"))
- {
- if (rs_val != 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
+ if (!strcasecmp(op_name, "BLTZC")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLEZC")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEZC")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGTZC")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BEQZC")) {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEZC")) {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_J (llvm::MCInst& insn)
-{
- bool success = false;
- uint64_t offset, pc;
+bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) {
+ bool success = false;
+ uint64_t offset, pc;
- /*
- * J offset
- * offset = sign_ext (offset << 2)
- * PC = PC[63-28] | offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * J offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC[63-28] | offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- /* This is a PC-region branch and not PC-relative */
- pc = (pc & 0xFFFFFFFFF0000000ULL) | offset;
+ /* This is a PC-region branch and not PC-relative */
+ pc = (pc & 0xFFFFFFFFF0000000ULL) | offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, pc))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, pc))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_JAL (llvm::MCInst& insn)
-{
- bool success = false;
- uint64_t offset, target, pc;
+bool EmulateInstructionMIPS64::Emulate_JAL(llvm::MCInst &insn) {
+ bool success = false;
+ uint64_t offset, target, pc;
- /*
- * JAL offset
- * offset = sign_ext (offset << 2)
- * PC = PC[63-28] | offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * JAL offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC[63-28] | offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- /* This is a PC-region branch and not PC-relative */
- target = (pc & 0xFFFFFFFFF0000000ULL) | offset;
+ /* This is a PC-region branch and not PC-relative */
+ target = (pc & 0xFFFFFFFFF0000000ULL) | offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_JALR (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- uint64_t pc, rs_val;
-
- /*
- * JALR rt, rs
- * GPR[rt] = PC + 8
- * PC = GPR[rs]
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_JALR(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ uint64_t pc, rs_val;
+
+ /*
+ * JALR rt, rs
+ * GPR[rt] = PC + 8
+ * PC = GPR[rs]
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
+ &success);
+ if (!success)
+ return false;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, rs_val))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ rs_val))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips64 + rt, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_JIALC (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rt;
- int64_t target, offset, pc, rt_val;
-
- /*
- * JIALC rt, offset
- * offset = sign_ext (offset)
- * PC = GPR[rt] + offset
- * RA = PC + 4
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_JIALC(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rt;
+ int64_t target, offset, pc, rt_val;
+
+ /*
+ * JIALC rt, offset
+ * offset = sign_ext (offset)
+ * PC = GPR[rt] + offset
+ * RA = PC + 4
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
- target = rt_val + offset;
+ target = rt_val + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 4))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 4))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_JIC (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rt;
- int64_t target, offset, rt_val;
-
- /*
- * JIC rt, offset
- * offset = sign_ext (offset)
- * PC = GPR[rt] + offset
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_JIC(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rt;
+ int64_t target, offset, rt_val;
+
+ /*
+ * JIC rt, offset
+ * offset = sign_ext (offset)
+ * PC = GPR[rt] + offset
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
- target = rt_val + offset;
+ target = rt_val + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_JR (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- uint64_t rs_val;
+bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ uint64_t rs_val;
- /*
- * JR rs
- * PC = GPR[rs]
- */
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ /*
+ * JR rs
+ * PC = GPR[rs]
+ */
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
+ &success);
+ if (!success)
+ return false;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, rs_val))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ rs_val))
+ return false;
- return true;
+ return true;
}
/*
@@ -1745,428 +1966,410 @@ EmulateInstructionMIPS64::Emulate_JR (llvm::MCInst& insn)
BC1F, BC1FL : Branch on FP False (L stands for branch likely)
BC1T, BC1TL : Branch on FP True (L stands for branch likely)
*/
-bool
-EmulateInstructionMIPS64::Emulate_FP_branch (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t cc, fcsr;
- int64_t pc, offset, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- /*
- * BC1F cc, offset
- * condition <- (FPConditionCode(cc) == 0)
- * if condition then
- * offset = sign_ext (offset)
- * PC = PC + offset
- */
- cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t cc, fcsr;
+ int64_t pc, offset, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ /*
+ * BC1F cc, offset
+ * condition <- (FPConditionCode(cc) == 0)
+ * if condition then
+ * offset = sign_ext (offset)
+ * PC = PC + offset
+ */
+ cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success);
- if (!success)
- return false;
+ fcsr =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success);
+ if (!success)
+ return false;
- /* fcsr[23], fcsr[25-31] are vaild condition bits */
- fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
-
- if (!strcasecmp (op_name, "BC1F") ||
- !strcasecmp (op_name, "BC1FL"))
- {
- if ((fcsr & (1 << cc)) == 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1T") ||
- !strcasecmp (op_name, "BC1TL"))
- {
- if ((fcsr & (1 << cc)) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ /* fcsr[23], fcsr[25-31] are vaild condition bits */
+ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
- Context context;
+ if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
+ if ((fcsr & (1 << cc)) == 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
+ if ((fcsr & (1 << cc)) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BC1EQZ (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t ft;
- uint64_t ft_val;
- int64_t target, pc, offset;
-
- /*
- * BC1EQZ ft, offset
- * condition <- (FPR[ft].bit0 == 0)
- * if condition then
- * offset = sign_ext (offset)
- * PC = PC + 4 + offset
- */
- ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t ft;
+ uint64_t ft_val;
+ int64_t target, pc, offset;
+
+ /*
+ * BC1EQZ ft, offset
+ * condition <- (FPR[ft].bit0 == 0)
+ * if condition then
+ * offset = sign_ext (offset)
+ * PC = PC + 4 + offset
+ */
+ ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0, &success);
- if (!success)
- return false;
+ ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
+ &success);
+ if (!success)
+ return false;
- if ((ft_val & 1) == 0)
- target = pc + 4 + offset;
- else
- target = pc + 8;
-
- Context context;
+ if ((ft_val & 1) == 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 8;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BC1NEZ (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t ft;
- uint64_t ft_val;
- int64_t target, pc, offset;
-
- /*
- * BC1NEZ ft, offset
- * condition <- (FPR[ft].bit0 != 0)
- * if condition then
- * offset = sign_ext (offset)
- * PC = PC + 4 + offset
- */
- ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t ft;
+ uint64_t ft_val;
+ int64_t target, pc, offset;
+
+ /*
+ * BC1NEZ ft, offset
+ * condition <- (FPR[ft].bit0 != 0)
+ * if condition then
+ * offset = sign_ext (offset)
+ * PC = PC + 4 + offset
+ */
+ ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0, &success);
- if (!success)
- return false;
+ ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
+ &success);
+ if (!success)
+ return false;
- if ((ft_val & 1) != 0)
- target = pc + 4 + offset;
- else
- target = pc + 8;
-
- Context context;
+ if ((ft_val & 1) != 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 8;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ return true;
}
/*
Emulate MIPS-3D Branch instructions
- BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes False/True
- BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes False/True
+ BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
+ False/True
+ BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
+ False/True
*/
-bool
-EmulateInstructionMIPS64::Emulate_3D_branch (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t cc, fcsr;
- int64_t pc, offset, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t cc, fcsr;
+ int64_t pc, offset, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success);
- if (!success)
- return false;
+ cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- /* fcsr[23], fcsr[25-31] are vaild condition bits */
- fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BC1ANY2F"))
- {
- /* if any one bit is 0 */
- if (((fcsr >> cc) & 3) != 3)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY2T"))
- {
- /* if any one bit is 1 */
- if (((fcsr >> cc) & 3) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY4F"))
- {
- /* if any one bit is 0 */
- if (((fcsr >> cc) & 0xf) != 0xf)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY4T"))
- {
- /* if any one bit is 1 */
- if (((fcsr >> cc) & 0xf) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64,
+ 0, &success);
+ if (!success)
+ return false;
- Context context;
+ /* fcsr[23], fcsr[25-31] are vaild condition bits */
+ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!strcasecmp(op_name, "BC1ANY2F")) {
+ /* if any one bit is 0 */
+ if (((fcsr >> cc) & 3) != 3)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY2T")) {
+ /* if any one bit is 1 */
+ if (((fcsr >> cc) & 3) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY4F")) {
+ /* if any one bit is 0 */
+ if (((fcsr >> cc) & 0xf) != 0xf)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY4T")) {
+ /* if any one bit is 1 */
+ if (((fcsr >> cc) & 0xf) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- return true;
+ Context context;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BNZB (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 1, true);
+bool EmulateInstructionMIPS64::Emulate_BNZB(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 1, true);
}
-bool
-EmulateInstructionMIPS64::Emulate_BNZH (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 2, true);
+bool EmulateInstructionMIPS64::Emulate_BNZH(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 2, true);
}
-bool
-EmulateInstructionMIPS64::Emulate_BNZW (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 4, true);
+bool EmulateInstructionMIPS64::Emulate_BNZW(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 4, true);
}
-bool
-EmulateInstructionMIPS64::Emulate_BNZD (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 8, true);
+bool EmulateInstructionMIPS64::Emulate_BNZD(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 8, true);
}
-bool
-EmulateInstructionMIPS64::Emulate_BZB (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 1, false);
+bool EmulateInstructionMIPS64::Emulate_BZB(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 1, false);
}
-bool
-EmulateInstructionMIPS64::Emulate_BZH (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 2, false);
+bool EmulateInstructionMIPS64::Emulate_BZH(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 2, false);
}
-bool
-EmulateInstructionMIPS64::Emulate_BZW (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 4, false);
+bool EmulateInstructionMIPS64::Emulate_BZW(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 4, false);
}
-bool
-EmulateInstructionMIPS64::Emulate_BZD (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 8, false);
+bool EmulateInstructionMIPS64::Emulate_BZD(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 8, false);
}
-bool
-EmulateInstructionMIPS64::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz)
-{
- bool success = false, branch_hit = true;
- int64_t target = 0;
- RegisterValue reg_value;
- const uint8_t *ptr = NULL;
+bool EmulateInstructionMIPS64::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
+ int element_byte_size,
+ bool bnz) {
+ bool success = false, branch_hit = true;
+ int64_t target = 0;
+ RegisterValue reg_value;
+ const uint8_t *ptr = NULL;
- uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int64_t offset = insn.getOperand(1).getImm();
+ uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ int64_t offset = insn.getOperand(1).getImm();
- int64_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+ int64_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
- ptr = (const uint8_t *)reg_value.GetBytes();
- else
- return false;
+ if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
+ ptr = (const uint8_t *)reg_value.GetBytes();
+ else
+ return false;
- for(int i = 0; i < 16 / element_byte_size; i++)
- {
- switch(element_byte_size)
- {
- case 1:
- if((*ptr == 0 && bnz) || (*ptr != 0 && !bnz) )
- branch_hit = false;
- break;
- case 2:
- if ((*(const uint16_t *)ptr == 0 && bnz) || (*(const uint16_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- case 4:
- if ((*(const uint32_t *)ptr == 0 && bnz) || (*(const uint32_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- case 8:
- if ((*(const uint64_t *)ptr == 0 && bnz) || (*(const uint64_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- }
- if(!branch_hit)
- break;
- ptr = ptr + element_byte_size;
+ for (int i = 0; i < 16 / element_byte_size; i++) {
+ switch (element_byte_size) {
+ case 1:
+ if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 2:
+ if ((*(const uint16_t *)ptr == 0 && bnz) ||
+ (*(const uint16_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 4:
+ if ((*(const uint32_t *)ptr == 0 && bnz) ||
+ (*(const uint32_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 8:
+ if ((*(const uint64_t *)ptr == 0 && bnz) ||
+ (*(const uint64_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
}
+ if (!branch_hit)
+ break;
+ ptr = ptr + element_byte_size;
+ }
- if(branch_hit)
- target = pc + offset;
- else
- target = pc + 8;
+ if (branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 8;
- Context context;
- context.type = eContextRelativeBranchImmediate;
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BNZV (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_V (insn, true);
+bool EmulateInstructionMIPS64::Emulate_BNZV(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_V(insn, true);
}
-bool
-EmulateInstructionMIPS64::Emulate_BZV (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_V (insn, false);
+bool EmulateInstructionMIPS64::Emulate_BZV(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_V(insn, false);
}
-bool
-EmulateInstructionMIPS64::Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz)
-{
- bool success = false;
- int64_t target = 0;
- llvm::APInt wr_val = llvm::APInt::getNullValue(128);
- llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
- llvm::APInt zero_value = llvm::APInt::getNullValue(128);
- RegisterValue reg_value;
-
- uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int64_t offset = insn.getOperand(1).getImm();
-
- int64_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn,
+ bool bnz) {
+ bool success = false;
+ int64_t target = 0;
+ llvm::APInt wr_val = llvm::APInt::getNullValue(128);
+ llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
+ llvm::APInt zero_value = llvm::APInt::getNullValue(128);
+ RegisterValue reg_value;
+
+ uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ int64_t offset = insn.getOperand(1).getImm();
+
+ int64_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
- wr_val = reg_value.GetAsUInt128(fail_value);
- else
- return false;
+ if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
+ wr_val = reg_value.GetAsUInt128(fail_value);
+ else
+ return false;
- if((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
- target = pc + offset;
- else
- target = pc + 8;
+ if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
+ (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
+ target = pc + offset;
+ else
+ target = pc + 8;
- Context context;
- context.type = eContextRelativeBranchImmediate;
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_LDST_Imm (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t base;
- int64_t imm, address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS64::Emulate_LDST_Imm(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t base;
+ int64_t imm, address;
+ Context bad_vaddr_context;
- uint32_t num_operands = insn.getNumOperands();
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
- imm = insn.getOperand(num_operands-1).getImm();
+ uint32_t num_operands = insn.getNumOperands();
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+ imm = insn.getOperand(num_operands - 1).getImm();
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- /* read base register */
- address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
+ &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_LDST_Reg (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t base, index;
- int64_t address, index_address;
- Context bad_vaddr_context;
-
- uint32_t num_operands = insn.getNumOperands();
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
- index = m_reg_info->getEncodingValue (insn.getOperand(num_operands-1).getReg());
-
- RegisterInfo reg_info_base, reg_info_index;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+bool EmulateInstructionMIPS64::Emulate_LDST_Reg(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t base, index;
+ int64_t address, index_address;
+ Context bad_vaddr_context;
+
+ uint32_t num_operands = insn.getNumOperands();
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+ index =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
+
+ RegisterInfo reg_info_base, reg_info_index;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + index, reg_info_index))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
+ reg_info_index))
+ return false;
- /* read base register */
- address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
+ &success);
+ if (!success)
+ return false;
- /* read index register */
- index_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
- if (!success)
- return false;
+ /* read index register */
+ index_address = ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + index, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + index_address;
+ /* destination address */
+ address = address + index_address;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- return true;
+ return true;
}
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
index 4ee690bbf184..5543615efade 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
@@ -18,232 +18,170 @@
#include "lldb/Core/Error.h"
#include "lldb/Interpreter/OptionValue.h"
-namespace llvm
-{
- class MCDisassembler;
- class MCSubtargetInfo;
- class MCRegisterInfo;
- class MCAsmInfo;
- class MCContext;
- class MCInstrInfo;
- class MCInst;
+namespace llvm {
+class MCDisassembler;
+class MCSubtargetInfo;
+class MCRegisterInfo;
+class MCAsmInfo;
+class MCContext;
+class MCInstrInfo;
+class MCInst;
} // namespace llvm
-class EmulateInstructionMIPS64 : public lldb_private::EmulateInstruction
-{
-public:
- EmulateInstructionMIPS64(const lldb_private::ArchSpec &arch);
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb_private::ConstString
- GetPluginNameStatic ();
-
- static const char *
- GetPluginDescriptionStatic ();
-
- static lldb_private::EmulateInstruction *
- CreateInstance (const lldb_private::ArchSpec &arch,
- lldb_private::InstructionType inst_type);
-
- static bool
- SupportsEmulatingInstructionsOfTypeStatic (lldb_private::InstructionType inst_type)
- {
- switch (inst_type)
- {
- case lldb_private::eInstructionTypeAny:
- case lldb_private::eInstructionTypePrologueEpilogue:
- case lldb_private::eInstructionTypePCModifying:
- return true;
-
- case lldb_private::eInstructionTypeAll:
- return false;
- }
- return false;
- }
+class EmulateInstructionMIPS64 : public lldb_private::EmulateInstruction {
+public:
+ EmulateInstructionMIPS64(const lldb_private::ArchSpec &arch);
- lldb_private::ConstString
- GetPluginName() override;
+ static void Initialize();
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ static void Terminate();
- bool
- SetTargetTriple(const lldb_private::ArchSpec &arch) override;
-
- bool
- SupportsEmulatingInstructionsOfType(lldb_private::InstructionType inst_type) override
- {
- return SupportsEmulatingInstructionsOfTypeStatic (inst_type);
- }
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
- bool
- ReadInstruction() override;
-
- bool
- EvaluateInstruction(uint32_t evaluate_options) override;
-
- bool
- TestEmulation(lldb_private::Stream *out_stream,
- lldb_private::ArchSpec &arch,
- lldb_private::OptionValueDictionary *test_data) override
- {
- return false;
+ static lldb_private::EmulateInstruction *
+ CreateInstance(const lldb_private::ArchSpec &arch,
+ lldb_private::InstructionType inst_type);
+
+ static bool SupportsEmulatingInstructionsOfTypeStatic(
+ lldb_private::InstructionType inst_type) {
+ switch (inst_type) {
+ case lldb_private::eInstructionTypeAny:
+ case lldb_private::eInstructionTypePrologueEpilogue:
+ case lldb_private::eInstructionTypePCModifying:
+ return true;
+
+ case lldb_private::eInstructionTypeAll:
+ return false;
}
+ return false;
+ }
+
+ lldb_private::ConstString GetPluginName() override;
- bool
- GetRegisterInfo(lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- lldb_private::RegisterInfo &reg_info) override;
+ uint32_t GetPluginVersion() override { return 1; }
- bool
- CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
+ bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
+
+ bool SupportsEmulatingInstructionsOfType(
+ lldb_private::InstructionType inst_type) override {
+ return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
+ }
+
+ bool ReadInstruction() override;
+
+ bool EvaluateInstruction(uint32_t evaluate_options) override;
+
+ bool TestEmulation(lldb_private::Stream *out_stream,
+ lldb_private::ArchSpec &arch,
+ lldb_private::OptionValueDictionary *test_data) override {
+ return false;
+ }
+
+ bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ lldb_private::RegisterInfo &reg_info) override;
+
+ bool
+ CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
protected:
- typedef struct
- {
- const char *op_name;
- bool (EmulateInstructionMIPS64::*callback) (llvm::MCInst& insn);
- const char *insn_name;
- } MipsOpcode;
-
- static MipsOpcode*
- GetOpcodeForInstruction (const char *op_name);
+ typedef struct {
+ const char *op_name;
+ bool (EmulateInstructionMIPS64::*callback)(llvm::MCInst &insn);
+ const char *insn_name;
+ } MipsOpcode;
+
+ static MipsOpcode *GetOpcodeForInstruction(const char *op_name);
- bool
- Emulate_DADDiu (llvm::MCInst& insn);
+ bool Emulate_DADDiu(llvm::MCInst &insn);
- bool
- Emulate_DSUBU_DADDU (llvm::MCInst& insn);
+ bool Emulate_DSUBU_DADDU(llvm::MCInst &insn);
- bool
- Emulate_LUI (llvm::MCInst& insn);
+ bool Emulate_LUI(llvm::MCInst &insn);
- bool
- Emulate_SD (llvm::MCInst& insn);
+ bool Emulate_SD(llvm::MCInst &insn);
- bool
- Emulate_LD (llvm::MCInst& insn);
+ bool Emulate_LD(llvm::MCInst &insn);
- bool
- Emulate_LDST_Imm (llvm::MCInst& insn);
+ bool Emulate_LDST_Imm(llvm::MCInst &insn);
- bool
- Emulate_LDST_Reg (llvm::MCInst& insn);
+ bool Emulate_LDST_Reg(llvm::MCInst &insn);
- bool
- Emulate_BXX_3ops (llvm::MCInst& insn);
+ bool Emulate_BXX_3ops(llvm::MCInst &insn);
- bool
- Emulate_BXX_3ops_C (llvm::MCInst& insn);
+ bool Emulate_BXX_3ops_C(llvm::MCInst &insn);
- bool
- Emulate_BXX_2ops (llvm::MCInst& insn);
+ bool Emulate_BXX_2ops(llvm::MCInst &insn);
- bool
- Emulate_BXX_2ops_C (llvm::MCInst& insn);
+ bool Emulate_BXX_2ops_C(llvm::MCInst &insn);
- bool
- Emulate_Bcond_Link_C (llvm::MCInst& insn);
+ bool Emulate_Bcond_Link_C(llvm::MCInst &insn);
- bool
- Emulate_Bcond_Link (llvm::MCInst& insn);
+ bool Emulate_Bcond_Link(llvm::MCInst &insn);
- bool
- Emulate_FP_branch (llvm::MCInst& insn);
+ bool Emulate_FP_branch(llvm::MCInst &insn);
- bool
- Emulate_3D_branch (llvm::MCInst& insn);
+ bool Emulate_3D_branch(llvm::MCInst &insn);
- bool
- Emulate_BAL (llvm::MCInst& insn);
+ bool Emulate_BAL(llvm::MCInst &insn);
- bool
- Emulate_BALC (llvm::MCInst& insn);
+ bool Emulate_BALC(llvm::MCInst &insn);
- bool
- Emulate_BC (llvm::MCInst& insn);
+ bool Emulate_BC(llvm::MCInst &insn);
- bool
- Emulate_J (llvm::MCInst& insn);
+ bool Emulate_J(llvm::MCInst &insn);
- bool
- Emulate_JAL (llvm::MCInst& insn);
+ bool Emulate_JAL(llvm::MCInst &insn);
- bool
- Emulate_JALR (llvm::MCInst& insn);
+ bool Emulate_JALR(llvm::MCInst &insn);
- bool
- Emulate_JIALC (llvm::MCInst& insn);
+ bool Emulate_JIALC(llvm::MCInst &insn);
- bool
- Emulate_JIC (llvm::MCInst& insn);
+ bool Emulate_JIC(llvm::MCInst &insn);
- bool
- Emulate_JR (llvm::MCInst& insn);
+ bool Emulate_JR(llvm::MCInst &insn);
- bool
- Emulate_BC1EQZ (llvm::MCInst& insn);
+ bool Emulate_BC1EQZ(llvm::MCInst &insn);
- bool
- Emulate_BC1NEZ (llvm::MCInst& insn);
+ bool Emulate_BC1NEZ(llvm::MCInst &insn);
- bool
- Emulate_BNZB (llvm::MCInst& insn);
+ bool Emulate_BNZB(llvm::MCInst &insn);
- bool
- Emulate_BNZH (llvm::MCInst& insn);
+ bool Emulate_BNZH(llvm::MCInst &insn);
- bool
- Emulate_BNZW (llvm::MCInst& insn);
+ bool Emulate_BNZW(llvm::MCInst &insn);
- bool
- Emulate_BNZD (llvm::MCInst& insn);
+ bool Emulate_BNZD(llvm::MCInst &insn);
- bool
- Emulate_BZB (llvm::MCInst& insn);
+ bool Emulate_BZB(llvm::MCInst &insn);
- bool
- Emulate_BZH (llvm::MCInst& insn);
+ bool Emulate_BZH(llvm::MCInst &insn);
- bool
- Emulate_BZW (llvm::MCInst& insn);
+ bool Emulate_BZW(llvm::MCInst &insn);
- bool
- Emulate_BZD (llvm::MCInst& insn);
+ bool Emulate_BZD(llvm::MCInst &insn);
- bool
- Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz);
+ bool Emulate_MSA_Branch_DF(llvm::MCInst &insn, int element_byte_size,
+ bool bnz);
- bool
- Emulate_BNZV (llvm::MCInst& insn);
+ bool Emulate_BNZV(llvm::MCInst &insn);
- bool
- Emulate_BZV (llvm::MCInst& insn);
+ bool Emulate_BZV(llvm::MCInst &insn);
- bool
- Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz);
+ bool Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz);
- bool
- nonvolatile_reg_p (uint64_t regnum);
+ bool nonvolatile_reg_p(uint64_t regnum);
- const char *
- GetRegisterName (unsigned reg_num, bool altnernate_name);
+ const char *GetRegisterName(unsigned reg_num, bool altnernate_name);
private:
- std::unique_ptr<llvm::MCDisassembler> m_disasm;
- std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
- std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
- std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
- std::unique_ptr<llvm::MCContext> m_context;
- std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
+ std::unique_ptr<llvm::MCDisassembler> m_disasm;
+ std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
+ std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
+ std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
+ std::unique_ptr<llvm::MCContext> m_context;
+ std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
};
#endif // EmulateInstructionMIPS64_h_