home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 20 / AACD20.BIN / AACD / Programming / Jikes / Source / src / long.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-24  |  13.4 KB  |  587 lines

  1. // $Id: long.cpp,v 1.20 2001/02/14 21:25:11 mdejong 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://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // 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.  
  18. BaseLong::operator LongInt()
  19. {
  20.     return LongInt(HighWord(), LowWord());
  21. }
  22.  
  23. BaseLong::operator ULongInt()
  24. {
  25.     return ULongInt(HighWord(), LowWord());
  26. }
  27.  
  28. bool BaseLong::operator== (BaseLong op)
  29. {
  30. #ifdef HAVE_UNSIGNED_LONG_LONG
  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_UNSIGNED_LONG_LONG
  36. }
  37.  
  38. bool BaseLong::operator!= (BaseLong op)
  39. {
  40. #ifdef HAVE_UNSIGNED_LONG_LONG
  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_UNSIGNED_LONG_LONG
  46. }
  47.  
  48. bool BaseLong::operator!()
  49. {
  50. #ifdef HAVE_UNSIGNED_LONG_LONG
  51.     return !value.words;
  52. #else
  53.     return (HighWord() != 0) || (LowWord() != 0);
  54. #endif // HAVE_UNSIGNED_LONG_LONG
  55. }
  56.  
  57. BaseLong BaseLong::operator~()
  58. {
  59. #ifdef HAVE_UNSIGNED_LONG_LONG
  60.     return BaseLong(~value.words);
  61. #else
  62.     return BaseLong(~HighWord(), ~LowWord());
  63. #endif // HAVE_UNSIGNED_LONG_LONG
  64. }
  65.  
  66. BaseLong BaseLong::operator^ (BaseLong op)
  67. {
  68. #ifdef HAVE_UNSIGNED_LONG_LONG
  69.     return BaseLong(value.words ^ op.value.words);
  70. #else
  71.     return BaseLong(HighWord() ^ op.HighWord(), LowWord() ^ op.LowWord());
  72. #endif // HAVE_UNSIGNED_LONG_LONG
  73. }
  74.  
  75. BaseLong &BaseLong::operator^= (BaseLong op)
  76. {
  77.     return *this = *this ^ op;
  78. }
  79.  
  80. BaseLong BaseLong::operator| (BaseLong op)
  81. {
  82. #ifdef HAVE_UNSIGNED_LONG_LONG
  83.     return BaseLong(value.words | op.value.words);
  84. #else
  85.     return BaseLong(HighWord() | op.HighWord(), LowWord() | op.LowWord());
  86. #endif // HAVE_UNSIGNED_LONG_LONG
  87. }
  88.  
  89. BaseLong &BaseLong::operator|= (BaseLong op)
  90. {
  91.     return *this = *this | op;
  92. }
  93.  
  94. BaseLong BaseLong::operator& (BaseLong op)
  95. {
  96. #ifdef HAVE_UNSIGNED_LONG_LONG
  97.     return BaseLong(value.words & op.value.words);
  98. #else
  99.     return BaseLong(HighWord() & op.HighWord(), LowWord() & op.LowWord());
  100. #endif // HAVE_UNSIGNED_LONG_LONG
  101. }
  102.  
  103. BaseLong &BaseLong::operator&= (BaseLong op)
  104. {
  105.     return *this = *this & op;
  106. }
  107.  
  108. bool BaseLong::operator&& (BaseLong op)
  109. {
  110.     return (*this != 0) && (op != 0);
  111. }
  112.  
  113. bool BaseLong::operator|| (BaseLong op)
  114. {
  115.     return (*this != 0) || (op != 0);
  116. }
  117.  
  118. BaseLong BaseLong::operator<< (int op)
  119. {
  120. #ifdef HAVE_UNSIGNED_LONG_LONG
  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_UNSIGNED_LONG_LONG
  144. }
  145.  
  146. BaseLong &BaseLong::operator<<= (int op)
  147. {
  148.     return *this = *this << op;
  149. }
  150.  
  151. BaseLong BaseLong::operator+ (BaseLong op)
  152. {
  153. #ifdef HAVE_UNSIGNED_LONG_LONG
  154.     return BaseLong(value.words + op.value.words);
  155. #else
  156.     u4 ushort1 = (LowWord() & 0xFFFF) + (op.LowWord() & 0xFFFF),
  157.        ushort2 = (ushort1 >> 16) + (LowWord() >> 16) + (op.LowWord() >> 16),
  158.        ushort3 = (ushort2 >> 16) + (HighWord() & 0xFFFF) + (op.HighWord() & 0xFFFF),
  159.        ushort4 = (ushort3 >> 16) + (HighWord() >> 16) + (op.HighWord() >> 16);
  160.  
  161.     return BaseLong((ushort3 & 0xFFFF) | (ushort4 << 16), (ushort1 & 0xFFFF) | (ushort2 << 16));
  162. #endif // HAVE_UNSIGNED_LONG_LONG
  163. }
  164.  
  165. BaseLong &BaseLong::operator+= (BaseLong op)
  166. {
  167.     return *this = *this + op;
  168. }
  169.  
  170. BaseLong BaseLong::operator++ (int dummy)
  171. {
  172.     BaseLong temp = *this;
  173.     *this += 1;
  174.     return temp;
  175. }
  176.  
  177. BaseLong BaseLong::operator++ ()
  178. {
  179.     return *this += 1;
  180. }
  181.  
  182. BaseLong BaseLong::operator+ ()
  183. {
  184.     return *this;
  185. }
  186.  
  187. BaseLong BaseLong::operator- ()
  188. {
  189.     return ~(*this) + 1;
  190. }
  191.  
  192. BaseLong BaseLong::operator- (BaseLong op)
  193. {
  194.     return *this + (-op);
  195. }
  196.  
  197. BaseLong &BaseLong::operator-= (BaseLong op)
  198. {
  199.     return *this = *this - op;
  200. }
  201.  
  202. BaseLong BaseLong::operator-- (int dummy)
  203. {
  204.     BaseLong temp = *this;
  205.     *this -= 1;
  206.     return temp;
  207. }
  208.  
  209. BaseLong BaseLong::operator-- ()
  210. {
  211.     return *this -= 1;
  212. }
  213.  
  214. BaseLong BaseLong::operator* (BaseLong op)
  215. {
  216. #ifdef HAVE_UNSIGNED_LONG_LONG
  217.     return BaseLong(value.words * op.value.words);
  218. #else
  219.     u4 x0 = LowWord()   & 0xFFFF,
  220.        x1 = LowWord()  >> 16,
  221.        x2 = HighWord()  & 0xFFFF,
  222.        x3 = HighWord() >> 16,
  223.  
  224.        y0 = op.LowWord()   & 0xFFFF,
  225.        y1 = op.LowWord()  >> 16,
  226.        y2 = op.HighWord()  & 0xFFFF,
  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_UNSIGNED_LONG_LONG
  254. }
  255.  
  256. BaseLong &BaseLong::operator*= (BaseLong op)
  257. {
  258.     return *this = *this * op;
  259. }
  260.  
  261.  
  262. BaseLong::BaseLong(u4 high, u4 low)
  263. {
  264.     setHighAndLowWords(high, low);
  265. }
  266.  
  267. BaseLong::BaseLong(u4 a)
  268. {
  269.     setHighAndLowWords(0, a);
  270. }
  271.  
  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.  
  283. void BaseLong::Divide(BaseLong ÷nd, BaseLong &divisor, BaseLong "ient, BaseLong &remainder)
  284. {
  285. #ifdef HAVE_UNSIGNED_LONG_LONG
  286.     quotient = BaseLong(dividend.value.words / divisor.value.words);
  287.     remainder = BaseLong(dividend.value.words % divisor.value.words);
  288. #else
  289.     u4 high = dividend.HighWord(),
  290.        low  = dividend.LowWord(),
  291.        remainder_high = 0;
  292.  
  293.     for (int i = 0; i < 32; i++)
  294.     {
  295.         remainder_high = (remainder_high << 1) | (high >> 31);
  296.         high <<= 1;
  297.         if ((ULongInt) divisor <= remainder_high)
  298.         {
  299.             high++;
  300.             remainder_high -= divisor.LowWord();
  301.         }
  302.     }
  303.  
  304.     remainder = BaseLong(0, remainder_high);
  305.  
  306.     for (int j = 0; j < 32; j++)
  307.     {
  308.         remainder <<= 1;
  309.         remainder.setLowWord(remainder.LowWord() | (low >> 31));
  310.         low <<= 1;
  311.         if ((ULongInt) divisor <= remainder)
  312.         {
  313.             low++;
  314.             remainder -= divisor;
  315.         }
  316.     }
  317.  
  318.     quotient = BaseLong(high, low);
  319.  
  320.     return;
  321. #endif // HAVE_UNSIGNED_LONG_LONG
  322. }
  323.  
  324.  
  325. ULongInt &ULongInt::operator/= (ULongInt op)
  326. {
  327.     return *this = *this / op;
  328. }
  329.  
  330.  
  331. ULongInt ULongInt::operator/ (ULongInt op)
  332. {
  333. #ifdef HAVE_UNSIGNED_LONG_LONG
  334.     return ULongInt(value.words / op.value.words);
  335. #else
  336.     BaseLong quotient,
  337.              remainder;
  338.  
  339.     Divide(*this, op, quotient, remainder);
  340.  
  341.     return quotient;
  342. #endif // HAVE_UNSIGNED_LONG_LONG
  343. }
  344.  
  345. ULongInt ULongInt::operator% (ULongInt op)
  346. {
  347. #ifdef HAVE_UNSIGNED_LONG_LONG
  348.     return ULongInt(value.words % op.value.words);
  349. #else
  350.     BaseLong quotient,
  351.              remainder;
  352.  
  353.     Divide(*this, op, quotient, remainder);
  354.  
  355.     return remainder;
  356. #endif // HAVE_UNSIGNED_LONG_LONG
  357. }
  358.  
  359. ULongInt &ULongInt::operator%= (ULongInt op)
  360. {
  361.     return *this = *this % op;
  362. }
  363.  
  364.  
  365. ULongInt ULongInt::operator>> (int op)
  366. {
  367. #ifdef HAVE_UNSIGNED_LONG_LONG
  368.     // TODO: Does this work correctly?
  369.     return ULongInt(value.words >> op);
  370. #else
  371.     u4 n = op; // Always treat this value as positive
  372.  
  373.     //
  374.     // Correct compilers treat x >> as x, and x >> 32+ as 0.
  375.     // But, since not all compilers follow these rules, we special-case on
  376.     // the shift amount.
  377.     //
  378.  
  379.     if (n == 0)
  380.         return *this;
  381.     if (n < 32)
  382.     {
  383.         u4 hi = HighWord();
  384.         return ULongInt(hi >> n, (hi << (32 - n)) | (LowWord() >> n));
  385.     }
  386.     if (n == 32)
  387.         return ULongInt(0, HighWord());
  388.     if (n >= 64)
  389.         return ULongInt(0);
  390.     return ULongInt(0, HighWord() >> (n - 32));
  391. #endif // HAVE_UNSIGNED_LONG_LONG
  392. }
  393.  
  394. ULongInt &ULongInt::operator>>= (int op)
  395. {
  396.     return *this = *this >> op;
  397. }
  398.  
  399. bool ULongInt::operator< (ULongInt op)
  400. {
  401. #ifdef HAVE_UNSIGNED_LONG_LONG
  402.     return value.words < op.value.words;
  403. #else
  404.     u4 a = HighWord(), b = op.HighWord();
  405.     return (a == b ? LowWord() < op.LowWord() : a < b);
  406. #endif // HAVE_UNSIGNED_LONG_LONG
  407. }
  408.  
  409. bool ULongInt::operator<= (ULongInt op)
  410. {
  411. #ifdef HAVE_UNSIGNED_LONG_LONG
  412.     return value.words <= op.value.words;
  413. #else
  414.     return (*this < op) || (*this == op);
  415. #endif // HAVE_UNSIGNED_LONG_LONG
  416. }
  417.  
  418. bool ULongInt::operator> (ULongInt op)
  419. {
  420. #ifdef HAVE_UNSIGNED_LONG_LONG
  421.     return value.words > op.value.words;
  422. #else
  423.     u4 a = HighWord(), b = op.HighWord();
  424.     return (a == b ? LowWord() > op.LowWord() : a > b);
  425. #endif // HAVE_UNSIGNED_LONG_LONG
  426. }
  427.  
  428. bool ULongInt::operator>= (ULongInt op)
  429. {
  430. #ifdef HAVE_UNSIGNED_LONG_LONG
  431.     return value.words >= op.value.words;
  432. #else
  433.     return (*this > op) || (*this == op);
  434. #endif // HAVE_UNSIGNED_LONG_LONG
  435. }
  436.  
  437. LongInt *LongInt::max_long_const = NULL;
  438. LongInt *LongInt::min_long_const = NULL;
  439.  
  440. LongInt::LongInt(IEEEfloat f)
  441. {
  442.     *this = f.LongValue();
  443. }
  444.  
  445. LongInt::LongInt(IEEEdouble d)
  446. {
  447.     *this = d.LongValue();
  448. }
  449.  
  450. LongInt LongInt::operator/ (LongInt op)
  451. {
  452. #ifdef HAVE_UNSIGNED_LONG_LONG
  453.     bool negative_dividend = (i8) value.words < 0,
  454.          negative_divisor  = (i8) op.value.words < 0;
  455.  
  456.     u8 a = negative_dividend ? -(i8) value.words : value.words,
  457.        b = negative_divisor  ? -(i8) op.value.words : op.value.words;
  458.  
  459.     return LongInt((negative_dividend ^ negative_divisor) ? -(a / b) : a / b);
  460. #else
  461.     bool negative_dividend = ((HighWord() & 0x80000000) != 0),
  462.          negative_divisor  = ((op.HighWord() & 0x80000000) != 0);
  463.  
  464.     BaseLong a = (negative_dividend ? -(*this) : *this),
  465.              b = (negative_divisor  ? -(op)    : op),
  466.              quotient,
  467.              remainder;
  468.  
  469.     Divide(a, b, quotient, remainder);
  470.  
  471.     return (negative_dividend ^ negative_divisor ? -quotient : quotient);
  472. #endif // HAVE_UNSIGNED_LONG_LONG
  473. }
  474.  
  475. LongInt &LongInt::operator/= (LongInt op)
  476. {
  477.     return *this = *this / op;
  478. }
  479.  
  480. LongInt LongInt::operator% (LongInt op)
  481. {
  482. #ifdef HAVE_UNSIGNED_LONG_LONG
  483.     bool negative_dividend = (i8) value.words < 0,
  484.          negative_divisor  = (i8) op.value.words < 0;
  485.  
  486.     u8 a = negative_dividend ? -(i8) value.words : value.words,
  487.        b = negative_divisor  ? -(i8) op.value.words : op.value.words;
  488.  
  489.     return LongInt(negative_dividend ? -(a % b) : a % b);
  490. #else
  491.     bool negative_dividend = ((HighWord() & 0x80000000) != 0),
  492.          negative_divisor  = ((op.HighWord() & 0x80000000) != 0);
  493.  
  494.     BaseLong a = (negative_dividend ? -(*this) : *this),
  495.              b = (negative_divisor  ? -(op)    : op),
  496.              quotient,
  497.              remainder;
  498.  
  499.     Divide(a, b, quotient, remainder);
  500.  
  501.     return (negative_dividend ? -remainder : remainder);
  502. #endif // HAVE_UNSIGNED_LONG_LONG
  503. }
  504.  
  505. LongInt &LongInt::operator%= (LongInt op)
  506. {
  507.     return *this = *this % op;
  508. }
  509.  
  510. LongInt LongInt::operator>> (int op)
  511. {
  512. #ifdef HAVE_UNSIGNED_LONG_LONG
  513.     // TODO: Does this work correctly?
  514.     return LongInt((u8) ((i8) value.words >> op));
  515. #else
  516.     u4 n = op; // Always treat this value as positive
  517.  
  518.     //
  519.     // Correct compilers treat x >> 0 as x, and x >> 32+ as x<0 ? -1 : 0.
  520.     // But, since not all compilers follow these rules, we special-case on
  521.     // the shift amount.
  522.     //
  523.  
  524.     if (n == 0)
  525.         return *this;
  526.     
  527.     i4 hi = HighWord();
  528.     u4 shift = (hi & 0x80000000) ? 0xffffffff : 0;
  529.  
  530.     if (n < 32)
  531.          return LongInt(hi >> n, (hi << (32 - n)) | (LowWord() >> n));
  532.     if (n == 32)
  533.         return LongInt(shift, hi);
  534.     if (n >= 64)
  535.         return LongInt(shift, shift);
  536.     return LongInt(shift, hi >> (n - 32));
  537. #endif // HAVE_UNSIGNED_LONG_LONG
  538. }
  539.  
  540. LongInt &LongInt::operator>>= (int op)
  541. {
  542.     return *this = *this >> op;
  543. }
  544.  
  545. bool LongInt::operator< (LongInt op)
  546. {
  547. #ifdef HAVE_UNSIGNED_LONG_LONG
  548.     return (i8) value.words < (i8) op.value.words;
  549. #else
  550.     i4 a = HighWord(), b = op.HighWord();
  551.     return (a == b) ? LowWord() < op.LowWord() : a < b;
  552. #endif // HAVE_UNSIGNED_LONG_LONG
  553. }
  554.  
  555. bool LongInt::operator<= (LongInt op)
  556. {
  557. #ifdef HAVE_UNSIGNED_LONG_LONG
  558.     return (i8) value.words <= (i8) op.value.words;
  559. #else
  560.     return (*this < op) || (*this == op);
  561. #endif // HAVE_UNSIGNED_LONG_LONG
  562. }
  563.  
  564. bool LongInt::operator> (LongInt op)
  565. {
  566. #ifdef HAVE_UNSIGNED_LONG_LONG
  567.     return (i8) value.words > (i8) op.value.words;
  568. #else
  569.     i4 a = HighWord(), b = op.HighWord();
  570.     return (a == b) ? LowWord() > op.LowWord() : a > b;
  571. #endif // HAVE_UNSIGNED_LONG_LONG
  572. }
  573.  
  574. bool LongInt::operator>= (LongInt op)
  575. {
  576. #ifdef HAVE_UNSIGNED_LONG_LONG
  577.     return (i8) value.words >= (i8) op.value.words;
  578. #else
  579.     return (*this > op) || (*this == op);
  580. #endif // HAVE_UNSIGNED_LONG_LONG
  581. }
  582.  
  583. #ifdef    HAVE_JIKES_NAMESPACE
  584. }            // Close namespace Jikes block
  585. #endif
  586.  
  587.