| Index: src/arm64/simulator-arm64.h
|
| diff --git a/src/arm64/simulator-arm64.h b/src/arm64/simulator-arm64.h
|
| index a9f2e09443eff0ae1b34d68aeba47de8ade5e99f..b748067b6593440a9f0df71512a3af92ec414c22 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_;
|
|
|