Chromium Code Reviews| 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 |