Commit 3dbb3c39 authored by Jacob.Bramley@arm.com's avatar Jacob.Bramley@arm.com

Reland r23732: ARM64: Fix and improve --trace-sim register trace.

- Use standard names (except that our GREY is the standard BLACK).
- Make non-bold colours explicit, otherwise the boldness can carry over
  into subsequent colour declarations.
- I've moved some colours around to make them consistent. Register value
  updates (which are very common) now stand out less than they did,
  making the less-common (and arguably more important) debug
  announcements appear brighter.
  - FP registers and values are now magenta.
  - Integer registers and values are now cyan.
  - Memory accesses are now blue.
- LOG_WRITE prints the source register for stores.
- Loads are logged with a format similar to that used for stores.
  Specifically, the memory address is printed alongside the new register
  value.
- Updates to D registers print the raw bits as well as the double value.
  Updates to S registers print the raw bits as well as the float value.
  (Previously, we printed both double and float interpretations of the
  bits, which was a bit cluttered.)

BUG=
R=svenpanne@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23802 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f3e03388
...@@ -1517,7 +1517,9 @@ int Disassembler::SubstituteLiteralField(Instruction* instr, ...@@ -1517,7 +1517,9 @@ int Disassembler::SubstituteLiteralField(Instruction* instr,
case LDR_w_lit: case LDR_w_lit:
case LDR_x_lit: case LDR_x_lit:
case LDR_s_lit: case LDR_s_lit:
case LDR_d_lit: AppendToOutput("(addr %p)", instr->LiteralAddress()); break; case LDR_d_lit:
AppendToOutput("(addr 0x%016" PRIxPTR ")", instr->LiteralAddress());
break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
......
...@@ -352,9 +352,9 @@ class Instruction { ...@@ -352,9 +352,9 @@ class Instruction {
// Patch a literal load instruction to load from 'source'. // Patch a literal load instruction to load from 'source'.
void SetImmLLiteral(Instruction* source); void SetImmLLiteral(Instruction* source);
uint8_t* LiteralAddress() { uintptr_t LiteralAddress() {
int offset = ImmLLiteral() << kLoadLiteralScaleLog2; int offset = ImmLLiteral() << kLoadLiteralScaleLog2;
return reinterpret_cast<uint8_t*>(this) + offset; return reinterpret_cast<uintptr_t>(this) + offset;
} }
enum CheckAlignment { NO_CHECK, CHECK_ALIGNMENT }; enum CheckAlignment { NO_CHECK, CHECK_ALIGNMENT };
......
This diff is collapsed.
...@@ -312,7 +312,6 @@ class Simulator : public DecoderVisitor { ...@@ -312,7 +312,6 @@ class Simulator : public DecoderVisitor {
DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstructionSize)); DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstructionSize));
CheckBreakNext(); CheckBreakNext();
Decode(pc_); Decode(pc_);
LogProcessorState();
increment_pc(); increment_pc();
CheckBreakpoints(); CheckBreakpoints();
} }
...@@ -348,16 +347,13 @@ class Simulator : public DecoderVisitor { ...@@ -348,16 +347,13 @@ class Simulator : public DecoderVisitor {
return reg<int64_t>(code, r31mode); return reg<int64_t>(code, r31mode);
} }
// Write 'size' bits of 'value' into an integer register. The value is // Write 'value' into an integer register. The value is zero-extended. This
// zero-extended. This behaviour matches AArch64 register writes. // behaviour matches AArch64 register writes.
// Like set_reg(), but infer the access size from the template type.
template<typename T> template<typename T>
void set_reg(unsigned code, T value, void set_reg(unsigned code, T value,
Reg31Mode r31mode = Reg31IsZeroRegister) { Reg31Mode r31mode = Reg31IsZeroRegister) {
DCHECK(code < kNumberOfRegisters); set_reg_no_log(code, value, r31mode);
if (!IsZeroRegister(code, r31mode)) LogRegister(code, r31mode);
registers_[code].Set(value);
} }
// Common specialized accessors for the set_reg() template. // Common specialized accessors for the set_reg() template.
...@@ -371,6 +367,26 @@ class Simulator : public DecoderVisitor { ...@@ -371,6 +367,26 @@ class Simulator : public DecoderVisitor {
set_reg(code, value, r31mode); set_reg(code, value, r31mode);
} }
// As above, but don't automatically log the register update.
template <typename T>
void set_reg_no_log(unsigned code, T value,
Reg31Mode r31mode = Reg31IsZeroRegister) {
DCHECK(code < kNumberOfRegisters);
if (!IsZeroRegister(code, r31mode)) {
registers_[code].Set(value);
}
}
void set_wreg_no_log(unsigned code, int32_t value,
Reg31Mode r31mode = Reg31IsZeroRegister) {
set_reg_no_log(code, value, r31mode);
}
void set_xreg_no_log(unsigned code, int64_t value,
Reg31Mode r31mode = Reg31IsZeroRegister) {
set_reg_no_log(code, value, r31mode);
}
// Commonly-used special cases. // Commonly-used special cases.
template<typename T> template<typename T>
void set_lr(T value) { void set_lr(T value) {
...@@ -430,9 +446,13 @@ class Simulator : public DecoderVisitor { ...@@ -430,9 +446,13 @@ class Simulator : public DecoderVisitor {
// This behaviour matches AArch64 register writes. // This behaviour matches AArch64 register writes.
template<typename T> template<typename T>
void set_fpreg(unsigned code, T value) { void set_fpreg(unsigned code, T value) {
DCHECK((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize)); set_fpreg_no_log(code, value);
DCHECK(code < kNumberOfFPRegisters);
fpregisters_[code].Set(value); if (sizeof(value) <= kSRegSize) {
LogFPRegister(code, kPrintSRegValue);
} else {
LogFPRegister(code, kPrintDRegValue);
}
} }
// Common specialized accessors for the set_fpreg() template. // Common specialized accessors for the set_fpreg() template.
...@@ -452,6 +472,22 @@ class Simulator : public DecoderVisitor { ...@@ -452,6 +472,22 @@ class Simulator : public DecoderVisitor {
set_fpreg(code, value); set_fpreg(code, value);
} }
// As above, but don't automatically log the register update.
template <typename T>
void set_fpreg_no_log(unsigned code, T value) {
DCHECK((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize));
DCHECK(code < kNumberOfFPRegisters);
fpregisters_[code].Set(value);
}
void set_sreg_no_log(unsigned code, float value) {
set_fpreg_no_log(code, value);
}
void set_dreg_no_log(unsigned code, double value) {
set_fpreg_no_log(code, value);
}
SimSystemRegister& nzcv() { return nzcv_; } SimSystemRegister& nzcv() { return nzcv_; }
SimSystemRegister& fpcr() { return fpcr_; } SimSystemRegister& fpcr() { return fpcr_; }
...@@ -478,33 +514,68 @@ class Simulator : public DecoderVisitor { ...@@ -478,33 +514,68 @@ class Simulator : public DecoderVisitor {
// Disassemble instruction at the given address. // Disassemble instruction at the given address.
void PrintInstructionsAt(Instruction* pc, uint64_t count); void PrintInstructionsAt(Instruction* pc, uint64_t count);
void PrintSystemRegisters(bool print_all = false); // Print all registers of the specified types.
void PrintRegisters(bool print_all_regs = false); void PrintRegisters();
void PrintFPRegisters(bool print_all_regs = false); void PrintFPRegisters();
void PrintProcessorState(); void PrintSystemRegisters();
void PrintWrite(uintptr_t address, uint64_t value, unsigned num_bytes);
// Like Print* (above), but respect log_parameters().
void LogSystemRegisters() { void LogSystemRegisters() {
if (log_parameters_ & LOG_SYS_REGS) PrintSystemRegisters(); if (log_parameters() & LOG_SYS_REGS) PrintSystemRegisters();
} }
void LogRegisters() { void LogRegisters() {
if (log_parameters_ & LOG_REGS) PrintRegisters(); if (log_parameters() & LOG_REGS) PrintRegisters();
} }
void LogFPRegisters() { void LogFPRegisters() {
if (log_parameters_ & LOG_FP_REGS) PrintFPRegisters(); if (log_parameters() & LOG_FP_REGS) PrintFPRegisters();
} }
void LogProcessorState() {
LogSystemRegisters(); // Specify relevant register sizes, for PrintFPRegister.
LogRegisters(); //
LogFPRegisters(); // These values are bit masks; they can be combined in case multiple views of
// a machine register are interesting.
enum PrintFPRegisterSizes {
kPrintDRegValue = 1 << kDRegSize,
kPrintSRegValue = 1 << kSRegSize,
kPrintAllFPRegValues = kPrintDRegValue | kPrintSRegValue
};
// Print individual register values (after update).
void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer);
void PrintFPRegister(unsigned code,
PrintFPRegisterSizes sizes = kPrintAllFPRegValues);
void PrintSystemRegister(SystemRegister id);
// Like Print* (above), but respect log_parameters().
void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) {
if (log_parameters() & LOG_REGS) PrintRegister(code, r31mode);
} }
template <typename T> void LogFPRegister(unsigned code,
void LogWrite(uintptr_t address, T value) { PrintFPRegisterSizes sizes = kPrintAllFPRegValues) {
uint64_t raw_value = 0; if (log_parameters() & LOG_FP_REGS) PrintFPRegister(code, sizes);
DCHECK(sizeof(value) <= sizeof(raw_value));
if (log_parameters_ & LOG_WRITE) {
memcpy(&raw_value, &value, sizeof(value));
PrintWrite(address, raw_value, sizeof(value));
} }
void LogSystemRegister(SystemRegister id) {
if (log_parameters() & LOG_SYS_REGS) PrintSystemRegister(id);
}
// Print memory accesses.
void PrintRead(uintptr_t address, size_t size, unsigned reg_code);
void PrintReadFP(uintptr_t address, size_t size, unsigned reg_code);
void PrintWrite(uintptr_t address, size_t size, unsigned reg_code);
void PrintWriteFP(uintptr_t address, size_t size, unsigned reg_code);
// Like Print* (above), but respect log_parameters().
void LogRead(uintptr_t address, size_t size, unsigned reg_code) {
if (log_parameters() & LOG_REGS) PrintRead(address, size, reg_code);
}
void LogReadFP(uintptr_t address, size_t size, unsigned reg_code) {
if (log_parameters() & LOG_FP_REGS) PrintReadFP(address, size, reg_code);
}
void LogWrite(uintptr_t address, size_t size, unsigned reg_code) {
if (log_parameters() & LOG_WRITE) PrintWrite(address, size, reg_code);
}
void LogWriteFP(uintptr_t address, size_t size, unsigned reg_code) {
if (log_parameters() & LOG_WRITE) PrintWriteFP(address, size, reg_code);
} }
int log_parameters() { return log_parameters_; } int log_parameters() { return log_parameters_; }
...@@ -595,14 +666,14 @@ class Simulator : public DecoderVisitor { ...@@ -595,14 +666,14 @@ class Simulator : public DecoderVisitor {
int64_t offset, int64_t offset,
AddrMode addrmode); AddrMode addrmode);
void LoadStorePairHelper(Instruction* instr, AddrMode addrmode); void LoadStorePairHelper(Instruction* instr, AddrMode addrmode);
uint8_t* LoadStoreAddress(unsigned addr_reg, uintptr_t LoadStoreAddress(unsigned addr_reg, int64_t offset,
int64_t offset,
AddrMode addrmode); AddrMode addrmode);
void LoadStoreWriteBack(unsigned addr_reg, void LoadStoreWriteBack(unsigned addr_reg,
int64_t offset, int64_t offset,
AddrMode addrmode); AddrMode addrmode);
void CheckMemoryAccess(uint8_t* address, uint8_t* stack); void CheckMemoryAccess(uintptr_t address, uintptr_t stack);
// Memory read helpers.
template <typename T, typename A> template <typename T, typename A>
T MemoryRead(A address) { T MemoryRead(A address) {
T value; T value;
...@@ -612,11 +683,11 @@ class Simulator : public DecoderVisitor { ...@@ -612,11 +683,11 @@ class Simulator : public DecoderVisitor {
return value; return value;
} }
// Memory write helpers.
template <typename T, typename A> template <typename T, typename A>
void MemoryWrite(A address, T value) { void MemoryWrite(A address, T value) {
STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
(sizeof(value) == 4) || (sizeof(value) == 8)); (sizeof(value) == 4) || (sizeof(value) == 8));
LogWrite(reinterpret_cast<uintptr_t>(address), value);
memcpy(reinterpret_cast<void*>(address), &value, sizeof(value)); memcpy(reinterpret_cast<void*>(address), &value, sizeof(value));
} }
...@@ -771,10 +842,10 @@ class Simulator : public DecoderVisitor { ...@@ -771,10 +842,10 @@ class Simulator : public DecoderVisitor {
static const uint32_t kConditionFlagsMask = 0xf0000000; static const uint32_t kConditionFlagsMask = 0xf0000000;
// Stack // Stack
byte* stack_; uintptr_t stack_;
static const intptr_t stack_protection_size_ = KB; static const size_t stack_protection_size_ = KB;
intptr_t stack_size_; size_t stack_size_;
byte* stack_limit_; uintptr_t stack_limit_;
Decoder<DispatchingDecoderVisitor>* decoder_; Decoder<DispatchingDecoderVisitor>* decoder_;
Decoder<DispatchingDecoderVisitor>* disassembler_decoder_; Decoder<DispatchingDecoderVisitor>* disassembler_decoder_;
......
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