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