1 //===-- EmulationStateARM.cpp -----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "EmulationStateARM.h"
12 #include "lldb/Core/RegisterValue.h"
13 #include "lldb/Core/Scalar.h"
14 #include "lldb/Interpreter/OptionValueArray.h"
15 #include "lldb/Interpreter/OptionValueDictionary.h"
16 #include "lldb/Target/RegisterContext.h"
17 #include "lldb/Target/StackFrame.h"
19 #include "Utility/ARM_DWARF_Registers.h"
22 using namespace lldb_private;
24 EmulationStateARM::EmulationStateARM() : m_gpr(), m_vfp_regs(), m_memory() {
25 ClearPseudoRegisters();
28 EmulationStateARM::~EmulationStateARM() {}
30 bool EmulationStateARM::LoadPseudoRegistersFromFrame(StackFrame &frame) {
31 RegisterContext *reg_ctx = frame.GetRegisterContext().get();
35 for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i) {
37 reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
38 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
39 RegisterValue reg_value;
40 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
41 m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32();
46 for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i) {
48 reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
49 RegisterValue reg_value;
50 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
52 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
53 uint64_t value = reg_value.GetAsUInt64();
54 uint32_t idx = i - dwarf_d0;
56 m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
57 m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
59 m_vfp_regs.d_regs[idx - 16] = value;
67 bool EmulationStateARM::StorePseudoRegisterValue(uint32_t reg_num,
69 if (reg_num <= dwarf_cpsr)
70 m_gpr[reg_num - dwarf_r0] = (uint32_t)value;
71 else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
72 uint32_t idx = reg_num - dwarf_s0;
73 m_vfp_regs.s_regs[idx] = (uint32_t)value;
74 } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
75 uint32_t idx = reg_num - dwarf_d0;
77 m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
78 m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
80 m_vfp_regs.d_regs[idx - 16] = value;
87 uint64_t EmulationStateARM::ReadPseudoRegisterValue(uint32_t reg_num,
92 if (reg_num <= dwarf_cpsr)
93 value = m_gpr[reg_num - dwarf_r0];
94 else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
95 uint32_t idx = reg_num - dwarf_s0;
96 value = m_vfp_regs.d_regs[idx];
97 } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
98 uint32_t idx = reg_num - dwarf_d0;
100 value = (uint64_t)m_vfp_regs.s_regs[idx * 2] |
101 ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] >> 32);
103 value = m_vfp_regs.d_regs[idx - 16];
110 void EmulationStateARM::ClearPseudoRegisters() {
111 for (int i = 0; i < 17; ++i)
114 for (int i = 0; i < 32; ++i)
115 m_vfp_regs.s_regs[i] = 0;
117 for (int i = 0; i < 16; ++i)
118 m_vfp_regs.d_regs[i] = 0;
121 void EmulationStateARM::ClearPseudoMemory() { m_memory.clear(); }
123 bool EmulationStateARM::StoreToPseudoAddress(lldb::addr_t p_address,
125 m_memory[p_address] = value;
129 uint32_t EmulationStateARM::ReadFromPseudoAddress(lldb::addr_t p_address,
131 std::map<lldb::addr_t, uint32_t>::iterator pos;
132 uint32_t ret_val = 0;
135 pos = m_memory.find(p_address);
136 if (pos != m_memory.end())
137 ret_val = pos->second;
144 size_t EmulationStateARM::ReadPseudoMemory(
145 EmulateInstruction *instruction, void *baton,
146 const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
152 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
154 uint32_t value = pseudo_state->ReadFromPseudoAddress(addr, success);
158 if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
159 value = llvm::ByteSwap_32(value);
160 *((uint32_t *)dst) = value;
161 } else if (length == 8) {
162 uint32_t value1 = pseudo_state->ReadFromPseudoAddress(addr, success);
166 uint32_t value2 = pseudo_state->ReadFromPseudoAddress(addr + 4, success);
170 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
171 value1 = llvm::ByteSwap_32(value1);
172 value2 = llvm::ByteSwap_32(value2);
174 ((uint32_t *)dst)[0] = value1;
175 ((uint32_t *)dst)[1] = value2;
185 size_t EmulationStateARM::WritePseudoMemory(
186 EmulateInstruction *instruction, void *baton,
187 const EmulateInstruction::Context &context, lldb::addr_t addr,
188 const void *dst, size_t length) {
192 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
196 memcpy (&value, dst, sizeof (uint32_t));
197 if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
198 value = llvm::ByteSwap_32(value);
200 pseudo_state->StoreToPseudoAddress(addr, value);
202 } else if (length == 8) {
205 memcpy (&value1, dst, sizeof (uint32_t));
206 memcpy (&value2, (uint8_t *) dst + sizeof (uint32_t), sizeof (uint32_t));
207 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
208 value1 = llvm::ByteSwap_32(value1);
209 value2 = llvm::ByteSwap_32(value2);
212 pseudo_state->StoreToPseudoAddress(addr, value1);
213 pseudo_state->StoreToPseudoAddress(addr + 4, value2);
220 bool EmulationStateARM::ReadPseudoRegister(
221 EmulateInstruction *instruction, void *baton,
222 const lldb_private::RegisterInfo *reg_info,
223 lldb_private::RegisterValue ®_value) {
224 if (!baton || !reg_info)
228 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
229 const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
230 assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
232 pseudo_state->ReadPseudoRegisterValue(dwarf_reg_num, success);
235 success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
239 bool EmulationStateARM::WritePseudoRegister(
240 EmulateInstruction *instruction, void *baton,
241 const EmulateInstruction::Context &context,
242 const lldb_private::RegisterInfo *reg_info,
243 const lldb_private::RegisterValue ®_value) {
244 if (!baton || !reg_info)
247 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
248 const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
249 assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
250 return pseudo_state->StorePseudoRegisterValue(dwarf_reg_num,
251 reg_value.GetAsUInt64());
254 bool EmulationStateARM::CompareState(EmulationStateARM &other_state) {
257 for (int i = 0; match && i < 17; ++i) {
258 if (m_gpr[i] != other_state.m_gpr[i])
262 for (int i = 0; match && i < 32; ++i) {
263 if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
267 for (int i = 0; match && i < 16; ++i) {
268 if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
275 bool EmulationStateARM::LoadStateFromDictionary(
276 OptionValueDictionary *test_data) {
277 static ConstString memory_key("memory");
278 static ConstString registers_key("registers");
283 OptionValueSP value_sp = test_data->GetValueForKey(memory_key);
285 // Load memory, if present.
287 if (value_sp.get() != NULL) {
288 static ConstString address_key("address");
289 static ConstString data_key("data");
290 uint64_t start_address = 0;
292 OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
293 value_sp = mem_dict->GetValueForKey(address_key);
294 if (value_sp.get() == NULL)
297 start_address = value_sp->GetUInt64Value();
299 value_sp = mem_dict->GetValueForKey(data_key);
300 OptionValueArray *mem_array = value_sp->GetAsArray();
304 uint32_t num_elts = mem_array->GetSize();
305 uint32_t address = (uint32_t)start_address;
307 for (uint32_t i = 0; i < num_elts; ++i) {
308 value_sp = mem_array->GetValueAtIndex(i);
309 if (value_sp.get() == NULL)
311 uint64_t value = value_sp->GetUInt64Value();
312 StoreToPseudoAddress(address, value);
313 address = address + 4;
317 value_sp = test_data->GetValueForKey(registers_key);
318 if (value_sp.get() == NULL)
321 // Load General Registers
323 OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
326 for (int i = 0; i < 16; ++i) {
328 sstr.Printf("r%d", i);
329 ConstString reg_name(sstr.GetString());
330 value_sp = reg_dict->GetValueForKey(reg_name);
331 if (value_sp.get() == NULL)
333 uint64_t reg_value = value_sp->GetUInt64Value();
334 StorePseudoRegisterValue(dwarf_r0 + i, reg_value);
337 static ConstString cpsr_name("cpsr");
338 value_sp = reg_dict->GetValueForKey(cpsr_name);
339 if (value_sp.get() == NULL)
341 StorePseudoRegisterValue(dwarf_cpsr, value_sp->GetUInt64Value());
343 // Load s/d Registers
344 for (int i = 0; i < 32; ++i) {
346 sstr.Printf("s%d", i);
347 ConstString reg_name(sstr.GetString());
348 value_sp = reg_dict->GetValueForKey(reg_name);
349 if (value_sp.get() == NULL)
351 uint64_t reg_value = value_sp->GetUInt64Value();
352 StorePseudoRegisterValue(dwarf_s0 + i, reg_value);