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

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

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

Powered by Google App Engine
This is Rietveld 408576698