Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: src/arm/simulator-arm.h

Issue 2006183004: Implement ldrex and strex in ARM simulator (Closed) Base URL: http://chromium.googlesource.com/v8/v8.git@master
Patch Set: Lock on reads Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/arm/simulator-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 ARM instructions if we are not generating a native 6 // Declares a Simulator for ARM instructions if we are not generating a native
7 // ARM binary. This Simulator allows us to run and debug ARM code generation on 7 // ARM binary. This Simulator allows us to run and debug ARM 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
11 // on a ARM HW platform. 11 // on a ARM HW platform.
12 12
13 #ifndef V8_ARM_SIMULATOR_ARM_H_ 13 #ifndef V8_ARM_SIMULATOR_ARM_H_
14 #define V8_ARM_SIMULATOR_ARM_H_ 14 #define V8_ARM_SIMULATOR_ARM_H_
15 15
16 #include "src/allocation.h" 16 #include "src/allocation.h"
17 #include "src/base/lazy-instance.h"
18 #include "src/base/platform/mutex.h"
17 19
18 #if !defined(USE_SIMULATOR) 20 #if !defined(USE_SIMULATOR)
19 // Running without a simulator on a native arm platform. 21 // Running without a simulator on a native arm platform.
20 22
21 namespace v8 { 23 namespace v8 {
22 namespace internal { 24 namespace internal {
23 25
24 // When running without a simulator we call the entry directly. 26 // When running without a simulator we call the entry directly.
25 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ 27 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
26 (entry(p0, p1, p2, p3, p4)) 28 (entry(p0, p1, p2, p3, p4))
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 // Stop helper functions. 297 // Stop helper functions.
296 inline bool isStopInstruction(Instruction* instr); 298 inline bool isStopInstruction(Instruction* instr);
297 inline bool isWatchedStop(uint32_t bkpt_code); 299 inline bool isWatchedStop(uint32_t bkpt_code);
298 inline bool isEnabledStop(uint32_t bkpt_code); 300 inline bool isEnabledStop(uint32_t bkpt_code);
299 inline void EnableStop(uint32_t bkpt_code); 301 inline void EnableStop(uint32_t bkpt_code);
300 inline void DisableStop(uint32_t bkpt_code); 302 inline void DisableStop(uint32_t bkpt_code);
301 inline void IncreaseStopCounter(uint32_t bkpt_code); 303 inline void IncreaseStopCounter(uint32_t bkpt_code);
302 void PrintStopInfo(uint32_t code); 304 void PrintStopInfo(uint32_t code);
303 305
304 // Read and write memory. 306 // Read and write memory.
307 // The *Ex functions are exclusive access. The writes return the strex status:
308 // 0 if the write succeeds, and 1 if the write fails.
305 inline uint8_t ReadBU(int32_t addr); 309 inline uint8_t ReadBU(int32_t addr);
306 inline int8_t ReadB(int32_t addr); 310 inline int8_t ReadB(int32_t addr);
311 uint8_t ReadExBU(int32_t addr);
307 inline void WriteB(int32_t addr, uint8_t value); 312 inline void WriteB(int32_t addr, uint8_t value);
308 inline void WriteB(int32_t addr, int8_t value); 313 inline void WriteB(int32_t addr, int8_t value);
314 int WriteExB(int32_t addr, uint8_t value);
309 315
310 inline uint16_t ReadHU(int32_t addr, Instruction* instr); 316 inline uint16_t ReadHU(int32_t addr, Instruction* instr);
311 inline int16_t ReadH(int32_t addr, Instruction* instr); 317 inline int16_t ReadH(int32_t addr, Instruction* instr);
318 uint16_t ReadExHU(int32_t addr, Instruction* instr);
312 // Note: Overloaded on the sign of the value. 319 // Note: Overloaded on the sign of the value.
313 inline void WriteH(int32_t addr, uint16_t value, Instruction* instr); 320 inline void WriteH(int32_t addr, uint16_t value, Instruction* instr);
314 inline void WriteH(int32_t addr, int16_t value, Instruction* instr); 321 inline void WriteH(int32_t addr, int16_t value, Instruction* instr);
322 int WriteExH(int32_t addr, uint16_t value, Instruction* instr);
315 323
316 inline int ReadW(int32_t addr, Instruction* instr); 324 inline int ReadW(int32_t addr, Instruction* instr);
325 int ReadExW(int32_t addr, Instruction* instr);
317 inline void WriteW(int32_t addr, int value, Instruction* instr); 326 inline void WriteW(int32_t addr, int value, Instruction* instr);
327 int WriteExW(int32_t addr, int value, Instruction* instr);
318 328
319 int32_t* ReadDW(int32_t addr); 329 int32_t* ReadDW(int32_t addr);
320 void WriteDW(int32_t addr, int32_t value1, int32_t value2); 330 void WriteDW(int32_t addr, int32_t value1, int32_t value2);
321 331
322 // Executing is handled based on the instruction type. 332 // Executing is handled based on the instruction type.
323 // Both type 0 and type 1 rolled into one. 333 // Both type 0 and type 1 rolled into one.
324 void DecodeType01(Instruction* instr); 334 void DecodeType01(Instruction* instr);
325 void DecodeType2(Instruction* instr); 335 void DecodeType2(Instruction* instr);
326 void DecodeType3(Instruction* instr); 336 void DecodeType3(Instruction* instr);
327 void DecodeType4(Instruction* instr); 337 void DecodeType4(Instruction* instr);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 440
431 // A stop is enabled, meaning the simulator will stop when meeting the 441 // A stop is enabled, meaning the simulator will stop when meeting the
432 // instruction, if bit 31 of watched_stops_[code].count is unset. 442 // instruction, if bit 31 of watched_stops_[code].count is unset.
433 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times 443 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times
434 // the breakpoint was hit or gone through. 444 // the breakpoint was hit or gone through.
435 struct StopCountAndDesc { 445 struct StopCountAndDesc {
436 uint32_t count; 446 uint32_t count;
437 char* desc; 447 char* desc;
438 }; 448 };
439 StopCountAndDesc watched_stops_[kNumOfWatchedStops]; 449 StopCountAndDesc watched_stops_[kNumOfWatchedStops];
450
451 // Syncronization primitives. See ARM DDI 0406C.b, A2.9.
452 enum class MonitorAccess {
453 Open,
454 Exclusive,
455 };
456
457 enum class TransactionSize {
458 None = 0,
459 Byte = 1,
460 HalfWord = 2,
461 Word = 4,
462 };
463
464 // The least-significant bits of the address are ignored. The number of bits
465 // is implementation-defined, between 3 and 11. See ARM DDI 0406C.b, A3.4.3.
466 static const int32_t kExclusiveTaggedAddrMask = ~((1 << 11) - 1);
467
468 class LocalMonitor {
469 public:
470 LocalMonitor();
471
472 // These functions manage the state machine for the local monitor, but do
473 // not actually perform loads and stores. NotifyStoreExcl only returns
474 // true if the exclusive store is allowed; the global monitor will still
475 // have to be checked to see whether the memory should be updated.
476 void NotifyLoad(int32_t addr);
477 void NotifyLoadExcl(int32_t addr, TransactionSize size);
478 void NotifyStore(int32_t addr);
479 bool NotifyStoreExcl(int32_t addr, TransactionSize size);
480
481 private:
482 void Clear();
483
484 MonitorAccess access_state_;
485 int32_t tagged_addr_;
486 TransactionSize size_;
487 };
488
489 class GlobalMonitor {
490 public:
491 GlobalMonitor();
492
493 class Processor {
494 public:
495 Processor();
496
497 private:
498 friend class GlobalMonitor;
499 // These functions manage the state machine for the global monitor, but do
500 // not actually perform loads and stores.
501 void Clear_Locked();
502 void NotifyLoadExcl_Locked(int32_t addr);
503 void NotifyStore_Locked(int32_t addr, bool is_requesting_processor);
504 bool NotifyStoreExcl_Locked(int32_t addr, bool is_requesting_processor);
505
506 MonitorAccess access_state_;
507 int32_t tagged_addr_;
508 Processor* next_;
509 Processor* prev_;
510 // A strex can fail due to background cache evictions. Rather than
511 // simulating this, we'll just occasionally introduce cases where an
512 // exclusive store fails. This will happen once after every
513 // kMaxFailureCounter exclusive stores.
514 static const int kMaxFailureCounter = 5;
515 int failure_counter_;
516 };
517
518 // Exposed so it can be accessed by Simulator::{Read,Write}Ex*.
519 base::Mutex mutex;
520
521 void NotifyLoadExcl_Locked(int32_t addr, Processor* processor);
522 void NotifyStore_Locked(int32_t addr, Processor* processor);
523 bool NotifyStoreExcl_Locked(int32_t addr, Processor* processor);
524
525 // Called when the simulator is destroyed.
526 void RemoveProcessor(Processor* processor);
527
528 private:
529 bool IsProcessorInLinkedList_Locked(Processor* processor) const;
530 void PrependProcessor_Locked(Processor* processor);
531
532 Processor* head_;
533 };
534
535 LocalMonitor local_monitor_;
536 GlobalMonitor::Processor global_monitor_processor_;
537 static base::LazyInstance<GlobalMonitor>::type global_monitor_;
440 }; 538 };
441 539
442 540
443 // When running with the simulator transition into simulated execution at this 541 // When running with the simulator transition into simulated execution at this
444 // point. 542 // point.
445 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ 543 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
446 reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \ 544 reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \
447 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4)) 545 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))
448 546
449 #define CALL_GENERATED_FP_INT(isolate, entry, p0, p1) \ 547 #define CALL_GENERATED_FP_INT(isolate, entry, p0, p1) \
(...skipping 25 matching lines...) Expand all
475 static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) { 573 static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) {
476 Simulator::current(isolate)->PopAddress(); 574 Simulator::current(isolate)->PopAddress();
477 } 575 }
478 }; 576 };
479 577
480 } // namespace internal 578 } // namespace internal
481 } // namespace v8 579 } // namespace v8
482 580
483 #endif // !defined(USE_SIMULATOR) 581 #endif // !defined(USE_SIMULATOR)
484 #endif // V8_ARM_SIMULATOR_ARM_H_ 582 #endif // V8_ARM_SIMULATOR_ARM_H_
OLDNEW
« no previous file with comments | « no previous file | src/arm/simulator-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698