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

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

Issue 648613006: Implement bigint absAdd, absSub, mulAdd, sqrAdd, estQuotientDigit intrinsics, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | runtime/vm/intrinsifier_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 647
648 __ Bind(&overflow); 648 __ Bind(&overflow);
649 // Arguments are Smi but the shift produced an overflow to Mint. 649 // Arguments are Smi but the shift produced an overflow to Mint.
650 __ cmpl(EBX, Immediate(0)); 650 __ cmpl(EBX, Immediate(0));
651 // TODO(srdjan): Implement negative values, for now fall through. 651 // TODO(srdjan): Implement negative values, for now fall through.
652 __ j(LESS, &fall_through, Assembler::kNearJump); 652 __ j(LESS, &fall_through, Assembler::kNearJump);
653 __ SmiUntag(EBX); 653 __ SmiUntag(EBX);
654 __ movl(EAX, EBX); 654 __ movl(EAX, EBX);
655 __ shll(EBX, ECX); 655 __ shll(EBX, ECX);
656 __ xorl(EDI, EDI); 656 __ xorl(EDI, EDI);
657 __ shld(EDI, EAX); 657 __ shldl(EDI, EAX);
658 // Result in EDI (high) and EBX (low). 658 // Result in EDI (high) and EBX (low).
659 const Class& mint_class = Class::Handle( 659 const Class& mint_class = Class::Handle(
660 Isolate::Current()->object_store()->mint_class()); 660 Isolate::Current()->object_store()->mint_class());
661 __ TryAllocate(mint_class, 661 __ TryAllocate(mint_class,
662 &fall_through, 662 &fall_through,
663 Assembler::kNearJump, 663 Assembler::kNearJump,
664 EAX, // Result register. 664 EAX, // Result register.
665 kNoRegister); 665 kNoRegister);
666 // EBX and EDI are not objects but integer values. 666 // EBX and EDI are not objects but integer values.
667 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX); 667 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX);
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits 930 __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits
931 931
932 // Precompute 'used - a_used' now so that carry flag is not lost later. 932 // Precompute 'used - a_used' now so that carry flag is not lost later.
933 __ subl(EAX, ECX); 933 __ subl(EAX, ECX);
934 __ incl(EAX); // To account for the extra test between loops. 934 __ incl(EAX); // To account for the extra test between loops.
935 __ pushl(EAX); 935 __ pushl(EAX);
936 936
937 __ xorl(EDX, EDX); // EDX = 0, carry flag = 0. 937 __ xorl(EDX, EDX); // EDX = 0, carry flag = 0.
938 Label add_loop; 938 Label add_loop;
939 __ Bind(&add_loop); 939 __ Bind(&add_loop);
940 // Loop a_used times, ECX = a_used, ECX > 0.
940 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset())); 941 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset()));
941 __ adcl(EAX, FieldAddress(ESI, EDX, TIMES_4, TypedData::data_offset())); 942 __ adcl(EAX, FieldAddress(ESI, EDX, TIMES_4, TypedData::data_offset()));
942 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); 943 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
943 __ incl(EDX); // Does not affect carry flag. 944 __ incl(EDX); // Does not affect carry flag.
944 __ decl(ECX); // Does not affect carry flag. 945 __ decl(ECX); // Does not affect carry flag.
945 __ j(NOT_ZERO, &add_loop, Assembler::kNearJump); 946 __ j(NOT_ZERO, &add_loop, Assembler::kNearJump);
946 947
947 Label last_carry; 948 Label last_carry;
948 __ popl(ECX); 949 __ popl(ECX);
949 __ decl(ECX); // Does not affect carry flag. 950 __ decl(ECX); // Does not affect carry flag.
950 __ j(ZERO, &last_carry, Assembler::kNearJump); 951 __ j(ZERO, &last_carry, Assembler::kNearJump); // If used - a_used == 0.
951 952
952 Label carry_loop; 953 Label carry_loop;
953 __ Bind(&carry_loop); 954 __ Bind(&carry_loop);
955 // Loop used - a_used times, ECX = used - a_used, ECX > 0.
954 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset())); 956 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset()));
955 __ adcl(EAX, Immediate(0)); 957 __ adcl(EAX, Immediate(0));
956 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); 958 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
957 __ incl(EDX); // Does not affect carry flag. 959 __ incl(EDX); // Does not affect carry flag.
958 __ decl(ECX); // Does not affect carry flag. 960 __ decl(ECX); // Does not affect carry flag.
959 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump); 961 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
960 962
961 __ Bind(&last_carry); 963 __ Bind(&last_carry);
962 __ movl(EAX, Immediate(0)); 964 __ movl(EAX, Immediate(0));
963 __ adcl(EAX, Immediate(0)); 965 __ adcl(EAX, Immediate(0));
(...skipping 24 matching lines...) Expand all
988 __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits 990 __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits
989 991
990 // Precompute 'used - a_used' now so that carry flag is not lost later. 992 // Precompute 'used - a_used' now so that carry flag is not lost later.
991 __ subl(EAX, ECX); 993 __ subl(EAX, ECX);
992 __ incl(EAX); // To account for the extra test between loops. 994 __ incl(EAX); // To account for the extra test between loops.
993 __ pushl(EAX); 995 __ pushl(EAX);
994 996
995 __ xorl(EDX, EDX); // EDX = 0, carry flag = 0. 997 __ xorl(EDX, EDX); // EDX = 0, carry flag = 0.
996 Label sub_loop; 998 Label sub_loop;
997 __ Bind(&sub_loop); 999 __ Bind(&sub_loop);
1000 // Loop a_used times, ECX = a_used, ECX > 0.
998 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset())); 1001 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset()));
999 __ sbbl(EAX, FieldAddress(ESI, EDX, TIMES_4, TypedData::data_offset())); 1002 __ sbbl(EAX, FieldAddress(ESI, EDX, TIMES_4, TypedData::data_offset()));
1000 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); 1003 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
1001 __ incl(EDX); // Does not affect carry flag. 1004 __ incl(EDX); // Does not affect carry flag.
1002 __ decl(ECX); // Does not affect carry flag. 1005 __ decl(ECX); // Does not affect carry flag.
1003 __ j(NOT_ZERO, &sub_loop, Assembler::kNearJump); 1006 __ j(NOT_ZERO, &sub_loop, Assembler::kNearJump);
1004 1007
1005 Label done; 1008 Label done;
1006 __ popl(ECX); 1009 __ popl(ECX);
1007 __ decl(ECX); // Does not affect carry flag. 1010 __ decl(ECX); // Does not affect carry flag.
1008 __ j(ZERO, &done, Assembler::kNearJump); 1011 __ j(ZERO, &done, Assembler::kNearJump); // If used - a_used == 0.
1009 1012
1010 Label carry_loop; 1013 Label carry_loop;
1011 __ Bind(&carry_loop); 1014 __ Bind(&carry_loop);
1015 // Loop used - a_used times, ECX = used - a_used, ECX > 0.
1012 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset())); 1016 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset()));
1013 __ sbbl(EAX, Immediate(0)); 1017 __ sbbl(EAX, Immediate(0));
1014 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); 1018 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
1015 __ incl(EDX); // Does not affect carry flag. 1019 __ incl(EDX); // Does not affect carry flag.
1016 __ decl(ECX); // Does not affect carry flag. 1020 __ decl(ECX); // Does not affect carry flag.
1017 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump); 1021 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
1018 1022
1019 __ Bind(&done); 1023 __ Bind(&done);
1020 // Restore CTX and return. 1024 // Restore CTX and return.
1021 __ popl(CTX); 1025 __ popl(CTX);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 __ Bind(&muladd_loop); 1093 __ Bind(&muladd_loop);
1090 // x: EBX 1094 // x: EBX
1091 // mip: EDI 1095 // mip: EDI
1092 // ajp: ESI 1096 // ajp: ESI
1093 // c: ECX 1097 // c: ECX
1094 // t: EDX:EAX (not live at loop entry) 1098 // t: EDX:EAX (not live at loop entry)
1095 // n: ESP[0] 1099 // n: ESP[0]
1096 1100
1097 // uint32_t mi = *mip++ 1101 // uint32_t mi = *mip++
1098 __ movl(EAX, Address(EDI, 0)); 1102 __ movl(EAX, Address(EDI, 0));
1099 __ addl(EDI, Immediate(kWordSize)); 1103 __ addl(EDI, Immediate(Bigint::kBytesPerDigit));
1100 1104
1101 // uint64_t t = x*mi 1105 // uint64_t t = x*mi
1102 __ mull(EBX); // t = EDX:EAX = EAX * EBX 1106 __ mull(EBX); // t = EDX:EAX = EAX * EBX
1103 __ addl(EAX, ECX); // t += c 1107 __ addl(EAX, ECX); // t += c
1104 __ adcl(EDX, Immediate(0)); 1108 __ adcl(EDX, Immediate(0));
1105 1109
1106 // uint32_t aj = *ajp; t += aj 1110 // uint32_t aj = *ajp; t += aj
1107 __ addl(EAX, Address(ESI, 0)); 1111 __ addl(EAX, Address(ESI, 0));
1108 __ adcl(EDX, Immediate(0)); 1112 __ adcl(EDX, Immediate(0));
1109 1113
1110 // *ajp++ = low32(t) 1114 // *ajp++ = low32(t)
1111 __ movl(Address(ESI, 0), EAX); 1115 __ movl(Address(ESI, 0), EAX);
1112 __ addl(ESI, Immediate(kWordSize)); 1116 __ addl(ESI, Immediate(Bigint::kBytesPerDigit));
1113 1117
1114 // c = high32(t) 1118 // c = high32(t)
1115 __ movl(ECX, EDX); 1119 __ movl(ECX, EDX);
1116 1120
1117 // while (--n > 0) 1121 // while (--n > 0)
1118 __ decl(n_addr); // --n 1122 __ decl(n_addr); // --n
1119 __ j(NOT_ZERO, &muladd_loop, Assembler::kNearJump); 1123 __ j(NOT_ZERO, &muladd_loop, Assembler::kNearJump);
1120 1124
1121 Label done; 1125 Label done;
1122 __ testl(ECX, ECX); 1126 __ testl(ECX, ECX);
1123 __ j(ZERO, &done); 1127 __ j(ZERO, &done, Assembler::kNearJump);
1124 1128
1125 // *ajp += c 1129 // *ajp += c
1126 __ addl(Address(ESI, 0), ECX); 1130 __ addl(Address(ESI, 0), ECX);
1127 __ j(NOT_CARRY, &done, Assembler::kNearJump); 1131 __ j(NOT_CARRY, &done, Assembler::kNearJump);
1128 1132
1129 Label propagate_carry_loop; 1133 Label propagate_carry_loop;
1130 __ Bind(&propagate_carry_loop); 1134 __ Bind(&propagate_carry_loop);
1131 __ addl(ESI, Immediate(kWordSize)); 1135 __ addl(ESI, Immediate(Bigint::kBytesPerDigit));
1132 __ incl(Address(ESI, 0)); // c == 0 or 1 1136 __ incl(Address(ESI, 0)); // c == 0 or 1
1133 __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump); 1137 __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump);
1134 1138
1135 __ Bind(&done); 1139 __ Bind(&done);
1136 __ Drop(1); // n 1140 __ Drop(1); // n
1137 // Restore CTX and return. 1141 // Restore CTX and return.
1138 __ popl(CTX); 1142 __ popl(CTX);
1139 1143
1140 __ Bind(&no_op); 1144 __ Bind(&no_op);
1141 // Returning Object::null() is not required, since this method is private. 1145 // Returning Object::null() is not required, since this method is private.
(...skipping 29 matching lines...) Expand all
1171 1175
1172 // EDI = xip = &x_digits[i >> 1] 1176 // EDI = xip = &x_digits[i >> 1]
1173 __ movl(EDI, Address(ESP, 4 * kWordSize)); // x_digits 1177 __ movl(EDI, Address(ESP, 4 * kWordSize)); // x_digits
1174 __ movl(EAX, Address(ESP, 3 * kWordSize)); // i is Smi 1178 __ movl(EAX, Address(ESP, 3 * kWordSize)); // i is Smi
1175 __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset())); 1179 __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset()));
1176 1180
1177 // EBX = x = *xip++, return if x == 0 1181 // EBX = x = *xip++, return if x == 0
1178 Label x_zero; 1182 Label x_zero;
1179 __ movl(EBX, Address(EDI, 0)); 1183 __ movl(EBX, Address(EDI, 0));
1180 __ cmpl(EBX, Immediate(0)); 1184 __ cmpl(EBX, Immediate(0));
1181 __ j(EQUAL, &x_zero); 1185 __ j(EQUAL, &x_zero, Assembler::kNearJump);
1182 __ addl(EDI, Immediate(kWordSize)); 1186 __ addl(EDI, Immediate(Bigint::kBytesPerDigit));
1183 1187
1184 // Preserve CTX to free ESI. 1188 // Preserve CTX to free ESI.
1185 __ pushl(CTX); 1189 __ pushl(CTX);
1186 ASSERT(CTX == ESI); 1190 ASSERT(CTX == ESI);
1187 1191
1188 // ESI = ajp = &a_digits[i] 1192 // ESI = ajp = &a_digits[i]
1189 __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits 1193 __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits
1190 __ leal(ESI, FieldAddress(ESI, EAX, TIMES_4, TypedData::data_offset())); 1194 __ leal(ESI, FieldAddress(ESI, EAX, TIMES_4, TypedData::data_offset()));
1191 1195
1192 // EDX:EAX = t = x*x + *ajp 1196 // EDX:EAX = t = x*x + *ajp
1193 __ movl(EAX, EBX); 1197 __ movl(EAX, EBX);
1194 __ mull(EBX); 1198 __ mull(EBX);
1195 __ addl(EAX, Address(ESI, 0)); 1199 __ addl(EAX, Address(ESI, 0));
1196 __ adcl(EDX, Immediate(0)); 1200 __ adcl(EDX, Immediate(0));
1197 1201
1198 // *ajp++ = low32(t) 1202 // *ajp++ = low32(t)
1199 __ movl(Address(ESI, 0), EAX); 1203 __ movl(Address(ESI, 0), EAX);
1200 __ addl(ESI, Immediate(kWordSize)); 1204 __ addl(ESI, Immediate(Bigint::kBytesPerDigit));
1201 1205
1202 // int n = used - i - 1 1206 // int n = used - i - 1
1203 __ movl(EAX, Address(ESP, 2 * kWordSize)); // used is Smi 1207 __ movl(EAX, Address(ESP, 2 * kWordSize)); // used is Smi
1204 __ subl(EAX, Address(ESP, 4 * kWordSize)); // i is Smi 1208 __ subl(EAX, Address(ESP, 4 * kWordSize)); // i is Smi
1205 __ SmiUntag(EAX); 1209 __ SmiUntag(EAX);
1206 __ decl(EAX); 1210 __ decl(EAX);
1207 __ pushl(EAX); // Save n on stack. 1211 __ pushl(EAX); // Save n on stack.
1208 1212
1209 // uint64_t c = high32(t) 1213 // uint64_t c = high32(t)
1210 __ pushl(Immediate(0)); // push high32(c) == 0 1214 __ pushl(Immediate(0)); // push high32(c) == 0
1211 __ pushl(EDX); // push low32(c) == high32(t) 1215 __ pushl(EDX); // push low32(c) == high32(t)
1212 1216
1213 Address n_addr = Address(ESP, 2 * kWordSize); 1217 Address n_addr = Address(ESP, 2 * kWordSize);
1214 Address ch_addr = Address(ESP, 1 * kWordSize); 1218 Address ch_addr = Address(ESP, 1 * kWordSize);
1215 Address cl_addr = Address(ESP, 0 * kWordSize); 1219 Address cl_addr = Address(ESP, 0 * kWordSize);
1216 1220
1217 Label loop, done; 1221 Label loop, done;
1218 __ Bind(&loop); 1222 __ Bind(&loop);
1219 // x: EBX 1223 // x: EBX
1220 // xip: EDI 1224 // xip: EDI
1221 // ajp: ESI 1225 // ajp: ESI
1222 // c: ESP[1]:ESP[0] 1226 // c: ESP[1]:ESP[0]
1223 // t: ECX:EDX:EAX (not live at loop entry) 1227 // t: ECX:EDX:EAX (not live at loop entry)
1224 // n: ESP[2] 1228 // n: ESP[2]
1225 1229
1226 // while (--n >= 0) 1230 // while (--n >= 0)
1227 __ decl(Address(ESP, 2 * kWordSize)); // --n 1231 __ decl(Address(ESP, 2 * kWordSize)); // --n
1228 __ j(NEGATIVE, &done); 1232 __ j(NEGATIVE, &done, Assembler::kNearJump);
1229 1233
1230 // uint32_t xi = *xip++ 1234 // uint32_t xi = *xip++
1231 __ movl(EAX, Address(EDI, 0)); 1235 __ movl(EAX, Address(EDI, 0));
1232 __ addl(EDI, Immediate(kWordSize)); 1236 __ addl(EDI, Immediate(Bigint::kBytesPerDigit));
1233 1237
1234 // uint96_t t = ECX:EDX:EAX = 2*x*xi + aj + c 1238 // uint96_t t = ECX:EDX:EAX = 2*x*xi + aj + c
1235 __ mull(EBX); // EDX:EAX = EAX * EBX 1239 __ mull(EBX); // EDX:EAX = EAX * EBX
1236 __ xorl(ECX, ECX); // ECX = 0 1240 __ xorl(ECX, ECX); // ECX = 0
1237 __ shld(ECX, EDX, Immediate(1)); 1241 __ shldl(ECX, EDX, Immediate(1));
1238 __ shld(EDX, EAX, Immediate(1)); 1242 __ shldl(EDX, EAX, Immediate(1));
1239 __ shll(EAX, Immediate(1)); // ECX:EDX:EAX <<= 1 1243 __ shll(EAX, Immediate(1)); // ECX:EDX:EAX <<= 1
1240 __ addl(EAX, Address(ESI, 0)); // t += aj 1244 __ addl(EAX, Address(ESI, 0)); // t += aj
1241 __ adcl(EDX, Immediate(0)); 1245 __ adcl(EDX, Immediate(0));
1242 __ adcl(ECX, Immediate(0)); 1246 __ adcl(ECX, Immediate(0));
1243 __ addl(EAX, cl_addr); // t += low32(c) 1247 __ addl(EAX, cl_addr); // t += low32(c)
1244 __ adcl(EDX, ch_addr); // t += high32(c) << 32 1248 __ adcl(EDX, ch_addr); // t += high32(c) << 32
1245 __ adcl(ECX, Immediate(0)); 1249 __ adcl(ECX, Immediate(0));
1246 1250
1247 // *ajp++ = low32(t) 1251 // *ajp++ = low32(t)
1248 __ movl(Address(ESI, 0), EAX); 1252 __ movl(Address(ESI, 0), EAX);
1249 __ addl(ESI, Immediate(kWordSize)); 1253 __ addl(ESI, Immediate(Bigint::kBytesPerDigit));
1250 1254
1251 // c = high64(t) 1255 // c = high64(t)
1252 __ movl(cl_addr, EDX); 1256 __ movl(cl_addr, EDX);
1253 __ movl(ch_addr, ECX); 1257 __ movl(ch_addr, ECX);
1254 1258
1255 __ jmp(&loop, Assembler::kNearJump); 1259 __ jmp(&loop, Assembler::kNearJump);
1256 1260
1257 __ Bind(&done); 1261 __ Bind(&done);
1258 // uint64_t t = aj + c 1262 // uint64_t t = aj + c
1259 __ movl(EAX, cl_addr); // t = c 1263 __ movl(EAX, cl_addr); // t = c
1260 __ movl(EDX, ch_addr); 1264 __ movl(EDX, ch_addr);
1261 __ addl(EAX, Address(ESI, 0)); // t += *ajp 1265 __ addl(EAX, Address(ESI, 0)); // t += *ajp
1262 __ adcl(EDX, Immediate(0)); 1266 __ adcl(EDX, Immediate(0));
1263 1267
1264 // *ajp++ = low32(t) 1268 // *ajp++ = low32(t)
1265 // *ajp = high32(t) 1269 // *ajp = high32(t)
1266 __ movl(Address(ESI, 0), EAX); 1270 __ movl(Address(ESI, 0), EAX);
1267 __ movl(Address(ESI, kWordSize), EDX); 1271 __ movl(Address(ESI, Bigint::kBytesPerDigit), EDX);
1268 1272
1269 // Restore CTX and return. 1273 // Restore CTX and return.
1270 __ Drop(3); 1274 __ Drop(3);
1271 __ popl(CTX); 1275 __ popl(CTX);
1272 __ Bind(&x_zero); 1276 __ Bind(&x_zero);
1273 // Returning Object::null() is not required, since this method is private. 1277 // Returning Object::null() is not required, since this method is private.
1274 __ ret(); 1278 __ ret();
1275 } 1279 }
1276 1280
1277 1281
(...skipping 29 matching lines...) Expand all
1307 1311
1308 // EAX = qd = DIGIT_MASK = -1 1312 // EAX = qd = DIGIT_MASK = -1
1309 __ movl(EAX, Immediate(-1)); 1313 __ movl(EAX, Immediate(-1));
1310 1314
1311 // Return qd if dh == yt 1315 // Return qd if dh == yt
1312 Label return_qd; 1316 Label return_qd;
1313 __ cmpl(EDX, ECX); 1317 __ cmpl(EDX, ECX);
1314 __ j(EQUAL, &return_qd, Assembler::kNearJump); 1318 __ j(EQUAL, &return_qd, Assembler::kNearJump);
1315 1319
1316 // EAX = dl = dp[-1] 1320 // EAX = dl = dp[-1]
1317 __ movl(EAX, Address(EBX, -kWordSize)); 1321 __ movl(EAX, Address(EBX, -Bigint::kBytesPerDigit));
1318 1322
1319 // EAX = qd = dh:dl / yt = EDX:EAX / ECX 1323 // EAX = qd = dh:dl / yt = EDX:EAX / ECX
1320 __ divl(ECX); 1324 __ divl(ECX);
1321 1325
1322 __ Bind(&return_qd); 1326 __ Bind(&return_qd);
1323 // args[1] = qd 1327 // args[1] = qd
1324 __ movl(FieldAddress(EDI, TypedData::data_offset() + kWordSize), EAX); 1328 __ movl(FieldAddress(EDI, TypedData::data_offset() + Bigint::kBytesPerDigit),
1329 EAX);
1325 1330
1326 // Returning Object::null() is not required, since this method is private. 1331 // Returning Object::null() is not required, since this method is private.
1327 __ ret(); 1332 __ ret();
1328 } 1333 }
1329 1334
1330 1335
1331 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) { 1336 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
1332 // Pseudo code: 1337 // Pseudo code:
1333 // static void _mulMod(Uint32List args, Uint32List digits, int i) { 1338 // static void _mulMod(Uint32List args, Uint32List digits, int i) {
1334 // uint32_t rho = args[_RHO]; // _RHO == 0. 1339 // uint32_t rho = args[_RHO]; // _RHO == 0.
(...skipping 10 matching lines...) Expand all
1345 1350
1346 // EAX = digits[i >> 1] 1351 // EAX = digits[i >> 1]
1347 __ movl(EBX, Address(ESP, 2 * kWordSize)); // digits 1352 __ movl(EBX, Address(ESP, 2 * kWordSize)); // digits
1348 __ movl(EAX, Address(ESP, 1 * kWordSize)); // i is Smi 1353 __ movl(EAX, Address(ESP, 1 * kWordSize)); // i is Smi
1349 __ movl(EAX, FieldAddress(EBX, EAX, TIMES_2, TypedData::data_offset())); 1354 __ movl(EAX, FieldAddress(EBX, EAX, TIMES_2, TypedData::data_offset()));
1350 1355
1351 // EDX:EAX = t = rho*d 1356 // EDX:EAX = t = rho*d
1352 __ mull(ECX); 1357 __ mull(ECX);
1353 1358
1354 // args[1] = t mod DIGIT_BASE = low32(t) 1359 // args[1] = t mod DIGIT_BASE = low32(t)
1355 __ movl(FieldAddress(EDI, TypedData::data_offset() + kWordSize), EAX); 1360 __ movl(FieldAddress(EDI, TypedData::data_offset() + Bigint::kBytesPerDigit),
1361 EAX);
1356 1362
1357 // Returning Object::null() is not required, since this method is private. 1363 // Returning Object::null() is not required, since this method is private.
1358 __ ret(); 1364 __ ret();
1359 } 1365 }
1360 1366
1361 1367
1362 // Check if the last argument is a double, jump to label 'is_smi' if smi 1368 // Check if the last argument is a double, jump to label 'is_smi' if smi
1363 // (easy to convert to double), otherwise jump to label 'not_double_smi', 1369 // (easy to convert to double), otherwise jump to label 'not_double_smi',
1364 // Returns the last argument in EAX. 1370 // Returns the last argument in EAX.
1365 static void TestLastArgumentIsDouble(Assembler* assembler, 1371 static void TestLastArgumentIsDouble(Assembler* assembler,
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after
2087 Isolate::current_tag_offset()); 2093 Isolate::current_tag_offset());
2088 // Set return value to Isolate::current_tag_. 2094 // Set return value to Isolate::current_tag_.
2089 __ movl(EAX, current_tag_addr); 2095 __ movl(EAX, current_tag_addr);
2090 __ ret(); 2096 __ ret();
2091 } 2097 }
2092 2098
2093 #undef __ 2099 #undef __
2094 } // namespace dart 2100 } // namespace dart
2095 2101
2096 #endif // defined TARGET_ARCH_IA32 2102 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | runtime/vm/intrinsifier_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698