[Lldb-commits] [lldb] r126010 - /lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
Johnny Chen
johnny.chen at apple.com
Fri Feb 18 17:36:13 PST 2011
Author: johnny
Date: Fri Feb 18 19:36:13 2011
New Revision: 126010
URL: http://llvm.org/viewvc/llvm-project?rev=126010&view=rev
Log:
Make the helper method ReadCoreReg(uint32_t reg, bool *success) more generic
which now handles R0-R12, SP, LR, as well as PC. And refactored a lot of
calls to ReadRegisterUnsigned() to now funnel through ReadCoreReg(), instead.
Modified:
lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
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=126010&r1=126009&r2=126010&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Fri Feb 18 19:36:13 2011
@@ -110,6 +110,8 @@
// 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
@@ -223,7 +225,7 @@
if (ConditionPassed())
{
const uint32_t addr_byte_size = GetAddressByteSize();
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
uint32_t registers = 0;
@@ -282,7 +284,7 @@
{
dwarf_reg.num = dwarf_r0 + i;
context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
- uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
+ uint32_t reg_value = ReadCoreReg(i, &success);
if (!success)
return false;
if (!MemAWrite (context, addr, reg_value, addr_byte_size))
@@ -295,10 +297,10 @@
{
dwarf_reg.num = dwarf_pc;
context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
- const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
if (!success)
return false;
- if (!MemAWrite (context, addr, pc + 8, addr_byte_size))
+ if (!MemAWrite (context, addr, pc, addr_byte_size))
return false;
}
@@ -344,7 +346,7 @@
if (ConditionPassed())
{
const uint32_t addr_byte_size = GetAddressByteSize();
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
uint32_t registers = 0;
@@ -473,7 +475,7 @@
if (ConditionPassed())
{
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
uint32_t Rd; // the destination register
@@ -535,7 +537,7 @@
if (ConditionPassed())
{
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
uint32_t Rd; // the destination register
@@ -809,7 +811,7 @@
if (ConditionPassed())
{
- const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
if (!success)
return false;
@@ -831,8 +833,6 @@
Rt = Bits32(opcode, 10, 8);
imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
add = true;
- base = Align(pc + 4, 4);
- context.SetRegisterPlusOffset (pc_reg, 4 + imm32);
break;
case eEncodingT2:
Rt = Bits32(opcode, 15, 12);
@@ -840,17 +840,18 @@
add = BitIsSet(opcode, 23);
if (Rt == 15 && InITBlock() && !LastInITBlock())
return false;
- base = Align(pc + 4, 4);
- context.SetRegisterPlusOffset (pc_reg, 4 + imm32);
break;
default:
return false;
}
+ base = Align(pc, 4);
if (add)
address = base + imm32;
else
address = base - imm32;
+
+ context.SetRegisterPlusOffset(pc_reg, address - base);
data = MemURead(context, address, 4, 0, &success);
if (!success)
return false;
@@ -910,7 +911,7 @@
if (ConditionPassed())
{
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
uint32_t imm32; // the immediate operand
@@ -965,7 +966,7 @@
if (ConditionPassed())
{
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
uint32_t Rm; // the second operand
@@ -976,7 +977,7 @@
default:
return false;
}
- int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
+ int32_t reg_value = ReadCoreReg(Rm, &success);
if (!success)
return false;
@@ -1026,7 +1027,7 @@
{
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
if (!success)
return false;
addr_t lr; // next instruction address
@@ -1035,7 +1036,7 @@
switch (encoding) {
case eEncodingT1:
{
- lr = (pc + 4) | 1u; // return address
+ lr = pc | 1u; // return address
uint32_t S = Bit32(opcode, 26);
uint32_t imm10 = Bits32(opcode, 25, 16);
uint32_t J1 = Bit32(opcode, 13);
@@ -1045,7 +1046,7 @@
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 + 4 + imm32;
+ target = pc + imm32;
context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
if (InITBlock() && !LastInITBlock())
return false;
@@ -1053,7 +1054,7 @@
}
case eEncodingT2:
{
- lr = (pc + 4) | 1u; // return address
+ lr = pc | 1u; // return address
uint32_t S = Bit32(opcode, 26);
uint32_t imm10H = Bits32(opcode, 25, 16);
uint32_t J1 = Bit32(opcode, 13);
@@ -1063,7 +1064,7 @@
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, 4) + imm32;
+ target = Align(pc, 4) + imm32;
context.SetModeAndImmediateSigned (eModeARM, 4 + imm32);
if (InITBlock() && !LastInITBlock())
return false;
@@ -1072,13 +1073,13 @@
case eEncodingA1:
lr = pc + 4; // return address
imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
- target = Align(pc + 8, 4) + imm32;
+ target = Align(pc, 4) + imm32;
context.SetModeAndImmediateSigned (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 + 8 + imm32;
+ target = pc + imm32;
context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32);
break;
default:
@@ -1123,14 +1124,14 @@
{
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
- const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ 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
+ lr = (pc - 2) | 1u; // return address
Rm = Bits32(opcode, 6, 3);
// if m == 15 then UNPREDICTABLE;
if (Rm == 15)
@@ -1139,7 +1140,7 @@
return false;
break;
case eEncodingA1:
- lr = pc + 4; // return address
+ lr = pc - 4; // return address
Rm = Bits32(opcode, 3, 0);
// if m == 15 then UNPREDICTABLE;
if (Rm == 15)
@@ -1148,7 +1149,7 @@
default:
return false;
}
- addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
+ addr_t target = ReadCoreReg (Rm, &success);
if (!success)
return false;
Register dwarf_reg;
@@ -1198,7 +1199,7 @@
default:
return false;
}
- addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
+ addr_t target = ReadCoreReg (Rm, &success);
if (!success)
return false;
@@ -1241,7 +1242,7 @@
if (ConditionPassed())
{
- const addr_t ip = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r12, 0, &success);
+ const addr_t ip = ReadCoreReg (12, &success);
if (!success)
return false;
uint32_t imm32;
@@ -1297,7 +1298,7 @@
if (ConditionPassed())
{
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
uint32_t imm32;
@@ -1352,7 +1353,7 @@
if (ConditionPassed())
{
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
uint32_t imm32;
@@ -1408,7 +1409,7 @@
if (ConditionPassed())
{
const uint32_t addr_byte_size = GetAddressByteSize();
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
uint32_t Rt; // the source register
@@ -1432,7 +1433,7 @@
{
dwarf_reg.num = dwarf_r0 + Rt;
context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
- uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
+ uint32_t reg_value = ReadCoreReg(Rt, &success);
if (!success)
return false;
if (!MemUWrite (context, addr, reg_value, addr_byte_size))
@@ -1442,7 +1443,7 @@
{
dwarf_reg.num = dwarf_pc;
context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
- const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
if (!success)
return false;
if (!MemUWrite (context, addr, pc + 8, addr_byte_size))
@@ -1490,7 +1491,7 @@
if (ConditionPassed())
{
const uint32_t addr_byte_size = GetAddressByteSize();
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
bool single_regs;
@@ -1585,7 +1586,7 @@
if (ConditionPassed())
{
const uint32_t addr_byte_size = GetAddressByteSize();
- const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
+ const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
return false;
bool single_regs;
@@ -1669,7 +1670,7 @@
if (ConditionPassed())
{
- const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
addr_t lr; // next instruction address
if (!success)
return false;
@@ -1740,7 +1741,7 @@
{
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
if (!success)
return false;
addr_t target; // target address
@@ -1749,12 +1750,12 @@
case eEncodingT1:
// The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
- target = pc + 4 + imm32;
+ target = pc + imm32;
context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
break;
case eEncodingT2:
imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
- target = pc + 4 + imm32;
+ target = pc + imm32;
context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
break;
case eEncodingT3:
@@ -1767,7 +1768,7 @@
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 + 4 + imm32;
+ target = pc + imm32;
context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
break;
}
@@ -1782,13 +1783,13 @@
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 + 4 + imm32;
+ target = pc + imm32;
context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
break;
}
case eEncodingA1:
imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
- target = pc + 8 + imm32;
+ target = pc + imm32;
context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
break;
default:
@@ -1819,13 +1820,13 @@
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);
+ 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 = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
if (!success)
return false;
@@ -1836,7 +1837,7 @@
case eEncodingT1:
imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
nonzero = BitIsSet(opcode, 11);
- target = pc + 4 + imm32;
+ target = pc + imm32;
context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
break;
default:
@@ -1894,14 +1895,12 @@
// 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 =
- Rn == 15 ? (ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success) + 4)
- : ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
+ uint32_t base = ReadCoreReg(Rm, &success);
if (!success)
return false;
// the table index
- uint32_t index = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
+ uint32_t index = ReadCoreReg(Rm, &success);
if (!success)
return false;
@@ -1915,12 +1914,12 @@
if (!success)
return false;
- const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
if (!success)
return false;
// target address
- addr_t target = pc + 4 + offset;
+ addr_t target = pc + offset;
context.type = EmulateInstruction::eContextRelativeBranchImmediate;
context.SetModeAndImmediateSigned (eModeThumb, 4 + offset);
@@ -2108,7 +2107,7 @@
return false;
}
// Read the register value from the operand register Rn.
- uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
+ uint32_t reg_val = ReadCoreReg(Rn, &success);
if (!success)
return false;
@@ -2163,12 +2162,12 @@
return false;
}
// Read the register value from register Rn.
- uint32_t reg_val1 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
+ uint32_t reg_val1 = ReadCoreReg(Rn, &success);
if (!success)
return false;
// Read the register value from register Rm.
// The register value is not being shifted since we don't handle ARM for now.
- uint32_t reg_val2 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
+ uint32_t reg_val2 = ReadCoreReg(Rm, &success);
if (!success)
return false;
@@ -2469,7 +2468,7 @@
shift_type = SRType_RRX;
// Get the first operand.
- uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
+ uint32_t value = ReadCoreReg (Rm, &success);
if (!success)
return false;
@@ -2534,11 +2533,11 @@
}
// Get the first operand.
- uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
+ uint32_t value = ReadCoreReg (Rn, &success);
if (!success)
return false;
// Get the Rm register content.
- uint32_t val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
+ uint32_t val = ReadCoreReg (Rm, &success);
if (!success)
return false;
@@ -6100,19 +6099,52 @@
}
uint32_t
-EmulateInstructionARM::ReadCoreReg(uint32_t regnum, bool *success)
+EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
{
- uint32_t val;
- if (regnum == 15)
+ uint32_t reg_kind, reg_num;
+ switch (num)
{
- val = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, success);
- if (CurrentInstrSet() == eModeThumb)
- val += 4;
+ 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 (0 <= num && num < SP_REG)
+ {
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_r0 + num;
+ }
else
+ {
+ assert(0 && "Invalid register number");
+ *success = false;
+ return ~0u;
+ }
+ 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;
}
- else
- val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + regnum, 0, success);
return val;
}
More information about the lldb-commits
mailing list