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

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

Issue 293993013: Beings adding SIMD support to arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/simulator_arm64.h ('k') | runtime/vm/stub_code_arm64.cc » ('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 <math.h> // for isnan. 5 #include <math.h> // for isnan.
6 #include <setjmp.h> 6 #include <setjmp.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include "vm/globals.h" 9 #include "vm/globals.h"
10 #if defined(TARGET_ARCH_ARM64) 10 #if defined(TARGET_ARCH_ARM64)
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 ~SimulatorDebugger(); 86 ~SimulatorDebugger();
87 87
88 void Stop(Instr* instr, const char* message); 88 void Stop(Instr* instr, const char* message);
89 void Debug(); 89 void Debug();
90 char* ReadLine(const char* prompt); 90 char* ReadLine(const char* prompt);
91 91
92 private: 92 private:
93 Simulator* sim_; 93 Simulator* sim_;
94 94
95 bool GetValue(char* desc, int64_t* value); 95 bool GetValue(char* desc, int64_t* value);
96 bool GetSValue(char* desc, int32_t* value);
96 bool GetDValue(char* desc, int64_t* value); 97 bool GetDValue(char* desc, int64_t* value);
98 bool GetQValue(char* desc, simd_value_t* value);
97 // TODO(zra): Breakpoints. 99 // TODO(zra): Breakpoints.
98 }; 100 };
99 101
100 102
101 SimulatorDebugger::SimulatorDebugger(Simulator* sim) { 103 SimulatorDebugger::SimulatorDebugger(Simulator* sim) {
102 sim_ = sim; 104 sim_ = sim;
103 } 105 }
104 106
105 107
106 SimulatorDebugger::~SimulatorDebugger() { 108 SimulatorDebugger::~SimulatorDebugger() {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 return true; 180 return true;
179 } 181 }
180 bool retval = SScanF(desc, "0x%"Px64, value) == 1; 182 bool retval = SScanF(desc, "0x%"Px64, value) == 1;
181 if (!retval) { 183 if (!retval) {
182 retval = SScanF(desc, "%"Px64, value) == 1; 184 retval = SScanF(desc, "%"Px64, value) == 1;
183 } 185 }
184 return retval; 186 return retval;
185 } 187 }
186 188
187 189
190 bool SimulatorDebugger::GetSValue(char* desc, int32_t* value) {
191 VRegister vreg = LookupVRegisterByName(desc);
192 if (vreg != kNoVRegister) {
193 *value = sim_->get_vregisters(vreg, 0);
194 return true;
195 }
196 if (desc[0] == '*') {
197 int64_t addr;
198 if (GetValue(desc + 1, &addr)) {
199 if (Simulator::IsIllegalAddress(addr)) {
200 return false;
201 }
202 *value = *(reinterpret_cast<int32_t*>(addr));
203 return true;
204 }
205 }
206 return false;
207 }
208
209
188 bool SimulatorDebugger::GetDValue(char* desc, int64_t* value) { 210 bool SimulatorDebugger::GetDValue(char* desc, int64_t* value) {
189 VRegister vreg = LookupVRegisterByName(desc); 211 VRegister vreg = LookupVRegisterByName(desc);
190 if (vreg != kNoVRegister) { 212 if (vreg != kNoVRegister) {
191 *value = sim_->get_vregisterd(vreg); 213 *value = sim_->get_vregisterd(vreg, 0);
192 return true; 214 return true;
193 } 215 }
194 if (desc[0] == '*') { 216 if (desc[0] == '*') {
195 int64_t addr; 217 int64_t addr;
196 if (GetValue(desc + 1, &addr)) { 218 if (GetValue(desc + 1, &addr)) {
197 if (Simulator::IsIllegalAddress(addr)) { 219 if (Simulator::IsIllegalAddress(addr)) {
198 return false; 220 return false;
199 } 221 }
200 *value = *(reinterpret_cast<int64_t*>(addr)); 222 *value = *(reinterpret_cast<int64_t*>(addr));
201 return true; 223 return true;
202 } 224 }
203 } 225 }
204 return false; 226 return false;
205 } 227 }
206 228
207 229
230 bool SimulatorDebugger::GetQValue(char* desc, simd_value_t* value) {
231 VRegister vreg = LookupVRegisterByName(desc);
232 if (vreg != kNoVRegister) {
233 sim_->get_vregister(vreg, value);
234 return true;
235 }
236 if (desc[0] == '*') {
237 int64_t addr;
238 if (GetValue(desc + 1, &addr)) {
239 if (Simulator::IsIllegalAddress(addr)) {
240 return false;
241 }
242 *value = *(reinterpret_cast<simd_value_t*>(addr));
243 return true;
244 }
245 }
246 return false;
247 }
248
249
208 void SimulatorDebugger::Debug() { 250 void SimulatorDebugger::Debug() {
209 intptr_t last_pc = -1; 251 intptr_t last_pc = -1;
210 bool done = false; 252 bool done = false;
211 253
212 #define COMMAND_SIZE 63 254 #define COMMAND_SIZE 63
213 #define ARG_SIZE 255 255 #define ARG_SIZE 255
214 256
215 #define STR(a) #a 257 #define STR(a) #a
216 #define XSTR(a) STR(a) 258 #define XSTR(a) STR(a)
217 259
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 OS::Print("c/cont -- continue execution\n" 294 OS::Print("c/cont -- continue execution\n"
253 "disasm -- disassemble instrs at current pc location\n" 295 "disasm -- disassemble instrs at current pc location\n"
254 " other variants are:\n" 296 " other variants are:\n"
255 " disasm <address>\n" 297 " disasm <address>\n"
256 " disasm <address> <number_of_instructions>\n" 298 " disasm <address> <number_of_instructions>\n"
257 " by default 10 instrs are disassembled\n" 299 " by default 10 instrs are disassembled\n"
258 "flags -- print flag values\n" 300 "flags -- print flag values\n"
259 "gdb -- transfer control to gdb\n" 301 "gdb -- transfer control to gdb\n"
260 "h/help -- print this help string\n" 302 "h/help -- print this help string\n"
261 "p/print <reg or value or *addr> -- print integer value\n" 303 "p/print <reg or value or *addr> -- print integer value\n"
262 "pd/printdouble <dreg or *addr> -- print double value\n" 304 "pf/printfloat <vreg or *addr> --print float value\n"
305 "pd/printdouble <vreg or *addr> -- print double value\n"
306 "pq/printquad <vreg or *addr> -- print vector register\n"
263 "po/printobject <*reg or *addr> -- print object\n" 307 "po/printobject <*reg or *addr> -- print object\n"
264 "si/stepi -- single step an instruction\n" 308 "si/stepi -- single step an instruction\n"
265 "q/quit -- Quit the debugger and exit the program\n"); 309 "q/quit -- Quit the debugger and exit the program\n");
266 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) { 310 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
267 OS::Print("Quitting\n"); 311 OS::Print("Quitting\n");
268 OS::Exit(0); 312 OS::Exit(0);
269 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 313 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
270 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 314 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
271 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 315 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
272 // Execute the one instruction we broke at with breakpoints disabled. 316 // Execute the one instruction we broke at with breakpoints disabled.
273 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 317 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
274 // Leave the debugger shell. 318 // Leave the debugger shell.
275 done = true; 319 done = true;
276 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 320 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
277 if (args == 2) { 321 if (args == 2) {
278 int64_t value; 322 int64_t value;
279 if (GetValue(arg1, &value)) { 323 if (GetValue(arg1, &value)) {
280 OS::Print("%s: %"Pu64" 0x%"Px64"\n", arg1, value, value); 324 OS::Print("%s: %"Pu64" 0x%"Px64"\n", arg1, value, value);
281 } else { 325 } else {
282 OS::Print("%s unrecognized\n", arg1); 326 OS::Print("%s unrecognized\n", arg1);
283 } 327 }
284 } else { 328 } else {
285 OS::Print("print <reg or value or *addr>\n"); 329 OS::Print("print <reg or value or *addr>\n");
286 } 330 }
331 } else if ((strcmp(cmd, "pf") == 0) ||
332 (strcmp(cmd, "printfloat") == 0)) {
333 if (args == 2) {
334 int32_t value;
335 if (GetSValue(arg1, &value)) {
336 float svalue = bit_cast<float, int32_t>(value);
337 OS::Print("%s: %d 0x%x %.8g\n",
338 arg1, value, value, svalue);
339 } else {
340 OS::Print("%s unrecognized\n", arg1);
341 }
342 } else {
343 OS::Print("printfloat <vreg or *addr>\n");
344 }
287 } else if ((strcmp(cmd, "pd") == 0) || 345 } else if ((strcmp(cmd, "pd") == 0) ||
288 (strcmp(cmd, "printdouble") == 0)) { 346 (strcmp(cmd, "printdouble") == 0)) {
289 if (args == 2) { 347 if (args == 2) {
290 int64_t long_value; 348 int64_t long_value;
291 if (GetDValue(arg1, &long_value)) { 349 if (GetDValue(arg1, &long_value)) {
292 double dvalue = bit_cast<double, int64_t>(long_value); 350 double dvalue = bit_cast<double, int64_t>(long_value);
293 OS::Print("%s: %"Pu64" 0x%"Px64" %.8g\n", 351 OS::Print("%s: %"Pu64" 0x%"Px64" %.8g\n",
294 arg1, long_value, long_value, dvalue); 352 arg1, long_value, long_value, dvalue);
295 } else { 353 } else {
296 OS::Print("%s unrecognized\n", arg1); 354 OS::Print("%s unrecognized\n", arg1);
297 } 355 }
298 } else { 356 } else {
299 OS::Print("printdouble <dreg or *addr>\n"); 357 OS::Print("printdouble <vreg or *addr>\n");
358 }
359 } else if ((strcmp(cmd, "pq") == 0) ||
360 (strcmp(cmd, "printquad") == 0)) {
361 if (args == 2) {
362 simd_value_t quad_value;
363 if (GetQValue(arg1, &quad_value)) {
364 const int64_t d0 = quad_value.bits.i64[0];
365 const int64_t d1 = quad_value.bits.i64[1];
366 const double dval0 = bit_cast<double, int64_t>(d0);
367 const double dval1 = bit_cast<double, int64_t>(d1);
368 const int32_t s0 = quad_value.bits.i32[0];
369 const int32_t s1 = quad_value.bits.i32[1];
370 const int32_t s2 = quad_value.bits.i32[2];
371 const int32_t s3 = quad_value.bits.i32[3];
372 const float sval0 = bit_cast<float, int32_t>(s0);
373 const float sval1 = bit_cast<float, int32_t>(s1);
374 const float sval2 = bit_cast<float, int32_t>(s2);
375 const float sval3 = bit_cast<float, int32_t>(s3);
376 OS::Print("%s: %"Pu64" 0x%"Px64" %.8g\n", arg1, d0, d0, dval0);
377 OS::Print("%s: %"Pu64" 0x%"Px64" %.8g\n", arg1, d1, d1, dval1);
378 OS::Print("%s: %d 0x%x %.8g\n", arg1, s0, s0, sval0);
379 OS::Print("%s: %d 0x%x %.8g\n", arg1, s1, s1, sval1);
380 OS::Print("%s: %d 0x%x %.8g\n", arg1, s2, s2, sval2);
381 OS::Print("%s: %d 0x%x %.8g\n", arg1, s3, s3, sval3);
382 } else {
383 OS::Print("%s unrecognized\n", arg1);
384 }
385 } else {
386 OS::Print("printquad <vreg or *addr>\n");
300 } 387 }
301 } else if ((strcmp(cmd, "po") == 0) || 388 } else if ((strcmp(cmd, "po") == 0) ||
302 (strcmp(cmd, "printobject") == 0)) { 389 (strcmp(cmd, "printobject") == 0)) {
303 if (args == 2) { 390 if (args == 2) {
304 int64_t value; 391 int64_t value;
305 // Make the dereferencing '*' optional. 392 // Make the dereferencing '*' optional.
306 if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) || 393 if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) ||
307 GetValue(arg1, &value)) { 394 GetValue(arg1, &value)) {
308 if (Isolate::Current()->heap()->Contains(value)) { 395 if (Isolate::Current()->heap()->Contains(value)) {
309 OS::Print("%s: \n", arg1); 396 OS::Print("%s: \n", arg1);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 // All registers are initialized to zero to start with. 551 // All registers are initialized to zero to start with.
465 for (int i = 0; i < kNumberOfCpuRegisters; i++) { 552 for (int i = 0; i < kNumberOfCpuRegisters; i++) {
466 registers_[i] = 0; 553 registers_[i] = 0;
467 } 554 }
468 n_flag_ = false; 555 n_flag_ = false;
469 z_flag_ = false; 556 z_flag_ = false;
470 c_flag_ = false; 557 c_flag_ = false;
471 v_flag_ = false; 558 v_flag_ = false;
472 559
473 for (int i = 0; i < kNumberOfVRegisters; i++) { 560 for (int i = 0; i < kNumberOfVRegisters; i++) {
474 vregisters_[i].lo = 0; 561 vregisters_[i].bits.i64[0] = 0;
475 vregisters_[i].hi = 0; 562 vregisters_[i].bits.i64[1] = 0;
476 } 563 }
477 564
478 // The sp is initialized to point to the bottom (high address) of the 565 // The sp is initialized to point to the bottom (high address) of the
479 // allocated stack area. 566 // allocated stack area.
480 registers_[R31] = StackTop(); 567 registers_[R31] = StackTop();
481 // The lr and pc are initialized to a known bad value that will cause an 568 // The lr and pc are initialized to a known bad value that will cause an
482 // access violation if the simulator ever tries to execute it. 569 // access violation if the simulator ever tries to execute it.
483 registers_[LR] = kBadLR; 570 registers_[LR] = kBadLR;
484 pc_ = kBadLR; 571 pc_ = kBadLR;
485 } 572 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 int32_t Simulator::get_wregister(Register reg, R31Type r31t) const { 696 int32_t Simulator::get_wregister(Register reg, R31Type r31t) const {
610 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 697 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
611 if ((reg == R31) && (r31t == R31IsZR)) { 698 if ((reg == R31) && (r31t == R31IsZR)) {
612 return 0; 699 return 0;
613 } else { 700 } else {
614 return static_cast<int32_t>(registers_[reg]); 701 return static_cast<int32_t>(registers_[reg]);
615 } 702 }
616 } 703 }
617 704
618 705
619 int64_t Simulator::get_vregisterd(VRegister reg) const { 706 int32_t Simulator::get_vregisters(VRegister reg, int idx) const {
620 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); 707 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
621 return vregisters_[reg].lo; 708 ASSERT((idx >= 0) && (idx <= 3));
709 return vregisters_[reg].bits.i32[idx];
622 } 710 }
623 711
624 712
625 void Simulator::set_vregisterd(VRegister reg, int64_t value) { 713 void Simulator::set_vregisters(VRegister reg, int idx, int32_t value) {
626 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); 714 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
627 vregisters_[reg].lo = value; 715 ASSERT((idx >= 0) && (idx <= 3));
628 vregisters_[reg].hi = 0; 716 vregisters_[reg].bits.i32[idx] = value;
717 }
718
719
720 int64_t Simulator::get_vregisterd(VRegister reg, int idx) const {
721 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
722 ASSERT((idx == 0) || (idx == 1));
723 return vregisters_[reg].bits.i64[idx];
724 }
725
726
727 void Simulator::set_vregisterd(VRegister reg, int idx, int64_t value) {
728 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
729 ASSERT((idx == 0) || (idx == 1));
730 vregisters_[reg].bits.i64[idx] = value;
629 } 731 }
630 732
631 733
632 void Simulator::get_vregister(VRegister reg, simd_value_t* value) const { 734 void Simulator::get_vregister(VRegister reg, simd_value_t* value) const {
633 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); 735 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
634 value->lo = vregisters_[reg].lo; 736 value->bits.i64[0] = vregisters_[reg].bits.i64[0];
635 value->hi = vregisters_[reg].hi; 737 value->bits.i64[1] = vregisters_[reg].bits.i64[1];
636 } 738 }
637 739
638 740
639 void Simulator::set_vregister(VRegister reg, const simd_value_t& value) { 741 void Simulator::set_vregister(VRegister reg, const simd_value_t& value) {
640 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); 742 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
641 vregisters_[reg].lo = value.lo; 743 vregisters_[reg].bits.i64[0] = value.bits.i64[0];
642 vregisters_[reg].hi = value.hi; 744 vregisters_[reg].bits.i64[1] = value.bits.i64[1];
643 } 745 }
644 746
645 747
646 // Raw access to the PC register. 748 // Raw access to the PC register.
647 void Simulator::set_pc(int64_t value) { 749 void Simulator::set_pc(int64_t value) {
648 pc_modified_ = true; 750 pc_modified_ = true;
649 last_pc_ = pc_; 751 last_pc_ = pc_;
650 pc_ = value; 752 pc_ = value;
651 } 753 }
652 754
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 const int64_t r6 = get_register(R6); 1312 const int64_t r6 = get_register(R6);
1211 const int64_t r7 = get_register(R7); 1313 const int64_t r7 = get_register(R7);
1212 const int64_t res = target(r0, r1, r2, r3, r4, r5, r6, r7); 1314 const int64_t res = target(r0, r1, r2, r3, r4, r5, r6, r7);
1213 set_register(R0, res); // Set returned result from function. 1315 set_register(R0, res); // Set returned result from function.
1214 set_register(R1, icount_); // Zap unused result register. 1316 set_register(R1, icount_); // Zap unused result register.
1215 } else if (redirection->call_kind() == kLeafFloatRuntimeCall) { 1317 } else if (redirection->call_kind() == kLeafFloatRuntimeCall) {
1216 ASSERT((0 <= redirection->argument_count()) && 1318 ASSERT((0 <= redirection->argument_count()) &&
1217 (redirection->argument_count() <= 8)); 1319 (redirection->argument_count() <= 8));
1218 SimulatorLeafFloatRuntimeCall target = 1320 SimulatorLeafFloatRuntimeCall target =
1219 reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external); 1321 reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external);
1220 const double d0 = bit_cast<double, int64_t>(get_vregisterd(V0)); 1322 const double d0 = bit_cast<double, int64_t>(get_vregisterd(V0, 0));
1221 const double d1 = bit_cast<double, int64_t>(get_vregisterd(V1)); 1323 const double d1 = bit_cast<double, int64_t>(get_vregisterd(V1, 0));
1222 const double d2 = bit_cast<double, int64_t>(get_vregisterd(V2)); 1324 const double d2 = bit_cast<double, int64_t>(get_vregisterd(V2, 0));
1223 const double d3 = bit_cast<double, int64_t>(get_vregisterd(V3)); 1325 const double d3 = bit_cast<double, int64_t>(get_vregisterd(V3, 0));
1224 const double d4 = bit_cast<double, int64_t>(get_vregisterd(V4)); 1326 const double d4 = bit_cast<double, int64_t>(get_vregisterd(V4, 0));
1225 const double d5 = bit_cast<double, int64_t>(get_vregisterd(V5)); 1327 const double d5 = bit_cast<double, int64_t>(get_vregisterd(V5, 0));
1226 const double d6 = bit_cast<double, int64_t>(get_vregisterd(V6)); 1328 const double d6 = bit_cast<double, int64_t>(get_vregisterd(V6, 0));
1227 const double d7 = bit_cast<double, int64_t>(get_vregisterd(V7)); 1329 const double d7 = bit_cast<double, int64_t>(get_vregisterd(V7, 0));
1228 const double res = target(d0, d1, d2, d3, d4, d5, d6, d7); 1330 const double res = target(d0, d1, d2, d3, d4, d5, d6, d7);
1229 set_vregisterd(V0, bit_cast<int64_t, double>(res)); 1331 set_vregisterd(V0, 0, bit_cast<int64_t, double>(res));
1332 set_vregisterd(V0, 1, 0);
1230 } else if (redirection->call_kind() == kBootstrapNativeCall) { 1333 } else if (redirection->call_kind() == kBootstrapNativeCall) {
1231 NativeArguments* arguments; 1334 NativeArguments* arguments;
1232 arguments = reinterpret_cast<NativeArguments*>(get_register(R0)); 1335 arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
1233 SimulatorBootstrapNativeCall target = 1336 SimulatorBootstrapNativeCall target =
1234 reinterpret_cast<SimulatorBootstrapNativeCall>(external); 1337 reinterpret_cast<SimulatorBootstrapNativeCall>(external);
1235 target(arguments); 1338 target(arguments);
1236 set_register(R0, icount_); // Zap result register from void function. 1339 set_register(R0, icount_); // Zap result register from void function.
1237 } else { 1340 } else {
1238 ASSERT(redirection->call_kind() == kNativeCall); 1341 ASSERT(redirection->call_kind() == kNativeCall);
1239 NativeArguments* arguments; 1342 NativeArguments* arguments;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 // Check the address. 1573 // Check the address.
1471 if (IsIllegalAddress(address)) { 1574 if (IsIllegalAddress(address)) {
1472 HandleIllegalAccess(address, instr); 1575 HandleIllegalAccess(address, instr);
1473 return; 1576 return;
1474 } 1577 }
1475 1578
1476 // Do access. 1579 // Do access.
1477 if (instr->Bit(26) == 1) { 1580 if (instr->Bit(26) == 1) {
1478 if (instr->Bit(22) == 0) { 1581 if (instr->Bit(22) == 0) {
1479 // Format(instr, "fstr'fsz 'vt, 'memop"); 1582 // Format(instr, "fstr'fsz 'vt, 'memop");
1480 const int64_t vt_val = get_vregisterd(vt); 1583 const int64_t vt_val = get_vregisterd(vt, 0);
1481 switch (size) { 1584 switch (size) {
1482 case 2: 1585 case 2:
1483 WriteW(address, vt_val & kWRegMask, instr); 1586 WriteW(address, vt_val & kWRegMask, instr);
1484 break; 1587 break;
1485 case 3: 1588 case 3:
1486 WriteX(address, vt_val, instr); 1589 WriteX(address, vt_val, instr);
1487 break; 1590 break;
1488 case 4: { 1591 case 4: {
1489 simd_value_t val; 1592 simd_value_t val;
1490 get_vregister(vt, &val); 1593 get_vregister(vt, &val);
1491 WriteX(address, val.lo, instr); 1594 WriteX(address, val.bits.i64[0], instr);
1492 WriteX(address + kWordSize, val.hi, instr); 1595 WriteX(address + kWordSize, val.bits.i64[1], instr);
1493 break; 1596 break;
1494 } 1597 }
1495 default: 1598 default:
1496 UnimplementedInstruction(instr); 1599 UnimplementedInstruction(instr);
1497 return; 1600 return;
1498 } 1601 }
1499 } else { 1602 } else {
1500 // Format(instr, "fldr'fsz 'vt, 'memop"); 1603 // Format(instr, "fldr'fsz 'vt, 'memop");
1501 switch (size) { 1604 switch (size) {
1502 case 2: 1605 case 2:
1503 set_vregisterd(vt, static_cast<int64_t>(ReadWU(address, instr))); 1606 set_vregisterd(vt, 0, static_cast<int64_t>(ReadWU(address, instr)));
1607 set_vregisterd(vt, 1, 0);
1504 break; 1608 break;
1505 case 3: 1609 case 3:
1506 set_vregisterd(vt, ReadX(address, instr)); 1610 set_vregisterd(vt, 0, ReadX(address, instr));
1611 set_vregisterd(vt, 1, 0);
1507 break; 1612 break;
1508 case 4: { 1613 case 4: {
1509 simd_value_t val; 1614 simd_value_t val;
1510 val.lo = ReadX(address, instr); 1615 val.bits.i64[0] = ReadX(address, instr);
1511 val.hi = ReadX(address + kWordSize, instr); 1616 val.bits.i64[1] = ReadX(address + kWordSize, instr);
1512 set_vregister(vt, val); 1617 set_vregister(vt, val);
1513 break; 1618 break;
1514 } 1619 }
1515 default: 1620 default:
1516 UnimplementedInstruction(instr); 1621 UnimplementedInstruction(instr);
1517 return; 1622 return;
1518 } 1623 }
1519 } 1624 }
1520 } else { 1625 } else {
1521 if (instr->Bits(22, 2) == 0) { 1626 if (instr->Bits(22, 2) == 0) {
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
2060 } else if (instr->IsMiscDP3SourceOp()) { 2165 } else if (instr->IsMiscDP3SourceOp()) {
2061 DecodeMiscDP3Source(instr); 2166 DecodeMiscDP3Source(instr);
2062 } else if (instr->IsConditionalSelectOp()) { 2167 } else if (instr->IsConditionalSelectOp()) {
2063 DecodeConditionalSelect(instr); 2168 DecodeConditionalSelect(instr);
2064 } else { 2169 } else {
2065 UnimplementedInstruction(instr); 2170 UnimplementedInstruction(instr);
2066 } 2171 }
2067 } 2172 }
2068 2173
2069 2174
2175 void Simulator::DecodeSIMDCopy(Instr* instr) {
2176 const int32_t Q = instr->Bit(30);
2177 const int32_t op = instr->Bit(29);
2178 const int32_t imm4 = instr->Bits(11, 4);
2179 const int32_t imm5 = instr->Bits(16, 5);
2180
2181 int32_t idx4 = -1;
2182 int32_t idx5 = -1;
2183 int32_t element_bytes;
2184 if (imm5 & 0x1) {
2185 idx4 = imm4;
2186 idx5 = imm5 >> 1;
2187 element_bytes = 1;
2188 } else if (imm5 & 0x2) {
2189 idx4 = imm4 >> 1;
2190 idx5 = imm5 >> 2;
2191 element_bytes = 2;
2192 } else if (imm5 & 0x4) {
2193 idx4 = imm4 >> 2;
2194 idx5 = imm5 >> 3;
2195 element_bytes = 4;
2196 } else if (imm5 & 0x8) {
2197 idx4 = imm4 >> 3;
2198 idx5 = imm5 >> 4;
2199 element_bytes = 8;
2200 } else {
2201 UnimplementedInstruction(instr);
2202 return;
2203 }
2204 ASSERT((idx4 != -1) && (idx5 != -1));
2205
2206 const VRegister vd = instr->VdField();
2207 const VRegister vn = instr->VnField();
2208 if ((Q == 1) && (op == 0) && (imm4 == 0)) {
2209 // Format(instr, "vdup'csz 'vd, 'vn'idx5");
2210 if (element_bytes == 4) {
2211 for (int i = 0; i < 4; i++) {
2212 set_vregisters(vd, i, get_vregisters(vn, idx5));
2213 }
2214 } else if (element_bytes == 8) {
2215 for (int i = 0; i < 2; i++) {
2216 set_vregisterd(vd, i, get_vregisterd(vn, idx5));
2217 }
2218 } else {
2219 UnimplementedInstruction(instr);
2220 return;
2221 }
2222 } else if ((Q == 1) && (op == 1)) {
2223 // Format(instr, "vins'csz 'vd'idx5, 'vn'idx4");
2224 if (element_bytes == 4) {
2225 set_vregisters(vd, idx5, get_vregisters(vn, idx4));
2226 } else if (element_bytes == 8) {
2227 set_vregisterd(vd, idx5, get_vregisterd(vn, idx4));
2228 } else {
2229 UnimplementedInstruction(instr);
2230 }
2231 } else {
2232 UnimplementedInstruction(instr);
2233 }
2234 }
2235
2236
2237 void Simulator::DecodeSIMDThreeSame(Instr* instr) {
2238 const int Q = instr->Bit(30);
2239 const int U = instr->Bit(29);
2240 const int opcode = instr->Bits(11, 5);
2241
2242 if (Q == 0) {
2243 UnimplementedInstruction(instr);
2244 return;
2245 }
2246
2247 const VRegister vd = instr->VdField();
2248 const VRegister vn = instr->VnField();
2249 const VRegister vm = instr->VmField();
2250 if (instr->Bit(22) == 0) {
2251 // f32 case.
2252 for (int idx = 0; idx < 4; idx++) {
2253 const float vn_val = bit_cast<float, int32_t>(get_vregisters(vn, idx));
2254 const float vm_val = bit_cast<float, int32_t>(get_vregisters(vm, idx));
2255 float res = 0.0;
2256 if ((U == 0) && (opcode == 0x1a)) {
2257 if (instr->Bit(23) == 0) {
2258 // Format(instr, "vadd'vsz 'vd, 'vn, 'vm");
2259 res = vn_val + vm_val;
2260 } else {
2261 // Format(instr, "vsub'vsz 'vd, 'vn, 'vm");
2262 res = vn_val - vm_val;
2263 }
2264 } else if ((U == 1) && (opcode == 0x1b)) {
2265 // Format(instr, "vmul'vsz 'vd, 'vn, 'vm");
2266 res = vn_val * vm_val;
2267 } else if ((U == 1) && (opcode == 0x1f)) {
2268 // Format(instr, "vdiv'vsz 'vd, 'vn, 'vm");
2269 res = vn_val / vm_val;
2270 } else {
2271 UnimplementedInstruction(instr);
2272 return;
2273 }
2274 set_vregisters(vd, idx, bit_cast<int32_t, float>(res));
2275 }
2276 } else {
2277 // f64 case.
2278 for (int idx = 0; idx < 2; idx++) {
2279 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, idx));
2280 const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, idx));
2281 double res = 0.0;
2282 if ((U == 0) && (opcode == 0x1a)) {
2283 if (instr->Bit(23) == 0) {
2284 // Format(instr, "vadd'vsz 'vd, 'vn, 'vm");
2285 res = vn_val + vm_val;
2286 } else {
2287 // Format(instr, "vsub'vsz 'vd, 'vn, 'vm");
2288 res = vn_val - vm_val;
2289 }
2290 } else if ((U == 1) && (opcode == 0x1b)) {
2291 // Format(instr, "vmul'vsz 'vd, 'vn, 'vm");
2292 res = vn_val * vm_val;
2293 } else if ((U == 1) && (opcode == 0x1f)) {
2294 // Format(instr, "vdiv'vsz 'vd, 'vn, 'vm");
2295 res = vn_val / vm_val;
2296 } else {
2297 UnimplementedInstruction(instr);
2298 return;
2299 }
2300 set_vregisterd(vd, idx, bit_cast<int64_t, double>(res));
2301 }
2302 }
2303 }
2304
2305
2070 void Simulator::DecodeDPSimd1(Instr* instr) { 2306 void Simulator::DecodeDPSimd1(Instr* instr) {
2071 UnimplementedInstruction(instr); 2307 if (instr->IsSIMDCopyOp()) {
2308 DecodeSIMDCopy(instr);
2309 } else if (instr->IsSIMDThreeSameOp()) {
2310 DecodeSIMDThreeSame(instr);
2311 } else {
2312 UnimplementedInstruction(instr);
2313 }
2072 } 2314 }
2073 2315
2074 2316
2075 void Simulator::DecodeFPImm(Instr* instr) { 2317 void Simulator::DecodeFPImm(Instr* instr) {
2076 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) || 2318 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) ||
2077 (instr->Bits(5, 5) != 0)) { 2319 (instr->Bits(5, 5) != 0)) {
2078 UnimplementedInstruction(instr); 2320 UnimplementedInstruction(instr);
2079 return; 2321 return;
2080 } 2322 }
2081 if (instr->Bit(22) == 1) { 2323 if (instr->Bit(22) == 1) {
2082 // Double. 2324 // Double.
2083 // Format(instr, "fmovd 'vd, #'immd"); 2325 // Format(instr, "fmovd 'vd, #'immd");
2084 const VRegister vd = instr->VdField(); 2326 const VRegister vd = instr->VdField();
2085 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field()); 2327 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field());
2086 set_vregisterd(vd, immd); 2328 set_vregisterd(vd, 0, immd);
2329 set_vregisterd(vd, 1, 0);
2087 } else { 2330 } else {
2088 // Single. 2331 // Single.
2089 UnimplementedInstruction(instr); 2332 UnimplementedInstruction(instr);
2090 } 2333 }
2091 } 2334 }
2092 2335
2093 2336
2094 void Simulator::DecodeFPIntCvt(Instr* instr) { 2337 void Simulator::DecodeFPIntCvt(Instr* instr) {
2095 const VRegister vd = instr->VdField(); 2338 const VRegister vd = instr->VdField();
2096 const VRegister vn = instr->VnField(); 2339 const VRegister vn = instr->VnField();
2097 const Register rd = instr->RdField(); 2340 const Register rd = instr->RdField();
2098 const Register rn = instr->RnField(); 2341 const Register rn = instr->RnField();
2099 2342
2100 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) || 2343 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) ||
2101 (instr->Bits(22, 2) != 1)) { 2344 (instr->Bits(22, 2) != 1)) {
2102 UnimplementedInstruction(instr); 2345 UnimplementedInstruction(instr);
2103 return; 2346 return;
2104 } 2347 }
2105 if (instr->Bits(16, 5) == 2) { 2348 if (instr->Bits(16, 5) == 2) {
2106 // Format(instr, "scvtfd 'vd, 'vn"); 2349 // Format(instr, "scvtfd 'vd, 'vn");
2107 const int64_t rn_val = get_register(rn, instr->RnMode()); 2350 const int64_t rn_val = get_register(rn, instr->RnMode());
2108 const double vn_dbl = static_cast<double>(rn_val); 2351 const double vn_dbl = static_cast<double>(rn_val);
2109 set_vregisterd(vd, bit_cast<int64_t, double>(vn_dbl)); 2352 set_vregisterd(vd, 0, bit_cast<int64_t, double>(vn_dbl));
2353 set_vregisterd(vd, 1, 0);
2110 } else if (instr->Bits(16, 5) == 6) { 2354 } else if (instr->Bits(16, 5) == 6) {
2111 // Format(instr, "fmovrd 'rd, 'vn"); 2355 // Format(instr, "fmovrd 'rd, 'vn");
2112 const int64_t vn_val = get_vregisterd(vn); 2356 const int64_t vn_val = get_vregisterd(vn, 0);
2113 set_register(rd, vn_val, R31IsZR); 2357 set_register(rd, vn_val, R31IsZR);
2114 } else if (instr->Bits(16, 5) == 7) { 2358 } else if (instr->Bits(16, 5) == 7) {
2115 // Format(instr, "fmovdr 'vd, 'rn"); 2359 // Format(instr, "fmovdr 'vd, 'rn");
2116 const int64_t rn_val = get_register(rn, R31IsZR); 2360 const int64_t rn_val = get_register(rn, R31IsZR);
2117 set_vregisterd(vd, rn_val); 2361 set_vregisterd(vd, 0, rn_val);
2362 set_vregisterd(vd, 1, 0);
2118 } else if (instr->Bits(16, 5) == 24) { 2363 } else if (instr->Bits(16, 5) == 24) {
2119 // Format(instr, "fcvtzds 'rd, 'vn"); 2364 // Format(instr, "fcvtzds 'rd, 'vn");
2120 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn)); 2365 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
2121 set_register(rd, static_cast<int64_t>(vn_val), instr->RdMode()); 2366 set_register(rd, static_cast<int64_t>(vn_val), instr->RdMode());
2122 } else { 2367 } else {
2123 UnimplementedInstruction(instr); 2368 UnimplementedInstruction(instr);
2124 } 2369 }
2125 } 2370 }
2126 2371
2127 2372
2128 void Simulator::DecodeFPOneSource(Instr* instr) { 2373 void Simulator::DecodeFPOneSource(Instr* instr) {
2129 const int opc = instr->Bits(15, 6); 2374 const int opc = instr->Bits(15, 6);
2130 const VRegister vd = instr->VdField(); 2375 const VRegister vd = instr->VdField();
2131 const VRegister vn = instr->VnField(); 2376 const VRegister vn = instr->VnField();
2132 const int64_t vn_val = get_vregisterd(vn); 2377 const int64_t vn_val = get_vregisterd(vn, 0);
2133 const int32_t vn_val32 = vn_val & kWRegMask; 2378 const int32_t vn_val32 = vn_val & kWRegMask;
2134 const double vn_dbl = bit_cast<double, int64_t>(vn_val); 2379 const double vn_dbl = bit_cast<double, int64_t>(vn_val);
2135 const float vn_flt = bit_cast<float, int32_t>(vn_val32); 2380 const float vn_flt = bit_cast<float, int32_t>(vn_val32);
2136 2381
2137 if ((opc != 5) && (instr->Bit(22) != 1)) { 2382 if ((opc != 5) && (instr->Bit(22) != 1)) {
2138 // Source is interpreted as single-precision only if we're doing a 2383 // Source is interpreted as single-precision only if we're doing a
2139 // conversion from single -> double. 2384 // conversion from single -> double.
2140 UnimplementedInstruction(instr); 2385 UnimplementedInstruction(instr);
2141 return; 2386 return;
2142 } 2387 }
2143 2388
2144 int64_t res_val = 0; 2389 int64_t res_val = 0;
2145 switch (opc) { 2390 switch (opc) {
2146 case 0: 2391 case 0:
2147 // Format("fmovdd 'vd, 'vn"); 2392 // Format("fmovdd 'vd, 'vn");
2148 res_val = get_vregisterd(vn); 2393 res_val = get_vregisterd(vn, 0);
2149 break; 2394 break;
2150 case 1: 2395 case 1:
2151 // Format("fabsd 'vd, 'vn"); 2396 // Format("fabsd 'vd, 'vn");
2152 res_val = bit_cast<int64_t, double>(fabs(vn_dbl)); 2397 res_val = bit_cast<int64_t, double>(fabs(vn_dbl));
2153 break; 2398 break;
2154 case 2: 2399 case 2:
2155 // Format("fnegd 'vd, 'vn"); 2400 // Format("fnegd 'vd, 'vn");
2156 res_val = bit_cast<int64_t, double>(-vn_dbl); 2401 res_val = bit_cast<int64_t, double>(-vn_dbl);
2157 break; 2402 break;
2158 case 3: 2403 case 3:
2159 // Format("fsqrtd 'vd, 'vn"); 2404 // Format("fsqrtd 'vd, 'vn");
2160 res_val = bit_cast<int64_t, double>(sqrt(vn_dbl)); 2405 res_val = bit_cast<int64_t, double>(sqrt(vn_dbl));
2161 break; 2406 break;
2162 case 4: { 2407 case 4: {
2163 // Format(instr, "fcvtsd 'vd, 'vn"); 2408 // Format(instr, "fcvtsd 'vd, 'vn");
2164 const uint32_t val = 2409 const uint32_t val =
2165 bit_cast<uint32_t, float>(static_cast<float>(vn_dbl)); 2410 bit_cast<uint32_t, float>(static_cast<float>(vn_dbl));
2166 res_val = static_cast<int64_t>(val); 2411 res_val = static_cast<int64_t>(val);
2167 break; 2412 break;
2168 } 2413 }
2169 case 5: 2414 case 5:
2170 // Format(instr, "fcvtds 'vd, 'vn"); 2415 // Format(instr, "fcvtds 'vd, 'vn");
2171 res_val = bit_cast<int64_t, double>(static_cast<double>(vn_flt)); 2416 res_val = bit_cast<int64_t, double>(static_cast<double>(vn_flt));
2172 break; 2417 break;
2173 default: 2418 default:
2174 UnimplementedInstruction(instr); 2419 UnimplementedInstruction(instr);
2175 break; 2420 break;
2176 } 2421 }
2177 2422
2178 set_vregisterd(vd, res_val); 2423 set_vregisterd(vd, 0, res_val);
2424 set_vregisterd(vd, 1, 0);
2179 } 2425 }
2180 2426
2181 2427
2182 void Simulator::DecodeFPTwoSource(Instr* instr) { 2428 void Simulator::DecodeFPTwoSource(Instr* instr) {
2183 if (instr->Bits(22, 2) != 1) { 2429 if (instr->Bits(22, 2) != 1) {
2184 UnimplementedInstruction(instr); 2430 UnimplementedInstruction(instr);
2185 return; 2431 return;
2186 } 2432 }
2187 const VRegister vd = instr->VdField(); 2433 const VRegister vd = instr->VdField();
2188 const VRegister vn = instr->VnField(); 2434 const VRegister vn = instr->VnField();
2189 const VRegister vm = instr->VmField(); 2435 const VRegister vm = instr->VmField();
2190 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn)); 2436 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
2191 const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm)); 2437 const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, 0));
2192 const int opc = instr->Bits(12, 4); 2438 const int opc = instr->Bits(12, 4);
2193 double result; 2439 double result;
2194 2440
2195 switch (opc) { 2441 switch (opc) {
2196 case 0: 2442 case 0:
2197 // Format(instr, "fmuld 'vd, 'vn, 'vm"); 2443 // Format(instr, "fmuld 'vd, 'vn, 'vm");
2198 result = vn_val * vm_val; 2444 result = vn_val * vm_val;
2199 break; 2445 break;
2200 case 1: 2446 case 1:
2201 // Format(instr, "fdivd 'vd, 'vn, 'vm"); 2447 // Format(instr, "fdivd 'vd, 'vn, 'vm");
2202 result = vn_val / vm_val; 2448 result = vn_val / vm_val;
2203 break; 2449 break;
2204 case 2: 2450 case 2:
2205 // Format(instr, "faddd 'vd, 'vn, 'vm"); 2451 // Format(instr, "faddd 'vd, 'vn, 'vm");
2206 result = vn_val + vm_val; 2452 result = vn_val + vm_val;
2207 break; 2453 break;
2208 case 3: 2454 case 3:
2209 // Format(instr, "fsubd 'vd, 'vn, 'vm"); 2455 // Format(instr, "fsubd 'vd, 'vn, 'vm");
2210 result = vn_val - vm_val; 2456 result = vn_val - vm_val;
2211 break; 2457 break;
2212 default: 2458 default:
2213 UnimplementedInstruction(instr); 2459 UnimplementedInstruction(instr);
2214 return; 2460 return;
2215 } 2461 }
2216 2462
2217 set_vregisterd(vd, bit_cast<int64_t, double>(result)); 2463 set_vregisterd(vd, 0, bit_cast<int64_t, double>(result));
2464 set_vregisterd(vd, 1, 0);
2218 } 2465 }
2219 2466
2220 2467
2221 void Simulator::DecodeFPCompare(Instr* instr) { 2468 void Simulator::DecodeFPCompare(Instr* instr) {
2222 const VRegister vn = instr->VnField(); 2469 const VRegister vn = instr->VnField();
2223 const VRegister vm = instr->VmField(); 2470 const VRegister vm = instr->VmField();
2224 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn)); 2471 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
2225 double vm_val; 2472 double vm_val;
2226 2473
2227 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) { 2474 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) {
2228 // Format(instr, "fcmpd 'vn, 'vm"); 2475 // Format(instr, "fcmpd 'vn, 'vm");
2229 vm_val = bit_cast<double, int64_t>(get_vregisterd(vm)); 2476 vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, 0));
2230 } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) { 2477 } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) {
2231 if (instr->VmField() == V0) { 2478 if (instr->VmField() == V0) {
2232 // Format(instr, "fcmpd 'vn, #0.0"); 2479 // Format(instr, "fcmpd 'vn, #0.0");
2233 vm_val = 0.0; 2480 vm_val = 0.0;
2234 } else { 2481 } else {
2235 UnimplementedInstruction(instr); 2482 UnimplementedInstruction(instr);
2236 return; 2483 return;
2237 } 2484 }
2238 } else { 2485 } else {
2239 UnimplementedInstruction(instr); 2486 UnimplementedInstruction(instr);
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
2359 int64_t parameter1, 2606 int64_t parameter1,
2360 int64_t parameter2, 2607 int64_t parameter2,
2361 int64_t parameter3, 2608 int64_t parameter3,
2362 bool fp_return, 2609 bool fp_return,
2363 bool fp_args) { 2610 bool fp_args) {
2364 // Save the SP register before the call so we can restore it. 2611 // Save the SP register before the call so we can restore it.
2365 const intptr_t sp_before_call = get_register(R31, R31IsSP); 2612 const intptr_t sp_before_call = get_register(R31, R31IsSP);
2366 2613
2367 // Setup parameters. 2614 // Setup parameters.
2368 if (fp_args) { 2615 if (fp_args) {
2369 set_vregisterd(V0, parameter0); 2616 set_vregisterd(V0, 0, parameter0);
2370 set_vregisterd(V1, parameter1); 2617 set_vregisterd(V0, 1, 0);
2371 set_vregisterd(V2, parameter2); 2618 set_vregisterd(V1, 0, parameter1);
2372 set_vregisterd(V3, parameter3); 2619 set_vregisterd(V1, 1, 0);
2620 set_vregisterd(V2, 0, parameter2);
2621 set_vregisterd(V2, 1, 0);
2622 set_vregisterd(V3, 0, parameter3);
2623 set_vregisterd(V3, 1, 0);
2373 } else { 2624 } else {
2374 set_register(R0, parameter0); 2625 set_register(R0, parameter0);
2375 set_register(R1, parameter1); 2626 set_register(R1, parameter1);
2376 set_register(R2, parameter2); 2627 set_register(R2, parameter2);
2377 set_register(R3, parameter3); 2628 set_register(R3, parameter3);
2378 } 2629 }
2379 2630
2380 // Make sure the activation frames are properly aligned. 2631 // Make sure the activation frames are properly aligned.
2381 intptr_t stack_pointer = sp_before_call; 2632 intptr_t stack_pointer = sp_before_call;
2382 if (OS::ActivationFrameAlignment() > 1) { 2633 if (OS::ActivationFrameAlignment() > 1) {
(...skipping 18 matching lines...) Expand all
2401 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) { 2652 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
2402 const Register r = static_cast<Register>(i); 2653 const Register r = static_cast<Register>(i);
2403 preserved_vals[i - kAbiFirstPreservedCpuReg] = get_register(r); 2654 preserved_vals[i - kAbiFirstPreservedCpuReg] = get_register(r);
2404 set_register(r, callee_saved_value); 2655 set_register(r, callee_saved_value);
2405 } 2656 }
2406 2657
2407 // Only the bottom half of the V registers must be preserved. 2658 // Only the bottom half of the V registers must be preserved.
2408 int64_t preserved_dvals[kAbiPreservedFpuRegCount]; 2659 int64_t preserved_dvals[kAbiPreservedFpuRegCount];
2409 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) { 2660 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
2410 const VRegister r = static_cast<VRegister>(i); 2661 const VRegister r = static_cast<VRegister>(i);
2411 preserved_dvals[i - kAbiFirstPreservedFpuReg] = get_vregisterd(r); 2662 preserved_dvals[i - kAbiFirstPreservedFpuReg] = get_vregisterd(r, 0);
2412 set_vregisterd(r, callee_saved_value); 2663 set_vregisterd(r, 0, callee_saved_value);
2664 set_vregisterd(r, 1, 0);
2413 } 2665 }
2414 2666
2415 // Start the simulation. 2667 // Start the simulation.
2416 Execute(); 2668 Execute();
2417 2669
2418 // Check that the callee-saved registers have been preserved, 2670 // Check that the callee-saved registers have been preserved,
2419 // and restore them with the original value. 2671 // and restore them with the original value.
2420 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) { 2672 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
2421 const Register r = static_cast<Register>(i); 2673 const Register r = static_cast<Register>(i);
2422 ASSERT(callee_saved_value == get_register(r)); 2674 ASSERT(callee_saved_value == get_register(r));
2423 set_register(r, preserved_vals[i - kAbiFirstPreservedCpuReg]); 2675 set_register(r, preserved_vals[i - kAbiFirstPreservedCpuReg]);
2424 } 2676 }
2425 2677
2426 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) { 2678 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
2427 const VRegister r = static_cast<VRegister>(i); 2679 const VRegister r = static_cast<VRegister>(i);
2428 ASSERT(callee_saved_value == get_vregisterd(r)); 2680 ASSERT(callee_saved_value == get_vregisterd(r, 0));
2429 set_vregisterd(r, preserved_dvals[i - kAbiFirstPreservedFpuReg]); 2681 set_vregisterd(r, 0, preserved_dvals[i - kAbiFirstPreservedFpuReg]);
2682 set_vregisterd(r, 1, 0);
2430 } 2683 }
2431 2684
2432 // Restore the SP register and return R0. 2685 // Restore the SP register and return R0.
2433 set_register(R31, sp_before_call, R31IsSP); 2686 set_register(R31, sp_before_call, R31IsSP);
2434 int64_t return_value; 2687 int64_t return_value;
2435 if (fp_return) { 2688 if (fp_return) {
2436 return_value = get_vregisterd(V0); 2689 return_value = get_vregisterd(V0, 0);
2437 } else { 2690 } else {
2438 return_value = get_register(R0); 2691 return_value = get_register(R0);
2439 } 2692 }
2440 return return_value; 2693 return return_value;
2441 } 2694 }
2442 2695
2443 2696
2444 void Simulator::Longjmp(uword pc, 2697 void Simulator::Longjmp(uword pc,
2445 uword sp, 2698 uword sp,
2446 uword fp, 2699 uword fp,
(...skipping 26 matching lines...) Expand all
2473 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); 2726 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception));
2474 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); 2727 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace));
2475 buf->Longjmp(); 2728 buf->Longjmp();
2476 } 2729 }
2477 2730
2478 } // namespace dart 2731 } // namespace dart
2479 2732
2480 #endif // !defined(HOST_ARCH_ARM64) 2733 #endif // !defined(HOST_ARCH_ARM64)
2481 2734
2482 #endif // defined TARGET_ARCH_ARM64 2735 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm64.h ('k') | runtime/vm/stub_code_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698