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

Side by Side Diff: src/arm64/simulator-arm64.cc

Issue 213943002: Change arm64 simulator register backing store. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/arm64/simulator-arm64.h ('K') | « src/arm64/simulator-arm64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <cmath> 6 #include <cmath>
7 #include <cstdarg> 7 #include <cstdarg>
8 #include "v8.h" 8 #include "v8.h"
9 9
10 #if V8_TARGET_ARCH_ARM64 10 #if V8_TARGET_ARCH_ARM64
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 } 816 }
817 } 817 }
818 if ((strcmp("csp", name) == 0) || (strcmp("wcsp", name) == 0)) { 818 if ((strcmp("csp", name) == 0) || (strcmp("wcsp", name) == 0)) {
819 return kSPRegInternalCode; 819 return kSPRegInternalCode;
820 } 820 }
821 return -1; 821 return -1;
822 } 822 }
823 823
824 824
825 // Helpers --------------------------------------------------------------------- 825 // Helpers ---------------------------------------------------------------------
826 int64_t Simulator::AddWithCarry(unsigned reg_size, 826 template<> struct make_unsigned<int32_t> {
827 bool set_flags, 827 typedef uint32_t type;
828 int64_t src1, 828 };
829 int64_t src2, 829
830 int64_t carry_in) { 830
831 template<> struct make_unsigned<int64_t> {
832 typedef uint64_t type;
833 };
834
835
836 template <typename T>
837 T Simulator::AddWithCarry(bool set_flags,
838 T src1,
839 T src2,
840 T carry_in) {
841 typedef typename make_unsigned<T>::type unsignedT;
831 ASSERT((carry_in == 0) || (carry_in == 1)); 842 ASSERT((carry_in == 0) || (carry_in == 1));
832 ASSERT((reg_size == kXRegSizeInBits) || (reg_size == kWRegSizeInBits));
833 843
834 uint64_t u1, u2; 844 T signed_sum = src1 + src2 + carry_in;
835 int64_t result; 845 T result = signed_sum;
836 int64_t signed_sum = src1 + src2 + carry_in;
837 846
838 bool N, Z, C, V; 847 bool N, Z, C, V;
848 unsignedT u1 = static_cast<unsignedT>(src1);
849 unsignedT u2 = static_cast<unsignedT>(src2);
839 850
840 if (reg_size == kWRegSizeInBits) { 851 // Compute the C flag by comparing the sum to the max unsigned integer.
841 u1 = static_cast<uint64_t>(src1) & kWRegMask; 852 C = ((std::numeric_limits<unsignedT>::max() - u1) < (u2 + carry_in)) ||
842 u2 = static_cast<uint64_t>(src2) & kWRegMask; 853 ((std::numeric_limits<unsignedT>::max() - u1 - carry_in) < u2);
854 // Overflow iff the sign bit is the same for the two inputs and different
855 // for the result.
856 V = ((src1 ^ src2) >= 0) && ((src1 ^ result) < 0);
843 857
844 result = signed_sum & kWRegMask; 858 N = CalcNFlag(result);
845 // Compute the C flag by comparing the sum to the max unsigned integer.
846 C = ((kWMaxUInt - u1) < (u2 + carry_in)) ||
847 ((kWMaxUInt - u1 - carry_in) < u2);
848 // Overflow iff the sign bit is the same for the two inputs and different
849 // for the result.
850 int64_t s_src1 = src1 << (kXRegSizeInBits - kWRegSizeInBits);
851 int64_t s_src2 = src2 << (kXRegSizeInBits - kWRegSizeInBits);
852 int64_t s_result = result << (kXRegSizeInBits - kWRegSizeInBits);
853 V = ((s_src1 ^ s_src2) >= 0) && ((s_src1 ^ s_result) < 0);
854
855 } else {
856 u1 = static_cast<uint64_t>(src1);
857 u2 = static_cast<uint64_t>(src2);
858
859 result = signed_sum;
860 // Compute the C flag by comparing the sum to the max unsigned integer.
861 C = ((kXMaxUInt - u1) < (u2 + carry_in)) ||
862 ((kXMaxUInt - u1 - carry_in) < u2);
863 // Overflow iff the sign bit is the same for the two inputs and different
864 // for the result.
865 V = ((src1 ^ src2) >= 0) && ((src1 ^ result) < 0);
866 }
867
868 N = CalcNFlag(result, reg_size);
869 Z = CalcZFlag(result); 859 Z = CalcZFlag(result);
870 860
871 if (set_flags) { 861 if (set_flags) {
872 nzcv().SetN(N); 862 nzcv().SetN(N);
873 nzcv().SetZ(Z); 863 nzcv().SetZ(Z);
874 nzcv().SetC(C); 864 nzcv().SetC(C);
875 nzcv().SetV(V); 865 nzcv().SetV(V);
876 } 866 }
877 return result; 867 return result;
878 } 868 }
879 869
880 870
881 int64_t Simulator::ShiftOperand(unsigned reg_size, 871 template<typename T>
882 int64_t value, 872 void Simulator::AddSubWithCarry(Instruction* instr) {
883 Shift shift_type, 873 T op2 = reg<T>(instr->Rm());
884 unsigned amount) { 874 T new_val;
875
876 if ((instr->Mask(AddSubOpMask) == SUB) || instr->Mask(AddSubOpMask) == SUBS) {
877 op2 = ~op2;
878 }
879
880 new_val = AddWithCarry<T>(instr->FlagsUpdate(),
881 reg<T>(instr->Rn()),
882 op2,
883 nzcv().C());
884
885 set_reg<T>(instr->Rd(), new_val);
886 }
887
888 template <typename T>
889 T Simulator::ShiftOperand(T value, Shift shift_type, unsigned amount) {
890 typedef typename make_unsigned<T>::type unsignedT;
891
885 if (amount == 0) { 892 if (amount == 0) {
886 return value; 893 return value;
887 } 894 }
888 int64_t mask = reg_size == kXRegSizeInBits ? kXRegMask : kWRegMask; 895
889 switch (shift_type) { 896 switch (shift_type) {
890 case LSL: 897 case LSL:
891 return (value << amount) & mask; 898 return value << amount;
892 case LSR: 899 case LSR:
893 return static_cast<uint64_t>(value) >> amount; 900 return static_cast<unsignedT>(value) >> amount;
894 case ASR: { 901 case ASR:
895 // Shift used to restore the sign. 902 return value >> amount;
896 unsigned s_shift = kXRegSizeInBits - reg_size; 903 case ROR:
897 // Value with its sign restored. 904 return (static_cast<unsignedT>(value) >> amount) |
898 int64_t s_value = (value << s_shift) >> s_shift; 905 ((value & ((1L << amount) - 1L)) <<
899 return (s_value >> amount) & mask; 906 (sizeof(unsignedT) * 8 - amount));
900 }
901 case ROR: {
902 if (reg_size == kWRegSizeInBits) {
903 value &= kWRegMask;
904 }
905 return (static_cast<uint64_t>(value) >> amount) |
906 ((value & ((1L << amount) - 1L)) << (reg_size - amount));
907 }
908 default: 907 default:
909 UNIMPLEMENTED(); 908 UNIMPLEMENTED();
910 return 0; 909 return 0;
911 } 910 }
912 } 911 }
913 912
914 913
915 int64_t Simulator::ExtendValue(unsigned reg_size, 914 template <typename T>
916 int64_t value, 915 T Simulator::ExtendValue(T value, Extend extend_type, unsigned left_shift) {
917 Extend extend_type, 916 const unsigned kSignExtendBShift = (sizeof(T) - 1) * 8;
918 unsigned left_shift) { 917 const unsigned kSignExtendHShift = (sizeof(T) - 2) * 8;
918 const unsigned kSignExtendWShift = (sizeof(T) - 4) * 8;
919
919 switch (extend_type) { 920 switch (extend_type) {
920 case UXTB: 921 case UXTB:
921 value &= kByteMask; 922 value &= kByteMask;
922 break; 923 break;
923 case UXTH: 924 case UXTH:
924 value &= kHalfWordMask; 925 value &= kHalfWordMask;
925 break; 926 break;
926 case UXTW: 927 case UXTW:
927 value &= kWordMask; 928 value &= kWordMask;
928 break; 929 break;
929 case SXTB: 930 case SXTB:
930 value = (value << 56) >> 56; 931 value = (value << kSignExtendBShift) >> kSignExtendBShift;
931 break; 932 break;
932 case SXTH: 933 case SXTH:
933 value = (value << 48) >> 48; 934 value = (value << kSignExtendHShift) >> kSignExtendHShift;
934 break; 935 break;
935 case SXTW: 936 case SXTW:
936 value = (value << 32) >> 32; 937 value = (value << kSignExtendWShift) >> kSignExtendWShift;
937 break; 938 break;
938 case UXTX: 939 case UXTX:
939 case SXTX: 940 case SXTX:
940 break; 941 break;
941 default: 942 default:
942 UNREACHABLE(); 943 UNREACHABLE();
943 } 944 }
944 int64_t mask = (reg_size == kXRegSizeInBits) ? kXRegMask : kWRegMask; 945 return value << left_shift;
945 return (value << left_shift) & mask;
946 } 946 }
947 947
948 948
949 template <typename T>
950 void Simulator::Extract(Instruction* instr) {
951 unsigned lsb = instr->ImmS();
952 T op2 = reg<T>(instr->Rm());
953 T result = op2;
954
955 if (lsb) {
956 T op1 = reg<T>(instr->Rn());
957 result = op2 >> lsb | (op1 << ((sizeof(T) * 8) - lsb));
958 }
959 set_reg<T>(instr->Rd(), result);
960 }
961
962
949 template<> double Simulator::FPDefaultNaN<double>() const { 963 template<> double Simulator::FPDefaultNaN<double>() const {
950 return kFP64DefaultNaN; 964 return kFP64DefaultNaN;
951 } 965 }
952 966
953 967
954 template<> float Simulator::FPDefaultNaN<float>() const { 968 template<> float Simulator::FPDefaultNaN<float>() const {
955 return kFP32DefaultNaN; 969 return kFP32DefaultNaN;
956 } 970 }
957 971
958 972
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 case CBNZ_w: take_branch = (wreg(rt) != 0); break; 1263 case CBNZ_w: take_branch = (wreg(rt) != 0); break;
1250 case CBNZ_x: take_branch = (xreg(rt) != 0); break; 1264 case CBNZ_x: take_branch = (xreg(rt) != 0); break;
1251 default: UNIMPLEMENTED(); 1265 default: UNIMPLEMENTED();
1252 } 1266 }
1253 if (take_branch) { 1267 if (take_branch) {
1254 set_pc(instr->ImmPCOffsetTarget()); 1268 set_pc(instr->ImmPCOffsetTarget());
1255 } 1269 }
1256 } 1270 }
1257 1271
1258 1272
1259 void Simulator::AddSubHelper(Instruction* instr, int64_t op2) { 1273 template<typename T>
1260 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits 1274 void Simulator::AddSubHelper(Instruction* instr, T op2) {
1261 : kWRegSizeInBits;
1262 bool set_flags = instr->FlagsUpdate(); 1275 bool set_flags = instr->FlagsUpdate();
1263 int64_t new_val = 0; 1276 T new_val = 0;
1264 Instr operation = instr->Mask(AddSubOpMask); 1277 Instr operation = instr->Mask(AddSubOpMask);
1265 1278
1266 switch (operation) { 1279 switch (operation) {
1267 case ADD: 1280 case ADD:
1268 case ADDS: { 1281 case ADDS: {
1269 new_val = AddWithCarry(reg_size, 1282 new_val = AddWithCarry<T>(set_flags,
1270 set_flags, 1283 reg<T>(instr->Rn(), instr->RnMode()),
1271 reg(reg_size, instr->Rn(), instr->RnMode()), 1284 op2);
1272 op2);
1273 break; 1285 break;
1274 } 1286 }
1275 case SUB: 1287 case SUB:
1276 case SUBS: { 1288 case SUBS: {
1277 new_val = AddWithCarry(reg_size, 1289 new_val = AddWithCarry<T>(set_flags,
1278 set_flags, 1290 reg<T>(instr->Rn(), instr->RnMode()),
1279 reg(reg_size, instr->Rn(), instr->RnMode()), 1291 ~op2,
1280 ~op2, 1292 1);
1281 1);
1282 break; 1293 break;
1283 } 1294 }
1284 default: UNREACHABLE(); 1295 default: UNREACHABLE();
1285 } 1296 }
1286 1297
1287 set_reg(reg_size, instr->Rd(), new_val, instr->RdMode()); 1298 set_reg<T>(instr->Rd(), new_val, instr->RdMode());
1288 } 1299 }
1289 1300
1290 1301
1291 void Simulator::VisitAddSubShifted(Instruction* instr) { 1302 void Simulator::VisitAddSubShifted(Instruction* instr) {
1292 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits 1303 Shift shift_type = static_cast<Shift>(instr->ShiftDP());
1293 : kWRegSizeInBits; 1304 unsigned shift_amount = instr->ImmDPShift();
1294 int64_t op2 = ShiftOperand(reg_size, 1305
1295 reg(reg_size, instr->Rm()), 1306 if (instr->SixtyFourBits()) {
1296 static_cast<Shift>(instr->ShiftDP()), 1307 int64_t op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount);
1297 instr->ImmDPShift()); 1308 AddSubHelper(instr, op2);
1298 AddSubHelper(instr, op2); 1309 } else {
1310 int32_t op2 = ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount);
1311 AddSubHelper(instr, op2);
1312 }
1299 } 1313 }
1300 1314
1301 1315
1302 void Simulator::VisitAddSubImmediate(Instruction* instr) { 1316 void Simulator::VisitAddSubImmediate(Instruction* instr) {
1303 int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0); 1317 int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0);
1304 AddSubHelper(instr, op2); 1318 if (instr->SixtyFourBits()) {
1319 AddSubHelper<int64_t>(instr, op2);
1320 } else {
1321 AddSubHelper<int32_t>(instr, op2);
1322 }
1305 } 1323 }
1306 1324
1307 1325
1308 void Simulator::VisitAddSubExtended(Instruction* instr) { 1326 void Simulator::VisitAddSubExtended(Instruction* instr) {
1309 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits 1327 Extend ext = static_cast<Extend>(instr->ExtendMode());
1310 : kWRegSizeInBits; 1328 unsigned left_shift = instr->ImmExtendShift();
1311 int64_t op2 = ExtendValue(reg_size, 1329 if (instr->SixtyFourBits()) {
1312 reg(reg_size, instr->Rm()), 1330 int64_t op2 = ExtendValue(xreg(instr->Rm()), ext, left_shift);
1313 static_cast<Extend>(instr->ExtendMode()), 1331 AddSubHelper(instr, op2);
1314 instr->ImmExtendShift()); 1332 } else {
1315 AddSubHelper(instr, op2); 1333 int32_t op2 = ExtendValue(wreg(instr->Rm()), ext, left_shift);
1334 AddSubHelper(instr, op2);
1335 }
1316 } 1336 }
1317 1337
1318 1338
1319 void Simulator::VisitAddSubWithCarry(Instruction* instr) { 1339 void Simulator::VisitAddSubWithCarry(Instruction* instr) {
1320 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits 1340 if (instr->SixtyFourBits()) {
1321 : kWRegSizeInBits; 1341 AddSubWithCarry<int64_t>(instr);
1322 int64_t op2 = reg(reg_size, instr->Rm()); 1342 } else {
1323 int64_t new_val; 1343 AddSubWithCarry<int32_t>(instr);
1324
1325 if ((instr->Mask(AddSubOpMask) == SUB) || instr->Mask(AddSubOpMask) == SUBS) {
1326 op2 = ~op2;
1327 } 1344 }
1328
1329 new_val = AddWithCarry(reg_size,
1330 instr->FlagsUpdate(),
1331 reg(reg_size, instr->Rn()),
1332 op2,
1333 nzcv().C());
1334
1335 set_reg(reg_size, instr->Rd(), new_val);
1336 } 1345 }
1337 1346
1338 1347
1339 void Simulator::VisitLogicalShifted(Instruction* instr) { 1348 void Simulator::VisitLogicalShifted(Instruction* instr) {
1340 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits
1341 : kWRegSizeInBits;
1342 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); 1349 Shift shift_type = static_cast<Shift>(instr->ShiftDP());
1343 unsigned shift_amount = instr->ImmDPShift(); 1350 unsigned shift_amount = instr->ImmDPShift();
1344 int64_t op2 = ShiftOperand(reg_size, reg(reg_size, instr->Rm()), shift_type, 1351
1345 shift_amount); 1352 if (instr->SixtyFourBits()) {
1346 if (instr->Mask(NOT) == NOT) { 1353 int64_t op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount);
1347 op2 = ~op2; 1354 op2 = (instr->Mask(NOT) == NOT) ? ~op2 : op2;
1355 LogicalHelper<int64_t>(instr, op2);
1356 } else {
1357 int32_t op2 = ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount);
1358 op2 = (instr->Mask(NOT) == NOT) ? ~op2 : op2;
1359 LogicalHelper<int32_t>(instr, op2);
1348 } 1360 }
1349 LogicalHelper(instr, op2);
1350 } 1361 }
1351 1362
1352 1363
1353 void Simulator::VisitLogicalImmediate(Instruction* instr) { 1364 void Simulator::VisitLogicalImmediate(Instruction* instr) {
1354 LogicalHelper(instr, instr->ImmLogical()); 1365 if (instr->SixtyFourBits()) {
1366 LogicalHelper<int64_t>(instr, instr->ImmLogical());
1367 } else {
1368 LogicalHelper<int32_t>(instr, instr->ImmLogical());
1369 }
1355 } 1370 }
1356 1371
1357 1372
1358 void Simulator::LogicalHelper(Instruction* instr, int64_t op2) { 1373 template<typename T>
1359 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits 1374 void Simulator::LogicalHelper(Instruction* instr, T op2) {
1360 : kWRegSizeInBits; 1375 T op1 = reg<T>(instr->Rn());
1361 int64_t op1 = reg(reg_size, instr->Rn()); 1376 T result = 0;
1362 int64_t result = 0;
1363 bool update_flags = false; 1377 bool update_flags = false;
1364 1378
1365 // Switch on the logical operation, stripping out the NOT bit, as it has a 1379 // Switch on the logical operation, stripping out the NOT bit, as it has a
1366 // different meaning for logical immediate instructions. 1380 // different meaning for logical immediate instructions.
1367 switch (instr->Mask(LogicalOpMask & ~NOT)) { 1381 switch (instr->Mask(LogicalOpMask & ~NOT)) {
1368 case ANDS: update_flags = true; // Fall through. 1382 case ANDS: update_flags = true; // Fall through.
1369 case AND: result = op1 & op2; break; 1383 case AND: result = op1 & op2; break;
1370 case ORR: result = op1 | op2; break; 1384 case ORR: result = op1 | op2; break;
1371 case EOR: result = op1 ^ op2; break; 1385 case EOR: result = op1 ^ op2; break;
1372 default: 1386 default:
1373 UNIMPLEMENTED(); 1387 UNIMPLEMENTED();
1374 } 1388 }
1375 1389
1376 if (update_flags) { 1390 if (update_flags) {
1377 nzcv().SetN(CalcNFlag(result, reg_size)); 1391 nzcv().SetN(CalcNFlag(result));
1378 nzcv().SetZ(CalcZFlag(result)); 1392 nzcv().SetZ(CalcZFlag(result));
1379 nzcv().SetC(0); 1393 nzcv().SetC(0);
1380 nzcv().SetV(0); 1394 nzcv().SetV(0);
1381 } 1395 }
1382 1396
1383 set_reg(reg_size, instr->Rd(), result, instr->RdMode()); 1397 set_reg<T>(instr->Rd(), result, instr->RdMode());
1384 } 1398 }
1385 1399
1386 1400
1387 void Simulator::VisitConditionalCompareRegister(Instruction* instr) { 1401 void Simulator::VisitConditionalCompareRegister(Instruction* instr) {
1388 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits 1402 if (instr->SixtyFourBits()) {
1389 : kWRegSizeInBits; 1403 ConditionalCompareHelper(instr, xreg(instr->Rm()));
1390 ConditionalCompareHelper(instr, reg(reg_size, instr->Rm())); 1404 } else {
1405 ConditionalCompareHelper(instr, wreg(instr->Rm()));
1406 }
1391 } 1407 }
1392 1408
1393 1409
1394 void Simulator::VisitConditionalCompareImmediate(Instruction* instr) { 1410 void Simulator::VisitConditionalCompareImmediate(Instruction* instr) {
1395 ConditionalCompareHelper(instr, instr->ImmCondCmp()); 1411 if (instr->SixtyFourBits()) {
1412 ConditionalCompareHelper<int64_t>(instr, instr->ImmCondCmp());
1413 } else {
1414 ConditionalCompareHelper<int32_t>(instr, instr->ImmCondCmp());
1415 }
1396 } 1416 }
1397 1417
1398 1418
1399 void Simulator::ConditionalCompareHelper(Instruction* instr, int64_t op2) { 1419 template<typename T>
1400 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits 1420 void Simulator::ConditionalCompareHelper(Instruction* instr, T op2) {
1401 : kWRegSizeInBits; 1421 T op1 = reg<T>(instr->Rn());
1402 int64_t op1 = reg(reg_size, instr->Rn());
1403 1422
1404 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { 1423 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) {
1405 // If the condition passes, set the status flags to the result of comparing 1424 // If the condition passes, set the status flags to the result of comparing
1406 // the operands. 1425 // the operands.
1407 if (instr->Mask(ConditionalCompareMask) == CCMP) { 1426 if (instr->Mask(ConditionalCompareMask) == CCMP) {
1408 AddWithCarry(reg_size, true, op1, ~op2, 1); 1427 AddWithCarry<T>(true, op1, ~op2, 1);
1409 } else { 1428 } else {
1410 ASSERT(instr->Mask(ConditionalCompareMask) == CCMN); 1429 ASSERT(instr->Mask(ConditionalCompareMask) == CCMN);
1411 AddWithCarry(reg_size, true, op1, op2, 0); 1430 AddWithCarry<T>(true, op1, op2, 0);
1412 } 1431 }
1413 } else { 1432 } else {
1414 // If the condition fails, set the status flags to the nzcv immediate. 1433 // If the condition fails, set the status flags to the nzcv immediate.
1415 nzcv().SetFlags(instr->Nzcv()); 1434 nzcv().SetFlags(instr->Nzcv());
1416 } 1435 }
1417 } 1436 }
1418 1437
1419 1438
1420 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) { 1439 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) {
1421 int offset = instr->ImmLSUnsigned() << instr->SizeLS(); 1440 int offset = instr->ImmLSUnsigned() << instr->SizeLS();
(...skipping 14 matching lines...) Expand all
1436 void Simulator::VisitLoadStorePostIndex(Instruction* instr) { 1455 void Simulator::VisitLoadStorePostIndex(Instruction* instr) {
1437 LoadStoreHelper(instr, instr->ImmLS(), PostIndex); 1456 LoadStoreHelper(instr, instr->ImmLS(), PostIndex);
1438 } 1457 }
1439 1458
1440 1459
1441 void Simulator::VisitLoadStoreRegisterOffset(Instruction* instr) { 1460 void Simulator::VisitLoadStoreRegisterOffset(Instruction* instr) {
1442 Extend ext = static_cast<Extend>(instr->ExtendMode()); 1461 Extend ext = static_cast<Extend>(instr->ExtendMode());
1443 ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX)); 1462 ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX));
1444 unsigned shift_amount = instr->ImmShiftLS() * instr->SizeLS(); 1463 unsigned shift_amount = instr->ImmShiftLS() * instr->SizeLS();
1445 1464
1446 int64_t offset = ExtendValue(kXRegSizeInBits, xreg(instr->Rm()), ext, 1465 int64_t offset = ExtendValue(xreg(instr->Rm()), ext, shift_amount);
1447 shift_amount);
1448 LoadStoreHelper(instr, offset, Offset); 1466 LoadStoreHelper(instr, offset, Offset);
1449 } 1467 }
1450 1468
1451 1469
1452 void Simulator::LoadStoreHelper(Instruction* instr, 1470 void Simulator::LoadStoreHelper(Instruction* instr,
1453 int64_t offset, 1471 int64_t offset,
1454 AddrMode addrmode) { 1472 AddrMode addrmode) {
1455 unsigned srcdst = instr->Rt(); 1473 unsigned srcdst = instr->Rt();
1456 unsigned addr_reg = instr->Rn(); 1474 unsigned addr_reg = instr->Rn();
1457 uint8_t* address = LoadStoreAddress(addr_reg, offset, addrmode); 1475 uint8_t* address = LoadStoreAddress(addr_reg, offset, addrmode);
(...skipping 19 matching lines...) Expand all
1477 switch (op) { 1495 switch (op) {
1478 case LDRB_w: 1496 case LDRB_w:
1479 case LDRH_w: 1497 case LDRH_w:
1480 case LDR_w: 1498 case LDR_w:
1481 case LDR_x: set_xreg(srcdst, MemoryRead(address, num_bytes)); break; 1499 case LDR_x: set_xreg(srcdst, MemoryRead(address, num_bytes)); break;
1482 case STRB_w: 1500 case STRB_w:
1483 case STRH_w: 1501 case STRH_w:
1484 case STR_w: 1502 case STR_w:
1485 case STR_x: MemoryWrite(address, xreg(srcdst), num_bytes); break; 1503 case STR_x: MemoryWrite(address, xreg(srcdst), num_bytes); break;
1486 case LDRSB_w: { 1504 case LDRSB_w: {
1487 set_wreg(srcdst, 1505 set_wreg(srcdst, ExtendValue<int32_t>(MemoryRead8(address), SXTB));
1488 ExtendValue(kWRegSizeInBits, MemoryRead8(address), SXTB));
1489 break; 1506 break;
1490 } 1507 }
1491 case LDRSB_x: { 1508 case LDRSB_x: {
1492 set_xreg(srcdst, 1509 set_xreg(srcdst, ExtendValue<int64_t>(MemoryRead8(address), SXTB));
1493 ExtendValue(kXRegSizeInBits, MemoryRead8(address), SXTB));
1494 break; 1510 break;
1495 } 1511 }
1496 case LDRSH_w: { 1512 case LDRSH_w: {
1497 set_wreg(srcdst, 1513 set_wreg(srcdst, ExtendValue<int32_t>(MemoryRead16(address), SXTH));
1498 ExtendValue(kWRegSizeInBits, MemoryRead16(address), SXTH));
1499 break; 1514 break;
1500 } 1515 }
1501 case LDRSH_x: { 1516 case LDRSH_x: {
1502 set_xreg(srcdst, 1517 set_xreg(srcdst, ExtendValue<int64_t>(MemoryRead16(address), SXTH));
1503 ExtendValue(kXRegSizeInBits, MemoryRead16(address), SXTH));
1504 break; 1518 break;
1505 } 1519 }
1506 case LDRSW_x: { 1520 case LDRSW_x: {
1507 set_xreg(srcdst, 1521 set_xreg(srcdst, ExtendValue<int64_t>(MemoryRead32(address), SXTW));
1508 ExtendValue(kXRegSizeInBits, MemoryRead32(address), SXTW));
1509 break; 1522 break;
1510 } 1523 }
1511 case LDR_s: set_sreg(srcdst, MemoryReadFP32(address)); break; 1524 case LDR_s: set_sreg(srcdst, MemoryReadFP32(address)); break;
1512 case LDR_d: set_dreg(srcdst, MemoryReadFP64(address)); break; 1525 case LDR_d: set_dreg(srcdst, MemoryReadFP64(address)); break;
1513 case STR_s: MemoryWriteFP32(address, sreg(srcdst)); break; 1526 case STR_s: MemoryWriteFP32(address, sreg(srcdst)); break;
1514 case STR_d: MemoryWriteFP64(address, dreg(srcdst)); break; 1527 case STR_d: MemoryWriteFP64(address, dreg(srcdst)); break;
1515 default: UNIMPLEMENTED(); 1528 default: UNIMPLEMENTED();
1516 } 1529 }
1517 1530
1518 // Handle the writeback for loads after the load to ensure safe pop 1531 // Handle the writeback for loads after the load to ensure safe pop
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 set_xreg(rt, MemoryRead64(address)); 1611 set_xreg(rt, MemoryRead64(address));
1599 set_xreg(rt2, MemoryRead64(address + kXRegSize)); 1612 set_xreg(rt2, MemoryRead64(address + kXRegSize));
1600 break; 1613 break;
1601 } 1614 }
1602 case LDP_d: { 1615 case LDP_d: {
1603 set_dreg(rt, MemoryReadFP64(address)); 1616 set_dreg(rt, MemoryReadFP64(address));
1604 set_dreg(rt2, MemoryReadFP64(address + kDRegSize)); 1617 set_dreg(rt2, MemoryReadFP64(address + kDRegSize));
1605 break; 1618 break;
1606 } 1619 }
1607 case LDPSW_x: { 1620 case LDPSW_x: {
1608 set_xreg(rt, ExtendValue(kXRegSizeInBits, MemoryRead32(address), SXTW)); 1621 set_xreg(rt, ExtendValue<int64_t>(MemoryRead32(address), SXTW));
1609 set_xreg(rt2, ExtendValue(kXRegSizeInBits, 1622 set_xreg(rt2, ExtendValue<int64_t>(
1610 MemoryRead32(address + kWRegSize), SXTW)); 1623 MemoryRead32(address + kWRegSize), SXTW));
1611 break; 1624 break;
1612 } 1625 }
1613 case STP_w: { 1626 case STP_w: {
1614 MemoryWrite32(address, wreg(rt)); 1627 MemoryWrite32(address, wreg(rt));
1615 MemoryWrite32(address + kWRegSize, wreg(rt2)); 1628 MemoryWrite32(address + kWRegSize, wreg(rt2));
1616 break; 1629 break;
1617 } 1630 }
1618 case STP_s: { 1631 case STP_s: {
1619 MemoryWriteFP32(address, sreg(rt)); 1632 MemoryWriteFP32(address, sreg(rt));
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1815 default: 1828 default:
1816 UNREACHABLE(); 1829 UNREACHABLE();
1817 } 1830 }
1818 1831
1819 // Update the destination register. 1832 // Update the destination register.
1820 set_xreg(instr->Rd(), new_xn_val); 1833 set_xreg(instr->Rd(), new_xn_val);
1821 } 1834 }
1822 1835
1823 1836
1824 void Simulator::VisitConditionalSelect(Instruction* instr) { 1837 void Simulator::VisitConditionalSelect(Instruction* instr) {
1825 uint64_t new_val = xreg(instr->Rn());
1826
1827 if (ConditionFailed(static_cast<Condition>(instr->Condition()))) { 1838 if (ConditionFailed(static_cast<Condition>(instr->Condition()))) {
1828 new_val = xreg(instr->Rm()); 1839 uint64_t new_val = xreg(instr->Rm());
1829 switch (instr->Mask(ConditionalSelectMask)) { 1840 switch (instr->Mask(ConditionalSelectMask)) {
1830 case CSEL_w: 1841 case CSEL_w: set_wreg(instr->Rd(), new_val); break;
1831 case CSEL_x: break; 1842 case CSEL_x: set_xreg(instr->Rd(), new_val); break;
1832 case CSINC_w: 1843 case CSINC_w: set_wreg(instr->Rd(), new_val + 1); break;
1833 case CSINC_x: new_val++; break; 1844 case CSINC_x: set_xreg(instr->Rd(), new_val + 1); break;
1834 case CSINV_w: 1845 case CSINV_w: set_wreg(instr->Rd(), ~new_val); break;
1835 case CSINV_x: new_val = ~new_val; break; 1846 case CSINV_x: set_xreg(instr->Rd(), ~new_val); break;
1836 case CSNEG_w: 1847 case CSNEG_w: set_wreg(instr->Rd(), -new_val); break;
1837 case CSNEG_x: new_val = -new_val; break; 1848 case CSNEG_x: set_xreg(instr->Rd(), -new_val); break;
1838 default: UNIMPLEMENTED(); 1849 default: UNIMPLEMENTED();
1839 } 1850 }
1851 } else {
1852 if (instr->SixtyFourBits()) {
1853 set_xreg(instr->Rd(), xreg(instr->Rn()));
1854 } else {
1855 set_wreg(instr->Rd(), wreg(instr->Rn()));
1856 }
1840 } 1857 }
1841 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits
1842 : kWRegSizeInBits;
1843 set_reg(reg_size, instr->Rd(), new_val);
1844 } 1858 }
1845 1859
1846 1860
1847 void Simulator::VisitDataProcessing1Source(Instruction* instr) { 1861 void Simulator::VisitDataProcessing1Source(Instruction* instr) {
1848 unsigned dst = instr->Rd(); 1862 unsigned dst = instr->Rd();
1849 unsigned src = instr->Rn(); 1863 unsigned src = instr->Rn();
1850 1864
1851 switch (instr->Mask(DataProcessing1SourceMask)) { 1865 switch (instr->Mask(DataProcessing1SourceMask)) {
1852 case RBIT_w: set_wreg(dst, ReverseBits(wreg(src), kWRegSizeInBits)); break; 1866 case RBIT_w: set_wreg(dst, ReverseBits(wreg(src), kWRegSizeInBits)); break;
1853 case RBIT_x: set_xreg(dst, ReverseBits(xreg(src), kXRegSizeInBits)); break; 1867 case RBIT_x: set_xreg(dst, ReverseBits(xreg(src), kXRegSizeInBits)); break;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1904 {0, 1, 2, 3, 4, 5, 6, 7} }; 1918 {0, 1, 2, 3, 4, 5, 6, 7} };
1905 uint64_t result = 0; 1919 uint64_t result = 0;
1906 for (int i = 0; i < 8; i++) { 1920 for (int i = 0; i < 8; i++) {
1907 result <<= 8; 1921 result <<= 8;
1908 result |= bytes[permute_table[mode][i]]; 1922 result |= bytes[permute_table[mode][i]];
1909 } 1923 }
1910 return result; 1924 return result;
1911 } 1925 }
1912 1926
1913 1927
1914 void Simulator::VisitDataProcessing2Source(Instruction* instr) { 1928 template <typename T>
1929 void Simulator::DataProcessing2Source(Instruction* instr) {
1915 Shift shift_op = NO_SHIFT; 1930 Shift shift_op = NO_SHIFT;
1916 int64_t result = 0; 1931 T result = 0;
1917 switch (instr->Mask(DataProcessing2SourceMask)) { 1932 switch (instr->Mask(DataProcessing2SourceMask)) {
1918 case SDIV_w: { 1933 case SDIV_w:
1919 int32_t rn = wreg(instr->Rn()); 1934 case SDIV_x: {
1920 int32_t rm = wreg(instr->Rm()); 1935 T rn = reg<T>(instr->Rn());
1921 if ((rn == kWMinInt) && (rm == -1)) { 1936 T rm = reg<T>(instr->Rm());
1922 result = kWMinInt; 1937 if ((rn == std::numeric_limits<T>::min()) && (rm == -1)) {
1938 result = std::numeric_limits<T>::min();
1923 } else if (rm == 0) { 1939 } else if (rm == 0) {
1924 // Division by zero can be trapped, but not on A-class processors. 1940 // Division by zero can be trapped, but not on A-class processors.
1925 result = 0; 1941 result = 0;
1926 } else {
1927 result = rn / rm;
1928 }
1929 break;
1930 }
1931 case SDIV_x: {
1932 int64_t rn = xreg(instr->Rn());
1933 int64_t rm = xreg(instr->Rm());
1934 if ((rn == kXMinInt) && (rm == -1)) {
1935 result = kXMinInt;
1936 } else if (rm == 0) {
1937 // Division by zero can be trapped, but not on A-class processors.
1938 result = 0;
1939 } else { 1942 } else {
1940 result = rn / rm; 1943 result = rn / rm;
1941 } 1944 }
1942 break; 1945 break;
1943 } 1946 }
1944 case UDIV_w: { 1947 case UDIV_w:
1945 uint32_t rn = static_cast<uint32_t>(wreg(instr->Rn())); 1948 case UDIV_x: {
1946 uint32_t rm = static_cast<uint32_t>(wreg(instr->Rm())); 1949 typedef typename make_unsigned<T>::type unsignedT;
1950 unsignedT rn = static_cast<unsignedT>(reg<T>(instr->Rn()));
1951 unsignedT rm = static_cast<unsignedT>(reg<T>(instr->Rm()));
1947 if (rm == 0) { 1952 if (rm == 0) {
1948 // Division by zero can be trapped, but not on A-class processors. 1953 // Division by zero can be trapped, but not on A-class processors.
1949 result = 0; 1954 result = 0;
1950 } else {
1951 result = rn / rm;
1952 }
1953 break;
1954 }
1955 case UDIV_x: {
1956 uint64_t rn = static_cast<uint64_t>(xreg(instr->Rn()));
1957 uint64_t rm = static_cast<uint64_t>(xreg(instr->Rm()));
1958 if (rm == 0) {
1959 // Division by zero can be trapped, but not on A-class processors.
1960 result = 0;
1961 } else { 1955 } else {
1962 result = rn / rm; 1956 result = rn / rm;
1963 } 1957 }
1964 break; 1958 break;
1965 } 1959 }
1966 case LSLV_w: 1960 case LSLV_w:
1967 case LSLV_x: shift_op = LSL; break; 1961 case LSLV_x: shift_op = LSL; break;
1968 case LSRV_w: 1962 case LSRV_w:
1969 case LSRV_x: shift_op = LSR; break; 1963 case LSRV_x: shift_op = LSR; break;
1970 case ASRV_w: 1964 case ASRV_w:
1971 case ASRV_x: shift_op = ASR; break; 1965 case ASRV_x: shift_op = ASR; break;
1972 case RORV_w: 1966 case RORV_w:
1973 case RORV_x: shift_op = ROR; break; 1967 case RORV_x: shift_op = ROR; break;
1974 default: UNIMPLEMENTED(); 1968 default: UNIMPLEMENTED();
1975 } 1969 }
1976 1970
1977 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits
1978 : kWRegSizeInBits;
1979 if (shift_op != NO_SHIFT) { 1971 if (shift_op != NO_SHIFT) {
1980 // Shift distance encoded in the least-significant five/six bits of the 1972 // Shift distance encoded in the least-significant five/six bits of the
1981 // register. 1973 // register.
1982 int mask = (instr->SixtyFourBits() == 1) ? kShiftAmountXRegMask 1974 unsigned shift = wreg(instr->Rm());
1983 : kShiftAmountWRegMask; 1975 if (sizeof(T) == kWRegSize) {
1984 unsigned shift = wreg(instr->Rm()) & mask; 1976 shift &= kShiftAmountWRegMask;
1985 result = ShiftOperand(reg_size, reg(reg_size, instr->Rn()), shift_op, 1977 } else {
1986 shift); 1978 shift &= kShiftAmountXRegMask;
1979 }
1980 result = ShiftOperand(reg<T>(instr->Rn()), shift_op, shift);
1987 } 1981 }
1988 set_reg(reg_size, instr->Rd(), result); 1982 set_reg<T>(instr->Rd(), result);
1989 } 1983 }
1990 1984
1991 1985
1986 void Simulator::VisitDataProcessing2Source(Instruction* instr) {
1987 if (instr->SixtyFourBits()) {
1988 DataProcessing2Source<int64_t>(instr);
1989 } else {
1990 DataProcessing2Source<int32_t>(instr);
1991 }
1992 }
1993
1994
1992 // The algorithm used is described in section 8.2 of 1995 // The algorithm used is described in section 8.2 of
1993 // Hacker's Delight, by Henry S. Warren, Jr. 1996 // Hacker's Delight, by Henry S. Warren, Jr.
1994 // It assumes that a right shift on a signed integer is an arithmetic shift. 1997 // It assumes that a right shift on a signed integer is an arithmetic shift.
1995 static int64_t MultiplyHighSigned(int64_t u, int64_t v) { 1998 static int64_t MultiplyHighSigned(int64_t u, int64_t v) {
1996 uint64_t u0, v0, w0; 1999 uint64_t u0, v0, w0;
1997 int64_t u1, v1, w1, w2, t; 2000 int64_t u1, v1, w1, w2, t;
1998 2001
1999 u0 = u & 0xffffffffL; 2002 u0 = u & 0xffffffffL;
2000 u1 = u >> 32; 2003 u1 = u >> 32;
2001 v0 = v & 0xffffffffL; 2004 v0 = v & 0xffffffffL;
2002 v1 = v >> 32; 2005 v1 = v >> 32;
2003 2006
2004 w0 = u0 * v0; 2007 w0 = u0 * v0;
2005 t = u1 * v0 + (w0 >> 32); 2008 t = u1 * v0 + (w0 >> 32);
2006 w1 = t & 0xffffffffL; 2009 w1 = t & 0xffffffffL;
2007 w2 = t >> 32; 2010 w2 = t >> 32;
2008 w1 = u0 * v1 + w1; 2011 w1 = u0 * v1 + w1;
2009 2012
2010 return u1 * v1 + w2 + (w1 >> 32); 2013 return u1 * v1 + w2 + (w1 >> 32);
2011 } 2014 }
2012 2015
2013 2016
2014 void Simulator::VisitDataProcessing3Source(Instruction* instr) { 2017 void Simulator::VisitDataProcessing3Source(Instruction* instr) {
2015 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits
2016 : kWRegSizeInBits;
2017
2018 int64_t result = 0; 2018 int64_t result = 0;
2019 // Extract and sign- or zero-extend 32-bit arguments for widening operations. 2019 // Extract and sign- or zero-extend 32-bit arguments for widening operations.
2020 uint64_t rn_u32 = reg<uint32_t>(instr->Rn()); 2020 uint64_t rn_u32 = reg<uint32_t>(instr->Rn());
2021 uint64_t rm_u32 = reg<uint32_t>(instr->Rm()); 2021 uint64_t rm_u32 = reg<uint32_t>(instr->Rm());
2022 int64_t rn_s32 = reg<int32_t>(instr->Rn()); 2022 int64_t rn_s32 = reg<int32_t>(instr->Rn());
2023 int64_t rm_s32 = reg<int32_t>(instr->Rm()); 2023 int64_t rm_s32 = reg<int32_t>(instr->Rm());
2024 switch (instr->Mask(DataProcessing3SourceMask)) { 2024 switch (instr->Mask(DataProcessing3SourceMask)) {
2025 case MADD_w: 2025 case MADD_w:
2026 case MADD_x: 2026 case MADD_x:
2027 result = xreg(instr->Ra()) + (xreg(instr->Rn()) * xreg(instr->Rm())); 2027 result = xreg(instr->Ra()) + (xreg(instr->Rn()) * xreg(instr->Rm()));
2028 break; 2028 break;
2029 case MSUB_w: 2029 case MSUB_w:
2030 case MSUB_x: 2030 case MSUB_x:
2031 result = xreg(instr->Ra()) - (xreg(instr->Rn()) * xreg(instr->Rm())); 2031 result = xreg(instr->Ra()) - (xreg(instr->Rn()) * xreg(instr->Rm()));
2032 break; 2032 break;
2033 case SMADDL_x: result = xreg(instr->Ra()) + (rn_s32 * rm_s32); break; 2033 case SMADDL_x: result = xreg(instr->Ra()) + (rn_s32 * rm_s32); break;
2034 case SMSUBL_x: result = xreg(instr->Ra()) - (rn_s32 * rm_s32); break; 2034 case SMSUBL_x: result = xreg(instr->Ra()) - (rn_s32 * rm_s32); break;
2035 case UMADDL_x: result = xreg(instr->Ra()) + (rn_u32 * rm_u32); break; 2035 case UMADDL_x: result = xreg(instr->Ra()) + (rn_u32 * rm_u32); break;
2036 case UMSUBL_x: result = xreg(instr->Ra()) - (rn_u32 * rm_u32); break; 2036 case UMSUBL_x: result = xreg(instr->Ra()) - (rn_u32 * rm_u32); break;
2037 case SMULH_x: 2037 case SMULH_x:
2038 ASSERT(instr->Ra() == kZeroRegCode); 2038 ASSERT(instr->Ra() == kZeroRegCode);
2039 result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm())); 2039 result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm()));
2040 break; 2040 break;
2041 default: UNIMPLEMENTED(); 2041 default: UNIMPLEMENTED();
2042 } 2042 }
2043 set_reg(reg_size, instr->Rd(), result); 2043
2044 if (instr->SixtyFourBits()) {
2045 set_xreg(instr->Rd(), result);
2046 } else {
2047 set_wreg(instr->Rd(), result);
2048 }
2044 } 2049 }
2045 2050
2046 2051
2047 void Simulator::VisitBitfield(Instruction* instr) { 2052 template <typename T>
2048 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits 2053 void Simulator::BitfieldHelper(Instruction* instr) {
2049 : kWRegSizeInBits; 2054 typedef typename make_unsigned<T>::type unsignedT;
2050 int64_t reg_mask = instr->SixtyFourBits() ? kXRegMask : kWRegMask; 2055 T reg_size = sizeof(T) * 8;
2051 int64_t R = instr->ImmR(); 2056 T R = instr->ImmR();
2052 int64_t S = instr->ImmS(); 2057 T S = instr->ImmS();
2053 int64_t diff = S - R; 2058 T diff = S - R;
2054 int64_t mask; 2059 T mask;
2055 if (diff >= 0) { 2060 if (diff >= 0) {
2056 mask = diff < reg_size - 1 ? (1L << (diff + 1)) - 1 2061 mask = diff < reg_size - 1 ? (static_cast<T>(1) << (diff + 1)) - 1
2057 : reg_mask; 2062 : static_cast<T>(-1);
2058 } else { 2063 } else {
2059 mask = ((1L << (S + 1)) - 1); 2064 mask = ((1L << (S + 1)) - 1);
2060 mask = (static_cast<uint64_t>(mask) >> R) | (mask << (reg_size - R)); 2065 mask = (static_cast<uint64_t>(mask) >> R) | (mask << (reg_size - R));
2061 diff += reg_size; 2066 diff += reg_size;
2062 } 2067 }
2063 2068
2064 // inzero indicates if the extracted bitfield is inserted into the 2069 // inzero indicates if the extracted bitfield is inserted into the
2065 // destination register value or in zero. 2070 // destination register value or in zero.
2066 // If extend is true, extend the sign of the extracted bitfield. 2071 // If extend is true, extend the sign of the extracted bitfield.
2067 bool inzero = false; 2072 bool inzero = false;
2068 bool extend = false; 2073 bool extend = false;
2069 switch (instr->Mask(BitfieldMask)) { 2074 switch (instr->Mask(BitfieldMask)) {
2070 case BFM_x: 2075 case BFM_x:
2071 case BFM_w: 2076 case BFM_w:
2072 break; 2077 break;
2073 case SBFM_x: 2078 case SBFM_x:
2074 case SBFM_w: 2079 case SBFM_w:
2075 inzero = true; 2080 inzero = true;
2076 extend = true; 2081 extend = true;
2077 break; 2082 break;
2078 case UBFM_x: 2083 case UBFM_x:
2079 case UBFM_w: 2084 case UBFM_w:
2080 inzero = true; 2085 inzero = true;
2081 break; 2086 break;
2082 default: 2087 default:
2083 UNIMPLEMENTED(); 2088 UNIMPLEMENTED();
2084 } 2089 }
2085 2090
2086 int64_t dst = inzero ? 0 : reg(reg_size, instr->Rd()); 2091 T dst = inzero ? 0 : reg<T>(instr->Rd());
2087 int64_t src = reg(reg_size, instr->Rn()); 2092 T src = reg<T>(instr->Rn());
2088 // Rotate source bitfield into place. 2093 // Rotate source bitfield into place.
2089 int64_t result = (static_cast<uint64_t>(src) >> R) | (src << (reg_size - R)); 2094 T result = (static_cast<unsignedT>(src) >> R) | (src << (reg_size - R));
2090 // Determine the sign extension. 2095 // Determine the sign extension.
2091 int64_t topbits_preshift = (1L << (reg_size - diff - 1)) - 1; 2096 T topbits_preshift = (static_cast<T>(1) << (reg_size - diff - 1)) - 1;
2092 int64_t signbits = (extend && ((src >> S) & 1) ? topbits_preshift : 0) 2097 T signbits = (extend && ((src >> S) & 1) ? topbits_preshift : 0)
2093 << (diff + 1); 2098 << (diff + 1);
2094 2099
2095 // Merge sign extension, dest/zero and bitfield. 2100 // Merge sign extension, dest/zero and bitfield.
2096 result = signbits | (result & mask) | (dst & ~mask); 2101 result = signbits | (result & mask) | (dst & ~mask);
2097 2102
2098 set_reg(reg_size, instr->Rd(), result); 2103 set_reg<T>(instr->Rd(), result);
2104 }
2105
2106
2107 void Simulator::VisitBitfield(Instruction* instr) {
2108 if (instr->SixtyFourBits()) {
2109 BitfieldHelper<int64_t>(instr);
2110 } else {
2111 BitfieldHelper<int32_t>(instr);
2112 }
2099 } 2113 }
2100 2114
2101 2115
2102 void Simulator::VisitExtract(Instruction* instr) { 2116 void Simulator::VisitExtract(Instruction* instr) {
2103 unsigned lsb = instr->ImmS(); 2117 if (instr->SixtyFourBits()) {
2104 unsigned reg_size = (instr->SixtyFourBits() == 1) ? kXRegSizeInBits 2118 Extract<uint64_t>(instr);
2105 : kWRegSizeInBits; 2119 } else {
2106 set_reg(reg_size, 2120 Extract<uint32_t>(instr);
2107 instr->Rd(), 2121 }
2108 (static_cast<uint64_t>(reg(reg_size, instr->Rm())) >> lsb) |
2109 (reg(reg_size, instr->Rn()) << (reg_size - lsb)));
2110 } 2122 }
2111 2123
2112 2124
2113 void Simulator::VisitFPImmediate(Instruction* instr) { 2125 void Simulator::VisitFPImmediate(Instruction* instr) {
2114 AssertSupportedFPCR(); 2126 AssertSupportedFPCR();
2115 2127
2116 unsigned dest = instr->Rd(); 2128 unsigned dest = instr->Rd();
2117 switch (instr->Mask(FPImmediateMask)) { 2129 switch (instr->Mask(FPImmediateMask)) {
2118 case FMOV_s_imm: set_sreg(dest, instr->ImmFP32()); break; 2130 case FMOV_s_imm: set_sreg(dest, instr->ImmFP32()); break;
2119 case FMOV_d_imm: set_dreg(dest, instr->ImmFP64()); break; 2131 case FMOV_d_imm: set_dreg(dest, instr->ImmFP64()); break;
(...skipping 1604 matching lines...) Expand 10 before | Expand all | Expand 10 after
3724 3736
3725 delete[] format; 3737 delete[] format;
3726 } 3738 }
3727 3739
3728 3740
3729 #endif // USE_SIMULATOR 3741 #endif // USE_SIMULATOR
3730 3742
3731 } } // namespace v8::internal 3743 } } // namespace v8::internal
3732 3744
3733 #endif // V8_TARGET_ARCH_ARM64 3745 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« src/arm64/simulator-arm64.h ('K') | « src/arm64/simulator-arm64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698