| 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 // The intrinsic code below is executed before a method has built its frame. | 5 // The intrinsic code below is executed before a method has built its frame. |
| 6 // The return address is on the stack and the arguments below it. | 6 // The return address is on the stack and the arguments below it. |
| 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. | 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. |
| 8 // Each intrinsification method returns true if the corresponding | 8 // Each intrinsification method returns true if the corresponding |
| 9 // Dart method was intrinsified. | 9 // Dart method was intrinsified. |
| 10 | 10 |
| (...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 __ bsrl(EAX, EAX); | 807 __ bsrl(EAX, EAX); |
| 808 __ SmiTag(EAX); | 808 __ SmiTag(EAX); |
| 809 __ ret(); | 809 __ ret(); |
| 810 } | 810 } |
| 811 | 811 |
| 812 | 812 |
| 813 void Intrinsifier::Bigint_lsh(Assembler* assembler) { | 813 void Intrinsifier::Bigint_lsh(Assembler* assembler) { |
| 814 // static void _lsh(Uint32List x_digits, int x_used, int n, | 814 // static void _lsh(Uint32List x_digits, int x_used, int n, |
| 815 // Uint32List r_digits) | 815 // Uint32List r_digits) |
| 816 | 816 |
| 817 __ movl(EDI, Address(ESP, 4 * kWordSize)); // x_digits | 817 // Preserve THR to free ESI. |
| 818 __ movl(ECX, Address(ESP, 2 * kWordSize)); // n is Smi | 818 __ pushl(THR); |
| 819 ASSERT(THR == ESI); |
| 820 |
| 821 __ movl(EDI, Address(ESP, 5 * kWordSize)); // x_digits |
| 822 __ movl(ECX, Address(ESP, 3 * kWordSize)); // n is Smi |
| 819 __ SmiUntag(ECX); | 823 __ SmiUntag(ECX); |
| 820 __ movl(EBX, Address(ESP, 1 * kWordSize)); // r_digits | 824 __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits |
| 821 __ movl(ESI, ECX); | 825 __ movl(ESI, ECX); |
| 822 __ sarl(ESI, Immediate(5)); // ESI = n ~/ _DIGIT_BITS. | 826 __ sarl(ESI, Immediate(5)); // ESI = n ~/ _DIGIT_BITS. |
| 823 __ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset())); | 827 __ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset())); |
| 824 __ movl(ESI, Address(ESP, 3 * kWordSize)); // x_used > 0, Smi. | 828 __ movl(ESI, Address(ESP, 4 * kWordSize)); // x_used > 0, Smi. |
| 825 __ SmiUntag(ESI); | 829 __ SmiUntag(ESI); |
| 826 __ decl(ESI); | 830 __ decl(ESI); |
| 827 __ xorl(EAX, EAX); // EAX = 0. | 831 __ xorl(EAX, EAX); // EAX = 0. |
| 828 __ movl(EDX, FieldAddress(EDI, ESI, TIMES_4, TypedData::data_offset())); | 832 __ movl(EDX, FieldAddress(EDI, ESI, TIMES_4, TypedData::data_offset())); |
| 829 __ shldl(EAX, EDX, ECX); | 833 __ shldl(EAX, EDX, ECX); |
| 830 __ movl(Address(EBX, ESI, TIMES_4, Bigint::kBytesPerDigit), EAX); | 834 __ movl(Address(EBX, ESI, TIMES_4, Bigint::kBytesPerDigit), EAX); |
| 831 Label last; | 835 Label last; |
| 832 __ cmpl(ESI, Immediate(0)); | 836 __ cmpl(ESI, Immediate(0)); |
| 833 __ j(EQUAL, &last, Assembler::kNearJump); | 837 __ j(EQUAL, &last, Assembler::kNearJump); |
| 834 Label loop; | 838 Label loop; |
| 835 __ Bind(&loop); | 839 __ Bind(&loop); |
| 836 __ movl(EAX, EDX); | 840 __ movl(EAX, EDX); |
| 837 __ movl(EDX, | 841 __ movl(EDX, |
| 838 FieldAddress(EDI, ESI, TIMES_4, | 842 FieldAddress(EDI, ESI, TIMES_4, |
| 839 TypedData::data_offset() - Bigint::kBytesPerDigit)); | 843 TypedData::data_offset() - Bigint::kBytesPerDigit)); |
| 840 __ shldl(EAX, EDX, ECX); | 844 __ shldl(EAX, EDX, ECX); |
| 841 __ movl(Address(EBX, ESI, TIMES_4, 0), EAX); | 845 __ movl(Address(EBX, ESI, TIMES_4, 0), EAX); |
| 842 __ decl(ESI); | 846 __ decl(ESI); |
| 843 __ j(NOT_ZERO, &loop, Assembler::kNearJump); | 847 __ j(NOT_ZERO, &loop, Assembler::kNearJump); |
| 844 __ Bind(&last); | 848 __ Bind(&last); |
| 845 __ shldl(EDX, ESI, ECX); // ESI == 0. | 849 __ shldl(EDX, ESI, ECX); // ESI == 0. |
| 846 __ movl(Address(EBX, 0), EDX); | 850 __ movl(Address(EBX, 0), EDX); |
| 851 |
| 852 // Restore THR and return. |
| 853 __ popl(THR); |
| 847 // Returning Object::null() is not required, since this method is private. | 854 // Returning Object::null() is not required, since this method is private. |
| 848 __ ret(); | 855 __ ret(); |
| 849 } | 856 } |
| 850 | 857 |
| 851 | 858 |
| 852 void Intrinsifier::Bigint_rsh(Assembler* assembler) { | 859 void Intrinsifier::Bigint_rsh(Assembler* assembler) { |
| 853 // static void _rsh(Uint32List x_digits, int x_used, int n, | 860 // static void _rsh(Uint32List x_digits, int x_used, int n, |
| 854 // Uint32List r_digits) | 861 // Uint32List r_digits) |
| 855 | 862 |
| 856 __ movl(EDI, Address(ESP, 4 * kWordSize)); // x_digits | 863 // Preserve THR to free ESI. |
| 857 __ movl(ECX, Address(ESP, 2 * kWordSize)); // n is Smi | 864 __ pushl(THR); |
| 865 ASSERT(THR == ESI); |
| 866 |
| 867 __ movl(EDI, Address(ESP, 5 * kWordSize)); // x_digits |
| 868 __ movl(ECX, Address(ESP, 3 * kWordSize)); // n is Smi |
| 858 __ SmiUntag(ECX); | 869 __ SmiUntag(ECX); |
| 859 __ movl(EBX, Address(ESP, 1 * kWordSize)); // r_digits | 870 __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits |
| 860 __ movl(EDX, ECX); | 871 __ movl(EDX, ECX); |
| 861 __ sarl(EDX, Immediate(5)); // EDX = n ~/ _DIGIT_BITS. | 872 __ sarl(EDX, Immediate(5)); // EDX = n ~/ _DIGIT_BITS. |
| 862 __ movl(ESI, Address(ESP, 3 * kWordSize)); // x_used > 0, Smi. | 873 __ movl(ESI, Address(ESP, 4 * kWordSize)); // x_used > 0, Smi. |
| 863 __ SmiUntag(ESI); | 874 __ SmiUntag(ESI); |
| 864 __ decl(ESI); | 875 __ decl(ESI); |
| 865 // EDI = &x_digits[x_used - 1]. | 876 // EDI = &x_digits[x_used - 1]. |
| 866 __ leal(EDI, FieldAddress(EDI, ESI, TIMES_4, TypedData::data_offset())); | 877 __ leal(EDI, FieldAddress(EDI, ESI, TIMES_4, TypedData::data_offset())); |
| 867 __ subl(ESI, EDX); | 878 __ subl(ESI, EDX); |
| 868 // EBX = &r_digits[x_used - 1 - (n ~/ 32)]. | 879 // EBX = &r_digits[x_used - 1 - (n ~/ 32)]. |
| 869 __ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset())); | 880 __ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset())); |
| 870 __ negl(ESI); | 881 __ negl(ESI); |
| 871 __ movl(EDX, Address(EDI, ESI, TIMES_4, 0)); | 882 __ movl(EDX, Address(EDI, ESI, TIMES_4, 0)); |
| 872 Label last; | 883 Label last; |
| 873 __ cmpl(ESI, Immediate(0)); | 884 __ cmpl(ESI, Immediate(0)); |
| 874 __ j(EQUAL, &last, Assembler::kNearJump); | 885 __ j(EQUAL, &last, Assembler::kNearJump); |
| 875 Label loop; | 886 Label loop; |
| 876 __ Bind(&loop); | 887 __ Bind(&loop); |
| 877 __ movl(EAX, EDX); | 888 __ movl(EAX, EDX); |
| 878 __ movl(EDX, Address(EDI, ESI, TIMES_4, Bigint::kBytesPerDigit)); | 889 __ movl(EDX, Address(EDI, ESI, TIMES_4, Bigint::kBytesPerDigit)); |
| 879 __ shrdl(EAX, EDX, ECX); | 890 __ shrdl(EAX, EDX, ECX); |
| 880 __ movl(Address(EBX, ESI, TIMES_4, 0), EAX); | 891 __ movl(Address(EBX, ESI, TIMES_4, 0), EAX); |
| 881 __ incl(ESI); | 892 __ incl(ESI); |
| 882 __ j(NOT_ZERO, &loop, Assembler::kNearJump); | 893 __ j(NOT_ZERO, &loop, Assembler::kNearJump); |
| 883 __ Bind(&last); | 894 __ Bind(&last); |
| 884 __ shrdl(EDX, ESI, ECX); // ESI == 0. | 895 __ shrdl(EDX, ESI, ECX); // ESI == 0. |
| 885 __ movl(Address(EBX, 0), EDX); | 896 __ movl(Address(EBX, 0), EDX); |
| 897 |
| 898 // Restore THR and return. |
| 899 __ popl(THR); |
| 886 // Returning Object::null() is not required, since this method is private. | 900 // Returning Object::null() is not required, since this method is private. |
| 887 __ ret(); | 901 __ ret(); |
| 888 } | 902 } |
| 889 | 903 |
| 890 | 904 |
| 891 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { | 905 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { |
| 892 // static void _absAdd(Uint32List digits, int used, | 906 // static void _absAdd(Uint32List digits, int used, |
| 893 // Uint32List a_digits, int a_used, | 907 // Uint32List a_digits, int a_used, |
| 894 // Uint32List r_digits) | 908 // Uint32List r_digits) |
| 895 | 909 |
| 896 __ movl(EDI, Address(ESP, 5 * kWordSize)); // digits | 910 // Preserve THR to free ESI. |
| 897 __ movl(EAX, Address(ESP, 4 * kWordSize)); // used is Smi | 911 __ pushl(THR); |
| 912 ASSERT(THR == ESI); |
| 913 |
| 914 __ movl(EDI, Address(ESP, 6 * kWordSize)); // digits |
| 915 __ movl(EAX, Address(ESP, 5 * kWordSize)); // used is Smi |
| 898 __ SmiUntag(EAX); // used > 0. | 916 __ SmiUntag(EAX); // used > 0. |
| 899 __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits | 917 __ movl(ESI, Address(ESP, 4 * kWordSize)); // a_digits |
| 900 __ movl(ECX, Address(ESP, 2 * kWordSize)); // a_used is Smi | 918 __ movl(ECX, Address(ESP, 3 * kWordSize)); // a_used is Smi |
| 901 __ SmiUntag(ECX); // a_used > 0. | 919 __ SmiUntag(ECX); // a_used > 0. |
| 902 __ movl(EBX, Address(ESP, 1 * kWordSize)); // r_digits | 920 __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits |
| 903 | 921 |
| 904 // Precompute 'used - a_used' now so that carry flag is not lost later. | 922 // Precompute 'used - a_used' now so that carry flag is not lost later. |
| 905 __ subl(EAX, ECX); | 923 __ subl(EAX, ECX); |
| 906 __ incl(EAX); // To account for the extra test between loops. | 924 __ incl(EAX); // To account for the extra test between loops. |
| 907 __ pushl(EAX); | 925 __ pushl(EAX); |
| 908 | 926 |
| 909 __ xorl(EDX, EDX); // EDX = 0, carry flag = 0. | 927 __ xorl(EDX, EDX); // EDX = 0, carry flag = 0. |
| 910 Label add_loop; | 928 Label add_loop; |
| 911 __ Bind(&add_loop); | 929 __ Bind(&add_loop); |
| 912 // Loop a_used times, ECX = a_used, ECX > 0. | 930 // Loop a_used times, ECX = a_used, ECX > 0. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 930 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); | 948 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); |
| 931 __ incl(EDX); // Does not affect carry flag. | 949 __ incl(EDX); // Does not affect carry flag. |
| 932 __ decl(ECX); // Does not affect carry flag. | 950 __ decl(ECX); // Does not affect carry flag. |
| 933 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump); | 951 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump); |
| 934 | 952 |
| 935 __ Bind(&last_carry); | 953 __ Bind(&last_carry); |
| 936 __ movl(EAX, Immediate(0)); | 954 __ movl(EAX, Immediate(0)); |
| 937 __ adcl(EAX, Immediate(0)); | 955 __ adcl(EAX, Immediate(0)); |
| 938 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); | 956 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); |
| 939 | 957 |
| 958 // Restore THR and return. |
| 959 __ popl(THR); |
| 940 // Returning Object::null() is not required, since this method is private. | 960 // Returning Object::null() is not required, since this method is private. |
| 941 __ ret(); | 961 __ ret(); |
| 942 } | 962 } |
| 943 | 963 |
| 944 | 964 |
| 945 void Intrinsifier::Bigint_absSub(Assembler* assembler) { | 965 void Intrinsifier::Bigint_absSub(Assembler* assembler) { |
| 946 // static void _absSub(Uint32List digits, int used, | 966 // static void _absSub(Uint32List digits, int used, |
| 947 // Uint32List a_digits, int a_used, | 967 // Uint32List a_digits, int a_used, |
| 948 // Uint32List r_digits) | 968 // Uint32List r_digits) |
| 949 | 969 |
| 950 __ movl(EDI, Address(ESP, 5 * kWordSize)); // digits | 970 // Preserve THR to free ESI. |
| 951 __ movl(EAX, Address(ESP, 4 * kWordSize)); // used is Smi | 971 __ pushl(THR); |
| 972 ASSERT(THR == ESI); |
| 973 |
| 974 __ movl(EDI, Address(ESP, 6 * kWordSize)); // digits |
| 975 __ movl(EAX, Address(ESP, 5 * kWordSize)); // used is Smi |
| 952 __ SmiUntag(EAX); // used > 0. | 976 __ SmiUntag(EAX); // used > 0. |
| 953 __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits | 977 __ movl(ESI, Address(ESP, 4 * kWordSize)); // a_digits |
| 954 __ movl(ECX, Address(ESP, 2 * kWordSize)); // a_used is Smi | 978 __ movl(ECX, Address(ESP, 3 * kWordSize)); // a_used is Smi |
| 955 __ SmiUntag(ECX); // a_used > 0. | 979 __ SmiUntag(ECX); // a_used > 0. |
| 956 __ movl(EBX, Address(ESP, 1 * kWordSize)); // r_digits | 980 __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits |
| 957 | 981 |
| 958 // Precompute 'used - a_used' now so that carry flag is not lost later. | 982 // Precompute 'used - a_used' now so that carry flag is not lost later. |
| 959 __ subl(EAX, ECX); | 983 __ subl(EAX, ECX); |
| 960 __ incl(EAX); // To account for the extra test between loops. | 984 __ incl(EAX); // To account for the extra test between loops. |
| 961 __ pushl(EAX); | 985 __ pushl(EAX); |
| 962 | 986 |
| 963 __ xorl(EDX, EDX); // EDX = 0, carry flag = 0. | 987 __ xorl(EDX, EDX); // EDX = 0, carry flag = 0. |
| 964 Label sub_loop; | 988 Label sub_loop; |
| 965 __ Bind(&sub_loop); | 989 __ Bind(&sub_loop); |
| 966 // Loop a_used times, ECX = a_used, ECX > 0. | 990 // Loop a_used times, ECX = a_used, ECX > 0. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 980 __ Bind(&carry_loop); | 1004 __ Bind(&carry_loop); |
| 981 // Loop used - a_used times, ECX = used - a_used, ECX > 0. | 1005 // Loop used - a_used times, ECX = used - a_used, ECX > 0. |
| 982 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset())); | 1006 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset())); |
| 983 __ sbbl(EAX, Immediate(0)); | 1007 __ sbbl(EAX, Immediate(0)); |
| 984 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); | 1008 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); |
| 985 __ incl(EDX); // Does not affect carry flag. | 1009 __ incl(EDX); // Does not affect carry flag. |
| 986 __ decl(ECX); // Does not affect carry flag. | 1010 __ decl(ECX); // Does not affect carry flag. |
| 987 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump); | 1011 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump); |
| 988 | 1012 |
| 989 __ Bind(&done); | 1013 __ Bind(&done); |
| 1014 // Restore THR and return. |
| 1015 __ popl(THR); |
| 990 // Returning Object::null() is not required, since this method is private. | 1016 // Returning Object::null() is not required, since this method is private. |
| 991 __ ret(); | 1017 __ ret(); |
| 992 } | 1018 } |
| 993 | 1019 |
| 994 | 1020 |
| 995 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { | 1021 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { |
| 996 // Pseudo code: | 1022 // Pseudo code: |
| 997 // static int _mulAdd(Uint32List x_digits, int xi, | 1023 // static int _mulAdd(Uint32List x_digits, int xi, |
| 998 // Uint32List m_digits, int i, | 1024 // Uint32List m_digits, int i, |
| 999 // Uint32List a_digits, int j, int n) { | 1025 // Uint32List a_digits, int j, int n) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1026 __ movl(EAX, Address(ESP, 6 * kWordSize)); // xi is Smi | 1052 __ movl(EAX, Address(ESP, 6 * kWordSize)); // xi is Smi |
| 1027 __ movl(EBX, FieldAddress(ECX, EAX, TIMES_2, TypedData::data_offset())); | 1053 __ movl(EBX, FieldAddress(ECX, EAX, TIMES_2, TypedData::data_offset())); |
| 1028 __ testl(EBX, EBX); | 1054 __ testl(EBX, EBX); |
| 1029 __ j(ZERO, &no_op, Assembler::kNearJump); | 1055 __ j(ZERO, &no_op, Assembler::kNearJump); |
| 1030 | 1056 |
| 1031 // EDX = SmiUntag(n), no_op if n == 0 | 1057 // EDX = SmiUntag(n), no_op if n == 0 |
| 1032 __ movl(EDX, Address(ESP, 1 * kWordSize)); | 1058 __ movl(EDX, Address(ESP, 1 * kWordSize)); |
| 1033 __ SmiUntag(EDX); | 1059 __ SmiUntag(EDX); |
| 1034 __ j(ZERO, &no_op, Assembler::kNearJump); | 1060 __ j(ZERO, &no_op, Assembler::kNearJump); |
| 1035 | 1061 |
| 1062 // Preserve THR to free ESI. |
| 1063 __ pushl(THR); |
| 1064 ASSERT(THR == ESI); |
| 1065 |
| 1036 // EDI = mip = &m_digits[i >> 1] | 1066 // EDI = mip = &m_digits[i >> 1] |
| 1037 __ movl(EDI, Address(ESP, 5 * kWordSize)); // m_digits | 1067 __ movl(EDI, Address(ESP, 6 * kWordSize)); // m_digits |
| 1038 __ movl(EAX, Address(ESP, 4 * kWordSize)); // i is Smi | 1068 __ movl(EAX, Address(ESP, 5 * kWordSize)); // i is Smi |
| 1039 __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset())); | 1069 __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset())); |
| 1040 | 1070 |
| 1041 // ESI = ajp = &a_digits[j >> 1] | 1071 // ESI = ajp = &a_digits[j >> 1] |
| 1042 __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits | 1072 __ movl(ESI, Address(ESP, 4 * kWordSize)); // a_digits |
| 1043 __ movl(EAX, Address(ESP, 2 * kWordSize)); // j is Smi | 1073 __ movl(EAX, Address(ESP, 3 * kWordSize)); // j is Smi |
| 1044 __ leal(ESI, FieldAddress(ESI, EAX, TIMES_2, TypedData::data_offset())); | 1074 __ leal(ESI, FieldAddress(ESI, EAX, TIMES_2, TypedData::data_offset())); |
| 1045 | 1075 |
| 1046 // Save n | 1076 // Save n |
| 1047 __ pushl(EDX); | 1077 __ pushl(EDX); |
| 1048 Address n_addr = Address(ESP, 0 * kWordSize); | 1078 Address n_addr = Address(ESP, 0 * kWordSize); |
| 1049 | 1079 |
| 1050 // ECX = c = 0 | 1080 // ECX = c = 0 |
| 1051 __ xorl(ECX, ECX); | 1081 __ xorl(ECX, ECX); |
| 1052 | 1082 |
| 1053 Label muladd_loop; | 1083 Label muladd_loop; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 __ j(NOT_CARRY, &done, Assembler::kNearJump); | 1122 __ j(NOT_CARRY, &done, Assembler::kNearJump); |
| 1093 | 1123 |
| 1094 Label propagate_carry_loop; | 1124 Label propagate_carry_loop; |
| 1095 __ Bind(&propagate_carry_loop); | 1125 __ Bind(&propagate_carry_loop); |
| 1096 __ addl(ESI, Immediate(Bigint::kBytesPerDigit)); | 1126 __ addl(ESI, Immediate(Bigint::kBytesPerDigit)); |
| 1097 __ incl(Address(ESI, 0)); // c == 0 or 1 | 1127 __ incl(Address(ESI, 0)); // c == 0 or 1 |
| 1098 __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump); | 1128 __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump); |
| 1099 | 1129 |
| 1100 __ Bind(&done); | 1130 __ Bind(&done); |
| 1101 __ Drop(1); // n | 1131 __ Drop(1); // n |
| 1132 // Restore THR and return. |
| 1133 __ popl(THR); |
| 1102 | 1134 |
| 1103 __ Bind(&no_op); | 1135 __ Bind(&no_op); |
| 1104 __ movl(EAX, Immediate(Smi::RawValue(1))); // One digit processed. | 1136 __ movl(EAX, Immediate(Smi::RawValue(1))); // One digit processed. |
| 1105 __ ret(); | 1137 __ ret(); |
| 1106 } | 1138 } |
| 1107 | 1139 |
| 1108 | 1140 |
| 1109 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) { | 1141 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) { |
| 1110 // Pseudo code: | 1142 // Pseudo code: |
| 1111 // static int _sqrAdd(Uint32List x_digits, int i, | 1143 // static int _sqrAdd(Uint32List x_digits, int i, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1138 __ movl(EAX, Address(ESP, 3 * kWordSize)); // i is Smi | 1170 __ movl(EAX, Address(ESP, 3 * kWordSize)); // i is Smi |
| 1139 __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset())); | 1171 __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset())); |
| 1140 | 1172 |
| 1141 // EBX = x = *xip++, return if x == 0 | 1173 // EBX = x = *xip++, return if x == 0 |
| 1142 Label x_zero; | 1174 Label x_zero; |
| 1143 __ movl(EBX, Address(EDI, 0)); | 1175 __ movl(EBX, Address(EDI, 0)); |
| 1144 __ cmpl(EBX, Immediate(0)); | 1176 __ cmpl(EBX, Immediate(0)); |
| 1145 __ j(EQUAL, &x_zero, Assembler::kNearJump); | 1177 __ j(EQUAL, &x_zero, Assembler::kNearJump); |
| 1146 __ addl(EDI, Immediate(Bigint::kBytesPerDigit)); | 1178 __ addl(EDI, Immediate(Bigint::kBytesPerDigit)); |
| 1147 | 1179 |
| 1180 // Preserve THR to free ESI. |
| 1181 __ pushl(THR); |
| 1182 ASSERT(THR == ESI); |
| 1183 |
| 1148 // ESI = ajp = &a_digits[i] | 1184 // ESI = ajp = &a_digits[i] |
| 1149 __ movl(ESI, Address(ESP, 2 * kWordSize)); // a_digits | 1185 __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits |
| 1150 __ leal(ESI, FieldAddress(ESI, EAX, TIMES_4, TypedData::data_offset())); | 1186 __ leal(ESI, FieldAddress(ESI, EAX, TIMES_4, TypedData::data_offset())); |
| 1151 | 1187 |
| 1152 // EDX:EAX = t = x*x + *ajp | 1188 // EDX:EAX = t = x*x + *ajp |
| 1153 __ movl(EAX, EBX); | 1189 __ movl(EAX, EBX); |
| 1154 __ mull(EBX); | 1190 __ mull(EBX); |
| 1155 __ addl(EAX, Address(ESI, 0)); | 1191 __ addl(EAX, Address(ESI, 0)); |
| 1156 __ adcl(EDX, Immediate(0)); | 1192 __ adcl(EDX, Immediate(0)); |
| 1157 | 1193 |
| 1158 // *ajp++ = low32(t) | 1194 // *ajp++ = low32(t) |
| 1159 __ movl(Address(ESI, 0), EAX); | 1195 __ movl(Address(ESI, 0), EAX); |
| 1160 __ addl(ESI, Immediate(Bigint::kBytesPerDigit)); | 1196 __ addl(ESI, Immediate(Bigint::kBytesPerDigit)); |
| 1161 | 1197 |
| 1162 // int n = used - i - 1 | 1198 // int n = used - i - 1 |
| 1163 __ movl(EAX, Address(ESP, 1 * kWordSize)); // used is Smi | 1199 __ movl(EAX, Address(ESP, 2 * kWordSize)); // used is Smi |
| 1164 __ subl(EAX, Address(ESP, 3 * kWordSize)); // i is Smi | 1200 __ subl(EAX, Address(ESP, 4 * kWordSize)); // i is Smi |
| 1165 __ SmiUntag(EAX); | 1201 __ SmiUntag(EAX); |
| 1166 __ decl(EAX); | 1202 __ decl(EAX); |
| 1167 __ pushl(EAX); // Save n on stack. | 1203 __ pushl(EAX); // Save n on stack. |
| 1168 | 1204 |
| 1169 // uint64_t c = high32(t) | 1205 // uint64_t c = high32(t) |
| 1170 __ pushl(Immediate(0)); // push high32(c) == 0 | 1206 __ pushl(Immediate(0)); // push high32(c) == 0 |
| 1171 __ pushl(EDX); // push low32(c) == high32(t) | 1207 __ pushl(EDX); // push low32(c) == high32(t) |
| 1172 | 1208 |
| 1173 Address n_addr = Address(ESP, 2 * kWordSize); | 1209 Address n_addr = Address(ESP, 2 * kWordSize); |
| 1174 Address ch_addr = Address(ESP, 1 * kWordSize); | 1210 Address ch_addr = Address(ESP, 1 * kWordSize); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1219 __ movl(EAX, cl_addr); // t = c | 1255 __ movl(EAX, cl_addr); // t = c |
| 1220 __ movl(EDX, ch_addr); | 1256 __ movl(EDX, ch_addr); |
| 1221 __ addl(EAX, Address(ESI, 0)); // t += *ajp | 1257 __ addl(EAX, Address(ESI, 0)); // t += *ajp |
| 1222 __ adcl(EDX, Immediate(0)); | 1258 __ adcl(EDX, Immediate(0)); |
| 1223 | 1259 |
| 1224 // *ajp++ = low32(t) | 1260 // *ajp++ = low32(t) |
| 1225 // *ajp = high32(t) | 1261 // *ajp = high32(t) |
| 1226 __ movl(Address(ESI, 0), EAX); | 1262 __ movl(Address(ESI, 0), EAX); |
| 1227 __ movl(Address(ESI, Bigint::kBytesPerDigit), EDX); | 1263 __ movl(Address(ESI, Bigint::kBytesPerDigit), EDX); |
| 1228 | 1264 |
| 1265 // Restore THR and return. |
| 1229 __ Drop(3); | 1266 __ Drop(3); |
| 1267 __ popl(THR); |
| 1230 __ Bind(&x_zero); | 1268 __ Bind(&x_zero); |
| 1231 __ movl(EAX, Immediate(Smi::RawValue(1))); // One digit processed. | 1269 __ movl(EAX, Immediate(Smi::RawValue(1))); // One digit processed. |
| 1232 __ ret(); | 1270 __ ret(); |
| 1233 } | 1271 } |
| 1234 | 1272 |
| 1235 | 1273 |
| 1236 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { | 1274 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { |
| 1237 // Pseudo code: | 1275 // Pseudo code: |
| 1238 // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) { | 1276 // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) { |
| 1239 // uint32_t yt = args[_YT]; // _YT == 1. | 1277 // uint32_t yt = args[_YT]; // _YT == 1. |
| (...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2086 Isolate::current_tag_offset()); | 2124 Isolate::current_tag_offset()); |
| 2087 // Set return value to Isolate::current_tag_. | 2125 // Set return value to Isolate::current_tag_. |
| 2088 __ movl(EAX, current_tag_addr); | 2126 __ movl(EAX, current_tag_addr); |
| 2089 __ ret(); | 2127 __ ret(); |
| 2090 } | 2128 } |
| 2091 | 2129 |
| 2092 #undef __ | 2130 #undef __ |
| 2093 } // namespace dart | 2131 } // namespace dart |
| 2094 | 2132 |
| 2095 #endif // defined TARGET_ARCH_IA32 | 2133 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |