OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <limits.h> | 5 #include <limits.h> |
6 #include <stdarg.h> | 6 #include <stdarg.h> |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #if V8_TARGET_ARCH_MIPS64 | 10 #if V8_TARGET_ARCH_MIPS64 |
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1254 } | 1254 } |
1255 | 1255 |
1256 return ret; | 1256 return ret; |
1257 } | 1257 } |
1258 | 1258 |
1259 | 1259 |
1260 // Sets the rounding error codes in FCSR based on the result of the rounding. | 1260 // Sets the rounding error codes in FCSR based on the result of the rounding. |
1261 // Returns true if the operation was invalid. | 1261 // Returns true if the operation was invalid. |
1262 bool Simulator::set_fcsr_round64_error(double original, double rounded) { | 1262 bool Simulator::set_fcsr_round64_error(double original, double rounded) { |
1263 bool ret = false; | 1263 bool ret = false; |
| 1264 // The value of INT64_MAX (2^63-1) can't be represented as double exactly, |
| 1265 // loading the most accurate representation into max_int64, which is 2^63. |
1264 double max_int64 = std::numeric_limits<int64_t>::max(); | 1266 double max_int64 = std::numeric_limits<int64_t>::max(); |
1265 double min_int64 = std::numeric_limits<int64_t>::min(); | 1267 double min_int64 = std::numeric_limits<int64_t>::min(); |
1266 | 1268 |
1267 if (!std::isfinite(original) || !std::isfinite(rounded)) { | 1269 if (!std::isfinite(original) || !std::isfinite(rounded)) { |
1268 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1270 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1269 ret = true; | 1271 ret = true; |
1270 } | 1272 } |
1271 | 1273 |
1272 if (original != rounded) { | 1274 if (original != rounded) { |
1273 set_fcsr_bit(kFCSRInexactFlagBit, true); | 1275 set_fcsr_bit(kFCSRInexactFlagBit, true); |
1274 } | 1276 } |
1275 | 1277 |
1276 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) { | 1278 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) { |
1277 set_fcsr_bit(kFCSRUnderflowFlagBit, true); | 1279 set_fcsr_bit(kFCSRUnderflowFlagBit, true); |
1278 ret = true; | 1280 ret = true; |
1279 } | 1281 } |
1280 | 1282 |
1281 if (rounded > max_int64 || rounded < min_int64) { | 1283 if (rounded >= max_int64 || rounded < min_int64) { |
1282 set_fcsr_bit(kFCSROverflowFlagBit, true); | 1284 set_fcsr_bit(kFCSROverflowFlagBit, true); |
1283 // The reference is not really clear but it seems this is required: | 1285 // The reference is not really clear but it seems this is required: |
1284 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1286 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1285 ret = true; | 1287 ret = true; |
1286 } | 1288 } |
1287 | 1289 |
1288 return ret; | 1290 return ret; |
1289 } | 1291 } |
1290 | 1292 |
1291 | 1293 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1355 } | 1357 } |
1356 } else { | 1358 } else { |
1357 set_fpu_register(fd_reg(), kFPUInvalidResult); | 1359 set_fpu_register(fd_reg(), kFPUInvalidResult); |
1358 } | 1360 } |
1359 } | 1361 } |
1360 | 1362 |
1361 | 1363 |
1362 void Simulator::set_fpu_register_invalid_result64(float original, | 1364 void Simulator::set_fpu_register_invalid_result64(float original, |
1363 float rounded) { | 1365 float rounded) { |
1364 if (FCSR_ & kFCSRNaN2008FlagMask) { | 1366 if (FCSR_ & kFCSRNaN2008FlagMask) { |
| 1367 // The value of INT64_MAX (2^63-1) can't be represented as double exactly, |
| 1368 // loading the most accurate representation into max_int64, which is 2^63. |
1365 double max_int64 = std::numeric_limits<int64_t>::max(); | 1369 double max_int64 = std::numeric_limits<int64_t>::max(); |
1366 double min_int64 = std::numeric_limits<int64_t>::min(); | 1370 double min_int64 = std::numeric_limits<int64_t>::min(); |
1367 if (std::isnan(original)) { | 1371 if (std::isnan(original)) { |
1368 set_fpu_register(fd_reg(), 0); | 1372 set_fpu_register(fd_reg(), 0); |
1369 } else if (rounded > max_int64) { | 1373 } else if (rounded >= max_int64) { |
1370 set_fpu_register(fd_reg(), kFPU64InvalidResult); | 1374 set_fpu_register(fd_reg(), kFPU64InvalidResult); |
1371 } else if (rounded < min_int64) { | 1375 } else if (rounded < min_int64) { |
1372 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative); | 1376 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative); |
1373 } else { | 1377 } else { |
1374 UNREACHABLE(); | 1378 UNREACHABLE(); |
1375 } | 1379 } |
1376 } else { | 1380 } else { |
1377 set_fpu_register(fd_reg(), kFPU64InvalidResult); | 1381 set_fpu_register(fd_reg(), kFPU64InvalidResult); |
1378 } | 1382 } |
1379 } | 1383 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 } | 1419 } |
1416 } else { | 1420 } else { |
1417 set_fpu_register(fd_reg(), kFPUInvalidResult); | 1421 set_fpu_register(fd_reg(), kFPUInvalidResult); |
1418 } | 1422 } |
1419 } | 1423 } |
1420 | 1424 |
1421 | 1425 |
1422 void Simulator::set_fpu_register_invalid_result64(double original, | 1426 void Simulator::set_fpu_register_invalid_result64(double original, |
1423 double rounded) { | 1427 double rounded) { |
1424 if (FCSR_ & kFCSRNaN2008FlagMask) { | 1428 if (FCSR_ & kFCSRNaN2008FlagMask) { |
| 1429 // The value of INT64_MAX (2^63-1) can't be represented as double exactly, |
| 1430 // loading the most accurate representation into max_int64, which is 2^63. |
1425 double max_int64 = std::numeric_limits<int64_t>::max(); | 1431 double max_int64 = std::numeric_limits<int64_t>::max(); |
1426 double min_int64 = std::numeric_limits<int64_t>::min(); | 1432 double min_int64 = std::numeric_limits<int64_t>::min(); |
1427 if (std::isnan(original)) { | 1433 if (std::isnan(original)) { |
1428 set_fpu_register(fd_reg(), 0); | 1434 set_fpu_register(fd_reg(), 0); |
1429 } else if (rounded > max_int64) { | 1435 } else if (rounded >= max_int64) { |
1430 set_fpu_register(fd_reg(), kFPU64InvalidResult); | 1436 set_fpu_register(fd_reg(), kFPU64InvalidResult); |
1431 } else if (rounded < min_int64) { | 1437 } else if (rounded < min_int64) { |
1432 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative); | 1438 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative); |
1433 } else { | 1439 } else { |
1434 UNREACHABLE(); | 1440 UNREACHABLE(); |
1435 } | 1441 } |
1436 } else { | 1442 } else { |
1437 set_fpu_register(fd_reg(), kFPU64InvalidResult); | 1443 set_fpu_register(fd_reg(), kFPU64InvalidResult); |
1438 } | 1444 } |
1439 } | 1445 } |
1440 | 1446 |
1441 | 1447 |
1442 // Sets the rounding error codes in FCSR based on the result of the rounding. | 1448 // Sets the rounding error codes in FCSR based on the result of the rounding. |
1443 // Returns true if the operation was invalid. | 1449 // Returns true if the operation was invalid. |
1444 bool Simulator::set_fcsr_round64_error(float original, float rounded) { | 1450 bool Simulator::set_fcsr_round64_error(float original, float rounded) { |
1445 bool ret = false; | 1451 bool ret = false; |
| 1452 // The value of INT64_MAX (2^63-1) can't be represented as double exactly, |
| 1453 // loading the most accurate representation into max_int64, which is 2^63. |
1446 double max_int64 = std::numeric_limits<int64_t>::max(); | 1454 double max_int64 = std::numeric_limits<int64_t>::max(); |
1447 double min_int64 = std::numeric_limits<int64_t>::min(); | 1455 double min_int64 = std::numeric_limits<int64_t>::min(); |
1448 | 1456 |
1449 if (!std::isfinite(original) || !std::isfinite(rounded)) { | 1457 if (!std::isfinite(original) || !std::isfinite(rounded)) { |
1450 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1458 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1451 ret = true; | 1459 ret = true; |
1452 } | 1460 } |
1453 | 1461 |
1454 if (original != rounded) { | 1462 if (original != rounded) { |
1455 set_fcsr_bit(kFCSRInexactFlagBit, true); | 1463 set_fcsr_bit(kFCSRInexactFlagBit, true); |
1456 } | 1464 } |
1457 | 1465 |
1458 if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) { | 1466 if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) { |
1459 set_fcsr_bit(kFCSRUnderflowFlagBit, true); | 1467 set_fcsr_bit(kFCSRUnderflowFlagBit, true); |
1460 ret = true; | 1468 ret = true; |
1461 } | 1469 } |
1462 | 1470 |
1463 if (rounded > max_int64 || rounded < min_int64) { | 1471 if (rounded >= max_int64 || rounded < min_int64) { |
1464 set_fcsr_bit(kFCSROverflowFlagBit, true); | 1472 set_fcsr_bit(kFCSROverflowFlagBit, true); |
1465 // The reference is not really clear but it seems this is required: | 1473 // The reference is not really clear but it seems this is required: |
1466 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1474 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1467 ret = true; | 1475 ret = true; |
1468 } | 1476 } |
1469 | 1477 |
1470 return ret; | 1478 return ret; |
1471 } | 1479 } |
1472 | 1480 |
1473 | 1481 |
(...skipping 3258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4732 } | 4740 } |
4733 | 4741 |
4734 | 4742 |
4735 #undef UNSUPPORTED | 4743 #undef UNSUPPORTED |
4736 } // namespace internal | 4744 } // namespace internal |
4737 } // namespace v8 | 4745 } // namespace v8 |
4738 | 4746 |
4739 #endif // USE_SIMULATOR | 4747 #endif // USE_SIMULATOR |
4740 | 4748 |
4741 #endif // V8_TARGET_ARCH_MIPS64 | 4749 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |