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 2607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2618 Register input = ToRegister(instr->InputAt(0)); | 2618 Register input = ToRegister(instr->InputAt(0)); |
2619 // Smi check. | 2619 // Smi check. |
2620 __ JumpIfNotSmi(input, deferred->entry()); | 2620 __ JumpIfNotSmi(input, deferred->entry()); |
2621 // If smi, handle it directly. | 2621 // If smi, handle it directly. |
2622 EmitIntegerMathAbs(instr); | 2622 EmitIntegerMathAbs(instr); |
2623 __ bind(deferred->exit()); | 2623 __ bind(deferred->exit()); |
2624 } | 2624 } |
2625 } | 2625 } |
2626 | 2626 |
2627 | 2627 |
2628 // Truncates a double using a specific rounding mode. | |
2629 // Clears the z flag (ne condition) if an overflow occurs. | |
2630 void LCodeGen::EmitVFPTruncate(VFPRoundingMode rounding_mode, | |
2631 SwVfpRegister result, | |
2632 DwVfpRegister double_input, | |
2633 Register scratch1, | |
2634 Register scratch2) { | |
2635 Register prev_fpscr = scratch1; | |
2636 Register scratch = scratch2; | |
2637 | |
2638 // Set custom FPCSR: | |
2639 // - Set rounding mode. | |
2640 // - Clear vfp cumulative exception flags. | |
2641 // - Make sure Flush-to-zero mode control bit is unset. | |
2642 __ vmrs(prev_fpscr); | |
2643 __ bic(scratch, prev_fpscr, Operand(kVFPExceptionMask | | |
2644 kVFPRoundingModeMask | | |
2645 kVFPFlushToZeroMask)); | |
2646 __ orr(scratch, scratch, Operand(rounding_mode)); | |
2647 __ vmsr(scratch); | |
2648 | |
2649 // Convert the argument to an integer. | |
2650 __ vcvt_s32_f64(result, | |
2651 double_input, | |
2652 kFPSCRRounding); | |
2653 | |
2654 // Retrieve FPSCR. | |
2655 __ vmrs(scratch); | |
2656 // Restore FPSCR. | |
2657 __ vmsr(prev_fpscr); | |
2658 // Check for vfp exceptions. | |
2659 __ tst(scratch, Operand(kVFPExceptionMask)); | |
2660 } | |
2661 | |
2662 | |
2628 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 2663 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
2629 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); | 2664 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); |
2630 Register result = ToRegister(instr->result()); | 2665 Register result = ToRegister(instr->result()); |
2631 Register prev_fpscr = ToRegister(instr->TempAt(0)); | |
2632 SwVfpRegister single_scratch = double_scratch0().low(); | 2666 SwVfpRegister single_scratch = double_scratch0().low(); |
2633 Register scratch = scratch0(); | 2667 Register scratch1 = scratch0(); |
2668 Register scratch2 = ToRegister(instr->TempAt(0)); | |
2634 | 2669 |
2635 // Set custom FPCSR: | 2670 EmitVFPTruncate(kRoundToMinusInf, |
Søren Thygesen Gjesse
2011/02/03 09:07:17
To much indentation.
Rodolph Perfetta
2011/02/03 15:03:39
Done.
| |
2636 // - Set rounding mode to "Round towards Minus Infinity". | 2671 single_scratch, |
2637 // - Clear vfp cumulative exception flags. | 2672 input, |
2638 // - Make sure Flush-to-zero mode control bit is unset. | 2673 scratch1, |
2639 __ vmrs(prev_fpscr); | 2674 scratch2); |
2640 __ bic(scratch, prev_fpscr, | |
2641 Operand(kVFPExceptionMask | kVFPRoundingModeMask | kVFPFlushToZeroMask)); | |
2642 __ orr(scratch, scratch, Operand(kVFPRoundToMinusInfinityBits)); | |
2643 __ vmsr(scratch); | |
2644 | |
2645 // Convert the argument to an integer. | |
2646 __ vcvt_s32_f64(single_scratch, | |
2647 input, | |
2648 Assembler::FPSCRRounding, | |
2649 al); | |
2650 | |
2651 // Retrieve FPSCR and check for vfp exceptions. | |
2652 __ vmrs(scratch); | |
2653 // Restore FPSCR | |
2654 __ vmsr(prev_fpscr); | |
2655 __ tst(scratch, Operand(kVFPExceptionMask)); | |
2656 DeoptimizeIf(ne, instr->environment()); | 2675 DeoptimizeIf(ne, instr->environment()); |
2657 | 2676 |
2658 // Move the result back to general purpose register r0. | 2677 // Move the result back to general purpose register r0. |
2659 __ vmov(result, single_scratch); | 2678 __ vmov(result, single_scratch); |
2660 | 2679 |
2661 // Test for -0. | 2680 // Test for -0. |
2662 Label done; | 2681 Label done; |
2663 __ cmp(result, Operand(0)); | 2682 __ cmp(result, Operand(0)); |
2664 __ b(ne, &done); | 2683 __ b(ne, &done); |
2665 __ vmov(scratch, input.high()); | 2684 __ vmov(scratch1, input.high()); |
2666 __ tst(scratch, Operand(HeapNumber::kSignMask)); | 2685 __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
2667 DeoptimizeIf(ne, instr->environment()); | 2686 DeoptimizeIf(ne, instr->environment()); |
2668 __ bind(&done); | 2687 __ bind(&done); |
2669 } | 2688 } |
2670 | 2689 |
2671 | 2690 |
2672 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 2691 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { |
2673 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); | 2692 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); |
2674 ASSERT(ToDoubleRegister(instr->result()).is(input)); | 2693 ASSERT(ToDoubleRegister(instr->result()).is(input)); |
2675 __ vsqrt(input, input); | 2694 __ vsqrt(input, input); |
2676 } | 2695 } |
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3290 ASSERT(result->IsDoubleRegister()); | 3309 ASSERT(result->IsDoubleRegister()); |
3291 | 3310 |
3292 Register input_reg = ToRegister(input); | 3311 Register input_reg = ToRegister(input); |
3293 DoubleRegister result_reg = ToDoubleRegister(result); | 3312 DoubleRegister result_reg = ToDoubleRegister(result); |
3294 | 3313 |
3295 EmitNumberUntagD(input_reg, result_reg, instr->environment()); | 3314 EmitNumberUntagD(input_reg, result_reg, instr->environment()); |
3296 } | 3315 } |
3297 | 3316 |
3298 | 3317 |
3299 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 3318 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
3300 Abort("DoDoubleToI unimplemented."); | 3319 LOperand* input = instr->InputAt(0); |
3320 ASSERT(input->IsDoubleRegister()); | |
3321 LOperand* result = instr->result(); | |
3322 ASSERT(result->IsRegister()); | |
3323 | |
3324 DoubleRegister double_input = ToDoubleRegister(input); | |
3325 Register result_reg = ToRegister(result); | |
3326 SwVfpRegister single_scratch = double_scratch0().low(); | |
3327 Register scratch1 = scratch0(); | |
3328 Register scratch2 = ToRegister(instr->TempAt(0)); | |
3329 | |
3330 VFPRoundingMode rounding_mode = instr->truncating() ? kRoundToMinusInf | |
3331 : kRoundToNearest; | |
3332 | |
3333 | |
3334 EmitVFPTruncate(rounding_mode, | |
Søren Thygesen Gjesse
2011/02/03 09:07:17
Indentation.
Rodolph Perfetta
2011/02/03 15:03:39
Done.
| |
3335 single_scratch, | |
3336 double_input, | |
3337 scratch1, | |
3338 scratch2); | |
3339 // Deoptimize if we had a vfp invalid exception. | |
3340 DeoptimizeIf(ne, instr->environment()); | |
3341 // Retrieve the result. | |
3342 __ vmov(result_reg, single_scratch); | |
3343 | |
3344 if (instr->truncating() && | |
3345 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
3346 Label done; | |
3347 __ cmp(result_reg, Operand(0)); | |
3348 __ b(ne, &done); | |
3349 // Check for -0. | |
3350 __ vmov(scratch1, double_input.high()); | |
3351 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | |
3352 DeoptimizeIf(ne, instr->environment()); | |
3353 | |
Søren Thygesen Gjesse
2011/02/03 09:07:17
Indentation.
Rodolph Perfetta
2011/02/03 15:03:39
Done.
| |
3354 __ bind(&done); | |
3355 } | |
3301 } | 3356 } |
3302 | 3357 |
3303 | 3358 |
3304 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 3359 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
3305 LOperand* input = instr->InputAt(0); | 3360 LOperand* input = instr->InputAt(0); |
3306 ASSERT(input->IsRegister()); | 3361 ASSERT(input->IsRegister()); |
3307 __ tst(ToRegister(input), Operand(kSmiTagMask)); | 3362 __ tst(ToRegister(input), Operand(kSmiTagMask)); |
3308 DeoptimizeIf(instr->condition(), instr->environment()); | 3363 DeoptimizeIf(instr->condition(), instr->environment()); |
3309 } | 3364 } |
3310 | 3365 |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3682 | 3737 |
3683 | 3738 |
3684 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 3739 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
3685 Abort("DoOsrEntry unimplemented."); | 3740 Abort("DoOsrEntry unimplemented."); |
3686 } | 3741 } |
3687 | 3742 |
3688 | 3743 |
3689 #undef __ | 3744 #undef __ |
3690 | 3745 |
3691 } } // namespace v8::internal | 3746 } } // namespace v8::internal |
OLD | NEW |