OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2579 Register input = ToRegister(instr->InputAt(0)); | 2579 Register input = ToRegister(instr->InputAt(0)); |
2580 // Smi check. | 2580 // Smi check. |
2581 __ JumpIfNotSmi(input, deferred->entry()); | 2581 __ JumpIfNotSmi(input, deferred->entry()); |
2582 // If smi, handle it directly. | 2582 // If smi, handle it directly. |
2583 EmitIntegerMathAbs(instr); | 2583 EmitIntegerMathAbs(instr); |
2584 __ bind(deferred->exit()); | 2584 __ bind(deferred->exit()); |
2585 } | 2585 } |
2586 } | 2586 } |
2587 | 2587 |
2588 | 2588 |
2589 // Truncates a double using a specific rounding mode. | |
2590 // Clears the z flag (ne condition) if an overflow occurs. | |
2591 void LCodeGen::EmitVFPTruncate(VFPRoundingMode rounding_mode, | |
2592 SwVfpRegister result, | |
2593 DwVfpRegister double_input, | |
2594 Register scratch1, | |
2595 Register scratch2) { | |
2596 Register prev_fpscr = scratch1; | |
2597 Register scratch = scratch2; | |
2598 | |
2599 // Set custom FPCSR: | |
2600 // - Set rounding mode. | |
2601 // - Clear vfp cumulative exception flags. | |
2602 // - Make sure Flush-to-zero mode control bit is unset. | |
2603 __ vmrs(prev_fpscr); | |
2604 __ bic(scratch, prev_fpscr, Operand(kVFPExceptionMask | | |
2605 kVFPRoundingModeMask | | |
2606 kVFPFlushToZeroMask)); | |
2607 __ orr(scratch, scratch, Operand(rounding_mode)); | |
2608 __ vmsr(scratch); | |
2609 | |
2610 // Convert the argument to an integer. | |
2611 __ vcvt_s32_f64(result, | |
2612 double_input, | |
2613 kFPSCRRounding); | |
2614 | |
2615 // Retrieve FPSCR. | |
2616 __ vmrs(scratch); | |
2617 // Restore FPSCR. | |
2618 __ vmsr(prev_fpscr); | |
2619 // Check for vfp exceptions. | |
2620 __ tst(scratch, Operand(kVFPExceptionMask)); | |
2621 } | |
2622 | |
2623 | |
2624 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 2589 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
2625 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); | 2590 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); |
2626 Register result = ToRegister(instr->result()); | 2591 Register result = ToRegister(instr->result()); |
2627 SwVfpRegister single_scratch = double_scratch0().low(); | 2592 SwVfpRegister single_scratch = double_scratch0().low(); |
2628 Register scratch1 = scratch0(); | 2593 Register scratch1 = scratch0(); |
2629 Register scratch2 = ToRegister(instr->TempAt(0)); | 2594 Register scratch2 = ToRegister(instr->TempAt(0)); |
2630 | 2595 |
2631 EmitVFPTruncate(kRoundToMinusInf, | 2596 __ EmitVFPTruncate(kRoundToMinusInf, |
2632 single_scratch, | 2597 single_scratch, |
2633 input, | 2598 input, |
2634 scratch1, | 2599 scratch1, |
2635 scratch2); | 2600 scratch2); |
2636 DeoptimizeIf(ne, instr->environment()); | 2601 DeoptimizeIf(ne, instr->environment()); |
2637 | 2602 |
2638 // Move the result back to general purpose register r0. | 2603 // Move the result back to general purpose register r0. |
2639 __ vmov(result, single_scratch); | 2604 __ vmov(result, single_scratch); |
2640 | 2605 |
2641 // Test for -0. | 2606 // Test for -0. |
2642 Label done; | 2607 Label done; |
2643 __ cmp(result, Operand(0)); | 2608 __ cmp(result, Operand(0)); |
2644 __ b(ne, &done); | 2609 __ b(ne, &done); |
2645 __ vmov(scratch1, input.high()); | 2610 __ vmov(scratch1, input.high()); |
2646 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | 2611 __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
2647 DeoptimizeIf(ne, instr->environment()); | 2612 DeoptimizeIf(ne, instr->environment()); |
2648 __ bind(&done); | 2613 __ bind(&done); |
2649 } | 2614 } |
2650 | 2615 |
2651 | 2616 |
2652 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 2617 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
2653 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); | 2618 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); |
2654 Register result = ToRegister(instr->result()); | 2619 Register result = ToRegister(instr->result()); |
2655 Register scratch1 = scratch0(); | 2620 Register scratch1 = scratch0(); |
2656 Register scratch2 = result; | 2621 Register scratch2 = result; |
2657 EmitVFPTruncate(kRoundToNearest, | 2622 __ EmitVFPTruncate(kRoundToNearest, |
2658 double_scratch0().low(), | 2623 double_scratch0().low(), |
2659 input, | 2624 input, |
2660 scratch1, | 2625 scratch1, |
2661 scratch2); | 2626 scratch2); |
2662 DeoptimizeIf(ne, instr->environment()); | 2627 DeoptimizeIf(ne, instr->environment()); |
2663 __ vmov(result, double_scratch0().low()); | 2628 __ vmov(result, double_scratch0().low()); |
2664 | 2629 |
2665 // Test for -0. | 2630 // Test for -0. |
2666 Label done; | 2631 Label done; |
2667 __ cmp(result, Operand(0)); | 2632 __ cmp(result, Operand(0)); |
2668 __ b(ne, &done); | 2633 __ b(ne, &done); |
2669 __ vmov(scratch1, input.high()); | 2634 __ vmov(scratch1, input.high()); |
2670 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | 2635 __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
2671 DeoptimizeIf(ne, instr->environment()); | 2636 DeoptimizeIf(ne, instr->environment()); |
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3364 ASSERT(input->IsDoubleRegister()); | 3329 ASSERT(input->IsDoubleRegister()); |
3365 LOperand* result = instr->result(); | 3330 LOperand* result = instr->result(); |
3366 ASSERT(result->IsRegister()); | 3331 ASSERT(result->IsRegister()); |
3367 | 3332 |
3368 DoubleRegister double_input = ToDoubleRegister(input); | 3333 DoubleRegister double_input = ToDoubleRegister(input); |
3369 Register result_reg = ToRegister(result); | 3334 Register result_reg = ToRegister(result); |
3370 SwVfpRegister single_scratch = double_scratch0().low(); | 3335 SwVfpRegister single_scratch = double_scratch0().low(); |
3371 Register scratch1 = scratch0(); | 3336 Register scratch1 = scratch0(); |
3372 Register scratch2 = ToRegister(instr->TempAt(0)); | 3337 Register scratch2 = ToRegister(instr->TempAt(0)); |
3373 | 3338 |
3374 EmitVFPTruncate(kRoundToZero, | 3339 VFPRoundingMode rounding_mode = instr->truncating() ? kRoundToZero |
3375 single_scratch, | 3340 : kRoundToMinusInf; |
3376 double_input, | 3341 |
3377 scratch1, | 3342 __ EmitVFPTruncate(rounding_mode, |
Søren Thygesen Gjesse
2011/02/28 09:54:32
r6951 changed this to always use kRoundToZero. Is
Søren Thygesen Gjesse
2011/03/02 09:33:08
Changed to always use kRoundToZero.
Use of inexac
| |
3378 scratch2); | 3343 single_scratch, |
3344 double_input, | |
3345 scratch1, | |
3346 scratch2); | |
3347 | |
3379 // Deoptimize if we had a vfp invalid exception. | 3348 // Deoptimize if we had a vfp invalid exception. |
3380 DeoptimizeIf(ne, instr->environment()); | 3349 DeoptimizeIf(ne, instr->environment()); |
3381 | 3350 |
3382 // Retrieve the result. | 3351 // Retrieve the result. |
3383 __ vmov(result_reg, single_scratch); | 3352 __ vmov(result_reg, single_scratch); |
3384 | 3353 |
3385 if (!instr->truncating()) { | 3354 if (!instr->truncating()) { |
3386 // Convert result back to double and compare with input | 3355 // Convert result back to double and compare with input |
3387 // to check if the conversion was exact. | 3356 // to check if the conversion was exact. |
3388 __ vmov(single_scratch, result_reg); | 3357 __ vmov(single_scratch, result_reg); |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3848 ASSERT(!environment->HasBeenRegistered()); | 3817 ASSERT(!environment->HasBeenRegistered()); |
3849 RegisterEnvironmentForDeoptimization(environment); | 3818 RegisterEnvironmentForDeoptimization(environment); |
3850 ASSERT(osr_pc_offset_ == -1); | 3819 ASSERT(osr_pc_offset_ == -1); |
3851 osr_pc_offset_ = masm()->pc_offset(); | 3820 osr_pc_offset_ = masm()->pc_offset(); |
3852 } | 3821 } |
3853 | 3822 |
3854 | 3823 |
3855 #undef __ | 3824 #undef __ |
3856 | 3825 |
3857 } } // namespace v8::internal | 3826 } } // namespace v8::internal |
OLD | NEW |