| 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 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 | 800 |
| 801 | 801 |
| 802 void UnaryOpStub::Generate(MacroAssembler* masm) { | 802 void UnaryOpStub::Generate(MacroAssembler* masm) { |
| 803 switch (operand_type_) { | 803 switch (operand_type_) { |
| 804 case UnaryOpIC::UNINITIALIZED: | 804 case UnaryOpIC::UNINITIALIZED: |
| 805 GenerateTypeTransition(masm); | 805 GenerateTypeTransition(masm); |
| 806 break; | 806 break; |
| 807 case UnaryOpIC::SMI: | 807 case UnaryOpIC::SMI: |
| 808 GenerateSmiStub(masm); | 808 GenerateSmiStub(masm); |
| 809 break; | 809 break; |
| 810 case UnaryOpIC::HEAP_NUMBER: | 810 case UnaryOpIC::NUMBER: |
| 811 GenerateHeapNumberStub(masm); | 811 GenerateNumberStub(masm); |
| 812 break; | 812 break; |
| 813 case UnaryOpIC::GENERIC: | 813 case UnaryOpIC::GENERIC: |
| 814 GenerateGenericStub(masm); | 814 GenerateGenericStub(masm); |
| 815 break; | 815 break; |
| 816 } | 816 } |
| 817 } | 817 } |
| 818 | 818 |
| 819 | 819 |
| 820 void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { | 820 void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { |
| 821 __ pop(rcx); // Save return address. | 821 __ pop(rcx); // Save return address. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 void UnaryOpStub::GenerateSmiCodeBitNot(MacroAssembler* masm, | 882 void UnaryOpStub::GenerateSmiCodeBitNot(MacroAssembler* masm, |
| 883 Label* non_smi, | 883 Label* non_smi, |
| 884 Label::Distance non_smi_near) { | 884 Label::Distance non_smi_near) { |
| 885 __ JumpIfNotSmi(rax, non_smi, non_smi_near); | 885 __ JumpIfNotSmi(rax, non_smi, non_smi_near); |
| 886 __ SmiNot(rax, rax); | 886 __ SmiNot(rax, rax); |
| 887 __ ret(0); | 887 __ ret(0); |
| 888 } | 888 } |
| 889 | 889 |
| 890 | 890 |
| 891 // TODO(svenpanne): Use virtual functions instead of switch. | 891 // TODO(svenpanne): Use virtual functions instead of switch. |
| 892 void UnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { | 892 void UnaryOpStub::GenerateNumberStub(MacroAssembler* masm) { |
| 893 switch (op_) { | 893 switch (op_) { |
| 894 case Token::SUB: | 894 case Token::SUB: |
| 895 GenerateHeapNumberStubSub(masm); | 895 GenerateNumberStubSub(masm); |
| 896 break; | 896 break; |
| 897 case Token::BIT_NOT: | 897 case Token::BIT_NOT: |
| 898 GenerateHeapNumberStubBitNot(masm); | 898 GenerateNumberStubBitNot(masm); |
| 899 break; | 899 break; |
| 900 default: | 900 default: |
| 901 UNREACHABLE(); | 901 UNREACHABLE(); |
| 902 } | 902 } |
| 903 } | 903 } |
| 904 | 904 |
| 905 | 905 |
| 906 void UnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) { | 906 void UnaryOpStub::GenerateNumberStubSub(MacroAssembler* masm) { |
| 907 Label non_smi, slow, call_builtin; | 907 Label non_smi, slow, call_builtin; |
| 908 GenerateSmiCodeSub(masm, &non_smi, &call_builtin, Label::kNear); | 908 GenerateSmiCodeSub(masm, &non_smi, &call_builtin, Label::kNear); |
| 909 __ bind(&non_smi); | 909 __ bind(&non_smi); |
| 910 GenerateHeapNumberCodeSub(masm, &slow); | 910 GenerateHeapNumberCodeSub(masm, &slow); |
| 911 __ bind(&slow); | 911 __ bind(&slow); |
| 912 GenerateTypeTransition(masm); | 912 GenerateTypeTransition(masm); |
| 913 __ bind(&call_builtin); | 913 __ bind(&call_builtin); |
| 914 GenerateGenericCodeFallback(masm); | 914 GenerateGenericCodeFallback(masm); |
| 915 } | 915 } |
| 916 | 916 |
| 917 | 917 |
| 918 void UnaryOpStub::GenerateHeapNumberStubBitNot( | 918 void UnaryOpStub::GenerateNumberStubBitNot( |
| 919 MacroAssembler* masm) { | 919 MacroAssembler* masm) { |
| 920 Label non_smi, slow; | 920 Label non_smi, slow; |
| 921 GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear); | 921 GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear); |
| 922 __ bind(&non_smi); | 922 __ bind(&non_smi); |
| 923 GenerateHeapNumberCodeBitNot(masm, &slow); | 923 GenerateHeapNumberCodeBitNot(masm, &slow); |
| 924 __ bind(&slow); | 924 __ bind(&slow); |
| 925 GenerateTypeTransition(masm); | 925 GenerateTypeTransition(masm); |
| 926 } | 926 } |
| 927 | 927 |
| 928 | 928 |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1460 __ bind(&check); | 1460 __ bind(&check); |
| 1461 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); | 1461 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
| 1462 __ j(not_equal, &done, Label::kNear); | 1462 __ j(not_equal, &done, Label::kNear); |
| 1463 if (Token::IsBitOp(op_)) { | 1463 if (Token::IsBitOp(op_)) { |
| 1464 __ xor_(rax, rax); | 1464 __ xor_(rax, rax); |
| 1465 } else { | 1465 } else { |
| 1466 __ LoadRoot(rax, Heap::kNanValueRootIndex); | 1466 __ LoadRoot(rax, Heap::kNanValueRootIndex); |
| 1467 } | 1467 } |
| 1468 __ bind(&done); | 1468 __ bind(&done); |
| 1469 | 1469 |
| 1470 GenerateHeapNumberStub(masm); | 1470 GenerateNumberStub(masm); |
| 1471 } | 1471 } |
| 1472 | 1472 |
| 1473 | 1473 |
| 1474 static void BinaryOpStub_CheckSmiInput(MacroAssembler* masm, | 1474 static void BinaryOpStub_CheckSmiInput(MacroAssembler* masm, |
| 1475 Register input, | 1475 Register input, |
| 1476 Label* fail) { | 1476 Label* fail) { |
| 1477 Label ok; | 1477 Label ok; |
| 1478 __ JumpIfSmi(input, &ok, Label::kNear); | 1478 __ JumpIfSmi(input, &ok, Label::kNear); |
| 1479 Register heap_number_map = r8; | 1479 Register heap_number_map = r8; |
| 1480 Register scratch1 = r9; | 1480 Register scratch1 = r9; |
| 1481 Register scratch2 = r10; | 1481 Register scratch2 = r10; |
| 1482 // HeapNumbers containing 32bit integer values are also allowed. | 1482 // HeapNumbers containing 32bit integer values are also allowed. |
| 1483 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); | 1483 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
| 1484 __ cmpq(FieldOperand(input, HeapObject::kMapOffset), heap_number_map); | 1484 __ cmpq(FieldOperand(input, HeapObject::kMapOffset), heap_number_map); |
| 1485 __ j(not_equal, fail); | 1485 __ j(not_equal, fail); |
| 1486 __ movsd(xmm0, FieldOperand(input, HeapNumber::kValueOffset)); | 1486 __ movsd(xmm0, FieldOperand(input, HeapNumber::kValueOffset)); |
| 1487 // Convert, convert back, and compare the two doubles' bits. | 1487 // Convert, convert back, and compare the two doubles' bits. |
| 1488 __ cvttsd2siq(scratch2, xmm0); | 1488 __ cvttsd2siq(scratch2, xmm0); |
| 1489 __ cvtlsi2sd(xmm1, scratch2); | 1489 __ cvtlsi2sd(xmm1, scratch2); |
| 1490 __ movq(scratch1, xmm0); | 1490 __ movq(scratch1, xmm0); |
| 1491 __ movq(scratch2, xmm1); | 1491 __ movq(scratch2, xmm1); |
| 1492 __ cmpq(scratch1, scratch2); | 1492 __ cmpq(scratch1, scratch2); |
| 1493 __ j(not_equal, fail); | 1493 __ j(not_equal, fail); |
| 1494 __ bind(&ok); | 1494 __ bind(&ok); |
| 1495 } | 1495 } |
| 1496 | 1496 |
| 1497 | 1497 |
| 1498 void BinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { | 1498 void BinaryOpStub::GenerateNumberStub(MacroAssembler* masm) { |
| 1499 Label gc_required, not_number; | 1499 Label gc_required, not_number; |
| 1500 | 1500 |
| 1501 // It could be that only SMIs have been seen at either the left | 1501 // It could be that only SMIs have been seen at either the left |
| 1502 // or the right operand. For precise type feedback, patch the IC | 1502 // or the right operand. For precise type feedback, patch the IC |
| 1503 // again if this changes. | 1503 // again if this changes. |
| 1504 if (left_type_ == BinaryOpIC::SMI) { | 1504 if (left_type_ == BinaryOpIC::SMI) { |
| 1505 BinaryOpStub_CheckSmiInput(masm, rdx, ¬_number); | 1505 BinaryOpStub_CheckSmiInput(masm, rdx, ¬_number); |
| 1506 } | 1506 } |
| 1507 if (right_type_ == BinaryOpIC::SMI) { | 1507 if (right_type_ == BinaryOpIC::SMI) { |
| 1508 BinaryOpStub_CheckSmiInput(masm, rax, ¬_number); | 1508 BinaryOpStub_CheckSmiInput(masm, rax, ¬_number); |
| (...skipping 2055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3564 } | 3564 } |
| 3565 | 3565 |
| 3566 | 3566 |
| 3567 static void CheckInputType(MacroAssembler* masm, | 3567 static void CheckInputType(MacroAssembler* masm, |
| 3568 Register input, | 3568 Register input, |
| 3569 CompareIC::State expected, | 3569 CompareIC::State expected, |
| 3570 Label* fail) { | 3570 Label* fail) { |
| 3571 Label ok; | 3571 Label ok; |
| 3572 if (expected == CompareIC::SMI) { | 3572 if (expected == CompareIC::SMI) { |
| 3573 __ JumpIfNotSmi(input, fail); | 3573 __ JumpIfNotSmi(input, fail); |
| 3574 } else if (expected == CompareIC::HEAP_NUMBER) { | 3574 } else if (expected == CompareIC::NUMBER) { |
| 3575 __ JumpIfSmi(input, &ok); | 3575 __ JumpIfSmi(input, &ok); |
| 3576 __ CompareMap(input, masm->isolate()->factory()->heap_number_map(), NULL); | 3576 __ CompareMap(input, masm->isolate()->factory()->heap_number_map(), NULL); |
| 3577 __ j(not_equal, fail); | 3577 __ j(not_equal, fail); |
| 3578 } | 3578 } |
| 3579 // We could be strict about symbol/string here, but as long as | 3579 // We could be strict about symbol/string here, but as long as |
| 3580 // hydrogen doesn't care, the stub doesn't have to care either. | 3580 // hydrogen doesn't care, the stub doesn't have to care either. |
| 3581 __ bind(&ok); | 3581 __ bind(&ok); |
| 3582 } | 3582 } |
| 3583 | 3583 |
| 3584 | 3584 |
| (...skipping 2182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5767 __ bind(&done); | 5767 __ bind(&done); |
| 5768 __ movq(rax, rdx); | 5768 __ movq(rax, rdx); |
| 5769 } | 5769 } |
| 5770 __ ret(0); | 5770 __ ret(0); |
| 5771 | 5771 |
| 5772 __ bind(&miss); | 5772 __ bind(&miss); |
| 5773 GenerateMiss(masm); | 5773 GenerateMiss(masm); |
| 5774 } | 5774 } |
| 5775 | 5775 |
| 5776 | 5776 |
| 5777 void ICCompareStub::GenerateHeapNumbers(MacroAssembler* masm) { | 5777 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { |
| 5778 ASSERT(state_ == CompareIC::HEAP_NUMBER); | 5778 ASSERT(state_ == CompareIC::NUMBER); |
| 5779 | 5779 |
| 5780 Label generic_stub; | 5780 Label generic_stub; |
| 5781 Label unordered, maybe_undefined1, maybe_undefined2; | 5781 Label unordered, maybe_undefined1, maybe_undefined2; |
| 5782 Label miss; | 5782 Label miss; |
| 5783 | 5783 |
| 5784 if (left_ == CompareIC::SMI) { | 5784 if (left_ == CompareIC::SMI) { |
| 5785 __ JumpIfNotSmi(rdx, &miss); | 5785 __ JumpIfNotSmi(rdx, &miss); |
| 5786 } | 5786 } |
| 5787 if (right_ == CompareIC::SMI) { | 5787 if (right_ == CompareIC::SMI) { |
| 5788 __ JumpIfNotSmi(rax, &miss); | 5788 __ JumpIfNotSmi(rax, &miss); |
| (...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6712 #endif | 6712 #endif |
| 6713 | 6713 |
| 6714 __ Ret(); | 6714 __ Ret(); |
| 6715 } | 6715 } |
| 6716 | 6716 |
| 6717 #undef __ | 6717 #undef __ |
| 6718 | 6718 |
| 6719 } } // namespace v8::internal | 6719 } } // namespace v8::internal |
| 6720 | 6720 |
| 6721 #endif // V8_TARGET_ARCH_X64 | 6721 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |