summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohnny Chen <johnny.chen@apple.com>2011-02-16 01:27:54 +0000
committerJohnny Chen <johnny.chen@apple.com>2011-02-16 01:27:54 +0000
commit22deaa5a1adf7d07060490954c4613a09702b274 (patch)
treec844d9203b9d185864f00dc7195e3d53e422caba
parent25468059e563b4c68062d931b8493b2f0c0b17ec (diff)
downloadbcm5719-llvm-22deaa5a1adf7d07060490954c4613a09702b274.tar.gz
bcm5719-llvm-22deaa5a1adf7d07060490954c4613a09702b274.zip
Add emulation methods for LSL (immediate), LSL (register), LSR (immediate), and LSR (register).
Create two helper methods EmulateShiftImm() and EmulateShiftReg() and have ASR, LSL, and LSR delegate to the helper methods which take an extra ARM_ShifterType parameter. The opcodes tables have not been updated yet to reflect these new entries. llvm-svn: 125633
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp156
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h25
-rw-r--r--lldb/source/Plugins/Process/Utility/ARMDefines.h12
-rw-r--r--lldb/source/Plugins/Process/Utility/ARMUtils.h10
4 files changed, 171 insertions, 32 deletions
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index b5c29bf73d1..c8755e82684 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -2125,6 +2125,136 @@ EmulateInstructionARM::EmulateASRImm (ARMEncoding encoding)
// APSR.V unchanged
#endif
+ return EmulateShiftImm(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
+// the condition flags based on the result.
+bool
+EmulateInstructionARM::EmulateASRReg (ARMEncoding encoding)
+{
+#if 0
+ // ARM pseudo code...
+ if ConditionPassed() then
+ EncodingSpecificOperations();
+ shift_n = UInt(R[m]<7:0>);
+ (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
+ R[d] = result;
+ if setflags then
+ APSR.N = result<31>;
+ APSR.Z = IsZeroBit(result);
+ APSR.C = carry;
+ // APSR.V unchanged
+#endif
+
+ return EmulateShiftReg(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
+// update the condition flags based on the result.
+bool
+EmulateInstructionARM::EmulateLSLImm (ARMEncoding encoding)
+{
+#if 0
+ // ARM pseudo code...
+ if ConditionPassed() then
+ EncodingSpecificOperations();
+ (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
+ 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 unchanged
+#endif
+
+ return EmulateShiftImm(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
+// flags based on the result.
+bool
+EmulateInstructionARM::EmulateLSLReg (ARMEncoding encoding)
+{
+#if 0
+ // ARM pseudo code...
+ if ConditionPassed() then
+ EncodingSpecificOperations();
+ shift_n = UInt(R[m]<7:0>);
+ (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
+ R[d] = result;
+ if setflags then
+ APSR.N = result<31>;
+ APSR.Z = IsZeroBit(result);
+ APSR.C = carry;
+ // APSR.V unchanged
+#endif
+
+ return EmulateShiftReg(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
+// update the condition flags based on the result.
+bool
+EmulateInstructionARM::EmulateLSRImm (ARMEncoding encoding)
+{
+#if 0
+ // ARM pseudo code...
+ if ConditionPassed() then
+ EncodingSpecificOperations();
+ (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
+ 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 unchanged
+#endif
+
+ return EmulateShiftImm(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
+// flags based on the result.
+bool
+EmulateInstructionARM::EmulateLSRReg (ARMEncoding encoding)
+{
+#if 0
+ // ARM pseudo code...
+ if ConditionPassed() then
+ EncodingSpecificOperations();
+ shift_n = UInt(R[m]<7:0>);
+ (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
+ R[d] = result;
+ if setflags then
+ APSR.N = result<31>;
+ APSR.Z = IsZeroBit(result);
+ APSR.C = carry;
+ // APSR.V unchanged
+#endif
+
+ return EmulateShiftReg(encoding, SRType_LSR);
+}
+
+bool
+EmulateInstructionARM::EmulateShiftImm (ARMEncoding encoding, ARM_ShifterType shift_type)
+{
+ assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
+
bool success = false;
const uint32_t opcode = OpcodeAsUnsigned (&success);
if (!success)
@@ -2168,9 +2298,9 @@ EmulateInstructionARM::EmulateASRImm (ARMEncoding encoding)
return false;
// Decode the shift amount.
- uint32_t amt = DecodeImmShift(SRType_ASR, imm5);
+ uint32_t amt = DecodeImmShift(shift_type, imm5);
- uint32_t result = Shift_C(value, SRType_ASR, amt, Bit32(m_inst_cpsr, CPSR_C), carry);
+ uint32_t result = Shift_C(value, shift_type, amt, Bit32(m_inst_cpsr, CPSR_C), carry);
// The context specifies that an immediate is to be moved into Rd.
EmulateInstruction::Context context;
@@ -2203,26 +2333,10 @@ EmulateInstructionARM::EmulateASRImm (ARMEncoding encoding)
return true;
}
-// 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 (ARMEncoding encoding)
+EmulateInstructionARM::EmulateShiftReg (ARMEncoding encoding, ARM_ShifterType shift_type)
{
-#if 0
- // ARM pseudo code...
- if ConditionPassed() then
- EncodingSpecificOperations();
- shift_n = UInt(R[m]<7:0>);
- (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
- R[d] = result;
- if setflags then
- APSR.N = result<31>;
- APSR.Z = IsZeroBit(result);
- APSR.C = carry;
- // APSR.V unchanged
-#endif
+ assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
bool success = false;
const uint32_t opcode = OpcodeAsUnsigned (&success);
@@ -2275,7 +2389,7 @@ EmulateInstructionARM::EmulateASRReg (ARMEncoding encoding)
// Get the shift amount.
uint32_t amt = Bits32(val, 7, 0);
- uint32_t result = Shift_C(value, SRType_ASR, amt, Bit32(m_inst_cpsr, CPSR_C), carry);
+ uint32_t result = Shift_C(value, shift_type, amt, Bit32(m_inst_cpsr, CPSR_C), carry);
// The context specifies that an immediate is to be moved into Rd.
EmulateInstruction::Context context;
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
index 1ff3643e6d5..d19e45aaa4d 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
@@ -12,6 +12,7 @@
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Error.h"
+#include "Plugins/Process/Utility/ARMDefines.h"
namespace lldb_private {
@@ -335,6 +336,30 @@ protected:
bool
EmulateASRReg (ARMEncoding encoding);
+ // A8.6.88 LSL (immediate)
+ bool
+ EmulateLSLImm (ARMEncoding encoding);
+
+ // A8.6.89 LSL (register)
+ bool
+ EmulateLSLReg (ARMEncoding encoding);
+
+ // A8.6.90 LSR (immediate)
+ bool
+ EmulateLSRImm (ARMEncoding encoding);
+
+ // A8.6.91 LSR (register)
+ bool
+ EmulateLSRReg (ARMEncoding encoding);
+
+ // Helper method for ASR, LSL, and LSR
+ bool
+ EmulateShiftImm (ARMEncoding encoding, ARM_ShifterType shift_type);
+
+ // Helper method for ASR, LSL, and LSR
+ bool
+ EmulateShiftReg (ARMEncoding encoding, ARM_ShifterType shift_type);
+
// A8.6.53 LDM/LDMIA/LDMFD
bool
EmulateLDM (ARMEncoding encoding);
diff --git a/lldb/source/Plugins/Process/Utility/ARMDefines.h b/lldb/source/Plugins/Process/Utility/ARMDefines.h
index 6453a3c1a4b..9a4dcc15a8e 100644
--- a/lldb/source/Plugins/Process/Utility/ARMDefines.h
+++ b/lldb/source/Plugins/Process/Utility/ARMDefines.h
@@ -10,12 +10,20 @@
#ifndef lldb_ARMDefines_h_
#define lldb_ARMDefines_h_
-#include "InstructionUtils.h"
-
// Common defintions for the ARM/Thumb Instruction Set Architecture.
namespace lldb_private {
+// ARM shifter types
+typedef enum
+{
+ SRType_LSL,
+ SRType_LSR,
+ SRType_ASR,
+ SRType_ROR,
+ SRType_RRX
+} ARM_ShifterType;
+
// ARM conditions // Meaning (integer) Meaning (floating-point) Condition flags
#define COND_EQ 0x0 // Equal Equal Z == 1
#define COND_NE 0x1 // Not equal Not equal, or unordered Z == 0
diff --git a/lldb/source/Plugins/Process/Utility/ARMUtils.h b/lldb/source/Plugins/Process/Utility/ARMUtils.h
index 523d0fc36c4..53a04bb06b7 100644
--- a/lldb/source/Plugins/Process/Utility/ARMUtils.h
+++ b/lldb/source/Plugins/Process/Utility/ARMUtils.h
@@ -10,6 +10,7 @@
#ifndef lldb_ARMUtils_h_
#define lldb_ARMUtils_h_
+#include "ARMDefines.h"
#include "InstructionUtils.h"
#include "llvm/Support/MathExtras.h" // for SignExtend64 template function
@@ -17,15 +18,6 @@
namespace lldb_private {
-typedef enum
-{
- SRType_LSL,
- SRType_LSR,
- SRType_ASR,
- SRType_ROR,
- SRType_RRX
-} ARM_ShifterType;
-
static inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5, ARM_ShifterType &shift_t)
{
switch (type) {
OpenPOWER on IntegriCloud