Chromium Code Reviews| 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 2939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2950 double dd_value = std::sqrt(dm_value); | 2950 double dd_value = std::sqrt(dm_value); |
| 2951 dd_value = canonicalizeNaN(dd_value); | 2951 dd_value = canonicalizeNaN(dd_value); |
| 2952 set_d_register_from_double(vd, dd_value); | 2952 set_d_register_from_double(vd, dd_value); |
| 2953 } else if (instr->Opc3Value() == 0x0) { | 2953 } else if (instr->Opc3Value() == 0x0) { |
| 2954 // vmov immediate. | 2954 // vmov immediate. |
| 2955 if (instr->SzValue() == 0x1) { | 2955 if (instr->SzValue() == 0x1) { |
| 2956 set_d_register_from_double(vd, instr->DoubleImmedVmov()); | 2956 set_d_register_from_double(vd, instr->DoubleImmedVmov()); |
| 2957 } else { | 2957 } else { |
| 2958 UNREACHABLE(); // Not used by v8. | 2958 UNREACHABLE(); // Not used by v8. |
| 2959 } | 2959 } |
| 2960 } else if (((instr->Opc2Value() == 0x6)) && (instr->Opc3Value() == 0x3)) { | |
| 2961 // vrintz - truncate | |
| 2962 double dm_value = get_double_from_d_register(vm); | |
| 2963 double dd_value = std::trunc(dm_value); | |
| 2964 dd_value = canonicalizeNaN(dd_value); | |
| 2965 set_d_register_from_double(vd, dd_value); | |
| 2960 } else { | 2966 } else { |
| 2961 UNREACHABLE(); // Not used by V8. | 2967 UNREACHABLE(); // Not used by V8. |
| 2962 } | 2968 } |
| 2963 } else if (instr->Opc1Value() == 0x3) { | 2969 } else if (instr->Opc1Value() == 0x3) { |
| 2964 if (instr->SzValue() != 0x1) { | 2970 if (instr->SzValue() != 0x1) { |
| 2965 UNREACHABLE(); // Not used by V8. | 2971 UNREACHABLE(); // Not used by V8. |
| 2966 } | 2972 } |
| 2967 | 2973 |
| 2968 if (instr->Opc3Value() & 0x1) { | 2974 if (instr->Opc3Value() & 0x1) { |
| 2969 // vsub | 2975 // vsub |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3600 } | 3606 } |
| 3601 break; | 3607 break; |
| 3602 case 0xA: | 3608 case 0xA: |
| 3603 case 0xB: | 3609 case 0xB: |
| 3604 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) { | 3610 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) { |
| 3605 // pld: ignore instruction. | 3611 // pld: ignore instruction. |
| 3606 } else { | 3612 } else { |
| 3607 UNIMPLEMENTED(); | 3613 UNIMPLEMENTED(); |
| 3608 } | 3614 } |
| 3609 break; | 3615 break; |
| 3616 case 0x1D: | |
| 3617 if (instr->Opc1Value() == 0x7 && instr->Opc3Value() == 0x1 && | |
| 3618 instr->Bits(11, 9) == 0x5 && instr->Bits(19, 18) == 0x2 && | |
| 3619 instr->Bit(8) == 0x1) { | |
| 3620 int vm = instr->VFPMRegValue(kDoublePrecision); | |
| 3621 int vd = instr->VFPDRegValue(kDoublePrecision); | |
| 3622 double dm_value = get_double_from_d_register(vm); | |
| 3623 double dd_value = 0.0; | |
| 3624 int rounding_mode = instr->Bits(17, 16); | |
| 3625 switch (rounding_mode) { | |
| 3626 case 0x0: // vrinta - round with ties to away from zero | |
| 3627 dd_value = std::round(dm_value); | |
|
Torne
2014/11/04 16:28:55
The calls to std::round and std::trunc added here
Sven Panne
2014/11/05 08:05:00
Yes, we follow this policy, and normally this kind
| |
| 3628 break; | |
| 3629 case 0x1: { // vrintn - round with ties to even | |
| 3630 dd_value = std::floor(dm_value); | |
| 3631 double error = dm_value - dd_value; | |
| 3632 // Take care of correctly handling the range [-0.5, -0.0], which | |
| 3633 // must yield -0.0. | |
| 3634 if ((-0.5 <= dm_value) && (dm_value < 0.0)) { | |
| 3635 dd_value = -0.0; | |
| 3636 // If the error is greater than 0.5, or is equal to 0.5 and the | |
| 3637 // integer result is odd, round up. | |
| 3638 } else if ((error > 0.5) || | |
| 3639 ((error == 0.5) && (fmod(dd_value, 2) != 0))) { | |
| 3640 dd_value++; | |
| 3641 } | |
| 3642 break; | |
| 3643 } | |
| 3644 case 0x2: // vrintp - ceil | |
| 3645 dd_value = std::ceil(dm_value); | |
| 3646 break; | |
| 3647 case 0x3: // vrintm - floor | |
| 3648 dd_value = std::floor(dm_value); | |
| 3649 break; | |
| 3650 default: | |
| 3651 UNREACHABLE(); // Case analysis is exhaustive. | |
| 3652 break; | |
| 3653 } | |
| 3654 dd_value = canonicalizeNaN(dd_value); | |
| 3655 set_d_register_from_double(vd, dd_value); | |
| 3656 } else { | |
| 3657 UNIMPLEMENTED(); | |
| 3658 } | |
| 3659 break; | |
| 3610 default: | 3660 default: |
| 3611 UNIMPLEMENTED(); | 3661 UNIMPLEMENTED(); |
| 3612 break; | 3662 break; |
| 3613 } | 3663 } |
| 3614 } | 3664 } |
| 3615 | 3665 |
| 3616 | 3666 |
| 3617 // Executes the current instruction. | 3667 // Executes the current instruction. |
| 3618 void Simulator::InstructionDecode(Instruction* instr) { | 3668 void Simulator::InstructionDecode(Instruction* instr) { |
| 3619 if (v8::internal::FLAG_check_icache) { | 3669 if (v8::internal::FLAG_check_icache) { |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3850 uintptr_t address = *stack_slot; | 3900 uintptr_t address = *stack_slot; |
| 3851 set_register(sp, current_sp + sizeof(uintptr_t)); | 3901 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 3852 return address; | 3902 return address; |
| 3853 } | 3903 } |
| 3854 | 3904 |
| 3855 } } // namespace v8::internal | 3905 } } // namespace v8::internal |
| 3856 | 3906 |
| 3857 #endif // USE_SIMULATOR | 3907 #endif // USE_SIMULATOR |
| 3858 | 3908 |
| 3859 #endif // V8_TARGET_ARCH_ARM | 3909 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |