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 |