Index: src/arm64/simulator-arm64.h |
diff --git a/src/arm64/simulator-arm64.h b/src/arm64/simulator-arm64.h |
index a9f2e09443eff0ae1b34d68aeba47de8ade5e99f..108f6f2b5473c5ac99995d34e4d141457ba186cd 100644 |
--- a/src/arm64/simulator-arm64.h |
+++ b/src/arm64/simulator-arm64.h |
@@ -312,7 +312,6 @@ class Simulator : public DecoderVisitor { |
DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstructionSize)); |
CheckBreakNext(); |
Decode(pc_); |
- LogProcessorState(); |
increment_pc(); |
CheckBreakpoints(); |
} |
@@ -348,16 +347,13 @@ class Simulator : public DecoderVisitor { |
return reg<int64_t>(code, r31mode); |
} |
- // Write 'size' bits of 'value' into an integer register. The value is |
- // zero-extended. This behaviour matches AArch64 register writes. |
- |
- // Like set_reg(), but infer the access size from the template type. |
+ // Write 'value' into an integer register. The value is zero-extended. This |
+ // behaviour matches AArch64 register writes. |
template<typename T> |
void set_reg(unsigned code, T value, |
Reg31Mode r31mode = Reg31IsZeroRegister) { |
- DCHECK(code < kNumberOfRegisters); |
- if (!IsZeroRegister(code, r31mode)) |
- registers_[code].Set(value); |
+ set_reg_no_log(code, value, r31mode); |
+ LogRegister(code, r31mode); |
} |
// Common specialized accessors for the set_reg() template. |
@@ -371,6 +367,26 @@ class Simulator : public DecoderVisitor { |
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. |
template<typename T> |
void set_lr(T value) { |
@@ -430,9 +446,13 @@ class Simulator : public DecoderVisitor { |
// This behaviour matches AArch64 register writes. |
template<typename T> |
void set_fpreg(unsigned code, T value) { |
- DCHECK((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize)); |
- DCHECK(code < kNumberOfFPRegisters); |
- fpregisters_[code].Set(value); |
+ set_fpreg_no_log(code, value); |
+ |
+ if (sizeof(value) <= kSRegSize) { |
+ LogFPRegister(code, kPrintSRegValue); |
+ } else { |
+ LogFPRegister(code, kPrintDRegValue); |
+ } |
} |
// Common specialized accessors for the set_fpreg() template. |
@@ -452,6 +472,22 @@ class Simulator : public DecoderVisitor { |
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& fpcr() { return fpcr_; } |
@@ -478,33 +514,68 @@ class Simulator : public DecoderVisitor { |
// Disassemble instruction at the given address. |
void PrintInstructionsAt(Instruction* pc, uint64_t count); |
- void PrintSystemRegisters(bool print_all = false); |
- void PrintRegisters(bool print_all_regs = false); |
- void PrintFPRegisters(bool print_all_regs = false); |
- void PrintProcessorState(); |
- void PrintWrite(uintptr_t address, uint64_t value, unsigned num_bytes); |
+ // Print all registers of the specified types. |
+ void PrintRegisters(); |
+ void PrintFPRegisters(); |
+ void PrintSystemRegisters(); |
+ |
+ // Like Print* (above), but respect log_parameters(). |
void LogSystemRegisters() { |
- if (log_parameters_ & LOG_SYS_REGS) PrintSystemRegisters(); |
+ if (log_parameters() & LOG_SYS_REGS) PrintSystemRegisters(); |
} |
void LogRegisters() { |
- if (log_parameters_ & LOG_REGS) PrintRegisters(); |
+ if (log_parameters() & LOG_REGS) PrintRegisters(); |
} |
void LogFPRegisters() { |
- if (log_parameters_ & LOG_FP_REGS) PrintFPRegisters(); |
- } |
- void LogProcessorState() { |
- LogSystemRegisters(); |
- LogRegisters(); |
- LogFPRegisters(); |
- } |
- template <typename T> |
- void LogWrite(uintptr_t address, T value) { |
- uint64_t raw_value = 0; |
- DCHECK(sizeof(value) <= sizeof(raw_value)); |
- if (log_parameters_ & LOG_WRITE) { |
- memcpy(&raw_value, &value, sizeof(value)); |
- PrintWrite(address, raw_value, sizeof(value)); |
- } |
+ if (log_parameters() & LOG_FP_REGS) PrintFPRegisters(); |
+ } |
+ |
+ // Specify relevant register sizes, for PrintFPRegister. |
+ // |
+ // 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); |
+ } |
+ void LogFPRegister(unsigned code, |
+ PrintFPRegisterSizes sizes = kPrintAllFPRegValues) { |
+ if (log_parameters() & LOG_FP_REGS) PrintFPRegister(code, sizes); |
+ } |
+ 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_; } |
@@ -595,14 +666,14 @@ class Simulator : public DecoderVisitor { |
int64_t offset, |
AddrMode addrmode); |
void LoadStorePairHelper(Instruction* instr, AddrMode addrmode); |
- uint8_t* LoadStoreAddress(unsigned addr_reg, |
- int64_t offset, |
- AddrMode addrmode); |
+ uintptr_t LoadStoreAddress(unsigned addr_reg, int64_t offset, |
+ AddrMode addrmode); |
void LoadStoreWriteBack(unsigned addr_reg, |
int64_t offset, |
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> |
T MemoryRead(A address) { |
T value; |
@@ -612,11 +683,11 @@ class Simulator : public DecoderVisitor { |
return value; |
} |
+ // Memory write helpers. |
template <typename T, typename A> |
void MemoryWrite(A address, T value) { |
STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || |
(sizeof(value) == 4) || (sizeof(value) == 8)); |
- LogWrite(reinterpret_cast<uintptr_t>(address), value); |
memcpy(reinterpret_cast<void*>(address), &value, sizeof(value)); |
} |
@@ -771,10 +842,10 @@ class Simulator : public DecoderVisitor { |
static const uint32_t kConditionFlagsMask = 0xf0000000; |
// Stack |
- byte* stack_; |
- static const intptr_t stack_protection_size_ = KB; |
- intptr_t stack_size_; |
- byte* stack_limit_; |
+ uintptr_t stack_; |
+ static const size_t stack_protection_size_ = KB; |
+ size_t stack_size_; |
+ uintptr_t stack_limit_; |
Decoder<DispatchingDecoderVisitor>* decoder_; |
Decoder<DispatchingDecoderVisitor>* disassembler_decoder_; |