[Lldb-commits] [lldb] r125134 - in /lldb/trunk/source/Plugins/Instruction/ARM: EmulateInstructionARM.cpp EmulateInstructionARM.h
Johnny Chen
johnny.chen at apple.com
Tue Feb 8 15:21:57 PST 2011
Author: johnny
Date: Tue Feb 8 17:21:57 2011
New Revision: 125134
URL: http://llvm.org/viewvc/llvm-project?rev=125134&view=rev
Log:
Add EmulateCB() entry to the g_thumb_opcodes table to represent "Compare and Branch
on NonZero and Compare and Branch on Zero" operations.
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=125134&r1=125133&r2=125134&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Tue Feb 8 17:21:57 2011
@@ -765,10 +765,10 @@
{
EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0};
const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
- addr_t lr; // next instruction address
- addr_t target; // target address
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:
@@ -781,7 +781,7 @@
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);
+ uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
imm32 = llvm::SignExtend32<25>(imm25);
target = pc + 4 + imm32;
context.arg1 = 4 + imm32; // signed offset
@@ -798,7 +798,7 @@
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);
+ uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
imm32 = llvm::SignExtend32<25>(imm25);
target = Align(pc + 4, 4) + imm32;
context.arg1 = 4 + imm32; // signed offset
@@ -1418,9 +1418,9 @@
{
EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0};
const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
- addr_t target; // target address
if (!success)
return false;
+ addr_t target; // target address
int32_t imm32; // PC-relative offset
switch (encoding) {
case eEncodingT1:
@@ -1444,7 +1444,7 @@
uint32_t J1 = Bits32(opcode, 13, 13);
uint32_t J2 = Bits32(opcode, 11, 11);
uint32_t imm11 = Bits32(opcode, 10, 0);
- uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) + (imm11 << 1);
+ uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
imm32 = llvm::SignExtend32<21>(imm21);
target = pc + 4 + imm32;
context.arg1 = eModeThumb; // target instruction set
@@ -1460,7 +1460,7 @@
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);
+ uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
imm32 = llvm::SignExtend32<25>(imm25);
target = pc + 4 + imm32;
context.arg1 = eModeThumb; // target instruction set
@@ -1482,6 +1482,55 @@
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.
+// CBNZ, CBZ
+bool
+EmulateInstructionARM::EmulateCB (ARMEncoding encoding)
+{
+#if 0
+ // ARM pseudo code...
+ EncodingSpecificOperations();
+ if nonzero ^ IsZero(R[n]) then
+ BranchWritePC(PC + imm32);
+#endif
+
+ bool success = false;
+ const uint32_t opcode = OpcodeAsUnsigned (&success);
+ if (!success)
+ return false;
+
+ // Read the register value from the operand register Rn.
+ uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Bits32(opcode, 2, 0), 0, &success);
+ if (!success)
+ return false;
+
+ EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0};
+ const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 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 = Bits32(opcode, 9, 9) << 6 | Bits32(opcode, 7, 3) << 1;
+ nonzero = BitIsSet(opcode, 11);
+ target = pc + 4 + imm32;
+ context.arg1 = 4 + imm32; // signed offset
+ context.arg2 = eModeThumb; // target instruction set
+ break;
+ default:
+ return false;
+ }
+ if (nonzero ^ (reg_val == 0))
+ if (!BranchWritePC(context, target))
+ return false;
+
+ return true;
+}
+
// LDM loads multiple registers from consecutive memory locations, using an
// address from a base register. Optionally the addres just above the highest of those locations
// can be written back to the base register.
@@ -1896,7 +1945,8 @@
{ 0xffff8000, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"},
{ 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
{ 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"},
-
+ // compare and branch
+ { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
//----------------------------------------------------------------------
// Load instructions
@@ -2098,8 +2148,9 @@
break;
}
if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
- return false;
- return false;
+ return false;
+
+ return true;
}
// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
@@ -2122,8 +2173,9 @@
return false; // address<1:0> == '10' => UNPREDICTABLE
if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
- return false;
- return false;
+ return false;
+
+ return true;
}
bool
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=125134&r1=125133&r2=125134&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h Tue Feb 8 17:21:57 2011
@@ -236,6 +236,10 @@
bool
EmulateB (ARMEncoding encoding);
+ // CBNZ, CBZ
+ bool
+ EmulateCB (ARMEncoding encoding);
+
bool
EmulateLDM (ARMEncoding encoding);
More information about the lldb-commits
mailing list