| 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_;
|
| };
|
|
|
|
|
|
|