| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
| 9 | 9 |
| 10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 | 29 |
| 30 void Intrinsifier::Array_getLength(Assembler* assembler) { | 30 void Intrinsifier::Array_getLength(Assembler* assembler) { |
| 31 __ movq(RAX, Address(RSP, + 1 * kWordSize)); | 31 __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
| 32 __ movq(RAX, FieldAddress(RAX, Array::length_offset())); | 32 __ movq(RAX, FieldAddress(RAX, Array::length_offset())); |
| 33 __ ret(); | 33 __ ret(); |
| 34 } | 34 } |
| 35 | 35 |
| 36 | 36 |
| 37 void Intrinsifier::ImmutableList_getLength(Assembler* assembler) { | 37 void Intrinsifier::ImmutableList_getLength(Assembler* assembler) { |
| 38 return Array_getLength(assembler); | 38 Array_getLength(assembler); |
| 39 } | 39 } |
| 40 | 40 |
| 41 | 41 |
| 42 void Intrinsifier::Array_getIndexed(Assembler* assembler) { | 42 void Intrinsifier::Array_getIndexed(Assembler* assembler) { |
| 43 Label fall_through; | 43 Label fall_through; |
| 44 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. | 44 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. |
| 45 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. | 45 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. |
| 46 __ testq(RCX, Immediate(kSmiTagMask)); | 46 __ testq(RCX, Immediate(kSmiTagMask)); |
| 47 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 47 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 48 // Range check. | 48 // Range check. |
| 49 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); | 49 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); |
| 50 // Runtime throws exception. | 50 // Runtime throws exception. |
| 51 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 51 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| 52 // Note that RBX is Smi, i.e, times 2. | 52 // Note that RBX is Smi, i.e, times 2. |
| 53 ASSERT(kSmiTagShift == 1); | 53 ASSERT(kSmiTagShift == 1); |
| 54 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset())); | 54 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset())); |
| 55 __ ret(); | 55 __ ret(); |
| 56 __ Bind(&fall_through); | 56 __ Bind(&fall_through); |
| 57 } | 57 } |
| 58 | 58 |
| 59 | 59 |
| 60 void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) { | 60 void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) { |
| 61 return Array_getIndexed(assembler); | 61 Array_getIndexed(assembler); |
| 62 } | 62 } |
| 63 | 63 |
| 64 | 64 |
| 65 void Intrinsifier::Array_setIndexed(Assembler* assembler) { | 65 void Intrinsifier::Array_setIndexed(Assembler* assembler) { |
| 66 if (FLAG_enable_type_checks) { | 66 if (FLAG_enable_type_checks) { |
| 67 return; | 67 return; |
| 68 } | 68 } |
| 69 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. | 69 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. |
| 70 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. | 70 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. |
| 71 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // Array. | 71 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // Array. |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 // RAX contains right argument. | 444 // RAX contains right argument. |
| 445 __ addq(RAX, Address(RSP, + 2 * kWordSize)); | 445 __ addq(RAX, Address(RSP, + 2 * kWordSize)); |
| 446 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); | 446 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); |
| 447 // Result is in RAX. | 447 // Result is in RAX. |
| 448 __ ret(); | 448 __ ret(); |
| 449 __ Bind(&fall_through); | 449 __ Bind(&fall_through); |
| 450 } | 450 } |
| 451 | 451 |
| 452 | 452 |
| 453 void Intrinsifier::Integer_add(Assembler* assembler) { | 453 void Intrinsifier::Integer_add(Assembler* assembler) { |
| 454 return Integer_addFromInteger(assembler); | 454 Integer_addFromInteger(assembler); |
| 455 } | 455 } |
| 456 | 456 |
| 457 | 457 |
| 458 void Intrinsifier::Integer_subFromInteger(Assembler* assembler) { | 458 void Intrinsifier::Integer_subFromInteger(Assembler* assembler) { |
| 459 Label fall_through; | 459 Label fall_through; |
| 460 TestBothArgumentsSmis(assembler, &fall_through); | 460 TestBothArgumentsSmis(assembler, &fall_through); |
| 461 // RAX contains right argument, which is the actual minuend of subtraction. | 461 // RAX contains right argument, which is the actual minuend of subtraction. |
| 462 __ subq(RAX, Address(RSP, + 2 * kWordSize)); | 462 __ subq(RAX, Address(RSP, + 2 * kWordSize)); |
| 463 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); | 463 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); |
| 464 // Result is in RAX. | 464 // Result is in RAX. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 490 __ SmiUntag(RAX); | 490 __ SmiUntag(RAX); |
| 491 __ imulq(RAX, Address(RSP, + 2 * kWordSize)); | 491 __ imulq(RAX, Address(RSP, + 2 * kWordSize)); |
| 492 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); | 492 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); |
| 493 // Result is in RAX. | 493 // Result is in RAX. |
| 494 __ ret(); | 494 __ ret(); |
| 495 __ Bind(&fall_through); | 495 __ Bind(&fall_through); |
| 496 } | 496 } |
| 497 | 497 |
| 498 | 498 |
| 499 void Intrinsifier::Integer_mul(Assembler* assembler) { | 499 void Intrinsifier::Integer_mul(Assembler* assembler) { |
| 500 return Integer_mulFromInteger(assembler); | 500 Integer_mulFromInteger(assembler); |
| 501 } | 501 } |
| 502 | 502 |
| 503 | 503 |
| 504 // Optimizations: | 504 // Optimizations: |
| 505 // - result is 0 if: | 505 // - result is 0 if: |
| 506 // - left is 0 | 506 // - left is 0 |
| 507 // - left equals right | 507 // - left equals right |
| 508 // - result is left if | 508 // - result is left if |
| 509 // - left > 0 && left < right | 509 // - left > 0 && left < right |
| 510 // RAX: Tagged left (dividend). | 510 // RAX: Tagged left (dividend). |
| 511 // RCX: Tagged right (divisor). | 511 // RCX: Tagged right (divisor). |
| 512 // RAX: Untagged result (remainder). | 512 // RAX: Untagged result (remainder). |
| 513 void EmitRemainderOperation(Assembler* assembler) { | 513 static void EmitRemainderOperation(Assembler* assembler) { |
| 514 Label return_zero, try_modulo, not_32bit, done; | 514 Label return_zero, try_modulo, not_32bit, done; |
| 515 // Check for quick zero results. | 515 // Check for quick zero results. |
| 516 __ cmpq(RAX, Immediate(0)); | 516 __ cmpq(RAX, Immediate(0)); |
| 517 __ j(EQUAL, &return_zero, Assembler::kNearJump); | 517 __ j(EQUAL, &return_zero, Assembler::kNearJump); |
| 518 __ cmpq(RAX, RCX); | 518 __ cmpq(RAX, RCX); |
| 519 __ j(EQUAL, &return_zero, Assembler::kNearJump); | 519 __ j(EQUAL, &return_zero, Assembler::kNearJump); |
| 520 | 520 |
| 521 // Check if result equals left. | 521 // Check if result equals left. |
| 522 __ cmpq(RAX, Immediate(0)); | 522 __ cmpq(RAX, Immediate(0)); |
| 523 __ j(LESS, &try_modulo, Assembler::kNearJump); | 523 __ j(LESS, &try_modulo, Assembler::kNearJump); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 TestBothArgumentsSmis(assembler, &fall_through); | 671 TestBothArgumentsSmis(assembler, &fall_through); |
| 672 // RAX is the right argument. | 672 // RAX is the right argument. |
| 673 __ andq(RAX, Address(RSP, + 2 * kWordSize)); | 673 __ andq(RAX, Address(RSP, + 2 * kWordSize)); |
| 674 // Result is in RAX. | 674 // Result is in RAX. |
| 675 __ ret(); | 675 __ ret(); |
| 676 __ Bind(&fall_through); | 676 __ Bind(&fall_through); |
| 677 } | 677 } |
| 678 | 678 |
| 679 | 679 |
| 680 void Intrinsifier::Integer_bitAnd(Assembler* assembler) { | 680 void Intrinsifier::Integer_bitAnd(Assembler* assembler) { |
| 681 return Integer_bitAndFromInteger(assembler); | 681 Integer_bitAndFromInteger(assembler); |
| 682 } | 682 } |
| 683 | 683 |
| 684 | 684 |
| 685 void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) { | 685 void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) { |
| 686 Label fall_through; | 686 Label fall_through; |
| 687 TestBothArgumentsSmis(assembler, &fall_through); | 687 TestBothArgumentsSmis(assembler, &fall_through); |
| 688 // RAX is the right argument. | 688 // RAX is the right argument. |
| 689 __ orq(RAX, Address(RSP, + 2 * kWordSize)); | 689 __ orq(RAX, Address(RSP, + 2 * kWordSize)); |
| 690 // Result is in RAX. | 690 // Result is in RAX. |
| 691 __ ret(); | 691 __ ret(); |
| 692 __ Bind(&fall_through); | 692 __ Bind(&fall_through); |
| 693 } | 693 } |
| 694 | 694 |
| 695 | 695 |
| 696 void Intrinsifier::Integer_bitOr(Assembler* assembler) { | 696 void Intrinsifier::Integer_bitOr(Assembler* assembler) { |
| 697 return Integer_bitOrFromInteger(assembler); | 697 Integer_bitOrFromInteger(assembler); |
| 698 } | 698 } |
| 699 | 699 |
| 700 | 700 |
| 701 void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) { | 701 void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) { |
| 702 Label fall_through; | 702 Label fall_through; |
| 703 TestBothArgumentsSmis(assembler, &fall_through); | 703 TestBothArgumentsSmis(assembler, &fall_through); |
| 704 // RAX is the right argument. | 704 // RAX is the right argument. |
| 705 __ xorq(RAX, Address(RSP, + 2 * kWordSize)); | 705 __ xorq(RAX, Address(RSP, + 2 * kWordSize)); |
| 706 // Result is in RAX. | 706 // Result is in RAX. |
| 707 __ ret(); | 707 __ ret(); |
| 708 __ Bind(&fall_through); | 708 __ Bind(&fall_through); |
| 709 } | 709 } |
| 710 | 710 |
| 711 | 711 |
| 712 void Intrinsifier::Integer_bitXor(Assembler* assembler) { | 712 void Intrinsifier::Integer_bitXor(Assembler* assembler) { |
| 713 return Integer_bitXorFromInteger(assembler); | 713 Integer_bitXorFromInteger(assembler); |
| 714 } | 714 } |
| 715 | 715 |
| 716 | 716 |
| 717 void Intrinsifier::Integer_shl(Assembler* assembler) { | 717 void Intrinsifier::Integer_shl(Assembler* assembler) { |
| 718 ASSERT(kSmiTagShift == 1); | 718 ASSERT(kSmiTagShift == 1); |
| 719 ASSERT(kSmiTag == 0); | 719 ASSERT(kSmiTag == 0); |
| 720 Label fall_through, overflow; | 720 Label fall_through, overflow; |
| 721 TestBothArgumentsSmis(assembler, &fall_through); | 721 TestBothArgumentsSmis(assembler, &fall_through); |
| 722 // Shift value is in RAX. Compare with tagged Smi. | 722 // Shift value is in RAX. Compare with tagged Smi. |
| 723 __ cmpq(RAX, Immediate(Smi::RawValue(Smi::kBits))); | 723 __ cmpq(RAX, Immediate(Smi::RawValue(Smi::kBits))); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 754 __ j(true_condition, &true_label, Assembler::kNearJump); | 754 __ j(true_condition, &true_label, Assembler::kNearJump); |
| 755 __ LoadObject(RAX, Bool::False(), PP); | 755 __ LoadObject(RAX, Bool::False(), PP); |
| 756 __ ret(); | 756 __ ret(); |
| 757 __ Bind(&true_label); | 757 __ Bind(&true_label); |
| 758 __ LoadObject(RAX, Bool::True(), PP); | 758 __ LoadObject(RAX, Bool::True(), PP); |
| 759 __ ret(); | 759 __ ret(); |
| 760 __ Bind(&fall_through); | 760 __ Bind(&fall_through); |
| 761 } | 761 } |
| 762 | 762 |
| 763 | 763 |
| 764 | |
| 765 void Intrinsifier::Integer_lessThan(Assembler* assembler) { | 764 void Intrinsifier::Integer_lessThan(Assembler* assembler) { |
| 766 return CompareIntegers(assembler, LESS); | 765 CompareIntegers(assembler, LESS); |
| 767 } | 766 } |
| 768 | 767 |
| 769 | 768 |
| 770 void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) { | 769 void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) { |
| 771 return CompareIntegers(assembler, LESS); | 770 CompareIntegers(assembler, LESS); |
| 772 } | 771 } |
| 773 | 772 |
| 774 | 773 |
| 775 void Intrinsifier::Integer_greaterThan(Assembler* assembler) { | 774 void Intrinsifier::Integer_greaterThan(Assembler* assembler) { |
| 776 return CompareIntegers(assembler, GREATER); | 775 CompareIntegers(assembler, GREATER); |
| 777 } | 776 } |
| 778 | 777 |
| 779 | 778 |
| 780 void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) { | 779 void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) { |
| 781 return CompareIntegers(assembler, LESS_EQUAL); | 780 CompareIntegers(assembler, LESS_EQUAL); |
| 782 } | 781 } |
| 783 | 782 |
| 784 | 783 |
| 785 void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) { | 784 void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) { |
| 786 return CompareIntegers(assembler, GREATER_EQUAL); | 785 CompareIntegers(assembler, GREATER_EQUAL); |
| 787 } | 786 } |
| 788 | 787 |
| 789 | 788 |
| 790 // This is called for Smi, Mint and Bigint receivers. The right argument | 789 // This is called for Smi, Mint and Bigint receivers. The right argument |
| 791 // can be Smi, Mint, Bigint or double. | 790 // can be Smi, Mint, Bigint or double. |
| 792 void Intrinsifier::Integer_equalToInteger(Assembler* assembler) { | 791 void Intrinsifier::Integer_equalToInteger(Assembler* assembler) { |
| 793 Label fall_through, true_label, check_for_mint; | 792 Label fall_through, true_label, check_for_mint; |
| 794 const intptr_t kReceiverOffset = 2; | 793 const intptr_t kReceiverOffset = 2; |
| 795 const intptr_t kArgumentOffset = 1; | 794 const intptr_t kArgumentOffset = 1; |
| 796 | 795 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 // Smi == Mint -> false. | 835 // Smi == Mint -> false. |
| 837 __ LoadObject(RAX, Bool::False(), PP); | 836 __ LoadObject(RAX, Bool::False(), PP); |
| 838 __ ret(); | 837 __ ret(); |
| 839 // TODO(srdjan): Implement Mint == Mint comparison. | 838 // TODO(srdjan): Implement Mint == Mint comparison. |
| 840 | 839 |
| 841 __ Bind(&fall_through); | 840 __ Bind(&fall_through); |
| 842 } | 841 } |
| 843 | 842 |
| 844 | 843 |
| 845 void Intrinsifier::Integer_equal(Assembler* assembler) { | 844 void Intrinsifier::Integer_equal(Assembler* assembler) { |
| 846 return Integer_equalToInteger(assembler); | 845 Integer_equalToInteger(assembler); |
| 847 } | 846 } |
| 848 | 847 |
| 849 | 848 |
| 850 void Intrinsifier::Integer_sar(Assembler* assembler) { | 849 void Intrinsifier::Integer_sar(Assembler* assembler) { |
| 851 Label fall_through, shift_count_ok; | 850 Label fall_through, shift_count_ok; |
| 852 TestBothArgumentsSmis(assembler, &fall_through); | 851 TestBothArgumentsSmis(assembler, &fall_through); |
| 853 const Immediate& count_limit = Immediate(0x3F); | 852 const Immediate& count_limit = Immediate(0x3F); |
| 854 // Check that the count is not larger than what the hardware can handle. | 853 // Check that the count is not larger than what the hardware can handle. |
| 855 // For shifting right a Smi the result is the same for all numbers | 854 // For shifting right a Smi the result is the same for all numbers |
| 856 // >= count_limit. | 855 // >= count_limit. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 __ ret(); | 924 __ ret(); |
| 926 __ Bind(&is_smi); | 925 __ Bind(&is_smi); |
| 927 __ SmiUntag(RAX); | 926 __ SmiUntag(RAX); |
| 928 __ cvtsi2sd(XMM1, RAX); | 927 __ cvtsi2sd(XMM1, RAX); |
| 929 __ jmp(&double_op); | 928 __ jmp(&double_op); |
| 930 __ Bind(&fall_through); | 929 __ Bind(&fall_through); |
| 931 } | 930 } |
| 932 | 931 |
| 933 | 932 |
| 934 void Intrinsifier::Double_greaterThan(Assembler* assembler) { | 933 void Intrinsifier::Double_greaterThan(Assembler* assembler) { |
| 935 return CompareDoubles(assembler, ABOVE); | 934 CompareDoubles(assembler, ABOVE); |
| 936 } | 935 } |
| 937 | 936 |
| 938 | 937 |
| 939 void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) { | 938 void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) { |
| 940 return CompareDoubles(assembler, ABOVE_EQUAL); | 939 CompareDoubles(assembler, ABOVE_EQUAL); |
| 941 } | 940 } |
| 942 | 941 |
| 943 | 942 |
| 944 void Intrinsifier::Double_lessThan(Assembler* assembler) { | 943 void Intrinsifier::Double_lessThan(Assembler* assembler) { |
| 945 return CompareDoubles(assembler, BELOW); | 944 CompareDoubles(assembler, BELOW); |
| 946 } | 945 } |
| 947 | 946 |
| 948 | 947 |
| 949 void Intrinsifier::Double_equal(Assembler* assembler) { | 948 void Intrinsifier::Double_equal(Assembler* assembler) { |
| 950 return CompareDoubles(assembler, EQUAL); | 949 CompareDoubles(assembler, EQUAL); |
| 951 } | 950 } |
| 952 | 951 |
| 953 | 952 |
| 954 void Intrinsifier::Double_lessEqualThan(Assembler* assembler) { | 953 void Intrinsifier::Double_lessEqualThan(Assembler* assembler) { |
| 955 return CompareDoubles(assembler, BELOW_EQUAL); | 954 CompareDoubles(assembler, BELOW_EQUAL); |
| 956 } | 955 } |
| 957 | 956 |
| 958 | 957 |
| 959 // Expects left argument to be double (receiver). Right argument is unknown. | 958 // Expects left argument to be double (receiver). Right argument is unknown. |
| 960 // Both arguments are on stack. | 959 // Both arguments are on stack. |
| 961 static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { | 960 static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { |
| 962 Label fall_through; | 961 Label fall_through; |
| 963 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through); | 962 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through); |
| 964 // Both arguments are double, right operand is in RAX. | 963 // Both arguments are double, right operand is in RAX. |
| 965 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); | 964 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 979 Assembler::kNearJump, | 978 Assembler::kNearJump, |
| 980 RAX, // Result register. | 979 RAX, // Result register. |
| 981 kNoRegister); // Pool pointer might not be loaded. | 980 kNoRegister); // Pool pointer might not be loaded. |
| 982 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 981 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
| 983 __ ret(); | 982 __ ret(); |
| 984 __ Bind(&fall_through); | 983 __ Bind(&fall_through); |
| 985 } | 984 } |
| 986 | 985 |
| 987 | 986 |
| 988 void Intrinsifier::Double_add(Assembler* assembler) { | 987 void Intrinsifier::Double_add(Assembler* assembler) { |
| 989 return DoubleArithmeticOperations(assembler, Token::kADD); | 988 DoubleArithmeticOperations(assembler, Token::kADD); |
| 990 } | 989 } |
| 991 | 990 |
| 992 | 991 |
| 993 void Intrinsifier::Double_mul(Assembler* assembler) { | 992 void Intrinsifier::Double_mul(Assembler* assembler) { |
| 994 return DoubleArithmeticOperations(assembler, Token::kMUL); | 993 DoubleArithmeticOperations(assembler, Token::kMUL); |
| 995 } | 994 } |
| 996 | 995 |
| 997 | 996 |
| 998 void Intrinsifier::Double_sub(Assembler* assembler) { | 997 void Intrinsifier::Double_sub(Assembler* assembler) { |
| 999 return DoubleArithmeticOperations(assembler, Token::kSUB); | 998 DoubleArithmeticOperations(assembler, Token::kSUB); |
| 1000 } | 999 } |
| 1001 | 1000 |
| 1002 | 1001 |
| 1003 void Intrinsifier::Double_div(Assembler* assembler) { | 1002 void Intrinsifier::Double_div(Assembler* assembler) { |
| 1004 return DoubleArithmeticOperations(assembler, Token::kDIV); | 1003 DoubleArithmeticOperations(assembler, Token::kDIV); |
| 1005 } | 1004 } |
| 1006 | 1005 |
| 1007 | 1006 |
| 1008 void Intrinsifier::Double_mulFromInteger(Assembler* assembler) { | 1007 void Intrinsifier::Double_mulFromInteger(Assembler* assembler) { |
| 1009 Label fall_through; | 1008 Label fall_through; |
| 1010 // Only smis allowed. | 1009 // Only smis allowed. |
| 1011 __ movq(RAX, Address(RSP, + 1 * kWordSize)); | 1010 __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
| 1012 __ testq(RAX, Immediate(kSmiTagMask)); | 1011 __ testq(RAX, Immediate(kSmiTagMask)); |
| 1013 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 1012 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
| 1014 // Is Smi. | 1013 // Is Smi. |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1584 // Set return value to Isolate::current_tag_. | 1583 // Set return value to Isolate::current_tag_. |
| 1585 __ movq(RAX, Address(RBX, Isolate::current_tag_offset())); | 1584 __ movq(RAX, Address(RBX, Isolate::current_tag_offset())); |
| 1586 __ ret(); | 1585 __ ret(); |
| 1587 } | 1586 } |
| 1588 | 1587 |
| 1589 #undef __ | 1588 #undef __ |
| 1590 | 1589 |
| 1591 } // namespace dart | 1590 } // namespace dart |
| 1592 | 1591 |
| 1593 #endif // defined TARGET_ARCH_X64 | 1592 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |