Index: src/ppc/simulator-ppc.h |
diff --git a/src/ppc/simulator-ppc.h b/src/ppc/simulator-ppc.h |
index 91e7f05ea5433b09fcb93b3287e323e1a644dc76..0c23b04a37964dd8c3051cbd3082951c3af82391 100644 |
--- a/src/ppc/simulator-ppc.h |
+++ b/src/ppc/simulator-ppc.h |
@@ -289,19 +289,25 @@ class Simulator { |
// Read and write memory. |
inline uint8_t ReadBU(intptr_t addr); |
+ inline uint8_t ReadExBU(intptr_t addr); |
inline int8_t ReadB(intptr_t addr); |
inline void WriteB(intptr_t addr, uint8_t value); |
+ inline int WriteExB(intptr_t addr, uint8_t value); |
inline void WriteB(intptr_t addr, int8_t value); |
inline uint16_t ReadHU(intptr_t addr, Instruction* instr); |
+ inline uint16_t ReadExHU(intptr_t addr, Instruction* instr); |
inline int16_t ReadH(intptr_t addr, Instruction* instr); |
// Note: Overloaded on the sign of the value. |
inline void WriteH(intptr_t addr, uint16_t value, Instruction* instr); |
+ inline int WriteExH(intptr_t addr, uint16_t value, Instruction* instr); |
inline void WriteH(intptr_t addr, int16_t value, Instruction* instr); |
inline uint32_t ReadWU(intptr_t addr, Instruction* instr); |
+ inline uint32_t ReadExWU(intptr_t addr, Instruction* instr); |
inline int32_t ReadW(intptr_t addr, Instruction* instr); |
inline void WriteW(intptr_t addr, uint32_t value, Instruction* instr); |
+ inline int WriteExW(intptr_t addr, uint32_t value, Instruction* instr); |
inline void WriteW(intptr_t addr, int32_t value, Instruction* instr); |
intptr_t* ReadDW(intptr_t addr); |
@@ -311,7 +317,8 @@ class Simulator { |
void SetCR0(intptr_t result, bool setSO = false); |
void ExecuteBranchConditional(Instruction* instr, BCType type); |
void ExecuteExt1(Instruction* instr); |
- bool ExecuteExt2_10bit(Instruction* instr); |
+ bool ExecuteExt2_10bit_part1(Instruction* instr); |
+ bool ExecuteExt2_10bit_part2(Instruction* instr); |
bool ExecuteExt2_9bit_part1(Instruction* instr); |
bool ExecuteExt2_9bit_part2(Instruction* instr); |
void ExecuteExt2_5bit(Instruction* instr); |
@@ -398,6 +405,84 @@ class Simulator { |
char* desc; |
}; |
StopCountAndDesc watched_stops_[kNumOfWatchedStops]; |
+ |
+ // Syncronization primitives. See ARM DDI 0406C.b, A2.9. |
+ enum class MonitorAccess { |
+ Open, |
+ Exclusive, |
+ }; |
+ |
+ enum class TransactionSize { |
+ None = 0, |
+ Byte = 1, |
+ HalfWord = 2, |
+ Word = 4, |
+ }; |
+ |
+ class LocalMonitor { |
+ public: |
+ LocalMonitor(); |
+ |
+ // These functions manage the state machine for the local monitor, but do |
+ // not actually perform loads and stores. NotifyStoreExcl only returns |
+ // true if the exclusive store is allowed; the global monitor will still |
+ // have to be checked to see whether the memory should be updated. |
+ void NotifyLoad(int32_t addr); |
+ void NotifyLoadExcl(int32_t addr, TransactionSize size); |
+ void NotifyStore(int32_t addr); |
+ bool NotifyStoreExcl(int32_t addr, TransactionSize size); |
+ |
+ private: |
+ void Clear(); |
+ |
+ MonitorAccess access_state_; |
+ int32_t tagged_addr_; |
+ TransactionSize size_; |
+ }; |
+ |
+ class GlobalMonitor { |
+ public: |
+ GlobalMonitor(); |
+ |
+ class Processor { |
+ public: |
+ Processor(); |
+ |
+ private: |
+ friend class GlobalMonitor; |
+ // These functions manage the state machine for the global monitor, but do |
+ // not actually perform loads and stores. |
+ void Clear_Locked(); |
+ void NotifyLoadExcl_Locked(int32_t addr); |
+ void NotifyStore_Locked(int32_t addr, bool is_requesting_processor); |
+ bool NotifyStoreExcl_Locked(int32_t addr, bool is_requesting_processor); |
+ |
+ MonitorAccess access_state_; |
+ int32_t tagged_addr_; |
+ Processor* next_; |
+ Processor* prev_; |
+ }; |
+ |
+ // Exposed so it can be accessed by Simulator::{Read,Write}Ex*. |
+ base::Mutex mutex; |
+ |
+ void NotifyLoadExcl_Locked(int32_t addr, Processor* processor); |
+ void NotifyStore_Locked(int32_t addr, Processor* processor); |
+ bool NotifyStoreExcl_Locked(int32_t addr, Processor* processor); |
+ |
+ // Called when the simulator is destroyed. |
+ void RemoveProcessor(Processor* processor); |
+ |
+ private: |
+ bool IsProcessorInLinkedList_Locked(Processor* processor) const; |
+ void PrependProcessor_Locked(Processor* processor); |
+ |
+ Processor* head_; |
+ }; |
+ |
+ LocalMonitor local_monitor_; |
+ GlobalMonitor::Processor global_monitor_processor_; |
+ static base::LazyInstance<GlobalMonitor>::type global_monitor_; |
}; |