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 &dividend, const BaseLong &divisor,
284                       BaseLong &quotient, 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