OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 3481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3492 // If smi, handle it directly. | 3492 // If smi, handle it directly. |
3493 EmitIntegerMathAbs(instr); | 3493 EmitIntegerMathAbs(instr); |
3494 __ bind(deferred->exit()); | 3494 __ bind(deferred->exit()); |
3495 } | 3495 } |
3496 } | 3496 } |
3497 | 3497 |
3498 | 3498 |
3499 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 3499 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
3500 DoubleRegister input = ToDoubleRegister(instr->value()); | 3500 DoubleRegister input = ToDoubleRegister(instr->value()); |
3501 Register result = ToRegister(instr->result()); | 3501 Register result = ToRegister(instr->result()); |
3502 SwVfpRegister single_scratch = double_scratch0().low(); | 3502 Register scratch = scratch0(); |
3503 Register scratch1 = scratch0(); | |
3504 Register scratch2 = ToRegister(instr->temp()); | |
3505 | 3503 |
3506 __ EmitVFPTruncate(kRoundToMinusInf, | 3504 __ EmitVFPTruncate(kRoundToMinusInf, |
3507 single_scratch, | 3505 result, |
3508 input, | 3506 input, |
3509 scratch1, | 3507 scratch, |
3510 scratch2); | 3508 double_scratch0()); |
3511 DeoptimizeIf(ne, instr->environment()); | 3509 DeoptimizeIf(ne, instr->environment()); |
3512 | 3510 |
3513 // Move the result back to general purpose register r0. | |
3514 __ vmov(result, single_scratch); | |
3515 | |
3516 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3511 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3517 // Test for -0. | 3512 // Test for -0. |
3518 Label done; | 3513 Label done; |
3519 __ cmp(result, Operand(0)); | 3514 __ cmp(result, Operand(0)); |
3520 __ b(ne, &done); | 3515 __ b(ne, &done); |
3521 __ vmov(scratch1, input.high()); | 3516 __ vmov(scratch, input.high()); |
3522 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | 3517 __ tst(scratch, Operand(HeapNumber::kSignMask)); |
3523 DeoptimizeIf(ne, instr->environment()); | 3518 DeoptimizeIf(ne, instr->environment()); |
3524 __ bind(&done); | 3519 __ bind(&done); |
3525 } | 3520 } |
3526 } | 3521 } |
3527 | 3522 |
3528 | 3523 |
3529 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 3524 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
3530 DoubleRegister input = ToDoubleRegister(instr->value()); | 3525 DoubleRegister input = ToDoubleRegister(instr->value()); |
3531 Register result = ToRegister(instr->result()); | 3526 Register result = ToRegister(instr->result()); |
| 3527 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); |
3532 Register scratch = scratch0(); | 3528 Register scratch = scratch0(); |
3533 Label done, check_sign_on_zero; | 3529 Label done, check_sign_on_zero; |
3534 | 3530 |
3535 // Extract exponent bits. | 3531 // Extract exponent bits. |
3536 __ vmov(result, input.high()); | 3532 __ vmov(result, input.high()); |
3537 __ ubfx(scratch, | 3533 __ ubfx(scratch, |
3538 result, | 3534 result, |
3539 HeapNumber::kExponentShift, | 3535 HeapNumber::kExponentShift, |
3540 HeapNumber::kExponentBits); | 3536 HeapNumber::kExponentBits); |
3541 | 3537 |
(...skipping 22 matching lines...) Expand all Loading... |
3564 __ vmov(result, double_scratch0().high()); | 3560 __ vmov(result, double_scratch0().high()); |
3565 __ eor(result, result, Operand(scratch), SetCC); | 3561 __ eor(result, result, Operand(scratch), SetCC); |
3566 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3562 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3567 DeoptimizeIf(mi, instr->environment()); | 3563 DeoptimizeIf(mi, instr->environment()); |
3568 } else { | 3564 } else { |
3569 __ mov(result, Operand(0), LeaveCC, mi); | 3565 __ mov(result, Operand(0), LeaveCC, mi); |
3570 __ b(mi, &done); | 3566 __ b(mi, &done); |
3571 } | 3567 } |
3572 | 3568 |
3573 __ EmitVFPTruncate(kRoundToMinusInf, | 3569 __ EmitVFPTruncate(kRoundToMinusInf, |
3574 double_scratch0().low(), | 3570 result, |
3575 double_scratch0(), | 3571 double_scratch0(), |
3576 result, | 3572 scratch, |
3577 scratch); | 3573 double_scratch1); |
3578 DeoptimizeIf(ne, instr->environment()); | 3574 DeoptimizeIf(ne, instr->environment()); |
3579 __ vmov(result, double_scratch0().low()); | |
3580 | 3575 |
3581 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3576 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3582 // Test for -0. | 3577 // Test for -0. |
3583 __ cmp(result, Operand(0)); | 3578 __ cmp(result, Operand(0)); |
3584 __ b(ne, &done); | 3579 __ b(ne, &done); |
3585 __ bind(&check_sign_on_zero); | 3580 __ bind(&check_sign_on_zero); |
3586 __ vmov(scratch, input.high()); | 3581 __ vmov(scratch, input.high()); |
3587 __ tst(scratch, Operand(HeapNumber::kSignMask)); | 3582 __ tst(scratch, Operand(HeapNumber::kSignMask)); |
3588 DeoptimizeIf(ne, instr->environment()); | 3583 DeoptimizeIf(ne, instr->environment()); |
3589 } | 3584 } |
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4595 __ vcvt_f64_s32(result_reg, flt_scratch); | 4590 __ vcvt_f64_s32(result_reg, flt_scratch); |
4596 __ bind(&done); | 4591 __ bind(&done); |
4597 } | 4592 } |
4598 | 4593 |
4599 | 4594 |
4600 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { | 4595 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { |
4601 Register input_reg = ToRegister(instr->value()); | 4596 Register input_reg = ToRegister(instr->value()); |
4602 Register scratch1 = scratch0(); | 4597 Register scratch1 = scratch0(); |
4603 Register scratch2 = ToRegister(instr->temp()); | 4598 Register scratch2 = ToRegister(instr->temp()); |
4604 DwVfpRegister double_scratch = double_scratch0(); | 4599 DwVfpRegister double_scratch = double_scratch0(); |
4605 SwVfpRegister single_scratch = double_scratch.low(); | 4600 DwVfpRegister double_scratch2 = ToDoubleRegister(instr->temp3()); |
4606 | 4601 |
4607 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); | 4602 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); |
4608 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); | 4603 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); |
4609 | 4604 |
4610 Label done; | 4605 Label done; |
4611 | 4606 |
4612 // The input was optimistically untagged; revert it. | 4607 // The input was optimistically untagged; revert it. |
4613 // The carry flag is set when we reach this deferred code as we just executed | 4608 // The carry flag is set when we reach this deferred code as we just executed |
4614 // SmiUntag(heap_object, SetCC) | 4609 // SmiUntag(heap_object, SetCC) |
4615 STATIC_ASSERT(kHeapObjectTag == 1); | 4610 STATIC_ASSERT(kHeapObjectTag == 1); |
4616 __ adc(input_reg, input_reg, Operand(input_reg)); | 4611 __ adc(input_reg, input_reg, Operand(input_reg)); |
4617 | 4612 |
4618 // Heap number map check. | 4613 // Heap number map check. |
4619 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4614 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
4620 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 4615 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
4621 __ cmp(scratch1, Operand(ip)); | 4616 __ cmp(scratch1, Operand(ip)); |
4622 | 4617 |
4623 if (instr->truncating()) { | 4618 if (instr->truncating()) { |
4624 Register scratch3 = ToRegister(instr->temp2()); | 4619 Register scratch3 = ToRegister(instr->temp2()); |
4625 DwVfpRegister double_scratch2 = ToDoubleRegister(instr->temp3()); | 4620 SwVfpRegister single_scratch = double_scratch.low(); |
4626 ASSERT(!scratch3.is(input_reg) && | 4621 ASSERT(!scratch3.is(input_reg) && |
4627 !scratch3.is(scratch1) && | 4622 !scratch3.is(scratch1) && |
4628 !scratch3.is(scratch2)); | 4623 !scratch3.is(scratch2)); |
4629 // Performs a truncating conversion of a floating point number as used by | 4624 // Performs a truncating conversion of a floating point number as used by |
4630 // the JS bitwise operations. | 4625 // the JS bitwise operations. |
4631 Label heap_number; | 4626 Label heap_number; |
4632 __ b(eq, &heap_number); | 4627 __ b(eq, &heap_number); |
4633 // Check for undefined. Undefined is converted to zero for truncating | 4628 // Check for undefined. Undefined is converted to zero for truncating |
4634 // conversions. | 4629 // conversions. |
4635 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 4630 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
(...skipping 14 matching lines...) Expand all Loading... |
4650 scratch3); | 4645 scratch3); |
4651 | 4646 |
4652 } else { | 4647 } else { |
4653 CpuFeatures::Scope scope(VFP3); | 4648 CpuFeatures::Scope scope(VFP3); |
4654 // Deoptimize if we don't have a heap number. | 4649 // Deoptimize if we don't have a heap number. |
4655 DeoptimizeIf(ne, instr->environment()); | 4650 DeoptimizeIf(ne, instr->environment()); |
4656 | 4651 |
4657 __ sub(ip, input_reg, Operand(kHeapObjectTag)); | 4652 __ sub(ip, input_reg, Operand(kHeapObjectTag)); |
4658 __ vldr(double_scratch, ip, HeapNumber::kValueOffset); | 4653 __ vldr(double_scratch, ip, HeapNumber::kValueOffset); |
4659 __ EmitVFPTruncate(kRoundToZero, | 4654 __ EmitVFPTruncate(kRoundToZero, |
4660 single_scratch, | 4655 input_reg, |
4661 double_scratch, | 4656 double_scratch, |
4662 scratch1, | 4657 scratch1, |
4663 scratch2, | 4658 double_scratch2, |
4664 kCheckForInexactConversion); | 4659 kCheckForInexactConversion); |
4665 DeoptimizeIf(ne, instr->environment()); | 4660 DeoptimizeIf(ne, instr->environment()); |
4666 // Load the result. | |
4667 __ vmov(input_reg, single_scratch); | |
4668 | 4661 |
4669 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 4662 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
4670 __ cmp(input_reg, Operand(0)); | 4663 __ cmp(input_reg, Operand(0)); |
4671 __ b(ne, &done); | 4664 __ b(ne, &done); |
4672 __ vmov(scratch1, double_scratch.high()); | 4665 __ vmov(scratch1, double_scratch.high()); |
4673 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | 4666 __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
4674 DeoptimizeIf(ne, instr->environment()); | 4667 DeoptimizeIf(ne, instr->environment()); |
4675 } | 4668 } |
4676 } | 4669 } |
4677 __ bind(&done); | 4670 __ bind(&done); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4721 instr->hydrogen()->deoptimize_on_minus_zero(), | 4714 instr->hydrogen()->deoptimize_on_minus_zero(), |
4722 instr->environment()); | 4715 instr->environment()); |
4723 } | 4716 } |
4724 | 4717 |
4725 | 4718 |
4726 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 4719 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
4727 Register result_reg = ToRegister(instr->result()); | 4720 Register result_reg = ToRegister(instr->result()); |
4728 Register scratch1 = scratch0(); | 4721 Register scratch1 = scratch0(); |
4729 Register scratch2 = ToRegister(instr->temp()); | 4722 Register scratch2 = ToRegister(instr->temp()); |
4730 DwVfpRegister double_input = ToDoubleRegister(instr->value()); | 4723 DwVfpRegister double_input = ToDoubleRegister(instr->value()); |
4731 SwVfpRegister single_scratch = double_scratch0().low(); | |
4732 | 4724 |
4733 Label done; | 4725 Label done; |
4734 | 4726 |
4735 if (instr->truncating()) { | 4727 if (instr->truncating()) { |
4736 Register scratch3 = ToRegister(instr->temp2()); | 4728 Register scratch3 = ToRegister(instr->temp2()); |
| 4729 SwVfpRegister single_scratch = double_scratch0().low(); |
4737 __ EmitECMATruncate(result_reg, | 4730 __ EmitECMATruncate(result_reg, |
4738 double_input, | 4731 double_input, |
4739 single_scratch, | 4732 single_scratch, |
4740 scratch1, | 4733 scratch1, |
4741 scratch2, | 4734 scratch2, |
4742 scratch3); | 4735 scratch3); |
4743 } else { | 4736 } else { |
4744 VFPRoundingMode rounding_mode = kRoundToMinusInf; | 4737 DwVfpRegister double_scratch = double_scratch0(); |
4745 __ EmitVFPTruncate(rounding_mode, | 4738 __ EmitVFPTruncate(kRoundToMinusInf, |
4746 single_scratch, | 4739 result_reg, |
4747 double_input, | 4740 double_input, |
4748 scratch1, | 4741 scratch1, |
4749 scratch2, | 4742 double_scratch, |
4750 kCheckForInexactConversion); | 4743 kCheckForInexactConversion); |
| 4744 |
4751 // Deoptimize if we had a vfp invalid exception, | 4745 // Deoptimize if we had a vfp invalid exception, |
4752 // including inexact operation. | 4746 // including inexact operation. |
4753 DeoptimizeIf(ne, instr->environment()); | 4747 DeoptimizeIf(ne, instr->environment()); |
4754 // Retrieve the result. | |
4755 __ vmov(result_reg, single_scratch); | |
4756 } | 4748 } |
4757 __ bind(&done); | 4749 __ bind(&done); |
4758 } | 4750 } |
4759 | 4751 |
4760 | 4752 |
4761 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 4753 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
4762 LOperand* input = instr->value(); | 4754 LOperand* input = instr->value(); |
4763 __ tst(ToRegister(input), Operand(kSmiTagMask)); | 4755 __ tst(ToRegister(input), Operand(kSmiTagMask)); |
4764 DeoptimizeIf(ne, instr->environment()); | 4756 DeoptimizeIf(ne, instr->environment()); |
4765 } | 4757 } |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5683 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 5675 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
5684 __ ldr(result, FieldMemOperand(scratch, | 5676 __ ldr(result, FieldMemOperand(scratch, |
5685 FixedArray::kHeaderSize - kPointerSize)); | 5677 FixedArray::kHeaderSize - kPointerSize)); |
5686 __ bind(&done); | 5678 __ bind(&done); |
5687 } | 5679 } |
5688 | 5680 |
5689 | 5681 |
5690 #undef __ | 5682 #undef __ |
5691 | 5683 |
5692 } } // namespace v8::internal | 5684 } } // namespace v8::internal |
OLD | NEW |