Index: src/mips/simulator-mips.h |
diff --git a/src/mips/simulator-mips.h b/src/mips/simulator-mips.h |
index 5c77756394e24d55fe15af266d91dea9add0e4f9..394d8e650a88a02e2bc2ad10fb9ca44de87aa5d0 100644 |
--- a/src/mips/simulator-mips.h |
+++ b/src/mips/simulator-mips.h |
@@ -113,6 +113,39 @@ class CachePage { |
char validity_map_[kValidityMapSize]; // One byte per line. |
}; |
+class SimInstructionBase : public InstructionBase { |
+ public: |
+ Type InstructionType() const { return type_; } |
+ inline Instruction* instr() const { return instr_; } |
+ inline int32_t operand() const { return operand_; } |
+ |
+ protected: |
+ SimInstructionBase() : operand_(-1), instr_(nullptr), type_(kUnsupported) {} |
+ explicit SimInstructionBase(Instruction* instr) {} |
+ |
+ int32_t operand_; |
+ Instruction* instr_; |
+ Type type_; |
+ |
+ private: |
+ DISALLOW_ASSIGN(SimInstructionBase); |
+}; |
+ |
+class SimInstruction : public InstructionGetters<SimInstructionBase> { |
+ public: |
+ SimInstruction() {} |
+ |
+ explicit SimInstruction(Instruction* instr) { *this = instr; } |
+ |
+ SimInstruction& operator=(Instruction* instr) { |
+ operand_ = *reinterpret_cast<const int32_t*>(instr); |
+ instr_ = instr; |
+ type_ = InstructionBase::InstructionType(EXTRA); |
+ DCHECK(reinterpret_cast<void*>(&operand_) == this); |
+ return *this; |
+ } |
+}; |
+ |
class Simulator { |
public: |
friend class MipsDebugger; |
@@ -299,8 +332,10 @@ class Simulator { |
inline int32_t SetDoubleHIW(double* addr); |
inline int32_t SetDoubleLOW(double* addr); |
+ SimInstruction instr_; |
+ |
// Executing is handled based on the instruction type. |
- void DecodeTypeRegister(Instruction* instr); |
+ void DecodeTypeRegister(); |
// Functions called from DecodeTypeRegister. |
void DecodeTypeRegisterCOP1(); |
@@ -322,39 +357,34 @@ class Simulator { |
void DecodeTypeRegisterLRsType(); |
- Instruction* currentInstr_; |
- |
- inline Instruction* get_instr() const { return currentInstr_; } |
- inline void set_instr(Instruction* instr) { currentInstr_ = instr; } |
- |
- inline int32_t rs_reg() const { return currentInstr_->RsValue(); } |
+ inline int32_t rs_reg() const { return instr_.RsValue(); } |
inline int32_t rs() const { return get_register(rs_reg()); } |
inline uint32_t rs_u() const { |
return static_cast<uint32_t>(get_register(rs_reg())); |
} |
- inline int32_t rt_reg() const { return currentInstr_->RtValue(); } |
+ inline int32_t rt_reg() const { return instr_.RtValue(); } |
inline int32_t rt() const { return get_register(rt_reg()); } |
inline uint32_t rt_u() const { |
return static_cast<uint32_t>(get_register(rt_reg())); |
} |
- inline int32_t rd_reg() const { return currentInstr_->RdValue(); } |
- inline int32_t fr_reg() const { return currentInstr_->FrValue(); } |
- inline int32_t fs_reg() const { return currentInstr_->FsValue(); } |
- inline int32_t ft_reg() const { return currentInstr_->FtValue(); } |
- inline int32_t fd_reg() const { return currentInstr_->FdValue(); } |
- inline int32_t sa() const { return currentInstr_->SaValue(); } |
- inline int32_t lsa_sa() const { return currentInstr_->LsaSaValue(); } |
+ inline int32_t rd_reg() const { return instr_.RdValue(); } |
+ inline int32_t fr_reg() const { return instr_.FrValue(); } |
+ inline int32_t fs_reg() const { return instr_.FsValue(); } |
+ inline int32_t ft_reg() const { return instr_.FtValue(); } |
+ inline int32_t fd_reg() const { return instr_.FdValue(); } |
+ inline int32_t sa() const { return instr_.SaValue(); } |
+ inline int32_t lsa_sa() const { return instr_.LsaSaValue(); } |
inline void SetResult(int32_t rd_reg, int32_t alu_out) { |
set_register(rd_reg, alu_out); |
TraceRegWr(alu_out); |
} |
- void DecodeTypeImmediate(Instruction* instr); |
- void DecodeTypeJump(Instruction* instr); |
+ void DecodeTypeImmediate(); |
+ void DecodeTypeJump(); |
// Used for breakpoints and traps. |
- void SoftwareInterrupt(Instruction* instr); |
+ void SoftwareInterrupt(); |
// Compact branch guard. |
void CheckForbiddenSlot(int32_t current_pc) { |