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

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

Issue 1044503002: Refactor bigint shifting code in preparation of shifting intrinsics. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 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/intrinsifier_arm.cc » ('j') | runtime/vm/method_recognizer.h » ('J')
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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 if ((t = x >> 16) != 0) { x = t; r += 16; } 164 if ((t = x >> 16) != 0) { x = t; r += 16; }
165 if ((t = x >> 8) != 0) { x = t; r += 8; } 165 if ((t = x >> 8) != 0) { x = t; r += 8; }
166 if ((t = x >> 4) != 0) { x = t; r += 4; } 166 if ((t = x >> 4) != 0) { x = t; r += 4; }
167 if ((t = x >> 2) != 0) { x = t; r += 2; } 167 if ((t = x >> 2) != 0) { x = t; r += 2; }
168 if ((x >> 1) != 0) { r += 1; } 168 if ((x >> 1) != 0) { r += 1; }
169 return r; 169 return r;
170 } 170 }
171 171
172 // Return this << n*_DIGIT_BITS. 172 // Return this << n*_DIGIT_BITS.
173 _Bigint _dlShift(int n) { 173 _Bigint _dlShift(int n) {
174 var used = _used; 174 final used = _used;
175 if (used == 0) { 175 if (used == 0) {
176 return _ZERO; 176 return _ZERO;
177 } 177 }
178 var r_used = used + n; 178 final r_used = used + n;
179 var digits = _digits; 179 final digits = _digits;
180 var r_digits = new Uint32List(r_used + (r_used & 1)); 180 final r_digits = new Uint32List(r_used + (r_used & 1));
181 var i = used; 181 var i = used;
182 while (--i >= 0) { 182 while (--i >= 0) {
183 r_digits[i + n] = digits[i]; 183 r_digits[i + n] = digits[i];
184 } 184 }
185 return new _Bigint(_neg, r_used, r_digits); 185 return new _Bigint(_neg, r_used, r_digits);
186 } 186 }
187 187
188 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n*_DIGIT_BITS. 188 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n*_DIGIT_BITS.
189 // Return r_used. 189 // Return r_used.
190 static int _dlShiftDigits(Uint32List x_digits, int x_used, int n, 190 static int _dlShiftDigits(Uint32List x_digits, int x_used, int n,
191 Uint32List r_digits) { 191 Uint32List r_digits) {
192 if (x_used == 0) { 192 if (x_used == 0) {
193 return 0; 193 return 0;
194 } 194 }
195 if (n == 0 && r_digits == x_digits) { 195 if (n == 0 && r_digits == x_digits) {
196 return x_used; 196 return x_used;
197 } 197 }
198 var r_used = x_used + n; 198 final r_used = x_used + n;
199 assert(r_digits.length >= r_used + (r_used & 1)); 199 assert(r_digits.length >= r_used + (r_used & 1));
200 var i = x_used; 200 var i = x_used;
201 while (--i >= 0) { 201 while (--i >= 0) {
202 r_digits[i + n] = x_digits[i]; 202 r_digits[i + n] = x_digits[i];
203 } 203 }
204 i = n; 204 i = n;
205 while (--i >= 0) { 205 while (--i >= 0) {
206 r_digits[i] = 0; 206 r_digits[i] = 0;
207 } 207 }
208 if (r_used.isOdd) { 208 if (r_used.isOdd) {
209 r_digits[r_used] = 0; 209 r_digits[r_used] = 0;
210 } 210 }
211 return r_used; 211 return r_used;
212 } 212 }
213 213
214 // Return this >> n*_DIGIT_BITS. 214 // Return this >> n*_DIGIT_BITS.
215 _Bigint _drShift(int n) { 215 _Bigint _drShift(int n) {
216 var used = _used; 216 final used = _used;
217 if (used == 0) { 217 if (used == 0) {
218 return _ZERO; 218 return _ZERO;
219 } 219 }
220 var r_used = used - n; 220 final r_used = used - n;
221 if (r_used <= 0) { 221 if (r_used <= 0) {
222 return _neg ? _MINUS_ONE : _ZERO; 222 return _neg ? _MINUS_ONE : _ZERO;
223 } 223 }
224 var digits = _digits; 224 final digits = _digits;
225 var r_digits = new Uint32List(r_used + (r_used & 1)); 225 final r_digits = new Uint32List(r_used + (r_used & 1));
226 for (var i = n; i < used; i++) { 226 for (var i = n; i < used; i++) {
227 r_digits[i - n] = digits[i]; 227 r_digits[i - n] = digits[i];
228 } 228 }
229 var r = new _Bigint(_neg, r_used, r_digits); 229 final r = new _Bigint(_neg, r_used, r_digits);
230 if (_neg) { 230 if (_neg) {
231 // Round down if any bit was shifted out. 231 // Round down if any bit was shifted out.
232 for (var i = 0; i < n; i++) { 232 for (var i = 0; i < n; i++) {
233 if (digits[i] != 0) { 233 if (digits[i] != 0) {
234 return r._sub(_ONE); 234 return r._sub(_ONE);
235 } 235 }
236 } 236 }
237 } 237 }
238 return r; 238 return r;
239 } 239 }
240 240
241 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n*_DIGIT_BITS. 241 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n*_DIGIT_BITS.
242 // Return r_used. 242 // Return r_used.
243 static int _drShiftDigits(Uint32List x_digits, int x_used, int n, 243 static int _drShiftDigits(Uint32List x_digits, int x_used, int n,
244 Uint32List r_digits) { 244 Uint32List r_digits) {
245 var r_used = x_used - n; 245 final r_used = x_used - n;
246 if (r_used <= 0) { 246 if (r_used <= 0) {
247 return 0; 247 return 0;
248 } 248 }
249 assert(r_digits.length >= r_used + (r_used & 1)); 249 assert(r_digits.length >= r_used + (r_used & 1));
250 for (var i = n; i < x_used; i++) { 250 for (var i = n; i < x_used; i++) {
251 r_digits[i - n] = x_digits[i]; 251 r_digits[i - n] = x_digits[i];
252 } 252 }
253 if (r_used.isOdd) { 253 if (r_used.isOdd) {
254 r_digits[r_used] = 0; 254 r_digits[r_used] = 0;
255 } 255 }
256 return r_used; 256 return r_used;
257 } 257 }
258 258
259 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n.
260 static void _lsh(Uint32List x_digits, int x_used, int n,
261 Uint32List r_digits) {
262 final ds = n ~/ _DIGIT_BITS;
263 final bs = n % _DIGIT_BITS;
srdjan 2015/03/27 22:29:54 You compute now ds and bs twice: once here and onc
regis 2015/03/27 22:41:46 Correct. It is cheaper to recalculate the values f
264 final cbs = _DIGIT_BITS - bs;
265 final bm = (1 << cbs) - 1;
266 var c = 0;
267 var i = x_used;
268 while (--i >= 0) {
269 final d = x_digits[i];
270 r_digits[i + ds + 1] = (d >> cbs) | c;
271 c = (d & bm) << bs;
272 }
273 r_digits[ds] = c;
274 i = ds;
275 while (--i >= 0) {
276 r_digits[i] = 0;
277 }
278 }
279
259 // Return this << n. 280 // Return this << n.
260 _Bigint _lShift(int n) { 281 _Bigint _lShift(int n) {
261 var ds = n ~/ _DIGIT_BITS; 282 final ds = n ~/ _DIGIT_BITS;
262 var bs = n % _DIGIT_BITS; 283 final bs = n % _DIGIT_BITS;
263 if (bs == 0) { 284 if (bs == 0) {
264 return _dlShift(ds); 285 return _dlShift(ds);
265 } 286 }
266 var cbs = _DIGIT_BITS - bs;
267 var bm = (1 << cbs) - 1;
268 var r_used = _used + ds + 1; 287 var r_used = _used + ds + 1;
269 var digits = _digits;
270 var r_digits = new Uint32List(r_used + (r_used & 1)); 288 var r_digits = new Uint32List(r_used + (r_used & 1));
271 var c = 0; 289 _lsh(_digits, _used, n, r_digits);
272 var i = _used;
273 while (--i >= 0) {
274 final d = digits[i];
275 r_digits[i + ds + 1] = (d >> cbs) | c;
276 c = (d & bm) << bs;
277 }
278 r_digits[ds] = c;
279 return new _Bigint(_neg, r_used, r_digits); 290 return new _Bigint(_neg, r_used, r_digits);
280 } 291 }
281 292
282 // 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.
283 // Return r_used. 294 // Return r_used.
284 static int _lShiftDigits(Uint32List x_digits, int x_used, int n, 295 static int _lShiftDigits(Uint32List x_digits, int x_used, int n,
285 Uint32List r_digits) { 296 Uint32List r_digits) {
286 var ds = n ~/ _DIGIT_BITS; 297 final ds = n ~/ _DIGIT_BITS;
287 var bs = n % _DIGIT_BITS; 298 final bs = n % _DIGIT_BITS;
288 if (bs == 0) { 299 if (bs == 0) {
289 return _dlShiftDigits(x_digits, x_used, ds, r_digits); 300 return _dlShiftDigits(x_digits, x_used, ds, r_digits);
290 } 301 }
291 var cbs = _DIGIT_BITS - bs;
292 var bm = (1 << cbs) - 1;
293 var r_used = x_used + ds + 1; 302 var r_used = x_used + ds + 1;
294 assert(r_digits.length >= r_used + (r_used & 1)); 303 assert(r_digits.length >= r_used + (r_used & 1));
295 var c = 0; 304 _lsh(x_digits, x_used, n, r_digits);
296 var i = x_used;
297 while (--i >= 0) {
298 final d = x_digits[i];
299 r_digits[i + ds + 1] = (d >> cbs) | c;
300 c = (d & bm) << bs;
301 }
302 r_digits[ds] = c;
303 i = ds;
304 while (--i >= 0) {
305 r_digits[i] = 0;
306 }
307 if (r_digits[r_used - 1] == 0) { 305 if (r_digits[r_used - 1] == 0) {
308 r_used--; // Clamp result. 306 r_used--; // Clamp result.
309 } else if (r_used.isOdd) { 307 } else if (r_used.isOdd) {
310 r_digits[r_used] = 0; 308 r_digits[r_used] = 0;
311 } 309 }
312 return r_used; 310 return r_used;
313 } 311 }
314 312
313 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n.
314 static void _rsh(Uint32List x_digits, int x_used, int n,
315 Uint32List r_digits) {
316 final ds = n ~/ _DIGIT_BITS;
317 final bs = n % _DIGIT_BITS;
318 final cbs = _DIGIT_BITS - bs;
319 final bm = (1 << bs) - 1;
320 var c = x_digits[ds] >> bs;
321 final last = x_used - ds - 1;
322 for (var i = 0; i < last; i++) {
323 final d = x_digits[i + ds + 1];
324 r_digits[i] = ((d & bm) << cbs) | c;
325 c = d >> bs;
326 }
327 r_digits[last] = c;
328 }
329
315 // Return this >> n. 330 // Return this >> n.
316 _Bigint _rShift(int n) { 331 _Bigint _rShift(int n) {
317 var ds = n ~/ _DIGIT_BITS; 332 final ds = n ~/ _DIGIT_BITS;
318 var bs = n % _DIGIT_BITS; 333 final bs = n % _DIGIT_BITS;
319 if (bs == 0) { 334 if (bs == 0) {
320 return _drShift(ds); 335 return _drShift(ds);
321 } 336 }
322 var r_used = _used - ds; 337 final used = _used;
338 final r_used = used - ds;
323 if (r_used <= 0) { 339 if (r_used <= 0) {
324 return _neg ? _MINUS_ONE : _ZERO; 340 return _neg ? _MINUS_ONE : _ZERO;
325 } 341 }
326 var cbs = _DIGIT_BITS - bs; 342 final digits = _digits;
327 var bm = (1 << bs) - 1; 343 final r_digits = new Uint32List(r_used + (r_used & 1));
328 var digits = _digits; 344 _rsh(digits, used, n, r_digits);
329 var r_digits = new Uint32List(r_used + (r_used & 1)); 345 final r = new _Bigint(_neg, r_used, r_digits);
330 r_digits[0] = digits[ds] >> bs;
331 var used = _used;
332 for (var i = ds + 1; i < used; i++) {
333 final d = digits[i];
334 r_digits[i - ds - 1] |= (d & bm) << cbs;
335 r_digits[i - ds] = d >> bs;
336 }
337 var r = new _Bigint(_neg, r_used, r_digits);
338 if (_neg) { 346 if (_neg) {
339 // Round down if any bit was shifted out. 347 // Round down if any bit was shifted out.
340 if ((digits[ds] & bm) != 0) { 348 if ((digits[ds] & ((1 << bs) - 1)) != 0) {
341 return r._sub(_ONE); 349 return r._sub(_ONE);
342 } 350 }
343 for (var i = 0; i < ds; i++) { 351 for (var i = 0; i < ds; i++) {
344 if (digits[i] != 0) { 352 if (digits[i] != 0) {
345 return r._sub(_ONE); 353 return r._sub(_ONE);
346 } 354 }
347 } 355 }
348 } 356 }
349 return r; 357 return r;
350 } 358 }
351 359
352 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n. 360 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n.
353 // Return r_used. 361 // Return r_used.
354 static int _rShiftDigits(Uint32List x_digits, int x_used, int n, 362 static int _rShiftDigits(Uint32List x_digits, int x_used, int n,
355 Uint32List r_digits) { 363 Uint32List r_digits) {
356 var ds = n ~/ _DIGIT_BITS; 364 final ds = n ~/ _DIGIT_BITS;
357 var bs = n % _DIGIT_BITS; 365 final bs = n % _DIGIT_BITS;
358 if (bs == 0) { 366 if (bs == 0) {
359 return _drShiftDigits(x_digits, x_used, ds, r_digits); 367 return _drShiftDigits(x_digits, x_used, ds, r_digits);
360 } 368 }
361 var r_used = x_used - ds; 369 var r_used = x_used - ds;
362 if (r_used <= 0) { 370 if (r_used <= 0) {
363 return 0; 371 return 0;
364 } 372 }
365 var cbs = _DIGIT_BITS - bs;
366 var bm = (1 << bs) - 1;
367 assert(r_digits.length >= r_used + (r_used & 1)); 373 assert(r_digits.length >= r_used + (r_used & 1));
368 r_digits[0] = x_digits[ds] >> bs; 374 _rsh(x_digits, x_used, n, r_digits);
369 for (var i = ds + 1; i < x_used; i++) {
370 final d = x_digits[i];
371 r_digits[i - ds - 1] |= (d & bm) << cbs;
372 r_digits[i - ds] = d >> bs;
373 }
374 if (r_digits[r_used - 1] == 0) { 375 if (r_digits[r_used - 1] == 0) {
375 r_used--; // Clamp result. 376 r_used--; // Clamp result.
376 } else if (r_used.isOdd) { 377 } else if (r_used.isOdd) {
377 r_digits[r_used] = 0; 378 r_digits[r_used] = 0;
378 } 379 }
379 return r_used; 380 return r_used;
380 } 381 }
381 382
382 // Return 0 if abs(this) == abs(a). 383 // Return 0 if abs(this) == abs(a).
383 // Return a positive number if abs(this) > abs(a). 384 // Return a positive number if abs(this) > abs(a).
(...skipping 1377 matching lines...) Expand 10 before | Expand all | Expand 10 after
1761 1762
1762 int _mul(Uint32List x_digits, int x_used, 1763 int _mul(Uint32List x_digits, int x_used,
1763 Uint32List y_digits, int y_used, 1764 Uint32List y_digits, int y_used,
1764 Uint32List r_digits) { 1765 Uint32List r_digits) {
1765 var r_used = _Bigint._mulDigits(x_digits, x_used, 1766 var r_used = _Bigint._mulDigits(x_digits, x_used,
1766 y_digits, y_used, 1767 y_digits, y_used,
1767 r_digits); 1768 r_digits);
1768 return _reduce(r_digits, r_used); 1769 return _reduce(r_digits, r_used);
1769 } 1770 }
1770 } 1771 }
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intrinsifier_arm.cc » ('j') | runtime/vm/method_recognizer.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698