| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 | 5 |
| 6 // Declares a Simulator for MIPS instructions if we are not generating a native | 6 // Declares a Simulator for MIPS instructions if we are not generating a native |
| 7 // MIPS binary. This Simulator allows us to run and debug MIPS code generation | 7 // MIPS binary. This Simulator allows us to run and debug MIPS code generation |
| 8 // on regular desktop machines. | 8 // on regular desktop machines. |
| 9 // V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro, | 9 // V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro, |
| 10 // which will start execution in the Simulator or forwards to the real entry | 10 // which will start execution in the Simulator or forwards to the real entry |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 | 319 |
| 320 // Operations depending on endianness. | 320 // Operations depending on endianness. |
| 321 // Get Double Higher / Lower word. | 321 // Get Double Higher / Lower word. |
| 322 inline int32_t GetDoubleHIW(double* addr); | 322 inline int32_t GetDoubleHIW(double* addr); |
| 323 inline int32_t GetDoubleLOW(double* addr); | 323 inline int32_t GetDoubleLOW(double* addr); |
| 324 // Set Double Higher / Lower word. | 324 // Set Double Higher / Lower word. |
| 325 inline int32_t SetDoubleHIW(double* addr); | 325 inline int32_t SetDoubleHIW(double* addr); |
| 326 inline int32_t SetDoubleLOW(double* addr); | 326 inline int32_t SetDoubleLOW(double* addr); |
| 327 | 327 |
| 328 // functions called from DecodeTypeRegister | 328 // functions called from DecodeTypeRegister |
| 329 void DecodeTypeRegisterCOP1(Instruction* instr, const int32_t& rs_reg, | 329 void DecodeTypeRegisterCOP1(Instruction* instr, const int32_t rs_reg, |
| 330 const int64_t& rs, const uint64_t& rs_u, | 330 const int64_t rs, const uint64_t rs_u, |
| 331 const int32_t& rt_reg, const int64_t& rt, | 331 const int32_t rt_reg, const int64_t rt, |
| 332 const uint64_t& rt_u, const int32_t& rd_reg, | 332 const uint64_t rt_u, const int32_t rd_reg, |
| 333 const int32_t& fr_reg, const int32_t& fs_reg, | 333 const int32_t fr_reg, const int32_t fs_reg, |
| 334 const int32_t& ft_reg, const int32_t& fd_reg, | 334 const int32_t ft_reg, const int32_t fd_reg, |
| 335 int64_t& alu_out); | 335 int64_t& alu_out); |
| 336 | 336 |
| 337 void DecodeTypeRegisterCOP1X(Instruction* instr, const int32_t& fr_reg, | 337 void DecodeTypeRegisterCOP1X(Instruction* instr, const int32_t fr_reg, |
| 338 const int32_t& fs_reg, const int32_t& ft_reg, | 338 const int32_t fs_reg, const int32_t ft_reg, |
| 339 const int32_t& fd_reg); | 339 const int32_t fd_reg); |
| 340 | 340 |
| 341 void DecodeTypeRegisterSPECIAL( | 341 void DecodeTypeRegisterSPECIAL( |
| 342 Instruction* instr, const int64_t& rs_reg, const int64_t& rs, | 342 Instruction* instr, const int32_t rs_reg, const int64_t rs, |
| 343 const uint64_t& rs_u, const int64_t& rt_reg, const int64_t& rt, | 343 const uint64_t rs_u, const int32_t rt_reg, const int64_t rt, |
| 344 const uint64_t& rt_u, const int64_t& rd_reg, const int32_t& fr_reg, | 344 const uint64_t rt_u, const int32_t rd_reg, const int32_t fr_reg, |
| 345 const int32_t& fs_reg, const int32_t& ft_reg, const int64_t& fd_reg, | 345 const int32_t fs_reg, const int32_t ft_reg, const int32_t fd_reg, |
| 346 int64_t& i64hilo, uint64_t& u64hilo, int64_t& alu_out, bool& do_interrupt, | 346 const int64_t i64hilo, const uint64_t u64hilo, const int64_t alu_out, |
| 347 int64_t& current_pc, int64_t& next_pc, int64_t& return_addr_reg, | 347 const bool do_interrupt, const int64_t current_pc, const int64_t next_pc, |
| 348 int64_t& i128resultH, int64_t& i128resultL); | 348 const int32_t return_addr_reg, const int64_t i128resultH, |
| 349 const int64_t i128resultL); |
| 349 | 350 |
| 350 void DecodeTypeRegisterSPECIAL2(Instruction* instr, const int64_t& rd_reg, | |
| 351 int64_t& alu_out); | |
| 352 | 351 |
| 353 void DecodeTypeRegisterSPECIAL3(Instruction* instr, const int64_t& rt_reg, | 352 void DecodeTypeRegisterSPECIAL2(Instruction* instr, const int32_t rd_reg, |
| 354 const int64_t& rd_reg, int64_t& alu_out); | 353 const int64_t alu_out); |
| 355 | 354 |
| 356 void DecodeTypeRegisterSRsType(Instruction* instr, const int32_t& fs_reg, | 355 void DecodeTypeRegisterSPECIAL3(Instruction* instr, const int32_t rt_reg, |
| 357 const int32_t& ft_reg, const int32_t& fd_reg); | 356 const int32_t rd_reg, const int64_t alu_out); |
| 358 | 357 |
| 359 void DecodeTypeRegisterDRsType(Instruction* instr, const int32_t& fs_reg, | 358 void DecodeTypeRegisterSRsType(Instruction* instr, const int32_t fs_reg, |
| 360 const int32_t& ft_reg, const int32_t& fd_reg); | 359 const int32_t ft_reg, const int32_t fd_reg); |
| 361 | 360 |
| 362 void DecodeTypeRegisterWRsType(Instruction* instr, const int32_t& fs_reg, | 361 void DecodeTypeRegisterDRsType(Instruction* instr, const int32_t fs_reg, |
| 363 const int32_t& ft_reg, const int32_t& fd_reg, | 362 const int32_t ft_reg, const int32_t fd_reg); |
| 363 |
| 364 void DecodeTypeRegisterWRsType(Instruction* instr, const int32_t fs_reg, |
| 365 const int32_t ft_reg, const int32_t fd_reg, |
| 364 int64_t& alu_out); | 366 int64_t& alu_out); |
| 365 | 367 |
| 366 void DecodeTypeRegisterLRsType(Instruction* instr, const int32_t& fs_reg, | 368 void DecodeTypeRegisterLRsType(Instruction* instr, const int32_t fs_reg, |
| 367 const int32_t& fd_reg, const int32_t& ft_reg); | 369 const int32_t fd_reg, const int32_t ft_reg); |
| 368 // Executing is handled based on the instruction type. | 370 // Executing is handled based on the instruction type. |
| 369 void DecodeTypeRegister(Instruction* instr); | 371 void DecodeTypeRegister(Instruction* instr); |
| 370 | 372 |
| 371 // Helper function for DecodeTypeRegister. | 373 // Helper function for DecodeTypeRegister. |
| 372 void ConfigureTypeRegister(Instruction* instr, | 374 void ConfigureTypeRegister(Instruction* instr, int64_t* alu_out, |
| 373 int64_t* alu_out, | 375 int64_t* i64hilo, uint64_t* u64hilo, |
| 374 int64_t* i64hilo, | 376 int64_t* next_pc, int* return_addr_reg, |
| 375 uint64_t* u64hilo, | 377 bool* do_interrupt, int64_t* result128H, |
| 376 int64_t* next_pc, | |
| 377 int64_t* return_addr_reg, | |
| 378 bool* do_interrupt, | |
| 379 int64_t* result128H, | |
| 380 int64_t* result128L); | 378 int64_t* result128L); |
| 381 | 379 |
| 382 void DecodeTypeImmediate(Instruction* instr); | 380 void DecodeTypeImmediate(Instruction* instr); |
| 383 void DecodeTypeJump(Instruction* instr); | 381 void DecodeTypeJump(Instruction* instr); |
| 384 | 382 |
| 385 // Used for breakpoints and traps. | 383 // Used for breakpoints and traps. |
| 386 void SoftwareInterrupt(Instruction* instr); | 384 void SoftwareInterrupt(Instruction* instr); |
| 387 | 385 |
| 388 // Stop helper functions. | 386 // Stop helper functions. |
| 389 bool IsWatchpoint(uint64_t code); | 387 bool IsWatchpoint(uint64_t code); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 411 V8_Fatal(__FILE__, __LINE__, | 409 V8_Fatal(__FILE__, __LINE__, |
| 412 "Eror:Unexpected %i opcode in a branch delay slot.", | 410 "Eror:Unexpected %i opcode in a branch delay slot.", |
| 413 instr->OpcodeValue()); | 411 instr->OpcodeValue()); |
| 414 } | 412 } |
| 415 InstructionDecode(instr); | 413 InstructionDecode(instr); |
| 416 } | 414 } |
| 417 | 415 |
| 418 // ICache. | 416 // ICache. |
| 419 static void CheckICache(v8::internal::HashMap* i_cache, Instruction* instr); | 417 static void CheckICache(v8::internal::HashMap* i_cache, Instruction* instr); |
| 420 static void FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start, | 418 static void FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start, |
| 421 int size); | 419 size_t size); |
| 422 static CachePage* GetCachePage(v8::internal::HashMap* i_cache, void* page); | 420 static CachePage* GetCachePage(v8::internal::HashMap* i_cache, void* page); |
| 423 | 421 |
| 424 enum Exception { | 422 enum Exception { |
| 425 none, | 423 none, |
| 426 kIntegerOverflow, | 424 kIntegerOverflow, |
| 427 kIntegerUnderflow, | 425 kIntegerUnderflow, |
| 428 kDivideByZero, | 426 kDivideByZero, |
| 429 kNumExceptions | 427 kNumExceptions |
| 430 }; | 428 }; |
| 431 int16_t exceptions[kNumExceptions]; | 429 int16_t exceptions[kNumExceptions]; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 // point. | 489 // point. |
| 492 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ | 490 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ |
| 493 reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \ | 491 reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \ |
| 494 FUNCTION_ADDR(entry), 5, reinterpret_cast<int64_t*>(p0), \ | 492 FUNCTION_ADDR(entry), 5, reinterpret_cast<int64_t*>(p0), \ |
| 495 reinterpret_cast<int64_t*>(p1), reinterpret_cast<int64_t*>(p2), \ | 493 reinterpret_cast<int64_t*>(p1), reinterpret_cast<int64_t*>(p2), \ |
| 496 reinterpret_cast<int64_t*>(p3), reinterpret_cast<int64_t*>(p4))) | 494 reinterpret_cast<int64_t*>(p3), reinterpret_cast<int64_t*>(p4))) |
| 497 | 495 |
| 498 | 496 |
| 499 #ifdef MIPS_ABI_N64 | 497 #ifdef MIPS_ABI_N64 |
| 500 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ | 498 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ |
| 501 Simulator::current(Isolate::Current())->Call( \ | 499 static_cast<int>( \ |
| 502 entry, 10, p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8) | 500 Simulator::current(Isolate::Current()) \ |
| 501 ->Call(entry, 10, p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8)) |
| 503 #else // Must be O32 Abi. | 502 #else // Must be O32 Abi. |
| 504 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ | 503 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ |
| 505 Simulator::current(Isolate::Current())->Call( \ | 504 static_cast<int>( \ |
| 506 entry, 10, p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8) | 505 Simulator::current(Isolate::Current()) \ |
| 506 ->Call(entry, 10, p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8)) |
| 507 #endif // MIPS_ABI_N64 | 507 #endif // MIPS_ABI_N64 |
| 508 | 508 |
| 509 | 509 |
| 510 // The simulator has its own stack. Thus it has a different stack limit from | 510 // The simulator has its own stack. Thus it has a different stack limit from |
| 511 // the C-based native code. Setting the c_limit to indicate a very small | 511 // the C-based native code. Setting the c_limit to indicate a very small |
| 512 // stack cause stack overflow errors, since the simulator ignores the input. | 512 // stack cause stack overflow errors, since the simulator ignores the input. |
| 513 // This is unlikely to be an issue in practice, though it might cause testing | 513 // This is unlikely to be an issue in practice, though it might cause testing |
| 514 // trouble down the line. | 514 // trouble down the line. |
| 515 class SimulatorStack : public v8::internal::AllStatic { | 515 class SimulatorStack : public v8::internal::AllStatic { |
| 516 public: | 516 public: |
| 517 static inline uintptr_t JsLimitFromCLimit(Isolate* isolate, | 517 static inline uintptr_t JsLimitFromCLimit(Isolate* isolate, |
| 518 uintptr_t c_limit) { | 518 uintptr_t c_limit) { |
| 519 return Simulator::current(isolate)->StackLimit(); | 519 return Simulator::current(isolate)->StackLimit(); |
| 520 } | 520 } |
| 521 | 521 |
| 522 static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { | 522 static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { |
| 523 Simulator* sim = Simulator::current(Isolate::Current()); | 523 Simulator* sim = Simulator::current(Isolate::Current()); |
| 524 return sim->PushAddress(try_catch_address); | 524 return sim->PushAddress(try_catch_address); |
| 525 } | 525 } |
| 526 | 526 |
| 527 static inline void UnregisterCTryCatch() { | 527 static inline void UnregisterCTryCatch() { |
| 528 Simulator::current(Isolate::Current())->PopAddress(); | 528 Simulator::current(Isolate::Current())->PopAddress(); |
| 529 } | 529 } |
| 530 }; | 530 }; |
| 531 | 531 |
| 532 } } // namespace v8::internal | 532 } } // namespace v8::internal |
| 533 | 533 |
| 534 #endif // !defined(USE_SIMULATOR) | 534 #endif // !defined(USE_SIMULATOR) |
| 535 #endif // V8_MIPS_SIMULATOR_MIPS_H_ | 535 #endif // V8_MIPS_SIMULATOR_MIPS_H_ |
| OLD | NEW |