12 #ifndef V8_MIPS64_SIMULATOR_MIPS64_H_ 13 #define V8_MIPS64_SIMULATOR_MIPS64_H_ 15 #include "src/allocation.h" 16 #include "src/mips64/constants-mips64.h" 18 #if defined(USE_SIMULATOR) 21 #include "src/assembler.h" 22 #include "src/base/hashmap.h" 23 #include "src/simulator-base.h" 33 static const int LINE_VALID = 0;
34 static const int LINE_INVALID = 1;
36 static const int kPageShift = 12;
37 static const int kPageSize = 1 << kPageShift;
38 static const int kPageMask = kPageSize - 1;
39 static const int kLineShift = 2;
40 static const int kLineLength = 1 << kLineShift;
41 static const int kLineMask = kLineLength - 1;
44 memset(&validity_map_, LINE_INVALID,
sizeof(validity_map_));
47 char* ValidityByte(
int offset) {
48 return &validity_map_[offset >> kLineShift];
51 char* CachedData(
int offset) {
52 return &data_[offset];
56 char data_[kPageSize];
57 static const int kValidityMapSize = kPageSize >> kLineShift;
58 char validity_map_[kValidityMapSize];
61 class SimInstructionBase :
public InstructionBase {
63 Type InstructionType()
const {
return type_; }
64 inline Instruction* instr()
const {
return instr_; }
65 inline int32_t operand()
const {
return operand_; }
68 SimInstructionBase() : operand_(-1), instr_(nullptr), type_(kUnsupported) {}
69 explicit SimInstructionBase(Instruction* instr) {}
76 DISALLOW_ASSIGN(SimInstructionBase);
79 class SimInstruction :
public InstructionGetters<SimInstructionBase> {
83 explicit SimInstruction(Instruction* instr) { *
this = instr; }
85 SimInstruction& operator=(Instruction* instr) {
86 operand_ = *
reinterpret_cast<const int32_t*
>(instr);
88 type_ = InstructionBase::InstructionType();
89 DCHECK(reinterpret_cast<void*>(&operand_) ==
this);
94 class Simulator :
public SimulatorBase {
96 friend class MipsDebugger;
104 a0, a1, a2, a3, a4, a5, a6, a7,
106 s0, s1, s2, s3, s4, s5, s6, s7,
125 f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11,
127 f16, f17, f18, f19, f20, f21, f22, f23, f24, f25,
128 f26, f27, f28, f29, f30, f31,
169 explicit Simulator(Isolate* isolate);
179 void set_register(
int reg,
int64_t value);
180 void set_register_word(
int reg, int32_t value);
181 void set_dw_register(
int dreg,
const int* dbl);
182 int64_t get_register(
int reg)
const;
183 double get_double_from_register_pair(
int reg);
185 void set_fpu_register(
int fpureg,
int64_t value);
186 void set_fpu_register_word(
int fpureg, int32_t value);
187 void set_fpu_register_hi_word(
int fpureg, int32_t value);
188 void set_fpu_register_float(
int fpureg,
float value);
189 void set_fpu_register_double(
int fpureg,
double value);
190 void set_fpu_register_invalid_result64(
float original,
float rounded);
191 void set_fpu_register_invalid_result(
float original,
float rounded);
192 void set_fpu_register_word_invalid_result(
float original,
float rounded);
193 void set_fpu_register_invalid_result64(
double original,
double rounded);
194 void set_fpu_register_invalid_result(
double original,
double rounded);
195 void set_fpu_register_word_invalid_result(
double original,
double rounded);
196 int64_t get_fpu_register(
int fpureg)
const;
197 int32_t get_fpu_register_word(
int fpureg)
const;
198 int32_t get_fpu_register_signed_word(
int fpureg)
const;
199 int32_t get_fpu_register_hi_word(
int fpureg)
const;
200 float get_fpu_register_float(
int fpureg)
const;
201 double get_fpu_register_double(
int fpureg)
const;
202 template <
typename T>
203 void get_msa_register(
int wreg, T* value);
204 template <
typename T>
205 void set_msa_register(
int wreg,
const T* value);
206 void set_fcsr_bit(
uint32_t cc,
bool value);
208 bool set_fcsr_round_error(
double original,
double rounded);
209 bool set_fcsr_round64_error(
double original,
double rounded);
210 bool set_fcsr_round_error(
float original,
float rounded);
211 bool set_fcsr_round64_error(
float original,
float rounded);
212 void round_according_to_fcsr(
double toRound,
double& rounded,
213 int32_t& rounded_int,
double fs);
214 void round64_according_to_fcsr(
double toRound,
double& rounded,
215 int64_t& rounded_int,
double fs);
216 void round_according_to_fcsr(
float toRound,
float& rounded,
217 int32_t& rounded_int,
float fs);
218 void round64_according_to_fcsr(
float toRound,
float& rounded,
219 int64_t& rounded_int,
float fs);
220 template <
typename T_fp,
typename T_
int>
221 void round_according_to_msacsr(T_fp toRound, T_fp& rounded,
223 void set_fcsr_rounding_mode(FPURoundingMode mode);
224 void set_msacsr_rounding_mode(FPURoundingMode mode);
225 unsigned int get_fcsr_rounding_mode();
226 unsigned int get_msacsr_rounding_mode();
231 Address get_sp()
const {
return static_cast<Address
>(get_register(sp)); }
239 template <
typename Return,
typename... Args>
240 Return Call(Address entry, Args... args) {
241 return VariadicCall<Return>(
this, &Simulator::CallImpl, entry, args...);
245 double CallFP(Address entry,
double d0,
double d1);
254 void set_last_debugger_input(
char* input);
255 char* last_debugger_input() {
return last_debugger_input_; }
258 static void SetRedirectInstruction(Instruction* instruction);
261 static bool ICacheMatch(
void* one,
void* two);
262 static void FlushICache(base::CustomMatcherHashMap* i_cache,
void* start,
267 bool has_bad_pc()
const;
270 enum special_values {
280 Unpredictable = 0xbadbeaf
283 V8_EXPORT_PRIVATE intptr_t CallImpl(Address entry,
int argument_count,
284 const intptr_t* arguments);
287 void Format(Instruction* instr,
const char* format);
302 enum MSADataFormat { MSA_VECT = 0, MSA_BYTE, MSA_HALF, MSA_WORD, MSA_DWORD };
304 int8_t b[kMSALanesByte];
305 uint8_t ub[kMSALanesByte];
306 int16_t h[kMSALanesHalf];
307 uint16_t uh[kMSALanesHalf];
308 int32_t w[kMSALanesWord];
311 uint64_t ud[kMSALanesDword];
316 inline int32_t ReadB(
int64_t addr);
317 inline void WriteB(
int64_t addr, uint8_t value);
318 inline void WriteB(
int64_t addr, int8_t value);
320 inline uint16_t ReadHU(
int64_t addr, Instruction* instr);
321 inline int16_t ReadH(
int64_t addr, Instruction* instr);
323 inline void WriteH(
int64_t addr, uint16_t value, Instruction* instr);
324 inline void WriteH(
int64_t addr, int16_t value, Instruction* instr);
327 inline int32_t ReadW(
int64_t addr, Instruction* instr, TraceType t = WORD);
328 inline void WriteW(
int64_t addr, int32_t value, Instruction* instr);
330 inline void Write2W(
int64_t addr,
int64_t value, Instruction* instr);
332 inline double ReadD(
int64_t addr, Instruction* instr);
333 inline void WriteD(
int64_t addr,
double value, Instruction* instr);
335 template <
typename T>
336 T ReadMem(
int64_t addr, Instruction* instr);
337 template <
typename T>
338 void WriteMem(
int64_t addr, T value, Instruction* instr);
341 inline void DieOrDebug();
343 void TraceRegWr(
int64_t value, TraceType t = DWORD);
344 template <
typename T>
345 void TraceMSARegWr(T* value, TraceType t);
346 template <
typename T>
347 void TraceMSARegWr(T* value);
349 void TraceMemRd(
int64_t addr,
int64_t value, TraceType t = DWORD);
350 template <
typename T>
351 void TraceMemRd(
int64_t addr, T value);
352 template <
typename T>
353 void TraceMemWr(
int64_t addr, T value);
357 inline int32_t GetDoubleHIW(
double* addr);
358 inline int32_t GetDoubleLOW(
double* addr);
360 inline int32_t SetDoubleHIW(
double* addr);
361 inline int32_t SetDoubleLOW(
double* addr);
363 SimInstruction instr_;
366 void DecodeTypeRegisterCOP1();
368 void DecodeTypeRegisterCOP1X();
370 void DecodeTypeRegisterSPECIAL();
373 void DecodeTypeRegisterSPECIAL2();
375 void DecodeTypeRegisterSPECIAL3();
377 void DecodeTypeRegisterSRsType();
379 void DecodeTypeRegisterDRsType();
381 void DecodeTypeRegisterWRsType();
383 void DecodeTypeRegisterLRsType();
385 int DecodeMsaDataFormat();
386 void DecodeTypeMsaI8();
387 void DecodeTypeMsaI5();
388 void DecodeTypeMsaI10();
389 void DecodeTypeMsaELM();
390 void DecodeTypeMsaBIT();
391 void DecodeTypeMsaMI10();
392 void DecodeTypeMsa3R();
393 void DecodeTypeMsa3RF();
394 void DecodeTypeMsaVec();
395 void DecodeTypeMsa2R();
396 void DecodeTypeMsa2RF();
397 template <
typename T>
398 T MsaI5InstrHelper(
uint32_t opcode, T ws, int32_t i5);
399 template <
typename T>
400 T MsaBitInstrHelper(
uint32_t opcode, T wd, T ws, int32_t m);
401 template <
typename T>
402 T Msa3RInstrHelper(
uint32_t opcode, T wd, T ws, T wt);
405 void DecodeTypeRegister();
407 inline int32_t rs_reg()
const {
return instr_.RsValue(); }
408 inline int64_t rs()
const {
return get_register(rs_reg()); }
409 inline uint64_t rs_u()
const {
410 return static_cast<uint64_t
>(get_register(rs_reg()));
412 inline int32_t rt_reg()
const {
return instr_.RtValue(); }
413 inline int64_t rt()
const {
return get_register(rt_reg()); }
414 inline uint64_t rt_u()
const {
415 return static_cast<uint64_t
>(get_register(rt_reg()));
417 inline int32_t rd_reg()
const {
return instr_.RdValue(); }
418 inline int32_t fr_reg()
const {
return instr_.FrValue(); }
419 inline int32_t fs_reg()
const {
return instr_.FsValue(); }
420 inline int32_t ft_reg()
const {
return instr_.FtValue(); }
421 inline int32_t fd_reg()
const {
return instr_.FdValue(); }
422 inline int32_t sa()
const {
return instr_.SaValue(); }
423 inline int32_t lsa_sa()
const {
return instr_.LsaSaValue(); }
424 inline int32_t ws_reg()
const {
return instr_.WsValue(); }
425 inline int32_t wt_reg()
const {
return instr_.WtValue(); }
426 inline int32_t wd_reg()
const {
return instr_.WdValue(); }
428 inline void SetResult(
const int32_t rd_reg,
const int64_t alu_out) {
429 set_register(rd_reg, alu_out);
433 inline void SetFPUWordResult(int32_t fd_reg, int32_t alu_out) {
434 set_fpu_register_word(fd_reg, alu_out);
435 TraceRegWr(get_fpu_register(fd_reg), WORD);
438 inline void SetFPUWordResult2(int32_t fd_reg, int32_t alu_out) {
439 set_fpu_register_word(fd_reg, alu_out);
440 TraceRegWr(get_fpu_register(fd_reg));
443 inline void SetFPUResult(int32_t fd_reg,
int64_t alu_out) {
444 set_fpu_register(fd_reg, alu_out);
445 TraceRegWr(get_fpu_register(fd_reg));
448 inline void SetFPUResult2(int32_t fd_reg,
int64_t alu_out) {
449 set_fpu_register(fd_reg, alu_out);
450 TraceRegWr(get_fpu_register(fd_reg), DOUBLE);
453 inline void SetFPUFloatResult(int32_t fd_reg,
float alu_out) {
454 set_fpu_register_float(fd_reg, alu_out);
455 TraceRegWr(get_fpu_register(fd_reg), FLOAT);
458 inline void SetFPUDoubleResult(int32_t fd_reg,
double alu_out) {
459 set_fpu_register_double(fd_reg, alu_out);
460 TraceRegWr(get_fpu_register(fd_reg), DOUBLE);
463 void DecodeTypeImmediate();
464 void DecodeTypeJump();
467 void SoftwareInterrupt();
470 void CheckForbiddenSlot(
int64_t current_pc) {
471 Instruction* instr_after_compact_branch =
472 reinterpret_cast<Instruction*
>(current_pc + kInstrSize);
473 if (instr_after_compact_branch->IsForbiddenAfterBranch()) {
475 "Error: Unexpected instruction 0x%08x immediately after a " 476 "compact branch instruction.",
477 *reinterpret_cast<uint32_t*>(instr_after_compact_branch));
482 bool IsWatchpoint(uint64_t code);
483 void PrintWatchpoint(uint64_t code);
484 void HandleStop(uint64_t code, Instruction* instr);
485 bool IsStopInstruction(Instruction* instr);
486 bool IsEnabledStop(uint64_t code);
487 void EnableStop(uint64_t code);
488 void DisableStop(uint64_t code);
489 void IncreaseStopCounter(uint64_t code);
490 void PrintStopInfo(uint64_t code);
494 void InstructionDecode(Instruction* instr);
496 void BranchDelayInstructionDecode(Instruction* instr) {
497 if (instr->InstructionBits() == nopInstr) {
503 if (instr->IsForbiddenAfterBranch()) {
504 FATAL(
"Eror:Unexpected %i opcode in a branch delay slot.",
505 instr->OpcodeValue());
507 InstructionDecode(instr);
508 SNPrintF(trace_buf_,
" ");
512 static void CheckICache(base::CustomMatcherHashMap* i_cache,
514 static void FlushOnePage(base::CustomMatcherHashMap* i_cache, intptr_t start,
516 static CachePage* GetCachePage(base::CustomMatcherHashMap* i_cache,
528 void SignalException(Exception e);
531 void GetFpArgs(
double* x,
double* y, int32_t* z);
532 void SetFpResult(
const double& result);
534 void CallInternal(Address entry);
538 int64_t registers_[kNumSimuRegisters];
542 int64_t FPUregisters_[kNumFPURegisters * 2];
555 EmbeddedVector<char, 128> trace_buf_;
558 char* last_debugger_input_;
563 Instruction* break_pc_;
567 static const uint32_t kStopDisabledBit = 1 << 31;
573 struct StopCountAndDesc {
577 StopCountAndDesc watched_stops_[kMaxStopCode + 1];
583 #endif // defined(USE_SIMULATOR) 584 #endif // V8_MIPS64_SIMULATOR_MIPS64_H_