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 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |