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 #if V8_TARGET_ARCH_ARM | 9 #if V8_TARGET_ARCH_ARM |
10 | 10 |
(...skipping 3851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3862 case 0xA: | 3862 case 0xA: |
3863 case 0xB: | 3863 case 0xB: |
3864 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) { | 3864 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) { |
3865 // pld: ignore instruction. | 3865 // pld: ignore instruction. |
3866 } else { | 3866 } else { |
3867 UNIMPLEMENTED(); | 3867 UNIMPLEMENTED(); |
3868 } | 3868 } |
3869 break; | 3869 break; |
3870 case 0x1D: | 3870 case 0x1D: |
3871 if (instr->Opc1Value() == 0x7 && instr->Opc3Value() == 0x1 && | 3871 if (instr->Opc1Value() == 0x7 && instr->Opc3Value() == 0x1 && |
3872 instr->Bits(11, 9) == 0x5 && instr->Bits(19, 18) == 0x2 && | 3872 instr->Bits(11, 9) == 0x5 && instr->Bits(19, 18) == 0x2) { |
3873 instr->Bit(8) == 0x1) { | 3873 if (instr->SzValue() == 0x1) { |
3874 int vm = instr->VFPMRegValue(kDoublePrecision); | 3874 int vm = instr->VFPMRegValue(kDoublePrecision); |
3875 int vd = instr->VFPDRegValue(kDoublePrecision); | 3875 int vd = instr->VFPDRegValue(kDoublePrecision); |
3876 double dm_value = get_double_from_d_register(vm); | 3876 double dm_value = get_double_from_d_register(vm); |
3877 double dd_value = 0.0; | 3877 double dd_value = 0.0; |
3878 int rounding_mode = instr->Bits(17, 16); | 3878 int rounding_mode = instr->Bits(17, 16); |
3879 switch (rounding_mode) { | 3879 switch (rounding_mode) { |
3880 case 0x0: // vrinta - round with ties to away from zero | 3880 case 0x0: // vrinta - round with ties to away from zero |
3881 dd_value = round(dm_value); | 3881 dd_value = round(dm_value); |
3882 break; | 3882 break; |
3883 case 0x1: { // vrintn - round with ties to even | 3883 case 0x1: { // vrintn - round with ties to even |
3884 dd_value = std::floor(dm_value); | 3884 dd_value = std::floor(dm_value); |
3885 double error = dm_value - dd_value; | 3885 double error = dm_value - dd_value; |
3886 // Take care of correctly handling the range [-0.5, -0.0], which | 3886 // Take care of correctly handling the range [-0.5, -0.0], which |
3887 // must yield -0.0. | 3887 // must yield -0.0. |
3888 if ((-0.5 <= dm_value) && (dm_value < 0.0)) { | 3888 if ((-0.5 <= dm_value) && (dm_value < 0.0)) { |
3889 dd_value = -0.0; | 3889 dd_value = -0.0; |
3890 // If the error is greater than 0.5, or is equal to 0.5 and the | 3890 // If the error is greater than 0.5, or is equal to 0.5 and the |
3891 // integer result is odd, round up. | 3891 // integer result is odd, round up. |
3892 } else if ((error > 0.5) || | 3892 } else if ((error > 0.5) || |
3893 ((error == 0.5) && (fmod(dd_value, 2) != 0))) { | 3893 ((error == 0.5) && (fmod(dd_value, 2) != 0))) { |
3894 dd_value++; | 3894 dd_value++; |
3895 } | |
3896 break; | |
3895 } | 3897 } |
3896 break; | 3898 case 0x2: // vrintp - ceil |
3899 dd_value = std::ceil(dm_value); | |
3900 break; | |
3901 case 0x3: // vrintm - floor | |
3902 dd_value = std::floor(dm_value); | |
3903 break; | |
3904 default: | |
3905 UNREACHABLE(); // Case analysis is exhaustive. | |
3906 break; | |
3897 } | 3907 } |
3898 case 0x2: // vrintp - ceil | 3908 dd_value = canonicalizeNaN(dd_value); |
3899 dd_value = std::ceil(dm_value); | 3909 set_d_register_from_double(vd, dd_value); |
3900 break; | 3910 } else { |
3901 case 0x3: // vrintm - floor | 3911 int m = instr->VFPMRegValue(kSinglePrecision); |
3902 dd_value = std::floor(dm_value); | 3912 int d = instr->VFPDRegValue(kSinglePrecision); |
3903 break; | 3913 float sm_value = get_float_from_s_register(m); |
3904 default: | 3914 float sd_value = 0.0; |
3905 UNREACHABLE(); // Case analysis is exhaustive. | 3915 int rounding_mode = instr->Bits(17, 16); |
3906 break; | 3916 switch (rounding_mode) { |
3917 case 0x0: // vrinta - round with ties to away from zero | |
3918 sd_value = roundf(sm_value); | |
3919 break; | |
3920 case 0x1: { // vrintn - round with ties to even | |
3921 sd_value = nearbyintf(sm_value); | |
3922 break; | |
3923 } | |
3924 case 0x2: // vrintp - ceil | |
3925 sd_value = ceilf(sm_value); | |
jbramley
2015/11/25 10:46:16
Why not std::ceil? (Ditto for the other Float32 op
| |
3926 break; | |
3927 case 0x3: // vrintm - floor | |
3928 sd_value = floorf(sm_value); | |
3929 break; | |
3930 default: | |
3931 UNREACHABLE(); // Case analysis is exhaustive. | |
3932 break; | |
3933 } | |
3934 sd_value = canonicalizeNaN(sd_value); | |
3935 set_s_register_from_float(d, sd_value); | |
3907 } | 3936 } |
3908 dd_value = canonicalizeNaN(dd_value); | |
3909 set_d_register_from_double(vd, dd_value); | |
3910 } else { | 3937 } else { |
3911 UNIMPLEMENTED(); | 3938 UNIMPLEMENTED(); |
3912 } | 3939 } |
3913 break; | 3940 break; |
3914 default: | 3941 default: |
3915 UNIMPLEMENTED(); | 3942 UNIMPLEMENTED(); |
3916 break; | 3943 break; |
3917 } | 3944 } |
3918 } | 3945 } |
3919 | 3946 |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4158 set_register(sp, current_sp + sizeof(uintptr_t)); | 4185 set_register(sp, current_sp + sizeof(uintptr_t)); |
4159 return address; | 4186 return address; |
4160 } | 4187 } |
4161 | 4188 |
4162 } // namespace internal | 4189 } // namespace internal |
4163 } // namespace v8 | 4190 } // namespace v8 |
4164 | 4191 |
4165 #endif // USE_SIMULATOR | 4192 #endif // USE_SIMULATOR |
4166 | 4193 |
4167 #endif // V8_TARGET_ARCH_ARM | 4194 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |