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

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: fixes 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') | src/arm/simulator-arm.cc » ('J')
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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 // Stop helper functions. 296 // Stop helper functions.
295 inline bool isStopInstruction(Instruction* instr); 297 inline bool isStopInstruction(Instruction* instr);
296 inline bool isWatchedStop(uint32_t bkpt_code); 298 inline bool isWatchedStop(uint32_t bkpt_code);
297 inline bool isEnabledStop(uint32_t bkpt_code); 299 inline bool isEnabledStop(uint32_t bkpt_code);
298 inline void EnableStop(uint32_t bkpt_code); 300 inline void EnableStop(uint32_t bkpt_code);
299 inline void DisableStop(uint32_t bkpt_code); 301 inline void DisableStop(uint32_t bkpt_code);
300 inline void IncreaseStopCounter(uint32_t bkpt_code); 302 inline void IncreaseStopCounter(uint32_t bkpt_code);
301 void PrintStopInfo(uint32_t code); 303 void PrintStopInfo(uint32_t code);
302 304
303 // Read and write memory. 305 // Read and write memory.
306 // The *Ex functions are exclusive access. The writes return the strex status:
307 // 0 if the write succeeds, and 1 if the write fails.
304 inline uint8_t ReadBU(int32_t addr); 308 inline uint8_t ReadBU(int32_t addr);
305 inline int8_t ReadB(int32_t addr); 309 inline int8_t ReadB(int32_t addr);
310 uint8_t ReadExBU(int32_t addr);
306 inline void WriteB(int32_t addr, uint8_t value); 311 inline void WriteB(int32_t addr, uint8_t value);
307 inline void WriteB(int32_t addr, int8_t value); 312 inline void WriteB(int32_t addr, int8_t value);
313 int WriteExB(int32_t addr, uint8_t value);
308 314
309 inline uint16_t ReadHU(int32_t addr, Instruction* instr); 315 inline uint16_t ReadHU(int32_t addr, Instruction* instr);
310 inline int16_t ReadH(int32_t addr, Instruction* instr); 316 inline int16_t ReadH(int32_t addr, Instruction* instr);
317 uint16_t ReadExHU(int32_t addr, Instruction* instr);
311 // Note: Overloaded on the sign of the value. 318 // Note: Overloaded on the sign of the value.
312 inline void WriteH(int32_t addr, uint16_t value, Instruction* instr); 319 inline void WriteH(int32_t addr, uint16_t value, Instruction* instr);
313 inline void WriteH(int32_t addr, int16_t value, Instruction* instr); 320 inline void WriteH(int32_t addr, int16_t value, Instruction* instr);
321 int WriteExH(int32_t addr, uint16_t value, Instruction* instr);
314 322
315 inline int ReadW(int32_t addr, Instruction* instr); 323 inline int ReadW(int32_t addr, Instruction* instr);
324 int ReadExW(int32_t addr, Instruction* instr);
316 inline void WriteW(int32_t addr, int value, Instruction* instr); 325 inline void WriteW(int32_t addr, int value, Instruction* instr);
326 int WriteExW(int32_t addr, int value, Instruction* instr);
317 327
318 int32_t* ReadDW(int32_t addr); 328 int32_t* ReadDW(int32_t addr);
319 void WriteDW(int32_t addr, int32_t value1, int32_t value2); 329 void WriteDW(int32_t addr, int32_t value1, int32_t value2);
320 330
321 // Executing is handled based on the instruction type. 331 // Executing is handled based on the instruction type.
322 // Both type 0 and type 1 rolled into one. 332 // Both type 0 and type 1 rolled into one.
323 void DecodeType01(Instruction* instr); 333 void DecodeType01(Instruction* instr);
324 void DecodeType2(Instruction* instr); 334 void DecodeType2(Instruction* instr);
325 void DecodeType3(Instruction* instr); 335 void DecodeType3(Instruction* instr);
326 void DecodeType4(Instruction* instr); 336 void DecodeType4(Instruction* instr);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 439
430 // A stop is enabled, meaning the simulator will stop when meeting the 440 // A stop is enabled, meaning the simulator will stop when meeting the
431 // instruction, if bit 31 of watched_stops_[code].count is unset. 441 // instruction, if bit 31 of watched_stops_[code].count is unset.
432 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times 442 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times
433 // the breakpoint was hit or gone through. 443 // the breakpoint was hit or gone through.
434 struct StopCountAndDesc { 444 struct StopCountAndDesc {
435 uint32_t count; 445 uint32_t count;
436 char* desc; 446 char* desc;
437 }; 447 };
438 StopCountAndDesc watched_stops_[kNumOfWatchedStops]; 448 StopCountAndDesc watched_stops_[kNumOfWatchedStops];
449
450 // Syncronization primitives. See ARM DDI 0406C.b, A2.9.
451 enum class MonitorAccess {
452 Open,
453 Exclusive,
454 };
455
456 enum class TransactionSize {
457 None = 0,
458 Byte = 1,
459 HalfWord = 2,
460 Word = 4,
461 };
462
463 // The least-significant bits of the address are ignored. The number of bits
464 // is implementation-defined, between 3 and 11. See ARM DDI 0406C.b, A3.4.3.
465 static const int32_t kExclusiveTaggedAddrMask = ~((1 << 11) - 1);
466
467 class LocalMonitor {
468 public:
469 LocalMonitor();
470
471 // These functions manage the state machine for the local monitor, but do
472 // not actually perform loads and stores. NotifyStoreExcl only returns
473 // true if the exclusive store is allowed; the global monitor will still
474 // have to be checked to see whether the memory should be updated.
475 void NotifyLoad(int32_t addr);
476 void NotifyLoadExcl(int32_t addr, TransactionSize size);
477 void NotifyStore(int32_t addr);
478 bool NotifyStoreExcl(int32_t addr, TransactionSize size);
479
480 private:
481 MonitorAccess access_state_;
482 int32_t tagged_addr_;
483 TransactionSize size_;
484 };
485
486 class GlobalMonitor {
487 public:
488 GlobalMonitor();
489
490 class Processor {
491 public:
492 Processor();
493
494 private:
495 friend class GlobalMonitor;
496 // These functions manage the state machine for the global monitor, but do
497 // not actually perform loads and stores.
498 void NotifyLoadExcl_Locked(int32_t addr);
499 void NotifyStore_Locked(int32_t addr, bool is_requesting_processor);
500 bool NotifyStoreExcl_Locked(int32_t addr, bool is_requesting_processor);
501
502 MonitorAccess access_state_;
503 int32_t tagged_addr_;
504 Processor* next_;
505 Processor* prev_;
506 // A strex can fail due to background cache evictions. Rather than
507 // simulating this, we'll just occasionally introduce cases where an
508 // exclusive store fails. This will happen once after every
509 // kMaxFailureCounter exclusive stores.
510 static const int kMaxFailureCounter = 5;
511 int failure_counter_;
512 };
513
514 // Exposed so it can be accessed by Simulator::{Read,Write}Ex*.
515 base::Mutex mutex;
516
517 void NotifyLoadExcl_Locked(int32_t addr, Processor* processor);
518 void NotifyStore_Locked(int32_t addr, Processor* processor);
519 bool NotifyStoreExcl_Locked(int32_t addr, Processor* processor);
520
521 // Called when the simulator is destroyed.
522 void RemoveProcessor(Processor* processor);
523
524 private:
525 bool IsProcessorInLinkedList_Locked(Processor* processor) const;
526 void PrependProcessor_Locked(Processor* processor);
527
528 Processor* head_;
529 };
530
531 LocalMonitor local_monitor_;
532 GlobalMonitor::Processor global_monitor_processor_;
533 static base::LazyInstance<GlobalMonitor>::type global_monitor_;
439 }; 534 };
440 535
441 536
442 // When running with the simulator transition into simulated execution at this 537 // When running with the simulator transition into simulated execution at this
443 // point. 538 // point.
444 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ 539 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
445 reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \ 540 reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \
446 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4)) 541 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))
447 542
448 #define CALL_GENERATED_FP_INT(isolate, entry, p0, p1) \ 543 #define CALL_GENERATED_FP_INT(isolate, entry, p0, p1) \
(...skipping 25 matching lines...) Expand all
474 static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) { 569 static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) {
475 Simulator::current(isolate)->PopAddress(); 570 Simulator::current(isolate)->PopAddress();
476 } 571 }
477 }; 572 };
478 573
479 } // namespace internal 574 } // namespace internal
480 } // namespace v8 575 } // namespace v8
481 576
482 #endif // !defined(USE_SIMULATOR) 577 #endif // !defined(USE_SIMULATOR)
483 #endif // V8_ARM_SIMULATOR_ARM_H_ 578 #endif // V8_ARM_SIMULATOR_ARM_H_
OLDNEW
« no previous file with comments | « no previous file | src/arm/simulator-arm.cc » ('j') | src/arm/simulator-arm.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698