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

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

Issue 261783005: Begins work on arm64 floating point instructions. (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/unit_test.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 <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 // TODO(zra): GetVValue for doubles. 96 bool GetDValue(char* desc, int64_t* value);
97 // TODO(zra): Breakpoints. 97 // TODO(zra): Breakpoints.
98 }; 98 };
99 99
100 100
101 SimulatorDebugger::SimulatorDebugger(Simulator* sim) { 101 SimulatorDebugger::SimulatorDebugger(Simulator* sim) {
102 sim_ = sim; 102 sim_ = sim;
103 } 103 }
104 104
105 105
106 SimulatorDebugger::~SimulatorDebugger() { 106 SimulatorDebugger::~SimulatorDebugger() {
(...skipping 29 matching lines...) Expand all
136 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters)); 136 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
137 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) { 137 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {
138 if (strcmp(kNames[i], name) == 0) { 138 if (strcmp(kNames[i], name) == 0) {
139 return kRegisters[i]; 139 return kRegisters[i];
140 } 140 }
141 } 141 }
142 return kNoRegister; 142 return kNoRegister;
143 } 143 }
144 144
145 145
146 static VRegister LookupVRegisterByName(const char* name) {
147 int reg_nr = -1;
148 bool ok = SScanF(name, "v%d", &reg_nr);
149 if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfVRegisters)) {
150 return static_cast<VRegister>(reg_nr);
151 }
152 return kNoVRegister;
153 }
154
155
146 bool SimulatorDebugger::GetValue(char* desc, int64_t* value) { 156 bool SimulatorDebugger::GetValue(char* desc, int64_t* value) {
147 Register reg = LookupCpuRegisterByName(desc); 157 Register reg = LookupCpuRegisterByName(desc);
148 if (reg != kNoRegister) { 158 if (reg != kNoRegister) {
149 if (reg == ZR) { 159 if (reg == ZR) {
150 *value = 0; 160 *value = 0;
151 return true; 161 return true;
152 } 162 }
153 *value = sim_->get_register(reg); 163 *value = sim_->get_register(reg);
154 return true; 164 return true;
155 } 165 }
(...skipping 12 matching lines...) Expand all
168 return true; 178 return true;
169 } 179 }
170 bool retval = SScanF(desc, "0x%"Px64, value) == 1; 180 bool retval = SScanF(desc, "0x%"Px64, value) == 1;
171 if (!retval) { 181 if (!retval) {
172 retval = SScanF(desc, "%"Px64, value) == 1; 182 retval = SScanF(desc, "%"Px64, value) == 1;
173 } 183 }
174 return retval; 184 return retval;
175 } 185 }
176 186
177 187
188 bool SimulatorDebugger::GetDValue(char* desc, int64_t* value) {
189 VRegister vreg = LookupVRegisterByName(desc);
190 if (vreg != kNoVRegister) {
191 *value = sim_->get_vregisterd(vreg);
192 return true;
193 }
194 if (desc[0] == '*') {
195 int64_t addr;
196 if (GetValue(desc + 1, &addr)) {
197 if (Simulator::IsIllegalAddress(addr)) {
198 return false;
199 }
200 *value = *(reinterpret_cast<int64_t*>(addr));
201 return true;
202 }
203 }
204 return false;
205 }
206
207
178 void SimulatorDebugger::Debug() { 208 void SimulatorDebugger::Debug() {
179 intptr_t last_pc = -1; 209 intptr_t last_pc = -1;
180 bool done = false; 210 bool done = false;
181 211
182 #define COMMAND_SIZE 63 212 #define COMMAND_SIZE 63
183 #define ARG_SIZE 255 213 #define ARG_SIZE 255
184 214
185 #define STR(a) #a 215 #define STR(a) #a
186 #define XSTR(a) STR(a) 216 #define XSTR(a) STR(a)
187 217
(...skipping 30 matching lines...) Expand all
218 "%" XSTR(ARG_SIZE) "s " 248 "%" XSTR(ARG_SIZE) "s "
219 "%" XSTR(ARG_SIZE) "s", 249 "%" XSTR(ARG_SIZE) "s",
220 cmd, arg1, arg2); 250 cmd, arg1, arg2);
221 if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) { 251 if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
222 OS::Print("c/cont -- continue execution\n" 252 OS::Print("c/cont -- continue execution\n"
223 "disasm -- disassemble instrs at current pc location\n" 253 "disasm -- disassemble instrs at current pc location\n"
224 " other variants are:\n" 254 " other variants are:\n"
225 " disasm <address>\n" 255 " disasm <address>\n"
226 " disasm <address> <number_of_instructions>\n" 256 " disasm <address> <number_of_instructions>\n"
227 " by default 10 instrs are disassembled\n" 257 " by default 10 instrs are disassembled\n"
258 "flags -- print flag values\n"
228 "gdb -- transfer control to gdb\n" 259 "gdb -- transfer control to gdb\n"
229 "h/help -- print this help string\n" 260 "h/help -- print this help string\n"
230 "p/print <reg or value or *addr> -- print integer value\n" 261 "p/print <reg or value or *addr> -- print integer value\n"
262 "pd/printdouble <dreg or *addr> -- print double value\n"
231 "po/printobject <*reg or *addr> -- print object\n" 263 "po/printobject <*reg or *addr> -- print object\n"
232 "si/stepi -- single step an instruction\n" 264 "si/stepi -- single step an instruction\n"
233 "q/quit -- Quit the debugger and exit the program\n"); 265 "q/quit -- Quit the debugger and exit the program\n");
234 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) { 266 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
235 OS::Print("Quitting\n"); 267 OS::Print("Quitting\n");
236 OS::Exit(0); 268 OS::Exit(0);
237 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 269 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
238 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 270 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
239 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 271 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
240 // Execute the one instruction we broke at with breakpoints disabled. 272 // Execute the one instruction we broke at with breakpoints disabled.
241 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 273 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
242 // Leave the debugger shell. 274 // Leave the debugger shell.
243 done = true; 275 done = true;
244 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 276 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
245 if (args == 2) { 277 if (args == 2) {
246 int64_t value; 278 int64_t value;
247 if (GetValue(arg1, &value)) { 279 if (GetValue(arg1, &value)) {
248 OS::Print("%s: %"Pu64" 0x%"Px64"\n", arg1, value, value); 280 OS::Print("%s: %"Pu64" 0x%"Px64"\n", arg1, value, value);
249 } else { 281 } else {
250 OS::Print("%s unrecognized\n", arg1); 282 OS::Print("%s unrecognized\n", arg1);
251 } 283 }
252 } else { 284 } else {
253 OS::Print("print <reg or value or *addr>\n"); 285 OS::Print("print <reg or value or *addr>\n");
254 } 286 }
287 } else if ((strcmp(cmd, "pd") == 0) ||
288 (strcmp(cmd, "printdouble") == 0)) {
289 if (args == 2) {
290 int64_t long_value;
291 if (GetDValue(arg1, &long_value)) {
292 double dvalue = bit_cast<double, int64_t>(long_value);
293 OS::Print("%s: %"Pu64" 0x%"Px64" %.8g\n",
294 arg1, long_value, long_value, dvalue);
295 } else {
296 OS::Print("%s unrecognized\n", arg1);
297 }
298 } else {
299 OS::Print("printdouble <dreg or *addr>\n");
300 }
255 } else if ((strcmp(cmd, "po") == 0) || 301 } else if ((strcmp(cmd, "po") == 0) ||
256 (strcmp(cmd, "printobject") == 0)) { 302 (strcmp(cmd, "printobject") == 0)) {
257 if (args == 2) { 303 if (args == 2) {
258 int64_t value; 304 int64_t value;
259 // Make the dereferencing '*' optional. 305 // Make the dereferencing '*' optional.
260 if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) || 306 if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) ||
261 GetValue(arg1, &value)) { 307 GetValue(arg1, &value)) {
262 if (Isolate::Current()->heap()->Contains(value)) { 308 if (Isolate::Current()->heap()->Contains(value)) {
263 OS::Print("%s: \n", arg1); 309 OS::Print("%s: \n", arg1);
264 #if defined(DEBUG) 310 #if defined(DEBUG)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 // If start isn't a valid address, warn and use PC instead 346 // If start isn't a valid address, warn and use PC instead
301 OS::Print("First argument yields invalid address: 0x%"Px64"\n", 347 OS::Print("First argument yields invalid address: 0x%"Px64"\n",
302 start); 348 start);
303 OS::Print("Using PC instead\n"); 349 OS::Print("Using PC instead\n");
304 start = sim_->get_pc(); 350 start = sim_->get_pc();
305 } 351 }
306 end = start + (length * Instr::kInstrSize); 352 end = start + (length * Instr::kInstrSize);
307 } 353 }
308 } 354 }
309 Disassembler::Disassemble(start, end); 355 Disassembler::Disassemble(start, end);
356 } else if (strcmp(cmd, "flags") == 0) {
357 OS::Print("APSR: ");
358 OS::Print("N flag: %d; ", sim_->n_flag_);
359 OS::Print("Z flag: %d; ", sim_->z_flag_);
360 OS::Print("C flag: %d; ", sim_->c_flag_);
361 OS::Print("V flag: %d\n", sim_->v_flag_);
362 OS::Print("FPSCR: ");
363 OS::Print("N flag: %d; ", sim_->fp_n_flag_);
364 OS::Print("Z flag: %d; ", sim_->fp_z_flag_);
365 OS::Print("C flag: %d; ", sim_->fp_c_flag_);
366 OS::Print("V flag: %d\n", sim_->fp_v_flag_);
310 } else if (strcmp(cmd, "gdb") == 0) { 367 } else if (strcmp(cmd, "gdb") == 0) {
311 OS::Print("relinquishing control to gdb\n"); 368 OS::Print("relinquishing control to gdb\n");
312 OS::DebugBreak(); 369 OS::DebugBreak();
313 OS::Print("regaining control from gdb\n"); 370 OS::Print("regaining control from gdb\n");
314 } else { 371 } else {
315 OS::Print("Unknown command: %s\n", cmd); 372 OS::Print("Unknown command: %s\n", cmd);
316 } 373 }
317 } 374 }
318 delete[] line; 375 delete[] line;
319 } 376 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 // Setup architecture state. 468 // Setup architecture state.
412 // All registers are initialized to zero to start with. 469 // All registers are initialized to zero to start with.
413 for (int i = 0; i < kNumberOfCpuRegisters; i++) { 470 for (int i = 0; i < kNumberOfCpuRegisters; i++) {
414 registers_[i] = 0; 471 registers_[i] = 0;
415 } 472 }
416 n_flag_ = false; 473 n_flag_ = false;
417 z_flag_ = false; 474 z_flag_ = false;
418 c_flag_ = false; 475 c_flag_ = false;
419 v_flag_ = false; 476 v_flag_ = false;
420 477
478 for (int i = 0; i < kNumberOfVRegisters; i++) {
479 vregisters_[i].lo = 0;
480 vregisters_[i].hi = 0;
481 }
482 fp_n_flag_ = false;
483 fp_z_flag_ = false;
484 fp_c_flag_ = false;
485 fp_v_flag_ = false;
486
421 // The sp is initialized to point to the bottom (high address) of the 487 // The sp is initialized to point to the bottom (high address) of the
422 // allocated stack area. 488 // allocated stack area.
423 registers_[R31] = StackTop(); 489 registers_[R31] = StackTop();
424 // The lr and pc are initialized to a known bad value that will cause an 490 // The lr and pc are initialized to a known bad value that will cause an
425 // access violation if the simulator ever tries to execute it. 491 // access violation if the simulator ever tries to execute it.
426 registers_[LR] = kBadLR; 492 registers_[LR] = kBadLR;
427 pc_ = kBadLR; 493 pc_ = kBadLR;
428 } 494 }
429 495
430 496
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 int32_t Simulator::get_wregister(Register reg, R31Type r31t) const { 618 int32_t Simulator::get_wregister(Register reg, R31Type r31t) const {
553 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 619 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
554 if ((reg == R31) && (r31t == R31IsZR)) { 620 if ((reg == R31) && (r31t == R31IsZR)) {
555 return 0; 621 return 0;
556 } else { 622 } else {
557 return registers_[reg]; 623 return registers_[reg];
558 } 624 }
559 } 625 }
560 626
561 627
628 int64_t Simulator::get_vregisterd(VRegister reg) {
629 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
630 return vregisters_[reg].lo;
631 }
632
633
634 void Simulator::set_vregisterd(VRegister reg, int64_t value) {
635 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
636 vregisters_[reg].lo = value;
637 vregisters_[reg].hi = 0;
638 }
639
640
562 // Raw access to the PC register. 641 // Raw access to the PC register.
563 void Simulator::set_pc(int64_t value) { 642 void Simulator::set_pc(int64_t value) {
564 pc_modified_ = true; 643 pc_modified_ = true;
565 last_pc_ = pc_; 644 last_pc_ = pc_;
566 pc_ = value; 645 pc_ = value;
567 } 646 }
568 647
569 648
570 // Raw access to the pc. 649 // Raw access to the pc.
571 int64_t Simulator::get_pc() const { 650 int64_t Simulator::get_pc() const {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 void Simulator::SetVFlag(bool val) { 915 void Simulator::SetVFlag(bool val) {
837 v_flag_ = val; 916 v_flag_ = val;
838 } 917 }
839 918
840 919
841 void Simulator::DecodeMoveWide(Instr* instr) { 920 void Simulator::DecodeMoveWide(Instr* instr) {
842 const Register rd = instr->RdField(); 921 const Register rd = instr->RdField();
843 const int hw = instr->HWField(); 922 const int hw = instr->HWField();
844 const int64_t shift = hw << 4; 923 const int64_t shift = hw << 4;
845 const int64_t shifted_imm = 924 const int64_t shifted_imm =
846 static_cast<uint64_t>(instr->Imm16Field()) << shift; 925 static_cast<int64_t>(instr->Imm16Field()) << shift;
847 926
848 if (instr->SFField()) { 927 if (instr->SFField()) {
849 if (instr->Bits(29, 2) == 0) { 928 if (instr->Bits(29, 2) == 0) {
850 // Format(instr, "movn'sf 'rd, 'imm16 'hw"); 929 // Format(instr, "movn'sf 'rd, 'imm16 'hw");
851 set_register(rd, ~shifted_imm, instr->RdMode()); 930 set_register(rd, ~shifted_imm, instr->RdMode());
852 } else if (instr->Bits(29, 2) == 2) { 931 } else if (instr->Bits(29, 2) == 2) {
853 // Format(instr, "movz'sf 'rd, 'imm16 'hw"); 932 // Format(instr, "movz'sf 'rd, 'imm16 'hw");
854 set_register(rd, shifted_imm, instr->RdMode()); 933 set_register(rd, shifted_imm, instr->RdMode());
855 } else if (instr->Bits(29, 2) == 3) { 934 } else if (instr->Bits(29, 2) == 3) {
856 // Format(instr, "movk'sf 'rd, 'imm16 'hw"); 935 // Format(instr, "movk'sf 'rd, 'imm16 'hw");
(...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 UnimplementedInstruction(instr); 1971 UnimplementedInstruction(instr);
1893 } 1972 }
1894 } 1973 }
1895 1974
1896 1975
1897 void Simulator::DecodeDPSimd1(Instr* instr) { 1976 void Simulator::DecodeDPSimd1(Instr* instr) {
1898 UnimplementedInstruction(instr); 1977 UnimplementedInstruction(instr);
1899 } 1978 }
1900 1979
1901 1980
1981 void Simulator::DecodeFPImm(Instr* instr) {
1982 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) ||
1983 (instr->Bits(5, 5) != 0)) {
1984 UnimplementedInstruction(instr);
1985 return;
1986 }
1987 if (instr->Bit(22) == 1) {
1988 // Double.
1989 // Format(instr, "fmovd 'vd, #'immd");
1990 const VRegister vd = instr->VdField();
1991 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field());
1992 set_vregisterd(vd, immd);
1993 } else {
1994 // Single.
1995 UnimplementedInstruction(instr);
1996 }
1997 }
1998
1999
2000 void Simulator::DecodeFPIntCvt(Instr* instr) {
2001 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) ||
2002 (instr->Bits(22, 2) != 1)) {
2003 UnimplementedInstruction(instr);
2004 return;
2005 }
2006 if (instr->Bits(16, 3) == 6) {
2007 // Format(instr, "fmovrd 'rd, 'vn");
2008 const VRegister vn = instr->VnField();
2009 const Register rd = instr->RdField();
2010 const int64_t vn_val = get_vregisterd(vn);
2011 set_register(rd, vn_val, R31IsZR);
2012 } else if (instr->Bits(16, 3) == 7) {
2013 // Format(instr, "fmovdr 'vd, 'rn");
2014 const VRegister vd = instr->VdField();
2015 const Register rn = instr->RnField();
2016 const int64_t rn_val = get_register(rn, R31IsZR);
2017 set_vregisterd(vd, rn_val);
2018 } else {
2019 UnimplementedInstruction(instr);
2020 }
2021 }
2022
2023
2024 void Simulator::DecodeFP(Instr* instr) {
2025 if (instr->IsFPImmOp()) {
2026 DecodeFPImm(instr);
2027 } else if (instr->IsFPIntCvtOp()) {
2028 DecodeFPIntCvt(instr);
2029 } else {
2030 UnimplementedInstruction(instr);
2031 }
2032 }
2033
2034
1902 void Simulator::DecodeDPSimd2(Instr* instr) { 2035 void Simulator::DecodeDPSimd2(Instr* instr) {
1903 UnimplementedInstruction(instr); 2036 if (instr->IsFPOp()) {
2037 DecodeFP(instr);
2038 } else {
2039 UnimplementedInstruction(instr);
2040 }
1904 } 2041 }
1905 2042
1906 2043
1907 // Executes the current instruction. 2044 // Executes the current instruction.
1908 void Simulator::InstructionDecode(Instr* instr) { 2045 void Simulator::InstructionDecode(Instr* instr) {
1909 pc_modified_ = false; 2046 pc_modified_ = false;
1910 if (FLAG_trace_sim) { 2047 if (FLAG_trace_sim) {
1911 const uword start = reinterpret_cast<uword>(instr); 2048 const uword start = reinterpret_cast<uword>(instr);
1912 const uword end = start + Instr::kInstrSize; 2049 const uword end = start + Instr::kInstrSize;
1913 Disassembler::Disassemble(start, end); 2050 Disassembler::Disassemble(start, end);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1970 program_counter = get_pc(); 2107 program_counter = get_pc();
1971 } 2108 }
1972 } 2109 }
1973 } 2110 }
1974 2111
1975 2112
1976 int64_t Simulator::Call(int64_t entry, 2113 int64_t Simulator::Call(int64_t entry,
1977 int64_t parameter0, 2114 int64_t parameter0,
1978 int64_t parameter1, 2115 int64_t parameter1,
1979 int64_t parameter2, 2116 int64_t parameter2,
1980 int64_t parameter3) { 2117 int64_t parameter3,
2118 bool fp_return,
2119 bool fp_args) {
1981 // Save the SP register before the call so we can restore it. 2120 // Save the SP register before the call so we can restore it.
1982 intptr_t sp_before_call = get_register(R31, R31IsSP); 2121 intptr_t sp_before_call = get_register(R31, R31IsSP);
1983 2122
1984 // Setup parameters. 2123 // Setup parameters.
1985 set_register(R0, parameter0); 2124 if (fp_args) {
1986 set_register(R1, parameter1); 2125 set_vregisterd(V0, parameter0);
1987 set_register(R2, parameter2); 2126 set_vregisterd(V1, parameter1);
1988 set_register(R3, parameter3); 2127 set_vregisterd(V2, parameter2);
2128 set_vregisterd(V3, parameter3);
2129 } else {
2130 set_register(R0, parameter0);
2131 set_register(R1, parameter1);
2132 set_register(R2, parameter2);
2133 set_register(R3, parameter3);
2134 }
1989 2135
1990 // Make sure the activation frames are properly aligned. 2136 // Make sure the activation frames are properly aligned.
1991 intptr_t stack_pointer = sp_before_call; 2137 intptr_t stack_pointer = sp_before_call;
1992 if (OS::ActivationFrameAlignment() > 1) { 2138 if (OS::ActivationFrameAlignment() > 1) {
1993 stack_pointer = 2139 stack_pointer =
1994 Utils::RoundDown(stack_pointer, OS::ActivationFrameAlignment()); 2140 Utils::RoundDown(stack_pointer, OS::ActivationFrameAlignment());
1995 } 2141 }
1996 set_register(R31, stack_pointer, R31IsSP); 2142 set_register(R31, stack_pointer, R31IsSP);
1997 2143
1998 // Prepare to execute the code at entry. 2144 // Prepare to execute the code at entry.
1999 set_pc(entry); 2145 set_pc(entry);
2000 // Put down marker for end of simulation. The simulator will stop simulation 2146 // Put down marker for end of simulation. The simulator will stop simulation
2001 // when the PC reaches this value. By saving the "end simulation" value into 2147 // when the PC reaches this value. By saving the "end simulation" value into
2002 // the LR the simulation stops when returning to this call point. 2148 // the LR the simulation stops when returning to this call point.
2003 set_register(LR, kEndSimulatingPC); 2149 set_register(LR, kEndSimulatingPC);
2004 2150
2005 // Remember the values of callee-saved registers. 2151 // Remember the values of callee-saved registers, and set them up with a
2006 int64_t r19_val = get_register(R19); 2152 // known value so that we are able to check that they are preserved
2007 int64_t r20_val = get_register(R20); 2153 // properly across Dart execution.
2008 int64_t r21_val = get_register(R21); 2154 int64_t preserved_vals[kAbiPreservedCpuRegCount];
2009 int64_t r22_val = get_register(R22); 2155 int64_t callee_saved_value = icount_;
2010 int64_t r23_val = get_register(R23); 2156 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
2011 int64_t r24_val = get_register(R24); 2157 const Register r = static_cast<Register>(i);
2012 int64_t r25_val = get_register(R25); 2158 preserved_vals[i - kAbiFirstPreservedCpuReg] = get_register(r);
2013 int64_t r26_val = get_register(R26); 2159 set_register(r, callee_saved_value);
2014 int64_t r27_val = get_register(R27); 2160 }
2015 int64_t r28_val = get_register(R28);
2016 int64_t r29_val = get_register(R29);
2017 2161
2018 // Setup the callee-saved registers with a known value. To be able to check 2162 // Only the bottom half of the V registers must be preserved.
2019 // that they are preserved properly across dart execution. 2163 int64_t preserved_dvals[kAbiPreservedFpuRegCount];
2020 int64_t callee_saved_value = icount_; 2164 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
2021 set_register(R19, callee_saved_value); 2165 const VRegister r = static_cast<VRegister>(i);
2022 set_register(R20, callee_saved_value); 2166 preserved_dvals[i - kAbiFirstPreservedFpuReg] = get_vregisterd(r);
2023 set_register(R21, callee_saved_value); 2167 set_vregisterd(r, callee_saved_value);
2024 set_register(R22, callee_saved_value); 2168 }
2025 set_register(R23, callee_saved_value);
2026 set_register(R24, callee_saved_value);
2027 set_register(R25, callee_saved_value);
2028 set_register(R26, callee_saved_value);
2029 set_register(R27, callee_saved_value);
2030 set_register(R28, callee_saved_value);
2031 set_register(R29, callee_saved_value);
2032 2169
2033 // Start the simulation 2170 // Start the simulation
2034 Execute(); 2171 Execute();
2035 2172
2036 // Check that the callee-saved registers have been preserved. 2173 // Check that the callee-saved registers have been preserved,
2037 ASSERT(callee_saved_value == get_register(R19)); 2174 // and restore them with the original value
2038 ASSERT(callee_saved_value == get_register(R20)); 2175 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
2039 ASSERT(callee_saved_value == get_register(R21)); 2176 const Register r = static_cast<Register>(i);
2040 ASSERT(callee_saved_value == get_register(R22)); 2177 ASSERT(callee_saved_value == get_register(r));
2041 ASSERT(callee_saved_value == get_register(R23)); 2178 set_register(r, preserved_vals[i - kAbiFirstPreservedCpuReg]);
2042 ASSERT(callee_saved_value == get_register(R24)); 2179 }
2043 ASSERT(callee_saved_value == get_register(R25));
2044 ASSERT(callee_saved_value == get_register(R26));
2045 ASSERT(callee_saved_value == get_register(R27));
2046 ASSERT(callee_saved_value == get_register(R28));
2047 ASSERT(callee_saved_value == get_register(R29));
2048 2180
2049 // Restore callee-saved registers with the original value. 2181 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
2050 set_register(R19, r19_val); 2182 const VRegister r = static_cast<VRegister>(i);
2051 set_register(R20, r20_val); 2183 ASSERT(callee_saved_value == get_vregisterd(r));
2052 set_register(R21, r21_val); 2184 set_vregisterd(r, preserved_dvals[i - kAbiFirstPreservedFpuReg]);
2053 set_register(R22, r22_val); 2185 }
2054 set_register(R23, r23_val);
2055 set_register(R24, r24_val);
2056 set_register(R25, r25_val);
2057 set_register(R26, r26_val);
2058 set_register(R27, r27_val);
2059 set_register(R28, r28_val);
2060 set_register(R29, r29_val);
2061 2186
2062 // Restore the SP register and return R0. 2187 // Restore the SP register and return R0.
2063 set_register(R31, sp_before_call, R31IsSP); 2188 set_register(R31, sp_before_call, R31IsSP);
2064 int64_t return_value; 2189 int64_t return_value;
2065 return_value = get_register(R0); 2190 if (fp_return) {
2191 return_value = get_vregisterd(V0);
2192 } else {
2193 return_value = get_register(R0);
2194 }
2066 return return_value; 2195 return return_value;
2067 } 2196 }
2068 2197
2069 2198
2070 void Simulator::Longjmp(uword pc, 2199 void Simulator::Longjmp(uword pc,
2071 uword sp, 2200 uword sp,
2072 uword fp, 2201 uword fp,
2073 RawObject* raw_exception, 2202 RawObject* raw_exception,
2074 RawObject* raw_stacktrace) { 2203 RawObject* raw_stacktrace) {
2075 // Walk over all setjmp buffers (simulated --> C++ transitions) 2204 // Walk over all setjmp buffers (simulated --> C++ transitions)
(...skipping 23 matching lines...) Expand all
2099 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); 2228 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception));
2100 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); 2229 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace));
2101 buf->Longjmp(); 2230 buf->Longjmp();
2102 } 2231 }
2103 2232
2104 } // namespace dart 2233 } // namespace dart
2105 2234
2106 #endif // !defined(HOST_ARCH_ARM64) 2235 #endif // !defined(HOST_ARCH_ARM64)
2107 2236
2108 #endif // defined TARGET_ARCH_ARM64 2237 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm64.h ('k') | runtime/vm/unit_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698