| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 | 697 |
| 698 // On entry r1 and r2 are the values to be compared. | 698 // On entry r1 and r2 are the values to be compared. |
| 699 // On exit r0 is 0, positive or negative to indicate the result of | 699 // On exit r0 is 0, positive or negative to indicate the result of |
| 700 // the comparison. | 700 // the comparison. |
| 701 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { | 701 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { |
| 702 Register lhs = r1; | 702 Register lhs = r1; |
| 703 Register rhs = r0; | 703 Register rhs = r0; |
| 704 Condition cc = GetCondition(); | 704 Condition cc = GetCondition(); |
| 705 | 705 |
| 706 Label miss; | 706 Label miss; |
| 707 ICCompareStub_CheckInputType(masm, lhs, r2, left_, &miss); | 707 ICCompareStub_CheckInputType(masm, lhs, r2, left(), &miss); |
| 708 ICCompareStub_CheckInputType(masm, rhs, r3, right_, &miss); | 708 ICCompareStub_CheckInputType(masm, rhs, r3, right(), &miss); |
| 709 | 709 |
| 710 Label slow; // Call builtin. | 710 Label slow; // Call builtin. |
| 711 Label not_smis, both_loaded_as_doubles, lhs_not_nan; | 711 Label not_smis, both_loaded_as_doubles, lhs_not_nan; |
| 712 | 712 |
| 713 Label not_two_smis, smi_done; | 713 Label not_two_smis, smi_done; |
| 714 __ orr(r2, r1, r0); | 714 __ orr(r2, r1, r0); |
| 715 __ JumpIfNotSmi(r2, ¬_two_smis); | 715 __ JumpIfNotSmi(r2, ¬_two_smis); |
| 716 __ mov(r1, Operand(r1, ASR, 1)); | 716 __ mov(r1, Operand(r1, ASR, 1)); |
| 717 __ sub(r0, r1, Operand(r0, ASR, 1)); | 717 __ sub(r0, r1, Operand(r0, ASR, 1)); |
| 718 __ Ret(); | 718 __ Ret(); |
| (...skipping 2746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3465 } | 3465 } |
| 3466 | 3466 |
| 3467 // Tail call into the stub that handles binary operations with allocation | 3467 // Tail call into the stub that handles binary operations with allocation |
| 3468 // sites. | 3468 // sites. |
| 3469 BinaryOpWithAllocationSiteStub stub(isolate(), state()); | 3469 BinaryOpWithAllocationSiteStub stub(isolate(), state()); |
| 3470 __ TailCallStub(&stub); | 3470 __ TailCallStub(&stub); |
| 3471 } | 3471 } |
| 3472 | 3472 |
| 3473 | 3473 |
| 3474 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { | 3474 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { |
| 3475 DCHECK(state_ == CompareIC::SMI); | 3475 DCHECK(state() == CompareIC::SMI); |
| 3476 Label miss; | 3476 Label miss; |
| 3477 __ orr(r2, r1, r0); | 3477 __ orr(r2, r1, r0); |
| 3478 __ JumpIfNotSmi(r2, &miss); | 3478 __ JumpIfNotSmi(r2, &miss); |
| 3479 | 3479 |
| 3480 if (GetCondition() == eq) { | 3480 if (GetCondition() == eq) { |
| 3481 // For equality we do not care about the sign of the result. | 3481 // For equality we do not care about the sign of the result. |
| 3482 __ sub(r0, r0, r1, SetCC); | 3482 __ sub(r0, r0, r1, SetCC); |
| 3483 } else { | 3483 } else { |
| 3484 // Untag before subtracting to avoid handling overflow. | 3484 // Untag before subtracting to avoid handling overflow. |
| 3485 __ SmiUntag(r1); | 3485 __ SmiUntag(r1); |
| 3486 __ sub(r0, r1, Operand::SmiUntag(r0)); | 3486 __ sub(r0, r1, Operand::SmiUntag(r0)); |
| 3487 } | 3487 } |
| 3488 __ Ret(); | 3488 __ Ret(); |
| 3489 | 3489 |
| 3490 __ bind(&miss); | 3490 __ bind(&miss); |
| 3491 GenerateMiss(masm); | 3491 GenerateMiss(masm); |
| 3492 } | 3492 } |
| 3493 | 3493 |
| 3494 | 3494 |
| 3495 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { | 3495 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { |
| 3496 DCHECK(state_ == CompareIC::NUMBER); | 3496 DCHECK(state() == CompareIC::NUMBER); |
| 3497 | 3497 |
| 3498 Label generic_stub; | 3498 Label generic_stub; |
| 3499 Label unordered, maybe_undefined1, maybe_undefined2; | 3499 Label unordered, maybe_undefined1, maybe_undefined2; |
| 3500 Label miss; | 3500 Label miss; |
| 3501 | 3501 |
| 3502 if (left_ == CompareIC::SMI) { | 3502 if (left() == CompareIC::SMI) { |
| 3503 __ JumpIfNotSmi(r1, &miss); | 3503 __ JumpIfNotSmi(r1, &miss); |
| 3504 } | 3504 } |
| 3505 if (right_ == CompareIC::SMI) { | 3505 if (right() == CompareIC::SMI) { |
| 3506 __ JumpIfNotSmi(r0, &miss); | 3506 __ JumpIfNotSmi(r0, &miss); |
| 3507 } | 3507 } |
| 3508 | 3508 |
| 3509 // Inlining the double comparison and falling back to the general compare | 3509 // Inlining the double comparison and falling back to the general compare |
| 3510 // stub if NaN is involved. | 3510 // stub if NaN is involved. |
| 3511 // Load left and right operand. | 3511 // Load left and right operand. |
| 3512 Label done, left, left_smi, right_smi; | 3512 Label done, left, left_smi, right_smi; |
| 3513 __ JumpIfSmi(r0, &right_smi); | 3513 __ JumpIfSmi(r0, &right_smi); |
| 3514 __ CheckMap(r0, r2, Heap::kHeapNumberMapRootIndex, &maybe_undefined1, | 3514 __ CheckMap(r0, r2, Heap::kHeapNumberMapRootIndex, &maybe_undefined1, |
| 3515 DONT_DO_SMI_CHECK); | 3515 DONT_DO_SMI_CHECK); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3537 __ b(vs, &unordered); | 3537 __ b(vs, &unordered); |
| 3538 | 3538 |
| 3539 // Return a result of -1, 0, or 1, based on status bits. | 3539 // Return a result of -1, 0, or 1, based on status bits. |
| 3540 __ mov(r0, Operand(EQUAL), LeaveCC, eq); | 3540 __ mov(r0, Operand(EQUAL), LeaveCC, eq); |
| 3541 __ mov(r0, Operand(LESS), LeaveCC, lt); | 3541 __ mov(r0, Operand(LESS), LeaveCC, lt); |
| 3542 __ mov(r0, Operand(GREATER), LeaveCC, gt); | 3542 __ mov(r0, Operand(GREATER), LeaveCC, gt); |
| 3543 __ Ret(); | 3543 __ Ret(); |
| 3544 | 3544 |
| 3545 __ bind(&unordered); | 3545 __ bind(&unordered); |
| 3546 __ bind(&generic_stub); | 3546 __ bind(&generic_stub); |
| 3547 ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC, | 3547 ICCompareStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC, |
| 3548 CompareIC::GENERIC); | 3548 CompareIC::GENERIC); |
| 3549 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | 3549 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 3550 | 3550 |
| 3551 __ bind(&maybe_undefined1); | 3551 __ bind(&maybe_undefined1); |
| 3552 if (Token::IsOrderedRelationalCompareOp(op_)) { | 3552 if (Token::IsOrderedRelationalCompareOp(op())) { |
| 3553 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); | 3553 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); |
| 3554 __ b(ne, &miss); | 3554 __ b(ne, &miss); |
| 3555 __ JumpIfSmi(r1, &unordered); | 3555 __ JumpIfSmi(r1, &unordered); |
| 3556 __ CompareObjectType(r1, r2, r2, HEAP_NUMBER_TYPE); | 3556 __ CompareObjectType(r1, r2, r2, HEAP_NUMBER_TYPE); |
| 3557 __ b(ne, &maybe_undefined2); | 3557 __ b(ne, &maybe_undefined2); |
| 3558 __ jmp(&unordered); | 3558 __ jmp(&unordered); |
| 3559 } | 3559 } |
| 3560 | 3560 |
| 3561 __ bind(&maybe_undefined2); | 3561 __ bind(&maybe_undefined2); |
| 3562 if (Token::IsOrderedRelationalCompareOp(op_)) { | 3562 if (Token::IsOrderedRelationalCompareOp(op())) { |
| 3563 __ CompareRoot(r1, Heap::kUndefinedValueRootIndex); | 3563 __ CompareRoot(r1, Heap::kUndefinedValueRootIndex); |
| 3564 __ b(eq, &unordered); | 3564 __ b(eq, &unordered); |
| 3565 } | 3565 } |
| 3566 | 3566 |
| 3567 __ bind(&miss); | 3567 __ bind(&miss); |
| 3568 GenerateMiss(masm); | 3568 GenerateMiss(masm); |
| 3569 } | 3569 } |
| 3570 | 3570 |
| 3571 | 3571 |
| 3572 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { | 3572 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { |
| 3573 DCHECK(state_ == CompareIC::INTERNALIZED_STRING); | 3573 DCHECK(state() == CompareIC::INTERNALIZED_STRING); |
| 3574 Label miss; | 3574 Label miss; |
| 3575 | 3575 |
| 3576 // Registers containing left and right operands respectively. | 3576 // Registers containing left and right operands respectively. |
| 3577 Register left = r1; | 3577 Register left = r1; |
| 3578 Register right = r0; | 3578 Register right = r0; |
| 3579 Register tmp1 = r2; | 3579 Register tmp1 = r2; |
| 3580 Register tmp2 = r3; | 3580 Register tmp2 = r3; |
| 3581 | 3581 |
| 3582 // Check that both operands are heap objects. | 3582 // Check that both operands are heap objects. |
| 3583 __ JumpIfEitherSmi(left, right, &miss); | 3583 __ JumpIfEitherSmi(left, right, &miss); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3601 STATIC_ASSERT(kSmiTag == 0); | 3601 STATIC_ASSERT(kSmiTag == 0); |
| 3602 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); | 3602 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); |
| 3603 __ Ret(); | 3603 __ Ret(); |
| 3604 | 3604 |
| 3605 __ bind(&miss); | 3605 __ bind(&miss); |
| 3606 GenerateMiss(masm); | 3606 GenerateMiss(masm); |
| 3607 } | 3607 } |
| 3608 | 3608 |
| 3609 | 3609 |
| 3610 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { | 3610 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { |
| 3611 DCHECK(state_ == CompareIC::UNIQUE_NAME); | 3611 DCHECK(state() == CompareIC::UNIQUE_NAME); |
| 3612 DCHECK(GetCondition() == eq); | 3612 DCHECK(GetCondition() == eq); |
| 3613 Label miss; | 3613 Label miss; |
| 3614 | 3614 |
| 3615 // Registers containing left and right operands respectively. | 3615 // Registers containing left and right operands respectively. |
| 3616 Register left = r1; | 3616 Register left = r1; |
| 3617 Register right = r0; | 3617 Register right = r0; |
| 3618 Register tmp1 = r2; | 3618 Register tmp1 = r2; |
| 3619 Register tmp2 = r3; | 3619 Register tmp2 = r3; |
| 3620 | 3620 |
| 3621 // Check that both operands are heap objects. | 3621 // Check that both operands are heap objects. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3640 STATIC_ASSERT(kSmiTag == 0); | 3640 STATIC_ASSERT(kSmiTag == 0); |
| 3641 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); | 3641 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); |
| 3642 __ Ret(); | 3642 __ Ret(); |
| 3643 | 3643 |
| 3644 __ bind(&miss); | 3644 __ bind(&miss); |
| 3645 GenerateMiss(masm); | 3645 GenerateMiss(masm); |
| 3646 } | 3646 } |
| 3647 | 3647 |
| 3648 | 3648 |
| 3649 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { | 3649 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
| 3650 DCHECK(state_ == CompareIC::STRING); | 3650 DCHECK(state() == CompareIC::STRING); |
| 3651 Label miss; | 3651 Label miss; |
| 3652 | 3652 |
| 3653 bool equality = Token::IsEqualityOp(op_); | 3653 bool equality = Token::IsEqualityOp(op()); |
| 3654 | 3654 |
| 3655 // Registers containing left and right operands respectively. | 3655 // Registers containing left and right operands respectively. |
| 3656 Register left = r1; | 3656 Register left = r1; |
| 3657 Register right = r0; | 3657 Register right = r0; |
| 3658 Register tmp1 = r2; | 3658 Register tmp1 = r2; |
| 3659 Register tmp2 = r3; | 3659 Register tmp2 = r3; |
| 3660 Register tmp3 = r4; | 3660 Register tmp3 = r4; |
| 3661 Register tmp4 = r5; | 3661 Register tmp4 = r5; |
| 3662 | 3662 |
| 3663 // Check that both operands are heap objects. | 3663 // Check that both operands are heap objects. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3719 } else { | 3719 } else { |
| 3720 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3720 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 3721 } | 3721 } |
| 3722 | 3722 |
| 3723 __ bind(&miss); | 3723 __ bind(&miss); |
| 3724 GenerateMiss(masm); | 3724 GenerateMiss(masm); |
| 3725 } | 3725 } |
| 3726 | 3726 |
| 3727 | 3727 |
| 3728 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 3728 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { |
| 3729 DCHECK(state_ == CompareIC::OBJECT); | 3729 DCHECK(state() == CompareIC::OBJECT); |
| 3730 Label miss; | 3730 Label miss; |
| 3731 __ and_(r2, r1, Operand(r0)); | 3731 __ and_(r2, r1, Operand(r0)); |
| 3732 __ JumpIfSmi(r2, &miss); | 3732 __ JumpIfSmi(r2, &miss); |
| 3733 | 3733 |
| 3734 __ CompareObjectType(r0, r2, r2, JS_OBJECT_TYPE); | 3734 __ CompareObjectType(r0, r2, r2, JS_OBJECT_TYPE); |
| 3735 __ b(ne, &miss); | 3735 __ b(ne, &miss); |
| 3736 __ CompareObjectType(r1, r2, r2, JS_OBJECT_TYPE); | 3736 __ CompareObjectType(r1, r2, r2, JS_OBJECT_TYPE); |
| 3737 __ b(ne, &miss); | 3737 __ b(ne, &miss); |
| 3738 | 3738 |
| 3739 DCHECK(GetCondition() == eq); | 3739 DCHECK(GetCondition() == eq); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3767 | 3767 |
| 3768 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { | 3768 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { |
| 3769 { | 3769 { |
| 3770 // Call the runtime system in a fresh internal frame. | 3770 // Call the runtime system in a fresh internal frame. |
| 3771 ExternalReference miss = | 3771 ExternalReference miss = |
| 3772 ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate()); | 3772 ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate()); |
| 3773 | 3773 |
| 3774 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 3774 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 3775 __ Push(r1, r0); | 3775 __ Push(r1, r0); |
| 3776 __ Push(lr, r1, r0); | 3776 __ Push(lr, r1, r0); |
| 3777 __ mov(ip, Operand(Smi::FromInt(op_))); | 3777 __ mov(ip, Operand(Smi::FromInt(op()))); |
| 3778 __ push(ip); | 3778 __ push(ip); |
| 3779 __ CallExternalReference(miss, 3); | 3779 __ CallExternalReference(miss, 3); |
| 3780 // Compute the entry point of the rewritten stub. | 3780 // Compute the entry point of the rewritten stub. |
| 3781 __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 3781 __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 3782 // Restore registers. | 3782 // Restore registers. |
| 3783 __ pop(lr); | 3783 __ pop(lr); |
| 3784 __ Pop(r1, r0); | 3784 __ Pop(r1, r0); |
| 3785 } | 3785 } |
| 3786 | 3786 |
| 3787 __ Jump(r2); | 3787 __ Jump(r2); |
| (...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4853 MemOperand(fp, 6 * kPointerSize), | 4853 MemOperand(fp, 6 * kPointerSize), |
| 4854 NULL); | 4854 NULL); |
| 4855 } | 4855 } |
| 4856 | 4856 |
| 4857 | 4857 |
| 4858 #undef __ | 4858 #undef __ |
| 4859 | 4859 |
| 4860 } } // namespace v8::internal | 4860 } } // namespace v8::internal |
| 4861 | 4861 |
| 4862 #endif // V8_TARGET_ARCH_ARM | 4862 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |