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

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

Issue 1049933002: Implement bigint shift intrinsics on x64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 8 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 | « 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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 } 278 }
279 279
280 // Return this << n. 280 // Return this << n.
281 _Bigint _lShift(int n) { 281 _Bigint _lShift(int n) {
282 final ds = n ~/ _DIGIT_BITS; 282 final ds = n ~/ _DIGIT_BITS;
283 final bs = n % _DIGIT_BITS; 283 final bs = n % _DIGIT_BITS;
284 if (bs == 0) { 284 if (bs == 0) {
285 return _dlShift(ds); 285 return _dlShift(ds);
286 } 286 }
287 var r_used = _used + ds + 1; 287 var r_used = _used + ds + 1;
288 var r_digits = new Uint32List(r_used + (r_used & 1)); 288 var r_digits = new Uint32List(r_used + 2 + (r_used & 1)); // +2 for 64-bit.
289 _lsh(_digits, _used, n, r_digits); 289 _lsh(_digits, _used, n, r_digits);
290 return new _Bigint(_neg, r_used, r_digits); 290 return new _Bigint(_neg, r_used, r_digits);
291 } 291 }
292 292
293 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n. 293 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n.
294 // Return r_used. 294 // Return r_used.
295 static int _lShiftDigits(Uint32List x_digits, int x_used, int n, 295 static int _lShiftDigits(Uint32List x_digits, int x_used, int n,
296 Uint32List r_digits) { 296 Uint32List r_digits) {
297 final ds = n ~/ _DIGIT_BITS; 297 final ds = n ~/ _DIGIT_BITS;
298 final bs = n % _DIGIT_BITS; 298 final bs = n % _DIGIT_BITS;
299 if (bs == 0) { 299 if (bs == 0) {
300 return _dlShiftDigits(x_digits, x_used, ds, r_digits); 300 return _dlShiftDigits(x_digits, x_used, ds, r_digits);
301 } 301 }
302 var r_used = x_used + ds + 1; 302 var r_used = x_used + ds + 1;
303 assert(r_digits.length >= r_used + (r_used & 1)); 303 assert(r_digits.length >= r_used + 2 + (r_used & 1)); // +2 for 64-bit.
304 _lsh(x_digits, x_used, n, r_digits); 304 _lsh(x_digits, x_used, n, r_digits);
305 if (r_digits[r_used - 1] == 0) { 305 if (r_digits[r_used - 1] == 0) {
306 r_used--; // Clamp result. 306 r_used--; // Clamp result.
307 } else if (r_used.isOdd) { 307 } else if (r_used.isOdd) {
308 r_digits[r_used] = 0; 308 r_digits[r_used] = 0;
309 } 309 }
310 return r_used; 310 return r_used;
311 } 311 }
312 312
313 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n. 313 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n.
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 if (a._used.isOdd) { 964 if (a._used.isOdd) {
965 nsh += _DIGIT_BITS; 965 nsh += _DIGIT_BITS;
966 } 966 }
967 // Concatenated positive quotient and normalized positive remainder. 967 // Concatenated positive quotient and normalized positive remainder.
968 var r_digits; 968 var r_digits;
969 var r_used; 969 var r_used;
970 // Normalized positive divisor. 970 // Normalized positive divisor.
971 var y_digits; 971 var y_digits;
972 var y_used; 972 var y_used;
973 if (nsh > 0) { 973 if (nsh > 0) {
974 y_digits = new Uint32List(a._used + 3); // +3 for normalization. 974 y_digits = new Uint32List(a._used + 5); // +5 for norm. and 64-bit.
975 y_used = _lShiftDigits(a._digits, a._used, nsh, y_digits); 975 y_used = _lShiftDigits(a._digits, a._used, nsh, y_digits);
976 r_digits = new Uint32List(_used + 3); // +3 for normalization. 976 r_digits = new Uint32List(_used + 5); // +5 for normalization and 64-bit.
977 r_used = _lShiftDigits(_digits, _used, nsh, r_digits); 977 r_used = _lShiftDigits(_digits, _used, nsh, r_digits);
978 } else { 978 } else {
979 y_digits = a._digits; 979 y_digits = a._digits;
980 y_used = a._used; 980 y_used = a._used;
981 r_digits = _cloneDigits(_digits, 0, _used, _used + 2); 981 r_digits = _cloneDigits(_digits, 0, _used, _used + 2);
982 r_used = _used; 982 r_used = _used;
983 } 983 }
984 Uint32List yt_qd = new Uint32List(4); 984 Uint32List yt_qd = new Uint32List(4);
985 yt_qd[_YT_LO] = y_digits[y_used - 2]; 985 yt_qd[_YT_LO] = y_digits[y_used - 2];
986 yt_qd[_YT] = y_digits[y_used - 1]; 986 yt_qd[_YT] = y_digits[y_used - 1];
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 1352
1353 // Returns pow(this, e) % m, with e >= 0, m > 0. 1353 // Returns pow(this, e) % m, with e >= 0, m > 0.
1354 int modPow(int e, int m) { 1354 int modPow(int e, int m) {
1355 if (e is! int) throw new ArgumentError(e); 1355 if (e is! int) throw new ArgumentError(e);
1356 if (m is! int) throw new ArgumentError(m); 1356 if (m is! int) throw new ArgumentError(m);
1357 if (e < 0) throw new RangeError(e); 1357 if (e < 0) throw new RangeError(e);
1358 if (m <= 0) throw new RangeError(m); 1358 if (m <= 0) throw new RangeError(m);
1359 if (e == 0) return 1; 1359 if (e == 0) return 1;
1360 m = m._toBigint(); 1360 m = m._toBigint();
1361 final m_used = m._used; 1361 final m_used = m._used;
1362 final m_used2p2 = 2*m_used + 2; 1362 final m_used2p4 = 2*m_used + 4;
1363 final e_bitlen = e.bitLength; 1363 final e_bitlen = e.bitLength;
1364 if (e_bitlen <= 0) return 1; 1364 if (e_bitlen <= 0) return 1;
1365 final bool cannotUseMontgomery = m.isEven || _abs() >= m; 1365 final bool cannotUseMontgomery = m.isEven || _abs() >= m;
1366 if (cannotUseMontgomery || e_bitlen < 64) { 1366 if (cannotUseMontgomery || e_bitlen < 64) {
1367 _Reduction z = (cannotUseMontgomery || e_bitlen < 8) ? 1367 _Reduction z = (cannotUseMontgomery || e_bitlen < 8) ?
1368 new _Classic(m) : new _Montgomery(m); 1368 new _Classic(m) : new _Montgomery(m);
1369 // TODO(regis): Should we use Barrett reduction for an even modulus and a 1369 // TODO(regis): Should we use Barrett reduction for an even modulus and a
1370 // large exponent? 1370 // large exponent?
1371 var r_digits = new Uint32List(m_used2p2); 1371 var r_digits = new Uint32List(m_used2p4);
1372 var r2_digits = new Uint32List(m_used2p2); 1372 var r2_digits = new Uint32List(m_used2p4);
1373 var g_digits = new Uint32List(m_used + (m_used & 1)); 1373 var g_digits = new Uint32List(m_used + (m_used & 1));
1374 var g_used = z._convert(this, g_digits); 1374 var g_used = z._convert(this, g_digits);
1375 // Initialize r with g. 1375 // Initialize r with g.
1376 var j = g_used + (g_used & 1); // Copy leading zero if any. 1376 var j = g_used + (g_used & 1); // Copy leading zero if any.
1377 while (--j >= 0) { 1377 while (--j >= 0) {
1378 r_digits[j] = g_digits[j]; 1378 r_digits[j] = g_digits[j];
1379 } 1379 }
1380 var r_used = g_used; 1380 var r_used = g_used;
1381 var r2_used; 1381 var r2_used;
1382 var i = e_bitlen - 1; 1382 var i = e_bitlen - 1;
(...skipping 21 matching lines...) Expand all
1404 else k = 6; 1404 else k = 6;
1405 _Reduction z = new _Montgomery(m); 1405 _Reduction z = new _Montgomery(m);
1406 var n = 3; 1406 var n = 3;
1407 final k1 = k - 1; 1407 final k1 = k - 1;
1408 final km = (1 << k) - 1; 1408 final km = (1 << k) - 1;
1409 List g_digits = new List(km + 1); 1409 List g_digits = new List(km + 1);
1410 List g_used = new List(km + 1); 1410 List g_used = new List(km + 1);
1411 g_digits[1] = new Uint32List(m_used + (m_used & 1)); 1411 g_digits[1] = new Uint32List(m_used + (m_used & 1));
1412 g_used[1] = z._convert(this, g_digits[1]); 1412 g_used[1] = z._convert(this, g_digits[1]);
1413 if (k > 1) { 1413 if (k > 1) {
1414 var g2_digits = new Uint32List(m_used2p2); 1414 var g2_digits = new Uint32List(m_used2p4);
1415 var g2_used = z._sqr(g_digits[1], g_used[1], g2_digits); 1415 var g2_used = z._sqr(g_digits[1], g_used[1], g2_digits);
1416 while (n <= km) { 1416 while (n <= km) {
1417 g_digits[n] = new Uint32List(m_used2p2); 1417 g_digits[n] = new Uint32List(m_used2p4);
1418 g_used[n] = z._mul(g2_digits, g2_used, 1418 g_used[n] = z._mul(g2_digits, g2_used,
1419 g_digits[n - 2], g_used[n - 2], 1419 g_digits[n - 2], g_used[n - 2],
1420 g_digits[n]); 1420 g_digits[n]);
1421 n += 2; 1421 n += 2;
1422 } 1422 }
1423 } 1423 }
1424 var w; 1424 var w;
1425 var is1 = true; 1425 var is1 = true;
1426 var r_digits = _ONE._digits; 1426 var r_digits = _ONE._digits;
1427 var r_used = _ONE._used; 1427 var r_used = _ONE._used;
1428 var r2_digits = new Uint32List(m_used2p2); 1428 var r2_digits = new Uint32List(m_used2p4);
1429 var r2_used; 1429 var r2_used;
1430 var e_digits = e._digits; 1430 var e_digits = e._digits;
1431 var j = e._used - 1; 1431 var j = e._used - 1;
1432 var i = _nbits(e_digits[j]) - 1; 1432 var i = _nbits(e_digits[j]) - 1;
1433 while (j >= 0) { 1433 while (j >= 0) {
1434 if (i >= k1) { 1434 if (i >= k1) {
1435 w = (e_digits[j] >> (i - k1)) & km; 1435 w = (e_digits[j] >> (i - k1)) & km;
1436 } else { 1436 } else {
1437 w = (e_digits[j] & ((1 << (i + 1)) - 1)) << (k1 - i); 1437 w = (e_digits[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
1438 if (j > 0) { 1438 if (j > 0) {
1439 w |= e_digits[j - 1] >> (_DIGIT_BITS + i - k1); 1439 w |= e_digits[j - 1] >> (_DIGIT_BITS + i - k1);
1440 } 1440 }
1441 } 1441 }
1442 n = k; 1442 n = k;
1443 while ((w & 1) == 0) { 1443 while ((w & 1) == 0) {
1444 w >>= 1; 1444 w >>= 1;
1445 --n; 1445 --n;
1446 } 1446 }
1447 if ((i -= n) < 0) { 1447 if ((i -= n) < 0) {
1448 i += _DIGIT_BITS; 1448 i += _DIGIT_BITS;
1449 --j; 1449 --j;
1450 } 1450 }
1451 if (is1) { // r == 1, don't bother squaring or multiplying it. 1451 if (is1) { // r == 1, don't bother squaring or multiplying it.
1452 r_digits = new Uint32List(m_used2p2); 1452 r_digits = new Uint32List(m_used2p4);
1453 r_used = g_used[w]; 1453 r_used = g_used[w];
1454 var gw_digits = g_digits[w]; 1454 var gw_digits = g_digits[w];
1455 var ri = r_used + (r_used & 1); // Copy leading zero if any. 1455 var ri = r_used + (r_used & 1); // Copy leading zero if any.
1456 while (--ri >= 0) { 1456 while (--ri >= 0) {
1457 r_digits[ri] = gw_digits[ri]; 1457 r_digits[ri] = gw_digits[ri];
1458 } 1458 }
1459 is1 = false; 1459 is1 = false;
1460 } 1460 }
1461 else { 1461 else {
1462 while (n > 1) { 1462 while (n > 1) {
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1762 1762
1763 int _mul(Uint32List x_digits, int x_used, 1763 int _mul(Uint32List x_digits, int x_used,
1764 Uint32List y_digits, int y_used, 1764 Uint32List y_digits, int y_used,
1765 Uint32List r_digits) { 1765 Uint32List r_digits) {
1766 var r_used = _Bigint._mulDigits(x_digits, x_used, 1766 var r_used = _Bigint._mulDigits(x_digits, x_used,
1767 y_digits, y_used, 1767 y_digits, y_used,
1768 r_digits); 1768 r_digits);
1769 return _reduce(r_digits, r_used); 1769 return _reduce(r_digits, r_used);
1770 } 1770 }
1771 } 1771 }
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