| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // Declares a Simulator for ARM64 instructions if we are not generating a native | 5 // Declares a Simulator for ARM64 instructions if we are not generating a native |
| 6 // ARM64 binary. This Simulator allows us to run and debug ARM64 code generation | 6 // ARM64 binary. This Simulator allows us to run and debug ARM64 code generation |
| 7 // on regular desktop machines. | 7 // on regular desktop machines. |
| 8 // Dart calls into generated code by "calling" the InvokeDartCode stub, | 8 // Dart calls into generated code by "calling" the InvokeDartCode stub, |
| 9 // which will start execution in the Simulator or forwards to the real entry | 9 // which will start execution in the Simulator or forwards to the real entry |
| 10 // on a ARM64 HW platform. | 10 // on a ARM64 HW platform. |
| 11 | 11 |
| 12 #ifndef VM_SIMULATOR_ARM64_H_ | 12 #ifndef VM_SIMULATOR_ARM64_H_ |
| 13 #define VM_SIMULATOR_ARM64_H_ | 13 #define VM_SIMULATOR_ARM64_H_ |
| 14 | 14 |
| 15 #ifndef VM_SIMULATOR_H_ | 15 #ifndef VM_SIMULATOR_H_ |
| 16 #error Do not include simulator_arm64.h directly; use simulator.h. | 16 #error Do not include simulator_arm64.h directly; use simulator.h. |
| 17 #endif | 17 #endif |
| 18 | 18 |
| 19 #include "vm/constants_arm64.h" | 19 #include "vm/constants_arm64.h" |
| 20 #include "vm/object.h" | |
| 21 | 20 |
| 22 namespace dart { | 21 namespace dart { |
| 23 | 22 |
| 24 class Isolate; | 23 class Isolate; |
| 24 class Mutex; |
| 25 class RawObject; |
| 25 class SimulatorSetjmpBuffer; | 26 class SimulatorSetjmpBuffer; |
| 26 | 27 |
| 27 typedef struct { | 28 typedef struct { |
| 28 union { | 29 union { |
| 29 int64_t i64[2]; | 30 int64_t i64[2]; |
| 30 int32_t i32[4]; | 31 int32_t i32[4]; |
| 31 } bits; | 32 } bits; |
| 32 } simd_value_t; | 33 } simd_value_t; |
| 33 | 34 |
| 34 class Simulator { | 35 class Simulator { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 // Accessor to the internal simulator stack top. | 71 // Accessor to the internal simulator stack top. |
| 71 uword StackTop() const; | 72 uword StackTop() const; |
| 72 | 73 |
| 73 // The isolate's top_exit_frame_info refers to a Dart frame in the simulator | 74 // The isolate's top_exit_frame_info refers to a Dart frame in the simulator |
| 74 // stack. The simulator's top_exit_frame_info refers to a C++ frame in the | 75 // stack. The simulator's top_exit_frame_info refers to a C++ frame in the |
| 75 // native stack. | 76 // native stack. |
| 76 uword top_exit_frame_info() const { return top_exit_frame_info_; } | 77 uword top_exit_frame_info() const { return top_exit_frame_info_; } |
| 77 void set_top_exit_frame_info(uword value) { top_exit_frame_info_ = value; } | 78 void set_top_exit_frame_info(uword value) { top_exit_frame_info_ = value; } |
| 78 | 79 |
| 79 // Call on program start. | 80 // Call on program start. |
| 80 static void InitOnce() {} | 81 static void InitOnce(); |
| 81 | 82 |
| 82 // Dart generally calls into generated code with 5 parameters. This is a | 83 // Dart generally calls into generated code with 5 parameters. This is a |
| 83 // convenience function, which sets up the simulator state and grabs the | 84 // convenience function, which sets up the simulator state and grabs the |
| 84 // result on return. The return value is R0. The parameters are placed in | 85 // result on return. The return value is R0. The parameters are placed in |
| 85 // R0-3. | 86 // R0-3. |
| 86 int64_t Call(int64_t entry, | 87 int64_t Call(int64_t entry, |
| 87 int64_t parameter0, | 88 int64_t parameter0, |
| 88 int64_t parameter1, | 89 int64_t parameter1, |
| 89 int64_t parameter2, | 90 int64_t parameter2, |
| 90 int64_t parameter3, | 91 int64_t parameter3, |
| 91 bool fp_return = false, | 92 bool fp_return = false, |
| 92 bool fp_args = false); | 93 bool fp_args = false); |
| 93 | 94 |
| 95 // Implementation of atomic compare and exchange in the same synchronization |
| 96 // domain as other synchronization primitive instructions (e.g. ldrex, strex). |
| 97 static uword CompareExchange(uword* address, |
| 98 uword compare_value, |
| 99 uword new_value); |
| 100 |
| 94 // Runtime and native call support. | 101 // Runtime and native call support. |
| 95 enum CallKind { | 102 enum CallKind { |
| 96 kRuntimeCall, | 103 kRuntimeCall, |
| 97 kLeafRuntimeCall, | 104 kLeafRuntimeCall, |
| 98 kLeafFloatRuntimeCall, | 105 kLeafFloatRuntimeCall, |
| 99 kBootstrapNativeCall, | 106 kBootstrapNativeCall, |
| 100 kNativeCall | 107 kNativeCall |
| 101 }; | 108 }; |
| 102 static uword RedirectExternalReference(uword function, | 109 static uword RedirectExternalReference(uword function, |
| 103 CallKind call_kind, | 110 CallKind call_kind, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 inline int16_t ReadH(uword addr, Instr* instr); | 173 inline int16_t ReadH(uword addr, Instr* instr); |
| 167 inline void WriteH(uword addr, uint16_t value, Instr* instr); | 174 inline void WriteH(uword addr, uint16_t value, Instr* instr); |
| 168 | 175 |
| 169 inline uint32_t ReadWU(uword addr, Instr* instr); | 176 inline uint32_t ReadWU(uword addr, Instr* instr); |
| 170 inline int32_t ReadW(uword addr, Instr* instr); | 177 inline int32_t ReadW(uword addr, Instr* instr); |
| 171 inline void WriteW(uword addr, uint32_t value, Instr* instr); | 178 inline void WriteW(uword addr, uint32_t value, Instr* instr); |
| 172 | 179 |
| 173 inline intptr_t ReadX(uword addr, Instr* instr); | 180 inline intptr_t ReadX(uword addr, Instr* instr); |
| 174 inline void WriteX(uword addr, intptr_t value, Instr* instr); | 181 inline void WriteX(uword addr, intptr_t value, Instr* instr); |
| 175 | 182 |
| 183 // In Dart, there is at most one thread per isolate. |
| 184 // We keep track of 16 exclusive access address tags across all isolates. |
| 185 // Since we cannot simulate a native context switch, which clears |
| 186 // the exclusive access state of the local monitor (using the CLREX |
| 187 // instruction), we associate the isolate requesting exclusive access to the |
| 188 // address tag. Multiple isolates requesting exclusive access (using the LDREX |
| 189 // instruction) to the same address will result in multiple address tags being |
| 190 // created for the same address, one per isolate. |
| 191 // At any given time, each isolate is associated to at most one address tag. |
| 192 static Mutex* exclusive_access_lock_; |
| 193 static const int kNumAddressTags = 16; |
| 194 static struct AddressTag { |
| 195 Isolate* isolate; |
| 196 uword addr; |
| 197 } exclusive_access_state_[kNumAddressTags]; |
| 198 static int next_address_tag_; |
| 199 |
| 200 // Synchronization primitives support. |
| 201 void ClearExclusive(); |
| 202 intptr_t ReadExclusiveW(uword addr, Instr* instr); |
| 203 intptr_t WriteExclusiveW(uword addr, intptr_t value, Instr* instr); |
| 204 |
| 205 // Set access to given address to 'exclusive state' for current isolate. |
| 206 static void SetExclusiveAccess(uword addr); |
| 207 |
| 208 // Returns true if the current isolate has exclusive access to given address, |
| 209 // returns false otherwise. In either case, set access to given address to |
| 210 // 'open state' for all isolates. |
| 211 // If given addr is NULL, set access to 'open state' for current |
| 212 // isolate (CLREX). |
| 213 static bool HasExclusiveAccessAndOpen(uword addr); |
| 214 |
| 176 // Helper functions to set the conditional flags in the architecture state. | 215 // Helper functions to set the conditional flags in the architecture state. |
| 177 void SetNZFlagsW(int32_t val); | 216 void SetNZFlagsW(int32_t val); |
| 178 bool CarryFromW(int32_t left, int32_t right, int32_t carry); | 217 bool CarryFromW(int32_t left, int32_t right, int32_t carry); |
| 179 bool OverflowFromW(int32_t left, int32_t right, int32_t carry); | 218 bool OverflowFromW(int32_t left, int32_t right, int32_t carry); |
| 180 | 219 |
| 181 void SetNZFlagsX(int64_t val); | 220 void SetNZFlagsX(int64_t val); |
| 182 bool CarryFromX(int64_t alu_out, int64_t left, int64_t right, bool addition); | 221 bool CarryFromX(int64_t alu_out, int64_t left, int64_t right, bool addition); |
| 183 bool OverflowFromX( | 222 bool OverflowFromX( |
| 184 int64_t alu_out, int64_t left, int64_t right, bool addition); | 223 int64_t alu_out, int64_t left, int64_t right, bool addition); |
| 185 | 224 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 } | 260 } |
| 222 | 261 |
| 223 friend class SimulatorDebugger; | 262 friend class SimulatorDebugger; |
| 224 friend class SimulatorSetjmpBuffer; | 263 friend class SimulatorSetjmpBuffer; |
| 225 DISALLOW_COPY_AND_ASSIGN(Simulator); | 264 DISALLOW_COPY_AND_ASSIGN(Simulator); |
| 226 }; | 265 }; |
| 227 | 266 |
| 228 } // namespace dart | 267 } // namespace dart |
| 229 | 268 |
| 230 #endif // VM_SIMULATOR_ARM64_H_ | 269 #endif // VM_SIMULATOR_ARM64_H_ |
| OLD | NEW |