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

Side by Side Diff: runtime/vm/simulator_arm.h

Issue 12041056: Initial revision of ARM simulator and (empty) MIPS simulator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
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.
4
5 // Declares a Simulator for ARM instructions if we are not generating a native
6 // ARM binary. This Simulator allows us to run and debug ARM code generation on
7 // regular desktop machines.
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
10 // on a ARM HW platform.
11
12 #ifndef VM_SIMULATOR_ARM_H_
13 #define VM_SIMULATOR_ARM_H_
14
15 #ifndef VM_SIMULATOR_H_
16 #error Do not include simulator_arm.h directly; use simulator.h.
17 #endif
18
19 #if !defined(HOST_ARCH_ARM)
20
21 #include "vm/allocation.h"
22 #include "vm/constants_arm.h"
23 #include "vm/object.h"
24
25 namespace dart {
26
27 class Isolate;
28 class SimulatorSetjmpBuffer;
29
30 class Simulator {
31 public:
32 static const size_t kSimulatorStackUnderflowSize = 64;
33
34 Simulator();
35 ~Simulator();
36
37 // The currently executing Simulator instance. Potentially there can be one
38 // for each isolate.
siva 2013/01/24 02:03:09 There should be one for each isolate right, not su
Ivan Posva 2013/01/24 18:25:57 Actually the Simulator should be tied to the threa
regis 2013/01/24 21:47:48 No, there is zero or one simulator per isolate. If
regis 2013/01/24 21:47:48 OK, leaving as is for now.
39 static Simulator* Current();
40
41 // Accessors for register state. Reading the pc value adheres to the ARM
42 // architecture specification and is off by 8 from the currently executing
43 // instruction.
44 void set_register(Register reg, int32_t value);
45 int32_t get_register(Register reg) const;
46
47 // Special case of set_register and get_register to access the raw PC value.
48 void set_pc(int32_t value);
49 int32_t get_pc() const;
50
51 // Accessors for VFP register state.
52 void set_sregister(SRegister reg, float value);
53 float get_sregister(SRegister reg) const;
54 void set_dregister(DRegister reg, double value);
55 double get_dregister(DRegister reg) const;
56
57 // Accessor to the internal simulator stack area.
58 uintptr_t StackTop() const;
59 uintptr_t StackLimit() const;
60
61 // Executes ARM instructions until the PC reaches end_sim_pc.
62 void Execute();
63
64 // Call on program start.
65 static void InitOnce();
66
67 // Dart generally calls into generated code with 5 parameters. This is a
68 // convenience function, which sets up the simulator state and grabs the
69 // result on return.
70 int64_t Call(int32_t entry,
71 int32_t parameter0,
72 int32_t parameter1,
73 int32_t parameter2,
74 int32_t parameter3,
75 int32_t parameter4);
76
77 // Implementation of atomic compare and exchange in the same synchronization
78 // domain as other synchronization primitive instructions (e.g. ldrex, strex).
79 static uword CompareExchange(uword* address,
80 uword compare_value,
81 uword new_value);
82
83 // Runtime call support.
84 static uword RedirectExternalReference(void* function,
85 uint32_t argument_count);
86
87 void Longjmp(int32_t pc, int32_t sp, int32_t fp, const Instance& object);
88
89 private:
90 // Known bad pc value to ensure that the simulator does not execute
91 // without being properly setup.
92 static const uword kBadLR = -1;
93 // A pc value used to signal the simulator to stop execution. Generally
94 // the lr is set to this value on transition from native C code to
95 // simulated execution, so that the simulator can "return" to the native
96 // C code.
97 static const uword kEndSimulatingPC = -2;
98
99 // CPU state.
100 int32_t registers_[kNumberOfCpuRegisters];
101 bool n_flag_;
102 bool z_flag_;
103 bool c_flag_;
104 bool v_flag_;
105
106 // VFP state.
107 union { // S and D register banks are overlapping.
108 float sregisters_[kNumberOfSRegisters];
109 double dregisters_[kNumberOfDRegisters];
110 };
111 bool fp_n_flag_;
112 bool fp_z_flag_;
113 bool fp_c_flag_;
114 bool fp_v_flag_;
115
116 // Simulator support.
117 char* stack_;
118 bool pc_modified_;
119 int icount_;
120 static bool flag_trace_sim_;
121 static int32_t flag_stop_sim_at_;
122 SimulatorSetjmpBuffer* last_setjmp_buffer_;
123
124 // Registered breakpoints.
125 Instr* break_pc_;
126 int32_t break_instr_;
127
128 // Implicit null guard support.
129 void HandleNullPageAccess(uword addr, Instr* instr);
130
131 // Unsupported instructions use Format to print an error and stop execution.
132 void Format(Instr* instr, const char* format);
133
134 // Checks if the current instruction should be executed based on its
135 // condition bits.
136 bool ConditionallyExecute(Instr* instr);
137
138 // Helper functions to set the conditional flags in the architecture state.
139 void SetNZFlags(int32_t val);
140 void SetCFlag(bool val);
141 void SetVFlag(bool val);
142 bool CarryFrom(int32_t left, int32_t right);
143 bool BorrowFrom(int32_t left, int32_t right);
144 bool OverflowFrom(int32_t alu_out,
145 int32_t left,
146 int32_t right,
147 bool addition);
148
149 // Helper functions to decode common "addressing" modes.
150 int32_t GetShiftRm(Instr* instr, bool* carry_out);
151 int32_t GetImm(Instr* instr, bool* carry_out);
152 void HandleRList(Instr* instr, bool load);
153 void SupervisorCall(Instr* instr);
154
155 // Read and write memory.
156 void UnalignedAccess(const char* msg, uword addr, Instr* instr);
157
158 inline uint8_t ReadBU(uword addr);
159 inline int8_t ReadB(uword addr);
160 inline void WriteB(uword addr, uint8_t value);
161
162 inline uint16_t ReadHU(uword addr, Instr* instr);
163 inline int16_t ReadH(uword addr, Instr* instr);
164 inline void WriteH(uword addr, uint16_t value, Instr* instr);
165
166 inline int ReadW(uword addr, Instr* instr);
167 inline void WriteW(uword addr, int value, Instr* instr);
168
169 // Synchronization primitives support.
170 void ClearExclusive();
171 int ReadExclusiveW(uword addr, Instr* instr);
172 int WriteExclusiveW(uword addr, int value, Instr* instr);
173
174 // In Dart, there is at most one thread per isolate.
175 // We keep track of 16 exclusive access address tags across all isolates.
176 // Since we cannot simulate a native context switch, which clears
177 // the exclusive access state of the local monitor (using the CLREX
178 // instruction), we associate the isolate requesting exclusive access to the
179 // address tag. Multiple isolates requesting exclusive access (using the LDREX
180 // instruction) to the same address will result in multiple address tags being
181 // created for the same address, one per isolate.
182 // At any given time, each isolate is associated to at most one address tag.
183 static Mutex* exclusive_access_lock_;
184 static const int kNumAddressTags = 16;
185 static struct AddressTag {
186 Isolate* isolate;
187 uword addr;
188 } exclusive_access_state_[kNumAddressTags];
siva 2013/01/24 02:03:09 Not sure if we will require this as there will be
regis 2013/01/24 21:47:48 TODO(regis) added.
189 static int next_address_tag_;
190
191 // Set access to given address to 'exclusive state' for current isolate.
192 static void SetExclusiveAccess(uword addr);
193
194 // Returns true if the current isolate has exclusive access to given address,
195 // returns false otherwise. In either case, set access to given address to
196 // 'open state' for all isolates.
197 // If given addr is NULL, set access to 'open state' for current
198 // isolate (CLREX).
199 static bool HasExclusiveAccessAndOpen(uword addr);
200
201 // Executing is handled based on the instruction type.
202 void DecodeType01(Instr* instr); // Both type 0 and type 1 rolled into one.
203 void DecodeType2(Instr* instr);
204 void DecodeType3(Instr* instr);
205 void DecodeType4(Instr* instr);
206 void DecodeType5(Instr* instr);
207 void DecodeType6(Instr* instr);
208 void DecodeType7(Instr* instr);
209
210 // Executes one instruction.
211 void InstructionDecode(Instr* instr);
212
213 // Longjmp support for exceptions.
214 SimulatorSetjmpBuffer* last_setjmp_buffer() {
215 return last_setjmp_buffer_;
216 }
217 void set_last_setjmp_buffer(SimulatorSetjmpBuffer* buffer) {
218 last_setjmp_buffer_ = buffer;
219 }
220
221 friend class SimulatorDebugger;
222 friend class SimulatorSetjmpBuffer;
223 DISALLOW_COPY_AND_ASSIGN(Simulator);
224 };
225
226 } // namespace dart
227
228 #endif // !defined(HOST_ARCH_ARM)
229
230 #endif // VM_SIMULATOR_ARM_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698