[Lldb-commits] [lldb] r125614 - in /lldb/trunk/source/Plugins/Instruction/ARM: EmulateInstructionARM.cpp EmulateInstructionARM.h

Johnny Chen johnny.chen at apple.com
Tue Feb 15 15:22:46 PST 2011


Author: johnny
Date: Tue Feb 15 17:22:46 2011
New Revision: 125614

URL: http://llvm.org/viewvc/llvm-project?rev=125614&view=rev
Log:
A8.6.14 ASR (register)

Add EmulateASRReg() Encodings T1, T2, and A1 to the opcodes tables.

Modified:
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp?rev=125614&r1=125613&r2=125614&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Tue Feb 15 17:22:46 2011
@@ -2132,9 +2132,9 @@
 
     if (ConditionPassed())
     {
-        uint32_t Rd;   // the destination register
-        uint32_t Rm;   // the first operand register
-        uint32_t imm5; // encoding for the shift amount
+        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 (encoding) {
@@ -2203,6 +2203,103 @@
     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)
+{
+#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
+
+    bool success = false;
+    const uint32_t opcode = OpcodeAsUnsigned (&success);
+    if (!success)
+        return false;
+
+    if (ConditionPassed())
+    {
+        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 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
+        if (!success)
+            return false;
+        // Get the Rm register content.
+        uint32_t val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
+        if (!success)
+            return false;
+
+        // 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);
+
+        // The context specifies that an immediate is to be moved into Rd.
+        EmulateInstruction::Context context;
+        context.type = EmulateInstruction::eContextImmediate;
+        context.SetNoArgs ();
+     
+        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result))
+            return false;
+        if (setflags)
+        {
+            m_new_inst_cpsr = m_inst_cpsr;
+            SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N));
+            SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0);
+            SetBit32(m_new_inst_cpsr, CPSR_C, carry);
+            if (m_new_inst_cpsr != m_inst_cpsr)
+            {
+                if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
+                    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
 // can be written back to the base register.
@@ -3625,6 +3722,8 @@
         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMvnRdImm, "mvn{s} <Rd>, #<const>"},
         // asr (immediate)
         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
+        // asr (immediate)
+        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
 
         //----------------------------------------------------------------------
         // Load instructions
@@ -3753,6 +3852,9 @@
         // asr (immediate)
         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
+        // asr (register)
+        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
+        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
 
         //----------------------------------------------------------------------
         // Load instructions

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h?rev=125614&r1=125613&r2=125614&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h Tue Feb 15 17:22:46 2011
@@ -308,6 +308,10 @@
     bool
     EmulateASRImm (ARMEncoding encoding);
 
+    // A8.6.15 ASR (register)
+    bool
+    EmulateASRReg (ARMEncoding encoding);
+
     bool
     EmulateLDM (ARMEncoding encoding);
     





More information about the lldb-commits mailing list