Commit 12e41568 authored by Djordje.Pesic's avatar Djordje.Pesic Committed by Commit bot

MIPS: Added data tracing to simulator

Added memory and register data tracing to mips32 simulator

Review URL: https://codereview.chromium.org/1195783002

Cr-Commit-Position: refs/heads/master@{#29163}
parent ad506eeb
......@@ -1620,6 +1620,40 @@ int32_t Simulator::get_pc() const {
// executed in the simulator. Since the host is typically IA32 we will not
// get the correct MIPS-like behaviour on unaligned accesses.
void Simulator::TraceRegWr(int32_t value) {
if (::v8::internal::FLAG_trace_sim) {
SNPrintF(trace_buf_, "%08x", value);
}
}
// TODO(plind): consider making icount_ printing a flag option.
void Simulator::TraceMemRd(int32_t addr, int32_t value) {
if (::v8::internal::FLAG_trace_sim) {
SNPrintF(trace_buf_, "%08x <-- [%08x] (%d)", value, addr, icount_);
}
}
void Simulator::TraceMemWr(int32_t addr, int32_t value, TraceType t) {
if (::v8::internal::FLAG_trace_sim) {
switch (t) {
case BYTE:
SNPrintF(trace_buf_, " %02x --> [%08x]",
static_cast<int8_t>(value), addr);
break;
case HALF:
SNPrintF(trace_buf_, " %04x --> [%08x]", static_cast<int16_t>(value),
addr);
break;
case WORD:
SNPrintF(trace_buf_, "%08x --> [%08x]", value, addr);
break;
}
}
}
int Simulator::ReadW(int32_t addr, Instruction* instr) {
if (addr >=0 && addr < 0x400) {
// This has to be a NULL-dereference, drop into debugger.
......@@ -1630,6 +1664,7 @@ int Simulator::ReadW(int32_t addr, Instruction* instr) {
}
if ((addr & kPointerAlignmentMask) == 0) {
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
TraceMemRd(addr, static_cast<int32_t>(*ptr));
return *ptr;
}
PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
......@@ -1651,6 +1686,7 @@ void Simulator::WriteW(int32_t addr, int value, Instruction* instr) {
}
if ((addr & kPointerAlignmentMask) == 0) {
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
TraceMemWr(addr, value, WORD);
*ptr = value;
return;
}
......@@ -1691,6 +1727,7 @@ void Simulator::WriteD(int32_t addr, double value, Instruction* instr) {
uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) {
if ((addr & 1) == 0) {
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
TraceMemRd(addr, static_cast<int32_t>(*ptr));
return *ptr;
}
PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
......@@ -1704,6 +1741,7 @@ uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) {
int16_t Simulator::ReadH(int32_t addr, Instruction* instr) {
if ((addr & 1) == 0) {
int16_t* ptr = reinterpret_cast<int16_t*>(addr);
TraceMemRd(addr, static_cast<int32_t>(*ptr));
return *ptr;
}
PrintF("Unaligned signed halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
......@@ -1717,6 +1755,7 @@ int16_t Simulator::ReadH(int32_t addr, Instruction* instr) {
void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) {
if ((addr & 1) == 0) {
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
TraceMemWr(addr, value, HALF);
*ptr = value;
return;
}
......@@ -1730,6 +1769,7 @@ void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) {
void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) {
if ((addr & 1) == 0) {
int16_t* ptr = reinterpret_cast<int16_t*>(addr);
TraceMemWr(addr, value, HALF);
*ptr = value;
return;
}
......@@ -1742,24 +1782,28 @@ void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) {
uint32_t Simulator::ReadBU(int32_t addr) {
uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
TraceMemRd(addr, static_cast<int32_t>(*ptr));
return *ptr & 0xff;
}
int32_t Simulator::ReadB(int32_t addr) {
int8_t* ptr = reinterpret_cast<int8_t*>(addr);
TraceMemRd(addr, static_cast<int32_t>(*ptr));
return *ptr;
}
void Simulator::WriteB(int32_t addr, uint8_t value) {
uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
TraceMemWr(addr, value, BYTE);
*ptr = value;
}
void Simulator::WriteB(int32_t addr, int8_t value) {
int8_t* ptr = reinterpret_cast<int8_t*>(addr);
TraceMemWr(addr, value, BYTE);
*ptr = value;
}
......@@ -3744,7 +3788,10 @@ void Simulator::DecodeTypeRegisterSPECIAL(
break;
// Conditional moves.
case MOVN:
if (rt) set_register(rd_reg, rs);
if (rt) {
set_register(rd_reg, rs);
TraceRegWr(rs);
}
break;
case MOVCI: {
uint32_t cc = instr->FBccValue();
......@@ -3757,10 +3804,14 @@ void Simulator::DecodeTypeRegisterSPECIAL(
break;
}
case MOVZ:
if (!rt) set_register(rd_reg, rs);
if (!rt) {
set_register(rd_reg, rs);
TraceRegWr(rs);
}
break;
default: // For other special opcodes we do the default operation.
set_register(rd_reg, alu_out);
TraceRegWr(alu_out);
}
}
......@@ -3771,12 +3822,14 @@ void Simulator::DecodeTypeRegisterSPECIAL2(Instruction* instr,
switch (instr->FunctionFieldRaw()) {
case MUL:
set_register(rd_reg, alu_out);
TraceRegWr(alu_out);
// HI and LO are UNPREDICTABLE after the operation.
set_register(LO, Unpredictable);
set_register(HI, Unpredictable);
break;
default: // For other special2 opcodes we do the default operation.
set_register(rd_reg, alu_out);
TraceRegWr(alu_out);
}
}
......@@ -3789,12 +3842,15 @@ void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr,
case INS:
// Ins instr leaves result in Rt, rather than Rd.
set_register(rt_reg, alu_out);
TraceRegWr(alu_out);
break;
case EXT:
set_register(rt_reg, alu_out);
TraceRegWr(alu_out);
break;
case BSHFL:
set_register(rd_reg, alu_out);
TraceRegWr(alu_out);
break;
default:
UNREACHABLE();
......@@ -4244,6 +4300,7 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
case XORI:
case LUI:
set_register(rt_reg, alu_out);
TraceRegWr(alu_out);
break;
// ------------- Memory instructions.
case LB:
......@@ -4340,14 +4397,12 @@ void Simulator::InstructionDecode(Instruction* instr) {
CheckICache(isolate_->simulator_i_cache(), instr);
}
pc_modified_ = false;
v8::internal::EmbeddedVector<char, 256> buffer;
if (::v8::internal::FLAG_trace_sim) {
SNPrintF(trace_buf_, "%s", "");
disasm::NameConverter converter;
disasm::Disassembler dasm(converter);
// Use a reasonably large buffer.
v8::internal::EmbeddedVector<char, 256> buffer;
dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr),
buffer.start());
}
switch (instr->InstructionType()) {
......@@ -4363,6 +4418,10 @@ void Simulator::InstructionDecode(Instruction* instr) {
default:
UNSUPPORTED();
}
if (::v8::internal::FLAG_trace_sim) {
PrintF(" 0x%08x %-44s %s\n", reinterpret_cast<intptr_t>(instr),
buffer.start(), trace_buf_.start());
}
if (!pc_modified_) {
set_register(pc, reinterpret_cast<int32_t>(instr) +
Instruction::kInstrSize);
......
......@@ -268,6 +268,20 @@ class Simulator {
inline double ReadD(int32_t addr, Instruction* instr);
inline void WriteD(int32_t addr, double value, Instruction* instr);
// Helpers for data value tracing.
enum TraceType {
BYTE,
HALF,
WORD
// DWORD,
// DFLOAT - Floats may have printing issues due to paired lwc1's
};
void TraceRegWr(int32_t value);
void TraceMemWr(int32_t addr, int32_t value, TraceType t);
void TraceMemRd(int32_t addr, int32_t value);
EmbeddedVector<char, 128> trace_buf_;
// Operations depending on endianness.
// Get Double Higher / Lower word.
inline int32_t GetDoubleHIW(double* addr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment