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

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: merge master Created 4 years, 5 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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 inline bool isWatchedStop(uint32_t bkpt_code); 297 inline bool isWatchedStop(uint32_t bkpt_code);
296 inline bool isEnabledStop(uint32_t bkpt_code); 298 inline bool isEnabledStop(uint32_t bkpt_code);
297 inline void EnableStop(uint32_t bkpt_code); 299 inline void EnableStop(uint32_t bkpt_code);
298 inline void DisableStop(uint32_t bkpt_code); 300 inline void DisableStop(uint32_t bkpt_code);
299 inline void IncreaseStopCounter(uint32_t bkpt_code); 301 inline void IncreaseStopCounter(uint32_t bkpt_code);
300 void PrintStopInfo(uint32_t code); 302 void PrintStopInfo(uint32_t code);
301 303
302 // Read and write memory. 304 // Read and write memory.
303 inline uint8_t ReadBU(int32_t addr); 305 inline uint8_t ReadBU(int32_t addr);
304 inline int8_t ReadB(int32_t addr); 306 inline int8_t ReadB(int32_t addr);
305 inline void WriteB(int32_t addr, uint8_t value); 307 inline void WriteB_Internal(int32_t addr, uint8_t value);
306 inline void WriteB(int32_t addr, int8_t value); 308 inline void WriteB_Internal(int32_t addr, int8_t value);
307 309
308 inline uint16_t ReadHU(int32_t addr, Instruction* instr); 310 inline uint16_t ReadHU(int32_t addr, Instruction* instr);
309 inline int16_t ReadH(int32_t addr, Instruction* instr); 311 inline int16_t ReadH(int32_t addr, Instruction* instr);
310 // Note: Overloaded on the sign of the value. 312 // Note: Overloaded on the sign of the value.
311 inline void WriteH(int32_t addr, uint16_t value, Instruction* instr); 313 inline void WriteH_Internal(int32_t addr, uint16_t value, Instruction* instr);
312 inline void WriteH(int32_t addr, int16_t value, Instruction* instr); 314 inline void WriteH_Internal(int32_t addr, int16_t value, Instruction* instr);
313 315
314 inline int ReadW(int32_t addr, Instruction* instr); 316 inline int ReadW(int32_t addr, Instruction* instr);
315 inline void WriteW(int32_t addr, int value, Instruction* instr); 317 inline void WriteW_Internal(int32_t addr, int value, Instruction* instr);
316 318
317 int32_t* ReadDW(int32_t addr); 319 int32_t* ReadDW(int32_t addr);
318 void WriteDW(int32_t addr, int32_t value1, int32_t value2); 320 void WriteDW(int32_t addr, int32_t value1, int32_t value2);
319 321
320 // Executing is handled based on the instruction type. 322 // Executing is handled based on the instruction type.
321 // Both type 0 and type 1 rolled into one. 323 // Both type 0 and type 1 rolled into one.
322 void DecodeType01(Instruction* instr); 324 void DecodeType01(Instruction* instr);
323 void DecodeType2(Instruction* instr); 325 void DecodeType2(Instruction* instr);
324 void DecodeType3(Instruction* instr); 326 void DecodeType3(Instruction* instr);
325 void DecodeType4(Instruction* instr); 327 void DecodeType4(Instruction* instr);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 422
421 // A stop is enabled, meaning the simulator will stop when meeting the 423 // A stop is enabled, meaning the simulator will stop when meeting the
422 // instruction, if bit 31 of watched_stops_[code].count is unset. 424 // instruction, if bit 31 of watched_stops_[code].count is unset.
423 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times 425 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times
424 // the breakpoint was hit or gone through. 426 // the breakpoint was hit or gone through.
425 struct StopCountAndDesc { 427 struct StopCountAndDesc {
426 uint32_t count; 428 uint32_t count;
427 char* desc; 429 char* desc;
428 }; 430 };
429 StopCountAndDesc watched_stops_[kNumOfWatchedStops]; 431 StopCountAndDesc watched_stops_[kNumOfWatchedStops];
432
433 // Syncronization primitives. See ARM DDI 0406C.b, A2.9.
434 enum class MonitorAccess {
435 Open,
436 Exclusive,
437 };
438
439 enum class TransactionSize {
440 None = 0,
441 Byte = 1,
442 HalfWord = 2,
443 Word = 4,
444 };
445
446 // The least-significant bits of the address are ignored. The number of bits
447 // is implementation-defined, between 3 and 11. See ARM DDI 0406C.b, A3.4.3.
448 static const int32_t kTaggedAddrMask = ~7;
jbramley 2016/07/20 16:09:24 Picking (2^)11 would probably be more demanding on
449
450 // Writes can affect the local and global monitors.
451 void WriteB(int32_t addr, uint8_t value);
452 void WriteB(int32_t addr, int8_t value);
jbramley 2016/07/20 16:09:24 There's no practical difference between storing si
binji 2016/07/29 21:46:30 I agree, and I started to make this change, but it
453 void WriteH(int32_t addr, uint16_t value, Instruction* instr);
454 void WriteH(int32_t addr, int16_t value, Instruction* instr);
455 void WriteW(int32_t addr, int value, Instruction* instr);
jbramley 2016/07/20 16:09:24 I suggest using (u)int32_t explicitly, for consist
binji 2016/07/29 21:46:30 Yes, but I was trying to have consistency with the
456
457 // Read and write exclusive. The writes return the strex status: 0 if the
458 // write succeeds, and 1 if the write fails.
459 uint8_t ReadExBU(int32_t addr);
460 uint16_t ReadExHU(int32_t addr, Instruction* instr);
461 int ReadExW(int32_t addr, Instruction* instr);
462 int WriteExB(int32_t addr, uint8_t value);
463 int WriteExH(int32_t addr, uint16_t value, Instruction* instr);
464 int WriteExW(int32_t addr, int value, Instruction* instr);
465
466 class LocalMonitor {
467 public:
468 LocalMonitor();
469
470 // These functions manage the state machine for the local monitor, but do
471 // not actually perform loads and stores.
472 // CheckStoreExcl only returns true if the exclusive store is allowed; the
473 // global monitor will still have to be checked to see whether the memory
474 // should be updated.
475 void LoadExcl(int32_t addr, TransactionSize size);
jbramley 2016/07/20 16:09:24 How about "NotifyLoadExcl" and so on? Then it's cl
binji 2016/07/29 21:46:30 Done.
476 void Store(int32_t addr, TransactionSize size);
477 bool CheckStoreExcl(int32_t addr, TransactionSize size);
478
479 private:
480 MonitorAccess access_state_;
481 int32_t tagged_addr_;
482 TransactionSize size_;
483 };
484
485 class GlobalMonitor {
486 public:
487 GlobalMonitor();
488
489 class Node {
jbramley 2016/07/20 16:09:24 Perhaps "Processor" or something similar would be
binji 2016/07/29 21:46:30 Done.
490 public:
491 Node();
492
493 private:
494 friend class GlobalMonitor;
495 // These functions manage the state machine for the global monitor, but do
496 // not actually perform loads and stores.
497 void LoadExcl_Locked(int32_t addr);
498 void Store_Locked(int32_t addr, bool is_requesting_processor);
499 bool CheckStoreExcl_Locked(int32_t addr, bool is_requesting_processor);
500
501 MonitorAccess access_state_;
502 int32_t tagged_addr_;
503 Node* next_;
504 Node* prev_;
505 };
506
507 // Exposed so it can be accessed by Simulator::{Read,Write}Ex*.
508 base::Mutex mutex;
509
510 void LoadExcl_Locked(int32_t addr, Node* node);
511 void Store_Locked(int32_t addr, Node* node);
512 bool CheckStoreExcl_Locked(int32_t addr, Node* node);
513
514 // Called when the simulator is destroyed.
515 void RemoveNode(Node* node);
516
517 private:
518 bool IsNodeInLinkedList_Locked(Node* node) const;
519 void PrependNode_Locked(Node* node);
520
521 Node* head_;
522 };
523
524 LocalMonitor local_monitor_;
525 GlobalMonitor::Node global_monitor_node_;
526 static base::LazyInstance<GlobalMonitor>::type global_monitor_;
430 }; 527 };
431 528
432 529
433 // When running with the simulator transition into simulated execution at this 530 // When running with the simulator transition into simulated execution at this
434 // point. 531 // point.
435 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ 532 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
436 reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \ 533 reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \
437 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4)) 534 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))
438 535
439 #define CALL_GENERATED_FP_INT(isolate, entry, p0, p1) \ 536 #define CALL_GENERATED_FP_INT(isolate, entry, p0, p1) \
(...skipping 25 matching lines...) Expand all
465 static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) { 562 static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) {
466 Simulator::current(isolate)->PopAddress(); 563 Simulator::current(isolate)->PopAddress();
467 } 564 }
468 }; 565 };
469 566
470 } // namespace internal 567 } // namespace internal
471 } // namespace v8 568 } // namespace v8
472 569
473 #endif // !defined(USE_SIMULATOR) 570 #endif // !defined(USE_SIMULATOR)
474 #endif // V8_ARM_SIMULATOR_ARM_H_ 571 #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