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 |