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

Side by Side Diff: runtime/lib/bigint.dart

Issue 732663003: Process two 32-bit digits as one 64-bit digit in bigint absAdd intrinsic on x64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 1 month 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 | « no previous file | runtime/vm/assembler_x64.h » ('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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 // Copyright 2009 The Go Authors. All rights reserved. 5 // Copyright 2009 The Go Authors. All rights reserved.
6 // Use of this source code is governed by a BSD-style 6 // Use of this source code is governed by a BSD-style
7 // license that can be found in the LICENSE file. 7 // license that can be found in the LICENSE file.
8 8
9 /* 9 /*
10 * Copyright (c) 2003-2005 Tom Wu 10 * Copyright (c) 2003-2005 Tom Wu
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 return -((digits[1] << DIGIT_BITS) | digits[0]); 196 return -((digits[1] << DIGIT_BITS) | digits[0]);
197 } 197 }
198 if (digits[1] >= 0x80000000) return this; 198 if (digits[1] >= 0x80000000) return this;
199 return (digits[1] << DIGIT_BITS) | digits[0]; 199 return (digits[1] << DIGIT_BITS) | digits[0];
200 } 200 }
201 201
202 // Conversion from int to bigint. 202 // Conversion from int to bigint.
203 _Bigint _toBigint() => this; 203 _Bigint _toBigint() => this;
204 204
205 // Make sure at least 'length' _digits are allocated. 205 // Make sure at least 'length' _digits are allocated.
206 // Copy existing _digits if reallocation is necessary. 206 // Copy existing and used _digits if reallocation is necessary.
207 // TODO(regis): Check that we are not preserving _digits unnecessarily. 207 // Avoid preserving _digits unnecessarily by calling this function with a
208 // meaningful _used field.
208 void _ensureLength(int length) { 209 void _ensureLength(int length) {
209 var digits = _digits; 210 var digits = _digits;
210 if (length > 0 && (length > digits.length)) { 211 if (length > digits.length) {
211 var new_digits = new Uint32List(length + EXTRA_DIGITS); 212 var new_digits = new Uint32List(length + EXTRA_DIGITS);
212 for (var i = _used; --i >= 0; ) { 213 _digits = new_digits;
213 new_digits[i] = digits[i]; 214 if (_used > 0) {
215 for (var i = _used + 1; --i >= 0; ) { // Copy leading zero.
zra 2014/11/18 19:04:45 So, every number has a leading zero? Even those wi
regis 2014/11/18 23:19:54 Yes, I figured that the _mulAdd intrinsic (among o
216 new_digits[i] = digits[i];
217 }
214 } 218 }
215 _digits = new_digits;
216 } 219 }
217 } 220 }
218 221
219 // Clamp off excess high _digits. 222 // Clamp off excess high _digits.
220 void _clamp() { 223 void _clamp() {
221 var digits = _digits; 224 var used = _used;
222 while (_used > 0 && digits[_used - 1] == 0) { 225 if (used > 0) {
223 --_used; 226 var digits = _digits;
227 if (digits[used - 1] == 0) {
228 do {
229 --used;
230 } while (used > 0 && digits[used - 1] == 0);
231 _used = used;
232 }
233 digits[used] = 0; // Set leading zero for 64-bit processing.
224 } 234 }
225 } 235 }
226 236
227 // Copy this to r. 237 // Copy this to r.
228 void _copyTo(_Bigint r) { 238 void _copyTo(_Bigint r) {
229 r._ensureLength(_used); 239 var used = _used;
230 var digits = _digits; 240 if (used > 0) {
231 var r_digits = r._digits; 241 r._used = 0; // No digits to preserve.
232 for (var i = _used - 1; i >= 0; --i) { 242 r._ensureLength(used);
233 r_digits[i] = digits[i]; 243 var digits = _digits;
244 var r_digits = r._digits;
245 // Copy leading zero for 64-bit processing.
246 for (var i = used + 1; --i >= 0; ) {
zra 2014/11/18 19:04:45 Would a while loop improve readability here?
regis 2014/11/18 23:19:54 Done.
247 r_digits[i] = digits[i];
248 }
234 } 249 }
235 r._used = _used; 250 r._used = used;
236 r._neg = _neg; 251 r._neg = _neg;
237 } 252 }
238 253
239 // Return the bit length of digit x. 254 // Return the bit length of digit x.
240 int _nbits(int x) { 255 int _nbits(int x) {
241 var r = 1, t; 256 var r = 1, t;
242 if ((t = x >> 16) != 0) { x = t; r += 16; } 257 if ((t = x >> 16) != 0) { x = t; r += 16; }
243 if ((t = x >> 8) != 0) { x = t; r += 8; } 258 if ((t = x >> 8) != 0) { x = t; r += 8; }
244 if ((t = x >> 4) != 0) { x = t; r += 4; } 259 if ((t = x >> 4) != 0) { x = t; r += 4; }
245 if ((t = x >> 2) != 0) { x = t; r += 2; } 260 if ((t = x >> 2) != 0) { x = t; r += 2; }
246 if ((x >> 1) != 0) { r += 1; } 261 if ((x >> 1) != 0) { r += 1; }
247 return r; 262 return r;
248 } 263 }
249 264
250 // r = this << n*DIGIT_BITS. 265 // r = this << n*DIGIT_BITS.
251 void _dlShiftTo(int n, _Bigint r) { 266 void _dlShiftTo(int n, _Bigint r) {
252 var r_used = _used + n; 267 var r_used = _used + n;
253 r._ensureLength(r_used); 268 r._ensureLength(r_used);
254 var digits = _digits; 269 var digits = _digits;
255 var r_digits = r._digits; 270 var r_digits = r._digits;
256 for (var i = _used - 1; i >= 0; --i) { 271 for (var i = _used; --i >= 0; ) {
zra 2014/11/18 19:04:45 Same comment
regis 2014/11/18 23:19:54 Done.
257 r_digits[i + n] = digits[i]; 272 r_digits[i + n] = digits[i];
258 } 273 }
259 for (var i = n - 1; i >= 0; --i) { 274 for (var i = n - 1; i >= 0; --i) {
260 r_digits[i] = 0; 275 r_digits[i] = 0;
261 } 276 }
262 r._used = r_used; 277 r._used = r_used;
263 r._neg = _neg; 278 r._neg = _neg;
279 // Set leading zero for 64-bit processing.
280 if (r_used > 0) {
281 r_digits[r_used] = 0;
282 }
264 } 283 }
265 284
266 // r = this >> n*DIGIT_BITS. 285 // r = this >> n*DIGIT_BITS.
267 void _drShiftTo(int n, _Bigint r) { 286 void _drShiftTo(int n, _Bigint r) {
268 var r_used = _used - n; 287 var r_used = _used - n;
269 if (r_used < 0) { 288 if (r_used < 0) {
270 if (_neg) { 289 if (_neg) {
271 // Set r to -1. 290 // Set r to -1.
291 r._used = 0; // No digits to preserve.
292 r._ensureLength(1);
272 r._neg = true; 293 r._neg = true;
273 r._ensureLength(1);
274 r._used = 1; 294 r._used = 1;
275 r._digits[0] = 1; 295 r._digits[0] = 1;
296 r._digits[1] = 0; // Set leading zero for 64-bit processing.
276 } else { 297 } else {
277 // Set r to 0. 298 // Set r to 0.
278 r._neg = false; 299 r._neg = false;
279 r._used = 0; 300 r._used = 0;
280 } 301 }
281 return; 302 return;
282 } 303 }
283 r._ensureLength(r_used); 304 r._ensureLength(r_used);
284 var digits = _digits; 305 var digits = _digits;
285 var r_digits = r._digits; 306 var r_digits = r._digits;
286 var used = _used; 307 var used = _used;
287 for (var i = n; i < used; ++i) { 308 for (var i = n; i < used; ++i) {
288 r_digits[i - n] = digits[i]; 309 r_digits[i - n] = digits[i];
289 } 310 }
290 r._used = r_used; 311 r._used = r_used;
291 r._neg = _neg; 312 r._neg = _neg;
313 // Set leading zero for 64-bit processing.
314 if (r_used > 0) {
315 r_digits[r_used] = 0;
316 }
292 if (_neg) { 317 if (_neg) {
293 // Round down if any bit was shifted out. 318 // Round down if any bit was shifted out.
294 for (var i = 0; i < n; i++) { 319 for (var i = 0; i < n; i++) {
295 if (digits[i] != 0) { 320 if (digits[i] != 0) {
296 r._subTo(ONE, r); 321 r._subTo(ONE, r);
297 break; 322 break;
298 } 323 }
299 } 324 }
300 } 325 }
301 } 326 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 var bs = n % DIGIT_BITS; 359 var bs = n % DIGIT_BITS;
335 if (bs == 0) { 360 if (bs == 0) {
336 _drShiftTo(ds, r); 361 _drShiftTo(ds, r);
337 return; 362 return;
338 } 363 }
339 var r_used = _used - ds; 364 var r_used = _used - ds;
340 if (r_used <= 0) { 365 if (r_used <= 0) {
341 if (_neg) { 366 if (_neg) {
342 // Set r to -1. 367 // Set r to -1.
343 r._neg = true; 368 r._neg = true;
369 r._used = 0; // No digits to preserve.
344 r._ensureLength(1); 370 r._ensureLength(1);
345 r._used = 1; 371 r._used = 1;
346 r._digits[0] = 1; 372 r._digits[0] = 1;
373 r._digits[1] = 0; // Set leading zero for 64-bit processing.
347 } else { 374 } else {
348 // Set r to 0. 375 // Set r to 0.
349 r._neg = false; 376 r._neg = false;
350 r._used = 0; 377 r._used = 0;
351 } 378 }
352 return; 379 return;
353 } 380 }
354 var cbs = DIGIT_BITS - bs; 381 var cbs = DIGIT_BITS - bs;
355 var bm = (1 << bs) - 1; 382 var bm = (1 << bs) - 1;
356 r._ensureLength(r_used); 383 r._ensureLength(r_used);
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 } else { 887 } else {
861 a_digits[i + used] = c; 888 a_digits[i + used] = c;
862 } 889 }
863 } 890 }
864 891
865 // r = this * a. 892 // r = this * a.
866 void _mulTo(_Bigint a, _Bigint r) { 893 void _mulTo(_Bigint a, _Bigint r) {
867 // TODO(regis): Use karatsuba multiplication when appropriate. 894 // TODO(regis): Use karatsuba multiplication when appropriate.
868 var used = _used; 895 var used = _used;
869 var a_used = a._used; 896 var a_used = a._used;
897 if (used == 0 || a_used == 0) {
898 r._used = 0;
899 r._neg = false;
900 return;
901 }
870 var r_used = used + a_used; 902 var r_used = used + a_used;
871 r._ensureLength(r_used); 903 r._ensureLength(r_used);
872 var digits = _digits; 904 var digits = _digits;
873 var a_digits = a._digits; 905 var a_digits = a._digits;
874 var r_digits = r._digits; 906 var r_digits = r._digits;
875 r._used = r_used; 907 r._used = r_used;
876 var i = r_used; 908 var i = r_used + 1; // Set leading zero for 64-bit processing.
877 while (--i >= 0) { 909 while (--i >= 0) {
878 r_digits[i] = 0; 910 r_digits[i] = 0;
879 } 911 }
880 for (i = 0; i < a_used; ++i) { 912 for (i = 0; i < a_used; ++i) {
881 _mulAdd(a_digits, i, digits, 0, r_digits, i, used); 913 _mulAdd(a_digits, i, digits, 0, r_digits, i, used);
882 } 914 }
883 r._clamp(); 915 r._clamp();
884 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative. 916 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative.
885 } 917 }
886 918
887 // r = this^2, r != this. 919 // r = this^2, r != this.
888 void _sqrTo(_Bigint r) { 920 void _sqrTo(_Bigint r) {
889 var used = _used; 921 var used = _used;
922 if (used == 0) {
923 r._used = 0;
924 r._neg = false;
925 return;
926 }
890 var r_used = 2 * used; 927 var r_used = 2 * used;
891 r._ensureLength(r_used); 928 r._ensureLength(r_used);
892 var digits = _digits; 929 var digits = _digits;
893 var r_digits = r._digits; 930 var r_digits = r._digits;
894 var i = r_used; 931 var i = r_used + 1; // Set leading zero for 64-bit processing.
895 while (--i >= 0) { 932 while (--i >= 0) {
896 r_digits[i] = 0; 933 r_digits[i] = 0;
897 } 934 }
898 for (i = 0; i < used - 1; ++i) { 935 for (i = 0; i < used - 1; ++i) {
899 _sqrAdd(digits, i, r_digits, used); 936 _sqrAdd(digits, i, r_digits, used);
900 } 937 }
901 if (r_used > 0) { 938 if (r_used > 0) {
902 _mulAdd(digits, i, digits, i, r_digits, 2*i, 1); 939 _mulAdd(digits, i, digits, i, r_digits, 2*i, 1);
903 } 940 }
904 r._used = r_used; 941 r._used = r_used;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 var y_digits = y._digits; 1000 var y_digits = y._digits;
964 var yt = y_digits[y_used - 1]; 1001 var yt = y_digits[y_used - 1];
965 if (yt == 0) return; 1002 if (yt == 0) return;
966 var i = r._used; 1003 var i = r._used;
967 var j = i - y_used; 1004 var j = i - y_used;
968 _Bigint t = (q == null) ? new _Bigint() : q; 1005 _Bigint t = (q == null) ? new _Bigint() : q;
969 y._dlShiftTo(j, t); 1006 y._dlShiftTo(j, t);
970 var r_digits = r._digits; 1007 var r_digits = r._digits;
971 if (r._compareTo(t) >= 0) { 1008 if (r._compareTo(t) >= 0) {
972 r_digits[r._used++] = 1; 1009 r_digits[r._used++] = 1;
1010 r_digits[r._used] = 0; // Set leading zero for 64-bit processing.
973 r._subTo(t, r); 1011 r._subTo(t, r);
974 } 1012 }
975 ONE._dlShiftTo(y_used, t); 1013 ONE._dlShiftTo(y_used, t);
976 t._subTo(y, y); // Negate y so we can replace sub with _mulAdd later. 1014 t._subTo(y, y); // Negate y so we can replace sub with _mulAdd later.
977 while (y._used < y_used) { 1015 while (y._used < y_used) {
978 y_digits[y._used++] = 0; 1016 y_digits[y._used++] = 0;
979 } 1017 }
1018 y_digits[y._used] = 0; // Set leading zero for 64-bit processing.
980 Uint32List args = new Uint32List(2); 1019 Uint32List args = new Uint32List(2);
981 args[_YT] = yt; 1020 args[_YT] = yt;
982 while (--j >= 0) { 1021 while (--j >= 0) {
983 _estQuotientDigit(args, r_digits, --i); 1022 _estQuotientDigit(args, r_digits, --i);
984 _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used); 1023 _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used);
985 if (r_digits[i] < args[_QD]) { 1024 if (r_digits[i] < args[_QD]) {
986 y._dlShiftTo(j, t); 1025 y._dlShiftTo(j, t);
987 r._subTo(t, r); 1026 r._subTo(t, r);
988 while (r_digits[i] < --args[_QD]) { 1027 while (r_digits[i] < --args[_QD]) {
989 r._subTo(t, r); 1028 r._subTo(t, r);
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 return r; 1451 return r;
1413 } 1452 }
1414 1453
1415 // x = x/R mod _m 1454 // x = x/R mod _m
1416 void _reduce(_Bigint x) { 1455 void _reduce(_Bigint x) {
1417 x._ensureLength(_mused2 + 1); 1456 x._ensureLength(_mused2 + 1);
1418 var x_digits = x._digits; 1457 var x_digits = x._digits;
1419 while (x._used <= _mused2) { // Pad x so _mulAdd has enough room later. 1458 while (x._used <= _mused2) { // Pad x so _mulAdd has enough room later.
1420 x_digits[x._used++] = 0; 1459 x_digits[x._used++] = 0;
1421 } 1460 }
1461 x_digits[x._used] = 0; // Set leading zero for 64-bit processing.
1422 var m_used = _m._used; 1462 var m_used = _m._used;
1423 var m_digits = _m._digits; 1463 var m_digits = _m._digits;
1424 for (var i = 0; i < m_used; ++i) { 1464 for (var i = 0; i < m_used; ++i) {
1425 _mulMod(_rho_mu, x_digits, i); 1465 _mulMod(_rho_mu, x_digits, i);
1426 _Bigint._mulAdd(_rho_mu, _MU, m_digits, 0, x_digits, i, m_used); 1466 _Bigint._mulAdd(_rho_mu, _MU, m_digits, 0, x_digits, i, m_used);
1427 } 1467 }
1428 x._clamp(); 1468 x._clamp();
1429 x._drShiftTo(m_used, x); 1469 x._drShiftTo(m_used, x);
1430 if (x._compareTo(_m) >= 0) { 1470 if (x._compareTo(_m) >= 0) {
1431 x._subTo(_m, x); 1471 x._subTo(_m, x);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1476 void _sqrTo(_Bigint x, _Bigint r) { 1516 void _sqrTo(_Bigint x, _Bigint r) {
1477 x._sqrTo(r); 1517 x._sqrTo(r);
1478 _reduce(r); 1518 _reduce(r);
1479 } 1519 }
1480 1520
1481 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { 1521 void _mulTo(_Bigint x, _Bigint y, _Bigint r) {
1482 x._mulTo(y, r); 1522 x._mulTo(y, r);
1483 _reduce(r); 1523 _reduce(r);
1484 } 1524 }
1485 } 1525 }
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698