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

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 var i = _used + 1; // Copy leading zero for 64-bit processing.
216 while (--i >= 0) {
217 new_digits[i] = digits[i];
218 }
214 } 219 }
215 _digits = new_digits;
216 } 220 }
217 } 221 }
218 222
219 // Clamp off excess high _digits. 223 // Clamp off excess high _digits.
220 void _clamp() { 224 void _clamp() {
221 var digits = _digits; 225 var used = _used;
222 while (_used > 0 && digits[_used - 1] == 0) { 226 if (used > 0) {
223 --_used; 227 var digits = _digits;
228 if (digits[used - 1] == 0) {
229 do {
230 --used;
231 } while (used > 0 && digits[used - 1] == 0);
232 _used = used;
233 }
234 digits[used] = 0; // Set leading zero for 64-bit processing.
224 } 235 }
225 } 236 }
226 237
227 // Copy this to r. 238 // Copy this to r.
228 void _copyTo(_Bigint r) { 239 void _copyTo(_Bigint r) {
229 r._ensureLength(_used); 240 var used = _used;
230 var digits = _digits; 241 if (used > 0) {
231 var r_digits = r._digits; 242 r._used = 0; // No digits to preserve.
232 for (var i = _used - 1; i >= 0; --i) { 243 r._ensureLength(used);
233 r_digits[i] = digits[i]; 244 var digits = _digits;
245 var r_digits = r._digits;
246 var i = used + 1; // Copy leading zero for 64-bit processing.
247 while (--i >= 0) {
248 r_digits[i] = digits[i];
249 }
234 } 250 }
235 r._used = _used; 251 r._used = used;
236 r._neg = _neg; 252 r._neg = _neg;
237 } 253 }
238 254
239 // Return the bit length of digit x. 255 // Return the bit length of digit x.
240 int _nbits(int x) { 256 int _nbits(int x) {
241 var r = 1, t; 257 var r = 1, t;
242 if ((t = x >> 16) != 0) { x = t; r += 16; } 258 if ((t = x >> 16) != 0) { x = t; r += 16; }
243 if ((t = x >> 8) != 0) { x = t; r += 8; } 259 if ((t = x >> 8) != 0) { x = t; r += 8; }
244 if ((t = x >> 4) != 0) { x = t; r += 4; } 260 if ((t = x >> 4) != 0) { x = t; r += 4; }
245 if ((t = x >> 2) != 0) { x = t; r += 2; } 261 if ((t = x >> 2) != 0) { x = t; r += 2; }
246 if ((x >> 1) != 0) { r += 1; } 262 if ((x >> 1) != 0) { r += 1; }
247 return r; 263 return r;
248 } 264 }
249 265
250 // r = this << n*DIGIT_BITS. 266 // r = this << n*DIGIT_BITS.
251 void _dlShiftTo(int n, _Bigint r) { 267 void _dlShiftTo(int n, _Bigint r) {
252 var r_used = _used + n; 268 var used = _used;
269 if (used == 0) {
270 r._used = 0;
271 r._neg = false;
272 return;
273 }
274 var r_used = used + n;
253 r._ensureLength(r_used); 275 r._ensureLength(r_used);
254 var digits = _digits; 276 var digits = _digits;
255 var r_digits = r._digits; 277 var r_digits = r._digits;
256 for (var i = _used - 1; i >= 0; --i) { 278 var i = used + 1; // Copy leading zero for 64-bit processing.
279 while (--i >= 0) {
257 r_digits[i + n] = digits[i]; 280 r_digits[i + n] = digits[i];
258 } 281 }
259 for (var i = n - 1; i >= 0; --i) { 282 i = n;
283 while (--i >= 0) {
260 r_digits[i] = 0; 284 r_digits[i] = 0;
261 } 285 }
262 r._used = r_used; 286 r._used = r_used;
263 r._neg = _neg; 287 r._neg = _neg;
264 } 288 }
265 289
266 // r = this >> n*DIGIT_BITS. 290 // r = this >> n*DIGIT_BITS.
267 void _drShiftTo(int n, _Bigint r) { 291 void _drShiftTo(int n, _Bigint r) {
268 var r_used = _used - n; 292 var used = _used;
269 if (r_used < 0) { 293 if (used == 0) {
294 r._used = 0;
295 r._neg = false;
296 return;
297 }
298 var r_used = used - n;
299 if (r_used <= 0) {
270 if (_neg) { 300 if (_neg) {
271 // Set r to -1. 301 // Set r to -1.
302 r._used = 0; // No digits to preserve.
303 r._ensureLength(1);
272 r._neg = true; 304 r._neg = true;
273 r._ensureLength(1);
274 r._used = 1; 305 r._used = 1;
275 r._digits[0] = 1; 306 r._digits[0] = 1;
307 r._digits[1] = 0; // Set leading zero for 64-bit processing.
276 } else { 308 } else {
277 // Set r to 0. 309 // Set r to 0.
278 r._neg = false; 310 r._neg = false;
279 r._used = 0; 311 r._used = 0;
280 } 312 }
281 return; 313 return;
282 } 314 }
283 r._ensureLength(r_used); 315 r._ensureLength(r_used);
284 var digits = _digits; 316 var digits = _digits;
285 var r_digits = r._digits; 317 var r_digits = r._digits;
286 var used = _used; 318 for (var i = n; i < used + 1; i++) { // Copy leading zero for 64-bit proc.
287 for (var i = n; i < used; ++i) {
288 r_digits[i - n] = digits[i]; 319 r_digits[i - n] = digits[i];
289 } 320 }
290 r._used = r_used; 321 r._used = r_used;
291 r._neg = _neg; 322 r._neg = _neg;
292 if (_neg) { 323 if (_neg) {
293 // Round down if any bit was shifted out. 324 // Round down if any bit was shifted out.
294 for (var i = 0; i < n; i++) { 325 for (var i = 0; i < n; i++) {
295 if (digits[i] != 0) { 326 if (digits[i] != 0) {
296 r._subTo(ONE, r); 327 r._subTo(ONE, r);
297 break; 328 break;
(...skipping 10 matching lines...) Expand all
308 _dlShiftTo(ds, r); 339 _dlShiftTo(ds, r);
309 return; 340 return;
310 } 341 }
311 var cbs = DIGIT_BITS - bs; 342 var cbs = DIGIT_BITS - bs;
312 var bm = (1 << cbs) - 1; 343 var bm = (1 << cbs) - 1;
313 var r_used = _used + ds + 1; 344 var r_used = _used + ds + 1;
314 r._ensureLength(r_used); 345 r._ensureLength(r_used);
315 var digits = _digits; 346 var digits = _digits;
316 var r_digits = r._digits; 347 var r_digits = r._digits;
317 var c = 0; 348 var c = 0;
318 for (var i = _used - 1; i >= 0; --i) { 349 var i = _used;
350 while (--i >= 0) {
319 r_digits[i + ds + 1] = (digits[i] >> cbs) | c; 351 r_digits[i + ds + 1] = (digits[i] >> cbs) | c;
320 c = (digits[i] & bm) << bs; 352 c = (digits[i] & bm) << bs;
321 } 353 }
322 for (var i = ds - 1; i >= 0; --i) { 354 i = ds;
355 while (--i >= 0) {
323 r_digits[i] = 0; 356 r_digits[i] = 0;
324 } 357 }
325 r_digits[ds] = c; 358 r_digits[ds] = c;
326 r._used = r_used; 359 r._used = r_used;
327 r._neg = _neg; 360 r._neg = _neg;
328 r._clamp(); 361 r._clamp();
329 } 362 }
330 363
331 // r = this >> n. 364 // r = this >> n.
332 void _rShiftTo(int n, _Bigint r) { 365 void _rShiftTo(int n, _Bigint r) {
333 var ds = n ~/ DIGIT_BITS; 366 var ds = n ~/ DIGIT_BITS;
334 var bs = n % DIGIT_BITS; 367 var bs = n % DIGIT_BITS;
335 if (bs == 0) { 368 if (bs == 0) {
336 _drShiftTo(ds, r); 369 _drShiftTo(ds, r);
337 return; 370 return;
338 } 371 }
339 var r_used = _used - ds; 372 var r_used = _used - ds;
340 if (r_used <= 0) { 373 if (r_used <= 0) {
341 if (_neg) { 374 if (_neg) {
342 // Set r to -1. 375 // Set r to -1.
343 r._neg = true; 376 r._neg = true;
377 r._used = 0; // No digits to preserve.
344 r._ensureLength(1); 378 r._ensureLength(1);
345 r._used = 1; 379 r._used = 1;
346 r._digits[0] = 1; 380 r._digits[0] = 1;
381 r._digits[1] = 0; // Set leading zero for 64-bit processing.
347 } else { 382 } else {
348 // Set r to 0. 383 // Set r to 0.
349 r._neg = false; 384 r._neg = false;
350 r._used = 0; 385 r._used = 0;
351 } 386 }
352 return; 387 return;
353 } 388 }
354 var cbs = DIGIT_BITS - bs; 389 var cbs = DIGIT_BITS - bs;
355 var bm = (1 << bs) - 1; 390 var bm = (1 << bs) - 1;
356 r._ensureLength(r_used); 391 r._ensureLength(r_used);
357 var digits = _digits; 392 var digits = _digits;
358 var r_digits = r._digits; 393 var r_digits = r._digits;
359 r_digits[0] = digits[ds] >> bs; 394 r_digits[0] = digits[ds] >> bs;
360 var used = _used; 395 var used = _used;
361 for (var i = ds + 1; i < used; ++i) { 396 for (var i = ds + 1; i < used; i++) {
362 r_digits[i - ds - 1] |= (digits[i] & bm) << cbs; 397 r_digits[i - ds - 1] |= (digits[i] & bm) << cbs;
363 r_digits[i - ds] = digits[i] >> bs; 398 r_digits[i - ds] = digits[i] >> bs;
364 } 399 }
365 r._neg = _neg; 400 r._neg = _neg;
366 r._used = r_used; 401 r._used = r_used;
367 r._clamp(); 402 r._clamp();
368 if (_neg) { 403 if (_neg) {
369 // Round down if any bit was shifted out. 404 // Round down if any bit was shifted out.
370 if ((digits[ds] & bm) != 0) { 405 if ((digits[ds] & bm) != 0) {
371 r._subTo(ONE, r); 406 r._subTo(ONE, r);
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 } else { 895 } else {
861 a_digits[i + used] = c; 896 a_digits[i + used] = c;
862 } 897 }
863 } 898 }
864 899
865 // r = this * a. 900 // r = this * a.
866 void _mulTo(_Bigint a, _Bigint r) { 901 void _mulTo(_Bigint a, _Bigint r) {
867 // TODO(regis): Use karatsuba multiplication when appropriate. 902 // TODO(regis): Use karatsuba multiplication when appropriate.
868 var used = _used; 903 var used = _used;
869 var a_used = a._used; 904 var a_used = a._used;
905 if (used == 0 || a_used == 0) {
906 r._used = 0;
907 r._neg = false;
908 return;
909 }
870 var r_used = used + a_used; 910 var r_used = used + a_used;
871 r._ensureLength(r_used); 911 r._ensureLength(r_used);
872 var digits = _digits; 912 var digits = _digits;
873 var a_digits = a._digits; 913 var a_digits = a._digits;
874 var r_digits = r._digits; 914 var r_digits = r._digits;
875 r._used = r_used; 915 r._used = r_used;
876 var i = r_used; 916 var i = r_used + 1; // Set leading zero for 64-bit processing.
877 while (--i >= 0) { 917 while (--i >= 0) {
878 r_digits[i] = 0; 918 r_digits[i] = 0;
879 } 919 }
880 for (i = 0; i < a_used; ++i) { 920 for (i = 0; i < a_used; ++i) {
881 _mulAdd(a_digits, i, digits, 0, r_digits, i, used); 921 _mulAdd(a_digits, i, digits, 0, r_digits, i, used);
882 } 922 }
883 r._clamp(); 923 r._clamp();
884 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative. 924 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative.
885 } 925 }
886 926
887 // r = this^2, r != this. 927 // r = this^2, r != this.
888 void _sqrTo(_Bigint r) { 928 void _sqrTo(_Bigint r) {
889 var used = _used; 929 var used = _used;
930 if (used == 0) {
931 r._used = 0;
932 r._neg = false;
933 return;
934 }
890 var r_used = 2 * used; 935 var r_used = 2 * used;
891 r._ensureLength(r_used); 936 r._ensureLength(r_used);
892 var digits = _digits; 937 var digits = _digits;
893 var r_digits = r._digits; 938 var r_digits = r._digits;
894 var i = r_used; 939 var i = r_used + 1; // Set leading zero for 64-bit processing.
895 while (--i >= 0) { 940 while (--i >= 0) {
896 r_digits[i] = 0; 941 r_digits[i] = 0;
897 } 942 }
898 for (i = 0; i < used - 1; ++i) { 943 for (i = 0; i < used - 1; ++i) {
899 _sqrAdd(digits, i, r_digits, used); 944 _sqrAdd(digits, i, r_digits, used);
900 } 945 }
901 if (r_used > 0) { 946 if (r_used > 0) {
902 _mulAdd(digits, i, digits, i, r_digits, 2*i, 1); 947 _mulAdd(digits, i, digits, i, r_digits, 2*i, 1);
903 } 948 }
904 r._used = r_used; 949 r._used = r_used;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 var y_digits = y._digits; 1008 var y_digits = y._digits;
964 var yt = y_digits[y_used - 1]; 1009 var yt = y_digits[y_used - 1];
965 if (yt == 0) return; 1010 if (yt == 0) return;
966 var i = r._used; 1011 var i = r._used;
967 var j = i - y_used; 1012 var j = i - y_used;
968 _Bigint t = (q == null) ? new _Bigint() : q; 1013 _Bigint t = (q == null) ? new _Bigint() : q;
969 y._dlShiftTo(j, t); 1014 y._dlShiftTo(j, t);
970 var r_digits = r._digits; 1015 var r_digits = r._digits;
971 if (r._compareTo(t) >= 0) { 1016 if (r._compareTo(t) >= 0) {
972 r_digits[r._used++] = 1; 1017 r_digits[r._used++] = 1;
1018 r_digits[r._used] = 0; // Set leading zero for 64-bit processing.
973 r._subTo(t, r); 1019 r._subTo(t, r);
974 } 1020 }
975 ONE._dlShiftTo(y_used, t); 1021 ONE._dlShiftTo(y_used, t);
976 t._subTo(y, y); // Negate y so we can replace sub with _mulAdd later. 1022 t._subTo(y, y); // Negate y so we can replace sub with _mulAdd later.
977 while (y._used < y_used) { 1023 while (y._used < y_used) {
978 y_digits[y._used++] = 0; 1024 y_digits[y._used++] = 0;
979 } 1025 }
1026 y_digits[y._used] = 0; // Set leading zero for 64-bit processing.
980 Uint32List args = new Uint32List(2); 1027 Uint32List args = new Uint32List(2);
981 args[_YT] = yt; 1028 args[_YT] = yt;
982 while (--j >= 0) { 1029 while (--j >= 0) {
983 _estQuotientDigit(args, r_digits, --i); 1030 _estQuotientDigit(args, r_digits, --i);
984 _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used); 1031 _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used);
985 if (r_digits[i] < args[_QD]) { 1032 if (r_digits[i] < args[_QD]) {
986 y._dlShiftTo(j, t); 1033 y._dlShiftTo(j, t);
987 r._subTo(t, r); 1034 r._subTo(t, r);
988 while (r_digits[i] < --args[_QD]) { 1035 while (r_digits[i] < --args[_QD]) {
989 r._subTo(t, r); 1036 r._subTo(t, r);
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 return r; 1459 return r;
1413 } 1460 }
1414 1461
1415 // x = x/R mod _m 1462 // x = x/R mod _m
1416 void _reduce(_Bigint x) { 1463 void _reduce(_Bigint x) {
1417 x._ensureLength(_mused2 + 1); 1464 x._ensureLength(_mused2 + 1);
1418 var x_digits = x._digits; 1465 var x_digits = x._digits;
1419 while (x._used <= _mused2) { // Pad x so _mulAdd has enough room later. 1466 while (x._used <= _mused2) { // Pad x so _mulAdd has enough room later.
1420 x_digits[x._used++] = 0; 1467 x_digits[x._used++] = 0;
1421 } 1468 }
1469 x_digits[x._used] = 0; // Set leading zero for 64-bit processing.
1422 var m_used = _m._used; 1470 var m_used = _m._used;
1423 var m_digits = _m._digits; 1471 var m_digits = _m._digits;
1424 for (var i = 0; i < m_used; ++i) { 1472 for (var i = 0; i < m_used; i++) {
1425 _mulMod(_rho_mu, x_digits, i); 1473 _mulMod(_rho_mu, x_digits, i);
1426 _Bigint._mulAdd(_rho_mu, _MU, m_digits, 0, x_digits, i, m_used); 1474 _Bigint._mulAdd(_rho_mu, _MU, m_digits, 0, x_digits, i, m_used);
1427 } 1475 }
1428 x._clamp(); 1476 x._clamp();
1429 x._drShiftTo(m_used, x); 1477 x._drShiftTo(m_used, x);
1430 if (x._compareTo(_m) >= 0) { 1478 if (x._compareTo(_m) >= 0) {
1431 x._subTo(_m, x); 1479 x._subTo(_m, x);
1432 } 1480 }
1433 } 1481 }
1434 1482
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1476 void _sqrTo(_Bigint x, _Bigint r) { 1524 void _sqrTo(_Bigint x, _Bigint r) {
1477 x._sqrTo(r); 1525 x._sqrTo(r);
1478 _reduce(r); 1526 _reduce(r);
1479 } 1527 }
1480 1528
1481 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { 1529 void _mulTo(_Bigint x, _Bigint y, _Bigint r) {
1482 x._mulTo(y, r); 1530 x._mulTo(y, r);
1483 _reduce(r); 1531 _reduce(r);
1484 } 1532 }
1485 } 1533 }
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