OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |