Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: runtime/vm/intrinsifier_ia32.cc

Issue 1156593002: Cache current thread in a reserved register and use it in LoadIsolate (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address review comments. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698