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 |