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 |