| 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 |