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_MIPS | 10 #if V8_TARGET_ARCH_MIPS |
(...skipping 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1336 } | 1336 } |
1337 } else { | 1337 } else { |
1338 set_fpu_register(fd_reg(), kFPUInvalidResult); | 1338 set_fpu_register(fd_reg(), kFPUInvalidResult); |
1339 } | 1339 } |
1340 } | 1340 } |
1341 | 1341 |
1342 | 1342 |
1343 void Simulator::set_fpu_register_invalid_result64(float original, | 1343 void Simulator::set_fpu_register_invalid_result64(float original, |
1344 float rounded) { | 1344 float rounded) { |
1345 if (FCSR_ & kFCSRNaN2008FlagMask) { | 1345 if (FCSR_ & kFCSRNaN2008FlagMask) { |
| 1346 // The value of INT64_MAX (2^63-1) can't be represented as double exactly, |
| 1347 // loading the most accurate representation into max_int64, which is 2^63. |
1346 double max_int64 = std::numeric_limits<int64_t>::max(); | 1348 double max_int64 = std::numeric_limits<int64_t>::max(); |
1347 double min_int64 = std::numeric_limits<int64_t>::min(); | 1349 double min_int64 = std::numeric_limits<int64_t>::min(); |
1348 if (std::isnan(original)) { | 1350 if (std::isnan(original)) { |
1349 set_fpu_register(fd_reg(), 0); | 1351 set_fpu_register(fd_reg(), 0); |
1350 } else if (rounded > max_int64) { | 1352 } else if (rounded >= max_int64) { |
1351 set_fpu_register(fd_reg(), kFPU64InvalidResult); | 1353 set_fpu_register(fd_reg(), kFPU64InvalidResult); |
1352 } else if (rounded < min_int64) { | 1354 } else if (rounded < min_int64) { |
1353 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative); | 1355 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative); |
1354 } else { | 1356 } else { |
1355 UNREACHABLE(); | 1357 UNREACHABLE(); |
1356 } | 1358 } |
1357 } else { | 1359 } else { |
1358 set_fpu_register(fd_reg(), kFPU64InvalidResult); | 1360 set_fpu_register(fd_reg(), kFPU64InvalidResult); |
1359 } | 1361 } |
1360 } | 1362 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 } | 1398 } |
1397 } else { | 1399 } else { |
1398 set_fpu_register(fd_reg(), kFPUInvalidResult); | 1400 set_fpu_register(fd_reg(), kFPUInvalidResult); |
1399 } | 1401 } |
1400 } | 1402 } |
1401 | 1403 |
1402 | 1404 |
1403 void Simulator::set_fpu_register_invalid_result64(double original, | 1405 void Simulator::set_fpu_register_invalid_result64(double original, |
1404 double rounded) { | 1406 double rounded) { |
1405 if (FCSR_ & kFCSRNaN2008FlagMask) { | 1407 if (FCSR_ & kFCSRNaN2008FlagMask) { |
| 1408 // The value of INT64_MAX (2^63-1) can't be represented as double exactly, |
| 1409 // loading the most accurate representation into max_int64, which is 2^63. |
1406 double max_int64 = std::numeric_limits<int64_t>::max(); | 1410 double max_int64 = std::numeric_limits<int64_t>::max(); |
1407 double min_int64 = std::numeric_limits<int64_t>::min(); | 1411 double min_int64 = std::numeric_limits<int64_t>::min(); |
1408 if (std::isnan(original)) { | 1412 if (std::isnan(original)) { |
1409 set_fpu_register(fd_reg(), 0); | 1413 set_fpu_register(fd_reg(), 0); |
1410 } else if (rounded > max_int64) { | 1414 } else if (rounded >= max_int64) { |
1411 set_fpu_register(fd_reg(), kFPU64InvalidResult); | 1415 set_fpu_register(fd_reg(), kFPU64InvalidResult); |
1412 } else if (rounded < min_int64) { | 1416 } else if (rounded < min_int64) { |
1413 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative); | 1417 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative); |
1414 } else { | 1418 } else { |
1415 UNREACHABLE(); | 1419 UNREACHABLE(); |
1416 } | 1420 } |
1417 } else { | 1421 } else { |
1418 set_fpu_register(fd_reg(), kFPU64InvalidResult); | 1422 set_fpu_register(fd_reg(), kFPU64InvalidResult); |
1419 } | 1423 } |
1420 } | 1424 } |
(...skipping 28 matching lines...) Expand all Loading... |
1449 } | 1453 } |
1450 | 1454 |
1451 return ret; | 1455 return ret; |
1452 } | 1456 } |
1453 | 1457 |
1454 | 1458 |
1455 // Sets the rounding error codes in FCSR based on the result of the rounding. | 1459 // Sets the rounding error codes in FCSR based on the result of the rounding. |
1456 // Returns true if the operation was invalid. | 1460 // Returns true if the operation was invalid. |
1457 bool Simulator::set_fcsr_round64_error(double original, double rounded) { | 1461 bool Simulator::set_fcsr_round64_error(double original, double rounded) { |
1458 bool ret = false; | 1462 bool ret = false; |
| 1463 // The value of INT64_MAX (2^63-1) can't be represented as double exactly, |
| 1464 // loading the most accurate representation into max_int64, which is 2^63. |
1459 double max_int64 = std::numeric_limits<int64_t>::max(); | 1465 double max_int64 = std::numeric_limits<int64_t>::max(); |
1460 double min_int64 = std::numeric_limits<int64_t>::min(); | 1466 double min_int64 = std::numeric_limits<int64_t>::min(); |
1461 | 1467 |
1462 if (!std::isfinite(original) || !std::isfinite(rounded)) { | 1468 if (!std::isfinite(original) || !std::isfinite(rounded)) { |
1463 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1469 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1464 ret = true; | 1470 ret = true; |
1465 } | 1471 } |
1466 | 1472 |
1467 if (original != rounded) { | 1473 if (original != rounded) { |
1468 set_fcsr_bit(kFCSRInexactFlagBit, true); | 1474 set_fcsr_bit(kFCSRInexactFlagBit, true); |
1469 } | 1475 } |
1470 | 1476 |
1471 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) { | 1477 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) { |
1472 set_fcsr_bit(kFCSRUnderflowFlagBit, true); | 1478 set_fcsr_bit(kFCSRUnderflowFlagBit, true); |
1473 ret = true; | 1479 ret = true; |
1474 } | 1480 } |
1475 | 1481 |
1476 if (rounded > max_int64 || rounded < min_int64) { | 1482 if (rounded >= max_int64 || rounded < min_int64) { |
1477 set_fcsr_bit(kFCSROverflowFlagBit, true); | 1483 set_fcsr_bit(kFCSROverflowFlagBit, true); |
1478 // The reference is not really clear but it seems this is required: | 1484 // The reference is not really clear but it seems this is required: |
1479 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1485 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1480 ret = true; | 1486 ret = true; |
1481 } | 1487 } |
1482 | 1488 |
1483 return ret; | 1489 return ret; |
1484 } | 1490 } |
1485 | 1491 |
1486 | 1492 |
(...skipping 26 matching lines...) Expand all Loading... |
1513 } | 1519 } |
1514 | 1520 |
1515 return ret; | 1521 return ret; |
1516 } | 1522 } |
1517 | 1523 |
1518 | 1524 |
1519 // Sets the rounding error codes in FCSR based on the result of the rounding. | 1525 // Sets the rounding error codes in FCSR based on the result of the rounding. |
1520 // Returns true if the operation was invalid. | 1526 // Returns true if the operation was invalid. |
1521 bool Simulator::set_fcsr_round64_error(float original, float rounded) { | 1527 bool Simulator::set_fcsr_round64_error(float original, float rounded) { |
1522 bool ret = false; | 1528 bool ret = false; |
| 1529 // The value of INT64_MAX (2^63-1) can't be represented as double exactly, |
| 1530 // loading the most accurate representation into max_int64, which is 2^63. |
1523 double max_int64 = std::numeric_limits<int64_t>::max(); | 1531 double max_int64 = std::numeric_limits<int64_t>::max(); |
1524 double min_int64 = std::numeric_limits<int64_t>::min(); | 1532 double min_int64 = std::numeric_limits<int64_t>::min(); |
1525 | 1533 |
1526 if (!std::isfinite(original) || !std::isfinite(rounded)) { | 1534 if (!std::isfinite(original) || !std::isfinite(rounded)) { |
1527 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1535 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1528 ret = true; | 1536 ret = true; |
1529 } | 1537 } |
1530 | 1538 |
1531 if (original != rounded) { | 1539 if (original != rounded) { |
1532 set_fcsr_bit(kFCSRInexactFlagBit, true); | 1540 set_fcsr_bit(kFCSRInexactFlagBit, true); |
1533 } | 1541 } |
1534 | 1542 |
1535 if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) { | 1543 if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) { |
1536 set_fcsr_bit(kFCSRUnderflowFlagBit, true); | 1544 set_fcsr_bit(kFCSRUnderflowFlagBit, true); |
1537 ret = true; | 1545 ret = true; |
1538 } | 1546 } |
1539 | 1547 |
1540 if (rounded > max_int64 || rounded < min_int64) { | 1548 if (rounded >= max_int64 || rounded < min_int64) { |
1541 set_fcsr_bit(kFCSROverflowFlagBit, true); | 1549 set_fcsr_bit(kFCSROverflowFlagBit, true); |
1542 // The reference is not really clear but it seems this is required: | 1550 // The reference is not really clear but it seems this is required: |
1543 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1551 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1544 ret = true; | 1552 ret = true; |
1545 } | 1553 } |
1546 | 1554 |
1547 return ret; | 1555 return ret; |
1548 } | 1556 } |
1549 | 1557 |
1550 | 1558 |
(...skipping 3022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4573 | 4581 |
4574 | 4582 |
4575 #undef UNSUPPORTED | 4583 #undef UNSUPPORTED |
4576 | 4584 |
4577 } // namespace internal | 4585 } // namespace internal |
4578 } // namespace v8 | 4586 } // namespace v8 |
4579 | 4587 |
4580 #endif // USE_SIMULATOR | 4588 #endif // USE_SIMULATOR |
4581 | 4589 |
4582 #endif // V8_TARGET_ARCH_MIPS | 4590 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |