1 // $Id: long.cpp,v 1.27 2002/11/27 00:18:32 ericb Exp $
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 1996, 1998, 1999, 2000, 2001 International Business
7 // Machines Corporation and others. All Rights Reserved.
8 // You must accept the terms of that agreement to use this software.
9 //
10
11 #include "long.h"
12 #include "double.h"
13
14 #ifdef HAVE_JIKES_NAMESPACE
15 namespace Jikes { // Open namespace Jikes block
16 #endif
17
operator LongInt() const18 BaseLong::operator LongInt() const
19 {
20 return LongInt(HighWord(), LowWord());
21 }
22
operator ULongInt() const23 BaseLong::operator ULongInt() const
24 {
25 return ULongInt(HighWord(), LowWord());
26 }
27
operator ==(const BaseLong op) const28 bool BaseLong::operator== (const BaseLong op) const
29 {
30 #ifdef HAVE_64BIT_TYPES
31 return value.words == op.value.words;
32 #else
33 return value.word[0] == op.value.word[0]
34 && value.word[1] == op.value.word[1];
35 #endif // HAVE_64BIT_TYPES
36 }
37
operator !=(const BaseLong op) const38 bool BaseLong::operator!= (const BaseLong op) const
39 {
40 #ifdef HAVE_64BIT_TYPES
41 return value.words != op.value.words;
42 #else
43 return value.word[0] != op.value.word[0]
44 || value.word[1] != op.value.word[1];
45 #endif // HAVE_64BIT_TYPES
46 }
47
operator !() const48 bool BaseLong::operator!() const
49 {
50 #ifdef HAVE_64BIT_TYPES
51 return !value.words;
52 #else
53 return (HighWord() != 0) || (LowWord() != 0);
54 #endif // HAVE_64BIT_TYPES
55 }
56
operator ~() const57 BaseLong BaseLong::operator~() const
58 {
59 #ifdef HAVE_64BIT_TYPES
60 return BaseLong(~value.words);
61 #else
62 return BaseLong(~HighWord(), ~LowWord());
63 #endif // HAVE_64BIT_TYPES
64 }
65
operator ^(const BaseLong op) const66 BaseLong BaseLong::operator^ (const BaseLong op) const
67 {
68 #ifdef HAVE_64BIT_TYPES
69 return BaseLong(value.words ^ op.value.words);
70 #else
71 return BaseLong(HighWord() ^ op.HighWord(), LowWord() ^ op.LowWord());
72 #endif // HAVE_64BIT_TYPES
73 }
74
operator ^=(const BaseLong op)75 BaseLong &BaseLong::operator^= (const BaseLong op)
76 {
77 return *this = *this ^ op;
78 }
79
operator |(const BaseLong op) const80 BaseLong BaseLong::operator| (const BaseLong op) const
81 {
82 #ifdef HAVE_64BIT_TYPES
83 return BaseLong(value.words | op.value.words);
84 #else
85 return BaseLong(HighWord() | op.HighWord(), LowWord() | op.LowWord());
86 #endif // HAVE_64BIT_TYPES
87 }
88
operator |=(const BaseLong op)89 BaseLong &BaseLong::operator|= (const BaseLong op)
90 {
91 return *this = *this | op;
92 }
93
operator &(const BaseLong op) const94 BaseLong BaseLong::operator& (const BaseLong op) const
95 {
96 #ifdef HAVE_64BIT_TYPES
97 return BaseLong(value.words & op.value.words);
98 #else
99 return BaseLong(HighWord() & op.HighWord(), LowWord() & op.LowWord());
100 #endif // HAVE_64BIT_TYPES
101 }
102
operator &=(const BaseLong op)103 BaseLong &BaseLong::operator&= (const BaseLong op)
104 {
105 return *this = *this & op;
106 }
107
operator &&(const BaseLong op) const108 bool BaseLong::operator&& (const BaseLong op) const
109 {
110 return (*this != 0) && (op != 0);
111 }
112
operator ||(const BaseLong op) const113 bool BaseLong::operator|| (const BaseLong op) const
114 {
115 return (*this != 0) || (op != 0);
116 }
117
operator <<(int op) const118 BaseLong BaseLong::operator<< (int op) const
119 {
120 #ifdef HAVE_64BIT_TYPES
121 // TODO: Does this work correctly?
122 return BaseLong(value.words << op);
123 #else
124 u4 n = op; // Always treat this value as positive
125
126 //
127 // Correct compilers treat x << 0 as x, and x << 32+ as 0.
128 // But, since not all compilers follow these rules, we special-case on
129 // the shift amount.
130 //
131 if (n == 0)
132 return *this;
133 if (n < 32)
134 {
135 u4 lo = LowWord();
136 return BaseLong((HighWord() << n) | (lo >> (32 - n)), lo << n);
137 }
138 if (n == 32)
139 return BaseLong(LowWord(), 0);
140 if (n >= 64)
141 return BaseLong(0);
142 return BaseLong(LowWord() << (n - 32), 0);
143 #endif // HAVE_64BIT_TYPES
144 }
145
operator <<=(int op)146 BaseLong &BaseLong::operator<<= (int op)
147 {
148 return *this = *this << op;
149 }
150
operator +(const BaseLong op) const151 BaseLong BaseLong::operator+ (const BaseLong op) const
152 {
153 #ifdef HAVE_64BIT_TYPES
154 return BaseLong(value.words + op.value.words);
155 #else
156 u4 ushort1 = (LowWord() & SHORT_MASK) + (op.LowWord() & SHORT_MASK),
157 ushort2 = (ushort1 >> 16) + (LowWord() >> 16) + (op.LowWord() >> 16),
158 ushort3 = (ushort2 >> 16) + (HighWord() & SHORT_MASK) + (op.HighWord() & SHORT_MASK),
159 ushort4 = (ushort3 >> 16) + (HighWord() >> 16) + (op.HighWord() >> 16);
160
161 return BaseLong((ushort3 & SHORT_MASK) | (ushort4 << 16), (ushort1 & SHORT_MASK) | (ushort2 << 16));
162 #endif // HAVE_64BIT_TYPES
163 }
164
operator +=(const BaseLong op)165 BaseLong &BaseLong::operator+= (const BaseLong op)
166 {
167 return *this = *this + op;
168 }
169
operator ++(int)170 BaseLong BaseLong::operator++ (int)
171 {
172 BaseLong temp = *this;
173 *this += 1;
174 return temp;
175 }
176
operator ++()177 BaseLong BaseLong::operator++ ()
178 {
179 return *this += 1;
180 }
181
operator +() const182 BaseLong BaseLong::operator+ () const
183 {
184 return *this;
185 }
186
operator -() const187 BaseLong BaseLong::operator- () const
188 {
189 return ~(*this) + 1;
190 }
191
operator -(const BaseLong op) const192 BaseLong BaseLong::operator- (const BaseLong op) const
193 {
194 return *this + (-op);
195 }
196
operator -=(const BaseLong op)197 BaseLong &BaseLong::operator-= (const BaseLong op)
198 {
199 return *this = *this - op;
200 }
201
operator --(int)202 BaseLong BaseLong::operator-- (int)
203 {
204 BaseLong temp = *this;
205 *this -= 1;
206 return temp;
207 }
208
operator --()209 BaseLong BaseLong::operator-- ()
210 {
211 return *this -= 1;
212 }
213
operator *(const BaseLong op) const214 BaseLong BaseLong::operator* (const BaseLong op) const
215 {
216 #ifdef HAVE_64BIT_TYPES
217 return BaseLong(value.words * op.value.words);
218 #else
219 u4 x0 = LowWord() & SHORT_MASK,
220 x1 = LowWord() >> 16,
221 x2 = HighWord() & SHORT_MASK,
222 x3 = HighWord() >> 16,
223
224 y0 = op.LowWord() & SHORT_MASK,
225 y1 = op.LowWord() >> 16,
226 y2 = op.HighWord() & SHORT_MASK,
227 y3 = op.HighWord() >> 16;
228
229 BaseLong result = BaseLong(0, x0 * y0),
230 partial = BaseLong(0, x0 * y1);
231 result += partial << 16;
232 partial = BaseLong(0, x0 * y2);
233 result += partial << 32;
234 partial = BaseLong(0, x0 * y3);
235 result += partial << 48;
236
237 partial = BaseLong(0, x1 * y0);
238 result += partial << 16;
239 partial = BaseLong(0, x1 * y1);
240 result += partial << 32;
241 partial = BaseLong(0, x1 * y2);
242 result += partial << 48;
243
244 partial = BaseLong(0, x2 * y0);
245 result += partial << 32;
246 partial = BaseLong(0, x2 * y1);
247 result += partial << 48;
248
249 partial = BaseLong(0, x3 * y0);
250 result += partial << 48;
251
252 return result;
253 #endif // HAVE_64BIT_TYPES
254 }
255
operator *=(const BaseLong op)256 BaseLong &BaseLong::operator*= (const BaseLong op)
257 {
258 return *this = *this * op;
259 }
260
261
BaseLong(u4 high,u4 low)262 BaseLong::BaseLong(u4 high, u4 low)
263 {
264 setHighAndLowWords(high, low);
265 }
266
BaseLong(u4 a)267 BaseLong::BaseLong(u4 a)
268 {
269 setHighAndLowWords(0, a);
270 }
271
BaseLong(i4 a)272 BaseLong::BaseLong(i4 a)
273 {
274 //
275 // Since the carry bit is not guaranteed to ripple, we cannot use this code.
276 //
277 // a >> 31;
278 //
279 setHighAndLowWords(a < 0 ? 0xFFFFFFFF : 0x00000000, a);
280 }
281
282
Divide(const BaseLong & dividend,const BaseLong & divisor,BaseLong & quotient,BaseLong & remainder)283 void BaseLong::Divide(const BaseLong ÷nd, const BaseLong &divisor,
284 BaseLong "ient, BaseLong &remainder)
285 {
286 #ifdef HAVE_64BIT_TYPES
287 quotient = BaseLong(dividend.value.words / divisor.value.words);
288 remainder = BaseLong(dividend.value.words % divisor.value.words);
289 #else
290 u4 high = dividend.HighWord(),
291 low = dividend.LowWord(),
292 remainder_high = 0;
293
294 for (int i = 0; i < 32; i++)
295 {
296 remainder_high = (remainder_high << 1) | (high >> 31);
297 high <<= 1;
298 if ((ULongInt) divisor <= remainder_high)
299 {
300 high++;
301 remainder_high -= divisor.LowWord();
302 }
303 }
304
305 remainder = BaseLong(0, remainder_high);
306
307 for (int j = 0; j < 32; j++)
308 {
309 remainder <<= 1;
310 remainder.setLowWord(remainder.LowWord() | (low >> 31));
311 low <<= 1;
312 if ((ULongInt) divisor <= remainder)
313 {
314 low++;
315 remainder -= divisor;
316 }
317 }
318
319 quotient = BaseLong(high, low);
320 #endif // HAVE_64BIT_TYPES
321 }
322
323
operator /=(const ULongInt op)324 ULongInt &ULongInt::operator/= (const ULongInt op)
325 {
326 return *this = *this / op;
327 }
328
329
operator /(const ULongInt op) const330 ULongInt ULongInt::operator/ (const ULongInt op) const
331 {
332 #ifdef HAVE_64BIT_TYPES
333 return ULongInt(value.words / op.value.words);
334 #else
335 BaseLong quotient,
336 remainder;
337
338 Divide(*this, op, quotient, remainder);
339
340 return quotient;
341 #endif // HAVE_64BIT_TYPES
342 }
343
operator %(const ULongInt op) const344 ULongInt ULongInt::operator% (const ULongInt op) const
345 {
346 #ifdef HAVE_64BIT_TYPES
347 return ULongInt(value.words % op.value.words);
348 #else
349 BaseLong quotient,
350 remainder;
351
352 Divide(*this, op, quotient, remainder);
353
354 return remainder;
355 #endif // HAVE_64BIT_TYPES
356 }
357
operator %=(const ULongInt op)358 ULongInt &ULongInt::operator%= (const ULongInt op)
359 {
360 return *this = *this % op;
361 }
362
363
operator >>(int op) const364 ULongInt ULongInt::operator>> (int op) const
365 {
366 #ifdef HAVE_64BIT_TYPES
367 // TODO: Does this work correctly?
368 return ULongInt(value.words >> op);
369 #else
370 u4 n = op; // Always treat this value as positive
371
372 //
373 // Correct compilers treat x >> as x, and x >> 32+ as 0.
374 // But, since not all compilers follow these rules, we special-case on
375 // the shift amount.
376 //
377
378 if (n == 0)
379 return *this;
380 if (n < 32)
381 {
382 u4 hi = HighWord();
383 return ULongInt(hi >> n, (hi << (32 - n)) | (LowWord() >> n));
384 }
385 if (n == 32)
386 return ULongInt(0, HighWord());
387 if (n >= 64)
388 return ULongInt(0);
389 return ULongInt(0, HighWord() >> (n - 32));
390 #endif // HAVE_64BIT_TYPES
391 }
392
operator >>=(int op)393 ULongInt &ULongInt::operator>>= (int op)
394 {
395 return *this = *this >> op;
396 }
397
operator <(const ULongInt op) const398 bool ULongInt::operator< (const ULongInt op) const
399 {
400 #ifdef HAVE_64BIT_TYPES
401 return value.words < op.value.words;
402 #else
403 u4 a = HighWord(), b = op.HighWord();
404 return (a == b ? LowWord() < op.LowWord() : a < b);
405 #endif // HAVE_64BIT_TYPES
406 }
407
operator <=(const ULongInt op) const408 bool ULongInt::operator<= (const ULongInt op) const
409 {
410 #ifdef HAVE_64BIT_TYPES
411 return value.words <= op.value.words;
412 #else
413 return (*this < op) || (*this == op);
414 #endif // HAVE_64BIT_TYPES
415 }
416
operator >(const ULongInt op) const417 bool ULongInt::operator> (const ULongInt op) const
418 {
419 #ifdef HAVE_64BIT_TYPES
420 return value.words > op.value.words;
421 #else
422 u4 a = HighWord(), b = op.HighWord();
423 return (a == b ? LowWord() > op.LowWord() : a > b);
424 #endif // HAVE_64BIT_TYPES
425 }
426
operator >=(const ULongInt op) const427 bool ULongInt::operator>= (const ULongInt op) const
428 {
429 #ifdef HAVE_64BIT_TYPES
430 return value.words >= op.value.words;
431 #else
432 return (*this > op) || (*this == op);
433 #endif // HAVE_64BIT_TYPES
434 }
435
436 const LongInt *LongInt::max_long_const = NULL;
437 const LongInt *LongInt::min_long_const = NULL;
438
LongInt(const IEEEfloat & f)439 LongInt::LongInt(const IEEEfloat &f)
440 {
441 *this = f.LongValue();
442 }
443
LongInt(const IEEEdouble & d)444 LongInt::LongInt(const IEEEdouble &d)
445 {
446 *this = d.LongValue();
447 }
448
operator /(const LongInt op) const449 LongInt LongInt::operator/ (const LongInt op) const
450 {
451 #ifdef HAVE_64BIT_TYPES
452 bool negative_dividend = (i8) value.words < 0,
453 negative_divisor = (i8) op.value.words < 0;
454
455 u8 a = negative_dividend ? -(i8) value.words : value.words,
456 b = negative_divisor ? -(i8) op.value.words : op.value.words;
457
458 return LongInt((negative_dividend ^ negative_divisor) ? -(a / b) : a / b);
459 #else
460 bool negative_dividend = ((HighWord() & 0x80000000) != 0),
461 negative_divisor = ((op.HighWord() & 0x80000000) != 0);
462
463 BaseLong a = (negative_dividend ? -(*this) : (BaseLong) *this),
464 b = (negative_divisor ? -(op) : (BaseLong) op),
465 quotient,
466 remainder;
467
468 Divide(a, b, quotient, remainder);
469
470 return (negative_dividend ^ negative_divisor ? -quotient : quotient);
471 #endif // HAVE_64BIT_TYPES
472 }
473
operator /=(const LongInt op)474 LongInt &LongInt::operator/= (const LongInt op)
475 {
476 return *this = *this / op;
477 }
478
operator %(const LongInt op) const479 LongInt LongInt::operator% (const LongInt op) const
480 {
481 #ifdef HAVE_64BIT_TYPES
482 bool negative_dividend = (i8) value.words < 0,
483 negative_divisor = (i8) op.value.words < 0;
484
485 u8 a = negative_dividend ? -(i8) value.words : value.words,
486 b = negative_divisor ? -(i8) op.value.words : op.value.words;
487
488 return LongInt(negative_dividend ? -(a % b) : a % b);
489 #else
490 bool negative_dividend = ((HighWord() & 0x80000000) != 0),
491 negative_divisor = ((op.HighWord() & 0x80000000) != 0);
492
493 BaseLong a = (negative_dividend ? -(*this) : (BaseLong) *this),
494 b = (negative_divisor ? -(op) : (BaseLong) op),
495 quotient,
496 remainder;
497
498 Divide(a, b, quotient, remainder);
499
500 return (negative_dividend ? -remainder : remainder);
501 #endif // HAVE_64BIT_TYPES
502 }
503
operator %=(const LongInt op)504 LongInt &LongInt::operator%= (const LongInt op)
505 {
506 return *this = *this % op;
507 }
508
operator >>(int op) const509 LongInt LongInt::operator>> (int op) const
510 {
511 #ifdef HAVE_64BIT_TYPES
512 // TODO: Does this work correctly?
513 return LongInt((u8) ((i8) value.words >> op));
514 #else
515 u4 n = op; // Always treat this value as positive
516
517 //
518 // Correct compilers treat x >> 0 as x, and x >> 32+ as x<0 ? -1 : 0.
519 // But, since not all compilers follow these rules, we special-case on
520 // the shift amount.
521 //
522
523 if (n == 0)
524 return *this;
525
526 i4 hi = HighWord();
527 u4 shift = (hi & SIGN_BIT) ? 0xffffffff : 0;
528
529 if (n < 32)
530 return LongInt(hi >> n, (hi << (32 - n)) | (LowWord() >> n));
531 if (n == 32)
532 return LongInt(shift, hi);
533 if (n >= 64)
534 return LongInt(shift, shift);
535 return LongInt(shift, hi >> (n - 32));
536 #endif // HAVE_64BIT_TYPES
537 }
538
operator >>=(int op)539 LongInt &LongInt::operator>>= (int op)
540 {
541 return *this = *this >> op;
542 }
543
operator <(const LongInt op) const544 bool LongInt::operator< (const LongInt op) const
545 {
546 #ifdef HAVE_64BIT_TYPES
547 return (i8) value.words < (i8) op.value.words;
548 #else
549 i4 a = HighWord(), b = op.HighWord();
550 return (a == b) ? LowWord() < op.LowWord() : a < b;
551 #endif // HAVE_64BIT_TYPES
552 }
553
operator <=(const LongInt op) const554 bool LongInt::operator<= (const LongInt op) const
555 {
556 #ifdef HAVE_64BIT_TYPES
557 return (i8) value.words <= (i8) op.value.words;
558 #else
559 return (*this < op) || (*this == op);
560 #endif // HAVE_64BIT_TYPES
561 }
562
operator >(const LongInt op) const563 bool LongInt::operator> (const LongInt op) const
564 {
565 #ifdef HAVE_64BIT_TYPES
566 return (i8) value.words > (i8) op.value.words;
567 #else
568 i4 a = HighWord(), b = op.HighWord();
569 return (a == b) ? LowWord() > op.LowWord() : a > b;
570 #endif // HAVE_64BIT_TYPES
571 }
572
operator >=(const LongInt op) const573 bool LongInt::operator>= (const LongInt op) const
574 {
575 #ifdef HAVE_64BIT_TYPES
576 return (i8) value.words >= (i8) op.value.words;
577 #else
578 return (*this > op) || (*this == op);
579 #endif // HAVE_64BIT_TYPES
580 }
581
582 #ifdef HAVE_JIKES_NAMESPACE
583 } // Close namespace Jikes block
584 #endif
585
586