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

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 860 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 if (set_flags) { 871 if (set_flags) {
872 nzcv().SetN(N); 872 nzcv().SetN(N);
873 nzcv().SetZ(Z); 873 nzcv().SetZ(Z);
874 nzcv().SetC(C); 874 nzcv().SetC(C);
875 nzcv().SetV(V); 875 nzcv().SetV(V);
876 } 876 }
877 return result; 877 return result;
878 } 878 }
879 879
880 880
881 int64_t Simulator::ShiftOperand(unsigned reg_size, 881 template<> struct make_unsigned<int32_t> {
882 int64_t value, 882 public:
883 Shift shift_type, 883 typedef uint32_t type;
884 unsigned amount) { 884 };
885
886
887 template<> struct make_unsigned<int64_t> {
888 public:
jbramley 2014/05/16 14:05:50 Is 'public' necessary here?
Fritz 2014/05/16 18:11:46 Yes. Below it is accessed make_unsigned<T>::type
Sven Panne 2014/05/19 08:12:26 Huh? struct = class + public, so this shouldn't be
Fritz 2014/05/20 19:44:24 Your correct. My mistake. Done.
889 typedef uint64_t type;
890 };
891
892
893 template <typename T>
894 T Simulator::ShiftOperand(T value, Shift shift_type, unsigned amount) {
895 typedef typename make_unsigned<T>::type unsignedT;
jbramley 2014/05/16 14:05:50 I don't like this mechanism I'm afraid; it's not a
Fritz 2014/05/16 18:11:46 I haven't found away around this yet. Propagating
896
885 if (amount == 0) { 897 if (amount == 0) {
886 return value; 898 return value;
887 } 899 }
888 int64_t mask = reg_size == kXRegSizeInBits ? kXRegMask : kWRegMask; 900
889 switch (shift_type) { 901 switch (shift_type) {
890 case LSL: 902 case LSL:
891 return (value << amount) & mask; 903 return value << amount;
892 case LSR: 904 case LSR:
893 return static_cast<uint64_t>(value) >> amount; 905 return static_cast<unsignedT>(value) >> amount;
894 case ASR: { 906 case ASR: {
895 // Shift used to restore the sign. 907 return value >> amount;
896 unsigned s_shift = kXRegSizeInBits - reg_size;
897 // Value with its sign restored.
898 int64_t s_value = (value << s_shift) >> s_shift;
899 return (s_value >> amount) & mask;
900 } 908 }
901 case ROR: { 909 case ROR: {
902 if (reg_size == kWRegSizeInBits) { 910 return (static_cast<unsignedT>(value) >> amount) |
903 value &= kWRegMask; 911 ((value & ((1L << amount) - 1L)) <<
904 } 912 (sizeof(unsignedT) * 8 - amount));
905 return (static_cast<uint64_t>(value) >> amount) |
906 ((value & ((1L << amount) - 1L)) << (reg_size - amount));
907 } 913 }
908 default: 914 default:
909 UNIMPLEMENTED(); 915 UNIMPLEMENTED();
910 return 0; 916 return 0;
911 } 917 }
912 } 918 }
913 919
914 920
915 int64_t Simulator::ExtendValue(unsigned reg_size, 921 int64_t Simulator::ExtendValue(unsigned reg_size,
916 int64_t value, 922 int64_t value,
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 break; 1288 break;
1283 } 1289 }
1284 default: UNREACHABLE(); 1290 default: UNREACHABLE();
1285 } 1291 }
1286 1292
1287 set_reg(reg_size, instr->Rd(), new_val, instr->RdMode()); 1293 set_reg(reg_size, instr->Rd(), new_val, instr->RdMode());
1288 } 1294 }
1289 1295
1290 1296
1291 void Simulator::VisitAddSubShifted(Instruction* instr) { 1297 void Simulator::VisitAddSubShifted(Instruction* instr) {
1292 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits 1298 int64_t op2 = 0;
1293 : kWRegSizeInBits; 1299 if (instr->SixtyFourBits()) {
1294 int64_t op2 = ShiftOperand(reg_size, 1300 op2 = ShiftOperand(xreg(instr->Rm()),
1295 reg(reg_size, instr->Rm()), 1301 static_cast<Shift>(instr->ShiftDP()),
1296 static_cast<Shift>(instr->ShiftDP()), 1302 instr->ImmDPShift());
1297 instr->ImmDPShift()); 1303 } else {
1304 op2 = ShiftOperand(wreg(instr->Rm()),
1305 static_cast<Shift>(instr->ShiftDP()),
1306 instr->ImmDPShift());
jbramley 2014/05/16 14:05:50 This would be clearer (and fit on one line) if it
Fritz 2014/05/16 18:11:46 Done.
1307 op2 &= kWRegMask;
1308 }
1298 AddSubHelper(instr, op2); 1309 AddSubHelper(instr, op2);
1299 } 1310 }
1300 1311
1301 1312
1302 void Simulator::VisitAddSubImmediate(Instruction* instr) { 1313 void Simulator::VisitAddSubImmediate(Instruction* instr) {
1303 int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0); 1314 int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0);
1304 AddSubHelper(instr, op2); 1315 AddSubHelper(instr, op2);
1305 } 1316 }
1306 1317
1307 1318
(...skipping 22 matching lines...) Expand all
1330 instr->FlagsUpdate(), 1341 instr->FlagsUpdate(),
1331 reg(reg_size, instr->Rn()), 1342 reg(reg_size, instr->Rn()),
1332 op2, 1343 op2,
1333 nzcv().C()); 1344 nzcv().C());
1334 1345
1335 set_reg(reg_size, instr->Rd(), new_val); 1346 set_reg(reg_size, instr->Rd(), new_val);
1336 } 1347 }
1337 1348
1338 1349
1339 void Simulator::VisitLogicalShifted(Instruction* instr) { 1350 void Simulator::VisitLogicalShifted(Instruction* instr) {
1340 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits
1341 : kWRegSizeInBits;
1342 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); 1351 Shift shift_type = static_cast<Shift>(instr->ShiftDP());
1343 unsigned shift_amount = instr->ImmDPShift(); 1352 unsigned shift_amount = instr->ImmDPShift();
1344 int64_t op2 = ShiftOperand(reg_size, reg(reg_size, instr->Rm()), shift_type, 1353 int64_t op2 = 0;
1345 shift_amount); 1354
1355 if (instr->SixtyFourBits()) {
1356 op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount);
1357 } else {
1358 op2 = ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount);
1359 op2 &= kWRegMask;
jbramley 2014/05/16 14:05:50 Doesn't the new ShiftOperand apply that mask? If s
Fritz 2014/05/16 18:11:46 ShiftOperand was returning a signed int64_t. It's
1360 }
1361
1346 if (instr->Mask(NOT) == NOT) { 1362 if (instr->Mask(NOT) == NOT) {
1347 op2 = ~op2; 1363 op2 = ~op2;
1348 } 1364 }
1349 LogicalHelper(instr, op2); 1365 LogicalHelper(instr, op2);
1350 } 1366 }
1351 1367
1352 1368
1353 void Simulator::VisitLogicalImmediate(Instruction* instr) { 1369 void Simulator::VisitLogicalImmediate(Instruction* instr) {
1354 LogicalHelper(instr, instr->ImmLogical()); 1370 LogicalHelper(instr, instr->ImmLogical());
1355 } 1371 }
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
1903 {4, 5, 6, 7, 0, 1, 2, 3}, 1919 {4, 5, 6, 7, 0, 1, 2, 3},
1904 {0, 1, 2, 3, 4, 5, 6, 7} }; 1920 {0, 1, 2, 3, 4, 5, 6, 7} };
1905 uint64_t result = 0; 1921 uint64_t result = 0;
1906 for (int i = 0; i < 8; i++) { 1922 for (int i = 0; i < 8; i++) {
1907 result <<= 8; 1923 result <<= 8;
1908 result |= bytes[permute_table[mode][i]]; 1924 result |= bytes[permute_table[mode][i]];
1909 } 1925 }
1910 return result; 1926 return result;
1911 } 1927 }
1912 1928
1913 1929 template <typename T>
1914 void Simulator::VisitDataProcessing2Source(Instruction* instr) { 1930 void Simulator::DataProcessing2Source(Instruction* instr) {
1931 typedef typename make_unsigned<T>::type unsignedT;
1915 Shift shift_op = NO_SHIFT; 1932 Shift shift_op = NO_SHIFT;
1916 int64_t result = 0; 1933 T result = 0;
1934 const T kMinimumInteger = static_cast<T>(1) << (sizeof(T) * 8 - 1);
jbramley 2014/05/16 14:05:50 Consider adding a helper function to do this (perh
Fritz 2014/05/16 18:11:46 Thanks, great idea.
Sven Panne 2014/05/19 08:12:26 Even better idea: Use <limits>: http://www.cpluspl
Fritz 2014/05/20 19:44:24 Done.
1917 switch (instr->Mask(DataProcessing2SourceMask)) { 1935 switch (instr->Mask(DataProcessing2SourceMask)) {
1918 case SDIV_w: { 1936 case SDIV_w:
1919 int32_t rn = wreg(instr->Rn()); 1937 case SDIV_x: {
1920 int32_t rm = wreg(instr->Rm()); 1938 T rn = reg<T>(instr->Rn());
1921 if ((rn == kWMinInt) && (rm == -1)) { 1939 T rm = reg<T>(instr->Rm());
1922 result = kWMinInt; 1940 if ((rn == kMinimumInteger) && (rm == -1)) {
1941 result = kMinimumInteger;
1923 } else if (rm == 0) { 1942 } else if (rm == 0) {
1924 // Division by zero can be trapped, but not on A-class processors. 1943 // Division by zero can be trapped, but not on A-class processors.
1925 result = 0; 1944 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 { 1945 } else {
1940 result = rn / rm; 1946 result = rn / rm;
1941 } 1947 }
1942 break; 1948 break;
1943 } 1949 }
1944 case UDIV_w: { 1950 case UDIV_w:
1945 uint32_t rn = static_cast<uint32_t>(wreg(instr->Rn())); 1951 case UDIV_x: {
1946 uint32_t rm = static_cast<uint32_t>(wreg(instr->Rm())); 1952 unsignedT rn = static_cast<unsignedT>(reg<T>(instr->Rn()));
1953 unsignedT rm = static_cast<unsignedT>(reg<T>(instr->Rm()));
1947 if (rm == 0) { 1954 if (rm == 0) {
1948 // Division by zero can be trapped, but not on A-class processors. 1955 // Division by zero can be trapped, but not on A-class processors.
1949 result = 0; 1956 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 { 1957 } else {
1962 result = rn / rm; 1958 result = rn / rm;
1963 } 1959 }
1964 break; 1960 break;
1965 } 1961 }
1966 case LSLV_w: 1962 case LSLV_w:
1967 case LSLV_x: shift_op = LSL; break; 1963 case LSLV_x: shift_op = LSL; break;
1968 case LSRV_w: 1964 case LSRV_w:
1969 case LSRV_x: shift_op = LSR; break; 1965 case LSRV_x: shift_op = LSR; break;
1970 case ASRV_w: 1966 case ASRV_w:
1971 case ASRV_x: shift_op = ASR; break; 1967 case ASRV_x: shift_op = ASR; break;
1972 case RORV_w: 1968 case RORV_w:
1973 case RORV_x: shift_op = ROR; break; 1969 case RORV_x: shift_op = ROR; break;
1974 default: UNIMPLEMENTED(); 1970 default: UNIMPLEMENTED();
1975 } 1971 }
1976 1972
1977 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits
1978 : kWRegSizeInBits;
1979 if (shift_op != NO_SHIFT) { 1973 if (shift_op != NO_SHIFT) {
1980 // Shift distance encoded in the least-significant five/six bits of the 1974 // Shift distance encoded in the least-significant five/six bits of the
1981 // register. 1975 // register.
1982 int mask = (instr->SixtyFourBits() == 1) ? kShiftAmountXRegMask 1976 unsigned shift = wreg(instr->Rm());
1983 : kShiftAmountWRegMask; 1977 if (sizeof(T) == kWRegSize) {
1984 unsigned shift = wreg(instr->Rm()) & mask; 1978 shift &= kShiftAmountWRegMask;
1985 result = ShiftOperand(reg_size, reg(reg_size, instr->Rn()), shift_op, 1979 } else {
1986 shift); 1980 shift &= kShiftAmountXRegMask;
1981 }
1982 result = ShiftOperand(reg<T>(instr->Rn()), shift_op, shift);
1987 } 1983 }
1988 set_reg(reg_size, instr->Rd(), result); 1984 set_reg<T>(instr->Rd(), result);
1989 } 1985 }
1990 1986
1991 1987
1988 void Simulator::VisitDataProcessing2Source(Instruction* instr) {
1989 if (instr->SixtyFourBits()) {
1990 DataProcessing2Source<int64_t>(instr);
1991 } else {
1992 DataProcessing2Source<int32_t>(instr);
1993 }
1994 }
1995
1996
1992 // The algorithm used is described in section 8.2 of 1997 // The algorithm used is described in section 8.2 of
1993 // Hacker's Delight, by Henry S. Warren, Jr. 1998 // Hacker's Delight, by Henry S. Warren, Jr.
1994 // It assumes that a right shift on a signed integer is an arithmetic shift. 1999 // 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) { 2000 static int64_t MultiplyHighSigned(int64_t u, int64_t v) {
1996 uint64_t u0, v0, w0; 2001 uint64_t u0, v0, w0;
1997 int64_t u1, v1, w1, w2, t; 2002 int64_t u1, v1, w1, w2, t;
1998 2003
1999 u0 = u & 0xffffffffL; 2004 u0 = u & 0xffffffffL;
2000 u1 = u >> 32; 2005 u1 = u >> 32;
2001 v0 = v & 0xffffffffL; 2006 v0 = v & 0xffffffffL;
(...skipping 1722 matching lines...) Expand 10 before | Expand all | Expand 10 after
3724 3729
3725 delete[] format; 3730 delete[] format;
3726 } 3731 }
3727 3732
3728 3733
3729 #endif // USE_SIMULATOR 3734 #endif // USE_SIMULATOR
3730 3735
3731 } } // namespace v8::internal 3736 } } // namespace v8::internal
3732 3737
3733 #endif // V8_TARGET_ARCH_ARM64 3738 #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