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 3159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3170 } | 3170 } |
3171 } else if (instr->Opc3Value() == 0x0) { | 3171 } else if (instr->Opc3Value() == 0x0) { |
3172 // vmov immediate. | 3172 // vmov immediate. |
3173 if (instr->SzValue() == 0x1) { | 3173 if (instr->SzValue() == 0x1) { |
3174 set_d_register_from_double(vd, instr->DoubleImmedVmov()); | 3174 set_d_register_from_double(vd, instr->DoubleImmedVmov()); |
3175 } else { | 3175 } else { |
3176 UNREACHABLE(); // Not used by v8. | 3176 UNREACHABLE(); // Not used by v8. |
3177 } | 3177 } |
3178 } else if (((instr->Opc2Value() == 0x6)) && (instr->Opc3Value() == 0x3)) { | 3178 } else if (((instr->Opc2Value() == 0x6)) && (instr->Opc3Value() == 0x3)) { |
3179 // vrintz - truncate | 3179 // vrintz - truncate |
3180 double dm_value = get_double_from_d_register(vm); | 3180 if (instr->SzValue() == 0x1) { |
3181 double dd_value = trunc(dm_value); | 3181 double dm_value = get_double_from_d_register(vm); |
3182 dd_value = canonicalizeNaN(dd_value); | 3182 double dd_value = trunc(dm_value); |
3183 set_d_register_from_double(vd, dd_value); | 3183 dd_value = canonicalizeNaN(dd_value); |
| 3184 set_d_register_from_double(vd, dd_value); |
| 3185 } else { |
| 3186 float sm_value = get_float_from_s_register(m); |
| 3187 float sd_value = truncf(sm_value); |
| 3188 sd_value = canonicalizeNaN(sd_value); |
| 3189 set_s_register_from_float(d, sd_value); |
| 3190 } |
3184 } else { | 3191 } else { |
3185 UNREACHABLE(); // Not used by V8. | 3192 UNREACHABLE(); // Not used by V8. |
3186 } | 3193 } |
3187 } else if (instr->Opc1Value() == 0x3) { | 3194 } else if (instr->Opc1Value() == 0x3) { |
3188 if (instr->Opc3Value() & 0x1) { | 3195 if (instr->Opc3Value() & 0x1) { |
3189 // vsub | 3196 // vsub |
3190 if (instr->SzValue() == 0x1) { | 3197 if (instr->SzValue() == 0x1) { |
3191 double dn_value = get_double_from_d_register(vn); | 3198 double dn_value = get_double_from_d_register(vn); |
3192 double dm_value = get_double_from_d_register(vm); | 3199 double dm_value = get_double_from_d_register(vm); |
3193 double dd_value = dn_value - dm_value; | 3200 double dd_value = dn_value - dm_value; |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3874 int vm = instr->VFPMRegValue(kDoublePrecision); | 3881 int vm = instr->VFPMRegValue(kDoublePrecision); |
3875 int vd = instr->VFPDRegValue(kDoublePrecision); | 3882 int vd = instr->VFPDRegValue(kDoublePrecision); |
3876 double dm_value = get_double_from_d_register(vm); | 3883 double dm_value = get_double_from_d_register(vm); |
3877 double dd_value = 0.0; | 3884 double dd_value = 0.0; |
3878 int rounding_mode = instr->Bits(17, 16); | 3885 int rounding_mode = instr->Bits(17, 16); |
3879 switch (rounding_mode) { | 3886 switch (rounding_mode) { |
3880 case 0x0: // vrinta - round with ties to away from zero | 3887 case 0x0: // vrinta - round with ties to away from zero |
3881 dd_value = round(dm_value); | 3888 dd_value = round(dm_value); |
3882 break; | 3889 break; |
3883 case 0x1: { // vrintn - round with ties to even | 3890 case 0x1: { // vrintn - round with ties to even |
3884 dd_value = std::floor(dm_value); | 3891 dd_value = nearbyint(dm_value); |
3885 double error = dm_value - dd_value; | |
3886 // Take care of correctly handling the range [-0.5, -0.0], which | |
3887 // must yield -0.0. | |
3888 if ((-0.5 <= dm_value) && (dm_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 | |
3891 // integer result is odd, round up. | |
3892 } else if ((error > 0.5) || | |
3893 ((error == 0.5) && (fmod(dd_value, 2) != 0))) { | |
3894 dd_value++; | |
3895 } | |
3896 break; | 3892 break; |
3897 } | 3893 } |
3898 case 0x2: // vrintp - ceil | 3894 case 0x2: // vrintp - ceil |
3899 dd_value = std::ceil(dm_value); | 3895 dd_value = ceil(dm_value); |
3900 break; | 3896 break; |
3901 case 0x3: // vrintm - floor | 3897 case 0x3: // vrintm - floor |
3902 dd_value = std::floor(dm_value); | 3898 dd_value = floor(dm_value); |
3903 break; | 3899 break; |
3904 default: | 3900 default: |
3905 UNREACHABLE(); // Case analysis is exhaustive. | 3901 UNREACHABLE(); // Case analysis is exhaustive. |
3906 break; | 3902 break; |
3907 } | 3903 } |
3908 dd_value = canonicalizeNaN(dd_value); | 3904 dd_value = canonicalizeNaN(dd_value); |
3909 set_d_register_from_double(vd, dd_value); | 3905 set_d_register_from_double(vd, dd_value); |
3910 } else { | 3906 } else { |
3911 int m = instr->VFPMRegValue(kSinglePrecision); | 3907 int m = instr->VFPMRegValue(kSinglePrecision); |
3912 int d = instr->VFPDRegValue(kSinglePrecision); | 3908 int d = instr->VFPDRegValue(kSinglePrecision); |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4185 set_register(sp, current_sp + sizeof(uintptr_t)); | 4181 set_register(sp, current_sp + sizeof(uintptr_t)); |
4186 return address; | 4182 return address; |
4187 } | 4183 } |
4188 | 4184 |
4189 } // namespace internal | 4185 } // namespace internal |
4190 } // namespace v8 | 4186 } // namespace v8 |
4191 | 4187 |
4192 #endif // USE_SIMULATOR | 4188 #endif // USE_SIMULATOR |
4193 | 4189 |
4194 #endif // V8_TARGET_ARCH_ARM | 4190 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |