| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 <stdarg.h> | 5 #include <stdarg.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 1903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1914 } | 1914 } |
| 1915 } | 1915 } |
| 1916 | 1916 |
| 1917 | 1917 |
| 1918 double Simulator::canonicalizeNaN(double value) { | 1918 double Simulator::canonicalizeNaN(double value) { |
| 1919 return (FPSCR_default_NaN_mode_ && std::isnan(value)) ? | 1919 return (FPSCR_default_NaN_mode_ && std::isnan(value)) ? |
| 1920 FixedDoubleArray::canonical_not_the_hole_nan_as_double() : value; | 1920 FixedDoubleArray::canonical_not_the_hole_nan_as_double() : value; |
| 1921 } | 1921 } |
| 1922 | 1922 |
| 1923 | 1923 |
| 1924 double Simulator::FPRoundInt(double value, VCVTRoundingMode rounding_mode) { |
| 1925 Double double_value(value); |
| 1926 if ((value == 0.0) || double_value.IsInfinite()) { |
| 1927 return value; |
| 1928 } else if (std::isnan(value)) { |
| 1929 return canonicalizeNaN(value); |
| 1930 } |
| 1931 |
| 1932 double int_result = floor(value); |
| 1933 double error = value - int_result; |
| 1934 switch (rounding_mode) { |
| 1935 case kVcvtTiesToAway: { |
| 1936 // Take care of correctly handling the range ]-0.5, -0.0], which must |
| 1937 // yield -0.0. |
| 1938 if ((-0.5 < value) && (value < 0.0)) { |
| 1939 int_result = -0.0; |
| 1940 |
| 1941 } else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) { |
| 1942 // If the error is greater than 0.5, or is equal to 0.5 and the integer |
| 1943 // result is positive, round up. |
| 1944 int_result++; |
| 1945 } |
| 1946 break; |
| 1947 } |
| 1948 case kVcvtTiesToEven: { |
| 1949 // Take care of correctly handling the range [-0.5, -0.0], which must |
| 1950 // yield -0.0. |
| 1951 if ((-0.5 <= value) && (value < 0.0)) { |
| 1952 int_result = -0.0; |
| 1953 |
| 1954 // If the error is greater than 0.5, or is equal to 0.5 and the integer |
| 1955 // result is odd, round up. |
| 1956 } else if ((error > 0.5) || |
| 1957 ((error == 0.5) && (fmod(int_result, 2) != 0))) { |
| 1958 int_result++; |
| 1959 } |
| 1960 break; |
| 1961 } |
| 1962 case kVcvtTowardPlusInfinity: { |
| 1963 int_result = -floor(-value); |
| 1964 break; |
| 1965 } |
| 1966 case kVcvtTowardMinusInfinity: { |
| 1967 // We always use floor(value). |
| 1968 break; |
| 1969 } |
| 1970 default: UNREACHABLE(); |
| 1971 } |
| 1972 return int_result; |
| 1973 } |
| 1974 |
| 1975 |
| 1976 int32_t Simulator::FPToInt32(double value, VCVTRoundingMode rounding_mode) { |
| 1977 value = FPRoundInt(value, rounding_mode); |
| 1978 if (value >= kMaxInt) { |
| 1979 return kMaxInt; |
| 1980 } else if (value < kMinInt) { |
| 1981 return kMinInt; |
| 1982 } |
| 1983 return std::isnan(value) ? 0 : static_cast<int32_t>(value); |
| 1984 } |
| 1985 |
| 1986 |
| 1987 uint32_t Simulator::FPToUInt32(double value, VCVTRoundingMode rounding_mode) { |
| 1988 value = FPRoundInt(value, rounding_mode); |
| 1989 if (value >= kMaxUInt32) { |
| 1990 return kMaxUInt32; |
| 1991 } else if (value < 0.0) { |
| 1992 return 0; |
| 1993 } |
| 1994 return std::isnan(value) ? 0 : static_cast<uint32_t>(value); |
| 1995 } |
| 1996 |
| 1997 |
| 1924 // Stop helper functions. | 1998 // Stop helper functions. |
| 1925 bool Simulator::isStopInstruction(Instruction* instr) { | 1999 bool Simulator::isStopInstruction(Instruction* instr) { |
| 1926 return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode); | 2000 return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode); |
| 1927 } | 2001 } |
| 1928 | 2002 |
| 1929 | 2003 |
| 1930 bool Simulator::isWatchedStop(uint32_t code) { | 2004 bool Simulator::isWatchedStop(uint32_t code) { |
| 1931 ASSERT(code <= kMaxStopCode); | 2005 ASSERT(code <= kMaxStopCode); |
| 1932 return code < kNumOfWatchedStops; | 2006 return code < kNumOfWatchedStops; |
| 1933 } | 2007 } |
| (...skipping 1645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3579 } | 3653 } |
| 3580 break; | 3654 break; |
| 3581 case 0xA: | 3655 case 0xA: |
| 3582 case 0xB: | 3656 case 0xB: |
| 3583 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) { | 3657 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) { |
| 3584 // pld: ignore instruction. | 3658 // pld: ignore instruction. |
| 3585 } else { | 3659 } else { |
| 3586 UNIMPLEMENTED(); | 3660 UNIMPLEMENTED(); |
| 3587 } | 3661 } |
| 3588 break; | 3662 break; |
| 3663 case 0x1D: |
| 3664 if ((instr->Bits(21, 18) == 0xF) && (instr->Bits(11, 9) == 5) && |
| 3665 (instr->Bit(6) == 1) && (instr->Bit(4) == 0)) { |
| 3666 // AArch32 vcvt instructions. |
| 3667 int size = instr->Bit(8); |
| 3668 int Vd = instr->VFPDRegValue(kSinglePrecision); |
| 3669 int Vm = instr->VFPMRegValue(static_cast<VFPRegPrecision>(size)); |
| 3670 VCVTRoundingMode rounding_mode = |
| 3671 static_cast<VCVTRoundingMode>(instr->Bits(17, 16)); |
| 3672 int data_type = instr->Bit(7); |
| 3673 double value; |
| 3674 if (size == 0) { |
| 3675 value = get_float_from_s_register(Vm); |
| 3676 } else { |
| 3677 value = get_double_from_d_register(Vm); |
| 3678 } |
| 3679 if (data_type == 0) { |
| 3680 uint32_t result = FPToUInt32(value, rounding_mode); |
| 3681 set_s_register_from_sinteger(Vd, result); |
| 3682 } else { |
| 3683 int32_t result = FPToInt32(value, rounding_mode); |
| 3684 set_s_register_from_sinteger(Vd, result); |
| 3685 } |
| 3686 } else { |
| 3687 UNIMPLEMENTED(); |
| 3688 } |
| 3689 break; |
| 3589 default: | 3690 default: |
| 3590 UNIMPLEMENTED(); | 3691 UNIMPLEMENTED(); |
| 3591 break; | 3692 break; |
| 3592 } | 3693 } |
| 3593 } | 3694 } |
| 3594 | 3695 |
| 3595 | 3696 |
| 3596 // Executes the current instruction. | 3697 // Executes the current instruction. |
| 3597 void Simulator::InstructionDecode(Instruction* instr) { | 3698 void Simulator::InstructionDecode(Instruction* instr) { |
| 3598 if (v8::internal::FLAG_check_icache) { | 3699 if (v8::internal::FLAG_check_icache) { |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3829 uintptr_t address = *stack_slot; | 3930 uintptr_t address = *stack_slot; |
| 3830 set_register(sp, current_sp + sizeof(uintptr_t)); | 3931 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 3831 return address; | 3932 return address; |
| 3832 } | 3933 } |
| 3833 | 3934 |
| 3834 } } // namespace v8::internal | 3935 } } // namespace v8::internal |
| 3835 | 3936 |
| 3836 #endif // USE_SIMULATOR | 3937 #endif // USE_SIMULATOR |
| 3837 | 3938 |
| 3838 #endif // V8_TARGET_ARCH_ARM | 3939 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |