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

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

Issue 311903004: Fixes to run "Hello, world!" on arm64 hardware. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 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 645 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 Simulator* simulator = Isolate::Current()->simulator(); 656 Simulator* simulator = Isolate::Current()->simulator();
657 if (simulator == NULL) { 657 if (simulator == NULL) {
658 simulator = new Simulator(); 658 simulator = new Simulator();
659 Isolate::Current()->set_simulator(simulator); 659 Isolate::Current()->set_simulator(simulator);
660 } 660 }
661 return simulator; 661 return simulator;
662 } 662 }
663 663
664 664
665 // Sets the register in the architecture state. 665 // Sets the register in the architecture state.
666 void Simulator::set_register(Register reg, int64_t value, R31Type r31t) { 666 void Simulator::set_register(
667 // register is in range, and if it is R31, a mode is specified. 667 Instr* instr, Register reg, int64_t value, R31Type r31t) {
668 // Register is in range.
668 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 669 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
669 if ((reg != R31) || (r31t != R31IsZR)) { 670 if ((reg != R31) || (r31t != R31IsZR)) {
670 registers_[reg] = value; 671 registers_[reg] = value;
672 // If we're setting CSP, make sure it is 16-byte aligned. In truth, CSP
673 // can store addresses that are not 16-byte aligned, but loads and stores
674 // are not allowed through CSP when it is not aligned. Thus, this check is
675 // more conservative that necessary. However, it will likely be more
676 // useful to find the program locations where CSP is set to a bad value,
677 // than to find only the resulting loads/stores that would cause a fault on
678 // hardware.
679 if ((instr != NULL) && (reg == R31) && !Utils::IsAligned(value, 16)) {
680 UnalignedAccess("CSP set", value, instr);
681 }
671 } 682 }
672 } 683 }
673 684
674 685
675 // Get the register from the architecture state. 686 // Get the register from the architecture state.
676 int64_t Simulator::get_register(Register reg, R31Type r31t) const { 687 int64_t Simulator::get_register(Register reg, R31Type r31t) const {
677 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 688 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
678 if ((reg == R31) && (r31t == R31IsZR)) { 689 if ((reg == R31) && (r31t == R31IsZR)) {
679 return 0; 690 return 0;
680 } else { 691 } else {
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 void Simulator::DecodeMoveWide(Instr* instr) { 1038 void Simulator::DecodeMoveWide(Instr* instr) {
1028 const Register rd = instr->RdField(); 1039 const Register rd = instr->RdField();
1029 const int hw = instr->HWField(); 1040 const int hw = instr->HWField();
1030 const int64_t shift = hw << 4; 1041 const int64_t shift = hw << 4;
1031 const int64_t shifted_imm = 1042 const int64_t shifted_imm =
1032 static_cast<int64_t>(instr->Imm16Field()) << shift; 1043 static_cast<int64_t>(instr->Imm16Field()) << shift;
1033 1044
1034 if (instr->SFField()) { 1045 if (instr->SFField()) {
1035 if (instr->Bits(29, 2) == 0) { 1046 if (instr->Bits(29, 2) == 0) {
1036 // Format(instr, "movn'sf 'rd, 'imm16 'hw"); 1047 // Format(instr, "movn'sf 'rd, 'imm16 'hw");
1037 set_register(rd, ~shifted_imm, instr->RdMode()); 1048 set_register(instr, rd, ~shifted_imm, instr->RdMode());
1038 } else if (instr->Bits(29, 2) == 2) { 1049 } else if (instr->Bits(29, 2) == 2) {
1039 // Format(instr, "movz'sf 'rd, 'imm16 'hw"); 1050 // Format(instr, "movz'sf 'rd, 'imm16 'hw");
1040 set_register(rd, shifted_imm, instr->RdMode()); 1051 set_register(instr, rd, shifted_imm, instr->RdMode());
1041 } else if (instr->Bits(29, 2) == 3) { 1052 } else if (instr->Bits(29, 2) == 3) {
1042 // Format(instr, "movk'sf 'rd, 'imm16 'hw"); 1053 // Format(instr, "movk'sf 'rd, 'imm16 'hw");
1043 const int64_t rd_val = get_register(rd, instr->RdMode()); 1054 const int64_t rd_val = get_register(rd, instr->RdMode());
1044 const int64_t result = (rd_val & ~(0xffffL << shift)) | shifted_imm; 1055 const int64_t result = (rd_val & ~(0xffffL << shift)) | shifted_imm;
1045 set_register(rd, result, instr->RdMode()); 1056 set_register(instr, rd, result, instr->RdMode());
1046 } else { 1057 } else {
1047 UnimplementedInstruction(instr); 1058 UnimplementedInstruction(instr);
1048 } 1059 }
1049 } else if ((hw & 0x2) == 0) { 1060 } else if ((hw & 0x2) == 0) {
1050 if (instr->Bits(29, 2) == 0) { 1061 if (instr->Bits(29, 2) == 0) {
1051 // Format(instr, "movn'sf 'rd, 'imm16 'hw"); 1062 // Format(instr, "movn'sf 'rd, 'imm16 'hw");
1052 set_wregister(rd, ~shifted_imm & kWRegMask, instr->RdMode()); 1063 set_wregister(rd, ~shifted_imm & kWRegMask, instr->RdMode());
1053 } else if (instr->Bits(29, 2) == 2) { 1064 } else if (instr->Bits(29, 2) == 2) {
1054 // Format(instr, "movz'sf 'rd, 'imm16 'hw"); 1065 // Format(instr, "movz'sf 'rd, 'imm16 'hw");
1055 set_wregister(rd, shifted_imm & kWRegMask, instr->RdMode()); 1066 set_wregister(rd, shifted_imm & kWRegMask, instr->RdMode());
(...skipping 17 matching lines...) Expand all
1073 // Format(instr, "addi'sf's 'rd, 'rn, 'imm12s"); 1084 // Format(instr, "addi'sf's 'rd, 'rn, 'imm12s");
1074 // Format(instr, "subi'sf's 'rd, 'rn, 'imm12s"); 1085 // Format(instr, "subi'sf's 'rd, 'rn, 'imm12s");
1075 const Register rd = instr->RdField(); 1086 const Register rd = instr->RdField();
1076 const Register rn = instr->RnField(); 1087 const Register rn = instr->RnField();
1077 const uint32_t imm = (instr->Bit(22) == 1) ? (instr->Imm12Field() << 12) 1088 const uint32_t imm = (instr->Bit(22) == 1) ? (instr->Imm12Field() << 12)
1078 : (instr->Imm12Field()); 1089 : (instr->Imm12Field());
1079 if (instr->SFField()) { 1090 if (instr->SFField()) {
1080 // 64-bit add. 1091 // 64-bit add.
1081 const int64_t rn_val = get_register(rn, instr->RnMode()); 1092 const int64_t rn_val = get_register(rn, instr->RnMode());
1082 const int64_t alu_out = addition ? (rn_val + imm) : (rn_val - imm); 1093 const int64_t alu_out = addition ? (rn_val + imm) : (rn_val - imm);
1083 set_register(rd, alu_out, instr->RdMode()); 1094 set_register(instr, rd, alu_out, instr->RdMode());
1084 if (instr->HasS()) { 1095 if (instr->HasS()) {
1085 SetNZFlagsX(alu_out); 1096 SetNZFlagsX(alu_out);
1086 if (addition) { 1097 if (addition) {
1087 SetCFlag(CarryFromX(rn_val, imm)); 1098 SetCFlag(CarryFromX(rn_val, imm));
1088 } else { 1099 } else {
1089 SetCFlag(!BorrowFromX(rn_val, imm)); 1100 SetCFlag(!BorrowFromX(rn_val, imm));
1090 } 1101 }
1091 SetVFlag(OverflowFromX(alu_out, rn_val, imm, addition)); 1102 SetVFlag(OverflowFromX(alu_out, rn_val, imm, addition));
1092 } 1103 }
1093 } else { 1104 } else {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 if (out_size == kXRegSizeInBits) { 1155 if (out_size == kXRegSizeInBits) {
1145 SetNZFlagsX(alu_out); 1156 SetNZFlagsX(alu_out);
1146 } else { 1157 } else {
1147 SetNZFlagsW(alu_out); 1158 SetNZFlagsW(alu_out);
1148 } 1159 }
1149 SetCFlag(false); 1160 SetCFlag(false);
1150 SetVFlag(false); 1161 SetVFlag(false);
1151 } 1162 }
1152 1163
1153 if (out_size == kXRegSizeInBits) { 1164 if (out_size == kXRegSizeInBits) {
1154 set_register(rd, alu_out, instr->RdMode()); 1165 set_register(instr, rd, alu_out, instr->RdMode());
1155 } else { 1166 } else {
1156 set_wregister(rd, alu_out, instr->RdMode()); 1167 set_wregister(rd, alu_out, instr->RdMode());
1157 } 1168 }
1158 } 1169 }
1159 1170
1160 1171
1161 void Simulator::DecodePCRel(Instr* instr) { 1172 void Simulator::DecodePCRel(Instr* instr) {
1162 const int op = instr->Bit(31); 1173 const int op = instr->Bit(31);
1163 if (op == 0) { 1174 if (op == 0) {
1164 // Format(instr, "adr 'rd, 'pcrel") 1175 // Format(instr, "adr 'rd, 'pcrel")
1165 const Register rd = instr->RdField(); 1176 const Register rd = instr->RdField();
1166 const int64_t immhi = instr->SImm19Field(); 1177 const int64_t immhi = instr->SImm19Field();
1167 const int64_t immlo = instr->Bits(29, 2); 1178 const int64_t immlo = instr->Bits(29, 2);
1168 const int64_t off = (immhi << 2) | immlo; 1179 const int64_t off = (immhi << 2) | immlo;
1169 const int64_t dest = get_pc() + off; 1180 const int64_t dest = get_pc() + off;
1170 set_register(rd, dest, instr->RdMode()); 1181 set_register(instr, rd, dest, instr->RdMode());
1171 } else { 1182 } else {
1172 UnimplementedInstruction(instr); 1183 UnimplementedInstruction(instr);
1173 } 1184 }
1174 } 1185 }
1175 1186
1176 1187
1177 void Simulator::DecodeDPImmediate(Instr* instr) { 1188 void Simulator::DecodeDPImmediate(Instr* instr) {
1178 if (instr->IsMoveWideOp()) { 1189 if (instr->IsMoveWideOp()) {
1179 DecodeMoveWide(instr); 1190 DecodeMoveWide(instr);
1180 } else if (instr->IsAddSubImmOp()) { 1191 } else if (instr->IsAddSubImmOp()) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 OS::Print("Call to host function at 0x%" Pd "\n", external); 1291 OS::Print("Call to host function at 0x%" Pd "\n", external);
1281 } 1292 }
1282 1293
1283 if ((redirection->call_kind() == kRuntimeCall) || 1294 if ((redirection->call_kind() == kRuntimeCall) ||
1284 (redirection->call_kind() == kBootstrapNativeCall) || 1295 (redirection->call_kind() == kBootstrapNativeCall) ||
1285 (redirection->call_kind() == kNativeCall)) { 1296 (redirection->call_kind() == kNativeCall)) {
1286 // Set the top_exit_frame_info of this simulator to the native stack. 1297 // Set the top_exit_frame_info of this simulator to the native stack.
1287 set_top_exit_frame_info(reinterpret_cast<uword>(&buffer)); 1298 set_top_exit_frame_info(reinterpret_cast<uword>(&buffer));
1288 } 1299 }
1289 if (redirection->call_kind() == kRuntimeCall) { 1300 if (redirection->call_kind() == kRuntimeCall) {
1290 NativeArguments arguments; 1301 NativeArguments* arguments =
1291 ASSERT(sizeof(NativeArguments) == 4*kWordSize); 1302 reinterpret_cast<NativeArguments*>(get_register(R0));
1292 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0));
1293 arguments.argc_tag_ = get_register(R1);
1294 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2));
1295 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));
1296 SimulatorRuntimeCall target = 1303 SimulatorRuntimeCall target =
1297 reinterpret_cast<SimulatorRuntimeCall>(external); 1304 reinterpret_cast<SimulatorRuntimeCall>(external);
1298 target(arguments); 1305 target(*arguments);
1299 set_register(R0, icount_); // Zap result register from void function. 1306 // Zap result register from void function.
1300 set_register(R1, icount_); 1307 set_register(instr, R0, icount_);
1308 set_register(instr, R1, icount_);
1301 } else if (redirection->call_kind() == kLeafRuntimeCall) { 1309 } else if (redirection->call_kind() == kLeafRuntimeCall) {
1302 ASSERT((0 <= redirection->argument_count()) && 1310 ASSERT((0 <= redirection->argument_count()) &&
1303 (redirection->argument_count() <= 8)); 1311 (redirection->argument_count() <= 8));
1304 SimulatorLeafRuntimeCall target = 1312 SimulatorLeafRuntimeCall target =
1305 reinterpret_cast<SimulatorLeafRuntimeCall>(external); 1313 reinterpret_cast<SimulatorLeafRuntimeCall>(external);
1306 const int64_t r0 = get_register(R0); 1314 const int64_t r0 = get_register(R0);
1307 const int64_t r1 = get_register(R1); 1315 const int64_t r1 = get_register(R1);
1308 const int64_t r2 = get_register(R2); 1316 const int64_t r2 = get_register(R2);
1309 const int64_t r3 = get_register(R3); 1317 const int64_t r3 = get_register(R3);
1310 const int64_t r4 = get_register(R4); 1318 const int64_t r4 = get_register(R4);
1311 const int64_t r5 = get_register(R5); 1319 const int64_t r5 = get_register(R5);
1312 const int64_t r6 = get_register(R6); 1320 const int64_t r6 = get_register(R6);
1313 const int64_t r7 = get_register(R7); 1321 const int64_t r7 = get_register(R7);
1314 const int64_t res = target(r0, r1, r2, r3, r4, r5, r6, r7); 1322 const int64_t res = target(r0, r1, r2, r3, r4, r5, r6, r7);
1315 set_register(R0, res); // Set returned result from function. 1323 set_register(instr, R0, res); // Set returned result from function.
1316 set_register(R1, icount_); // Zap unused result register. 1324 set_register(instr, R1, icount_); // Zap unused result register.
1317 } else if (redirection->call_kind() == kLeafFloatRuntimeCall) { 1325 } else if (redirection->call_kind() == kLeafFloatRuntimeCall) {
1318 ASSERT((0 <= redirection->argument_count()) && 1326 ASSERT((0 <= redirection->argument_count()) &&
1319 (redirection->argument_count() <= 8)); 1327 (redirection->argument_count() <= 8));
1320 SimulatorLeafFloatRuntimeCall target = 1328 SimulatorLeafFloatRuntimeCall target =
1321 reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external); 1329 reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external);
1322 const double d0 = bit_cast<double, int64_t>(get_vregisterd(V0, 0)); 1330 const double d0 = bit_cast<double, int64_t>(get_vregisterd(V0, 0));
1323 const double d1 = bit_cast<double, int64_t>(get_vregisterd(V1, 0)); 1331 const double d1 = bit_cast<double, int64_t>(get_vregisterd(V1, 0));
1324 const double d2 = bit_cast<double, int64_t>(get_vregisterd(V2, 0)); 1332 const double d2 = bit_cast<double, int64_t>(get_vregisterd(V2, 0));
1325 const double d3 = bit_cast<double, int64_t>(get_vregisterd(V3, 0)); 1333 const double d3 = bit_cast<double, int64_t>(get_vregisterd(V3, 0));
1326 const double d4 = bit_cast<double, int64_t>(get_vregisterd(V4, 0)); 1334 const double d4 = bit_cast<double, int64_t>(get_vregisterd(V4, 0));
1327 const double d5 = bit_cast<double, int64_t>(get_vregisterd(V5, 0)); 1335 const double d5 = bit_cast<double, int64_t>(get_vregisterd(V5, 0));
1328 const double d6 = bit_cast<double, int64_t>(get_vregisterd(V6, 0)); 1336 const double d6 = bit_cast<double, int64_t>(get_vregisterd(V6, 0));
1329 const double d7 = bit_cast<double, int64_t>(get_vregisterd(V7, 0)); 1337 const double d7 = bit_cast<double, int64_t>(get_vregisterd(V7, 0));
1330 const double res = target(d0, d1, d2, d3, d4, d5, d6, d7); 1338 const double res = target(d0, d1, d2, d3, d4, d5, d6, d7);
1331 set_vregisterd(V0, 0, bit_cast<int64_t, double>(res)); 1339 set_vregisterd(V0, 0, bit_cast<int64_t, double>(res));
1332 set_vregisterd(V0, 1, 0); 1340 set_vregisterd(V0, 1, 0);
1333 } else if (redirection->call_kind() == kBootstrapNativeCall) { 1341 } else if (redirection->call_kind() == kBootstrapNativeCall) {
1334 NativeArguments* arguments; 1342 NativeArguments* arguments;
1335 arguments = reinterpret_cast<NativeArguments*>(get_register(R0)); 1343 arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
1336 SimulatorBootstrapNativeCall target = 1344 SimulatorBootstrapNativeCall target =
1337 reinterpret_cast<SimulatorBootstrapNativeCall>(external); 1345 reinterpret_cast<SimulatorBootstrapNativeCall>(external);
1338 target(arguments); 1346 target(arguments);
1339 set_register(R0, icount_); // Zap result register from void function. 1347 // Zap result register from void function.
1348 set_register(instr, R0, icount_);
1340 } else { 1349 } else {
1341 ASSERT(redirection->call_kind() == kNativeCall); 1350 ASSERT(redirection->call_kind() == kNativeCall);
1342 NativeArguments* arguments; 1351 NativeArguments* arguments;
1343 arguments = reinterpret_cast<NativeArguments*>(get_register(R0)); 1352 arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
1344 uword target_func = get_register(R1); 1353 uword target_func = get_register(R1);
1345 SimulatorNativeCall target = 1354 SimulatorNativeCall target =
1346 reinterpret_cast<SimulatorNativeCall>(external); 1355 reinterpret_cast<SimulatorNativeCall>(external);
1347 target(arguments, target_func); 1356 target(arguments, target_func);
1348 set_register(R0, icount_); // Zap result register from void function. 1357 // Zap result register from void function.
1349 set_register(R1, icount_); 1358 set_register(instr, R0, icount_);
1359 set_register(instr, R1, icount_);
1350 } 1360 }
1351 set_top_exit_frame_info(0); 1361 set_top_exit_frame_info(0);
1352 1362
1353 // Zap caller-saved registers, since the actual runtime call could have 1363 // Zap caller-saved registers, since the actual runtime call could have
1354 // used them. 1364 // used them.
1355 set_register(R2, icount_); 1365 set_register(instr, R2, icount_);
1356 set_register(R3, icount_); 1366 set_register(instr, R3, icount_);
1357 set_register(R4, icount_); 1367 set_register(instr, R4, icount_);
1358 set_register(R5, icount_); 1368 set_register(instr, R5, icount_);
1359 set_register(R6, icount_); 1369 set_register(instr, R6, icount_);
1360 set_register(R7, icount_); 1370 set_register(instr, R7, icount_);
1361 set_register(R8, icount_); 1371 set_register(instr, R8, icount_);
1362 set_register(R9, icount_); 1372 set_register(instr, R9, icount_);
1363 set_register(R10, icount_); 1373 set_register(instr, R10, icount_);
1364 set_register(R11, icount_); 1374 set_register(instr, R11, icount_);
1365 set_register(R12, icount_); 1375 set_register(instr, R12, icount_);
1366 set_register(R13, icount_); 1376 set_register(instr, R13, icount_);
1367 set_register(R14, icount_); 1377 set_register(instr, R14, icount_);
1368 set_register(R15, icount_); 1378 set_register(instr, R15, icount_);
1369 set_register(IP0, icount_); 1379 set_register(instr, IP0, icount_);
1370 set_register(IP1, icount_); 1380 set_register(instr, IP1, icount_);
1371 set_register(R18, icount_); 1381 set_register(instr, R18, icount_);
1372 set_register(LR, icount_); 1382 set_register(instr, LR, icount_);
1373 1383
1374 // TODO(zra): Zap caller-saved fpu registers. 1384 // TODO(zra): Zap caller-saved fpu registers.
1375 1385
1376 // Return. 1386 // Return.
1377 set_pc(saved_lr); 1387 set_pc(saved_lr);
1378 } else { 1388 } else {
1379 // Coming via long jump from a throw. Continue to exception handler. 1389 // Coming via long jump from a throw. Continue to exception handler.
1380 set_top_exit_frame_info(0); 1390 set_top_exit_frame_info(0);
1381 } 1391 }
1382 } 1392 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 } 1460 }
1451 1461
1452 1462
1453 void Simulator::DecodeUnconditionalBranch(Instr* instr) { 1463 void Simulator::DecodeUnconditionalBranch(Instr* instr) {
1454 const bool link = instr->Bit(31) == 1; 1464 const bool link = instr->Bit(31) == 1;
1455 const int64_t imm26 = instr->SImm26Field(); 1465 const int64_t imm26 = instr->SImm26Field();
1456 const int64_t dest = get_pc() + (imm26 << 2); 1466 const int64_t dest = get_pc() + (imm26 << 2);
1457 const int64_t ret = get_pc() + Instr::kInstrSize; 1467 const int64_t ret = get_pc() + Instr::kInstrSize;
1458 set_pc(dest); 1468 set_pc(dest);
1459 if (link) { 1469 if (link) {
1460 set_register(LR, ret); 1470 set_register(instr, LR, ret);
1461 } 1471 }
1462 } 1472 }
1463 1473
1464 1474
1465 void Simulator::DecodeUnconditionalBranchReg(Instr* instr) { 1475 void Simulator::DecodeUnconditionalBranchReg(Instr* instr) {
1466 if ((instr->Bits(0, 5) == 0) && (instr->Bits(10, 6) == 0) && 1476 if ((instr->Bits(0, 5) == 0) && (instr->Bits(10, 6) == 0) &&
1467 (instr->Bits(16, 5) == 0x1f)) { 1477 (instr->Bits(16, 5) == 0x1f)) {
1468 switch (instr->Bits(21, 4)) { 1478 switch (instr->Bits(21, 4)) {
1469 case 0: { 1479 case 0: {
1470 // Format(instr, "br 'rn"); 1480 // Format(instr, "br 'rn");
1471 const Register rn = instr->RnField(); 1481 const Register rn = instr->RnField();
1472 const int64_t dest = get_register(rn, instr->RnMode()); 1482 const int64_t dest = get_register(rn, instr->RnMode());
1473 set_pc(dest); 1483 set_pc(dest);
1474 break; 1484 break;
1475 } 1485 }
1476 case 1: { 1486 case 1: {
1477 // Format(instr, "blr 'rn"); 1487 // Format(instr, "blr 'rn");
1478 const Register rn = instr->RnField(); 1488 const Register rn = instr->RnField();
1479 const int64_t dest = get_register(rn, instr->RnMode()); 1489 const int64_t dest = get_register(rn, instr->RnMode());
1480 const int64_t ret = get_pc() + Instr::kInstrSize; 1490 const int64_t ret = get_pc() + Instr::kInstrSize;
1481 set_pc(dest); 1491 set_pc(dest);
1482 set_register(LR, ret); 1492 set_register(instr, LR, ret);
1483 break; 1493 break;
1484 } 1494 }
1485 case 2: { 1495 case 2: {
1486 // Format(instr, "ret 'rn"); 1496 // Format(instr, "ret 'rn");
1487 const Register rn = instr->RnField(); 1497 const Register rn = instr->RnField();
1488 const int64_t rn_val = get_register(rn, instr->RnMode()); 1498 const int64_t rn_val = get_register(rn, instr->RnMode());
1489 set_pc(rn_val); 1499 set_pc(rn_val);
1490 break; 1500 break;
1491 } 1501 }
1492 default: 1502 default:
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 break; 1706 break;
1697 default: 1707 default:
1698 UNREACHABLE(); 1708 UNREACHABLE();
1699 break; 1709 break;
1700 } 1710 }
1701 1711
1702 // Write to register. 1712 // Write to register.
1703 if (use_w) { 1713 if (use_w) {
1704 set_wregister(rt, static_cast<int32_t>(val), R31IsZR); 1714 set_wregister(rt, static_cast<int32_t>(val), R31IsZR);
1705 } else { 1715 } else {
1706 set_register(rt, val, R31IsZR); 1716 set_register(instr, rt, val, R31IsZR);
1707 } 1717 }
1708 } 1718 }
1709 } 1719 }
1710 1720
1711 // Do writeback. 1721 // Do writeback.
1712 if (wb) { 1722 if (wb) {
1713 set_register(rn, wb_address, R31IsSP); 1723 set_register(instr, rn, wb_address, R31IsSP);
1714 } 1724 }
1715 } 1725 }
1716 1726
1717 1727
1718 void Simulator::DecodeLoadRegLiteral(Instr* instr) { 1728 void Simulator::DecodeLoadRegLiteral(Instr* instr) {
1719 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || 1729 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) ||
1720 (instr->Bits(24, 3) != 0)) { 1730 (instr->Bits(24, 3) != 0)) {
1721 UnimplementedInstruction(instr); 1731 UnimplementedInstruction(instr);
1722 } 1732 }
1723 1733
1724 const Register rt = instr->RtField(); 1734 const Register rt = instr->RtField();
1725 const int64_t off = instr->SImm19Field() << 2; 1735 const int64_t off = instr->SImm19Field() << 2;
1726 const int64_t pc = reinterpret_cast<int64_t>(instr); 1736 const int64_t pc = reinterpret_cast<int64_t>(instr);
1727 const int64_t address = pc + off; 1737 const int64_t address = pc + off;
1728 const int64_t val = ReadX(address, instr); 1738 const int64_t val = ReadX(address, instr);
1729 if (instr->Bit(30)) { 1739 if (instr->Bit(30)) {
1730 // Format(instr, "ldrx 'rt, 'pcldr"); 1740 // Format(instr, "ldrx 'rt, 'pcldr");
1731 set_register(rt, val, R31IsZR); 1741 set_register(instr, rt, val, R31IsZR);
1732 } else { 1742 } else {
1733 // Format(instr, "ldrw 'rt, 'pcldr"); 1743 // Format(instr, "ldrw 'rt, 'pcldr");
1734 set_wregister(rt, static_cast<int32_t>(val), R31IsZR); 1744 set_wregister(rt, static_cast<int32_t>(val), R31IsZR);
1735 } 1745 }
1736 } 1746 }
1737 1747
1738 1748
1739 void Simulator::DecodeLoadStore(Instr* instr) { 1749 void Simulator::DecodeLoadStore(Instr* instr) {
1740 if (instr->IsLoadStoreRegOp()) { 1750 if (instr->IsLoadStoreRegOp()) {
1741 DecodeLoadStoreReg(instr); 1751 DecodeLoadStoreReg(instr);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1844 const int64_t rm_val = DecodeShiftExtendOperand(instr); 1854 const int64_t rm_val = DecodeShiftExtendOperand(instr);
1845 if (instr->SFField()) { 1855 if (instr->SFField()) {
1846 // 64-bit add. 1856 // 64-bit add.
1847 const int64_t rn_val = get_register(rn, instr->RnMode()); 1857 const int64_t rn_val = get_register(rn, instr->RnMode());
1848 int64_t alu_out = 0; 1858 int64_t alu_out = 0;
1849 if (subtract) { 1859 if (subtract) {
1850 alu_out = rn_val - rm_val; 1860 alu_out = rn_val - rm_val;
1851 } else { 1861 } else {
1852 alu_out = rn_val + rm_val; 1862 alu_out = rn_val + rm_val;
1853 } 1863 }
1854 set_register(rd, alu_out, instr->RdMode()); 1864 set_register(instr, rd, alu_out, instr->RdMode());
1855 if (instr->HasS()) { 1865 if (instr->HasS()) {
1856 SetNZFlagsX(alu_out); 1866 SetNZFlagsX(alu_out);
1857 if (subtract) { 1867 if (subtract) {
1858 SetCFlag(!BorrowFromX(rn_val, rm_val)); 1868 SetCFlag(!BorrowFromX(rn_val, rm_val));
1859 } else { 1869 } else {
1860 SetCFlag(CarryFromX(rn_val, rm_val)); 1870 SetCFlag(CarryFromX(rn_val, rm_val));
1861 } 1871 }
1862 SetVFlag(OverflowFromX(alu_out, rn_val, rm_val, !subtract)); 1872 SetVFlag(OverflowFromX(alu_out, rn_val, rm_val, !subtract));
1863 } 1873 }
1864 } else { 1874 } else {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 if (instr->SFField() == 1) { 1945 if (instr->SFField() == 1) {
1936 SetNZFlagsX(alu_out); 1946 SetNZFlagsX(alu_out);
1937 } else { 1947 } else {
1938 SetNZFlagsW(alu_out); 1948 SetNZFlagsW(alu_out);
1939 } 1949 }
1940 SetCFlag(false); 1950 SetCFlag(false);
1941 SetVFlag(false); 1951 SetVFlag(false);
1942 } 1952 }
1943 1953
1944 if (instr->SFField() == 1) { 1954 if (instr->SFField() == 1) {
1945 set_register(rd, alu_out, instr->RdMode()); 1955 set_register(instr, rd, alu_out, instr->RdMode());
1946 } else { 1956 } else {
1947 set_wregister(rd, alu_out & kWRegMask, instr->RdMode()); 1957 set_wregister(rd, alu_out & kWRegMask, instr->RdMode());
1948 } 1958 }
1949 } 1959 }
1950 1960
1951 1961
1952 static int64_t divide64(int64_t top, int64_t bottom, bool signd) { 1962 static int64_t divide64(int64_t top, int64_t bottom, bool signd) {
1953 // ARM64 does not trap on integer division by zero. The destination register 1963 // ARM64 does not trap on integer division by zero. The destination register
1954 // is instead set to 0. 1964 // is instead set to 0.
1955 if (bottom == 0) { 1965 if (bottom == 0) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2008 const int64_t rm_val64 = get_register(rm, R31IsZR); 2018 const int64_t rm_val64 = get_register(rm, R31IsZR);
2009 const int32_t rn_val32 = get_wregister(rn, R31IsZR); 2019 const int32_t rn_val32 = get_wregister(rn, R31IsZR);
2010 const int32_t rm_val32 = get_wregister(rm, R31IsZR); 2020 const int32_t rm_val32 = get_wregister(rm, R31IsZR);
2011 switch (op) { 2021 switch (op) {
2012 case 2: 2022 case 2:
2013 case 3: { 2023 case 3: {
2014 // Format(instr, "udiv'sf 'rd, 'rn, 'rm"); 2024 // Format(instr, "udiv'sf 'rd, 'rn, 'rm");
2015 // Format(instr, "sdiv'sf 'rd, 'rn, 'rm"); 2025 // Format(instr, "sdiv'sf 'rd, 'rn, 'rm");
2016 const bool signd = instr->Bit(10) == 1; 2026 const bool signd = instr->Bit(10) == 1;
2017 if (instr->SFField() == 1) { 2027 if (instr->SFField() == 1) {
2018 set_register(rd, divide64(rn_val64, rm_val64, signd), R31IsZR); 2028 set_register(instr, rd, divide64(rn_val64, rm_val64, signd), R31IsZR);
2019 } else { 2029 } else {
2020 set_wregister(rd, divide32(rn_val32, rm_val32, signd), R31IsZR); 2030 set_wregister(rd, divide32(rn_val32, rm_val32, signd), R31IsZR);
2021 } 2031 }
2022 break; 2032 break;
2023 } 2033 }
2024 case 8: { 2034 case 8: {
2025 // Format(instr, "lsl'sf 'rd, 'rn, 'rm"); 2035 // Format(instr, "lsl'sf 'rd, 'rn, 'rm");
2026 if (instr->SFField() == 1) { 2036 if (instr->SFField() == 1) {
2027 const int64_t alu_out = rn_val64 << (rm_val64 & (kXRegSizeInBits - 1)); 2037 const int64_t alu_out = rn_val64 << (rm_val64 & (kXRegSizeInBits - 1));
2028 set_register(rd, alu_out, R31IsZR); 2038 set_register(instr, rd, alu_out, R31IsZR);
2029 } else { 2039 } else {
2030 const int32_t alu_out = rn_val32 << (rm_val32 & (kXRegSizeInBits - 1)); 2040 const int32_t alu_out = rn_val32 << (rm_val32 & (kXRegSizeInBits - 1));
2031 set_wregister(rd, alu_out, R31IsZR); 2041 set_wregister(rd, alu_out, R31IsZR);
2032 } 2042 }
2033 break; 2043 break;
2034 } 2044 }
2035 case 9: { 2045 case 9: {
2036 // Format(instr, "lsr'sf 'rd, 'rn, 'rm"); 2046 // Format(instr, "lsr'sf 'rd, 'rn, 'rm");
2037 if (instr->SFField() == 1) { 2047 if (instr->SFField() == 1) {
2038 const uint64_t rn_u64 = static_cast<uint64_t>(rn_val64); 2048 const uint64_t rn_u64 = static_cast<uint64_t>(rn_val64);
2039 const int64_t alu_out = rn_u64 >> (rm_val64 & (kXRegSizeInBits - 1)); 2049 const int64_t alu_out = rn_u64 >> (rm_val64 & (kXRegSizeInBits - 1));
2040 set_register(rd, alu_out, R31IsZR); 2050 set_register(instr, rd, alu_out, R31IsZR);
2041 } else { 2051 } else {
2042 const uint32_t rn_u32 = static_cast<uint32_t>(rn_val32); 2052 const uint32_t rn_u32 = static_cast<uint32_t>(rn_val32);
2043 const int32_t alu_out = rn_u32 >> (rm_val32 & (kXRegSizeInBits - 1)); 2053 const int32_t alu_out = rn_u32 >> (rm_val32 & (kXRegSizeInBits - 1));
2044 set_wregister(rd, alu_out, R31IsZR); 2054 set_wregister(rd, alu_out, R31IsZR);
2045 } 2055 }
2046 break; 2056 break;
2047 } 2057 }
2048 case 10: { 2058 case 10: {
2049 // Format(instr, "asr'sf 'rd, 'rn, 'rm"); 2059 // Format(instr, "asr'sf 'rd, 'rn, 'rm");
2050 if (instr->SFField() == 1) { 2060 if (instr->SFField() == 1) {
2051 const int64_t alu_out = rn_val64 >> (rm_val64 & (kXRegSizeInBits - 1)); 2061 const int64_t alu_out = rn_val64 >> (rm_val64 & (kXRegSizeInBits - 1));
2052 set_register(rd, alu_out, R31IsZR); 2062 set_register(instr, rd, alu_out, R31IsZR);
2053 } else { 2063 } else {
2054 const int32_t alu_out = rn_val32 >> (rm_val32 & (kXRegSizeInBits - 1)); 2064 const int32_t alu_out = rn_val32 >> (rm_val32 & (kXRegSizeInBits - 1));
2055 set_wregister(rd, alu_out, R31IsZR); 2065 set_wregister(rd, alu_out, R31IsZR);
2056 } 2066 }
2057 break; 2067 break;
2058 } 2068 }
2059 default: 2069 default:
2060 UnimplementedInstruction(instr); 2070 UnimplementedInstruction(instr);
2061 break; 2071 break;
2062 } 2072 }
2063 } 2073 }
2064 2074
2065 2075
2066 void Simulator::DecodeMiscDP3Source(Instr* instr) { 2076 void Simulator::DecodeMiscDP3Source(Instr* instr) {
2067 const Register rd = instr->RdField(); 2077 const Register rd = instr->RdField();
2068 const Register rn = instr->RnField(); 2078 const Register rn = instr->RnField();
2069 const Register rm = instr->RmField(); 2079 const Register rm = instr->RmField();
2070 const Register ra = instr->RaField(); 2080 const Register ra = instr->RaField();
2071 if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) && 2081 if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) &&
2072 (instr->Bit(15) == 0)) { 2082 (instr->Bit(15) == 0)) {
2073 // Format(instr, "madd'sf 'rd, 'rn, 'rm, 'ra"); 2083 // Format(instr, "madd'sf 'rd, 'rn, 'rm, 'ra");
2074 if (instr->SFField() == 1) { 2084 if (instr->SFField() == 1) {
2075 const int64_t rn_val = get_register(rn, R31IsZR); 2085 const int64_t rn_val = get_register(rn, R31IsZR);
2076 const int64_t rm_val = get_register(rm, R31IsZR); 2086 const int64_t rm_val = get_register(rm, R31IsZR);
2077 const int64_t ra_val = get_register(ra, R31IsZR); 2087 const int64_t ra_val = get_register(ra, R31IsZR);
2078 const int64_t alu_out = ra_val + (rn_val * rm_val); 2088 const int64_t alu_out = ra_val + (rn_val * rm_val);
2079 set_register(rd, alu_out, R31IsZR); 2089 set_register(instr, rd, alu_out, R31IsZR);
2080 } else { 2090 } else {
2081 const int32_t rn_val = get_wregister(rn, R31IsZR); 2091 const int32_t rn_val = get_wregister(rn, R31IsZR);
2082 const int32_t rm_val = get_wregister(rm, R31IsZR); 2092 const int32_t rm_val = get_wregister(rm, R31IsZR);
2083 const int32_t ra_val = get_wregister(ra, R31IsZR); 2093 const int32_t ra_val = get_wregister(ra, R31IsZR);
2084 const int32_t alu_out = ra_val + (rn_val * rm_val); 2094 const int32_t alu_out = ra_val + (rn_val * rm_val);
2085 set_wregister(rd, alu_out, R31IsZR); 2095 set_wregister(rd, alu_out, R31IsZR);
2086 } 2096 }
2087 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) && 2097 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) &&
2088 (instr->Bit(15) == 1)) { 2098 (instr->Bit(15) == 1)) {
2089 // Format(instr, "msub'sf 'rd, 'rn, 'rm, 'ra"); 2099 // Format(instr, "msub'sf 'rd, 'rn, 'rm, 'ra");
2090 if (instr->SFField() == 1) { 2100 if (instr->SFField() == 1) {
2091 const int64_t rn_val = get_register(rn, R31IsZR); 2101 const int64_t rn_val = get_register(rn, R31IsZR);
2092 const int64_t rm_val = get_register(rm, R31IsZR); 2102 const int64_t rm_val = get_register(rm, R31IsZR);
2093 const int64_t ra_val = get_register(ra, R31IsZR); 2103 const int64_t ra_val = get_register(ra, R31IsZR);
2094 const int64_t alu_out = ra_val - (rn_val * rm_val); 2104 const int64_t alu_out = ra_val - (rn_val * rm_val);
2095 set_register(rd, alu_out, R31IsZR); 2105 set_register(instr, rd, alu_out, R31IsZR);
2096 } else { 2106 } else {
2097 const int32_t rn_val = get_wregister(rn, R31IsZR); 2107 const int32_t rn_val = get_wregister(rn, R31IsZR);
2098 const int32_t rm_val = get_wregister(rm, R31IsZR); 2108 const int32_t rm_val = get_wregister(rm, R31IsZR);
2099 const int32_t ra_val = get_wregister(ra, R31IsZR); 2109 const int32_t ra_val = get_wregister(ra, R31IsZR);
2100 const int32_t alu_out = ra_val - (rn_val * rm_val); 2110 const int32_t alu_out = ra_val - (rn_val * rm_val);
2101 set_wregister(rd, alu_out, R31IsZR); 2111 set_wregister(rd, alu_out, R31IsZR);
2102 } 2112 }
2103 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 2) && 2113 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 2) &&
2104 (instr->Bit(15) == 0)) { 2114 (instr->Bit(15) == 0)) {
2105 // Format(instr, "smulh 'rd, 'rn, 'rm"); 2115 // Format(instr, "smulh 'rd, 'rn, 'rm");
2106 const int64_t rn_val = get_register(rn, R31IsZR); 2116 const int64_t rn_val = get_register(rn, R31IsZR);
2107 const int64_t rm_val = get_register(rm, R31IsZR); 2117 const int64_t rm_val = get_register(rm, R31IsZR);
2108 const __int128 res = 2118 const __int128 res =
2109 static_cast<__int128>(rn_val) * static_cast<__int128>(rm_val); 2119 static_cast<__int128>(rn_val) * static_cast<__int128>(rm_val);
2110 const int64_t alu_out = static_cast<int64_t>(res >> 64); 2120 const int64_t alu_out = static_cast<int64_t>(res >> 64);
2111 set_register(rd, alu_out, R31IsZR); 2121 set_register(instr, rd, alu_out, R31IsZR);
2112 } else { 2122 } else {
2113 UnimplementedInstruction(instr); 2123 UnimplementedInstruction(instr);
2114 } 2124 }
2115 } 2125 }
2116 2126
2117 2127
2118 void Simulator::DecodeConditionalSelect(Instr* instr) { 2128 void Simulator::DecodeConditionalSelect(Instr* instr) {
2119 const Register rd = instr->RdField(); 2129 const Register rd = instr->RdField();
2120 const Register rn = instr->RnField(); 2130 const Register rn = instr->RnField();
2121 const Register rm = instr->RmField(); 2131 const Register rm = instr->RmField();
(...skipping 27 matching lines...) Expand all
2149 if (ConditionallyExecute(instr)) { 2159 if (ConditionallyExecute(instr)) {
2150 result64 = rn_val64; 2160 result64 = rn_val64;
2151 result32 = rn_val32; 2161 result32 = rn_val32;
2152 } 2162 }
2153 } else { 2163 } else {
2154 UnimplementedInstruction(instr); 2164 UnimplementedInstruction(instr);
2155 return; 2165 return;
2156 } 2166 }
2157 2167
2158 if (instr->SFField() == 1) { 2168 if (instr->SFField() == 1) {
2159 set_register(rd, result64, instr->RdMode()); 2169 set_register(instr, rd, result64, instr->RdMode());
2160 } else { 2170 } else {
2161 set_wregister(rd, result32, instr->RdMode()); 2171 set_wregister(rd, result32, instr->RdMode());
2162 } 2172 }
2163 } 2173 }
2164 2174
2165 2175
2166 void Simulator::DecodeDPRegister(Instr* instr) { 2176 void Simulator::DecodeDPRegister(Instr* instr) {
2167 if (instr->IsAddSubShiftExtOp()) { 2177 if (instr->IsAddSubShiftExtOp()) {
2168 DecodeAddSubShiftExt(instr); 2178 DecodeAddSubShiftExt(instr);
2169 } else if (instr->IsLogicalShiftOp()) { 2179 } else if (instr->IsLogicalShiftOp()) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 const VRegister vd = instr->VdField(); 2224 const VRegister vd = instr->VdField();
2215 const VRegister vn = instr->VnField(); 2225 const VRegister vn = instr->VnField();
2216 const Register rn = instr->RnField(); 2226 const Register rn = instr->RnField();
2217 const Register rd = instr->RdField(); 2227 const Register rd = instr->RdField();
2218 if ((op == 0) && (imm4 == 7)) { 2228 if ((op == 0) && (imm4 == 7)) {
2219 if (Q == 0) { 2229 if (Q == 0) {
2220 // Format(instr, "vmovrs 'rd, 'vn'idx5"); 2230 // Format(instr, "vmovrs 'rd, 'vn'idx5");
2221 set_wregister(rd, get_vregisters(vn, idx5), R31IsZR); 2231 set_wregister(rd, get_vregisters(vn, idx5), R31IsZR);
2222 } else { 2232 } else {
2223 // Format(instr, "vmovrd 'rd, 'vn'idx5"); 2233 // Format(instr, "vmovrd 'rd, 'vn'idx5");
2224 set_register(rd, get_vregisterd(vn, idx5), R31IsZR); 2234 set_register(instr, rd, get_vregisterd(vn, idx5), R31IsZR);
2225 } 2235 }
2226 } else if ((Q == 1) && (op == 0) && (imm4 == 0)) { 2236 } else if ((Q == 1) && (op == 0) && (imm4 == 0)) {
2227 // Format(instr, "vdup'csz 'vd, 'vn'idx5"); 2237 // Format(instr, "vdup'csz 'vd, 'vn'idx5");
2228 if (element_bytes == 4) { 2238 if (element_bytes == 4) {
2229 for (int i = 0; i < 4; i++) { 2239 for (int i = 0; i < 4; i++) {
2230 set_vregisters(vd, i, get_vregisters(vn, idx5)); 2240 set_vregisters(vd, i, get_vregisters(vn, idx5));
2231 } 2241 }
2232 } else if (element_bytes == 8) { 2242 } else if (element_bytes == 8) {
2233 for (int i = 0; i < 2; i++) { 2243 for (int i = 0; i < 2; i++) {
2234 set_vregisterd(vd, i, get_vregisterd(vn, idx5)); 2244 set_vregisterd(vd, i, get_vregisterd(vn, idx5));
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2665 } 2675 }
2666 if (instr->Bits(16, 5) == 2) { 2676 if (instr->Bits(16, 5) == 2) {
2667 // Format(instr, "scvtfd 'vd, 'vn"); 2677 // Format(instr, "scvtfd 'vd, 'vn");
2668 const int64_t rn_val = get_register(rn, instr->RnMode()); 2678 const int64_t rn_val = get_register(rn, instr->RnMode());
2669 const double vn_dbl = static_cast<double>(rn_val); 2679 const double vn_dbl = static_cast<double>(rn_val);
2670 set_vregisterd(vd, 0, bit_cast<int64_t, double>(vn_dbl)); 2680 set_vregisterd(vd, 0, bit_cast<int64_t, double>(vn_dbl));
2671 set_vregisterd(vd, 1, 0); 2681 set_vregisterd(vd, 1, 0);
2672 } else if (instr->Bits(16, 5) == 6) { 2682 } else if (instr->Bits(16, 5) == 6) {
2673 // Format(instr, "fmovrd 'rd, 'vn"); 2683 // Format(instr, "fmovrd 'rd, 'vn");
2674 const int64_t vn_val = get_vregisterd(vn, 0); 2684 const int64_t vn_val = get_vregisterd(vn, 0);
2675 set_register(rd, vn_val, R31IsZR); 2685 set_register(instr, rd, vn_val, R31IsZR);
2676 } else if (instr->Bits(16, 5) == 7) { 2686 } else if (instr->Bits(16, 5) == 7) {
2677 // Format(instr, "fmovdr 'vd, 'rn"); 2687 // Format(instr, "fmovdr 'vd, 'rn");
2678 const int64_t rn_val = get_register(rn, R31IsZR); 2688 const int64_t rn_val = get_register(rn, R31IsZR);
2679 set_vregisterd(vd, 0, rn_val); 2689 set_vregisterd(vd, 0, rn_val);
2680 set_vregisterd(vd, 1, 0); 2690 set_vregisterd(vd, 1, 0);
2681 } else if (instr->Bits(16, 5) == 24) { 2691 } else if (instr->Bits(16, 5) == 24) {
2682 // Format(instr, "fcvtzds 'rd, 'vn"); 2692 // Format(instr, "fcvtzds 'rd, 'vn");
2683 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0)); 2693 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
2684 set_register(rd, static_cast<int64_t>(vn_val), instr->RdMode()); 2694 set_register(instr, rd, static_cast<int64_t>(vn_val), instr->RdMode());
2685 } else { 2695 } else {
2686 UnimplementedInstruction(instr); 2696 UnimplementedInstruction(instr);
2687 } 2697 }
2688 } 2698 }
2689 2699
2690 2700
2691 void Simulator::DecodeFPOneSource(Instr* instr) { 2701 void Simulator::DecodeFPOneSource(Instr* instr) {
2692 const int opc = instr->Bits(15, 6); 2702 const int opc = instr->Bits(15, 6);
2693 const VRegister vd = instr->VdField(); 2703 const VRegister vd = instr->VdField();
2694 const VRegister vn = instr->VnField(); 2704 const VRegister vn = instr->VnField();
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
2933 if (fp_args) { 2943 if (fp_args) {
2934 set_vregisterd(V0, 0, parameter0); 2944 set_vregisterd(V0, 0, parameter0);
2935 set_vregisterd(V0, 1, 0); 2945 set_vregisterd(V0, 1, 0);
2936 set_vregisterd(V1, 0, parameter1); 2946 set_vregisterd(V1, 0, parameter1);
2937 set_vregisterd(V1, 1, 0); 2947 set_vregisterd(V1, 1, 0);
2938 set_vregisterd(V2, 0, parameter2); 2948 set_vregisterd(V2, 0, parameter2);
2939 set_vregisterd(V2, 1, 0); 2949 set_vregisterd(V2, 1, 0);
2940 set_vregisterd(V3, 0, parameter3); 2950 set_vregisterd(V3, 0, parameter3);
2941 set_vregisterd(V3, 1, 0); 2951 set_vregisterd(V3, 1, 0);
2942 } else { 2952 } else {
2943 set_register(R0, parameter0); 2953 set_register(NULL, R0, parameter0);
2944 set_register(R1, parameter1); 2954 set_register(NULL, R1, parameter1);
2945 set_register(R2, parameter2); 2955 set_register(NULL, R2, parameter2);
2946 set_register(R3, parameter3); 2956 set_register(NULL, R3, parameter3);
2947 } 2957 }
2948 2958
2949 // Make sure the activation frames are properly aligned. 2959 // Make sure the activation frames are properly aligned.
2950 intptr_t stack_pointer = sp_before_call; 2960 intptr_t stack_pointer = sp_before_call;
2951 if (OS::ActivationFrameAlignment() > 1) { 2961 if (OS::ActivationFrameAlignment() > 1) {
2952 stack_pointer = 2962 stack_pointer =
2953 Utils::RoundDown(stack_pointer, OS::ActivationFrameAlignment()); 2963 Utils::RoundDown(stack_pointer, OS::ActivationFrameAlignment());
2954 } 2964 }
2955 set_register(R31, stack_pointer, R31IsSP); 2965 set_register(NULL, R31, stack_pointer, R31IsSP);
2956 2966
2957 // Prepare to execute the code at entry. 2967 // Prepare to execute the code at entry.
2958 set_pc(entry); 2968 set_pc(entry);
2959 // Put down marker for end of simulation. The simulator will stop simulation 2969 // Put down marker for end of simulation. The simulator will stop simulation
2960 // when the PC reaches this value. By saving the "end simulation" value into 2970 // when the PC reaches this value. By saving the "end simulation" value into
2961 // the LR the simulation stops when returning to this call point. 2971 // the LR the simulation stops when returning to this call point.
2962 set_register(LR, kEndSimulatingPC); 2972 set_register(NULL, LR, kEndSimulatingPC);
2963 2973
2964 // Remember the values of callee-saved registers, and set them up with a 2974 // Remember the values of callee-saved registers, and set them up with a
2965 // known value so that we are able to check that they are preserved 2975 // known value so that we are able to check that they are preserved
2966 // properly across Dart execution. 2976 // properly across Dart execution.
2967 int64_t preserved_vals[kAbiPreservedCpuRegCount]; 2977 int64_t preserved_vals[kAbiPreservedCpuRegCount];
2968 const double dicount = static_cast<double>(icount_); 2978 const double dicount = static_cast<double>(icount_);
2969 const int64_t callee_saved_value = bit_cast<int64_t, double>(dicount); 2979 const int64_t callee_saved_value = bit_cast<int64_t, double>(dicount);
2970 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) { 2980 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
2971 const Register r = static_cast<Register>(i); 2981 const Register r = static_cast<Register>(i);
2972 preserved_vals[i - kAbiFirstPreservedCpuReg] = get_register(r); 2982 preserved_vals[i - kAbiFirstPreservedCpuReg] = get_register(r);
2973 set_register(r, callee_saved_value); 2983 set_register(NULL, r, callee_saved_value);
2974 } 2984 }
2975 2985
2976 // Only the bottom half of the V registers must be preserved. 2986 // Only the bottom half of the V registers must be preserved.
2977 int64_t preserved_dvals[kAbiPreservedFpuRegCount]; 2987 int64_t preserved_dvals[kAbiPreservedFpuRegCount];
2978 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) { 2988 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
2979 const VRegister r = static_cast<VRegister>(i); 2989 const VRegister r = static_cast<VRegister>(i);
2980 preserved_dvals[i - kAbiFirstPreservedFpuReg] = get_vregisterd(r, 0); 2990 preserved_dvals[i - kAbiFirstPreservedFpuReg] = get_vregisterd(r, 0);
2981 set_vregisterd(r, 0, callee_saved_value); 2991 set_vregisterd(r, 0, callee_saved_value);
2982 set_vregisterd(r, 1, 0); 2992 set_vregisterd(r, 1, 0);
2983 } 2993 }
2984 2994
2985 // Start the simulation. 2995 // Start the simulation.
2986 Execute(); 2996 Execute();
2987 2997
2988 // Check that the callee-saved registers have been preserved, 2998 // Check that the callee-saved registers have been preserved,
2989 // and restore them with the original value. 2999 // and restore them with the original value.
2990 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) { 3000 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
2991 const Register r = static_cast<Register>(i); 3001 const Register r = static_cast<Register>(i);
2992 ASSERT(callee_saved_value == get_register(r)); 3002 ASSERT(callee_saved_value == get_register(r));
2993 set_register(r, preserved_vals[i - kAbiFirstPreservedCpuReg]); 3003 set_register(NULL, r, preserved_vals[i - kAbiFirstPreservedCpuReg]);
2994 } 3004 }
2995 3005
2996 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) { 3006 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
2997 const VRegister r = static_cast<VRegister>(i); 3007 const VRegister r = static_cast<VRegister>(i);
2998 ASSERT(callee_saved_value == get_vregisterd(r, 0)); 3008 ASSERT(callee_saved_value == get_vregisterd(r, 0));
2999 set_vregisterd(r, 0, preserved_dvals[i - kAbiFirstPreservedFpuReg]); 3009 set_vregisterd(r, 0, preserved_dvals[i - kAbiFirstPreservedFpuReg]);
3000 set_vregisterd(r, 1, 0); 3010 set_vregisterd(r, 1, 0);
3001 } 3011 }
3002 3012
3003 // Restore the SP register and return R0. 3013 // Restore the SP register and return R0.
3004 set_register(R31, sp_before_call, R31IsSP); 3014 set_register(NULL, R31, sp_before_call, R31IsSP);
3005 int64_t return_value; 3015 int64_t return_value;
3006 if (fp_return) { 3016 if (fp_return) {
3007 return_value = get_vregisterd(V0, 0); 3017 return_value = get_vregisterd(V0, 0);
3008 } else { 3018 } else {
3009 return_value = get_register(R0); 3019 return_value = get_register(R0);
3010 } 3020 }
3011 return return_value; 3021 return return_value;
3012 } 3022 }
3013 3023
3014 3024
(...skipping 15 matching lines...) Expand all
3030 // in the previous C++ frames. 3040 // in the previous C++ frames.
3031 uword native_sp = buf->native_sp(); 3041 uword native_sp = buf->native_sp();
3032 Isolate* isolate = Isolate::Current(); 3042 Isolate* isolate = Isolate::Current();
3033 while (isolate->top_resource() != NULL && 3043 while (isolate->top_resource() != NULL &&
3034 (reinterpret_cast<uword>(isolate->top_resource()) < native_sp)) { 3044 (reinterpret_cast<uword>(isolate->top_resource()) < native_sp)) {
3035 isolate->top_resource()->~StackResource(); 3045 isolate->top_resource()->~StackResource();
3036 } 3046 }
3037 3047
3038 // Unwind the C++ stack and continue simulation in the target frame. 3048 // Unwind the C++ stack and continue simulation in the target frame.
3039 set_pc(static_cast<int64_t>(pc)); 3049 set_pc(static_cast<int64_t>(pc));
3040 set_register(R31, static_cast<int64_t>(sp), R31IsSP); 3050 set_register(NULL, SP, static_cast<int64_t>(sp));
3041 set_register(FP, static_cast<int64_t>(fp)); 3051 set_register(NULL, FP, static_cast<int64_t>(fp));
3042 3052
3043 ASSERT(raw_exception != Object::null()); 3053 ASSERT(raw_exception != Object::null());
3044 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); 3054 set_register(NULL, kExceptionObjectReg, bit_cast<int64_t>(raw_exception));
3045 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); 3055 set_register(NULL, kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace));
3046 buf->Longjmp(); 3056 buf->Longjmp();
3047 } 3057 }
3048 3058
3049 } // namespace dart 3059 } // namespace dart
3050 3060
3051 #endif // !defined(HOST_ARCH_ARM64) 3061 #endif // !defined(HOST_ARCH_ARM64)
3052 3062
3053 #endif // defined TARGET_ARCH_ARM64 3063 #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