| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 PPC instructions if we are not generating a native | 6 // Declares a Simulator for PPC instructions if we are not generating a native |
| 7 // PPC binary. This Simulator allows us to run and debug PPC code generation on | 7 // PPC binary. This Simulator allows us to run and debug PPC code generation on |
| 8 // regular desktop machines. | 8 // 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 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 inline bool isStopInstruction(Instruction* instr); | 282 inline bool isStopInstruction(Instruction* instr); |
| 283 inline bool isWatchedStop(uint32_t bkpt_code); | 283 inline bool isWatchedStop(uint32_t bkpt_code); |
| 284 inline bool isEnabledStop(uint32_t bkpt_code); | 284 inline bool isEnabledStop(uint32_t bkpt_code); |
| 285 inline void EnableStop(uint32_t bkpt_code); | 285 inline void EnableStop(uint32_t bkpt_code); |
| 286 inline void DisableStop(uint32_t bkpt_code); | 286 inline void DisableStop(uint32_t bkpt_code); |
| 287 inline void IncreaseStopCounter(uint32_t bkpt_code); | 287 inline void IncreaseStopCounter(uint32_t bkpt_code); |
| 288 void PrintStopInfo(uint32_t code); | 288 void PrintStopInfo(uint32_t code); |
| 289 | 289 |
| 290 // Read and write memory. | 290 // Read and write memory. |
| 291 inline uint8_t ReadBU(intptr_t addr); | 291 inline uint8_t ReadBU(intptr_t addr); |
| 292 inline uint8_t ReadExBU(intptr_t addr); |
| 292 inline int8_t ReadB(intptr_t addr); | 293 inline int8_t ReadB(intptr_t addr); |
| 293 inline void WriteB(intptr_t addr, uint8_t value); | 294 inline void WriteB(intptr_t addr, uint8_t value); |
| 295 inline int WriteExB(intptr_t addr, uint8_t value); |
| 294 inline void WriteB(intptr_t addr, int8_t value); | 296 inline void WriteB(intptr_t addr, int8_t value); |
| 295 | 297 |
| 296 inline uint16_t ReadHU(intptr_t addr, Instruction* instr); | 298 inline uint16_t ReadHU(intptr_t addr, Instruction* instr); |
| 299 inline uint16_t ReadExHU(intptr_t addr, Instruction* instr); |
| 297 inline int16_t ReadH(intptr_t addr, Instruction* instr); | 300 inline int16_t ReadH(intptr_t addr, Instruction* instr); |
| 298 // Note: Overloaded on the sign of the value. | 301 // Note: Overloaded on the sign of the value. |
| 299 inline void WriteH(intptr_t addr, uint16_t value, Instruction* instr); | 302 inline void WriteH(intptr_t addr, uint16_t value, Instruction* instr); |
| 303 inline int WriteExH(intptr_t addr, uint16_t value, Instruction* instr); |
| 300 inline void WriteH(intptr_t addr, int16_t value, Instruction* instr); | 304 inline void WriteH(intptr_t addr, int16_t value, Instruction* instr); |
| 301 | 305 |
| 302 inline uint32_t ReadWU(intptr_t addr, Instruction* instr); | 306 inline uint32_t ReadWU(intptr_t addr, Instruction* instr); |
| 307 inline uint32_t ReadExWU(intptr_t addr, Instruction* instr); |
| 303 inline int32_t ReadW(intptr_t addr, Instruction* instr); | 308 inline int32_t ReadW(intptr_t addr, Instruction* instr); |
| 304 inline void WriteW(intptr_t addr, uint32_t value, Instruction* instr); | 309 inline void WriteW(intptr_t addr, uint32_t value, Instruction* instr); |
| 310 inline int WriteExW(intptr_t addr, uint32_t value, Instruction* instr); |
| 305 inline void WriteW(intptr_t addr, int32_t value, Instruction* instr); | 311 inline void WriteW(intptr_t addr, int32_t value, Instruction* instr); |
| 306 | 312 |
| 307 intptr_t* ReadDW(intptr_t addr); | 313 intptr_t* ReadDW(intptr_t addr); |
| 308 void WriteDW(intptr_t addr, int64_t value); | 314 void WriteDW(intptr_t addr, int64_t value); |
| 309 | 315 |
| 310 void Trace(Instruction* instr); | 316 void Trace(Instruction* instr); |
| 311 void SetCR0(intptr_t result, bool setSO = false); | 317 void SetCR0(intptr_t result, bool setSO = false); |
| 312 void ExecuteBranchConditional(Instruction* instr, BCType type); | 318 void ExecuteBranchConditional(Instruction* instr, BCType type); |
| 313 void ExecuteExt1(Instruction* instr); | 319 void ExecuteExt1(Instruction* instr); |
| 314 bool ExecuteExt2_10bit(Instruction* instr); | 320 bool ExecuteExt2_10bit_part1(Instruction* instr); |
| 321 bool ExecuteExt2_10bit_part2(Instruction* instr); |
| 315 bool ExecuteExt2_9bit_part1(Instruction* instr); | 322 bool ExecuteExt2_9bit_part1(Instruction* instr); |
| 316 bool ExecuteExt2_9bit_part2(Instruction* instr); | 323 bool ExecuteExt2_9bit_part2(Instruction* instr); |
| 317 void ExecuteExt2_5bit(Instruction* instr); | 324 void ExecuteExt2_5bit(Instruction* instr); |
| 318 void ExecuteExt2(Instruction* instr); | 325 void ExecuteExt2(Instruction* instr); |
| 319 void ExecuteExt3(Instruction* instr); | 326 void ExecuteExt3(Instruction* instr); |
| 320 void ExecuteExt4(Instruction* instr); | 327 void ExecuteExt4(Instruction* instr); |
| 321 #if V8_TARGET_ARCH_PPC64 | 328 #if V8_TARGET_ARCH_PPC64 |
| 322 void ExecuteExt5(Instruction* instr); | 329 void ExecuteExt5(Instruction* instr); |
| 323 #endif | 330 #endif |
| 324 void ExecuteExt6(Instruction* instr); | 331 void ExecuteExt6(Instruction* instr); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 | 398 |
| 392 // A stop is enabled, meaning the simulator will stop when meeting the | 399 // A stop is enabled, meaning the simulator will stop when meeting the |
| 393 // instruction, if bit 31 of watched_stops_[code].count is unset. | 400 // instruction, if bit 31 of watched_stops_[code].count is unset. |
| 394 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times | 401 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times |
| 395 // the breakpoint was hit or gone through. | 402 // the breakpoint was hit or gone through. |
| 396 struct StopCountAndDesc { | 403 struct StopCountAndDesc { |
| 397 uint32_t count; | 404 uint32_t count; |
| 398 char* desc; | 405 char* desc; |
| 399 }; | 406 }; |
| 400 StopCountAndDesc watched_stops_[kNumOfWatchedStops]; | 407 StopCountAndDesc watched_stops_[kNumOfWatchedStops]; |
| 408 |
| 409 // Syncronization primitives. See ARM DDI 0406C.b, A2.9. |
| 410 enum class MonitorAccess { |
| 411 Open, |
| 412 Exclusive, |
| 413 }; |
| 414 |
| 415 enum class TransactionSize { |
| 416 None = 0, |
| 417 Byte = 1, |
| 418 HalfWord = 2, |
| 419 Word = 4, |
| 420 }; |
| 421 |
| 422 class LocalMonitor { |
| 423 public: |
| 424 LocalMonitor(); |
| 425 |
| 426 // These functions manage the state machine for the local monitor, but do |
| 427 // not actually perform loads and stores. NotifyStoreExcl only returns |
| 428 // true if the exclusive store is allowed; the global monitor will still |
| 429 // have to be checked to see whether the memory should be updated. |
| 430 void NotifyLoad(int32_t addr); |
| 431 void NotifyLoadExcl(int32_t addr, TransactionSize size); |
| 432 void NotifyStore(int32_t addr); |
| 433 bool NotifyStoreExcl(int32_t addr, TransactionSize size); |
| 434 |
| 435 private: |
| 436 void Clear(); |
| 437 |
| 438 MonitorAccess access_state_; |
| 439 int32_t tagged_addr_; |
| 440 TransactionSize size_; |
| 441 }; |
| 442 |
| 443 class GlobalMonitor { |
| 444 public: |
| 445 GlobalMonitor(); |
| 446 |
| 447 class Processor { |
| 448 public: |
| 449 Processor(); |
| 450 |
| 451 private: |
| 452 friend class GlobalMonitor; |
| 453 // These functions manage the state machine for the global monitor, but do |
| 454 // not actually perform loads and stores. |
| 455 void Clear_Locked(); |
| 456 void NotifyLoadExcl_Locked(int32_t addr); |
| 457 void NotifyStore_Locked(int32_t addr, bool is_requesting_processor); |
| 458 bool NotifyStoreExcl_Locked(int32_t addr, bool is_requesting_processor); |
| 459 |
| 460 MonitorAccess access_state_; |
| 461 int32_t tagged_addr_; |
| 462 Processor* next_; |
| 463 Processor* prev_; |
| 464 }; |
| 465 |
| 466 // Exposed so it can be accessed by Simulator::{Read,Write}Ex*. |
| 467 base::Mutex mutex; |
| 468 |
| 469 void NotifyLoadExcl_Locked(int32_t addr, Processor* processor); |
| 470 void NotifyStore_Locked(int32_t addr, Processor* processor); |
| 471 bool NotifyStoreExcl_Locked(int32_t addr, Processor* processor); |
| 472 |
| 473 // Called when the simulator is destroyed. |
| 474 void RemoveProcessor(Processor* processor); |
| 475 |
| 476 private: |
| 477 bool IsProcessorInLinkedList_Locked(Processor* processor) const; |
| 478 void PrependProcessor_Locked(Processor* processor); |
| 479 |
| 480 Processor* head_; |
| 481 }; |
| 482 |
| 483 LocalMonitor local_monitor_; |
| 484 GlobalMonitor::Processor global_monitor_processor_; |
| 485 static base::LazyInstance<GlobalMonitor>::type global_monitor_; |
| 401 }; | 486 }; |
| 402 | 487 |
| 403 | 488 |
| 404 // When running with the simulator transition into simulated execution at this | 489 // When running with the simulator transition into simulated execution at this |
| 405 // point. | 490 // point. |
| 406 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ | 491 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ |
| 407 reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \ | 492 reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \ |
| 408 FUNCTION_ADDR(entry), 5, (intptr_t)p0, (intptr_t)p1, (intptr_t)p2, \ | 493 FUNCTION_ADDR(entry), 5, (intptr_t)p0, (intptr_t)p1, (intptr_t)p2, \ |
| 409 (intptr_t)p3, (intptr_t)p4)) | 494 (intptr_t)p3, (intptr_t)p4)) |
| 410 | 495 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 435 | 520 |
| 436 static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) { | 521 static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) { |
| 437 Simulator::current(isolate)->PopAddress(); | 522 Simulator::current(isolate)->PopAddress(); |
| 438 } | 523 } |
| 439 }; | 524 }; |
| 440 } // namespace internal | 525 } // namespace internal |
| 441 } // namespace v8 | 526 } // namespace v8 |
| 442 | 527 |
| 443 #endif // !defined(USE_SIMULATOR) | 528 #endif // !defined(USE_SIMULATOR) |
| 444 #endif // V8_PPC_SIMULATOR_PPC_H_ | 529 #endif // V8_PPC_SIMULATOR_PPC_H_ |
| OLD | NEW |