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

Side by Side Diff: runtime/vm/simulator_arm64.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 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 | « runtime/vm/simulator_arm.cc ('k') | runtime/vm/simulator_dbc.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <setjmp.h> // NOLINT 5 #include <setjmp.h> // NOLINT
6 #include <stdlib.h> 6 #include <stdlib.h>
7 7
8 #include "vm/globals.h" 8 #include "vm/globals.h"
9 #if defined(TARGET_ARCH_ARM64) 9 #if defined(TARGET_ARCH_ARM64)
10 10
11 // Only build the simulator if not compiling for real ARM hardware. 11 // Only build the simulator if not compiling for real ARM hardware.
12 #if defined(USING_SIMULATOR) 12 #if defined(USING_SIMULATOR)
13 13
14 #include "vm/simulator.h" 14 #include "vm/simulator.h"
15 15
16 #include "vm/assembler.h" 16 #include "vm/assembler.h"
17 #include "vm/constants_arm64.h" 17 #include "vm/constants_arm64.h"
18 #include "vm/disassembler.h" 18 #include "vm/disassembler.h"
19 #include "vm/lockers.h" 19 #include "vm/lockers.h"
20 #include "vm/native_arguments.h" 20 #include "vm/native_arguments.h"
21 #include "vm/os_thread.h"
21 #include "vm/stack_frame.h" 22 #include "vm/stack_frame.h"
22 #include "vm/os_thread.h"
23 23
24 namespace dart { 24 namespace dart {
25 25
26 DEFINE_FLAG(uint64_t, 26 DEFINE_FLAG(uint64_t,
27 trace_sim_after, 27 trace_sim_after,
28 ULLONG_MAX, 28 ULLONG_MAX,
29 "Trace simulator execution after instruction count reached."); 29 "Trace simulator execution after instruction count reached.");
30 DEFINE_FLAG(uint64_t, 30 DEFINE_FLAG(uint64_t,
31 stop_sim_at, 31 stop_sim_at,
32 ULLONG_MAX, 32 ULLONG_MAX,
33 "Instruction address or instruction count to stop simulator at."); 33 "Instruction address or instruction count to stop simulator at.");
34 34
35
36 // This macro provides a platform independent use of sscanf. The reason for 35 // This macro provides a platform independent use of sscanf. The reason for
37 // SScanF not being implemented in a platform independent way through 36 // SScanF not being implemented in a platform independent way through
38 // OS in the same way as SNPrint is that the Windows C Run-Time 37 // OS in the same way as SNPrint is that the Windows C Run-Time
39 // Library does not provide vsscanf. 38 // Library does not provide vsscanf.
40 #define SScanF sscanf // NOLINT 39 #define SScanF sscanf // NOLINT
41 40
42
43 // SimulatorSetjmpBuffer are linked together, and the last created one 41 // SimulatorSetjmpBuffer are linked together, and the last created one
44 // is referenced by the Simulator. When an exception is thrown, the exception 42 // is referenced by the Simulator. When an exception is thrown, the exception
45 // runtime looks at where to jump and finds the corresponding 43 // runtime looks at where to jump and finds the corresponding
46 // SimulatorSetjmpBuffer based on the stack pointer of the exception handler. 44 // SimulatorSetjmpBuffer based on the stack pointer of the exception handler.
47 // The runtime then does a Longjmp on that buffer to return to the simulator. 45 // The runtime then does a Longjmp on that buffer to return to the simulator.
48 class SimulatorSetjmpBuffer { 46 class SimulatorSetjmpBuffer {
49 public: 47 public:
50 void Longjmp() { 48 void Longjmp() {
51 // "This" is now the last setjmp buffer. 49 // "This" is now the last setjmp buffer.
52 simulator_->set_last_setjmp_buffer(this); 50 simulator_->set_last_setjmp_buffer(this);
(...skipping 18 matching lines...) Expand all
71 69
72 private: 70 private:
73 uword sp_; 71 uword sp_;
74 Simulator* simulator_; 72 Simulator* simulator_;
75 SimulatorSetjmpBuffer* link_; 73 SimulatorSetjmpBuffer* link_;
76 jmp_buf buffer_; 74 jmp_buf buffer_;
77 75
78 friend class Simulator; 76 friend class Simulator;
79 }; 77 };
80 78
81
82 // The SimulatorDebugger class is used by the simulator while debugging 79 // The SimulatorDebugger class is used by the simulator while debugging
83 // simulated ARM64 code. 80 // simulated ARM64 code.
84 class SimulatorDebugger { 81 class SimulatorDebugger {
85 public: 82 public:
86 explicit SimulatorDebugger(Simulator* sim); 83 explicit SimulatorDebugger(Simulator* sim);
87 ~SimulatorDebugger(); 84 ~SimulatorDebugger();
88 85
89 void Stop(Instr* instr, const char* message); 86 void Stop(Instr* instr, const char* message);
90 void Debug(); 87 void Debug();
91 char* ReadLine(const char* prompt); 88 char* ReadLine(const char* prompt);
(...skipping 20 matching lines...) Expand all
112 // Set or delete a breakpoint. Returns true if successful. 109 // Set or delete a breakpoint. Returns true if successful.
113 bool SetBreakpoint(Instr* breakpc); 110 bool SetBreakpoint(Instr* breakpc);
114 bool DeleteBreakpoint(Instr* breakpc); 111 bool DeleteBreakpoint(Instr* breakpc);
115 112
116 // Undo and redo all breakpoints. This is needed to bracket disassembly and 113 // Undo and redo all breakpoints. This is needed to bracket disassembly and
117 // execution to skip past breakpoints when run from the debugger. 114 // execution to skip past breakpoints when run from the debugger.
118 void UndoBreakpoints(); 115 void UndoBreakpoints();
119 void RedoBreakpoints(); 116 void RedoBreakpoints();
120 }; 117 };
121 118
122
123 SimulatorDebugger::SimulatorDebugger(Simulator* sim) { 119 SimulatorDebugger::SimulatorDebugger(Simulator* sim) {
124 sim_ = sim; 120 sim_ = sim;
125 } 121 }
126 122
127
128 SimulatorDebugger::~SimulatorDebugger() {} 123 SimulatorDebugger::~SimulatorDebugger() {}
129 124
130
131 void SimulatorDebugger::Stop(Instr* instr, const char* message) { 125 void SimulatorDebugger::Stop(Instr* instr, const char* message) {
132 OS::Print("Simulator hit %s\n", message); 126 OS::Print("Simulator hit %s\n", message);
133 Debug(); 127 Debug();
134 } 128 }
135 129
136
137 static Register LookupCpuRegisterByName(const char* name) { 130 static Register LookupCpuRegisterByName(const char* name) {
138 static const char* kNames[] = { 131 static const char* kNames[] = {
139 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 132 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
140 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 133 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
141 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 134 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
142 "r24", "r25", "r26", "r27", "r28", "r29", "r30", 135 "r24", "r25", "r26", "r27", "r28", "r29", "r30",
143 136
144 "ip0", "ip1", "pp", "ctx", "fp", "lr", "sp", "zr", 137 "ip0", "ip1", "pp", "ctx", "fp", "lr", "sp", "zr",
145 }; 138 };
146 static const Register kRegisters[] = { 139 static const Register kRegisters[] = {
147 R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, 140 R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10,
148 R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, 141 R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21,
149 R22, R23, R24, R25, R26, R27, R28, R29, R30, 142 R22, R23, R24, R25, R26, R27, R28, R29, R30,
150 143
151 IP0, IP1, PP, CTX, FP, LR, R31, ZR, 144 IP0, IP1, PP, CTX, FP, LR, R31, ZR,
152 }; 145 };
153 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters)); 146 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
154 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) { 147 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {
155 if (strcmp(kNames[i], name) == 0) { 148 if (strcmp(kNames[i], name) == 0) {
156 return kRegisters[i]; 149 return kRegisters[i];
157 } 150 }
158 } 151 }
159 return kNoRegister; 152 return kNoRegister;
160 } 153 }
161 154
162
163 static VRegister LookupVRegisterByName(const char* name) { 155 static VRegister LookupVRegisterByName(const char* name) {
164 int reg_nr = -1; 156 int reg_nr = -1;
165 bool ok = SScanF(name, "v%d", &reg_nr); 157 bool ok = SScanF(name, "v%d", &reg_nr);
166 if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfVRegisters)) { 158 if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfVRegisters)) {
167 return static_cast<VRegister>(reg_nr); 159 return static_cast<VRegister>(reg_nr);
168 } 160 }
169 return kNoVRegister; 161 return kNoVRegister;
170 } 162 }
171 163
172
173 bool SimulatorDebugger::GetValue(char* desc, uint64_t* value) { 164 bool SimulatorDebugger::GetValue(char* desc, uint64_t* value) {
174 Register reg = LookupCpuRegisterByName(desc); 165 Register reg = LookupCpuRegisterByName(desc);
175 if (reg != kNoRegister) { 166 if (reg != kNoRegister) {
176 if (reg == ZR) { 167 if (reg == ZR) {
177 *value = 0; 168 *value = 0;
178 return true; 169 return true;
179 } 170 }
180 *value = sim_->get_register(reg); 171 *value = sim_->get_register(reg);
181 return true; 172 return true;
182 } 173 }
(...skipping 11 matching lines...) Expand all
194 *value = sim_->get_pc(); 185 *value = sim_->get_pc();
195 return true; 186 return true;
196 } 187 }
197 bool retval = SScanF(desc, "0x%" Px64, value) == 1; 188 bool retval = SScanF(desc, "0x%" Px64, value) == 1;
198 if (!retval) { 189 if (!retval) {
199 retval = SScanF(desc, "%" Px64, value) == 1; 190 retval = SScanF(desc, "%" Px64, value) == 1;
200 } 191 }
201 return retval; 192 return retval;
202 } 193 }
203 194
204
205 bool SimulatorDebugger::GetSValue(char* desc, uint32_t* value) { 195 bool SimulatorDebugger::GetSValue(char* desc, uint32_t* value) {
206 VRegister vreg = LookupVRegisterByName(desc); 196 VRegister vreg = LookupVRegisterByName(desc);
207 if (vreg != kNoVRegister) { 197 if (vreg != kNoVRegister) {
208 *value = sim_->get_vregisters(vreg, 0); 198 *value = sim_->get_vregisters(vreg, 0);
209 return true; 199 return true;
210 } 200 }
211 if (desc[0] == '*') { 201 if (desc[0] == '*') {
212 uint64_t addr; 202 uint64_t addr;
213 if (GetValue(desc + 1, &addr)) { 203 if (GetValue(desc + 1, &addr)) {
214 if (Simulator::IsIllegalAddress(addr)) { 204 if (Simulator::IsIllegalAddress(addr)) {
215 return false; 205 return false;
216 } 206 }
217 *value = *(reinterpret_cast<uint32_t*>(addr)); 207 *value = *(reinterpret_cast<uint32_t*>(addr));
218 return true; 208 return true;
219 } 209 }
220 } 210 }
221 return false; 211 return false;
222 } 212 }
223 213
224
225 bool SimulatorDebugger::GetDValue(char* desc, uint64_t* value) { 214 bool SimulatorDebugger::GetDValue(char* desc, uint64_t* value) {
226 VRegister vreg = LookupVRegisterByName(desc); 215 VRegister vreg = LookupVRegisterByName(desc);
227 if (vreg != kNoVRegister) { 216 if (vreg != kNoVRegister) {
228 *value = sim_->get_vregisterd(vreg, 0); 217 *value = sim_->get_vregisterd(vreg, 0);
229 return true; 218 return true;
230 } 219 }
231 if (desc[0] == '*') { 220 if (desc[0] == '*') {
232 uint64_t addr; 221 uint64_t addr;
233 if (GetValue(desc + 1, &addr)) { 222 if (GetValue(desc + 1, &addr)) {
234 if (Simulator::IsIllegalAddress(addr)) { 223 if (Simulator::IsIllegalAddress(addr)) {
235 return false; 224 return false;
236 } 225 }
237 *value = *(reinterpret_cast<uint64_t*>(addr)); 226 *value = *(reinterpret_cast<uint64_t*>(addr));
238 return true; 227 return true;
239 } 228 }
240 } 229 }
241 return false; 230 return false;
242 } 231 }
243 232
244
245 bool SimulatorDebugger::GetQValue(char* desc, simd_value_t* value) { 233 bool SimulatorDebugger::GetQValue(char* desc, simd_value_t* value) {
246 VRegister vreg = LookupVRegisterByName(desc); 234 VRegister vreg = LookupVRegisterByName(desc);
247 if (vreg != kNoVRegister) { 235 if (vreg != kNoVRegister) {
248 sim_->get_vregister(vreg, value); 236 sim_->get_vregister(vreg, value);
249 return true; 237 return true;
250 } 238 }
251 if (desc[0] == '*') { 239 if (desc[0] == '*') {
252 uint64_t addr; 240 uint64_t addr;
253 if (GetValue(desc + 1, &addr)) { 241 if (GetValue(desc + 1, &addr)) {
254 if (Simulator::IsIllegalAddress(addr)) { 242 if (Simulator::IsIllegalAddress(addr)) {
255 return false; 243 return false;
256 } 244 }
257 *value = *(reinterpret_cast<simd_value_t*>(addr)); 245 *value = *(reinterpret_cast<simd_value_t*>(addr));
258 return true; 246 return true;
259 } 247 }
260 } 248 }
261 return false; 249 return false;
262 } 250 }
263 251
264
265 TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code, 252 TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
266 uword pc) { 253 uword pc) {
267 TokenPosition token_pos = TokenPosition::kNoSource; 254 TokenPosition token_pos = TokenPosition::kNoSource;
268 uword pc_offset = pc - code.PayloadStart(); 255 uword pc_offset = pc - code.PayloadStart();
269 const PcDescriptors& descriptors = 256 const PcDescriptors& descriptors =
270 PcDescriptors::Handle(code.pc_descriptors()); 257 PcDescriptors::Handle(code.pc_descriptors());
271 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); 258 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
272 while (iter.MoveNext()) { 259 while (iter.MoveNext()) {
273 if (iter.PcOffset() == pc_offset) { 260 if (iter.PcOffset() == pc_offset) {
274 return iter.TokenPos(); 261 return iter.TokenPos();
275 } else if (!token_pos.IsReal() && (iter.PcOffset() > pc_offset)) { 262 } else if (!token_pos.IsReal() && (iter.PcOffset() > pc_offset)) {
276 token_pos = iter.TokenPos(); 263 token_pos = iter.TokenPos();
277 } 264 }
278 } 265 }
279 return token_pos; 266 return token_pos;
280 } 267 }
281 268
282
283 void SimulatorDebugger::PrintDartFrame(uword pc, 269 void SimulatorDebugger::PrintDartFrame(uword pc,
284 uword fp, 270 uword fp,
285 uword sp, 271 uword sp,
286 const Function& function, 272 const Function& function,
287 TokenPosition token_pos, 273 TokenPosition token_pos,
288 bool is_optimized, 274 bool is_optimized,
289 bool is_inlined) { 275 bool is_inlined) {
290 const Script& script = Script::Handle(function.script()); 276 const Script& script = Script::Handle(function.script());
291 const String& func_name = String::Handle(function.QualifiedScrubbedName()); 277 const String& func_name = String::Handle(function.QualifiedScrubbedName());
292 const String& url = String::Handle(script.url()); 278 const String& url = String::Handle(script.url());
293 intptr_t line = -1; 279 intptr_t line = -1;
294 intptr_t column = -1; 280 intptr_t column = -1;
295 if (token_pos.IsReal()) { 281 if (token_pos.IsReal()) {
296 script.GetTokenLocation(token_pos, &line, &column); 282 script.GetTokenLocation(token_pos, &line, &column);
297 } 283 }
298 OS::Print( 284 OS::Print(
299 "pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")\n", pc, 285 "pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")\n", pc,
300 fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "", 286 fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
301 func_name.ToCString(), url.ToCString(), line, column); 287 func_name.ToCString(), url.ToCString(), line, column);
302 } 288 }
303 289
304
305 void SimulatorDebugger::PrintBacktrace() { 290 void SimulatorDebugger::PrintBacktrace() {
306 StackFrameIterator frames( 291 StackFrameIterator frames(
307 sim_->get_register(FP), sim_->get_register(SP), sim_->get_pc(), 292 sim_->get_register(FP), sim_->get_register(SP), sim_->get_pc(),
308 StackFrameIterator::kDontValidateFrames, Thread::Current(), 293 StackFrameIterator::kDontValidateFrames, Thread::Current(),
309 StackFrameIterator::kNoCrossThreadIteration); 294 StackFrameIterator::kNoCrossThreadIteration);
310 StackFrame* frame = frames.NextFrame(); 295 StackFrame* frame = frames.NextFrame();
311 ASSERT(frame != NULL); 296 ASSERT(frame != NULL);
312 Function& function = Function::Handle(); 297 Function& function = Function::Handle();
313 Function& inlined_function = Function::Handle(); 298 Function& inlined_function = Function::Handle();
314 Code& code = Code::Handle(); 299 Code& code = Code::Handle();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 frame->IsEntryFrame() 331 frame->IsEntryFrame()
347 ? "entry" 332 ? "entry"
348 : frame->IsExitFrame() 333 : frame->IsExitFrame()
349 ? "exit" 334 ? "exit"
350 : frame->IsStubFrame() ? "stub" : "invalid"); 335 : frame->IsStubFrame() ? "stub" : "invalid");
351 } 336 }
352 frame = frames.NextFrame(); 337 frame = frames.NextFrame();
353 } 338 }
354 } 339 }
355 340
356
357 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) { 341 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) {
358 // Check if a breakpoint can be set. If not return without any side-effects. 342 // Check if a breakpoint can be set. If not return without any side-effects.
359 if (sim_->break_pc_ != NULL) { 343 if (sim_->break_pc_ != NULL) {
360 return false; 344 return false;
361 } 345 }
362 346
363 // Set the breakpoint. 347 // Set the breakpoint.
364 sim_->break_pc_ = breakpc; 348 sim_->break_pc_ = breakpc;
365 sim_->break_instr_ = breakpc->InstructionBits(); 349 sim_->break_instr_ = breakpc->InstructionBits();
366 // Not setting the breakpoint instruction in the code itself. It will be set 350 // Not setting the breakpoint instruction in the code itself. It will be set
367 // when the debugger shell continues. 351 // when the debugger shell continues.
368 return true; 352 return true;
369 } 353 }
370 354
371
372 bool SimulatorDebugger::DeleteBreakpoint(Instr* breakpc) { 355 bool SimulatorDebugger::DeleteBreakpoint(Instr* breakpc) {
373 if (sim_->break_pc_ != NULL) { 356 if (sim_->break_pc_ != NULL) {
374 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 357 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
375 } 358 }
376 359
377 sim_->break_pc_ = NULL; 360 sim_->break_pc_ = NULL;
378 sim_->break_instr_ = 0; 361 sim_->break_instr_ = 0;
379 return true; 362 return true;
380 } 363 }
381 364
382
383 void SimulatorDebugger::UndoBreakpoints() { 365 void SimulatorDebugger::UndoBreakpoints() {
384 if (sim_->break_pc_ != NULL) { 366 if (sim_->break_pc_ != NULL) {
385 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 367 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
386 } 368 }
387 } 369 }
388 370
389
390 void SimulatorDebugger::RedoBreakpoints() { 371 void SimulatorDebugger::RedoBreakpoints() {
391 if (sim_->break_pc_ != NULL) { 372 if (sim_->break_pc_ != NULL) {
392 sim_->break_pc_->SetInstructionBits(Instr::kSimulatorBreakpointInstruction); 373 sim_->break_pc_->SetInstructionBits(Instr::kSimulatorBreakpointInstruction);
393 } 374 }
394 } 375 }
395 376
396
397 void SimulatorDebugger::Debug() { 377 void SimulatorDebugger::Debug() {
398 intptr_t last_pc = -1; 378 intptr_t last_pc = -1;
399 bool done = false; 379 bool done = false;
400 380
401 #define COMMAND_SIZE 63 381 #define COMMAND_SIZE 63
402 #define ARG_SIZE 255 382 #define ARG_SIZE 255
403 383
404 #define STR(a) #a 384 #define STR(a) #a
405 #define XSTR(a) STR(a) 385 #define XSTR(a) STR(a)
406 386
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 // shell when hit. 641 // shell when hit.
662 RedoBreakpoints(); 642 RedoBreakpoints();
663 643
664 #undef COMMAND_SIZE 644 #undef COMMAND_SIZE
665 #undef ARG_SIZE 645 #undef ARG_SIZE
666 646
667 #undef STR 647 #undef STR
668 #undef XSTR 648 #undef XSTR
669 } 649 }
670 650
671
672 char* SimulatorDebugger::ReadLine(const char* prompt) { 651 char* SimulatorDebugger::ReadLine(const char* prompt) {
673 char* result = NULL; 652 char* result = NULL;
674 char line_buf[256]; 653 char line_buf[256];
675 intptr_t offset = 0; 654 intptr_t offset = 0;
676 bool keep_going = true; 655 bool keep_going = true;
677 OS::Print("%s", prompt); 656 OS::Print("%s", prompt);
678 while (keep_going) { 657 while (keep_going) {
679 if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) { 658 if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
680 // fgets got an error. Just give up. 659 // fgets got an error. Just give up.
681 if (result != NULL) { 660 if (result != NULL) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 } 699 }
721 // Copy the newly read line into the result. 700 // Copy the newly read line into the result.
722 memmove(result + offset, line_buf, len); 701 memmove(result + offset, line_buf, len);
723 offset += len; 702 offset += len;
724 } 703 }
725 ASSERT(result != NULL); 704 ASSERT(result != NULL);
726 result[offset] = '\0'; 705 result[offset] = '\0';
727 return result; 706 return result;
728 } 707 }
729 708
730
731 // Synchronization primitives support. 709 // Synchronization primitives support.
732 Mutex* Simulator::exclusive_access_lock_ = NULL; 710 Mutex* Simulator::exclusive_access_lock_ = NULL;
733 Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags] = { 711 Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags] = {
734 {NULL, 0}}; 712 {NULL, 0}};
735 int Simulator::next_address_tag_ = 0; 713 int Simulator::next_address_tag_ = 0;
736 714
737
738 void Simulator::InitOnce() { 715 void Simulator::InitOnce() {
739 // Setup exclusive access state lock. 716 // Setup exclusive access state lock.
740 exclusive_access_lock_ = new Mutex(); 717 exclusive_access_lock_ = new Mutex();
741 } 718 }
742 719
743
744 Simulator::Simulator() { 720 Simulator::Simulator() {
745 // Setup simulator support first. Some of this information is needed to 721 // Setup simulator support first. Some of this information is needed to
746 // setup the architecture state. 722 // setup the architecture state.
747 // We allocate the stack here, the size is computed as the sum of 723 // We allocate the stack here, the size is computed as the sum of
748 // the size specified by the user and the buffer space needed for 724 // the size specified by the user and the buffer space needed for
749 // handling stack overflow exceptions. To be safe in potential 725 // handling stack overflow exceptions. To be safe in potential
750 // stack underflows we also add some underflow buffer space. 726 // stack underflows we also add some underflow buffer space.
751 stack_ = 727 stack_ =
752 new char[(OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer + 728 new char[(OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer +
753 kSimulatorStackUnderflowSize)]; 729 kSimulatorStackUnderflowSize)];
(...skipping 21 matching lines...) Expand all
775 751
776 // The sp is initialized to point to the bottom (high address) of the 752 // The sp is initialized to point to the bottom (high address) of the
777 // allocated stack area. 753 // allocated stack area.
778 registers_[R31] = StackTop(); 754 registers_[R31] = StackTop();
779 // The lr and pc are initialized to a known bad value that will cause an 755 // The lr and pc are initialized to a known bad value that will cause an
780 // access violation if the simulator ever tries to execute it. 756 // access violation if the simulator ever tries to execute it.
781 registers_[LR] = kBadLR; 757 registers_[LR] = kBadLR;
782 pc_ = kBadLR; 758 pc_ = kBadLR;
783 } 759 }
784 760
785
786 Simulator::~Simulator() { 761 Simulator::~Simulator() {
787 delete[] stack_; 762 delete[] stack_;
788 Isolate* isolate = Isolate::Current(); 763 Isolate* isolate = Isolate::Current();
789 if (isolate != NULL) { 764 if (isolate != NULL) {
790 isolate->set_simulator(NULL); 765 isolate->set_simulator(NULL);
791 } 766 }
792 } 767 }
793 768
794
795 // When the generated code calls an external reference we need to catch that in 769 // When the generated code calls an external reference we need to catch that in
796 // the simulator. The external reference will be a function compiled for the 770 // the simulator. The external reference will be a function compiled for the
797 // host architecture. We need to call that function instead of trying to 771 // host architecture. We need to call that function instead of trying to
798 // execute it with the simulator. We do that by redirecting the external 772 // execute it with the simulator. We do that by redirecting the external
799 // reference to a svc (supervisor call) instruction that is handled by 773 // reference to a svc (supervisor call) instruction that is handled by
800 // the simulator. We write the original destination of the jump just at a known 774 // the simulator. We write the original destination of the jump just at a known
801 // offset from the svc instruction so the simulator knows what to call. 775 // offset from the svc instruction so the simulator knows what to call.
802 class Redirection { 776 class Redirection {
803 public: 777 public:
804 uword address_of_hlt_instruction() { 778 uword address_of_hlt_instruction() {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 } 834 }
861 835
862 uword external_function_; 836 uword external_function_;
863 Simulator::CallKind call_kind_; 837 Simulator::CallKind call_kind_;
864 int argument_count_; 838 int argument_count_;
865 uint32_t hlt_instruction_; 839 uint32_t hlt_instruction_;
866 Redirection* next_; 840 Redirection* next_;
867 static Redirection* list_; 841 static Redirection* list_;
868 }; 842 };
869 843
870
871 Redirection* Redirection::list_ = NULL; 844 Redirection* Redirection::list_ = NULL;
872 845
873
874 uword Simulator::RedirectExternalReference(uword function, 846 uword Simulator::RedirectExternalReference(uword function,
875 CallKind call_kind, 847 CallKind call_kind,
876 int argument_count) { 848 int argument_count) {
877 Redirection* redirection = 849 Redirection* redirection =
878 Redirection::Get(function, call_kind, argument_count); 850 Redirection::Get(function, call_kind, argument_count);
879 return redirection->address_of_hlt_instruction(); 851 return redirection->address_of_hlt_instruction();
880 } 852 }
881 853
882
883 uword Simulator::FunctionForRedirect(uword redirect) { 854 uword Simulator::FunctionForRedirect(uword redirect) {
884 return Redirection::FunctionForRedirect(redirect); 855 return Redirection::FunctionForRedirect(redirect);
885 } 856 }
886 857
887
888 // Get the active Simulator for the current isolate. 858 // Get the active Simulator for the current isolate.
889 Simulator* Simulator::Current() { 859 Simulator* Simulator::Current() {
890 Simulator* simulator = Isolate::Current()->simulator(); 860 Simulator* simulator = Isolate::Current()->simulator();
891 if (simulator == NULL) { 861 if (simulator == NULL) {
892 simulator = new Simulator(); 862 simulator = new Simulator();
893 Isolate::Current()->set_simulator(simulator); 863 Isolate::Current()->set_simulator(simulator);
894 } 864 }
895 return simulator; 865 return simulator;
896 } 866 }
897 867
898
899 // Sets the register in the architecture state. 868 // Sets the register in the architecture state.
900 void Simulator::set_register(Instr* instr, 869 void Simulator::set_register(Instr* instr,
901 Register reg, 870 Register reg,
902 int64_t value, 871 int64_t value,
903 R31Type r31t) { 872 R31Type r31t) {
904 // Register is in range. 873 // Register is in range.
905 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 874 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
906 ASSERT(instr == NULL || reg != R18); // R18 is globally reserved on iOS. 875 ASSERT(instr == NULL || reg != R18); // R18 is globally reserved on iOS.
907 if ((reg != R31) || (r31t != R31IsZR)) { 876 if ((reg != R31) || (r31t != R31IsZR)) {
908 registers_[reg] = value; 877 registers_[reg] = value;
909 // If we're setting CSP, make sure it is 16-byte aligned. In truth, CSP 878 // If we're setting CSP, make sure it is 16-byte aligned. In truth, CSP
910 // can store addresses that are not 16-byte aligned, but loads and stores 879 // can store addresses that are not 16-byte aligned, but loads and stores
911 // are not allowed through CSP when it is not aligned. Thus, this check is 880 // are not allowed through CSP when it is not aligned. Thus, this check is
912 // more conservative that necessary. However, it will likely be more 881 // more conservative that necessary. However, it will likely be more
913 // useful to find the program locations where CSP is set to a bad value, 882 // useful to find the program locations where CSP is set to a bad value,
914 // than to find only the resulting loads/stores that would cause a fault on 883 // than to find only the resulting loads/stores that would cause a fault on
915 // hardware. 884 // hardware.
916 if ((instr != NULL) && (reg == R31) && !Utils::IsAligned(value, 16)) { 885 if ((instr != NULL) && (reg == R31) && !Utils::IsAligned(value, 16)) {
917 UnalignedAccess("CSP set", value, instr); 886 UnalignedAccess("CSP set", value, instr);
918 } 887 }
919 } 888 }
920 } 889 }
921 890
922
923 // Get the register from the architecture state. 891 // Get the register from the architecture state.
924 int64_t Simulator::get_register(Register reg, R31Type r31t) const { 892 int64_t Simulator::get_register(Register reg, R31Type r31t) const {
925 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 893 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
926 if ((reg == R31) && (r31t == R31IsZR)) { 894 if ((reg == R31) && (r31t == R31IsZR)) {
927 return 0; 895 return 0;
928 } else { 896 } else {
929 return registers_[reg]; 897 return registers_[reg];
930 } 898 }
931 } 899 }
932 900
933
934 void Simulator::set_wregister(Register reg, int32_t value, R31Type r31t) { 901 void Simulator::set_wregister(Register reg, int32_t value, R31Type r31t) {
935 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 902 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
936 // When setting in W mode, clear the high bits. 903 // When setting in W mode, clear the high bits.
937 if ((reg != R31) || (r31t != R31IsZR)) { 904 if ((reg != R31) || (r31t != R31IsZR)) {
938 registers_[reg] = Utils::LowHighTo64Bits(static_cast<uint32_t>(value), 0); 905 registers_[reg] = Utils::LowHighTo64Bits(static_cast<uint32_t>(value), 0);
939 } 906 }
940 } 907 }
941 908
942
943 // Get the register from the architecture state. 909 // Get the register from the architecture state.
944 int32_t Simulator::get_wregister(Register reg, R31Type r31t) const { 910 int32_t Simulator::get_wregister(Register reg, R31Type r31t) const {
945 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 911 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
946 if ((reg == R31) && (r31t == R31IsZR)) { 912 if ((reg == R31) && (r31t == R31IsZR)) {
947 return 0; 913 return 0;
948 } else { 914 } else {
949 return static_cast<int32_t>(registers_[reg]); 915 return static_cast<int32_t>(registers_[reg]);
950 } 916 }
951 } 917 }
952 918
953
954 int32_t Simulator::get_vregisters(VRegister reg, int idx) const { 919 int32_t Simulator::get_vregisters(VRegister reg, int idx) const {
955 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); 920 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
956 ASSERT((idx >= 0) && (idx <= 3)); 921 ASSERT((idx >= 0) && (idx <= 3));
957 return vregisters_[reg].bits.i32[idx]; 922 return vregisters_[reg].bits.i32[idx];
958 } 923 }
959 924
960
961 void Simulator::set_vregisters(VRegister reg, int idx, int32_t value) { 925 void Simulator::set_vregisters(VRegister reg, int idx, int32_t value) {
962 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); 926 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
963 ASSERT((idx >= 0) && (idx <= 3)); 927 ASSERT((idx >= 0) && (idx <= 3));
964 vregisters_[reg].bits.i32[idx] = value; 928 vregisters_[reg].bits.i32[idx] = value;
965 } 929 }
966 930
967
968 int64_t Simulator::get_vregisterd(VRegister reg, int idx) const { 931 int64_t Simulator::get_vregisterd(VRegister reg, int idx) const {
969 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); 932 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
970 ASSERT((idx == 0) || (idx == 1)); 933 ASSERT((idx == 0) || (idx == 1));
971 return vregisters_[reg].bits.i64[idx]; 934 return vregisters_[reg].bits.i64[idx];
972 } 935 }
973 936
974
975 void Simulator::set_vregisterd(VRegister reg, int idx, int64_t value) { 937 void Simulator::set_vregisterd(VRegister reg, int idx, int64_t value) {
976 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); 938 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
977 ASSERT((idx == 0) || (idx == 1)); 939 ASSERT((idx == 0) || (idx == 1));
978 vregisters_[reg].bits.i64[idx] = value; 940 vregisters_[reg].bits.i64[idx] = value;
979 } 941 }
980 942
981
982 void Simulator::get_vregister(VRegister reg, simd_value_t* value) const { 943 void Simulator::get_vregister(VRegister reg, simd_value_t* value) const {
983 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); 944 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
984 value->bits.i64[0] = vregisters_[reg].bits.i64[0]; 945 value->bits.i64[0] = vregisters_[reg].bits.i64[0];
985 value->bits.i64[1] = vregisters_[reg].bits.i64[1]; 946 value->bits.i64[1] = vregisters_[reg].bits.i64[1];
986 } 947 }
987 948
988
989 void Simulator::set_vregister(VRegister reg, const simd_value_t& value) { 949 void Simulator::set_vregister(VRegister reg, const simd_value_t& value) {
990 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); 950 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
991 vregisters_[reg].bits.i64[0] = value.bits.i64[0]; 951 vregisters_[reg].bits.i64[0] = value.bits.i64[0];
992 vregisters_[reg].bits.i64[1] = value.bits.i64[1]; 952 vregisters_[reg].bits.i64[1] = value.bits.i64[1];
993 } 953 }
994 954
995
996 // Raw access to the PC register. 955 // Raw access to the PC register.
997 void Simulator::set_pc(int64_t value) { 956 void Simulator::set_pc(int64_t value) {
998 pc_modified_ = true; 957 pc_modified_ = true;
999 last_pc_ = pc_; 958 last_pc_ = pc_;
1000 pc_ = value; 959 pc_ = value;
1001 } 960 }
1002 961
1003
1004 // Raw access to the pc. 962 // Raw access to the pc.
1005 int64_t Simulator::get_pc() const { 963 int64_t Simulator::get_pc() const {
1006 return pc_; 964 return pc_;
1007 } 965 }
1008 966
1009
1010 int64_t Simulator::get_last_pc() const { 967 int64_t Simulator::get_last_pc() const {
1011 return last_pc_; 968 return last_pc_;
1012 } 969 }
1013 970
1014
1015 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { 971 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) {
1016 uword fault_pc = get_pc(); 972 uword fault_pc = get_pc();
1017 uword last_pc = get_last_pc(); 973 uword last_pc = get_last_pc();
1018 char buffer[128]; 974 char buffer[128];
1019 snprintf(buffer, sizeof(buffer), "illegal memory access at 0x%" Px 975 snprintf(buffer, sizeof(buffer),
1020 ", pc=0x%" Px ", last_pc=0x%" Px "\n", 976 "illegal memory access at 0x%" Px ", pc=0x%" Px ", last_pc=0x%" Px
977 "\n",
1021 addr, fault_pc, last_pc); 978 addr, fault_pc, last_pc);
1022 SimulatorDebugger dbg(this); 979 SimulatorDebugger dbg(this);
1023 dbg.Stop(instr, buffer); 980 dbg.Stop(instr, buffer);
1024 // The debugger will return control in non-interactive mode. 981 // The debugger will return control in non-interactive mode.
1025 FATAL("Cannot continue execution after illegal memory access."); 982 FATAL("Cannot continue execution after illegal memory access.");
1026 } 983 }
1027 984
1028
1029 // The ARMv8 manual advises that an unaligned access may generate a fault, 985 // The ARMv8 manual advises that an unaligned access may generate a fault,
1030 // and if not, will likely take a number of additional cycles to execute, 986 // and if not, will likely take a number of additional cycles to execute,
1031 // so let's just not generate any. 987 // so let's just not generate any.
1032 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) { 988 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) {
1033 char buffer[128]; 989 char buffer[128];
1034 snprintf(buffer, sizeof(buffer), "unaligned %s at 0x%" Px ", pc=%p\n", msg, 990 snprintf(buffer, sizeof(buffer), "unaligned %s at 0x%" Px ", pc=%p\n", msg,
1035 addr, instr); 991 addr, instr);
1036 SimulatorDebugger dbg(this); 992 SimulatorDebugger dbg(this);
1037 dbg.Stop(instr, buffer); 993 dbg.Stop(instr, buffer);
1038 // The debugger will not be able to single step past this instruction, but 994 // The debugger will not be able to single step past this instruction, but
1039 // it will be possible to disassemble the code and inspect registers. 995 // it will be possible to disassemble the code and inspect registers.
1040 FATAL("Cannot continue execution after unaligned access."); 996 FATAL("Cannot continue execution after unaligned access.");
1041 } 997 }
1042 998
1043
1044 void Simulator::UnimplementedInstruction(Instr* instr) { 999 void Simulator::UnimplementedInstruction(Instr* instr) {
1045 char buffer[128]; 1000 char buffer[128];
1046 snprintf(buffer, sizeof(buffer), 1001 snprintf(buffer, sizeof(buffer),
1047 "Unimplemented instruction: at %p, last_pc=0x%" Px64 "\n", instr, 1002 "Unimplemented instruction: at %p, last_pc=0x%" Px64 "\n", instr,
1048 get_last_pc()); 1003 get_last_pc());
1049 SimulatorDebugger dbg(this); 1004 SimulatorDebugger dbg(this);
1050 dbg.Stop(instr, buffer); 1005 dbg.Stop(instr, buffer);
1051 FATAL("Cannot continue execution after unimplemented instruction."); 1006 FATAL("Cannot continue execution after unimplemented instruction.");
1052 } 1007 }
1053 1008
1054
1055 // Returns the top of the stack area to enable checking for stack pointer 1009 // Returns the top of the stack area to enable checking for stack pointer
1056 // validity. 1010 // validity.
1057 uword Simulator::StackTop() const { 1011 uword Simulator::StackTop() const {
1058 // To be safe in potential stack underflows we leave some buffer above and 1012 // To be safe in potential stack underflows we leave some buffer above and
1059 // set the stack top. 1013 // set the stack top.
1060 return StackBase() + 1014 return StackBase() +
1061 (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer); 1015 (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer);
1062 } 1016 }
1063 1017
1064
1065 bool Simulator::IsTracingExecution() const { 1018 bool Simulator::IsTracingExecution() const {
1066 return icount_ > FLAG_trace_sim_after; 1019 return icount_ > FLAG_trace_sim_after;
1067 } 1020 }
1068 1021
1069
1070 intptr_t Simulator::ReadX(uword addr, Instr* instr) { 1022 intptr_t Simulator::ReadX(uword addr, Instr* instr) {
1071 if ((addr & 7) == 0) { 1023 if ((addr & 7) == 0) {
1072 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1024 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1073 return *ptr; 1025 return *ptr;
1074 } 1026 }
1075 UnalignedAccess("read", addr, instr); 1027 UnalignedAccess("read", addr, instr);
1076 return 0; 1028 return 0;
1077 } 1029 }
1078 1030
1079
1080 void Simulator::WriteX(uword addr, intptr_t value, Instr* instr) { 1031 void Simulator::WriteX(uword addr, intptr_t value, Instr* instr) {
1081 if ((addr & 7) == 0) { 1032 if ((addr & 7) == 0) {
1082 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1033 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1083 *ptr = value; 1034 *ptr = value;
1084 return; 1035 return;
1085 } 1036 }
1086 UnalignedAccess("write", addr, instr); 1037 UnalignedAccess("write", addr, instr);
1087 } 1038 }
1088 1039
1089
1090 uint32_t Simulator::ReadWU(uword addr, Instr* instr) { 1040 uint32_t Simulator::ReadWU(uword addr, Instr* instr) {
1091 if ((addr & 3) == 0) { 1041 if ((addr & 3) == 0) {
1092 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); 1042 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
1093 return *ptr; 1043 return *ptr;
1094 } 1044 }
1095 UnalignedAccess("read unsigned single word", addr, instr); 1045 UnalignedAccess("read unsigned single word", addr, instr);
1096 return 0; 1046 return 0;
1097 } 1047 }
1098 1048
1099
1100 int32_t Simulator::ReadW(uword addr, Instr* instr) { 1049 int32_t Simulator::ReadW(uword addr, Instr* instr) {
1101 if ((addr & 3) == 0) { 1050 if ((addr & 3) == 0) {
1102 int32_t* ptr = reinterpret_cast<int32_t*>(addr); 1051 int32_t* ptr = reinterpret_cast<int32_t*>(addr);
1103 return *ptr; 1052 return *ptr;
1104 } 1053 }
1105 UnalignedAccess("read single word", addr, instr); 1054 UnalignedAccess("read single word", addr, instr);
1106 return 0; 1055 return 0;
1107 } 1056 }
1108 1057
1109
1110 void Simulator::WriteW(uword addr, uint32_t value, Instr* instr) { 1058 void Simulator::WriteW(uword addr, uint32_t value, Instr* instr) {
1111 if ((addr & 3) == 0) { 1059 if ((addr & 3) == 0) {
1112 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); 1060 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
1113 *ptr = value; 1061 *ptr = value;
1114 return; 1062 return;
1115 } 1063 }
1116 UnalignedAccess("write single word", addr, instr); 1064 UnalignedAccess("write single word", addr, instr);
1117 } 1065 }
1118 1066
1119
1120 uint16_t Simulator::ReadHU(uword addr, Instr* instr) { 1067 uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
1121 if ((addr & 1) == 0) { 1068 if ((addr & 1) == 0) {
1122 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1069 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1123 return *ptr; 1070 return *ptr;
1124 } 1071 }
1125 UnalignedAccess("unsigned halfword read", addr, instr); 1072 UnalignedAccess("unsigned halfword read", addr, instr);
1126 return 0; 1073 return 0;
1127 } 1074 }
1128 1075
1129
1130 int16_t Simulator::ReadH(uword addr, Instr* instr) { 1076 int16_t Simulator::ReadH(uword addr, Instr* instr) {
1131 if ((addr & 1) == 0) { 1077 if ((addr & 1) == 0) {
1132 int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1078 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1133 return *ptr; 1079 return *ptr;
1134 } 1080 }
1135 UnalignedAccess("signed halfword read", addr, instr); 1081 UnalignedAccess("signed halfword read", addr, instr);
1136 return 0; 1082 return 0;
1137 } 1083 }
1138 1084
1139
1140 void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) { 1085 void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) {
1141 if ((addr & 1) == 0) { 1086 if ((addr & 1) == 0) {
1142 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1087 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1143 *ptr = value; 1088 *ptr = value;
1144 return; 1089 return;
1145 } 1090 }
1146 UnalignedAccess("halfword write", addr, instr); 1091 UnalignedAccess("halfword write", addr, instr);
1147 } 1092 }
1148 1093
1149
1150 uint8_t Simulator::ReadBU(uword addr) { 1094 uint8_t Simulator::ReadBU(uword addr) {
1151 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1095 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1152 return *ptr; 1096 return *ptr;
1153 } 1097 }
1154 1098
1155
1156 int8_t Simulator::ReadB(uword addr) { 1099 int8_t Simulator::ReadB(uword addr) {
1157 int8_t* ptr = reinterpret_cast<int8_t*>(addr); 1100 int8_t* ptr = reinterpret_cast<int8_t*>(addr);
1158 return *ptr; 1101 return *ptr;
1159 } 1102 }
1160 1103
1161
1162 void Simulator::WriteB(uword addr, uint8_t value) { 1104 void Simulator::WriteB(uword addr, uint8_t value) {
1163 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1105 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1164 *ptr = value; 1106 *ptr = value;
1165 } 1107 }
1166 1108
1167
1168 // Synchronization primitives support. 1109 // Synchronization primitives support.
1169 void Simulator::SetExclusiveAccess(uword addr) { 1110 void Simulator::SetExclusiveAccess(uword addr) {
1170 Thread* thread = Thread::Current(); 1111 Thread* thread = Thread::Current();
1171 ASSERT(thread != NULL); 1112 ASSERT(thread != NULL);
1172 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); 1113 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread());
1173 int i = 0; 1114 int i = 0;
1174 // Find an entry for this thread in the exclusive access state. 1115 // Find an entry for this thread in the exclusive access state.
1175 while ((i < kNumAddressTags) && 1116 while ((i < kNumAddressTags) &&
1176 (exclusive_access_state_[i].thread != thread)) { 1117 (exclusive_access_state_[i].thread != thread)) {
1177 i++; 1118 i++;
1178 } 1119 }
1179 // Round-robin replacement of previously used entries. 1120 // Round-robin replacement of previously used entries.
1180 if (i == kNumAddressTags) { 1121 if (i == kNumAddressTags) {
1181 i = next_address_tag_; 1122 i = next_address_tag_;
1182 if (++next_address_tag_ == kNumAddressTags) { 1123 if (++next_address_tag_ == kNumAddressTags) {
1183 next_address_tag_ = 0; 1124 next_address_tag_ = 0;
1184 } 1125 }
1185 exclusive_access_state_[i].thread = thread; 1126 exclusive_access_state_[i].thread = thread;
1186 } 1127 }
1187 // Remember the address being reserved. 1128 // Remember the address being reserved.
1188 exclusive_access_state_[i].addr = addr; 1129 exclusive_access_state_[i].addr = addr;
1189 } 1130 }
1190 1131
1191
1192 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { 1132 bool Simulator::HasExclusiveAccessAndOpen(uword addr) {
1193 Thread* thread = Thread::Current(); 1133 Thread* thread = Thread::Current();
1194 ASSERT(thread != NULL); 1134 ASSERT(thread != NULL);
1195 ASSERT(addr != 0); 1135 ASSERT(addr != 0);
1196 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); 1136 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread());
1197 bool result = false; 1137 bool result = false;
1198 for (int i = 0; i < kNumAddressTags; i++) { 1138 for (int i = 0; i < kNumAddressTags; i++) {
1199 if (exclusive_access_state_[i].thread == thread) { 1139 if (exclusive_access_state_[i].thread == thread) {
1200 // Check whether the current threads address reservation matches. 1140 // Check whether the current threads address reservation matches.
1201 if (exclusive_access_state_[i].addr == addr) { 1141 if (exclusive_access_state_[i].addr == addr) {
1202 result = true; 1142 result = true;
1203 } 1143 }
1204 exclusive_access_state_[i].addr = 0; 1144 exclusive_access_state_[i].addr = 0;
1205 } else if (exclusive_access_state_[i].addr == addr) { 1145 } else if (exclusive_access_state_[i].addr == addr) {
1206 // Other threads with matching address lose their reservations. 1146 // Other threads with matching address lose their reservations.
1207 exclusive_access_state_[i].addr = 0; 1147 exclusive_access_state_[i].addr = 0;
1208 } 1148 }
1209 } 1149 }
1210 return result; 1150 return result;
1211 } 1151 }
1212 1152
1213
1214 void Simulator::ClearExclusive() { 1153 void Simulator::ClearExclusive() {
1215 MutexLocker ml(exclusive_access_lock_); 1154 MutexLocker ml(exclusive_access_lock_);
1216 // Remove the reservation for this thread. 1155 // Remove the reservation for this thread.
1217 SetExclusiveAccess(0); 1156 SetExclusiveAccess(0);
1218 } 1157 }
1219 1158
1220
1221 intptr_t Simulator::ReadExclusiveX(uword addr, Instr* instr) { 1159 intptr_t Simulator::ReadExclusiveX(uword addr, Instr* instr) {
1222 MutexLocker ml(exclusive_access_lock_); 1160 MutexLocker ml(exclusive_access_lock_);
1223 SetExclusiveAccess(addr); 1161 SetExclusiveAccess(addr);
1224 return ReadX(addr, instr); 1162 return ReadX(addr, instr);
1225 } 1163 }
1226 1164
1227
1228 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) { 1165 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) {
1229 MutexLocker ml(exclusive_access_lock_); 1166 MutexLocker ml(exclusive_access_lock_);
1230 SetExclusiveAccess(addr); 1167 SetExclusiveAccess(addr);
1231 return ReadWU(addr, instr); 1168 return ReadWU(addr, instr);
1232 } 1169 }
1233 1170
1234
1235 intptr_t Simulator::WriteExclusiveX(uword addr, intptr_t value, Instr* instr) { 1171 intptr_t Simulator::WriteExclusiveX(uword addr, intptr_t value, Instr* instr) {
1236 MutexLocker ml(exclusive_access_lock_); 1172 MutexLocker ml(exclusive_access_lock_);
1237 bool write_allowed = HasExclusiveAccessAndOpen(addr); 1173 bool write_allowed = HasExclusiveAccessAndOpen(addr);
1238 if (write_allowed) { 1174 if (write_allowed) {
1239 WriteX(addr, value, instr); 1175 WriteX(addr, value, instr);
1240 return 0; // Success. 1176 return 0; // Success.
1241 } 1177 }
1242 return 1; // Failure. 1178 return 1; // Failure.
1243 } 1179 }
1244 1180
1245
1246 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) { 1181 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) {
1247 MutexLocker ml(exclusive_access_lock_); 1182 MutexLocker ml(exclusive_access_lock_);
1248 bool write_allowed = HasExclusiveAccessAndOpen(addr); 1183 bool write_allowed = HasExclusiveAccessAndOpen(addr);
1249 if (write_allowed) { 1184 if (write_allowed) {
1250 WriteW(addr, value, instr); 1185 WriteW(addr, value, instr);
1251 return 0; // Success. 1186 return 0; // Success.
1252 } 1187 }
1253 return 1; // Failure. 1188 return 1; // Failure.
1254 } 1189 }
1255 1190
1256
1257 uword Simulator::CompareExchange(uword* address, 1191 uword Simulator::CompareExchange(uword* address,
1258 uword compare_value, 1192 uword compare_value,
1259 uword new_value) { 1193 uword new_value) {
1260 MutexLocker ml(exclusive_access_lock_); 1194 MutexLocker ml(exclusive_access_lock_);
1261 // We do not get a reservation as it would be guaranteed to be found when 1195 // We do not get a reservation as it would be guaranteed to be found when
1262 // writing below. No other thread is able to make a reservation while we 1196 // writing below. No other thread is able to make a reservation while we
1263 // hold the lock. 1197 // hold the lock.
1264 uword value = *address; 1198 uword value = *address;
1265 if (value == compare_value) { 1199 if (value == compare_value) {
1266 *address = new_value; 1200 *address = new_value;
1267 // Same effect on exclusive access state as a successful STREX. 1201 // Same effect on exclusive access state as a successful STREX.
1268 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address)); 1202 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address));
1269 } else { 1203 } else {
1270 // Same effect on exclusive access state as an LDREX. 1204 // Same effect on exclusive access state as an LDREX.
1271 SetExclusiveAccess(reinterpret_cast<uword>(address)); 1205 SetExclusiveAccess(reinterpret_cast<uword>(address));
1272 } 1206 }
1273 return value; 1207 return value;
1274 } 1208 }
1275 1209
1276
1277 uint32_t Simulator::CompareExchangeUint32(uint32_t* address, 1210 uint32_t Simulator::CompareExchangeUint32(uint32_t* address,
1278 uint32_t compare_value, 1211 uint32_t compare_value,
1279 uint32_t new_value) { 1212 uint32_t new_value) {
1280 MutexLocker ml(exclusive_access_lock_); 1213 MutexLocker ml(exclusive_access_lock_);
1281 // We do not get a reservation as it would be guaranteed to be found when 1214 // We do not get a reservation as it would be guaranteed to be found when
1282 // writing below. No other thread is able to make a reservation while we 1215 // writing below. No other thread is able to make a reservation while we
1283 // hold the lock. 1216 // hold the lock.
1284 uint32_t value = *address; 1217 uint32_t value = *address;
1285 if (value == compare_value) { 1218 if (value == compare_value) {
1286 *address = new_value; 1219 *address = new_value;
1287 // Same effect on exclusive access state as a successful STREX. 1220 // Same effect on exclusive access state as a successful STREX.
1288 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address)); 1221 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address));
1289 } else { 1222 } else {
1290 // Same effect on exclusive access state as an LDREX. 1223 // Same effect on exclusive access state as an LDREX.
1291 SetExclusiveAccess(reinterpret_cast<uword>(address)); 1224 SetExclusiveAccess(reinterpret_cast<uword>(address));
1292 } 1225 }
1293 return value; 1226 return value;
1294 } 1227 }
1295 1228
1296
1297 // Unsupported instructions use Format to print an error and stop execution. 1229 // Unsupported instructions use Format to print an error and stop execution.
1298 void Simulator::Format(Instr* instr, const char* format) { 1230 void Simulator::Format(Instr* instr, const char* format) {
1299 OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n", instr, 1231 OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n", instr,
1300 format); 1232 format);
1301 UNIMPLEMENTED(); 1233 UNIMPLEMENTED();
1302 } 1234 }
1303 1235
1304
1305 // Calculate and set the Negative and Zero flags. 1236 // Calculate and set the Negative and Zero flags.
1306 void Simulator::SetNZFlagsW(int32_t val) { 1237 void Simulator::SetNZFlagsW(int32_t val) {
1307 n_flag_ = (val < 0); 1238 n_flag_ = (val < 0);
1308 z_flag_ = (val == 0); 1239 z_flag_ = (val == 0);
1309 } 1240 }
1310 1241
1311
1312 // Calculate C flag value for additions (and subtractions with adjusted args). 1242 // Calculate C flag value for additions (and subtractions with adjusted args).
1313 bool Simulator::CarryFromW(int32_t left, int32_t right, int32_t carry) { 1243 bool Simulator::CarryFromW(int32_t left, int32_t right, int32_t carry) {
1314 uint64_t uleft = static_cast<uint32_t>(left); 1244 uint64_t uleft = static_cast<uint32_t>(left);
1315 uint64_t uright = static_cast<uint32_t>(right); 1245 uint64_t uright = static_cast<uint32_t>(right);
1316 uint64_t ucarry = static_cast<uint32_t>(carry); 1246 uint64_t ucarry = static_cast<uint32_t>(carry);
1317 return ((uleft + uright + ucarry) >> 32) != 0; 1247 return ((uleft + uright + ucarry) >> 32) != 0;
1318 } 1248 }
1319 1249
1320
1321 // Calculate V flag value for additions (and subtractions with adjusted args). 1250 // Calculate V flag value for additions (and subtractions with adjusted args).
1322 bool Simulator::OverflowFromW(int32_t left, int32_t right, int32_t carry) { 1251 bool Simulator::OverflowFromW(int32_t left, int32_t right, int32_t carry) {
1323 int64_t result = static_cast<int64_t>(left) + right + carry; 1252 int64_t result = static_cast<int64_t>(left) + right + carry;
1324 return (result >> 31) != (result >> 32); 1253 return (result >> 31) != (result >> 32);
1325 } 1254 }
1326 1255
1327
1328 // Calculate and set the Negative and Zero flags. 1256 // Calculate and set the Negative and Zero flags.
1329 void Simulator::SetNZFlagsX(int64_t val) { 1257 void Simulator::SetNZFlagsX(int64_t val) {
1330 n_flag_ = (val < 0); 1258 n_flag_ = (val < 0);
1331 z_flag_ = (val == 0); 1259 z_flag_ = (val == 0);
1332 } 1260 }
1333 1261
1334
1335 // Calculate C flag value for additions and subtractions. 1262 // Calculate C flag value for additions and subtractions.
1336 bool Simulator::CarryFromX(int64_t alu_out, 1263 bool Simulator::CarryFromX(int64_t alu_out,
1337 int64_t left, 1264 int64_t left,
1338 int64_t right, 1265 int64_t right,
1339 bool addition) { 1266 bool addition) {
1340 if (addition) { 1267 if (addition) {
1341 return (((left & right) | ((left | right) & ~alu_out)) >> 63) != 0; 1268 return (((left & right) | ((left | right) & ~alu_out)) >> 63) != 0;
1342 } else { 1269 } else {
1343 return (((~left & right) | ((~left | right) & alu_out)) >> 63) == 0; 1270 return (((~left & right) | ((~left | right) & alu_out)) >> 63) == 0;
1344 } 1271 }
1345 } 1272 }
1346 1273
1347
1348 // Calculate V flag value for additions and subtractions. 1274 // Calculate V flag value for additions and subtractions.
1349 bool Simulator::OverflowFromX(int64_t alu_out, 1275 bool Simulator::OverflowFromX(int64_t alu_out,
1350 int64_t left, 1276 int64_t left,
1351 int64_t right, 1277 int64_t right,
1352 bool addition) { 1278 bool addition) {
1353 if (addition) { 1279 if (addition) {
1354 return (((alu_out ^ left) & (alu_out ^ right)) >> 63) != 0; 1280 return (((alu_out ^ left) & (alu_out ^ right)) >> 63) != 0;
1355 } else { 1281 } else {
1356 return (((left ^ right) & (alu_out ^ left)) >> 63) != 0; 1282 return (((left ^ right) & (alu_out ^ left)) >> 63) != 0;
1357 } 1283 }
1358 } 1284 }
1359 1285
1360
1361 // Set the Carry flag. 1286 // Set the Carry flag.
1362 void Simulator::SetCFlag(bool val) { 1287 void Simulator::SetCFlag(bool val) {
1363 c_flag_ = val; 1288 c_flag_ = val;
1364 } 1289 }
1365 1290
1366
1367 // Set the oVerflow flag. 1291 // Set the oVerflow flag.
1368 void Simulator::SetVFlag(bool val) { 1292 void Simulator::SetVFlag(bool val) {
1369 v_flag_ = val; 1293 v_flag_ = val;
1370 } 1294 }
1371 1295
1372
1373 void Simulator::DecodeMoveWide(Instr* instr) { 1296 void Simulator::DecodeMoveWide(Instr* instr) {
1374 const Register rd = instr->RdField(); 1297 const Register rd = instr->RdField();
1375 const int hw = instr->HWField(); 1298 const int hw = instr->HWField();
1376 const int64_t shift = hw << 4; 1299 const int64_t shift = hw << 4;
1377 const int64_t shifted_imm = static_cast<int64_t>(instr->Imm16Field()) 1300 const int64_t shifted_imm = static_cast<int64_t>(instr->Imm16Field())
1378 << shift; 1301 << shift;
1379 1302
1380 if (instr->SFField()) { 1303 if (instr->SFField()) {
1381 if (instr->Bits(29, 2) == 0) { 1304 if (instr->Bits(29, 2) == 0) {
1382 // Format(instr, "movn'sf 'rd, 'imm16 'hw"); 1305 // Format(instr, "movn'sf 'rd, 'imm16 'hw");
(...skipping 23 matching lines...) Expand all
1406 set_wregister(rd, result, instr->RdMode()); 1329 set_wregister(rd, result, instr->RdMode());
1407 } else { 1330 } else {
1408 UnimplementedInstruction(instr); 1331 UnimplementedInstruction(instr);
1409 } 1332 }
1410 } else { 1333 } else {
1411 // Dest is 32 bits, but shift is more than 32. 1334 // Dest is 32 bits, but shift is more than 32.
1412 UnimplementedInstruction(instr); 1335 UnimplementedInstruction(instr);
1413 } 1336 }
1414 } 1337 }
1415 1338
1416
1417 void Simulator::DecodeAddSubImm(Instr* instr) { 1339 void Simulator::DecodeAddSubImm(Instr* instr) {
1418 const bool addition = (instr->Bit(30) == 0); 1340 const bool addition = (instr->Bit(30) == 0);
1419 // Format(instr, "addi'sf's 'rd, 'rn, 'imm12s"); 1341 // Format(instr, "addi'sf's 'rd, 'rn, 'imm12s");
1420 // Format(instr, "subi'sf's 'rd, 'rn, 'imm12s"); 1342 // Format(instr, "subi'sf's 'rd, 'rn, 'imm12s");
1421 const Register rd = instr->RdField(); 1343 const Register rd = instr->RdField();
1422 const Register rn = instr->RnField(); 1344 const Register rn = instr->RnField();
1423 uint32_t imm = (instr->Bit(22) == 1) ? (instr->Imm12Field() << 12) 1345 uint32_t imm = (instr->Bit(22) == 1) ? (instr->Imm12Field() << 12)
1424 : (instr->Imm12Field()); 1346 : (instr->Imm12Field());
1425 if (instr->SFField()) { 1347 if (instr->SFField()) {
1426 // 64-bit add. 1348 // 64-bit add.
(...skipping 16 matching lines...) Expand all
1443 const int32_t alu_out = rn_val + imm + carry_in; 1365 const int32_t alu_out = rn_val + imm + carry_in;
1444 set_wregister(rd, alu_out, instr->RdMode()); 1366 set_wregister(rd, alu_out, instr->RdMode());
1445 if (instr->HasS()) { 1367 if (instr->HasS()) {
1446 SetNZFlagsW(alu_out); 1368 SetNZFlagsW(alu_out);
1447 SetCFlag(CarryFromW(rn_val, imm, carry_in)); 1369 SetCFlag(CarryFromW(rn_val, imm, carry_in));
1448 SetVFlag(OverflowFromW(rn_val, imm, carry_in)); 1370 SetVFlag(OverflowFromW(rn_val, imm, carry_in));
1449 } 1371 }
1450 } 1372 }
1451 } 1373 }
1452 1374
1453
1454 void Simulator::DecodeLogicalImm(Instr* instr) { 1375 void Simulator::DecodeLogicalImm(Instr* instr) {
1455 const int op = instr->Bits(29, 2); 1376 const int op = instr->Bits(29, 2);
1456 const bool set_flags = op == 3; 1377 const bool set_flags = op == 3;
1457 const int out_size = ((instr->SFField() == 0) && (instr->NField() == 0)) 1378 const int out_size = ((instr->SFField() == 0) && (instr->NField() == 0))
1458 ? kWRegSizeInBits 1379 ? kWRegSizeInBits
1459 : kXRegSizeInBits; 1380 : kXRegSizeInBits;
1460 const Register rn = instr->RnField(); 1381 const Register rn = instr->RnField();
1461 const Register rd = instr->RdField(); 1382 const Register rd = instr->RdField();
1462 const int64_t rn_val = get_register(rn, instr->RnMode()); 1383 const int64_t rn_val = get_register(rn, instr->RnMode());
1463 const uint64_t imm = instr->ImmLogical(); 1384 const uint64_t imm = instr->ImmLogical();
(...skipping 30 matching lines...) Expand all
1494 SetVFlag(false); 1415 SetVFlag(false);
1495 } 1416 }
1496 1417
1497 if (out_size == kXRegSizeInBits) { 1418 if (out_size == kXRegSizeInBits) {
1498 set_register(instr, rd, alu_out, instr->RdMode()); 1419 set_register(instr, rd, alu_out, instr->RdMode());
1499 } else { 1420 } else {
1500 set_wregister(rd, alu_out, instr->RdMode()); 1421 set_wregister(rd, alu_out, instr->RdMode());
1501 } 1422 }
1502 } 1423 }
1503 1424
1504
1505 void Simulator::DecodePCRel(Instr* instr) { 1425 void Simulator::DecodePCRel(Instr* instr) {
1506 const int op = instr->Bit(31); 1426 const int op = instr->Bit(31);
1507 if (op == 0) { 1427 if (op == 0) {
1508 // Format(instr, "adr 'rd, 'pcrel") 1428 // Format(instr, "adr 'rd, 'pcrel")
1509 const Register rd = instr->RdField(); 1429 const Register rd = instr->RdField();
1510 const int64_t immhi = instr->SImm19Field(); 1430 const int64_t immhi = instr->SImm19Field();
1511 const int64_t immlo = instr->Bits(29, 2); 1431 const int64_t immlo = instr->Bits(29, 2);
1512 const int64_t off = (immhi << 2) | immlo; 1432 const int64_t off = (immhi << 2) | immlo;
1513 const int64_t dest = get_pc() + off; 1433 const int64_t dest = get_pc() + off;
1514 set_register(instr, rd, dest, instr->RdMode()); 1434 set_register(instr, rd, dest, instr->RdMode());
1515 } else { 1435 } else {
1516 UnimplementedInstruction(instr); 1436 UnimplementedInstruction(instr);
1517 } 1437 }
1518 } 1438 }
1519 1439
1520
1521 void Simulator::DecodeDPImmediate(Instr* instr) { 1440 void Simulator::DecodeDPImmediate(Instr* instr) {
1522 if (instr->IsMoveWideOp()) { 1441 if (instr->IsMoveWideOp()) {
1523 DecodeMoveWide(instr); 1442 DecodeMoveWide(instr);
1524 } else if (instr->IsAddSubImmOp()) { 1443 } else if (instr->IsAddSubImmOp()) {
1525 DecodeAddSubImm(instr); 1444 DecodeAddSubImm(instr);
1526 } else if (instr->IsLogicalImmOp()) { 1445 } else if (instr->IsLogicalImmOp()) {
1527 DecodeLogicalImm(instr); 1446 DecodeLogicalImm(instr);
1528 } else if (instr->IsPCRelOp()) { 1447 } else if (instr->IsPCRelOp()) {
1529 DecodePCRel(instr); 1448 DecodePCRel(instr);
1530 } else { 1449 } else {
1531 UnimplementedInstruction(instr); 1450 UnimplementedInstruction(instr);
1532 } 1451 }
1533 } 1452 }
1534 1453
1535
1536 void Simulator::DecodeCompareAndBranch(Instr* instr) { 1454 void Simulator::DecodeCompareAndBranch(Instr* instr) {
1537 const int op = instr->Bit(24); 1455 const int op = instr->Bit(24);
1538 const Register rt = instr->RtField(); 1456 const Register rt = instr->RtField();
1539 const int64_t imm19 = instr->SImm19Field(); 1457 const int64_t imm19 = instr->SImm19Field();
1540 const int64_t dest = get_pc() + (imm19 << 2); 1458 const int64_t dest = get_pc() + (imm19 << 2);
1541 const int64_t mask = instr->SFField() == 1 ? kXRegMask : kWRegMask; 1459 const int64_t mask = instr->SFField() == 1 ? kXRegMask : kWRegMask;
1542 const int64_t rt_val = get_register(rt, R31IsZR) & mask; 1460 const int64_t rt_val = get_register(rt, R31IsZR) & mask;
1543 if (op == 0) { 1461 if (op == 0) {
1544 // Format(instr, "cbz'sf 'rt, 'dest19"); 1462 // Format(instr, "cbz'sf 'rt, 'dest19");
1545 if (rt_val == 0) { 1463 if (rt_val == 0) {
1546 set_pc(dest); 1464 set_pc(dest);
1547 } 1465 }
1548 } else { 1466 } else {
1549 // Format(instr, "cbnz'sf 'rt, 'dest19"); 1467 // Format(instr, "cbnz'sf 'rt, 'dest19");
1550 if (rt_val != 0) { 1468 if (rt_val != 0) {
1551 set_pc(dest); 1469 set_pc(dest);
1552 } 1470 }
1553 } 1471 }
1554 } 1472 }
1555 1473
1556
1557 bool Simulator::ConditionallyExecute(Instr* instr) { 1474 bool Simulator::ConditionallyExecute(Instr* instr) {
1558 Condition cond; 1475 Condition cond;
1559 if (instr->IsConditionalSelectOp()) { 1476 if (instr->IsConditionalSelectOp()) {
1560 cond = instr->SelectConditionField(); 1477 cond = instr->SelectConditionField();
1561 } else { 1478 } else {
1562 cond = instr->ConditionField(); 1479 cond = instr->ConditionField();
1563 } 1480 }
1564 switch (cond) { 1481 switch (cond) {
1565 case EQ: 1482 case EQ:
1566 return z_flag_; 1483 return z_flag_;
(...skipping 24 matching lines...) Expand all
1591 case LE: 1508 case LE:
1592 return z_flag_ || (n_flag_ != v_flag_); 1509 return z_flag_ || (n_flag_ != v_flag_);
1593 case AL: 1510 case AL:
1594 return true; 1511 return true;
1595 default: 1512 default:
1596 UNREACHABLE(); 1513 UNREACHABLE();
1597 } 1514 }
1598 return false; 1515 return false;
1599 } 1516 }
1600 1517
1601
1602 void Simulator::DecodeConditionalBranch(Instr* instr) { 1518 void Simulator::DecodeConditionalBranch(Instr* instr) {
1603 // Format(instr, "b'cond 'dest19"); 1519 // Format(instr, "b'cond 'dest19");
1604 if ((instr->Bit(24) != 0) || (instr->Bit(4) != 0)) { 1520 if ((instr->Bit(24) != 0) || (instr->Bit(4) != 0)) {
1605 UnimplementedInstruction(instr); 1521 UnimplementedInstruction(instr);
1606 } 1522 }
1607 const int64_t imm19 = instr->SImm19Field(); 1523 const int64_t imm19 = instr->SImm19Field();
1608 const int64_t dest = get_pc() + (imm19 << 2); 1524 const int64_t dest = get_pc() + (imm19 << 2);
1609 if (ConditionallyExecute(instr)) { 1525 if (ConditionallyExecute(instr)) {
1610 set_pc(dest); 1526 set_pc(dest);
1611 } 1527 }
1612 } 1528 }
1613 1529
1614
1615 // Calls into the Dart runtime are based on this interface. 1530 // Calls into the Dart runtime are based on this interface.
1616 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); 1531 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
1617 1532
1618 // Calls to leaf Dart runtime functions are based on this interface. 1533 // Calls to leaf Dart runtime functions are based on this interface.
1619 typedef int64_t (*SimulatorLeafRuntimeCall)(int64_t r0, 1534 typedef int64_t (*SimulatorLeafRuntimeCall)(int64_t r0,
1620 int64_t r1, 1535 int64_t r1,
1621 int64_t r2, 1536 int64_t r2,
1622 int64_t r3, 1537 int64_t r3,
1623 int64_t r4, 1538 int64_t r4,
1624 int64_t r5, 1539 int64_t r5,
1625 int64_t r6, 1540 int64_t r6,
1626 int64_t r7); 1541 int64_t r7);
1627 1542
1628 // Calls to leaf float Dart runtime functions are based on this interface. 1543 // Calls to leaf float Dart runtime functions are based on this interface.
1629 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, 1544 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0,
1630 double d1, 1545 double d1,
1631 double d2, 1546 double d2,
1632 double d3, 1547 double d3,
1633 double d4, 1548 double d4,
1634 double d5, 1549 double d5,
1635 double d6, 1550 double d6,
1636 double d7); 1551 double d7);
1637 1552
1638 // Calls to native Dart functions are based on this interface. 1553 // Calls to native Dart functions are based on this interface.
1639 typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments); 1554 typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments);
1640 typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target); 1555 typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target);
1641 1556
1642
1643 void Simulator::DoRedirectedCall(Instr* instr) { 1557 void Simulator::DoRedirectedCall(Instr* instr) {
1644 SimulatorSetjmpBuffer buffer(this); 1558 SimulatorSetjmpBuffer buffer(this);
1645 if (!setjmp(buffer.buffer_)) { 1559 if (!setjmp(buffer.buffer_)) {
1646 int64_t saved_lr = get_register(LR); 1560 int64_t saved_lr = get_register(LR);
1647 Redirection* redirection = Redirection::FromHltInstruction(instr); 1561 Redirection* redirection = Redirection::FromHltInstruction(instr);
1648 uword external = redirection->external_function(); 1562 uword external = redirection->external_function();
1649 if (IsTracingExecution()) { 1563 if (IsTracingExecution()) {
1650 THR_Print("Call to host function at 0x%" Pd "\n", external); 1564 THR_Print("Call to host function at 0x%" Pd "\n", external);
1651 } 1565 }
1652 1566
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 // TODO(zra): Zap caller-saved fpu registers. 1658 // TODO(zra): Zap caller-saved fpu registers.
1745 1659
1746 // Return. 1660 // Return.
1747 set_pc(saved_lr); 1661 set_pc(saved_lr);
1748 } else { 1662 } else {
1749 // Coming via long jump from a throw. Continue to exception handler. 1663 // Coming via long jump from a throw. Continue to exception handler.
1750 set_top_exit_frame_info(0); 1664 set_top_exit_frame_info(0);
1751 } 1665 }
1752 } 1666 }
1753 1667
1754
1755 void Simulator::DecodeExceptionGen(Instr* instr) { 1668 void Simulator::DecodeExceptionGen(Instr* instr) {
1756 if ((instr->Bits(0, 2) == 1) && (instr->Bits(2, 3) == 0) && 1669 if ((instr->Bits(0, 2) == 1) && (instr->Bits(2, 3) == 0) &&
1757 (instr->Bits(21, 3) == 0)) { 1670 (instr->Bits(21, 3) == 0)) {
1758 // Format(instr, "svc 'imm16"); 1671 // Format(instr, "svc 'imm16");
1759 UnimplementedInstruction(instr); 1672 UnimplementedInstruction(instr);
1760 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) && 1673 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) &&
1761 (instr->Bits(21, 3) == 1)) { 1674 (instr->Bits(21, 3) == 1)) {
1762 // Format(instr, "brk 'imm16"); 1675 // Format(instr, "brk 'imm16");
1763 SimulatorDebugger dbg(this); 1676 SimulatorDebugger dbg(this);
1764 int32_t imm = instr->Imm16Field(); 1677 int32_t imm = instr->Imm16Field();
(...skipping 18 matching lines...) Expand all
1783 } else if (imm == Instr::kSimulatorRedirectCode) { 1696 } else if (imm == Instr::kSimulatorRedirectCode) {
1784 DoRedirectedCall(instr); 1697 DoRedirectedCall(instr);
1785 } else { 1698 } else {
1786 UnimplementedInstruction(instr); 1699 UnimplementedInstruction(instr);
1787 } 1700 }
1788 } else { 1701 } else {
1789 UnimplementedInstruction(instr); 1702 UnimplementedInstruction(instr);
1790 } 1703 }
1791 } 1704 }
1792 1705
1793
1794 void Simulator::DecodeSystem(Instr* instr) { 1706 void Simulator::DecodeSystem(Instr* instr) {
1795 if (instr->InstructionBits() == CLREX) { 1707 if (instr->InstructionBits() == CLREX) {
1796 // Format(instr, "clrex"); 1708 // Format(instr, "clrex");
1797 ClearExclusive(); 1709 ClearExclusive();
1798 return; 1710 return;
1799 } 1711 }
1800 1712
1801 if ((instr->Bits(0, 8) == 0x1f) && (instr->Bits(12, 4) == 2) && 1713 if ((instr->Bits(0, 8) == 0x1f) && (instr->Bits(12, 4) == 2) &&
1802 (instr->Bits(16, 3) == 3) && (instr->Bits(19, 2) == 0) && 1714 (instr->Bits(16, 3) == 3) && (instr->Bits(19, 2) == 0) &&
1803 (instr->Bit(21) == 0)) { 1715 (instr->Bit(21) == 0)) {
1804 if (instr->Bits(8, 4) == 0) { 1716 if (instr->Bits(8, 4) == 0) {
1805 // Format(instr, "nop"); 1717 // Format(instr, "nop");
1806 } else { 1718 } else {
1807 UnimplementedInstruction(instr); 1719 UnimplementedInstruction(instr);
1808 } 1720 }
1809 } else { 1721 } else {
1810 UnimplementedInstruction(instr); 1722 UnimplementedInstruction(instr);
1811 } 1723 }
1812 } 1724 }
1813 1725
1814
1815 void Simulator::DecodeTestAndBranch(Instr* instr) { 1726 void Simulator::DecodeTestAndBranch(Instr* instr) {
1816 const int op = instr->Bit(24); 1727 const int op = instr->Bit(24);
1817 const int bitpos = instr->Bits(19, 4) | (instr->Bit(31) << 5); 1728 const int bitpos = instr->Bits(19, 4) | (instr->Bit(31) << 5);
1818 const int64_t imm14 = instr->SImm14Field(); 1729 const int64_t imm14 = instr->SImm14Field();
1819 const int64_t dest = get_pc() + (imm14 << 2); 1730 const int64_t dest = get_pc() + (imm14 << 2);
1820 const Register rt = instr->RtField(); 1731 const Register rt = instr->RtField();
1821 const int64_t rt_val = get_register(rt, R31IsZR); 1732 const int64_t rt_val = get_register(rt, R31IsZR);
1822 if (op == 0) { 1733 if (op == 0) {
1823 // Format(instr, "tbz'sf 'rt, 'bitpos, 'dest14"); 1734 // Format(instr, "tbz'sf 'rt, 'bitpos, 'dest14");
1824 if ((rt_val & (1 << bitpos)) == 0) { 1735 if ((rt_val & (1 << bitpos)) == 0) {
1825 set_pc(dest); 1736 set_pc(dest);
1826 } 1737 }
1827 } else { 1738 } else {
1828 // Format(instr, "tbnz'sf 'rt, 'bitpos, 'dest14"); 1739 // Format(instr, "tbnz'sf 'rt, 'bitpos, 'dest14");
1829 if ((rt_val & (1 << bitpos)) != 0) { 1740 if ((rt_val & (1 << bitpos)) != 0) {
1830 set_pc(dest); 1741 set_pc(dest);
1831 } 1742 }
1832 } 1743 }
1833 } 1744 }
1834 1745
1835
1836 void Simulator::DecodeUnconditionalBranch(Instr* instr) { 1746 void Simulator::DecodeUnconditionalBranch(Instr* instr) {
1837 const bool link = instr->Bit(31) == 1; 1747 const bool link = instr->Bit(31) == 1;
1838 const int64_t imm26 = instr->SImm26Field(); 1748 const int64_t imm26 = instr->SImm26Field();
1839 const int64_t dest = get_pc() + (imm26 << 2); 1749 const int64_t dest = get_pc() + (imm26 << 2);
1840 const int64_t ret = get_pc() + Instr::kInstrSize; 1750 const int64_t ret = get_pc() + Instr::kInstrSize;
1841 set_pc(dest); 1751 set_pc(dest);
1842 if (link) { 1752 if (link) {
1843 set_register(instr, LR, ret); 1753 set_register(instr, LR, ret);
1844 } 1754 }
1845 } 1755 }
1846 1756
1847
1848 void Simulator::DecodeUnconditionalBranchReg(Instr* instr) { 1757 void Simulator::DecodeUnconditionalBranchReg(Instr* instr) {
1849 if ((instr->Bits(0, 5) == 0) && (instr->Bits(10, 6) == 0) && 1758 if ((instr->Bits(0, 5) == 0) && (instr->Bits(10, 6) == 0) &&
1850 (instr->Bits(16, 5) == 0x1f)) { 1759 (instr->Bits(16, 5) == 0x1f)) {
1851 switch (instr->Bits(21, 4)) { 1760 switch (instr->Bits(21, 4)) {
1852 case 0: { 1761 case 0: {
1853 // Format(instr, "br 'rn"); 1762 // Format(instr, "br 'rn");
1854 const Register rn = instr->RnField(); 1763 const Register rn = instr->RnField();
1855 const int64_t dest = get_register(rn, instr->RnMode()); 1764 const int64_t dest = get_register(rn, instr->RnMode());
1856 set_pc(dest); 1765 set_pc(dest);
1857 break; 1766 break;
(...skipping 16 matching lines...) Expand all
1874 } 1783 }
1875 default: 1784 default:
1876 UnimplementedInstruction(instr); 1785 UnimplementedInstruction(instr);
1877 break; 1786 break;
1878 } 1787 }
1879 } else { 1788 } else {
1880 UnimplementedInstruction(instr); 1789 UnimplementedInstruction(instr);
1881 } 1790 }
1882 } 1791 }
1883 1792
1884
1885 void Simulator::DecodeCompareBranch(Instr* instr) { 1793 void Simulator::DecodeCompareBranch(Instr* instr) {
1886 if (instr->IsCompareAndBranchOp()) { 1794 if (instr->IsCompareAndBranchOp()) {
1887 DecodeCompareAndBranch(instr); 1795 DecodeCompareAndBranch(instr);
1888 } else if (instr->IsConditionalBranchOp()) { 1796 } else if (instr->IsConditionalBranchOp()) {
1889 DecodeConditionalBranch(instr); 1797 DecodeConditionalBranch(instr);
1890 } else if (instr->IsExceptionGenOp()) { 1798 } else if (instr->IsExceptionGenOp()) {
1891 DecodeExceptionGen(instr); 1799 DecodeExceptionGen(instr);
1892 } else if (instr->IsSystemOp()) { 1800 } else if (instr->IsSystemOp()) {
1893 DecodeSystem(instr); 1801 DecodeSystem(instr);
1894 } else if (instr->IsTestAndBranchOp()) { 1802 } else if (instr->IsTestAndBranchOp()) {
1895 DecodeTestAndBranch(instr); 1803 DecodeTestAndBranch(instr);
1896 } else if (instr->IsUnconditionalBranchOp()) { 1804 } else if (instr->IsUnconditionalBranchOp()) {
1897 DecodeUnconditionalBranch(instr); 1805 DecodeUnconditionalBranch(instr);
1898 } else if (instr->IsUnconditionalBranchRegOp()) { 1806 } else if (instr->IsUnconditionalBranchRegOp()) {
1899 DecodeUnconditionalBranchReg(instr); 1807 DecodeUnconditionalBranchReg(instr);
1900 } else { 1808 } else {
1901 UnimplementedInstruction(instr); 1809 UnimplementedInstruction(instr);
1902 } 1810 }
1903 } 1811 }
1904 1812
1905
1906 void Simulator::DecodeLoadStoreReg(Instr* instr) { 1813 void Simulator::DecodeLoadStoreReg(Instr* instr) {
1907 // Calculate the address. 1814 // Calculate the address.
1908 const Register rn = instr->RnField(); 1815 const Register rn = instr->RnField();
1909 const Register rt = instr->RtField(); 1816 const Register rt = instr->RtField();
1910 const VRegister vt = instr->VtField(); 1817 const VRegister vt = instr->VtField();
1911 const int64_t rn_val = get_register(rn, R31IsSP); 1818 const int64_t rn_val = get_register(rn, R31IsSP);
1912 const uint32_t size = (instr->Bit(26) == 1) 1819 const uint32_t size = (instr->Bit(26) == 1)
1913 ? ((instr->Bit(23) << 2) | instr->SzField()) 1820 ? ((instr->Bit(23) << 2) | instr->SzField())
1914 : instr->SzField(); 1821 : instr->SzField();
1915 uword address = 0; 1822 uword address = 0;
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2089 } 1996 }
2090 } 1997 }
2091 } 1998 }
2092 1999
2093 // Do writeback. 2000 // Do writeback.
2094 if (wb) { 2001 if (wb) {
2095 set_register(instr, rn, wb_address, R31IsSP); 2002 set_register(instr, rn, wb_address, R31IsSP);
2096 } 2003 }
2097 } 2004 }
2098 2005
2099
2100 void Simulator::DecodeLoadStoreRegPair(Instr* instr) { 2006 void Simulator::DecodeLoadStoreRegPair(Instr* instr) {
2101 const int32_t opc = instr->Bits(23, 3); 2007 const int32_t opc = instr->Bits(23, 3);
2102 const Register rn = instr->RnField(); 2008 const Register rn = instr->RnField();
2103 const Register rt = instr->RtField(); 2009 const Register rt = instr->RtField();
2104 const Register rt2 = instr->Rt2Field(); 2010 const Register rt2 = instr->Rt2Field();
2105 const int64_t rn_val = get_register(rn, R31IsSP); 2011 const int64_t rn_val = get_register(rn, R31IsSP);
2106 const intptr_t shift = 2 + instr->SFField(); 2012 const intptr_t shift = 2 + instr->SFField();
2107 const intptr_t size = 1 << shift; 2013 const intptr_t size = 1 << shift;
2108 const int32_t offset = (instr->SImm7Field() << shift); 2014 const int32_t offset = (instr->SImm7Field() << shift);
2109 uword address = 0; 2015 uword address = 0;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 WriteW(address + size, val2, instr); 2089 WriteW(address + size, val2, instr);
2184 } 2090 }
2185 } 2091 }
2186 2092
2187 // Do writeback. 2093 // Do writeback.
2188 if (wb) { 2094 if (wb) {
2189 set_register(instr, rn, wb_address, R31IsSP); 2095 set_register(instr, rn, wb_address, R31IsSP);
2190 } 2096 }
2191 } 2097 }
2192 2098
2193
2194 void Simulator::DecodeLoadRegLiteral(Instr* instr) { 2099 void Simulator::DecodeLoadRegLiteral(Instr* instr) {
2195 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || 2100 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) ||
2196 (instr->Bits(24, 3) != 0)) { 2101 (instr->Bits(24, 3) != 0)) {
2197 UnimplementedInstruction(instr); 2102 UnimplementedInstruction(instr);
2198 } 2103 }
2199 2104
2200 const Register rt = instr->RtField(); 2105 const Register rt = instr->RtField();
2201 const int64_t off = instr->SImm19Field() << 2; 2106 const int64_t off = instr->SImm19Field() << 2;
2202 const int64_t pc = reinterpret_cast<int64_t>(instr); 2107 const int64_t pc = reinterpret_cast<int64_t>(instr);
2203 const int64_t address = pc + off; 2108 const int64_t address = pc + off;
2204 const int64_t val = ReadX(address, instr); 2109 const int64_t val = ReadX(address, instr);
2205 if (instr->Bit(30)) { 2110 if (instr->Bit(30)) {
2206 // Format(instr, "ldrx 'rt, 'pcldr"); 2111 // Format(instr, "ldrx 'rt, 'pcldr");
2207 set_register(instr, rt, val, R31IsZR); 2112 set_register(instr, rt, val, R31IsZR);
2208 } else { 2113 } else {
2209 // Format(instr, "ldrw 'rt, 'pcldr"); 2114 // Format(instr, "ldrw 'rt, 'pcldr");
2210 set_wregister(rt, static_cast<int32_t>(val), R31IsZR); 2115 set_wregister(rt, static_cast<int32_t>(val), R31IsZR);
2211 } 2116 }
2212 } 2117 }
2213 2118
2214
2215 void Simulator::DecodeLoadStoreExclusive(Instr* instr) { 2119 void Simulator::DecodeLoadStoreExclusive(Instr* instr) {
2216 if ((instr->Bit(23) != 0) || (instr->Bit(21) != 0) || (instr->Bit(15) != 0)) { 2120 if ((instr->Bit(23) != 0) || (instr->Bit(21) != 0) || (instr->Bit(15) != 0)) {
2217 UNIMPLEMENTED(); 2121 UNIMPLEMENTED();
2218 } 2122 }
2219 const int32_t size = instr->Bits(30, 2); 2123 const int32_t size = instr->Bits(30, 2);
2220 if (size != 3 && size != 2) { 2124 if (size != 3 && size != 2) {
2221 UNIMPLEMENTED(); 2125 UNIMPLEMENTED();
2222 } 2126 }
2223 const Register rs = instr->RsField(); 2127 const Register rs = instr->RsField();
2224 const Register rn = instr->RnField(); 2128 const Register rn = instr->RnField();
(...skipping 19 matching lines...) Expand all
2244 set_register(instr, rs, status, R31IsSP); 2148 set_register(instr, rs, status, R31IsSP);
2245 } else { 2149 } else {
2246 uint32_t value = get_register(rt, R31IsSP); 2150 uint32_t value = get_register(rt, R31IsSP);
2247 uword addr = get_register(rn, R31IsSP); 2151 uword addr = get_register(rn, R31IsSP);
2248 intptr_t status = WriteExclusiveW(addr, value, instr); 2152 intptr_t status = WriteExclusiveW(addr, value, instr);
2249 set_register(instr, rs, status, R31IsSP); 2153 set_register(instr, rs, status, R31IsSP);
2250 } 2154 }
2251 } 2155 }
2252 } 2156 }
2253 2157
2254
2255 void Simulator::DecodeLoadStore(Instr* instr) { 2158 void Simulator::DecodeLoadStore(Instr* instr) {
2256 if (instr->IsLoadStoreRegOp()) { 2159 if (instr->IsLoadStoreRegOp()) {
2257 DecodeLoadStoreReg(instr); 2160 DecodeLoadStoreReg(instr);
2258 } else if (instr->IsLoadStoreRegPairOp()) { 2161 } else if (instr->IsLoadStoreRegPairOp()) {
2259 DecodeLoadStoreRegPair(instr); 2162 DecodeLoadStoreRegPair(instr);
2260 } else if (instr->IsLoadRegLiteralOp()) { 2163 } else if (instr->IsLoadRegLiteralOp()) {
2261 DecodeLoadRegLiteral(instr); 2164 DecodeLoadRegLiteral(instr);
2262 } else if (instr->IsLoadStoreExclusiveOp()) { 2165 } else if (instr->IsLoadStoreExclusiveOp()) {
2263 DecodeLoadStoreExclusive(instr); 2166 DecodeLoadStoreExclusive(instr);
2264 } else { 2167 } else {
2265 UnimplementedInstruction(instr); 2168 UnimplementedInstruction(instr);
2266 } 2169 }
2267 } 2170 }
2268 2171
2269
2270 int64_t Simulator::ShiftOperand(uint8_t reg_size, 2172 int64_t Simulator::ShiftOperand(uint8_t reg_size,
2271 int64_t value, 2173 int64_t value,
2272 Shift shift_type, 2174 Shift shift_type,
2273 uint8_t amount) { 2175 uint8_t amount) {
2274 if (amount == 0) { 2176 if (amount == 0) {
2275 return value; 2177 return value;
2276 } 2178 }
2277 int64_t mask = reg_size == kXRegSizeInBits ? kXRegMask : kWRegMask; 2179 int64_t mask = reg_size == kXRegSizeInBits ? kXRegMask : kWRegMask;
2278 switch (shift_type) { 2180 switch (shift_type) {
2279 case LSL: 2181 case LSL:
(...skipping 14 matching lines...) Expand all
2294 return (static_cast<uint64_t>(value) >> amount) | 2196 return (static_cast<uint64_t>(value) >> amount) |
2295 ((static_cast<uint64_t>(value) & ((1ULL << amount) - 1ULL)) 2197 ((static_cast<uint64_t>(value) & ((1ULL << amount) - 1ULL))
2296 << (reg_size - amount)); 2198 << (reg_size - amount));
2297 } 2199 }
2298 default: 2200 default:
2299 UNIMPLEMENTED(); 2201 UNIMPLEMENTED();
2300 return 0; 2202 return 0;
2301 } 2203 }
2302 } 2204 }
2303 2205
2304
2305 int64_t Simulator::ExtendOperand(uint8_t reg_size, 2206 int64_t Simulator::ExtendOperand(uint8_t reg_size,
2306 int64_t value, 2207 int64_t value,
2307 Extend extend_type, 2208 Extend extend_type,
2308 uint8_t amount) { 2209 uint8_t amount) {
2309 switch (extend_type) { 2210 switch (extend_type) {
2310 case UXTB: 2211 case UXTB:
2311 value &= 0xff; 2212 value &= 0xff;
2312 break; 2213 break;
2313 case UXTH: 2214 case UXTH:
2314 value &= 0xffff; 2215 value &= 0xffff;
(...skipping 14 matching lines...) Expand all
2329 case SXTX: 2230 case SXTX:
2330 break; 2231 break;
2331 default: 2232 default:
2332 UNREACHABLE(); 2233 UNREACHABLE();
2333 break; 2234 break;
2334 } 2235 }
2335 int64_t mask = (reg_size == kXRegSizeInBits) ? kXRegMask : kWRegMask; 2236 int64_t mask = (reg_size == kXRegSizeInBits) ? kXRegMask : kWRegMask;
2336 return (value << amount) & mask; 2237 return (value << amount) & mask;
2337 } 2238 }
2338 2239
2339
2340 int64_t Simulator::DecodeShiftExtendOperand(Instr* instr) { 2240 int64_t Simulator::DecodeShiftExtendOperand(Instr* instr) {
2341 const Register rm = instr->RmField(); 2241 const Register rm = instr->RmField();
2342 const int64_t rm_val = get_register(rm, R31IsZR); 2242 const int64_t rm_val = get_register(rm, R31IsZR);
2343 const uint8_t size = instr->SFField() ? kXRegSizeInBits : kWRegSizeInBits; 2243 const uint8_t size = instr->SFField() ? kXRegSizeInBits : kWRegSizeInBits;
2344 if (instr->IsShift()) { 2244 if (instr->IsShift()) {
2345 const Shift shift_type = instr->ShiftTypeField(); 2245 const Shift shift_type = instr->ShiftTypeField();
2346 const uint8_t shift_amount = instr->Imm6Field(); 2246 const uint8_t shift_amount = instr->Imm6Field();
2347 return ShiftOperand(size, rm_val, shift_type, shift_amount); 2247 return ShiftOperand(size, rm_val, shift_type, shift_amount);
2348 } else { 2248 } else {
2349 ASSERT(instr->IsExtend()); 2249 ASSERT(instr->IsExtend());
2350 const Extend extend_type = instr->ExtendTypeField(); 2250 const Extend extend_type = instr->ExtendTypeField();
2351 const uint8_t shift_amount = instr->Imm3Field(); 2251 const uint8_t shift_amount = instr->Imm3Field();
2352 return ExtendOperand(size, rm_val, extend_type, shift_amount); 2252 return ExtendOperand(size, rm_val, extend_type, shift_amount);
2353 } 2253 }
2354 UNREACHABLE(); 2254 UNREACHABLE();
2355 return -1; 2255 return -1;
2356 } 2256 }
2357 2257
2358
2359 void Simulator::DecodeAddSubShiftExt(Instr* instr) { 2258 void Simulator::DecodeAddSubShiftExt(Instr* instr) {
2360 // Format(instr, "add'sf's 'rd, 'rn, 'shift_op"); 2259 // Format(instr, "add'sf's 'rd, 'rn, 'shift_op");
2361 // also, sub, cmp, etc. 2260 // also, sub, cmp, etc.
2362 const bool addition = (instr->Bit(30) == 0); 2261 const bool addition = (instr->Bit(30) == 0);
2363 const Register rd = instr->RdField(); 2262 const Register rd = instr->RdField();
2364 const Register rn = instr->RnField(); 2263 const Register rn = instr->RnField();
2365 const int64_t rm_val = DecodeShiftExtendOperand(instr); 2264 const int64_t rm_val = DecodeShiftExtendOperand(instr);
2366 if (instr->SFField()) { 2265 if (instr->SFField()) {
2367 // 64-bit add. 2266 // 64-bit add.
2368 const int64_t rn_val = get_register(rn, instr->RnMode()); 2267 const int64_t rn_val = get_register(rn, instr->RnMode());
(...skipping 16 matching lines...) Expand all
2385 const int32_t alu_out = rn_val + rm_val32 + carry_in; 2284 const int32_t alu_out = rn_val + rm_val32 + carry_in;
2386 set_wregister(rd, alu_out, instr->RdMode()); 2285 set_wregister(rd, alu_out, instr->RdMode());
2387 if (instr->HasS()) { 2286 if (instr->HasS()) {
2388 SetNZFlagsW(alu_out); 2287 SetNZFlagsW(alu_out);
2389 SetCFlag(CarryFromW(rn_val, rm_val32, carry_in)); 2288 SetCFlag(CarryFromW(rn_val, rm_val32, carry_in));
2390 SetVFlag(OverflowFromW(rn_val, rm_val32, carry_in)); 2289 SetVFlag(OverflowFromW(rn_val, rm_val32, carry_in));
2391 } 2290 }
2392 } 2291 }
2393 } 2292 }
2394 2293
2395
2396 void Simulator::DecodeAddSubWithCarry(Instr* instr) { 2294 void Simulator::DecodeAddSubWithCarry(Instr* instr) {
2397 // Format(instr, "adc'sf's 'rd, 'rn, 'rm"); 2295 // Format(instr, "adc'sf's 'rd, 'rn, 'rm");
2398 // Format(instr, "sbc'sf's 'rd, 'rn, 'rm"); 2296 // Format(instr, "sbc'sf's 'rd, 'rn, 'rm");
2399 const bool addition = (instr->Bit(30) == 0); 2297 const bool addition = (instr->Bit(30) == 0);
2400 const Register rd = instr->RdField(); 2298 const Register rd = instr->RdField();
2401 const Register rn = instr->RnField(); 2299 const Register rn = instr->RnField();
2402 const Register rm = instr->RmField(); 2300 const Register rm = instr->RmField();
2403 const int64_t rn_val64 = get_register(rn, R31IsZR); 2301 const int64_t rn_val64 = get_register(rn, R31IsZR);
2404 const int32_t rn_val32 = get_wregister(rn, R31IsZR); 2302 const int32_t rn_val32 = get_wregister(rn, R31IsZR);
2405 const int64_t rm_val64 = get_register(rm, R31IsZR); 2303 const int64_t rm_val64 = get_register(rm, R31IsZR);
(...skipping 17 matching lines...) Expand all
2423 const int32_t alu_out = rn_val32 + rm_val32 + carry_in; 2321 const int32_t alu_out = rn_val32 + rm_val32 + carry_in;
2424 set_wregister(rd, alu_out, R31IsZR); 2322 set_wregister(rd, alu_out, R31IsZR);
2425 if (instr->HasS()) { 2323 if (instr->HasS()) {
2426 SetNZFlagsW(alu_out); 2324 SetNZFlagsW(alu_out);
2427 SetCFlag(CarryFromW(rn_val32, rm_val32, carry_in)); 2325 SetCFlag(CarryFromW(rn_val32, rm_val32, carry_in));
2428 SetVFlag(OverflowFromW(rn_val32, rm_val32, carry_in)); 2326 SetVFlag(OverflowFromW(rn_val32, rm_val32, carry_in));
2429 } 2327 }
2430 } 2328 }
2431 } 2329 }
2432 2330
2433
2434 void Simulator::DecodeLogicalShift(Instr* instr) { 2331 void Simulator::DecodeLogicalShift(Instr* instr) {
2435 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21); 2332 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21);
2436 const Register rd = instr->RdField(); 2333 const Register rd = instr->RdField();
2437 const Register rn = instr->RnField(); 2334 const Register rn = instr->RnField();
2438 const int64_t rn_val = get_register(rn, instr->RnMode()); 2335 const int64_t rn_val = get_register(rn, instr->RnMode());
2439 const int64_t rm_val = DecodeShiftExtendOperand(instr); 2336 const int64_t rm_val = DecodeShiftExtendOperand(instr);
2440 int64_t alu_out = 0; 2337 int64_t alu_out = 0;
2441 switch (op) { 2338 switch (op) {
2442 case 0: 2339 case 0:
2443 // Format(instr, "and'sf 'rd, 'rn, 'shift_op"); 2340 // Format(instr, "and'sf 'rd, 'rn, 'shift_op");
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2487 SetVFlag(false); 2384 SetVFlag(false);
2488 } 2385 }
2489 2386
2490 if (instr->SFField() == 1) { 2387 if (instr->SFField() == 1) {
2491 set_register(instr, rd, alu_out, instr->RdMode()); 2388 set_register(instr, rd, alu_out, instr->RdMode());
2492 } else { 2389 } else {
2493 set_wregister(rd, alu_out & kWRegMask, instr->RdMode()); 2390 set_wregister(rd, alu_out & kWRegMask, instr->RdMode());
2494 } 2391 }
2495 } 2392 }
2496 2393
2497
2498 static int64_t divide64(int64_t top, int64_t bottom, bool signd) { 2394 static int64_t divide64(int64_t top, int64_t bottom, bool signd) {
2499 // ARM64 does not trap on integer division by zero. The destination register 2395 // ARM64 does not trap on integer division by zero. The destination register
2500 // is instead set to 0. 2396 // is instead set to 0.
2501 if (bottom == 0) { 2397 if (bottom == 0) {
2502 return 0; 2398 return 0;
2503 } 2399 }
2504 2400
2505 if (signd) { 2401 if (signd) {
2506 // INT_MIN / -1 = INT_MIN. 2402 // INT_MIN / -1 = INT_MIN.
2507 if ((top == static_cast<int64_t>(0x8000000000000000LL)) && 2403 if ((top == static_cast<int64_t>(0x8000000000000000LL)) &&
2508 (bottom == static_cast<int64_t>(0xffffffffffffffffLL))) { 2404 (bottom == static_cast<int64_t>(0xffffffffffffffffLL))) {
2509 return static_cast<int64_t>(0x8000000000000000LL); 2405 return static_cast<int64_t>(0x8000000000000000LL);
2510 } else { 2406 } else {
2511 return top / bottom; 2407 return top / bottom;
2512 } 2408 }
2513 } else { 2409 } else {
2514 const uint64_t utop = static_cast<uint64_t>(top); 2410 const uint64_t utop = static_cast<uint64_t>(top);
2515 const uint64_t ubottom = static_cast<uint64_t>(bottom); 2411 const uint64_t ubottom = static_cast<uint64_t>(bottom);
2516 return static_cast<int64_t>(utop / ubottom); 2412 return static_cast<int64_t>(utop / ubottom);
2517 } 2413 }
2518 } 2414 }
2519 2415
2520
2521 static int32_t divide32(int32_t top, int32_t bottom, bool signd) { 2416 static int32_t divide32(int32_t top, int32_t bottom, bool signd) {
2522 // ARM64 does not trap on integer division by zero. The destination register 2417 // ARM64 does not trap on integer division by zero. The destination register
2523 // is instead set to 0. 2418 // is instead set to 0.
2524 if (bottom == 0) { 2419 if (bottom == 0) {
2525 return 0; 2420 return 0;
2526 } 2421 }
2527 2422
2528 if (signd) { 2423 if (signd) {
2529 // INT_MIN / -1 = INT_MIN. 2424 // INT_MIN / -1 = INT_MIN.
2530 if ((top == static_cast<int32_t>(0x80000000)) && 2425 if ((top == static_cast<int32_t>(0x80000000)) &&
2531 (bottom == static_cast<int32_t>(0xffffffff))) { 2426 (bottom == static_cast<int32_t>(0xffffffff))) {
2532 return static_cast<int32_t>(0x80000000); 2427 return static_cast<int32_t>(0x80000000);
2533 } else { 2428 } else {
2534 return top / bottom; 2429 return top / bottom;
2535 } 2430 }
2536 } else { 2431 } else {
2537 const uint32_t utop = static_cast<uint32_t>(top); 2432 const uint32_t utop = static_cast<uint32_t>(top);
2538 const uint32_t ubottom = static_cast<uint32_t>(bottom); 2433 const uint32_t ubottom = static_cast<uint32_t>(bottom);
2539 return static_cast<int32_t>(utop / ubottom); 2434 return static_cast<int32_t>(utop / ubottom);
2540 } 2435 }
2541 } 2436 }
2542 2437
2543
2544 void Simulator::DecodeMiscDP1Source(Instr* instr) { 2438 void Simulator::DecodeMiscDP1Source(Instr* instr) {
2545 if (instr->Bit(29) != 0) { 2439 if (instr->Bit(29) != 0) {
2546 UnimplementedInstruction(instr); 2440 UnimplementedInstruction(instr);
2547 } 2441 }
2548 2442
2549 const Register rd = instr->RdField(); 2443 const Register rd = instr->RdField();
2550 const Register rn = instr->RnField(); 2444 const Register rn = instr->RnField();
2551 const int op = instr->Bits(10, 10); 2445 const int op = instr->Bits(10, 10);
2552 const int64_t rn_val64 = get_register(rn, R31IsZR); 2446 const int64_t rn_val64 = get_register(rn, R31IsZR);
2553 const int32_t rn_val32 = get_wregister(rn, R31IsZR); 2447 const int32_t rn_val32 = get_wregister(rn, R31IsZR);
(...skipping 16 matching lines...) Expand all
2570 set_wregister(rd, rd_val, R31IsZR); 2464 set_wregister(rd, rd_val, R31IsZR);
2571 } 2465 }
2572 break; 2466 break;
2573 } 2467 }
2574 default: 2468 default:
2575 UnimplementedInstruction(instr); 2469 UnimplementedInstruction(instr);
2576 break; 2470 break;
2577 } 2471 }
2578 } 2472 }
2579 2473
2580
2581 void Simulator::DecodeMiscDP2Source(Instr* instr) { 2474 void Simulator::DecodeMiscDP2Source(Instr* instr) {
2582 if (instr->Bit(29) != 0) { 2475 if (instr->Bit(29) != 0) {
2583 UnimplementedInstruction(instr); 2476 UnimplementedInstruction(instr);
2584 } 2477 }
2585 2478
2586 const Register rd = instr->RdField(); 2479 const Register rd = instr->RdField();
2587 const Register rn = instr->RnField(); 2480 const Register rn = instr->RnField();
2588 const Register rm = instr->RmField(); 2481 const Register rm = instr->RmField();
2589 const int op = instr->Bits(10, 5); 2482 const int op = instr->Bits(10, 5);
2590 const int64_t rn_val64 = get_register(rn, R31IsZR); 2483 const int64_t rn_val64 = get_register(rn, R31IsZR);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2638 set_wregister(rd, alu_out, R31IsZR); 2531 set_wregister(rd, alu_out, R31IsZR);
2639 } 2532 }
2640 break; 2533 break;
2641 } 2534 }
2642 default: 2535 default:
2643 UnimplementedInstruction(instr); 2536 UnimplementedInstruction(instr);
2644 break; 2537 break;
2645 } 2538 }
2646 } 2539 }
2647 2540
2648
2649 void Simulator::DecodeMiscDP3Source(Instr* instr) { 2541 void Simulator::DecodeMiscDP3Source(Instr* instr) {
2650 const Register rd = instr->RdField(); 2542 const Register rd = instr->RdField();
2651 const Register rn = instr->RnField(); 2543 const Register rn = instr->RnField();
2652 const Register rm = instr->RmField(); 2544 const Register rm = instr->RmField();
2653 const Register ra = instr->RaField(); 2545 const Register ra = instr->RaField();
2654 if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) && 2546 if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) &&
2655 (instr->Bit(15) == 0)) { 2547 (instr->Bit(15) == 0)) {
2656 // Format(instr, "madd'sf 'rd, 'rn, 'rm, 'ra"); 2548 // Format(instr, "madd'sf 'rd, 'rn, 'rm, 'ra");
2657 if (instr->SFField() == 1) { 2549 if (instr->SFField() == 1) {
2658 const int64_t rn_val = get_register(rn, R31IsZR); 2550 const int64_t rn_val = get_register(rn, R31IsZR);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2719 const uint64_t rn_val = static_cast<uint32_t>(get_wregister(rn, R31IsZR)); 2611 const uint64_t rn_val = static_cast<uint32_t>(get_wregister(rn, R31IsZR));
2720 const uint64_t rm_val = static_cast<uint32_t>(get_wregister(rm, R31IsZR)); 2612 const uint64_t rm_val = static_cast<uint32_t>(get_wregister(rm, R31IsZR));
2721 const uint64_t ra_val = get_register(ra, R31IsZR); 2613 const uint64_t ra_val = get_register(ra, R31IsZR);
2722 const uint64_t alu_out = ra_val + (rn_val * rm_val); 2614 const uint64_t alu_out = ra_val + (rn_val * rm_val);
2723 set_register(instr, rd, alu_out, R31IsZR); 2615 set_register(instr, rd, alu_out, R31IsZR);
2724 } else { 2616 } else {
2725 UnimplementedInstruction(instr); 2617 UnimplementedInstruction(instr);
2726 } 2618 }
2727 } 2619 }
2728 2620
2729
2730 void Simulator::DecodeConditionalSelect(Instr* instr) { 2621 void Simulator::DecodeConditionalSelect(Instr* instr) {
2731 const Register rd = instr->RdField(); 2622 const Register rd = instr->RdField();
2732 const Register rn = instr->RnField(); 2623 const Register rn = instr->RnField();
2733 const Register rm = instr->RmField(); 2624 const Register rm = instr->RmField();
2734 const int64_t rm_val64 = get_register(rm, R31IsZR); 2625 const int64_t rm_val64 = get_register(rm, R31IsZR);
2735 const int32_t rm_val32 = get_wregister(rm, R31IsZR); 2626 const int32_t rm_val32 = get_wregister(rm, R31IsZR);
2736 const int64_t rn_val64 = get_register(rn, instr->RnMode()); 2627 const int64_t rn_val64 = get_register(rn, instr->RnMode());
2737 const int32_t rn_val32 = get_wregister(rn, instr->RnMode()); 2628 const int32_t rn_val32 = get_wregister(rn, instr->RnMode());
2738 int64_t result64 = 0; 2629 int64_t result64 = 0;
2739 int32_t result32 = 0; 2630 int32_t result32 = 0;
(...skipping 27 matching lines...) Expand all
2767 return; 2658 return;
2768 } 2659 }
2769 2660
2770 if (instr->SFField() == 1) { 2661 if (instr->SFField() == 1) {
2771 set_register(instr, rd, result64, instr->RdMode()); 2662 set_register(instr, rd, result64, instr->RdMode());
2772 } else { 2663 } else {
2773 set_wregister(rd, result32, instr->RdMode()); 2664 set_wregister(rd, result32, instr->RdMode());
2774 } 2665 }
2775 } 2666 }
2776 2667
2777
2778 void Simulator::DecodeDPRegister(Instr* instr) { 2668 void Simulator::DecodeDPRegister(Instr* instr) {
2779 if (instr->IsAddSubShiftExtOp()) { 2669 if (instr->IsAddSubShiftExtOp()) {
2780 DecodeAddSubShiftExt(instr); 2670 DecodeAddSubShiftExt(instr);
2781 } else if (instr->IsAddSubWithCarryOp()) { 2671 } else if (instr->IsAddSubWithCarryOp()) {
2782 DecodeAddSubWithCarry(instr); 2672 DecodeAddSubWithCarry(instr);
2783 } else if (instr->IsLogicalShiftOp()) { 2673 } else if (instr->IsLogicalShiftOp()) {
2784 DecodeLogicalShift(instr); 2674 DecodeLogicalShift(instr);
2785 } else if (instr->IsMiscDP1SourceOp()) { 2675 } else if (instr->IsMiscDP1SourceOp()) {
2786 DecodeMiscDP1Source(instr); 2676 DecodeMiscDP1Source(instr);
2787 } else if (instr->IsMiscDP2SourceOp()) { 2677 } else if (instr->IsMiscDP2SourceOp()) {
2788 DecodeMiscDP2Source(instr); 2678 DecodeMiscDP2Source(instr);
2789 } else if (instr->IsMiscDP3SourceOp()) { 2679 } else if (instr->IsMiscDP3SourceOp()) {
2790 DecodeMiscDP3Source(instr); 2680 DecodeMiscDP3Source(instr);
2791 } else if (instr->IsConditionalSelectOp()) { 2681 } else if (instr->IsConditionalSelectOp()) {
2792 DecodeConditionalSelect(instr); 2682 DecodeConditionalSelect(instr);
2793 } else { 2683 } else {
2794 UnimplementedInstruction(instr); 2684 UnimplementedInstruction(instr);
2795 } 2685 }
2796 } 2686 }
2797 2687
2798
2799 void Simulator::DecodeSIMDCopy(Instr* instr) { 2688 void Simulator::DecodeSIMDCopy(Instr* instr) {
2800 const int32_t Q = instr->Bit(30); 2689 const int32_t Q = instr->Bit(30);
2801 const int32_t op = instr->Bit(29); 2690 const int32_t op = instr->Bit(29);
2802 const int32_t imm4 = instr->Bits(11, 4); 2691 const int32_t imm4 = instr->Bits(11, 4);
2803 const int32_t imm5 = instr->Bits(16, 5); 2692 const int32_t imm5 = instr->Bits(16, 5);
2804 2693
2805 int32_t idx4 = -1; 2694 int32_t idx4 = -1;
2806 int32_t idx5 = -1; 2695 int32_t idx5 = -1;
2807 int32_t element_bytes; 2696 int32_t element_bytes;
2808 if (imm5 & 0x1) { 2697 if (imm5 & 0x1) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2883 } else if (element_bytes == 8) { 2772 } else if (element_bytes == 8) {
2884 set_vregisterd(vd, idx5, get_vregisterd(vn, idx4)); 2773 set_vregisterd(vd, idx5, get_vregisterd(vn, idx4));
2885 } else { 2774 } else {
2886 UnimplementedInstruction(instr); 2775 UnimplementedInstruction(instr);
2887 } 2776 }
2888 } else { 2777 } else {
2889 UnimplementedInstruction(instr); 2778 UnimplementedInstruction(instr);
2890 } 2779 }
2891 } 2780 }
2892 2781
2893
2894 void Simulator::DecodeSIMDThreeSame(Instr* instr) { 2782 void Simulator::DecodeSIMDThreeSame(Instr* instr) {
2895 const int Q = instr->Bit(30); 2783 const int Q = instr->Bit(30);
2896 const int U = instr->Bit(29); 2784 const int U = instr->Bit(29);
2897 const int opcode = instr->Bits(11, 5); 2785 const int opcode = instr->Bits(11, 5);
2898 2786
2899 if (Q == 0) { 2787 if (Q == 0) {
2900 UnimplementedInstruction(instr); 2788 UnimplementedInstruction(instr);
2901 return; 2789 return;
2902 } 2790 }
2903 2791
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
3040 } 2928 }
3041 } else { 2929 } else {
3042 UnimplementedInstruction(instr); 2930 UnimplementedInstruction(instr);
3043 return; 2931 return;
3044 } 2932 }
3045 set_vregisterd(vd, idx, res); 2933 set_vregisterd(vd, idx, res);
3046 } 2934 }
3047 } 2935 }
3048 } 2936 }
3049 2937
3050
3051 static float arm_reciprocal_sqrt_estimate(float a) { 2938 static float arm_reciprocal_sqrt_estimate(float a) {
3052 // From the ARM Architecture Reference Manual A2-87. 2939 // From the ARM Architecture Reference Manual A2-87.
3053 if (isinf(a) || (fabs(a) >= exp2f(126))) 2940 if (isinf(a) || (fabs(a) >= exp2f(126)))
3054 return 0.0; 2941 return 0.0;
3055 else if (a == 0.0) 2942 else if (a == 0.0)
3056 return kPosInfinity; 2943 return kPosInfinity;
3057 else if (isnan(a)) 2944 else if (isnan(a))
3058 return a; 2945 return a;
3059 2946
3060 uint32_t a_bits = bit_cast<uint32_t, float>(a); 2947 uint32_t a_bits = bit_cast<uint32_t, float>(a);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3095 double estimate = static_cast<double>(s) / 256.0; 2982 double estimate = static_cast<double>(s) / 256.0;
3096 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0))); 2983 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0)));
3097 2984
3098 // result = 0 : result_exp<7:0> : estimate<51:29> 2985 // result = 0 : result_exp<7:0> : estimate<51:29>
3099 int32_t result_bits = 2986 int32_t result_bits =
3100 ((result_exp & 0xff) << 23) | 2987 ((result_exp & 0xff) << 23) |
3101 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); 2988 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff);
3102 return bit_cast<float, int32_t>(result_bits); 2989 return bit_cast<float, int32_t>(result_bits);
3103 } 2990 }
3104 2991
3105
3106 static float arm_recip_estimate(float a) { 2992 static float arm_recip_estimate(float a) {
3107 // From the ARM Architecture Reference Manual A2-85. 2993 // From the ARM Architecture Reference Manual A2-85.
3108 if (isinf(a) || (fabs(a) >= exp2f(126))) 2994 if (isinf(a) || (fabs(a) >= exp2f(126)))
3109 return 0.0; 2995 return 0.0;
3110 else if (a == 0.0) 2996 else if (a == 0.0)
3111 return kPosInfinity; 2997 return kPosInfinity;
3112 else if (isnan(a)) 2998 else if (isnan(a))
3113 return a; 2999 return a;
3114 3000
3115 uint32_t a_bits = bit_cast<uint32_t, float>(a); 3001 uint32_t a_bits = bit_cast<uint32_t, float>(a);
(...skipping 16 matching lines...) Expand all
3132 double estimate = static_cast<double>(s) / 256.0; 3018 double estimate = static_cast<double>(s) / 256.0;
3133 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0))); 3019 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0)));
3134 3020
3135 // result = sign : result_exp<7:0> : estimate<51:29> 3021 // result = sign : result_exp<7:0> : estimate<51:29>
3136 int32_t result_bits = 3022 int32_t result_bits =
3137 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) | 3023 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) |
3138 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); 3024 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff);
3139 return bit_cast<float, int32_t>(result_bits); 3025 return bit_cast<float, int32_t>(result_bits);
3140 } 3026 }
3141 3027
3142
3143 void Simulator::DecodeSIMDTwoReg(Instr* instr) { 3028 void Simulator::DecodeSIMDTwoReg(Instr* instr) {
3144 const int32_t Q = instr->Bit(30); 3029 const int32_t Q = instr->Bit(30);
3145 const int32_t U = instr->Bit(29); 3030 const int32_t U = instr->Bit(29);
3146 const int32_t op = instr->Bits(12, 5); 3031 const int32_t op = instr->Bits(12, 5);
3147 const int32_t sz = instr->Bits(22, 2); 3032 const int32_t sz = instr->Bits(22, 2);
3148 const VRegister vd = instr->VdField(); 3033 const VRegister vd = instr->VdField();
3149 const VRegister vn = instr->VnField(); 3034 const VRegister vn = instr->VnField();
3150 3035
3151 if (Q != 1) { 3036 if (Q != 1) {
3152 UnimplementedInstruction(instr); 3037 UnimplementedInstruction(instr);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3234 const int32_t vn_val = get_vregisters(vn, i); 3119 const int32_t vn_val = get_vregisters(vn, i);
3235 const float vn_flt = bit_cast<float, int32_t>(vn_val); 3120 const float vn_flt = bit_cast<float, int32_t>(vn_val);
3236 const float re = arm_reciprocal_sqrt_estimate(vn_flt); 3121 const float re = arm_reciprocal_sqrt_estimate(vn_flt);
3237 set_vregisters(vd, i, bit_cast<int32_t, float>(re)); 3122 set_vregisters(vd, i, bit_cast<int32_t, float>(re));
3238 } 3123 }
3239 } else { 3124 } else {
3240 UnimplementedInstruction(instr); 3125 UnimplementedInstruction(instr);
3241 } 3126 }
3242 } 3127 }
3243 3128
3244
3245 void Simulator::DecodeDPSimd1(Instr* instr) { 3129 void Simulator::DecodeDPSimd1(Instr* instr) {
3246 if (instr->IsSIMDCopyOp()) { 3130 if (instr->IsSIMDCopyOp()) {
3247 DecodeSIMDCopy(instr); 3131 DecodeSIMDCopy(instr);
3248 } else if (instr->IsSIMDThreeSameOp()) { 3132 } else if (instr->IsSIMDThreeSameOp()) {
3249 DecodeSIMDThreeSame(instr); 3133 DecodeSIMDThreeSame(instr);
3250 } else if (instr->IsSIMDTwoRegOp()) { 3134 } else if (instr->IsSIMDTwoRegOp()) {
3251 DecodeSIMDTwoReg(instr); 3135 DecodeSIMDTwoReg(instr);
3252 } else { 3136 } else {
3253 UnimplementedInstruction(instr); 3137 UnimplementedInstruction(instr);
3254 } 3138 }
3255 } 3139 }
3256 3140
3257
3258 void Simulator::DecodeFPImm(Instr* instr) { 3141 void Simulator::DecodeFPImm(Instr* instr) {
3259 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) || 3142 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) ||
3260 (instr->Bits(5, 5) != 0)) { 3143 (instr->Bits(5, 5) != 0)) {
3261 UnimplementedInstruction(instr); 3144 UnimplementedInstruction(instr);
3262 return; 3145 return;
3263 } 3146 }
3264 if (instr->Bit(22) == 1) { 3147 if (instr->Bit(22) == 1) {
3265 // Double. 3148 // Double.
3266 // Format(instr, "fmovd 'vd, #'immd"); 3149 // Format(instr, "fmovd 'vd, #'immd");
3267 const VRegister vd = instr->VdField(); 3150 const VRegister vd = instr->VdField();
3268 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field()); 3151 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field());
3269 set_vregisterd(vd, 0, immd); 3152 set_vregisterd(vd, 0, immd);
3270 set_vregisterd(vd, 1, 0); 3153 set_vregisterd(vd, 1, 0);
3271 } else { 3154 } else {
3272 // Single. 3155 // Single.
3273 UnimplementedInstruction(instr); 3156 UnimplementedInstruction(instr);
3274 } 3157 }
3275 } 3158 }
3276 3159
3277
3278 void Simulator::DecodeFPIntCvt(Instr* instr) { 3160 void Simulator::DecodeFPIntCvt(Instr* instr) {
3279 const VRegister vd = instr->VdField(); 3161 const VRegister vd = instr->VdField();
3280 const VRegister vn = instr->VnField(); 3162 const VRegister vn = instr->VnField();
3281 const Register rd = instr->RdField(); 3163 const Register rd = instr->RdField();
3282 const Register rn = instr->RnField(); 3164 const Register rn = instr->RnField();
3283 3165
3284 if (instr->Bit(29) != 0) { 3166 if (instr->Bit(29) != 0) {
3285 UnimplementedInstruction(instr); 3167 UnimplementedInstruction(instr);
3286 return; 3168 return;
3287 } 3169 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3325 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0)); 3207 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
3326 set_register(instr, rd, static_cast<int64_t>(vn_val), instr->RdMode()); 3208 set_register(instr, rd, static_cast<int64_t>(vn_val), instr->RdMode());
3327 } else { 3209 } else {
3328 UnimplementedInstruction(instr); 3210 UnimplementedInstruction(instr);
3329 } 3211 }
3330 } else { 3212 } else {
3331 UnimplementedInstruction(instr); 3213 UnimplementedInstruction(instr);
3332 } 3214 }
3333 } 3215 }
3334 3216
3335
3336 void Simulator::DecodeFPOneSource(Instr* instr) { 3217 void Simulator::DecodeFPOneSource(Instr* instr) {
3337 const int opc = instr->Bits(15, 6); 3218 const int opc = instr->Bits(15, 6);
3338 const VRegister vd = instr->VdField(); 3219 const VRegister vd = instr->VdField();
3339 const VRegister vn = instr->VnField(); 3220 const VRegister vn = instr->VnField();
3340 const int64_t vn_val = get_vregisterd(vn, 0); 3221 const int64_t vn_val = get_vregisterd(vn, 0);
3341 const int32_t vn_val32 = vn_val & kWRegMask; 3222 const int32_t vn_val32 = vn_val & kWRegMask;
3342 const double vn_dbl = bit_cast<double, int64_t>(vn_val); 3223 const double vn_dbl = bit_cast<double, int64_t>(vn_val);
3343 const float vn_flt = bit_cast<float, int32_t>(vn_val32); 3224 const float vn_flt = bit_cast<float, int32_t>(vn_val32);
3344 3225
3345 if ((opc != 5) && (instr->Bit(22) != 1)) { 3226 if ((opc != 5) && (instr->Bit(22) != 1)) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3380 break; 3261 break;
3381 default: 3262 default:
3382 UnimplementedInstruction(instr); 3263 UnimplementedInstruction(instr);
3383 break; 3264 break;
3384 } 3265 }
3385 3266
3386 set_vregisterd(vd, 0, res_val); 3267 set_vregisterd(vd, 0, res_val);
3387 set_vregisterd(vd, 1, 0); 3268 set_vregisterd(vd, 1, 0);
3388 } 3269 }
3389 3270
3390
3391 void Simulator::DecodeFPTwoSource(Instr* instr) { 3271 void Simulator::DecodeFPTwoSource(Instr* instr) {
3392 if (instr->Bits(22, 2) != 1) { 3272 if (instr->Bits(22, 2) != 1) {
3393 UnimplementedInstruction(instr); 3273 UnimplementedInstruction(instr);
3394 return; 3274 return;
3395 } 3275 }
3396 const VRegister vd = instr->VdField(); 3276 const VRegister vd = instr->VdField();
3397 const VRegister vn = instr->VnField(); 3277 const VRegister vn = instr->VnField();
3398 const VRegister vm = instr->VmField(); 3278 const VRegister vm = instr->VmField();
3399 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0)); 3279 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
3400 const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, 0)); 3280 const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, 0));
(...skipping 19 matching lines...) Expand all
3420 break; 3300 break;
3421 default: 3301 default:
3422 UnimplementedInstruction(instr); 3302 UnimplementedInstruction(instr);
3423 return; 3303 return;
3424 } 3304 }
3425 3305
3426 set_vregisterd(vd, 0, bit_cast<int64_t, double>(result)); 3306 set_vregisterd(vd, 0, bit_cast<int64_t, double>(result));
3427 set_vregisterd(vd, 1, 0); 3307 set_vregisterd(vd, 1, 0);
3428 } 3308 }
3429 3309
3430
3431 void Simulator::DecodeFPCompare(Instr* instr) { 3310 void Simulator::DecodeFPCompare(Instr* instr) {
3432 const VRegister vn = instr->VnField(); 3311 const VRegister vn = instr->VnField();
3433 const VRegister vm = instr->VmField(); 3312 const VRegister vm = instr->VmField();
3434 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0)); 3313 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
3435 double vm_val; 3314 double vm_val;
3436 3315
3437 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) { 3316 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) {
3438 // Format(instr, "fcmpd 'vn, 'vm"); 3317 // Format(instr, "fcmpd 'vn, 'vm");
3439 vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, 0)); 3318 vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, 0));
3440 } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) { 3319 } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) {
(...skipping 20 matching lines...) Expand all
3461 } else if (vn_val == vm_val) { 3340 } else if (vn_val == vm_val) {
3462 z_flag_ = true; 3341 z_flag_ = true;
3463 c_flag_ = true; 3342 c_flag_ = true;
3464 } else if (vn_val < vm_val) { 3343 } else if (vn_val < vm_val) {
3465 n_flag_ = true; 3344 n_flag_ = true;
3466 } else { 3345 } else {
3467 c_flag_ = true; 3346 c_flag_ = true;
3468 } 3347 }
3469 } 3348 }
3470 3349
3471
3472 void Simulator::DecodeFP(Instr* instr) { 3350 void Simulator::DecodeFP(Instr* instr) {
3473 if (instr->IsFPImmOp()) { 3351 if (instr->IsFPImmOp()) {
3474 DecodeFPImm(instr); 3352 DecodeFPImm(instr);
3475 } else if (instr->IsFPIntCvtOp()) { 3353 } else if (instr->IsFPIntCvtOp()) {
3476 DecodeFPIntCvt(instr); 3354 DecodeFPIntCvt(instr);
3477 } else if (instr->IsFPOneSourceOp()) { 3355 } else if (instr->IsFPOneSourceOp()) {
3478 DecodeFPOneSource(instr); 3356 DecodeFPOneSource(instr);
3479 } else if (instr->IsFPTwoSourceOp()) { 3357 } else if (instr->IsFPTwoSourceOp()) {
3480 DecodeFPTwoSource(instr); 3358 DecodeFPTwoSource(instr);
3481 } else if (instr->IsFPCompareOp()) { 3359 } else if (instr->IsFPCompareOp()) {
3482 DecodeFPCompare(instr); 3360 DecodeFPCompare(instr);
3483 } else { 3361 } else {
3484 UnimplementedInstruction(instr); 3362 UnimplementedInstruction(instr);
3485 } 3363 }
3486 } 3364 }
3487 3365
3488
3489 void Simulator::DecodeDPSimd2(Instr* instr) { 3366 void Simulator::DecodeDPSimd2(Instr* instr) {
3490 if (instr->IsFPOp()) { 3367 if (instr->IsFPOp()) {
3491 DecodeFP(instr); 3368 DecodeFP(instr);
3492 } else { 3369 } else {
3493 UnimplementedInstruction(instr); 3370 UnimplementedInstruction(instr);
3494 } 3371 }
3495 } 3372 }
3496 3373
3497
3498 // Executes the current instruction. 3374 // Executes the current instruction.
3499 void Simulator::InstructionDecode(Instr* instr) { 3375 void Simulator::InstructionDecode(Instr* instr) {
3500 pc_modified_ = false; 3376 pc_modified_ = false;
3501 if (IsTracingExecution()) { 3377 if (IsTracingExecution()) {
3502 THR_Print("%" Pu64 " ", icount_); 3378 THR_Print("%" Pu64 " ", icount_);
3503 const uword start = reinterpret_cast<uword>(instr); 3379 const uword start = reinterpret_cast<uword>(instr);
3504 const uword end = start + Instr::kInstrSize; 3380 const uword end = start + Instr::kInstrSize;
3505 if (FLAG_support_disassembler) { 3381 if (FLAG_support_disassembler) {
3506 Disassembler::Disassemble(start, end); 3382 Disassembler::Disassemble(start, end);
3507 } else { 3383 } else {
(...skipping 15 matching lines...) Expand all
3523 DecodeDPSimd2(instr); 3399 DecodeDPSimd2(instr);
3524 } else { 3400 } else {
3525 UnimplementedInstruction(instr); 3401 UnimplementedInstruction(instr);
3526 } 3402 }
3527 3403
3528 if (!pc_modified_) { 3404 if (!pc_modified_) {
3529 set_pc(reinterpret_cast<int64_t>(instr) + Instr::kInstrSize); 3405 set_pc(reinterpret_cast<int64_t>(instr) + Instr::kInstrSize);
3530 } 3406 }
3531 } 3407 }
3532 3408
3533
3534 void Simulator::Execute() { 3409 void Simulator::Execute() {
3535 // Get the PC to simulate. Cannot use the accessor here as we need the 3410 // Get the PC to simulate. Cannot use the accessor here as we need the
3536 // raw PC value and not the one used as input to arithmetic instructions. 3411 // raw PC value and not the one used as input to arithmetic instructions.
3537 uword program_counter = get_pc(); 3412 uword program_counter = get_pc();
3538 3413
3539 if (FLAG_stop_sim_at == ULLONG_MAX) { 3414 if (FLAG_stop_sim_at == ULLONG_MAX) {
3540 // Fast version of the dispatch loop without checking whether the simulator 3415 // Fast version of the dispatch loop without checking whether the simulator
3541 // should be stopping at a particular executed instruction. 3416 // should be stopping at a particular executed instruction.
3542 while (program_counter != kEndSimulatingPC) { 3417 while (program_counter != kEndSimulatingPC) {
3543 Instr* instr = reinterpret_cast<Instr*>(program_counter); 3418 Instr* instr = reinterpret_cast<Instr*>(program_counter);
(...skipping 20 matching lines...) Expand all
3564 } else if (IsIllegalAddress(program_counter)) { 3439 } else if (IsIllegalAddress(program_counter)) {
3565 HandleIllegalAccess(program_counter, instr); 3440 HandleIllegalAccess(program_counter, instr);
3566 } else { 3441 } else {
3567 InstructionDecode(instr); 3442 InstructionDecode(instr);
3568 } 3443 }
3569 program_counter = get_pc(); 3444 program_counter = get_pc();
3570 } 3445 }
3571 } 3446 }
3572 } 3447 }
3573 3448
3574
3575 int64_t Simulator::Call(int64_t entry, 3449 int64_t Simulator::Call(int64_t entry,
3576 int64_t parameter0, 3450 int64_t parameter0,
3577 int64_t parameter1, 3451 int64_t parameter1,
3578 int64_t parameter2, 3452 int64_t parameter2,
3579 int64_t parameter3, 3453 int64_t parameter3,
3580 bool fp_return, 3454 bool fp_return,
3581 bool fp_args) { 3455 bool fp_args) {
3582 // Save the SP register before the call so we can restore it. 3456 // Save the SP register before the call so we can restore it.
3583 const intptr_t sp_before_call = get_register(R31, R31IsSP); 3457 const intptr_t sp_before_call = get_register(R31, R31IsSP);
3584 3458
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3657 set_register(NULL, R31, sp_before_call, R31IsSP); 3531 set_register(NULL, R31, sp_before_call, R31IsSP);
3658 int64_t return_value; 3532 int64_t return_value;
3659 if (fp_return) { 3533 if (fp_return) {
3660 return_value = get_vregisterd(V0, 0); 3534 return_value = get_vregisterd(V0, 0);
3661 } else { 3535 } else {
3662 return_value = get_register(R0); 3536 return_value = get_register(R0);
3663 } 3537 }
3664 return return_value; 3538 return return_value;
3665 } 3539 }
3666 3540
3667
3668 void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { 3541 void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
3669 // Walk over all setjmp buffers (simulated --> C++ transitions) 3542 // Walk over all setjmp buffers (simulated --> C++ transitions)
3670 // and try to find the setjmp associated with the simulated stack pointer. 3543 // and try to find the setjmp associated with the simulated stack pointer.
3671 SimulatorSetjmpBuffer* buf = last_setjmp_buffer(); 3544 SimulatorSetjmpBuffer* buf = last_setjmp_buffer();
3672 while (buf->link() != NULL && buf->link()->sp() <= sp) { 3545 while (buf->link() != NULL && buf->link()->sp() <= sp) {
3673 buf = buf->link(); 3546 buf = buf->link();
3674 } 3547 }
3675 ASSERT(buf != NULL); 3548 ASSERT(buf != NULL);
3676 3549
3677 // The C++ caller has not cleaned up the stack memory of C++ frames. 3550 // The C++ caller has not cleaned up the stack memory of C++ frames.
(...skipping 19 matching lines...) Expand all
3697 set_register(NULL, CODE_REG, code); 3570 set_register(NULL, CODE_REG, code);
3698 set_register(NULL, PP, pp); 3571 set_register(NULL, PP, pp);
3699 buf->Longjmp(); 3572 buf->Longjmp();
3700 } 3573 }
3701 3574
3702 } // namespace dart 3575 } // namespace dart
3703 3576
3704 #endif // !defined(USING_SIMULATOR) 3577 #endif // !defined(USING_SIMULATOR)
3705 3578
3706 #endif // defined TARGET_ARCH_ARM64 3579 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm.cc ('k') | runtime/vm/simulator_dbc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698