LargeInteger.st
branchjv
changeset 18630 a74d669db937
parent 18383 3a40da3624b7
parent 18621 78b4a4b916a5
child 18710 c0a0e0b57e59
equal deleted inserted replaced
18617:fbfd2d411738 18630:a74d669db937
   339     "
   339     "
   340      this is the common case, multiplying with SmallInteger.
   340      this is the common case, multiplying with SmallInteger.
   341      Use a special method for this case ...
   341      Use a special method for this case ...
   342     "
   342     "
   343     ((numberClass := aNumber class) == SmallInteger) ifTrue:[
   343     ((numberClass := aNumber class) == SmallInteger) ifTrue:[
   344         ^ self productFromInteger:aNumber
   344 	^ self productFromInteger:aNumber
   345     ].
   345     ].
   346 
   346 
   347     "
   347     "
   348      if the argument is not a largeInteger, coerce
   348      if the argument is not a largeInteger, coerce
   349     "
   349     "
   350     (numberClass == self class) ifFalse:[
   350     (numberClass == self class) ifFalse:[
   351         ^ self retry:#* coercing:aNumber
   351 	^ self retry:#* coercing:aNumber
   352     ].
   352     ].
   353 
   353 
   354     otherSign := aNumber sign.
   354     otherSign := aNumber sign.
   355     (sign == otherSign) ifTrue:[^ self absMul:aNumber].
   355     (sign == otherSign) ifTrue:[^ self absMul:aNumber].
   356     (otherSign == 0) ifTrue:[^ 0].
   356     (otherSign == 0) ifTrue:[^ 0].
   496     "return the integer part of the quotient of the receivers value
   496     "return the integer part of the quotient of the receivers value
   497      and the arguments value.
   497      and the arguments value.
   498      The result is truncated toward negative infinity
   498      The result is truncated toward negative infinity
   499      and will be negative, if the operands signs differ.
   499      and will be negative, if the operands signs differ.
   500      The following is always true:
   500      The following is always true:
   501         (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   501 	(receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   502 
   502 
   503      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   503      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   504      Especially surprising:
   504      Especially surprising:
   505         -1 // 10 -> -1 (because -(1/10) is truncated towards next smaller integer, which is -1.
   505 	-1 // 10 -> -1 (because -(1/10) is truncated towards next smaller integer, which is -1.
   506         -10 // 3 -> -4 (because -(10/3) is truncated towards next smaller integer, which is -4.
   506 	-10 // 3 -> -4 (because -(10/3) is truncated towards next smaller integer, which is -4.
   507 
   507 
   508      See #quo: which returns -2 in the above case and #rem: which is the corresponding remainder."
   508      See #quo: which returns -2 in the above case and #rem: which is the corresponding remainder."
   509 
   509 
   510     |cls divMod quo abs "{ Class: SmallInteger }" n|
   510     |cls divMod quo abs "{ Class: SmallInteger }" n|
   511 
   511 
   515     "
   515     "
   516      this is the common case, dividing by a SmallInteger.
   516      this is the common case, dividing by a SmallInteger.
   517      Use a special method for this case ...
   517      Use a special method for this case ...
   518     "
   518     "
   519     (cls == SmallInteger) ifTrue:[
   519     (cls == SmallInteger) ifTrue:[
   520         abs := aNumber.
   520 	abs := aNumber.
   521         abs := abs abs.
   521 	abs := abs abs.
   522         (abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
   522 	(abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
   523             divMod := self absFastDivMod:abs.
   523 	    divMod := self absFastDivMod:abs.
   524         ] ifFalse:[
   524 	] ifFalse:[
   525             n := abs asLargeInteger.
   525 	    n := abs asLargeInteger.
   526         ].
   526 	].
   527     ] ifFalse:[
   527     ] ifFalse:[
   528         "
   528 	"
   529          if the argument is not a largeInteger, coerce
   529 	 if the argument is not a largeInteger, coerce
   530         "
   530 	"
   531         (cls == self class) ifFalse:[
   531 	(cls == self class) ifFalse:[
   532             ^ self retry:#// coercing:aNumber
   532 	    ^ self retry:#// coercing:aNumber
   533         ].
   533 	].
   534         n := aNumber
   534 	n := aNumber
   535     ].
   535     ].
   536 
   536 
   537     divMod isNil ifTrue:[
   537     divMod isNil ifTrue:[
   538         divMod := self absDivMod:n.
   538 	divMod := self absDivMod:n.
   539     ].
   539     ].
   540     quo := divMod at:1.
   540     quo := divMod at:1.
   541     (sign == aNumber sign) ifFalse:[
   541     (sign == aNumber sign) ifFalse:[
   542         "/ adjust for truncation if negative and there is a remainder ...
   542 	"/ adjust for truncation if negative and there is a remainder ...
   543         "/ be careful: there is one special case to care for here:
   543 	"/ be careful: there is one special case to care for here:
   544         "/ if quo is maxInt+1, the negation can be represented as a smallInt.
   544 	"/ if quo is maxInt+1, the negation can be represented as a smallInt.
   545         quo := quo setSign:-1.
   545 	quo := quo setSign:-1.
   546         (divMod at:2) == 0 ifFalse:[
   546 	(divMod at:2) == 0 ifFalse:[
   547             ^ quo - 1
   547 	    ^ quo - 1
   548         ].
   548 	].
   549         quo digitLength == SmallInteger maxBytes ifTrue:[
   549 	quo digitLength == SmallInteger maxBytes ifTrue:[
   550             ^ quo compressed
   550 	    ^ quo compressed
   551         ].
   551 	].
   552     ].
   552     ].
   553     ^ quo
   553     ^ quo
   554 
   554 
   555     "
   555     "
   556      (9000000000 // 4000000000)   =   (900 // 400)   ifFalse:[self halt].
   556      (9000000000 // 4000000000)   =   (900 // 400)   ifFalse:[self halt].
   584      negative infinity.
   584      negative infinity.
   585      m < |aNumber| AND there is an integer k with (k * aNumber + m) = self
   585      m < |aNumber| AND there is an integer k with (k * aNumber + m) = self
   586 
   586 
   587      The returned remainder has the same sign as aNumber.
   587      The returned remainder has the same sign as aNumber.
   588      The following is always true:
   588      The following is always true:
   589         (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   589 	(receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   590 
   590 
   591      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   591      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   592      Especially surprising:
   592      Especially surprising:
   593         -1 \\ 10 -> 9  (because -(1/10) is truncated towards next smaller integer, which is -1,
   593 	-1 \\ 10 -> 9  (because -(1/10) is truncated towards next smaller integer, which is -1,
   594                         and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
   594 			and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
   595         -10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
   595 	-10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
   596                         and -4 * 4 gives -12, so we need to add 2 to get the original -10.
   596 			and -4 * 4 gives -12, so we need to add 2 to get the original -10.
   597 
   597 
   598      See #rem: which is the corresponding remainder for division via #quo:.
   598      See #rem: which is the corresponding remainder for division via #quo:.
   599 
   599 
   600      Redefined here for speed."
   600      Redefined here for speed."
   601 
   601 
   602     |abs rem negativeDivisor|
   602     |abs rem negativeDivisor|
   603 
   603 
   604     aNumber negative ifTrue:[
   604     aNumber negative ifTrue:[
   605         negativeDivisor := true.
   605 	negativeDivisor := true.
   606         abs := aNumber negated.
   606 	abs := aNumber negated.
   607     ] ifFalse:[
   607     ] ifFalse:[
   608         negativeDivisor := false.
   608 	negativeDivisor := false.
   609         abs := aNumber.
   609 	abs := aNumber.
   610     ].
   610     ].
   611 
   611 
   612     "
   612     "
   613      this is the common case, dividing by a SmallInteger.
   613      this is the common case, dividing by a SmallInteger.
   614      Use a special method for this case ...
   614      Use a special method for this case ...
   615     "
   615     "
   616     (aNumber class == SmallInteger) ifTrue:[
   616     (aNumber class == SmallInteger) ifTrue:[
   617         (abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
   617 	(abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
   618             rem := (self absFastDivMod:abs) at:2.
   618 	    rem := (self absFastDivMod:abs) at:2.
   619         ] ifFalse:[
   619 	] ifFalse:[
   620             rem := self absMod:abs asLargeInteger
   620 	    rem := self absMod:abs asLargeInteger
   621         ].
   621 	].
   622     ] ifFalse:[
   622     ] ifFalse:[
   623         "
   623 	"
   624          if the argument is not a largeInteger, coerce
   624 	 if the argument is not a largeInteger, coerce
   625         "
   625 	"
   626         (aNumber class == self class) ifFalse:[
   626 	(aNumber class == self class) ifFalse:[
   627             ^ self retry:#\\ coercing:aNumber
   627 	    ^ self retry:#\\ coercing:aNumber
   628         ].
   628 	].
   629 
   629 
   630         rem := self absMod:abs.
   630 	rem := self absMod:abs.
   631     ].
   631     ].
   632 
   632 
   633     rem = 0 ifFalse:[
   633     rem = 0 ifFalse:[
   634         negativeDivisor ifTrue:[
   634 	negativeDivisor ifTrue:[
   635             rem := rem setSign:-1
   635 	    rem := rem setSign:-1
   636         ].
   636 	].
   637         (self negative ~~ negativeDivisor) ifTrue:[
   637 	(self negative ~~ negativeDivisor) ifTrue:[
   638             "different sign, so remainder would have been negative.
   638 	    "different sign, so remainder would have been negative.
   639              rem has been rounded toward zero, this code will simulate
   639 	     rem has been rounded toward zero, this code will simulate
   640              rounding to negative infinity."
   640 	     rounding to negative infinity."
   641 
   641 
   642             rem := aNumber - rem.
   642 	    rem := aNumber - rem.
   643         ].
   643 	].
   644     ].
   644     ].
   645     ^ rem
   645     ^ rem
   646 
   646 
   647     "
   647     "
   648      (9000000000 \\ 4000000000)   = (900 \\ 400 * 10000000)  ifFalse:[self halt].
   648      (9000000000 \\ 4000000000)   = (900 \\ 400 * 10000000)  ifFalse:[self halt].
   745 
   745 
   746     "
   746     "
   747      special case for SmallInteger minVal
   747      special case for SmallInteger minVal
   748     "
   748     "
   749     sign == 1 ifTrue:[
   749     sign == 1 ifTrue:[
   750         sz := digitByteArray size.
   750 	sz := digitByteArray size.
   751 %{
   751 %{
   752         int idx;
   752 #ifdef __SCHTEAM__
   753         unsigned char *bp;
   753 #else /* not SCHTEAM */
   754 
   754 	int idx;
   755         bp = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
   755 	unsigned char *bp;
   756         idx = __intVal(sz);
   756 
   757 
   757 	bp = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
   758         while ((idx > 1) && (bp[idx-1] == 0)) idx--;
   758 	idx = __intVal(sz);
   759 
   759 
   760         if (idx == sizeof(INT)) {
   760 	while ((idx > 1) && (bp[idx-1] == 0)) idx--;
   761 #if defined(__LSBFIRST__)
   761 
   762 # if __POINTER_SIZE__ == 8
   762 	if (idx == sizeof(INT)) {
   763             if ( ((unsigned INT *)bp)[0] == 0x4000000000000000L)
   763 # if defined(__LSBFIRST__)
       
   764 #  if __POINTER_SIZE__ == 8
       
   765 	    if ( ((unsigned INT *)bp)[0] == 0x4000000000000000L)
       
   766 #  else
       
   767 	    if ( ((unsigned INT *)bp)[0] == 0x40000000)
       
   768 #  endif
   764 # else
   769 # else
   765             if ( ((unsigned INT *)bp)[0] == 0x40000000)
   770 	    /*
       
   771 	     * generic code
       
   772 	     */
       
   773 	    if ((bp[idx-1] == 0x40)
       
   774 	     && (bp[idx-2] == 0)
       
   775 	     && (bp[idx-3] == 0)
       
   776 	     && (bp[idx-4] == 0)
       
   777 #  if __POINTER_SIZE__ == 8
       
   778 	     && (bp[idx-5] == 0)
       
   779 	     && (bp[idx-6] == 0)
       
   780 	     && (bp[idx-7] == 0)
       
   781 	     && (bp[idx-8] == 0)
       
   782 #  endif
       
   783 	    )
   766 # endif
   784 # endif
   767 #else
   785 	    {
   768             /*
   786 		RETURN (__mkSmallInteger(_MIN_INT));
   769              * generic code
   787 	    }
   770              */
   788 	}
   771             if ((bp[idx-1] == 0x40)
       
   772              && (bp[idx-2] == 0)
       
   773              && (bp[idx-3] == 0)
       
   774              && (bp[idx-4] == 0)
       
   775 # if __POINTER_SIZE__ == 8
       
   776              && (bp[idx-5] == 0)
       
   777              && (bp[idx-6] == 0)
       
   778              && (bp[idx-7] == 0)
       
   779              && (bp[idx-8] == 0)
       
   780 # endif
       
   781             )
       
   782 #endif
   789 #endif
   783             {
       
   784                 RETURN (__mkSmallInteger(_MIN_INT));
       
   785             }
       
   786         }
       
   787 %}.
   790 %}.
   788 "/      sz == 4 ifTrue:[
   791 
   789 "/        (digitByteArray at:1) == 0 ifTrue:[
   792 	sz == SmallInteger maxBytes ifTrue:[
   790 "/          (digitByteArray at:2) == 0 ifTrue:[
   793 	  (digitByteArray at:1) == 0 ifTrue:[
   791 "/            (digitByteArray at:3) == 0 ifTrue:[
   794 	   (digitByteArray at:2) == 0 ifTrue:[
   792 "/              (digitByteArray at:4) == 16r40 ifTrue:[
   795 	    (digitByteArray at:3) == 0 ifTrue:[
   793 "/                ^ SmallInteger minVal
   796 		SmallInteger maxBytes == 8 ifTrue:[
   794 "/              ].
   797 		  (digitByteArray at:4) == 0 ifTrue:[
   795 "/            ]
   798 		   (digitByteArray at:5) == 0 ifTrue:[
   796 "/          ]
   799 		    (digitByteArray at:6) == 0 ifTrue:[
   797 "/        ]
   800 		     (digitByteArray at:7) == 0 ifTrue:[
   798 "/      ]
   801 		      (digitByteArray at:8) == 16r40 ifTrue:[
       
   802 			^ SmallInteger minVal
       
   803 		      ].
       
   804 		     ]
       
   805 		    ]
       
   806 		   ]
       
   807 		  ]
       
   808 		] ifFalse:[
       
   809 		  (digitByteArray at:4) == 16r40 ifTrue:[
       
   810 		    ^ SmallInteger minVal
       
   811 		  ].
       
   812 		]
       
   813 	    ]
       
   814 	   ]
       
   815 	  ]
       
   816 	].
   799     ].
   817     ].
   800     "/ cg - can share the digits ...
   818     "/ cg - can share the digits ...
   801     newNumber := self class digitBytes:digitByteArray sign:(sign negated).
   819     newNumber := self class digitBytes:digitByteArray sign:(sign negated).
   802     ^ newNumber
   820     ^ newNumber
   803 !
   821 !
   807      The result is truncated toward zero (which is different from //, which
   825      The result is truncated toward zero (which is different from //, which
   808      truncates toward negative infinity).
   826      truncates toward negative infinity).
   809      The results sign is negative if the receiver has a sign
   827      The results sign is negative if the receiver has a sign
   810      different from the args sign.
   828      different from the args sign.
   811      The following is always true:
   829      The following is always true:
   812         (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
   830 	(receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
   813     "
   831     "
   814 
   832 
   815     |otherSign quo abs "{ Class: SmallInteger }" |
   833     |otherSign quo abs "{ Class: SmallInteger }" |
   816 
   834 
   817     otherSign := aNumber sign.
   835     otherSign := aNumber sign.
   819     "
   837     "
   820      this is the common case, dividing by a SmallInteger.
   838      this is the common case, dividing by a SmallInteger.
   821      Use a special method for this case ...
   839      Use a special method for this case ...
   822     "
   840     "
   823     (aNumber class == SmallInteger) ifTrue:[
   841     (aNumber class == SmallInteger) ifTrue:[
   824         abs := aNumber.
   842 	abs := aNumber.
   825         abs := abs abs.
   843 	abs := abs abs.
   826         (abs between:1 and:16r00ffffff) ifTrue:[
   844 	(abs between:1 and:16r00ffffff) ifTrue:[
   827             quo := (self absFastDivMod:abs) at:1.
   845 	    quo := (self absFastDivMod:abs) at:1.
   828             (sign == otherSign) ifTrue:[^ quo].
   846 	    (sign == otherSign) ifTrue:[^ quo].
   829             ^ quo setSign:-1
   847 	    ^ quo setSign:-1
   830         ]
   848 	]
   831     ].
   849     ].
   832 
   850 
   833     "
   851     "
   834      if the argument is not a largeInteger, coerce
   852      if the argument is not a largeInteger, coerce
   835     "
   853     "
   836     (aNumber class == self class) ifFalse:[
   854     (aNumber class == self class) ifFalse:[
   837         ^ self retry:#quo: coercing:aNumber
   855 	^ self retry:#quo: coercing:aNumber
   838     ].
   856     ].
   839 
   857 
   840     sign < 0 ifTrue:[
   858     sign < 0 ifTrue:[
   841         (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber negated) at:1].
   859 	(sign == otherSign) ifTrue:[^ (self absDivMod:aNumber negated) at:1].
   842     ] ifFalse:[
   860     ] ifFalse:[
   843         (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber) at:1].
   861 	(sign == otherSign) ifTrue:[^ (self absDivMod:aNumber) at:1].
   844     ].
   862     ].
   845     ^ ((self absDivMod:aNumber) at:1) setSign:-1
   863     ^ ((self absDivMod:aNumber) at:1) setSign:-1
   846 
   864 
   847     "
   865     "
   848      900 // 400
   866      900 // 400
   872 
   890 
   873 rem:aNumber
   891 rem:aNumber
   874     "return the remainder of division of the receiver by the argument, aNumber.
   892     "return the remainder of division of the receiver by the argument, aNumber.
   875      The returned remainder has the same sign as the receiver.
   893      The returned remainder has the same sign as the receiver.
   876      The following is always true:
   894      The following is always true:
   877         (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
   895 	(receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
   878     "
   896     "
   879 
   897 
   880     |rem abs "{ Class: SmallInteger }" |
   898     |rem abs "{ Class: SmallInteger }" |
   881 
   899 
   882     "
   900     "
   883      this is the common case, dividing by a SmallInteger.
   901      this is the common case, dividing by a SmallInteger.
   884      Use special code for this case ...
   902      Use special code for this case ...
   885     "
   903     "
   886     (aNumber class == SmallInteger) ifTrue:[
   904     (aNumber class == SmallInteger) ifTrue:[
   887         abs := aNumber.
   905 	abs := aNumber.
   888         abs := abs abs.
   906 	abs := abs abs.
   889         (abs between:1 and:16r00ffffff) ifTrue:[
   907 	(abs between:1 and:16r00ffffff) ifTrue:[
   890             rem := (self absFastDivMod:abs) at:2.
   908 	    rem := (self absFastDivMod:abs) at:2.
   891         ] ifFalse:[
   909 	] ifFalse:[
   892             rem := self absMod:abs asLargeInteger
   910 	    rem := self absMod:abs asLargeInteger
   893         ].
   911 	].
   894     ] ifFalse:[
   912     ] ifFalse:[
   895         "
   913 	"
   896          if the argument is not a largeInteger, coerce
   914 	 if the argument is not a largeInteger, coerce
   897         "
   915 	"
   898         (aNumber class == self class) ifFalse:[
   916 	(aNumber class == self class) ifFalse:[
   899             ^ self retry:#rem coercing:aNumber
   917 	    ^ self retry:#rem coercing:aNumber
   900         ].
   918 	].
   901 
   919 
   902         rem := self absMod:aNumber
   920 	rem := self absMod:aNumber
   903     ].
   921     ].
   904 
   922 
   905     sign < 0 ifTrue:[
   923     sign < 0 ifTrue:[
   906         ^ rem setSign:-1
   924 	^ rem setSign:-1
   907     ].
   925     ].
   908     ^ rem
   926     ^ rem
   909 
   927 
   910     "
   928     "
   911      900 \\ 400
   929      900 \\ 400
  1325      but a new number is returned. Should be named #withBitSet:"
  1343      but a new number is returned. Should be named #withBitSet:"
  1326 
  1344 
  1327     |myDigitLength newDigitLength newDigitBytes byteIndexOfBitToSet|
  1345     |myDigitLength newDigitLength newDigitBytes byteIndexOfBitToSet|
  1328 
  1346 
  1329     index <= 0 ifTrue:[
  1347     index <= 0 ifTrue:[
  1330         ^ SubscriptOutOfBoundsSignal
  1348 	^ SubscriptOutOfBoundsSignal
  1331                 raiseRequestWith:index
  1349 		raiseRequestWith:index
  1332                 errorString:'index out of bounds'
  1350 		errorString:'index out of bounds'
  1333     ].
  1351     ].
  1334 
  1352 
  1335     myDigitLength := digitByteArray size.
  1353     myDigitLength := digitByteArray size.
  1336     byteIndexOfBitToSet := ((index-1)//8)+1.
  1354     byteIndexOfBitToSet := ((index-1)//8)+1.
  1337     byteIndexOfBitToSet > myDigitLength ifTrue:[
  1355     byteIndexOfBitToSet > myDigitLength ifTrue:[
  1338         newDigitLength := myDigitLength max:byteIndexOfBitToSet.
  1356 	newDigitLength := myDigitLength max:byteIndexOfBitToSet.
  1339         newDigitBytes := ByteArray new:newDigitLength.
  1357 	newDigitBytes := ByteArray new:newDigitLength.
  1340         newDigitBytes replaceFrom:1 to:myDigitLength with:digitByteArray startingAt:1.
  1358 	newDigitBytes replaceFrom:1 to:myDigitLength with:digitByteArray startingAt:1.
  1341     ] ifFalse:[
  1359     ] ifFalse:[
  1342         newDigitBytes := digitByteArray copy
  1360 	newDigitBytes := digitByteArray copy
  1343     ].
  1361     ].
  1344     newDigitBytes
  1362     newDigitBytes
  1345         at:byteIndexOfBitToSet
  1363 	at:byteIndexOfBitToSet
  1346         put:((newDigitBytes at:byteIndexOfBitToSet) setBit:(((index-1)\\8)+1)).
  1364 	put:((newDigitBytes at:byteIndexOfBitToSet) setBit:(((index-1)\\8)+1)).
  1347     ^ self class digitBytes:newDigitBytes sign:sign
  1365     ^ self class digitBytes:newDigitBytes sign:sign
  1348 
  1366 
  1349     "
  1367     "
  1350      TestCase assert:( 16r80000000 setBit:3  ) = 16r80000004
  1368      TestCase assert:( 16r80000000 setBit:3  ) = 16r80000004
  1351      TestCase assert:( 16r80000000 setBit:33 ) = 16r180000000
  1369      TestCase assert:( 16r80000000 setBit:33 ) = 16r180000000
  1597 #ifdef __SCHTEAM__
  1615 #ifdef __SCHTEAM__
  1598     return context._RETURN( ((STLargeInteger)self).digitByteAt( index.intValue() ) );
  1616     return context._RETURN( ((STLargeInteger)self).digitByteAt( index.intValue() ) );
  1599 #endif
  1617 #endif
  1600 %}.
  1618 %}.
  1601     sign >= 0 ifTrue:[
  1619     sign >= 0 ifTrue:[
  1602         index > digitByteArray size ifTrue:[
  1620 	index > digitByteArray size ifTrue:[
  1603             ^ 0
  1621 	    ^ 0
  1604         ].
  1622 	].
  1605         ^ digitByteArray at:index.
  1623 	^ digitByteArray at:index.
  1606     ].
  1624     ].
  1607 
  1625 
  1608     "/ negative int - do 2's complement here
  1626     "/ negative int - do 2's complement here
  1609 
  1627 
  1610     t := self bitInvert + 1.
  1628     t := self bitInvert + 1.
  1611     t setSign:1.
  1629     t setSign:1.
  1612     digits := t digitBytes.
  1630     digits := t digitBytes.
  1613     index > digits size ifTrue:[
  1631     index > digits size ifTrue:[
  1614         ^ 16rFF
  1632 	^ 16rFF
  1615     ].
  1633     ].
  1616     ^ digits at:index.
  1634     ^ digits at:index.
  1617 
  1635 
  1618     "
  1636     "
  1619      16r11111111111111111111 negated digitByteAt:1
  1637      16r11111111111111111111 negated digitByteAt:1
  2358     anInteger == 0 ifTrue:[^ 0].
  2376     anInteger == 0 ifTrue:[^ 0].
  2359     anInteger == 1 ifTrue:[^ self].
  2377     anInteger == 1 ifTrue:[^ self].
  2360 
  2378 
  2361     num := anInteger abs.
  2379     num := anInteger abs.
  2362     (num > 16r3FFFFF) ifTrue:[
  2380     (num > 16r3FFFFF) ifTrue:[
  2363         "if num is too big (so that multiplying by a byte could create a Large)"
  2381 	"if num is too big (so that multiplying by a byte could create a Large)"
  2364 
  2382 
  2365         ^ anInteger retry:#* coercing:self
  2383 	^ anInteger retry:#* coercing:self
  2366     ].
  2384     ].
  2367 
  2385 
  2368     len := digitByteArray size.
  2386     len := digitByteArray size.
  2369 
  2387 
  2370     val := num.
  2388     val := num.
  2371     val <= 16rFF ifTrue:[
  2389     val <= 16rFF ifTrue:[
  2372         lResult := len + 1.
  2390 	lResult := len + 1.
  2373     ] ifFalse:[
  2391     ] ifFalse:[
  2374         val <= 16rFFFF ifTrue:[
  2392 	val <= 16rFFFF ifTrue:[
  2375             lResult := len + 2
  2393 	    lResult := len + 2
  2376         ] ifFalse:[
  2394 	] ifFalse:[
  2377             val <= 16rFFFFFF ifTrue:[
  2395 	    val <= 16rFFFFFF ifTrue:[
  2378                 lResult := len + 4.
  2396 		lResult := len + 4.
  2379             ] ifFalse:[
  2397 	    ] ifFalse:[
  2380                 lResult := len + 6.
  2398 		lResult := len + 6.
  2381             ]
  2399 	    ]
  2382         ]
  2400 	]
  2383     ].
  2401     ].
  2384     resultDigitByteArray := ByteArray uninitializedNew:lResult.
  2402     resultDigitByteArray := ByteArray uninitializedNew:lResult.
  2385     result := self class basicNew setDigits:resultDigitByteArray.
  2403     result := self class basicNew setDigits:resultDigitByteArray.
  2386 
  2404 
  2387     anInteger < 0 ifTrue:[
  2405     anInteger < 0 ifTrue:[
  2388         sign > 0 ifTrue:[
  2406 	sign > 0 ifTrue:[
  2389             result setSign:-1
  2407 	    result setSign:-1
  2390         ].
  2408 	].
  2391     ] ifFalse:[
  2409     ] ifFalse:[
  2392         sign < 0 ifTrue:[
  2410 	sign < 0 ifTrue:[
  2393             result setSign:sign
  2411 	    result setSign:sign
  2394         ]
  2412 	]
  2395     ].
  2413     ].
  2396 
  2414 
  2397     ok := false.
  2415     ok := false.
  2398 %{
  2416 %{
  2399     OBJ __digitByteArray = __INST(digitByteArray);
  2417     OBJ __digitByteArray = __INST(digitByteArray);
  2400 
  2418 
  2401     if (__isSmallInteger(len)
  2419     if (__isSmallInteger(len)
  2402      && __isByteArray(__digitByteArray)
  2420      && __isByteArray(__digitByteArray)
  2403      && __isByteArray(resultDigitByteArray)) {
  2421      && __isByteArray(resultDigitByteArray)) {
  2404         INT _l = __intVal(len);
  2422 	INT _l = __intVal(len);
  2405         INT _v = __intVal(val);
  2423 	INT _v = __intVal(val);
  2406         unsigned INT _carry = 0;
  2424 	unsigned INT _carry = 0;
  2407         unsigned INT _prod;
  2425 	unsigned INT _prod;
  2408         unsigned char *digitP = __ByteArrayInstPtr(__digitByteArray)->ba_element;
  2426 	unsigned char *digitP = __ByteArrayInstPtr(__digitByteArray)->ba_element;
  2409         unsigned char *resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  2427 	unsigned char *resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  2410 
  2428 
  2411         /*
  2429 	/*
  2412          * skipping zeros does not help much (a few percent) on
  2430 	 * skipping zeros does not help much (a few percent) on
  2413          * a P5 or other CPUS with a fast multiplier.
  2431 	 * a P5 or other CPUS with a fast multiplier.
  2414          * It may make more of a difference on CPUs with slower 0-multiply.
  2432 	 * It may make more of a difference on CPUs with slower 0-multiply.
  2415          */
  2433 	 */
  2416         while ((_l >= sizeof(INT)) && (((unsigned INT *)digitP)[0] == 0)) {
  2434 	while ((_l >= sizeof(INT)) && (((unsigned INT *)digitP)[0] == 0)) {
  2417             ((unsigned INT *)resultP)[0] = 0;
  2435 	    ((unsigned INT *)resultP)[0] = 0;
  2418             digitP += sizeof(INT);
  2436 	    digitP += sizeof(INT);
  2419             resultP += sizeof(INT);
  2437 	    resultP += sizeof(INT);
  2420             _l -= sizeof(INT);
  2438 	    _l -= sizeof(INT);
  2421         }
  2439 	}
  2422 
  2440 
  2423 #if defined(__LSBFIRST__)
  2441 #if defined(__LSBFIRST__)
  2424 # if defined (__GNUC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
  2442 # if defined (__GNUC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
  2425         /*
  2443 	/*
  2426          * can do it long-word-wise;
  2444 	 * can do it long-word-wise;
  2427          * 32*32 -> 64 multiplication
  2445 	 * 32*32 -> 64 multiplication
  2428          */
  2446 	 */
  2429         while (_l > 3) {
  2447 	while (_l > 3) {
  2430             unsigned __pHi, __pLow;
  2448 	    unsigned __pHi, __pLow;
  2431             unsigned __digit;
  2449 	    unsigned __digit;
  2432 
  2450 
  2433             /*
  2451 	    /*
  2434              * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
  2452 	     * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
  2435              * + maxCarry (0xFFFF.FFFF)  -> 0xFFFF.FFFF.0000.0000
  2453 	     * + maxCarry (0xFFFF.FFFF)  -> 0xFFFF.FFFF.0000.0000
  2436              */
  2454 	     */
  2437             __digit = ((unsigned long *)digitP)[0];
  2455 	    __digit = ((unsigned long *)digitP)[0];
  2438             asm ("mull %3               \n\
  2456 	    asm ("mull %3               \n\
  2439                   addl %4,%%eax         \n\
  2457 		  addl %4,%%eax         \n\
  2440                   adcl $0,%%edx"
  2458 		  adcl $0,%%edx"
  2441                     : "=a"  (__pLow),
  2459 		    : "=a"  (__pLow),
  2442                       "=d"  (__pHi)
  2460 		      "=d"  (__pHi)
  2443                     : "0"   (__digit),
  2461 		    : "0"   (__digit),
  2444                       "1"   ((unsigned long)(_v)),
  2462 		      "1"   ((unsigned long)(_v)),
  2445                       "rm"  ((unsigned long)(_carry)) );
  2463 		      "rm"  ((unsigned long)(_carry)) );
  2446 
  2464 
  2447             ((unsigned long *)resultP)[0] = __pLow;
  2465 	    ((unsigned long *)resultP)[0] = __pLow;
  2448             _carry = __pHi;
  2466 	    _carry = __pHi;
  2449             digitP += 4;
  2467 	    digitP += 4;
  2450             resultP += 4;
  2468 	    resultP += 4;
  2451             _l -= 4;
  2469 	    _l -= 4;
  2452         }
  2470 	}
  2453 # else /* not GNU-i386 */
  2471 # else /* not GNU-i386 */
  2454 #  if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
  2472 #  if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
  2455         /*
  2473 	/*
  2456          * can do it long-word-wise;
  2474 	 * can do it long-word-wise;
  2457          * 32*32 -> 64 multiplication
  2475 	 * 32*32 -> 64 multiplication
  2458          */
  2476 	 */
  2459         while (_l > 3) {
  2477 	while (_l > 3) {
  2460             unsigned __pLow;
  2478 	    unsigned __pLow;
  2461             unsigned digit;
  2479 	    unsigned digit;
  2462 
  2480 
  2463             /*
  2481 	    /*
  2464              * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
  2482 	     * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
  2465              * + maxCarry (0xFFFF.FFFF)  -> 0xFFFF.FFFF.0000.0000
  2483 	     * + maxCarry (0xFFFF.FFFF)  -> 0xFFFF.FFFF.0000.0000
  2466              */
  2484 	     */
  2467 /*
  2485 /*
  2468             digit = ((unsigned long *)digitP)[0];
  2486 	    digit = ((unsigned long *)digitP)[0];
  2469             edx::eax = (digit * _v);
  2487 	    edx::eax = (digit * _v);
  2470             edx::eax += _carry;
  2488 	    edx::eax += _carry;
  2471             ((unsigned long *)resultP)[0] = eax; -- pLow
  2489 	    ((unsigned long *)resultP)[0] = eax; -- pLow
  2472             _carry = edx; -- pHigh
  2490 	    _carry = edx; -- pHigh
  2473             digitP += 4;
  2491 	    digitP += 4;
  2474             resultP += 4;
  2492 	    resultP += 4;
  2475 */
  2493 */
  2476             digit = ((unsigned long *)digitP)[0];
  2494 	    digit = ((unsigned long *)digitP)[0];
  2477             asm {
  2495 	    asm {
  2478                 mov   eax, digit
  2496 		mov   eax, digit
  2479                 mov   edx, _v
  2497 		mov   edx, _v
  2480                 mul   edx
  2498 		mul   edx
  2481                 add   eax, _carry
  2499 		add   eax, _carry
  2482                 adc   edx, 0
  2500 		adc   edx, 0
  2483                 mov   __pLow, eax
  2501 		mov   __pLow, eax
  2484                 mov   _carry, edx
  2502 		mov   _carry, edx
  2485             }
  2503 	    }
  2486 
  2504 
  2487             ((unsigned long *)resultP)[0] = __pLow;
  2505 	    ((unsigned long *)resultP)[0] = __pLow;
  2488             digitP += 4;
  2506 	    digitP += 4;
  2489             resultP += 4;
  2507 	    resultP += 4;
  2490             _l -= 4;
  2508 	    _l -= 4;
  2491         }
  2509 	}
  2492 #  else /* not WIN32-i386 */
  2510 #  else /* not WIN32-i386 */
  2493 #   if defined(INT64)
  2511 #   if defined(INT64)
  2494         if (_v <= 0xFFFFFFFFL) {
  2512 	if (_v <= 0xFFFFFFFFL) {
  2495             /*
  2513 	    /*
  2496              * have a 64bit int type ... good
  2514 	     * have a 64bit int type ... good
  2497              */
  2515 	     */
  2498             UINT64 _prod64;
  2516 	    UINT64 _prod64;
  2499 
  2517 
  2500             /* have 64bit ints; can do it int-wise
  2518 	    /* have 64bit ints; can do it int-wise
  2501              *
  2519 	     *
  2502              * max: 0xFFFFFFFF * 0xFFFFFFFF -> 0xFFFFFFFE.0001
  2520 	     * max: 0xFFFFFFFF * 0xFFFFFFFF -> 0xFFFFFFFE.0001
  2503              * + maxCarry (0xFFFFFFFF)  -> 0xFFFFFFFF.0000
  2521 	     * + maxCarry (0xFFFFFFFF)  -> 0xFFFFFFFF.0000
  2504              */
  2522 	     */
  2505             while (_l > 3) {
  2523 	    while (_l > 3) {
  2506                 unsigned __t;
  2524 		unsigned __t;
  2507 
  2525 
  2508                 __t = ((unsigned *)digitP)[0];
  2526 		__t = ((unsigned *)digitP)[0];
  2509                 digitP += 4;
  2527 		digitP += 4;
  2510                 _prod64 = (INT64)_v;
  2528 		_prod64 = (INT64)_v;
  2511                 _prod64 *= __t;
  2529 		_prod64 *= __t;
  2512                 _prod64 += _carry;
  2530 		_prod64 += _carry;
  2513                 ((unsigned *)resultP)[0] = _prod64 /* & 0xFFFFFFFFL */;
  2531 		((unsigned *)resultP)[0] = _prod64 /* & 0xFFFFFFFFL */;
  2514                 _carry = _prod64 >> 32;
  2532 		_carry = _prod64 >> 32;
  2515                 resultP += 4;
  2533 		resultP += 4;
  2516                 _l -= 4;
  2534 		_l -= 4;
  2517             }
  2535 	    }
  2518             if (_l > 1) {
  2536 	    if (_l > 1) {
  2519                 unsigned short __t;
  2537 		unsigned short __t;
  2520 
  2538 
  2521                 __t = ((unsigned short *)digitP)[0];
  2539 		__t = ((unsigned short *)digitP)[0];
  2522                 digitP += 2;
  2540 		digitP += 2;
  2523                 _prod64 = (INT64)_v;
  2541 		_prod64 = (INT64)_v;
  2524                 _prod64 *= __t;
  2542 		_prod64 *= __t;
  2525                 _prod64 += _carry;
  2543 		_prod64 += _carry;
  2526                 ((unsigned short *)resultP)[0] = _prod64 /* & 0xFFFF */;
  2544 		((unsigned short *)resultP)[0] = _prod64 /* & 0xFFFF */;
  2527                 _carry = _prod64 >> 16;
  2545 		_carry = _prod64 >> 16;
  2528                 resultP += 2;
  2546 		resultP += 2;
  2529                 _l -= 2;
  2547 		_l -= 2;
  2530             }
  2548 	    }
  2531             if (_l > 0) {
  2549 	    if (_l > 0) {
  2532                 _prod64 = *digitP++ * _v + _carry;
  2550 		_prod64 = *digitP++ * _v + _carry;
  2533                 *resultP++ = _prod64 /* & 0xFF */;
  2551 		*resultP++ = _prod64 /* & 0xFF */;
  2534                 _carry = _prod64 >> 8;
  2552 		_carry = _prod64 >> 8;
  2535                 _l--;
  2553 		_l--;
  2536             }
  2554 	    }
  2537         }
  2555 	}
  2538 #   else /* no INT64 type */
  2556 #   else /* no INT64 type */
  2539         if (_v <= 0xFFFF) {
  2557 	if (_v <= 0xFFFF) {
  2540             /* can do it short-wise
  2558 	    /* can do it short-wise
  2541              *
  2559 	     *
  2542              * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
  2560 	     * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
  2543              * + maxCarry (0xFFFF)  -> 0xFFFF.0000
  2561 	     * + maxCarry (0xFFFF)  -> 0xFFFF.0000
  2544              */
  2562 	     */
  2545             while (_l > 1) {
  2563 	    while (_l > 1) {
  2546                 _prod = ((unsigned short *)digitP)[0] * _v + _carry;
  2564 		_prod = ((unsigned short *)digitP)[0] * _v + _carry;
  2547                 ((unsigned short *)resultP)[0] = _prod /* & 0xFFFF */;
  2565 		((unsigned short *)resultP)[0] = _prod /* & 0xFFFF */;
  2548                 _carry = _prod >> 16;
  2566 		_carry = _prod >> 16;
  2549                 digitP += 2;
  2567 		digitP += 2;
  2550                 resultP += 2;
  2568 		resultP += 2;
  2551                 _l -= 2;
  2569 		_l -= 2;
  2552             }
  2570 	    }
  2553         }
  2571 	}
  2554 #   endif /* no INT64 */
  2572 #   endif /* no INT64 */
  2555 #  endif /* not WIN32-i386 */
  2573 #  endif /* not WIN32-i386 */
  2556 # endif /* not GNU-i386 */
  2574 # endif /* not GNU-i386 */
  2557 #else /* not LSB_FIRST */
  2575 #else /* not LSB_FIRST */
  2558 
  2576 
  2559 # ifdef __mips__
  2577 # ifdef __mips__
  2560 #  define LOAD_WORD_WISE
  2578 #  define LOAD_WORD_WISE
  2561    /* no, STORE_WORD_WISE makes it slower */
  2579    /* no, STORE_WORD_WISE makes it slower */
  2562 # endif
  2580 # endif
  2563 
  2581 
  2564         if (_v <= 0xFFFF) {
  2582 	if (_v <= 0xFFFF) {
  2565             /* can do it short-wise
  2583 	    /* can do it short-wise
  2566              *
  2584 	     *
  2567              * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
  2585 	     * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
  2568              * + maxCarry (0xFFFF)  -> 0xFFFF.0000
  2586 	     * + maxCarry (0xFFFF)  -> 0xFFFF.0000
  2569              */
  2587 	     */
  2570             while (_l > 1) {
  2588 	    while (_l > 1) {
  2571                 unsigned int t;
  2589 		unsigned int t;
  2572 
  2590 
  2573 #if defined(LOAD_WORD_WISE)
  2591 #if defined(LOAD_WORD_WISE)
  2574                 /* better fetch short-wise */
  2592 		/* better fetch short-wise */
  2575                 t = ((unsigned short *)digitP)[0];
  2593 		t = ((unsigned short *)digitP)[0];
  2576                 digitP += 2;
  2594 		digitP += 2;
  2577                 t = ((t >> 8) | (t << 8)) & 0xFFFF;
  2595 		t = ((t >> 8) | (t << 8)) & 0xFFFF;
  2578 #else
  2596 #else
  2579                 t = (digitP[1]<<8) + digitP[0];
  2597 		t = (digitP[1]<<8) + digitP[0];
  2580                 digitP += 2;
  2598 		digitP += 2;
  2581 #endif
  2599 #endif
  2582                 _prod = t * _v + _carry;
  2600 		_prod = t * _v + _carry;
  2583                 _carry = _prod >> 16;
  2601 		_carry = _prod >> 16;
  2584 #if defined(STORE_WORD_WISE)
  2602 #if defined(STORE_WORD_WISE)
  2585                 /* better store short-wise */
  2603 		/* better store short-wise */
  2586                 _prod = ((_prod >> 8) | (_prod << 8)) & 0xFFFF;
  2604 		_prod = ((_prod >> 8) | (_prod << 8)) & 0xFFFF;
  2587                 ((unsigned short *)resultP)[0] = _prod;
  2605 		((unsigned short *)resultP)[0] = _prod;
  2588 #else
  2606 #else
  2589                 resultP[0] = _prod /* & 0xFF */;
  2607 		resultP[0] = _prod /* & 0xFF */;
  2590                 resultP[1] = (_prod>>8) /* & 0xFF */;
  2608 		resultP[1] = (_prod>>8) /* & 0xFF */;
  2591 #endif
  2609 #endif
  2592                 resultP += 2;
  2610 		resultP += 2;
  2593                 _l -= 2;
  2611 		_l -= 2;
  2594             }
  2612 	    }
  2595         }
  2613 	}
  2596 
  2614 
  2597 #endif /* LSB_FIRST */
  2615 #endif /* LSB_FIRST */
  2598 
  2616 
  2599         /*
  2617 	/*
  2600          * rest is done byte-wise
  2618 	 * rest is done byte-wise
  2601          */
  2619 	 */
  2602         while (_l > 0) {
  2620 	while (_l > 0) {
  2603             _prod = *digitP++ * _v + _carry;
  2621 	    _prod = *digitP++ * _v + _carry;
  2604             *resultP++ = _prod /* & 0xFF */;
  2622 	    *resultP++ = _prod /* & 0xFF */;
  2605             _carry = _prod >> 8;
  2623 	    _carry = _prod >> 8;
  2606             _l--;
  2624 	    _l--;
  2607         }
  2625 	}
  2608 
  2626 
  2609         _l = __intVal(lResult) - __intVal(len);
  2627 	_l = __intVal(lResult) - __intVal(len);
  2610 
  2628 
  2611         /*
  2629 	/*
  2612          * remaining carry
  2630 	 * remaining carry
  2613          */
  2631 	 */
  2614         while (_carry) {
  2632 	while (_carry) {
  2615             *resultP++ = _carry /* & 0xFF */;
  2633 	    *resultP++ = _carry /* & 0xFF */;
  2616             _carry >>= 8;
  2634 	    _carry >>= 8;
  2617             _l--;
  2635 	    _l--;
  2618         }
  2636 	}
  2619 
  2637 
  2620         /*
  2638 	/*
  2621          * remaining zeros
  2639 	 * remaining zeros
  2622          */
  2640 	 */
  2623         while (_l--) {
  2641 	while (_l--) {
  2624             *resultP++ = 0;
  2642 	    *resultP++ = 0;
  2625         }
  2643 	}
  2626 
  2644 
  2627         /*
  2645 	/*
  2628          * need compress ?
  2646 	 * need compress ?
  2629          */
  2647 	 */
  2630         if (resultP[-1]) {
  2648 	if (resultP[-1]) {
  2631             /*
  2649 	    /*
  2632              * no
  2650 	     * no
  2633              */
  2651 	     */
  2634             RETURN(result);
  2652 	    RETURN(result);
  2635         }
  2653 	}
  2636 
  2654 
  2637         ok = true;
  2655 	ok = true;
  2638     }
  2656     }
  2639 %}.
  2657 %}.
  2640     "
  2658     "
  2641      fall back - normally not reached
  2659      fall back - normally not reached
  2642      (could make it a primitive-failure as well)
  2660      (could make it a primitive-failure as well)
  2643     "
  2661     "
  2644     ok ifFalse:[
  2662     ok ifFalse:[
  2645         carry := 0.
  2663 	carry := 0.
  2646         1 to:len do:[:i |
  2664 	1 to:len do:[:i |
  2647             prod := (digitByteArray basicAt:i) * val + carry.
  2665 	    prod := (digitByteArray basicAt:i) * val + carry.
  2648             resultDigitByteArray basicAt:i put:(prod bitAnd:16rFF).
  2666 	    resultDigitByteArray basicAt:i put:(prod bitAnd:16rFF).
  2649             carry := prod bitShift:-8.
  2667 	    carry := prod bitShift:-8.
  2650         ].
  2668 	].
  2651         [carry ~~ 0] whileTrue:[
  2669 	[carry ~~ 0] whileTrue:[
  2652             len := len + 1.
  2670 	    len := len + 1.
  2653             resultDigitByteArray basicAt:len put:(carry bitAnd:16rFF).
  2671 	    resultDigitByteArray basicAt:len put:(carry bitAnd:16rFF).
  2654             carry := carry bitShift:-8
  2672 	    carry := carry bitShift:-8
  2655         ].
  2673 	].
  2656         [len < lResult] whileTrue:[
  2674 	[len < lResult] whileTrue:[
  2657             len := len + 1.
  2675 	    len := len + 1.
  2658             resultDigitByteArray basicAt:len put:0
  2676 	    resultDigitByteArray basicAt:len put:0
  2659         ]
  2677 	]
  2660     ].
  2678     ].
  2661     ^ result compressed
  2679     ^ result compressed
  2662 !
  2680 !
  2663 
  2681 
  2664 sumFromInteger:anInteger
  2682 sumFromInteger:anInteger
  3059     "/ the following code only works with
  3077     "/ the following code only works with
  3060     "/ smallIntegers in the range _MIN_INT+255 .. _MAX_INT-255
  3078     "/ smallIntegers in the range _MIN_INT+255 .. _MAX_INT-255
  3061 
  3079 
  3062     ((aSmallInteger < (SmallInteger minVal + 255))
  3080     ((aSmallInteger < (SmallInteger minVal + 255))
  3063     or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
  3081     or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
  3064         ^ self absMinus:(self class value:aSmallInteger) sign:newSign.
  3082 	^ self absMinus:(self class value:aSmallInteger) sign:newSign.
  3065     ].
  3083     ].
  3066 
  3084 
  3067     len := digitByteArray size.
  3085     len := digitByteArray size.
  3068 
  3086 
  3069     rsltLen := len "+ 1".
  3087     rsltLen := len "+ 1".
  3073     borrow := aSmallInteger abs.
  3091     borrow := aSmallInteger abs.
  3074 
  3092 
  3075 %{
  3093 %{
  3076     if (__isByteArray(__INST(digitByteArray))
  3094     if (__isByteArray(__INST(digitByteArray))
  3077      && __isByteArray(resultDigitByteArray)) {
  3095      && __isByteArray(resultDigitByteArray)) {
  3078         unsigned INT __borrow = __intVal(borrow);
  3096 	unsigned INT __borrow = __intVal(borrow);
  3079         INT __diff;
  3097 	INT __diff;
  3080         int __index = 1;
  3098 	int __index = 1;
  3081         int __len = __intVal(len);
  3099 	int __len = __intVal(len);
  3082         unsigned char *__digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
  3100 	unsigned char *__digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
  3083         unsigned char *__resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  3101 	unsigned char *__resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  3084         int __len3;
  3102 	int __len3;
  3085 
  3103 
  3086 #if defined(__LSBFIRST__)
  3104 #if defined(__LSBFIRST__)
  3087 # if (__POINTER_SIZE__ == 8)
  3105 # if (__POINTER_SIZE__ == 8)
  3088         /*
  3106 	/*
  3089          * subtract int-wise
  3107 	 * subtract int-wise
  3090          */
  3108 	 */
  3091         __len3 = __len - 3;
  3109 	__len3 = __len - 3;
  3092         while (__index < __len3) {
  3110 	while (__index < __len3) {
  3093             /* do not make this into one expression - ask cg why */
  3111 	    /* do not make this into one expression - ask cg why */
  3094             __diff = ((unsigned int *)(__digitP + __index-1))[0];
  3112 	    __diff = ((unsigned int *)(__digitP + __index-1))[0];
  3095             __diff -= (__borrow & 0xFFFFFFFFL);
  3113 	    __diff -= (__borrow & 0xFFFFFFFFL);
  3096             __borrow >>= 32;
  3114 	    __borrow >>= 32;
  3097             if (__diff < 0) {
  3115 	    if (__diff < 0) {
  3098                 /* __diff += 0x100000000; */
  3116 		/* __diff += 0x100000000; */
  3099                 __borrow++;
  3117 		__borrow++;
  3100             }
  3118 	    }
  3101             ((unsigned int *)(__resultP+__index-1))[0] = __diff;
  3119 	    ((unsigned int *)(__resultP+__index-1))[0] = __diff;
  3102             __index += 4;
  3120 	    __index += 4;
  3103         }
  3121 	}
  3104 # endif
  3122 # endif
  3105         /*
  3123 	/*
  3106          * subtract short-wise
  3124 	 * subtract short-wise
  3107          */
  3125 	 */
  3108         while (__index < __len) {
  3126 	while (__index < __len) {
  3109             /* do not make this into one expression - ask cg why */
  3127 	    /* do not make this into one expression - ask cg why */
  3110             __diff = ((unsigned short *)(__digitP+__index-1))[0];
  3128 	    __diff = ((unsigned short *)(__digitP+__index-1))[0];
  3111             __diff -= (__borrow & 0xFFFF);
  3129 	    __diff -= (__borrow & 0xFFFF);
  3112             __borrow >>= 16;
  3130 	    __borrow >>= 16;
  3113             if (__diff < 0) {
  3131 	    if (__diff < 0) {
  3114                 /* __diff += 0x10000; */
  3132 		/* __diff += 0x10000; */
  3115                 __borrow++;
  3133 		__borrow++;
  3116             } else {
  3134 	    } else {
  3117                 if (__borrow == 0) {
  3135 		if (__borrow == 0) {
  3118                     ((unsigned short *)(__resultP+__index-1))[0] = __diff;
  3136 		    ((unsigned short *)(__resultP+__index-1))[0] = __diff;
  3119                     __index += 2;
  3137 		    __index += 2;
  3120 
  3138 
  3121                     /* nothing more to subtract .. */
  3139 		    /* nothing more to subtract .. */
  3122                     while (__index < __len) {
  3140 		    while (__index < __len) {
  3123                         ((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0];
  3141 			((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0];
  3124                         __index += 2;
  3142 			__index += 2;
  3125                     }
  3143 		    }
  3126                     if (__index <= __len) {
  3144 		    if (__index <= __len) {
  3127                         __resultP[__index-1] = __digitP[__index-1];
  3145 			__resultP[__index-1] = __digitP[__index-1];
  3128                     }
  3146 		    }
  3129                     break;
  3147 		    break;
  3130                 }
  3148 		}
  3131             }
  3149 	    }
  3132             ((unsigned short *)(__resultP+__index-1))[0] = __diff;
  3150 	    ((unsigned short *)(__resultP+__index-1))[0] = __diff;
  3133             __index += 2;
  3151 	    __index += 2;
  3134         }
  3152 	}
  3135 #endif
  3153 #endif
  3136         /*
  3154 	/*
  3137          * subtract byte-wise
  3155 	 * subtract byte-wise
  3138          */
  3156 	 */
  3139         while (__index <= __len) {
  3157 	while (__index <= __len) {
  3140             __diff = __digitP[__index-1];
  3158 	    __diff = __digitP[__index-1];
  3141             __diff -= (__borrow & 0xFF);
  3159 	    __diff -= (__borrow & 0xFF);
  3142             __borrow >>= 8;
  3160 	    __borrow >>= 8;
  3143             if (__diff < 0) {
  3161 	    if (__diff < 0) {
  3144                 /* __diff += 0x100; */
  3162 		/* __diff += 0x100; */
  3145                 __borrow++;
  3163 		__borrow++;
  3146             } else {
  3164 	    } else {
  3147                 if (__borrow == 0) {
  3165 		if (__borrow == 0) {
  3148                     __resultP[__index-1] = __diff;
  3166 		    __resultP[__index-1] = __diff;
  3149                     __index++;
  3167 		    __index++;
  3150 
  3168 
  3151                     /* nothing more to subtract .. */
  3169 		    /* nothing more to subtract .. */
  3152                     while (__index <= __len) {
  3170 		    while (__index <= __len) {
  3153                         __resultP[__index-1] = __digitP[__index-1];
  3171 			__resultP[__index-1] = __digitP[__index-1];
  3154                         __index++;
  3172 			__index++;
  3155                     }
  3173 		    }
  3156                     break;
  3174 		    break;
  3157                 }
  3175 		}
  3158             }
  3176 	    }
  3159             __resultP[__index-1] = __diff;
  3177 	    __resultP[__index-1] = __diff;
  3160             __index++;
  3178 	    __index++;
  3161         }
  3179 	}
  3162         lastDigit = __mkSmallInteger( __resultP[__index-1-1] );
  3180 	lastDigit = __mkSmallInteger( __resultP[__index-1-1] );
  3163         ok = true;
  3181 	ok = true;
  3164     }
  3182     }
  3165 %}.
  3183 %}.
  3166 
  3184 
  3167     ok == true ifFalse:[        "/ cannot happen
  3185     ok == true ifFalse:[        "/ cannot happen
  3168         index := 1.
  3186 	index := 1.
  3169         [borrow ~~ 0] whileTrue:[
  3187 	[borrow ~~ 0] whileTrue:[
  3170             (index <= len) ifTrue:[
  3188 	    (index <= len) ifTrue:[
  3171                 diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF).
  3189 		diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF).
  3172                 borrow := borrow bitShift:-8.
  3190 		borrow := borrow bitShift:-8.
  3173                 diff < 0 ifTrue:[
  3191 		diff < 0 ifTrue:[
  3174                     diff := diff + 256.
  3192 		    diff := diff + 256.
  3175                     borrow := borrow + 1.
  3193 		    borrow := borrow + 1.
  3176                 ]
  3194 		]
  3177             ] ifFalse:[
  3195 	    ] ifFalse:[
  3178                 diff := borrow bitAnd:255.
  3196 		diff := borrow bitAnd:255.
  3179                 borrow := borrow bitShift:-8.
  3197 		borrow := borrow bitShift:-8.
  3180             ].
  3198 	    ].
  3181             resultDigitByteArray basicAt:index put:(lastDigit := diff).
  3199 	    resultDigitByteArray basicAt:index put:(lastDigit := diff).
  3182             index := index + 1
  3200 	    index := index + 1
  3183         ].
  3201 	].
  3184         [index <= len] whileTrue:[
  3202 	[index <= len] whileTrue:[
  3185             resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index).
  3203 	    resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index).
  3186             index := index + 1
  3204 	    index := index + 1
  3187         ].
  3205 	].
  3188         (index <= rsltLen) ifTrue:[
  3206 	(index <= rsltLen) ifTrue:[
  3189             lastDigit := 0.
  3207 	    lastDigit := 0.
  3190         ]
  3208 	]
  3191     ].
  3209     ].
  3192 
  3210 
  3193     (lastDigit == 0 or:[rsltLen <= SmallInteger maxBytes]) ifTrue:[
  3211     (lastDigit == 0 or:[rsltLen <= SmallInteger maxBytes]) ifTrue:[
  3194         ^ result compressed.
  3212 	^ result compressed.
  3195     ].
  3213     ].
  3196     ^ result
  3214     ^ result
  3197 
  3215 
  3198     "
  3216     "
  3199      12345678900000000000 absFastMinus:1 sign:1
  3217      12345678900000000000 absFastMinus:1 sign:1
  3224     "/ the following code only works with
  3242     "/ the following code only works with
  3225     "/ smallIntegers in the range _MIN_INT+255 .. _MAX_INT-255
  3243     "/ smallIntegers in the range _MIN_INT+255 .. _MAX_INT-255
  3226 
  3244 
  3227     ((aSmallInteger < (SmallInteger minVal + 255))
  3245     ((aSmallInteger < (SmallInteger minVal + 255))
  3228     or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
  3246     or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
  3229         ^ self absPlus:(self class value:aSmallInteger) sign:newSign.
  3247 	^ self absPlus:(self class value:aSmallInteger) sign:newSign.
  3230     ].
  3248     ].
  3231 
  3249 
  3232     len := rsltLen := digitByteArray size.
  3250     len := rsltLen := digitByteArray size.
  3233     "/
  3251     "/
  3234     "/ there can only be an overflow from the high byte,
  3252     "/ there can only be an overflow from the high byte,
  3235     "/ if it is 255 (since the other number is definitely smaller)
  3253     "/ if it is 255 (since the other number is definitely smaller)
  3236     "/
  3254     "/
  3237     (digitByteArray at:len) == 16rFF ifTrue:[
  3255     (digitByteArray at:len) == 16rFF ifTrue:[
  3238         rsltLen := len + 1.
  3256 	rsltLen := len + 1.
  3239     ] ifFalse:[
  3257     ] ifFalse:[
  3240         "/ or the argument has something in the high byte ..
  3258 	"/ or the argument has something in the high byte ..
  3241 %{
  3259 %{
  3242 #if __POINTER_SIZE__ == 8
  3260 #if __POINTER_SIZE__ == 8
  3243         if (__intVal(aSmallInteger) & 0xFF00000000000000L) {
  3261 	if (__intVal(aSmallInteger) & 0xFF00000000000000L) {
  3244             rsltLen = __mkSmallInteger(__intVal(len) + 1);
  3262 	    rsltLen = __mkSmallInteger(__intVal(len) + 1);
  3245         }
  3263 	}
  3246 #else
  3264 #else
  3247         if (__intVal(aSmallInteger) & 0xFF000000) {
  3265 	if (__intVal(aSmallInteger) & 0xFF000000) {
  3248             rsltLen = __mkSmallInteger(__intVal(len) + 1);
  3266 	    rsltLen = __mkSmallInteger(__intVal(len) + 1);
  3249         }
  3267 	}
  3250 #endif
  3268 #endif
  3251 %}
  3269 %}
  3252     ].
  3270     ].
  3253 
  3271 
  3254     result := self class basicNew numberOfDigits:rsltLen sign:newSign.
  3272     result := self class basicNew numberOfDigits:rsltLen sign:newSign.
  3256 
  3274 
  3257 %{
  3275 %{
  3258     if (__isByteArray(__INST(digitByteArray))
  3276     if (__isByteArray(__INST(digitByteArray))
  3259      && __isByteArray(resultDigitByteArray)
  3277      && __isByteArray(resultDigitByteArray)
  3260      && __isSmallInteger(aSmallInteger)) {
  3278      && __isSmallInteger(aSmallInteger)) {
  3261         /* carry is NOT unsigned (see negation below) */
  3279 	/* carry is NOT unsigned (see negation below) */
  3262         INT __carry = __intVal(aSmallInteger);
  3280 	INT __carry = __intVal(aSmallInteger);
  3263         int __index = 1;
  3281 	int __index = 1;
  3264         int __len = __intVal(len);
  3282 	int __len = __intVal(len);
  3265         unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
  3283 	unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
  3266         unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element);
  3284 	unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element);
  3267         INT __ptrDelta = __dst - __src;
  3285 	INT __ptrDelta = __dst - __src;
  3268         unsigned char *__srcLast = __src + __len - 1;
  3286 	unsigned char *__srcLast = __src + __len - 1;
  3269         int __rsltLen = __intVal(rsltLen);
  3287 	int __rsltLen = __intVal(rsltLen);
  3270 
  3288 
  3271         if (__carry < 0) {
  3289 	if (__carry < 0) {
  3272             __carry = -__carry;
  3290 	    __carry = -__carry;
  3273         }
  3291 	}
  3274 
  3292 
  3275 #if defined(__LSBFIRST__)
  3293 #if defined(__LSBFIRST__)
  3276 # if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4)
  3294 # if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4)
  3277 #  if 0 /* NOTICE - the code below is 20% slower ... - why */
  3295 #  if 0 /* NOTICE - the code below is 20% slower ... - why */
  3278         /*
  3296 	/*
  3279          * add long-wise
  3297 	 * add long-wise
  3280          */
  3298 	 */
  3281         asm("  jecxz nothingToDo                                      \n\
  3299 	asm("  jecxz nothingToDo                                      \n\
  3282                movl  %%eax, %%esi      /* __src input */              \n\
  3300 	       movl  %%eax, %%esi      /* __src input */              \n\
  3283                movl  %%ebx, %%edi      /* __dst input */              \n\
  3301 	       movl  %%ebx, %%edi      /* __dst input */              \n\
  3284                                                                       \n\
  3302 								      \n\
  3285                /* the first 4-byte int */                             \n\
  3303 	       /* the first 4-byte int */                             \n\
  3286                lodsl                   /* fetch */                    \n\
  3304 	       lodsl                   /* fetch */                    \n\
  3287                addl  %%edx, %%eax      /* add */                      \n\
  3305 	       addl  %%edx, %%eax      /* add */                      \n\
  3288                stosl                   /* store */                    \n\
  3306 	       stosl                   /* store */                    \n\
  3289                leal  -1(%%ecx),%%ecx   /* do not clobber carry */     \n\
  3307 	       leal  -1(%%ecx),%%ecx   /* do not clobber carry */     \n\
  3290                jecxz doneLoop          /* any more ? */               \n\
  3308 	       jecxz doneLoop          /* any more ? */               \n\
  3291                /* remaining 4-byte ints */                            \n\
  3309 	       /* remaining 4-byte ints */                            \n\
  3292                jmp   addLoop                                          \n\
  3310 	       jmp   addLoop                                          \n\
  3293                                                                       \n\
  3311 								      \n\
  3294                .align 8                                               \n\
  3312 	       .align 8                                               \n\
  3295              addLoop:                                                 \n\
  3313 	     addLoop:                                                 \n\
  3296                movl  0(%%esi), %%ebx   /* fetch  */                   \n\
  3314 	       movl  0(%%esi), %%ebx   /* fetch  */                   \n\
  3297                jnc   copyLoop2                                        \n\
  3315 	       jnc   copyLoop2                                        \n\
  3298                movl  $0, %%eax                                        \n\
  3316 	       movl  $0, %%eax                                        \n\
  3299                leal  4(%%esi), %%esi                                  \n\
  3317 	       leal  4(%%esi), %%esi                                  \n\
  3300                adcl  %%ebx, %%eax      /* & add carry from prev int */\n\
  3318 	       adcl  %%ebx, %%eax      /* & add carry from prev int */\n\
  3301                leal  8(%%edi), %%edi                                  \n\
  3319 	       leal  8(%%edi), %%edi                                  \n\
  3302                movl  %%eax, -8(%%edi)  /* store */                    \n\
  3320 	       movl  %%eax, -8(%%edi)  /* store */                    \n\
  3303                leal  -1(%%ecx),%%ecx   /* do not clobber carry */     \n\
  3321 	       leal  -1(%%ecx),%%ecx   /* do not clobber carry */     \n\
  3304                jecxz doneLoop          /* any more ? */               \n\
  3322 	       jecxz doneLoop          /* any more ? */               \n\
  3305                                                                       \n\
  3323 								      \n\
  3306                movl  0(%%esi), %%ebx   /* fetch  */                   \n\
  3324 	       movl  0(%%esi), %%ebx   /* fetch  */                   \n\
  3307                movl  $0, %%eax                                        \n\
  3325 	       movl  $0, %%eax                                        \n\
  3308                leal  4(%%esi), %%esi                                  \
  3326 	       leal  4(%%esi), %%esi                                  \
  3309                adcl  %%ebx, %%eax      /* & add carry from prev int */\n\
  3327 	       adcl  %%ebx, %%eax      /* & add carry from prev int */\n\
  3310                movl  %%eax, -4(%%edi)  /* store */                    \n\
  3328 	       movl  %%eax, -4(%%edi)  /* store */                    \n\
  3311                                                                       \n\
  3329 								      \n\
  3312                loop  addLoop                                          \n\
  3330 	       loop  addLoop                                          \n\
  3313                jmp   doneLoop                                         \n\
  3331 	       jmp   doneLoop                                         \n\
  3314                                                                       \n\
  3332 								      \n\
  3315                .align 8                                               \n\
  3333 	       .align 8                                               \n\
  3316              copyLoop:                                                \n\
  3334 	     copyLoop:                                                \n\
  3317                movl  0(%%esi), %%ebx                                  \n\
  3335 	       movl  0(%%esi), %%ebx                                  \n\
  3318              copyLoop2:                                               \n\
  3336 	     copyLoop2:                                               \n\
  3319                add   $4, %%esi                                        \n\
  3337 	       add   $4, %%esi                                        \n\
  3320                add   $4, %%edi                                        \n\
  3338 	       add   $4, %%edi                                        \n\
  3321                movl  %%ebx, -4(%%edi)                                 \n\
  3339 	       movl  %%ebx, -4(%%edi)                                 \n\
  3322                loop  copyLoop                                         \n\
  3340 	       loop  copyLoop                                         \n\
  3323                                                                       \n\
  3341 								      \n\
  3324              doneLoop:                                                \n\
  3342 	     doneLoop:                                                \n\
  3325                movl  $0, %%edx         /* do not clobber carry (xorl clears it) */   \n\
  3343 	       movl  $0, %%edx         /* do not clobber carry (xorl clears it) */   \n\
  3326                adcl  $0, %%edx                                        \n\
  3344 	       adcl  $0, %%edx                                        \n\
  3327                movl  %%esi, %%eax      /* __src output */             \n\
  3345 	       movl  %%esi, %%eax      /* __src output */             \n\
  3328              nothingToDo:                                             \n\
  3346 	     nothingToDo:                                             \n\
  3329             " : "=d"  ((unsigned long)(__carry)),
  3347 	    " : "=d"  ((unsigned long)(__carry)),
  3330                 "=a"  (__src)
  3348 		"=a"  (__src)
  3331               : "1"   (__src),
  3349 	      : "1"   (__src),
  3332                 "b"   (__dst),
  3350 		"b"   (__dst),
  3333                 "c"   (__len / 4),
  3351 		"c"   (__len / 4),
  3334                 "0"   (__carry)
  3352 		"0"   (__carry)
  3335               : "esi", "edi");
  3353 	      : "esi", "edi");
  3336 
  3354 
  3337 #  else
  3355 #  else
  3338         {
  3356 	{
  3339             unsigned char *__srcLastX;
  3357 	    unsigned char *__srcLastX;
  3340 
  3358 
  3341             __srcLastX = __srcLast - 3 - 4;
  3359 	    __srcLastX = __srcLast - 3 - 4;
  3342             while (__src <= __srcLastX) {
  3360 	    while (__src <= __srcLastX) {
  3343                 unsigned int __sum, __sum2;
  3361 		unsigned int __sum, __sum2;
  3344                 unsigned __digit1, __digit2;
  3362 		unsigned __digit1, __digit2;
  3345 
  3363 
  3346                 __digit1 = ((unsigned *)__src)[0];
  3364 		__digit1 = ((unsigned *)__src)[0];
  3347                 __digit2 = ((unsigned *)__src)[1];
  3365 		__digit2 = ((unsigned *)__src)[1];
  3348                 asm ("addl %%edx,%%ecx          \n\
  3366 		asm ("addl %%edx,%%ecx          \n\
  3349                       adcl $0, %%eax            \n\
  3367 		      adcl $0, %%eax            \n\
  3350                       movl $0, %%edx            \n\
  3368 		      movl $0, %%edx            \n\
  3351                       adcl $0, %%edx"
  3369 		      adcl $0, %%edx"
  3352                         : "=d"  ((unsigned long)(__carry)),
  3370 			: "=d"  ((unsigned long)(__carry)),
  3353                           "=c"  ((unsigned long)(__sum)),
  3371 			  "=c"  ((unsigned long)(__sum)),
  3354                           "=a"  ((unsigned long)(__sum2))
  3372 			  "=a"  ((unsigned long)(__sum2))
  3355                         : "0"   ((unsigned long)(__carry)),
  3373 			: "0"   ((unsigned long)(__carry)),
  3356                           "1"   (__digit1),
  3374 			  "1"   (__digit1),
  3357                           "2"   (__digit2));
  3375 			  "2"   (__digit2));
  3358 
  3376 
  3359                 ((unsigned int *)(__src + __ptrDelta))[0] = __sum;
  3377 		((unsigned int *)(__src + __ptrDelta))[0] = __sum;
  3360                 ((unsigned int *)(__src + __ptrDelta))[1] = __sum2;
  3378 		((unsigned int *)(__src + __ptrDelta))[1] = __sum2;
  3361 
  3379 
  3362                 __src += 8;
  3380 		__src += 8;
  3363 
  3381 
  3364                 if (__carry == 0) {
  3382 		if (__carry == 0) {
  3365                     while (__src <= __srcLastX) {
  3383 		    while (__src <= __srcLastX) {
  3366                         /* copy over words */
  3384 			/* copy over words */
  3367                         ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
  3385 			((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
  3368                         ((unsigned int *)(__src + __ptrDelta))[1] = ((unsigned int *)__src)[1];
  3386 			((unsigned int *)(__src + __ptrDelta))[1] = ((unsigned int *)__src)[1];
  3369                         __src += 8;
  3387 			__src += 8;
  3370                     }
  3388 		    }
  3371                     while (__src <= __srcLast) {
  3389 		    while (__src <= __srcLast) {
  3372                         /* copy over bytes */
  3390 			/* copy over bytes */
  3373                         __src[__ptrDelta] = __src[0];
  3391 			__src[__ptrDelta] = __src[0];
  3374                         __src ++;
  3392 			__src ++;
  3375                     }
  3393 		    }
  3376                     goto doneSource;
  3394 		    goto doneSource;
  3377                 }
  3395 		}
  3378             }
  3396 	    }
  3379 
  3397 
  3380             __srcLastX = __srcLastX + 4;
  3398 	    __srcLastX = __srcLastX + 4;
  3381             if (__src <= __srcLastX) {
  3399 	    if (__src <= __srcLastX) {
  3382                 unsigned int __sum, __digit;
  3400 		unsigned int __sum, __digit;
  3383 
  3401 
  3384                 __digit = ((unsigned *)__src)[0];
  3402 		__digit = ((unsigned *)__src)[0];
  3385 
  3403 
  3386                 asm ("addl %%eax,%%edx  \n\
  3404 		asm ("addl %%eax,%%edx  \n\
  3387                       movl $0,%%eax     \n\
  3405 		      movl $0,%%eax     \n\
  3388                       adcl $0,%%eax"
  3406 		      adcl $0,%%eax"
  3389                         : "=a"  ((unsigned long)(__carry)),
  3407 			: "=a"  ((unsigned long)(__carry)),
  3390                           "=d"  ((unsigned long)(__sum))
  3408 			  "=d"  ((unsigned long)(__sum))
  3391                         : "0"   ((unsigned long)(__carry)),
  3409 			: "0"   ((unsigned long)(__carry)),
  3392                           "1"   (__digit) );
  3410 			  "1"   (__digit) );
  3393 
  3411 
  3394                 ((unsigned int *)(__src + __ptrDelta))[0] = __sum;
  3412 		((unsigned int *)(__src + __ptrDelta))[0] = __sum;
  3395                 __src += 4;
  3413 		__src += 4;
  3396 
  3414 
  3397                 if (__carry == 0) {
  3415 		if (__carry == 0) {
  3398                     while (__src <= __srcLast) {
  3416 		    while (__src <= __srcLast) {
  3399                         /* copy over bytes */
  3417 			/* copy over bytes */
  3400                         __src[__ptrDelta] = __src[0];
  3418 			__src[__ptrDelta] = __src[0];
  3401                         __src ++;
  3419 			__src ++;
  3402                     }
  3420 		    }
  3403                     goto doneSource;
  3421 		    goto doneSource;
  3404                 }
  3422 		}
  3405             }
  3423 	    }
  3406         }
  3424 	}
  3407 #  endif
  3425 #  endif
  3408 # else /* not i386-GNUC */
  3426 # else /* not i386-GNUC */
  3409 #  if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
  3427 #  if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
  3410         {
  3428 	{
  3411             unsigned char *__srcLast4;
  3429 	    unsigned char *__srcLast4;
  3412 
  3430 
  3413             /*
  3431 	    /*
  3414              * add long-wise
  3432 	     * add long-wise
  3415              */
  3433 	     */
  3416             __srcLast4 = __srcLast - 3;
  3434 	    __srcLast4 = __srcLast - 3;
  3417             while (__src <= __srcLast4) {
  3435 	    while (__src <= __srcLast4) {
  3418                 unsigned int __sum;
  3436 		unsigned int __sum;
  3419 
  3437 
  3420                 __sum = ((unsigned int *)__src)[0];
  3438 		__sum = ((unsigned int *)__src)[0];
  3421                 asm {
  3439 		asm {
  3422                       mov eax, __sum
  3440 		      mov eax, __sum
  3423                       add eax, __carry
  3441 		      add eax, __carry
  3424                       mov edx, 0
  3442 		      mov edx, 0
  3425                       adc edx, 0
  3443 		      adc edx, 0
  3426                       mov __sum, eax
  3444 		      mov __sum, eax
  3427                       mov __carry, edx
  3445 		      mov __carry, edx
  3428                     }
  3446 		    }
  3429 
  3447 
  3430                 ((unsigned int *)(__src + __ptrDelta))[0] = __sum;
  3448 		((unsigned int *)(__src + __ptrDelta))[0] = __sum;
  3431                 __src += 4;
  3449 		__src += 4;
  3432                 if (__carry == 0) {
  3450 		if (__carry == 0) {
  3433                     while (__src <= __srcLast4) {
  3451 		    while (__src <= __srcLast4) {
  3434                         /* copy over words */
  3452 			/* copy over words */
  3435                         ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
  3453 			((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
  3436                         __src += 4;
  3454 			__src += 4;
  3437                     }
  3455 		    }
  3438                     while (__src <= __srcLast) {
  3456 		    while (__src <= __srcLast) {
  3439                         /* copy over bytes */
  3457 			/* copy over bytes */
  3440                         __src[__ptrDelta] = __src[0];
  3458 			__src[__ptrDelta] = __src[0];
  3441                         __src ++;
  3459 			__src ++;
  3442                     }
  3460 		    }
  3443                     goto doneSource;
  3461 		    goto doneSource;
  3444                 }
  3462 		}
  3445             }
  3463 	    }
  3446         }
  3464 	}
  3447 #  else /* not i386-WIN32 */
  3465 #  else /* not i386-WIN32 */
  3448 #   if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8)
  3466 #   if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8)
  3449         {
  3467 	{
  3450             unsigned char *__srcLast4;
  3468 	    unsigned char *__srcLast4;
  3451 
  3469 
  3452             /*
  3470 	    /*
  3453              * add long-wise
  3471 	     * add long-wise
  3454              */
  3472 	     */
  3455             __srcLast4 = __srcLast - 3;
  3473 	    __srcLast4 = __srcLast - 3;
  3456             while (__src <= __srcLast4) {
  3474 	    while (__src <= __srcLast4) {
  3457                 unsigned INT __sum;
  3475 		unsigned INT __sum;
  3458 
  3476 
  3459                 __sum = ((unsigned int *)__src)[0] + __carry;
  3477 		__sum = ((unsigned int *)__src)[0] + __carry;
  3460                 ((unsigned int *)(__src + __ptrDelta))[0] = __sum /* & 0xFFFF */;
  3478 		((unsigned int *)(__src + __ptrDelta))[0] = __sum /* & 0xFFFF */;
  3461                 __src += 4;
  3479 		__src += 4;
  3462                 __carry = __sum >> 32;
  3480 		__carry = __sum >> 32;
  3463                 if (__carry == 0) {
  3481 		if (__carry == 0) {
  3464                     while (__src <= __srcLast4) {
  3482 		    while (__src <= __srcLast4) {
  3465                         /* copy over words */
  3483 			/* copy over words */
  3466                         ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
  3484 			((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
  3467                         __src += 4;
  3485 			__src += 4;
  3468                     }
  3486 		    }
  3469                     while (__src <= __srcLast) {
  3487 		    while (__src <= __srcLast) {
  3470                         /* copy over bytes */
  3488 			/* copy over bytes */
  3471                         __src[__ptrDelta] = __src[0];
  3489 			__src[__ptrDelta] = __src[0];
  3472                         __src ++;
  3490 			__src ++;
  3473                     }
  3491 		    }
  3474                     goto doneSource;
  3492 		    goto doneSource;
  3475                 }
  3493 		}
  3476             }
  3494 	    }
  3477         }
  3495 	}
  3478 #   endif /* LSB+64bit */
  3496 #   endif /* LSB+64bit */
  3479 #  endif /* __i386__ & WIN32 */
  3497 #  endif /* __i386__ & WIN32 */
  3480 # endif /* __i386__ & GNUC */
  3498 # endif /* __i386__ & GNUC */
  3481 
  3499 
  3482         /*
  3500 	/*
  3483          * add short-wise
  3501 	 * add short-wise
  3484          */
  3502 	 */
  3485         while (__src < __srcLast) {
  3503 	while (__src < __srcLast) {
  3486             __carry += ((unsigned short *)__src)[0];
  3504 	    __carry += ((unsigned short *)__src)[0];
  3487             ((unsigned short *)(__src + __ptrDelta))[0] = __carry /* & 0xFFFF */;
  3505 	    ((unsigned short *)(__src + __ptrDelta))[0] = __carry /* & 0xFFFF */;
  3488             __carry >>= 16;
  3506 	    __carry >>= 16;
  3489             __src += 2;
  3507 	    __src += 2;
  3490         }
  3508 	}
  3491         /*
  3509 	/*
  3492          * last (odd) byte
  3510 	 * last (odd) byte
  3493          */
  3511 	 */
  3494         if (__src <= __srcLast) {
  3512 	if (__src <= __srcLast) {
  3495             __carry += __src[0];
  3513 	    __carry += __src[0];
  3496             __src[__ptrDelta] = __carry /* & 0xFF */;
  3514 	    __src[__ptrDelta] = __carry /* & 0xFF */;
  3497             __carry >>= 8;
  3515 	    __carry >>= 8;
  3498             __src++;
  3516 	    __src++;
  3499         }
  3517 	}
  3500 #else /* not __LSBFIRST__ */
  3518 #else /* not __LSBFIRST__ */
  3501 
  3519 
  3502         /*
  3520 	/*
  3503          * add byte-wise
  3521 	 * add byte-wise
  3504          */
  3522 	 */
  3505         while (__src <= __srcLast) {
  3523 	while (__src <= __srcLast) {
  3506             __carry += __src[0];
  3524 	    __carry += __src[0];
  3507             __src[__ptrDelta] = __carry /* & 0xFF */;
  3525 	    __src[__ptrDelta] = __carry /* & 0xFF */;
  3508             __src++;
  3526 	    __src++;
  3509             __carry >>= 8;
  3527 	    __carry >>= 8;
  3510 
  3528 
  3511             if (__carry == 0) {
  3529 	    if (__carry == 0) {
  3512                 while (__src <= __srcLast) {
  3530 		while (__src <= __srcLast) {
  3513                     /* copy over rest */
  3531 		    /* copy over rest */
  3514                     __src[__ptrDelta] = __src[0];
  3532 		    __src[__ptrDelta] = __src[0];
  3515                     __src++;
  3533 		    __src++;
  3516                 }
  3534 		}
  3517                 goto doneSource;
  3535 		goto doneSource;
  3518             }
  3536 	    }
  3519         }
  3537 	}
  3520 #endif /* __LSBFIRST__ */
  3538 #endif /* __LSBFIRST__ */
  3521 
  3539 
  3522     doneSource: ;
  3540     doneSource: ;
  3523         /*
  3541 	/*
  3524          * now, at most one other byte is to be stored ...
  3542 	 * now, at most one other byte is to be stored ...
  3525          */
  3543 	 */
  3526         if (__len < __rsltLen) {
  3544 	if (__len < __rsltLen) {
  3527             __src[__ptrDelta] = __carry /* & 0xFF */;
  3545 	    __src[__ptrDelta] = __carry /* & 0xFF */;
  3528             __src++;
  3546 	    __src++;
  3529         }
  3547 	}
  3530 
  3548 
  3531         if (__src[__ptrDelta-1]) {      /* lastDigit */
  3549 	if (__src[__ptrDelta-1]) {      /* lastDigit */
  3532             RETURN (result);
  3550 	    RETURN (result);
  3533         }
  3551 	}
  3534         ok = true;
  3552 	ok = true;
  3535     }
  3553     }
  3536 %}.
  3554 %}.
  3537 
  3555 
  3538     ok ~~ true ifTrue:[
  3556     ok ~~ true ifTrue:[
  3539         index := 1.
  3557 	index := 1.
  3540         carry := aSmallInteger abs.
  3558 	carry := aSmallInteger abs.
  3541 
  3559 
  3542         [carry ~~ 0] whileTrue:[
  3560 	[carry ~~ 0] whileTrue:[
  3543             (index <= len) ifTrue:[
  3561 	    (index <= len) ifTrue:[
  3544                 carry := (digitByteArray basicAt:index) + carry.
  3562 		carry := (digitByteArray basicAt:index) + carry.
  3545             ].
  3563 	    ].
  3546             resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF).
  3564 	    resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF).
  3547             carry := carry bitShift:-8.
  3565 	    carry := carry bitShift:-8.
  3548             index := index + 1
  3566 	    index := index + 1
  3549         ].
  3567 	].
  3550 
  3568 
  3551         (index <= rsltLen) ifTrue:[
  3569 	(index <= rsltLen) ifTrue:[
  3552             [index <= len] whileTrue:[
  3570 	    [index <= len] whileTrue:[
  3553                 resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index).
  3571 		resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index).
  3554                 index := index + 1
  3572 		index := index + 1
  3555             ].
  3573 	    ].
  3556             lastDigit := 0.
  3574 	    lastDigit := 0.
  3557         ].
  3575 	].
  3558 
  3576 
  3559         (lastDigit ~~ 0 and:[rsltLen > SmallInteger maxBytes]) ifTrue:[
  3577 	(lastDigit ~~ 0 and:[rsltLen > SmallInteger maxBytes]) ifTrue:[
  3560             ^ result
  3578 	    ^ result
  3561         ].
  3579 	].
  3562     ].
  3580     ].
  3563 
  3581 
  3564     ^ result compressed
  3582     ^ result compressed
  3565 
  3583 
  3566     "Modified: 24.3.1997 / 21:32:41 / cg"
  3584     "Modified: 24.3.1997 / 21:32:41 / cg"
  3797     len1 := digitByteArray size.
  3815     len1 := digitByteArray size.
  3798     otherDigitByteArray := aLargeInteger digitBytes.
  3816     otherDigitByteArray := aLargeInteger digitBytes.
  3799     len2 := otherDigitByteArray size.
  3817     len2 := otherDigitByteArray size.
  3800 
  3818 
  3801     len1 > len2 ifTrue:[
  3819     len1 > len2 ifTrue:[
  3802         lResult := len1
  3820 	lResult := len1
  3803     ] ifFalse:[
  3821     ] ifFalse:[
  3804         lResult := (len1 max: len2) + 1.
  3822 	lResult := (len1 max: len2) + 1.
  3805     ].
  3823     ].
  3806     result := self class basicNew numberOfDigits:lResult sign:newSign.
  3824     result := self class basicNew numberOfDigits:lResult sign:newSign.
  3807     resultDigitByteArray := result digitBytes.
  3825     resultDigitByteArray := result digitBytes.
  3808 
  3826 
  3809     lastDigit := 0.
  3827     lastDigit := 0.
  3812     OBJ _digitByteArray = __INST(digitByteArray);
  3830     OBJ _digitByteArray = __INST(digitByteArray);
  3813 
  3831 
  3814     if (__isByteArray(_digitByteArray)
  3832     if (__isByteArray(_digitByteArray)
  3815      && __isByteArray(otherDigitByteArray)
  3833      && __isByteArray(otherDigitByteArray)
  3816      && __isByteArray(resultDigitByteArray)) {
  3834      && __isByteArray(resultDigitByteArray)) {
  3817         int __len1 = __intVal(len1);
  3835 	int __len1 = __intVal(len1);
  3818         int __len2 = __intVal(len2);
  3836 	int __len2 = __intVal(len2);
  3819         int __minLen = __len1 < __len2 ? __len1 : __len2;
  3837 	int __minLen = __len1 < __len2 ? __len1 : __len2;
  3820         int __index, __borrow = 0;
  3838 	int __index, __borrow = 0;
  3821         INT __diff;
  3839 	INT __diff;
  3822         unsigned char *__myDigits, *__otherDigits, *__resultDigits;
  3840 	unsigned char *__myDigits, *__otherDigits, *__resultDigits;
  3823 
  3841 
  3824         ok = true;
  3842 	ok = true;
  3825 
  3843 
  3826         __resultDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  3844 	__resultDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  3827         __otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  3845 	__otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  3828         __myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  3846 	__myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  3829 
  3847 
  3830         __index = 1;
  3848 	__index = 1;
  3831 
  3849 
  3832 #if defined(__LSBFIRST__)
  3850 #if defined(__LSBFIRST__)
  3833 # if __POINTER_SIZE__ == 8
  3851 # if __POINTER_SIZE__ == 8
  3834         /*
  3852 	/*
  3835          * subtract int-wise
  3853 	 * subtract int-wise
  3836          */
  3854 	 */
  3837         while ((__index+3) <= __minLen) {
  3855 	while ((__index+3) <= __minLen) {
  3838             /* do not make this into one expression - ask cg why */
  3856 	    /* do not make this into one expression - ask cg why */
  3839             __diff = ((unsigned int *)(__myDigits+__index-1))[0];
  3857 	    __diff = ((unsigned int *)(__myDigits+__index-1))[0];
  3840             __diff -= ((unsigned int *)(__otherDigits+__index-1))[0];
  3858 	    __diff -= ((unsigned int *)(__otherDigits+__index-1))[0];
  3841             __diff -= __borrow;
  3859 	    __diff -= __borrow;
  3842 
  3860 
  3843             if (__diff >= 0) {
  3861 	    if (__diff >= 0) {
  3844                 __borrow = 0;
  3862 		__borrow = 0;
  3845             } else {
  3863 	    } else {
  3846                 __borrow = 1;
  3864 		__borrow = 1;
  3847                 /* __diff += 0x10000; */
  3865 		/* __diff += 0x10000; */
  3848             }
  3866 	    }
  3849             ((unsigned int *)(__resultDigits+__index-1))[0] = __diff;
  3867 	    ((unsigned int *)(__resultDigits+__index-1))[0] = __diff;
  3850             __index += 4;
  3868 	    __index += 4;
  3851         }
  3869 	}
  3852 # endif /* 64bit */
  3870 # endif /* 64bit */
  3853 
  3871 
  3854         /*
  3872 	/*
  3855          * subtract short-wise
  3873 	 * subtract short-wise
  3856          */
  3874 	 */
  3857         while (__index < __minLen) {   /* i.e. index+1 <= minLen */
  3875 	while (__index < __minLen) {   /* i.e. index+1 <= minLen */
  3858             /* do not make this into one expression - ask cg why */
  3876 	    /* do not make this into one expression - ask cg why */
  3859             __diff = ((unsigned short *)(__myDigits+__index-1))[0];
  3877 	    __diff = ((unsigned short *)(__myDigits+__index-1))[0];
  3860             __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
  3878 	    __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
  3861             __diff -= __borrow;
  3879 	    __diff -= __borrow;
  3862             if (__diff >= 0) {
  3880 	    if (__diff >= 0) {
  3863                 __borrow = 0;
  3881 		__borrow = 0;
  3864             } else {
  3882 	    } else {
  3865                 __borrow = 1;
  3883 		__borrow = 1;
  3866                 /* __diff += 0x10000; */
  3884 		/* __diff += 0x10000; */
  3867             }
  3885 	    }
  3868             ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3886 	    ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3869             __index += 2;
  3887 	    __index += 2;
  3870         }
  3888 	}
  3871 
  3889 
  3872         if (__index == __minLen) {
  3890 	if (__index == __minLen) {
  3873             /* one of the operands has odd length - cannot continue short-wise */
  3891 	    /* one of the operands has odd length - cannot continue short-wise */
  3874         } else {
  3892 	} else {
  3875             if (__len1 > __len2) {
  3893 	    if (__len1 > __len2) {
  3876                 while (__index < __len1) {
  3894 		while (__index < __len1) {
  3877                     /* do not make this into one expression - ask cg why */
  3895 		    /* do not make this into one expression - ask cg why */
  3878                     __diff = ((unsigned short *)(__myDigits+__index-1))[0];
  3896 		    __diff = ((unsigned short *)(__myDigits+__index-1))[0];
  3879                     __diff -= __borrow;
  3897 		    __diff -= __borrow;
  3880                     if (__diff >= 0) {
  3898 		    if (__diff >= 0) {
  3881                         __borrow = 0;
  3899 			__borrow = 0;
  3882                         ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3900 			((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3883                         __index += 2;
  3901 			__index += 2;
  3884 
  3902 
  3885                         /* copy over rest */
  3903 			/* copy over rest */
  3886                         while (__index < __len1) {
  3904 			while (__index < __len1) {
  3887                             ((unsigned short *)(__resultDigits+__index-1))[0] = ((unsigned short *)(__myDigits+__index-1))[0];
  3905 			    ((unsigned short *)(__resultDigits+__index-1))[0] = ((unsigned short *)(__myDigits+__index-1))[0];
  3888                             __index+=2;
  3906 			    __index+=2;
  3889                         }
  3907 			}
  3890                         if (__index <= __len1) {
  3908 			if (__index <= __len1) {
  3891                             __resultDigits[__index-1] = __myDigits[__index-1];
  3909 			    __resultDigits[__index-1] = __myDigits[__index-1];
  3892                             __index++;
  3910 			    __index++;
  3893                         }
  3911 			}
  3894                         break;
  3912 			break;
  3895                     }
  3913 		    }
  3896                     __borrow = 1;
  3914 		    __borrow = 1;
  3897                     /* __diff += 0x10000; */
  3915 		    /* __diff += 0x10000; */
  3898                     ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3916 		    ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3899                     __index += 2;
  3917 		    __index += 2;
  3900                 }
  3918 		}
  3901             } else {
  3919 	    } else {
  3902                 if (__len2 > __len1) {
  3920 		if (__len2 > __len1) {
  3903                     while (__index < __len2) {
  3921 		    while (__index < __len2) {
  3904                         /* do not make this into one expression - ask cg why */
  3922 			/* do not make this into one expression - ask cg why */
  3905                         __diff = 0;
  3923 			__diff = 0;
  3906                         __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
  3924 			__diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
  3907                         __diff -= __borrow;
  3925 			__diff -= __borrow;
  3908                         if (__diff >= 0) {
  3926 			if (__diff >= 0) {
  3909                             __borrow = 0;
  3927 			    __borrow = 0;
  3910                         } else {
  3928 			} else {
  3911                             __borrow = 1;
  3929 			    __borrow = 1;
  3912                             /* __diff += 0x10000; */
  3930 			    /* __diff += 0x10000; */
  3913                         }
  3931 			}
  3914                         ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3932 			((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3915                         __index += 2;
  3933 			__index += 2;
  3916                     }
  3934 		    }
  3917                 }
  3935 		}
  3918             }
  3936 	    }
  3919         }
  3937 	}
  3920 #endif
  3938 #endif
  3921         /*
  3939 	/*
  3922          * subtract byte-wise
  3940 	 * subtract byte-wise
  3923          */
  3941 	 */
  3924         while (__index <= __minLen) {
  3942 	while (__index <= __minLen) {
  3925             /* do not make this into one expression - ask cg why */
  3943 	    /* do not make this into one expression - ask cg why */
  3926             __diff = __myDigits[__index-1];
  3944 	    __diff = __myDigits[__index-1];
  3927             __diff -= __otherDigits[__index-1];
  3945 	    __diff -= __otherDigits[__index-1];
  3928             __diff -= __borrow;
  3946 	    __diff -= __borrow;
  3929             if (__diff >= 0) {
  3947 	    if (__diff >= 0) {
  3930                 __borrow = 0;
  3948 		__borrow = 0;
  3931             } else {
  3949 	    } else {
  3932                 __borrow = 1;
  3950 		__borrow = 1;
  3933                 /* __diff += 0x100; */
  3951 		/* __diff += 0x100; */
  3934             }
  3952 	    }
  3935             __resultDigits[__index-1] = __diff;
  3953 	    __resultDigits[__index-1] = __diff;
  3936             __index++;
  3954 	    __index++;
  3937         }
  3955 	}
  3938 
  3956 
  3939         if (__len1 > __len2) {
  3957 	if (__len1 > __len2) {
  3940             while (__index <= __len1) {
  3958 	    while (__index <= __len1) {
  3941                 /* do not make this into one expression - ask cg why */
  3959 		/* do not make this into one expression - ask cg why */
  3942                 __diff = __myDigits[__index-1];
  3960 		__diff = __myDigits[__index-1];
  3943                 __diff -= __borrow;
  3961 		__diff -= __borrow;
  3944                 if (__diff >= 0) {
  3962 		if (__diff >= 0) {
  3945                     __borrow = 0;
  3963 		    __borrow = 0;
  3946                     /* copy over rest */
  3964 		    /* copy over rest */
  3947                     __resultDigits[__index-1] = __diff;
  3965 		    __resultDigits[__index-1] = __diff;
  3948                     __index++;
  3966 		    __index++;
  3949                     while (__index <= __len1) {
  3967 		    while (__index <= __len1) {
  3950                         __resultDigits[__index-1] = __myDigits[__index-1];
  3968 			__resultDigits[__index-1] = __myDigits[__index-1];
  3951                         __index++;
  3969 			__index++;
  3952                     }
  3970 		    }
  3953                     break;
  3971 		    break;
  3954                 }
  3972 		}
  3955                 __borrow = 1;
  3973 		__borrow = 1;
  3956                 /* __diff += 0x100; */
  3974 		/* __diff += 0x100; */
  3957                 __resultDigits[__index-1] = __diff;
  3975 		__resultDigits[__index-1] = __diff;
  3958                 __index++;
  3976 		__index++;
  3959             }
  3977 	    }
  3960         } else {
  3978 	} else {
  3961             if (__len2 > __len1) {
  3979 	    if (__len2 > __len1) {
  3962                 while (__index <= __len2) {
  3980 		while (__index <= __len2) {
  3963                     /* do not make this into one expression - ask cg why */
  3981 		    /* do not make this into one expression - ask cg why */
  3964                     __diff = 0;
  3982 		    __diff = 0;
  3965                     __diff -= __otherDigits[__index-1];
  3983 		    __diff -= __otherDigits[__index-1];
  3966                     __diff -= __borrow;
  3984 		    __diff -= __borrow;
  3967                     if (__diff >= 0) {
  3985 		    if (__diff >= 0) {
  3968                         __borrow = 0;
  3986 			__borrow = 0;
  3969                     } else {
  3987 		    } else {
  3970                         __borrow = 1;
  3988 			__borrow = 1;
  3971                         /* __diff += 0x100; */
  3989 			/* __diff += 0x100; */
  3972                     }
  3990 		    }
  3973                     __resultDigits[__index-1] = __diff;
  3991 		    __resultDigits[__index-1] = __diff;
  3974                     __index++;
  3992 		    __index++;
  3975                 }
  3993 		}
  3976             }
  3994 	    }
  3977         }
  3995 	}
  3978         borrow = __mkSmallInteger(__borrow);
  3996 	borrow = __mkSmallInteger(__borrow);
  3979         index = __mkSmallInteger(__index);
  3997 	index = __mkSmallInteger(__index);
  3980         lastDigit = __mkSmallInteger(__resultDigits[__intVal(lResult)-1]);
  3998 	lastDigit = __mkSmallInteger(__resultDigits[__intVal(lResult)-1]);
  3981     }
  3999     }
  3982 %}.
  4000 %}.
  3983     ok == true ifFalse:[
  4001     ok == true ifFalse:[
  3984         index := 1.
  4002 	index := 1.
  3985         borrow := 0.
  4003 	borrow := 0.
  3986 
  4004 
  3987         done := false.
  4005 	done := false.
  3988         [done] whileFalse:[
  4006 	[done] whileFalse:[
  3989             diff := borrow.
  4007 	    diff := borrow.
  3990             (index <= len1) ifTrue:[
  4008 	    (index <= len1) ifTrue:[
  3991                 diff := diff + (digitByteArray basicAt:index).
  4009 		diff := diff + (digitByteArray basicAt:index).
  3992                 (index <= len2) ifTrue:[
  4010 		(index <= len2) ifTrue:[
  3993                     diff := diff - (otherDigitByteArray basicAt:index)
  4011 		    diff := diff - (otherDigitByteArray basicAt:index)
  3994                 ]
  4012 		]
  3995             ] ifFalse:[
  4013 	    ] ifFalse:[
  3996                 (index <= len2) ifTrue:[
  4014 		(index <= len2) ifTrue:[
  3997                     diff := diff - (otherDigitByteArray basicAt:index)
  4015 		    diff := diff - (otherDigitByteArray basicAt:index)
  3998                 ] ifFalse:[
  4016 		] ifFalse:[
  3999                     "end reached"
  4017 		    "end reached"
  4000                     done := true
  4018 		    done := true
  4001                 ]
  4019 		]
  4002             ].
  4020 	    ].
  4003 
  4021 
  4004             "/ workaround for
  4022 	    "/ workaround for
  4005             "/ gcc code generator bug
  4023 	    "/ gcc code generator bug
  4006 
  4024 
  4007             (diff >= 0) ifTrue:[
  4025 	    (diff >= 0) ifTrue:[
  4008                 borrow := 0
  4026 		borrow := 0
  4009             ] ifFalse:[
  4027 	    ] ifFalse:[
  4010                 borrow := -1.
  4028 		borrow := -1.
  4011                 diff := diff + 16r100
  4029 		diff := diff + 16r100
  4012             ].
  4030 	    ].
  4013 
  4031 
  4014     "/        (diff < 0) ifTrue:[
  4032     "/        (diff < 0) ifTrue:[
  4015     "/            borrow := -1.
  4033     "/            borrow := -1.
  4016     "/            diff := diff + 16r100
  4034     "/            diff := diff + 16r100
  4017     "/        ] ifFalse:[
  4035     "/        ] ifFalse:[
  4018     "/            borrow := 0
  4036     "/            borrow := 0
  4019     "/        ].
  4037     "/        ].
  4020 
  4038 
  4021             resultDigitByteArray basicAt:index put:diff.
  4039 	    resultDigitByteArray basicAt:index put:diff.
  4022             index := index + 1
  4040 	    index := index + 1
  4023         ].
  4041 	].
  4024         lastDigit := resultDigitByteArray basicAt:lResult.
  4042 	lastDigit := resultDigitByteArray basicAt:lResult.
  4025     ].
  4043     ].
  4026 
  4044 
  4027     (borrow ~~ 0) ifTrue:[
  4045     (borrow ~~ 0) ifTrue:[
  4028         "/ must generate 255's complement
  4046 	"/ must generate 255's complement
  4029 
  4047 
  4030         result sign:newSign negated.
  4048 	result sign:newSign negated.
  4031         [index <= lResult] whileTrue:[
  4049 	[index <= lResult] whileTrue:[
  4032             resultDigitByteArray basicAt:index put:16rFF.
  4050 	    resultDigitByteArray basicAt:index put:16rFF.
  4033             index := index + 1.
  4051 	    index := index + 1.
  4034         ].
  4052 	].
  4035         index := lResult.
  4053 	index := lResult.
  4036         [index > 0] whileTrue:[
  4054 	[index > 0] whileTrue:[
  4037             resultDigitByteArray basicAt:index put:(255 - (resultDigitByteArray at:index)).
  4055 	    resultDigitByteArray basicAt:index put:(255 - (resultDigitByteArray at:index)).
  4038             index := index - 1.
  4056 	    index := index - 1.
  4039         ].
  4057 	].
  4040 
  4058 
  4041         index := 1.
  4059 	index := 1.
  4042         carry := 1.
  4060 	carry := 1.
  4043         [carry ~~ 0] whileTrue:[
  4061 	[carry ~~ 0] whileTrue:[
  4044             (index <= lResult) ifTrue:[
  4062 	    (index <= lResult) ifTrue:[
  4045                 carry := (resultDigitByteArray basicAt:index) + carry.
  4063 		carry := (resultDigitByteArray basicAt:index) + carry.
  4046             ].
  4064 	    ].
  4047             resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF).
  4065 	    resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF).
  4048             carry := carry bitShift:-8.
  4066 	    carry := carry bitShift:-8.
  4049             index := index + 1
  4067 	    index := index + 1
  4050         ].
  4068 	].
  4051         lastDigit := resultDigitByteArray basicAt:lResult.
  4069 	lastDigit := resultDigitByteArray basicAt:lResult.
  4052     ].
  4070     ].
  4053     (lastDigit == 0 or:[lResult <= SmallInteger maxBytes]) ifTrue:[
  4071     (lastDigit == 0 or:[lResult <= SmallInteger maxBytes]) ifTrue:[
  4054         ^ result compressed.
  4072 	^ result compressed.
  4055     ].
  4073     ].
  4056     ^ result
  4074     ^ result
  4057 
  4075 
  4058     "Modified: 5.11.1996 / 14:09:25 / cg"
  4076     "Modified: 5.11.1996 / 14:09:25 / cg"
  4059 !
  4077 !
  4427 %{
  4445 %{
  4428     OBJ _digitByteArray = __INST(digitByteArray);
  4446     OBJ _digitByteArray = __INST(digitByteArray);
  4429 
  4447 
  4430     if (__isByteArray(_digitByteArray)
  4448     if (__isByteArray(_digitByteArray)
  4431      && __isByteArray(otherDigitByteArray)) {
  4449      && __isByteArray(otherDigitByteArray)) {
  4432         int _len1, _len2, _newLen;
  4450 	int _len1, _len2, _newLen;
  4433         unsigned char *_myDigits, *_otherDigits, *_newDigits;
  4451 	unsigned char *_myDigits, *_otherDigits, *_newDigits;
  4434         int _index, _carry;
  4452 	int _index, _carry;
  4435         int _comLen;
  4453 	int _comLen;
  4436 
  4454 
  4437         _len1 = __byteArraySize(_digitByteArray);
  4455 	_len1 = __byteArraySize(_digitByteArray);
  4438         _len2 = __byteArraySize(otherDigitByteArray);
  4456 	_len2 = __byteArraySize(otherDigitByteArray);
  4439 
  4457 
  4440         _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  4458 	_otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  4441         _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  4459 	_myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  4442 
  4460 
  4443         if (_len1 < _len2) {
  4461 	if (_len1 < _len2) {
  4444             _comLen = _len1;
  4462 	    _comLen = _len1;
  4445             _newLen = _len2;
  4463 	    _newLen = _len2;
  4446             if (_otherDigits[_len2 - 1] == 0xFF) _newLen++;
  4464 	    if (_otherDigits[_len2 - 1] == 0xFF) _newLen++;
  4447         } else if (_len2 < _len1) {
  4465 	} else if (_len2 < _len1) {
  4448             _comLen = _len2;
  4466 	    _comLen = _len2;
  4449             _newLen = _len1;
  4467 	    _newLen = _len1;
  4450             if (_myDigits[_len1 - 1] == 0xFF) _newLen++;
  4468 	    if (_myDigits[_len1 - 1] == 0xFF) _newLen++;
  4451         } else {
  4469 	} else {
  4452             /*
  4470 	    /*
  4453              * there can only be an overflow from the high bytes,
  4471 	     * there can only be an overflow from the high bytes,
  4454              * if their sum is >= 255
  4472 	     * if their sum is >= 255
  4455              * (with sum==255, a carry could still occur from the next lower bytes)
  4473 	     * (with sum==255, a carry could still occur from the next lower bytes)
  4456              */
  4474 	     */
  4457             _newLen = _len1;
  4475 	    _newLen = _len1;
  4458             if ((_otherDigits[_len2 - 1] + _myDigits[_len1 - 1]) >= 0xFF) {
  4476 	    if ((_otherDigits[_len2 - 1] + _myDigits[_len1 - 1]) >= 0xFF) {
  4459                 _newLen++;
  4477 		_newLen++;
  4460             } else {
  4478 	    } else {
  4461                 if (_newLen == sizeof(INT)) {
  4479 		if (_newLen == sizeof(INT)) {
  4462                     OBJ _uint;
  4480 		    OBJ _uint;
  4463 
  4481 
  4464                     /*
  4482 		    /*
  4465                      * two word-sized numbers, no carry - a very common case ...
  4483 		     * two word-sized numbers, no carry - a very common case ...
  4466                      */
  4484 		     */
  4467 #if defined(__LSB_FIRST__)
  4485 #if defined(__LSB_FIRST__)
  4468                     unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits;
  4486 		    unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits;
  4469 #else
  4487 #else
  4470                     unsigned INT _sum = __unsignedLongIntVal(self) + __unsignedLongIntVal(aLargeInteger);
  4488 		    unsigned INT _sum = __unsignedLongIntVal(self) + __unsignedLongIntVal(aLargeInteger);
  4471 #endif /* not LSB_FIRST */
  4489 #endif /* not LSB_FIRST */
  4472                     if (_sum <= _MAX_INT) {
  4490 		    if (_sum <= _MAX_INT) {
  4473                         _uint = __mkSmallInteger(_sum * __intVal(newSign));
  4491 			_uint = __mkSmallInteger(_sum * __intVal(newSign));
  4474                     } else {
  4492 		    } else {
  4475                         _uint = __MKULARGEINT(_sum);
  4493 			_uint = __MKULARGEINT(_sum);
  4476                         __LargeIntegerInstPtr(_uint)->l_sign = newSign;
  4494 			__LargeIntegerInstPtr(_uint)->l_sign = newSign;
  4477                     }
  4495 		    }
  4478                     RETURN (_uint);
  4496 		    RETURN (_uint);
  4479                 }
  4497 		}
  4480             }
  4498 	    }
  4481             _comLen = _len1;
  4499 	    _comLen = _len1;
  4482         }
  4500 	}
  4483         resultDigitByteArray = __BYTEARRAY_UNINITIALIZED_NEW_INT(_newLen);
  4501 	resultDigitByteArray = __BYTEARRAY_UNINITIALIZED_NEW_INT(_newLen);
  4484 
  4502 
  4485         /*
  4503 	/*
  4486          * must refetch - GC could have been invoked
  4504 	 * must refetch - GC could have been invoked
  4487          */
  4505 	 */
  4488         _digitByteArray = __INST(digitByteArray);
  4506 	_digitByteArray = __INST(digitByteArray);
  4489 
  4507 
  4490         _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  4508 	_myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  4491         _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  4509 	_otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  4492         _newDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  4510 	_newDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  4493 
  4511 
  4494         /*
  4512 	/*
  4495          * add them ...
  4513 	 * add them ...
  4496          */
  4514 	 */
  4497         _index = 1;
  4515 	_index = 1;
  4498         _carry = 0;
  4516 	_carry = 0;
  4499 
  4517 
  4500 #if defined(__LSBFIRST__)
  4518 #if defined(__LSBFIRST__)
  4501 # if (__POINTER_SIZE__ == 8) && defined(__GNUC__)
  4519 # if (__POINTER_SIZE__ == 8) && defined(__GNUC__)
  4502 #  if 0  /* not faster (on alpha) */
  4520 #  if 0  /* not faster (on alpha) */
  4503         {
  4521 	{
  4504             int _comLen7;
  4522 	    int _comLen7;
  4505 
  4523 
  4506             /*
  4524 	    /*
  4507              * have a 64bit integers;
  4525 	     * have a 64bit integers;
  4508              * add quad-wise
  4526 	     * add quad-wise
  4509              * accessing bytes at: [index-1][index][index+1]..[index+6]
  4527 	     * accessing bytes at: [index-1][index][index+1]..[index+6]
  4510              */
  4528 	     */
  4511             _comLen7 = _comLen - 3 - 4;
  4529 	    _comLen7 = _comLen - 3 - 4;
  4512             while (_index <= _comLen7) {
  4530 	    while (_index <= _comLen7) {
  4513                 UINT64 _sum, _t1, _t2;
  4531 		UINT64 _sum, _t1, _t2;
  4514 
  4532 
  4515                 asm ("addq   %5,%6,%1         /* sum */                  \n\
  4533 		asm ("addq   %5,%6,%1         /* sum */                  \n\
  4516                       addq   %0,%1,%1         /* plus carryIn */         \n\
  4534 		      addq   %0,%1,%1         /* plus carryIn */         \n\
  4517                       cmpult %1,%5,%2         /* was there a carry ? */  \n\
  4535 		      cmpult %1,%5,%2         /* was there a carry ? */  \n\
  4518                       cmpult %1,%6,%3         /* was there a carry ? */  \n\
  4536 		      cmpult %1,%6,%3         /* was there a carry ? */  \n\
  4519                       bis    %2,%3,%0         /* carryOut */             \n\
  4537 		      bis    %2,%3,%0         /* carryOut */             \n\
  4520                      "
  4538 		     "
  4521                         : "=r"  (_carry),
  4539 			: "=r"  (_carry),
  4522                           "=r"  (_sum),
  4540 			  "=r"  (_sum),
  4523                           "r"   (_t1),
  4541 			  "r"   (_t1),
  4524                           "r"   (_t2)
  4542 			  "r"   (_t2)
  4525                         : "r"   (_carry),
  4543 			: "r"   (_carry),
  4526                           "r"   (((unsigned long *)(&(_myDigits[_index - 1])))[0]),
  4544 			  "r"   (((unsigned long *)(&(_myDigits[_index - 1])))[0]),
  4527                           "r"   (((unsigned long *)(&(_otherDigits[_index - 1])))[0])
  4545 			  "r"   (((unsigned long *)(&(_otherDigits[_index - 1])))[0])
  4528                     );
  4546 		    );
  4529                 /* _sum = _sum & 0xFFFFFFFF; */
  4547 		/* _sum = _sum & 0xFFFFFFFF; */
  4530                 ((unsigned long *)(&(_newDigits[_index - 1])))[0] = _sum;
  4548 		((unsigned long *)(&(_newDigits[_index - 1])))[0] = _sum;
  4531                 _index += 8;
  4549 		_index += 8;
  4532             }
  4550 	    }
  4533         }
  4551 	}
  4534 #  endif
  4552 #  endif
  4535 # endif /* 64bit */
  4553 # endif /* 64bit */
  4536 
  4554 
  4537 # if (__POINTER_SIZE__ == 8)
  4555 # if (__POINTER_SIZE__ == 8)
  4538 # if 0  /* not faster (on alpha) */
  4556 # if 0  /* not faster (on alpha) */
  4539         {
  4557 	{
  4540             int _comLen7;
  4558 	    int _comLen7;
  4541 
  4559 
  4542             /*
  4560 	    /*
  4543              * have a 64bit integers;
  4561 	     * have a 64bit integers;
  4544              * add quad-wise
  4562 	     * add quad-wise
  4545              * accessing bytes at: [index-1][index][index+1]..[index+6]
  4563 	     * accessing bytes at: [index-1][index][index+1]..[index+6]
  4546              */
  4564 	     */
  4547             _comLen7 = _comLen - 3 - 4;
  4565 	    _comLen7 = _comLen - 3 - 4;
  4548             while (_index <= _comLen7) {
  4566 	    while (_index <= _comLen7) {
  4549                 UINT64 _sum, _t1, _t2;
  4567 		UINT64 _sum, _t1, _t2;
  4550 
  4568 
  4551                 _t1 = ((UINT64 *)(&(_myDigits[_index - 1])))[0];
  4569 		_t1 = ((UINT64 *)(&(_myDigits[_index - 1])))[0];
  4552                 _t2 = ((UINT64 *)(&(_otherDigits[_index - 1])))[0];
  4570 		_t2 = ((UINT64 *)(&(_otherDigits[_index - 1])))[0];
  4553                 _sum = _t1 + _t2 + _carry;
  4571 		_sum = _t1 + _t2 + _carry;
  4554                 ((UINT64 *)(&(_newDigits[_index - 1])))[0] = _sum;
  4572 		((UINT64 *)(&(_newDigits[_index - 1])))[0] = _sum;
  4555                 _carry = (_sum < _t1) | (_sum < _t2);
  4573 		_carry = (_sum < _t1) | (_sum < _t2);
  4556                 _index += 8;
  4574 		_index += 8;
  4557             }
  4575 	    }
  4558         }
  4576 	}
  4559 #  endif
  4577 #  endif
  4560 # endif /* 64bit */
  4578 # endif /* 64bit */
  4561 
  4579 
  4562 # ifdef UINT64
  4580 # ifdef UINT64
  4563         {
  4581 	{
  4564             int _comLen3;
  4582 	    int _comLen3;
  4565 
  4583 
  4566             /*
  4584 	    /*
  4567              * have a 64bit integer type;
  4585 	     * have a 64bit integer type;
  4568              * add int-wise
  4586 	     * add int-wise
  4569              * accessing bytes at: [index-1][index][index+1][index+2]
  4587 	     * accessing bytes at: [index-1][index][index+1][index+2]
  4570              */
  4588 	     */
  4571             _comLen3 = _comLen - 3;
  4589 	    _comLen3 = _comLen - 3;
  4572             while (_index <= _comLen3) {
  4590 	    while (_index <= _comLen3) {
  4573                 UINT64 _sum;
  4591 		UINT64 _sum;
  4574 
  4592 
  4575                 /* do not merge the 3 lines below into one -
  4593 		/* do not merge the 3 lines below into one -
  4576                  * (will do sign extension then, which is wrong here)
  4594 		 * (will do sign extension then, which is wrong here)
  4577                  */
  4595 		 */
  4578                 _sum = (unsigned)_carry;
  4596 		_sum = (unsigned)_carry;
  4579                 _sum += ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  4597 		_sum += ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  4580                 _sum += ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  4598 		_sum += ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  4581                 _carry = _sum >> 32;
  4599 		_carry = _sum >> 32;
  4582                 /* _sum = _sum & 0xFFFFFFFF; */
  4600 		/* _sum = _sum & 0xFFFFFFFF; */
  4583                 ((unsigned int *)(&(_newDigits[_index - 1])))[0] = _sum;
  4601 		((unsigned int *)(&(_newDigits[_index - 1])))[0] = _sum;
  4584                 _index += 4;
  4602 		_index += 4;
  4585             }
  4603 	    }
  4586         }
  4604 	}
  4587 # else
  4605 # else
  4588 #  if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4)
  4606 #  if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4)
  4589         {
  4607 	{
  4590             int _comLen3;
  4608 	    int _comLen3;
  4591 
  4609 
  4592             _comLen3 = _comLen - 3 - 4;
  4610 	    _comLen3 = _comLen - 3 - 4;
  4593             while (_index <= _comLen3) {
  4611 	    while (_index <= _comLen3) {
  4594                 unsigned int _sum, _sum2;
  4612 		unsigned int _sum, _sum2;
  4595                 unsigned int __in1A, __in1B, __in2A, __in2B;
  4613 		unsigned int __in1A, __in1B, __in2A, __in2B;
  4596 
  4614 
  4597                 __in1A = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  4615 		__in1A = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  4598                 __in2A = ((unsigned int *)(&(_myDigits[_index - 1])))[1];
  4616 		__in2A = ((unsigned int *)(&(_myDigits[_index - 1])))[1];
  4599                 __in1B = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  4617 		__in1B = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  4600                 __in2B = ((unsigned int *)(&(_otherDigits[_index - 1])))[1];
  4618 		__in2B = ((unsigned int *)(&(_otherDigits[_index - 1])))[1];
  4601 
  4619 
  4602                 asm ("addl %%edx,%%eax  \n\
  4620 		asm ("addl %%edx,%%eax  \n\
  4603                       movl $0,%%edx     \n\
  4621 		      movl $0,%%edx     \n\
  4604                       adcl $0,%%edx     \n\
  4622 		      adcl $0,%%edx     \n\
  4605                       addl %5,%%eax     \n\
  4623 		      addl %5,%%eax     \n\
  4606                       adcl $0,%%edx     \n\
  4624 		      adcl $0,%%edx     \n\
  4607                                         \n\
  4625 					\n\
  4608                       addl %%edx,%%ecx  \n\
  4626 		      addl %%edx,%%ecx  \n\
  4609                       movl $0,%%edx     \n\
  4627 		      movl $0,%%edx     \n\
  4610                       adcl $0,%%edx     \n\
  4628 		      adcl $0,%%edx     \n\
  4611                       addl %7,%%ecx     \n\
  4629 		      addl %7,%%ecx     \n\
  4612                       adcl $0,%%edx     \n\
  4630 		      adcl $0,%%edx     \n\
  4613                      "
  4631 		     "
  4614                         : "=d"  (_carry),
  4632 			: "=d"  (_carry),
  4615                           "=a"  (_sum),
  4633 			  "=a"  (_sum),
  4616                           "=c"  (_sum2)
  4634 			  "=c"  (_sum2)
  4617                         : "0"   (_carry),
  4635 			: "0"   (_carry),
  4618                           "1"   (__in1A),
  4636 			  "1"   (__in1A),
  4619                           "rm"  (__in1B),
  4637 			  "rm"  (__in1B),
  4620                           "2"   (__in2A),
  4638 			  "2"   (__in2A),
  4621                           "rm"  (__in2B)
  4639 			  "rm"  (__in2B)
  4622                     );
  4640 		    );
  4623 
  4641 
  4624                 ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
  4642 		((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
  4625                 ((unsigned *)(&(_newDigits[_index - 1])))[1] = _sum2;
  4643 		((unsigned *)(&(_newDigits[_index - 1])))[1] = _sum2;
  4626                 _index += 8;
  4644 		_index += 8;
  4627             }
  4645 	    }
  4628             /*
  4646 	    /*
  4629              * add int-wise
  4647 	     * add int-wise
  4630              * accessing bytes at: [index-1][index][index+1][index+2]
  4648 	     * accessing bytes at: [index-1][index][index+1][index+2]
  4631              */
  4649 	     */
  4632             _comLen3 = _comLen3 + 4;
  4650 	    _comLen3 = _comLen3 + 4;
  4633             if (_index <= _comLen3) {
  4651 	    if (_index <= _comLen3) {
  4634                 unsigned int _sum;
  4652 		unsigned int _sum;
  4635                 unsigned int __inA, __inB;
  4653 		unsigned int __inA, __inB;
  4636 
  4654 
  4637                 __inA = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  4655 		__inA = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  4638                 __inB = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  4656 		__inB = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  4639 
  4657 
  4640                 asm ("addl %%edx,%%eax      \n\
  4658 		asm ("addl %%edx,%%eax      \n\
  4641                       movl $0,%%edx         \n\
  4659 		      movl $0,%%edx         \n\
  4642                       adcl $0,%%edx         \n\
  4660 		      adcl $0,%%edx         \n\
  4643                       addl %4,%%eax         \n\
  4661 		      addl %4,%%eax         \n\
  4644                       adcl $0,%%edx"
  4662 		      adcl $0,%%edx"
  4645                         : "=d"  (_carry),
  4663 			: "=d"  (_carry),
  4646                           "=a"  (_sum)
  4664 			  "=a"  (_sum)
  4647                         : "0"   (_carry),
  4665 			: "0"   (_carry),
  4648                           "1"   (__inA),
  4666 			  "1"   (__inA),
  4649                           "rm"  (__inB)
  4667 			  "rm"  (__inB)
  4650                     );
  4668 		    );
  4651 
  4669 
  4652                 ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
  4670 		((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
  4653                 _index += 4;
  4671 		_index += 4;
  4654             }
  4672 	    }
  4655         }
  4673 	}
  4656 #  endif /* __i386__ && GNUC */
  4674 #  endif /* __i386__ && GNUC */
  4657 #  if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
  4675 #  if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
  4658         {
  4676 	{
  4659             int _comLen3;
  4677 	    int _comLen3;
  4660 
  4678 
  4661             /*
  4679 	    /*
  4662              * add long-wise
  4680 	     * add long-wise
  4663              * accessing bytes at: [index-1][index][index+1][index+2]
  4681 	     * accessing bytes at: [index-1][index][index+1][index+2]
  4664              */
  4682 	     */
  4665             _comLen3 = _comLen - 3;
  4683 	    _comLen3 = _comLen - 3;
  4666             while (_index <= _comLen3) {
  4684 	    while (_index <= _comLen3) {
  4667                 unsigned int _sum, _v1, _v2;
  4685 		unsigned int _sum, _v1, _v2;
  4668 
  4686 
  4669                 _v1 = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  4687 		_v1 = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  4670                 _v2 = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  4688 		_v2 = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  4671                 asm {
  4689 		asm {
  4672                       mov eax, _v1
  4690 		      mov eax, _v1
  4673                       add eax, _v2
  4691 		      add eax, _v2
  4674                       mov edx, 0
  4692 		      mov edx, 0
  4675                       adc edx, 0
  4693 		      adc edx, 0
  4676                       add eax, _carry
  4694 		      add eax, _carry
  4677                       adc edx, 0
  4695 		      adc edx, 0
  4678                       mov _carry, edx
  4696 		      mov _carry, edx
  4679                       mov _sum, eax
  4697 		      mov _sum, eax
  4680                     }
  4698 		    }
  4681 
  4699 
  4682                 ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
  4700 		((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
  4683                 _index += 4;
  4701 		_index += 4;
  4684             }
  4702 	    }
  4685         }
  4703 	}
  4686 #  endif /* __i386__ && WIN32 */
  4704 #  endif /* __i386__ && WIN32 */
  4687 # endif /* INT64 */
  4705 # endif /* INT64 */
  4688         /*
  4706 	/*
  4689          * add short-wise
  4707 	 * add short-wise
  4690          * accessing bytes at: [index-1][index]
  4708 	 * accessing bytes at: [index-1][index]
  4691          */
  4709 	 */
  4692         while (_index < _comLen) {
  4710 	while (_index < _comLen) {
  4693             unsigned int _sum;
  4711 	    unsigned int _sum;
  4694 
  4712 
  4695             _sum = _carry
  4713 	    _sum = _carry
  4696                    + ((unsigned short *)(&(_myDigits[_index - 1])))[0]
  4714 		   + ((unsigned short *)(&(_myDigits[_index - 1])))[0]
  4697                    + ((unsigned short *)(&(_otherDigits[_index - 1])))[0];
  4715 		   + ((unsigned short *)(&(_otherDigits[_index - 1])))[0];
  4698             _carry = _sum >> 16;
  4716 	    _carry = _sum >> 16;
  4699             /* _sum = _sum & 0xFFFF; */
  4717 	    /* _sum = _sum & 0xFFFF; */
  4700             *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
  4718 	    *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
  4701             _index += 2;
  4719 	    _index += 2;
  4702         }
  4720 	}
  4703 #else
  4721 #else
  4704 # ifdef __sparc__
  4722 # ifdef __sparc__
  4705         /*
  4723 	/*
  4706          * add short-wise
  4724 	 * add short-wise
  4707          * accessing bytes at: [index-1][index]
  4725 	 * accessing bytes at: [index-1][index]
  4708          */
  4726 	 */
  4709         while (_index < _comLen) {
  4727 	while (_index < _comLen) {
  4710             unsigned int _sum;
  4728 	    unsigned int _sum;
  4711             unsigned short _v1, _v2;
  4729 	    unsigned short _v1, _v2;
  4712 
  4730 
  4713             _v1 = ((unsigned short *)(&(_myDigits[_index - 1])))[0];
  4731 	    _v1 = ((unsigned short *)(&(_myDigits[_index - 1])))[0];
  4714             _v2 = ((unsigned short *)(&(_otherDigits[_index - 1])))[0];
  4732 	    _v2 = ((unsigned short *)(&(_otherDigits[_index - 1])))[0];
  4715             _sum = _carry + (_v1>>8) + (_v2>>8);
  4733 	    _sum = _carry + (_v1>>8) + (_v2>>8);
  4716             _carry = _sum >> 8;
  4734 	    _carry = _sum >> 8;
  4717             _newDigits[_index - 1] = _sum;
  4735 	    _newDigits[_index - 1] = _sum;
  4718 
  4736 
  4719             _sum = _carry + (_v1 & 0xFF) + (_v2 & 0xFF);
  4737 	    _sum = _carry + (_v1 & 0xFF) + (_v2 & 0xFF);
  4720             _carry = _sum >> 8;
  4738 	    _carry = _sum >> 8;
  4721             _newDigits[_index] = _sum;
  4739 	    _newDigits[_index] = _sum;
  4722             _index += 2;
  4740 	    _index += 2;
  4723         }
  4741 	}
  4724 # endif
  4742 # endif
  4725 #endif /* __LSBFIRST__ */
  4743 #endif /* __LSBFIRST__ */
  4726 
  4744 
  4727         /*
  4745 	/*
  4728          * add byte-wise
  4746 	 * add byte-wise
  4729          */
  4747 	 */
  4730         while (_index <= _comLen) {
  4748 	while (_index <= _comLen) {
  4731             unsigned int _sum;
  4749 	    unsigned int _sum;
  4732 
  4750 
  4733             _sum = _carry
  4751 	    _sum = _carry
  4734                    + _myDigits[_index - 1]
  4752 		   + _myDigits[_index - 1]
  4735                    + _otherDigits[_index - 1];
  4753 		   + _otherDigits[_index - 1];
  4736             _carry = _sum >> 8;
  4754 	    _carry = _sum >> 8;
  4737             /* _sum = _sum & 0xFF; */
  4755 	    /* _sum = _sum & 0xFF; */
  4738             _newDigits[_index - 1] = _sum;
  4756 	    _newDigits[_index - 1] = _sum;
  4739             _index++;
  4757 	    _index++;
  4740         }
  4758 	}
  4741 
  4759 
  4742         /*
  4760 	/*
  4743          * rest
  4761 	 * rest
  4744          */
  4762 	 */
  4745         if (_len1 > _len2) {
  4763 	if (_len1 > _len2) {
  4746 #if defined(__LSBFIRST__)
  4764 #if defined(__LSBFIRST__)
  4747             if (_index <= _len1) {
  4765 	    if (_index <= _len1) {
  4748                 if ((_index - 1) & 1) {
  4766 		if ((_index - 1) & 1) {
  4749                     /* odd byte */
  4767 		    /* odd byte */
  4750                     unsigned int _sum;
  4768 		    unsigned int _sum;
  4751 
  4769 
  4752                     _sum = _carry + _myDigits[_index - 1];
  4770 		    _sum = _carry + _myDigits[_index - 1];
  4753                     _carry = _sum >> 8;
  4771 		    _carry = _sum >> 8;
  4754                     /* _sum = _sum & 0xFF; */
  4772 		    /* _sum = _sum & 0xFF; */
  4755                     _newDigits[_index - 1] = _sum;
  4773 		    _newDigits[_index - 1] = _sum;
  4756                     _index++;
  4774 		    _index++;
  4757                 }
  4775 		}
  4758 
  4776 
  4759                 while (_index < _len1) {
  4777 		while (_index < _len1) {
  4760                     /* shorts */
  4778 		    /* shorts */
  4761                     unsigned int _sum;
  4779 		    unsigned int _sum;
  4762 
  4780 
  4763                     _sum = _carry + *(unsigned short *)(&(_myDigits[_index - 1]));
  4781 		    _sum = _carry + *(unsigned short *)(&(_myDigits[_index - 1]));
  4764                     _carry = _sum >> 16;
  4782 		    _carry = _sum >> 16;
  4765                     /* _sum = _sum & 0xFFFF; */
  4783 		    /* _sum = _sum & 0xFFFF; */
  4766                     *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
  4784 		    *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
  4767                     _index += 2;
  4785 		    _index += 2;
  4768                 }
  4786 		}
  4769 
  4787 
  4770                 if (_index <= _len1) {
  4788 		if (_index <= _len1) {
  4771                     /* last byte */
  4789 		    /* last byte */
  4772                     unsigned int _sum;
  4790 		    unsigned int _sum;
  4773 
  4791 
  4774                     _sum = _carry + _myDigits[_index - 1];
  4792 		    _sum = _carry + _myDigits[_index - 1];
  4775                     _carry = _sum >> 8;
  4793 		    _carry = _sum >> 8;
  4776                     /* _sum = _sum & 0xFF; */
  4794 		    /* _sum = _sum & 0xFF; */
  4777                     _newDigits[_index - 1] = _sum;
  4795 		    _newDigits[_index - 1] = _sum;
  4778                     _index++;
  4796 		    _index++;
  4779                 }
  4797 		}
  4780             }
  4798 	    }
  4781 #else
  4799 #else
  4782             while (_index <= _len1) {
  4800 	    while (_index <= _len1) {
  4783                 unsigned int _sum;
  4801 		unsigned int _sum;
  4784 
  4802 
  4785                 _sum = _carry + _myDigits[_index - 1];
  4803 		_sum = _carry + _myDigits[_index - 1];
  4786                 _carry = _sum >> 8;
  4804 		_carry = _sum >> 8;
  4787                 /* _sum = _sum & 0xFF; */
  4805 		/* _sum = _sum & 0xFF; */
  4788                 _newDigits[_index - 1] = _sum;
  4806 		_newDigits[_index - 1] = _sum;
  4789                 _index++;
  4807 		_index++;
  4790             }
  4808 	    }
  4791 #endif /* not LSB */
  4809 #endif /* not LSB */
  4792         } else {
  4810 	} else {
  4793             if (_len2 > _len1) {
  4811 	    if (_len2 > _len1) {
  4794 #if defined(__LSBFIRST__)
  4812 #if defined(__LSBFIRST__)
  4795                 if (_index <= _len2) {
  4813 		if (_index <= _len2) {
  4796                     if ((_index - 1) & 1) {
  4814 		    if ((_index - 1) & 1) {
  4797                         /* odd byte */
  4815 			/* odd byte */
  4798                         unsigned int _sum;
  4816 			unsigned int _sum;
  4799 
  4817 
  4800                         _sum = _carry + _otherDigits[_index - 1];
  4818 			_sum = _carry + _otherDigits[_index - 1];
  4801                         _carry = _sum >> 8;
  4819 			_carry = _sum >> 8;
  4802                         /* _sum = _sum & 0xFF; */
  4820 			/* _sum = _sum & 0xFF; */
  4803                         _newDigits[_index - 1] = _sum;
  4821 			_newDigits[_index - 1] = _sum;
  4804                         _index++;
  4822 			_index++;
  4805                     }
  4823 		    }
  4806 
  4824 
  4807                     while (_index < _len2) {
  4825 		    while (_index < _len2) {
  4808                         /* shorts */
  4826 			/* shorts */
  4809                         unsigned int _sum;
  4827 			unsigned int _sum;
  4810 
  4828 
  4811                         _sum = _carry + *(unsigned short *)(&(_otherDigits[_index - 1]));
  4829 			_sum = _carry + *(unsigned short *)(&(_otherDigits[_index - 1]));
  4812                         _carry = _sum >> 16;
  4830 			_carry = _sum >> 16;
  4813                         /* _sum = _sum & 0xFFFF; */
  4831 			/* _sum = _sum & 0xFFFF; */
  4814                         *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
  4832 			*(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
  4815                         _index += 2;
  4833 			_index += 2;
  4816                     }
  4834 		    }
  4817 
  4835 
  4818                     if (_index <= _len2) {
  4836 		    if (_index <= _len2) {
  4819                         /* last byte */
  4837 			/* last byte */
  4820                         unsigned int _sum;
  4838 			unsigned int _sum;
  4821 
  4839 
  4822                         _sum = _carry + _otherDigits[_index - 1];
  4840 			_sum = _carry + _otherDigits[_index - 1];
  4823                         _carry = _sum >> 8;
  4841 			_carry = _sum >> 8;
  4824                         /* _sum = _sum & 0xFF; */
  4842 			/* _sum = _sum & 0xFF; */
  4825                         _newDigits[_index - 1] = _sum;
  4843 			_newDigits[_index - 1] = _sum;
  4826                         _index++;
  4844 			_index++;
  4827                     }
  4845 		    }
  4828                 }
  4846 		}
  4829 #else
  4847 #else
  4830                 while (_index <= _len2) {
  4848 		while (_index <= _len2) {
  4831                     unsigned int _sum;
  4849 		    unsigned int _sum;
  4832 
  4850 
  4833                     _sum = _carry + _otherDigits[_index - 1];
  4851 		    _sum = _carry + _otherDigits[_index - 1];
  4834                     _carry = _sum >> 8;
  4852 		    _carry = _sum >> 8;
  4835                     /* _sum = _sum & 0xFF; */
  4853 		    /* _sum = _sum & 0xFF; */
  4836                     _newDigits[_index - 1] = _sum;
  4854 		    _newDigits[_index - 1] = _sum;
  4837                     _index++;
  4855 		    _index++;
  4838                 }
  4856 		}
  4839 #endif /* not LSB */
  4857 #endif /* not LSB */
  4840             }
  4858 	    }
  4841         }
  4859 	}
  4842 
  4860 
  4843         while (_index <= _newLen) {
  4861 	while (_index <= _newLen) {
  4844             unsigned int _sum;
  4862 	    unsigned int _sum;
  4845 
  4863 
  4846             _sum = _carry;
  4864 	    _sum = _carry;
  4847             _carry = _sum >> 8;
  4865 	    _carry = _sum >> 8;
  4848             /* _sum = _sum & 0xFF; */
  4866 	    /* _sum = _sum & 0xFF; */
  4849             _newDigits[_index - 1] = _sum;
  4867 	    _newDigits[_index - 1] = _sum;
  4850             _index++;
  4868 	    _index++;
  4851         }
  4869 	}
  4852     }
  4870     }
  4853 %}.
  4871 %}.
  4854     resultDigitByteArray notNil ifTrue:[
  4872     resultDigitByteArray notNil ifTrue:[
  4855         result := self class basicNew.
  4873 	result := self class basicNew.
  4856         result setDigits:resultDigitByteArray.
  4874 	result setDigits:resultDigitByteArray.
  4857         result setSign:newSign.
  4875 	result setSign:newSign.
  4858     ] ifFalse:[
  4876     ] ifFalse:[
  4859         len1 := digitByteArray size.
  4877 	len1 := digitByteArray size.
  4860         len2 := otherDigitByteArray size.
  4878 	len2 := otherDigitByteArray size.
  4861 
  4879 
  4862         "/ earlier versions estimated the newLength as:
  4880 	"/ earlier versions estimated the newLength as:
  4863         "/ (len1 max:len2) + 1
  4881 	"/ (len1 max:len2) + 1
  4864         "/ and reduced the result.
  4882 	"/ and reduced the result.
  4865         "/ however, if one of the addends is smaller,
  4883 	"/ however, if one of the addends is smaller,
  4866         "/ the result will never require another digit,
  4884 	"/ the result will never require another digit,
  4867         "/ if the highest digit of the larger addent is
  4885 	"/ if the highest digit of the larger addent is
  4868         "/ not equal to 255. Therefore, in most cases,
  4886 	"/ not equal to 255. Therefore, in most cases,
  4869         "/ we can avoid the computation and resizing
  4887 	"/ we can avoid the computation and resizing
  4870         "/ in #reduced.
  4888 	"/ in #reduced.
  4871 
  4889 
  4872         len1 < len2 ifTrue:[
  4890 	len1 < len2 ifTrue:[
  4873             newLen := len2.
  4891 	    newLen := len2.
  4874             (otherDigitByteArray at:len2) == 16rFF ifTrue:[
  4892 	    (otherDigitByteArray at:len2) == 16rFF ifTrue:[
  4875                 newLen := newLen + 1
  4893 		newLen := newLen + 1
  4876             ]
  4894 	    ]
  4877         ] ifFalse:[
  4895 	] ifFalse:[
  4878             len2 < len1 ifTrue:[
  4896 	    len2 < len1 ifTrue:[
  4879                 newLen := len1.
  4897 		newLen := len1.
  4880                 (digitByteArray at:len1) == 16rFF ifTrue:[
  4898 		(digitByteArray at:len1) == 16rFF ifTrue:[
  4881                     newLen := newLen + 1
  4899 		    newLen := newLen + 1
  4882                 ]
  4900 		]
  4883             ] ifFalse:[
  4901 	    ] ifFalse:[
  4884                 newLen := len1 + 1.
  4902 		newLen := len1 + 1.
  4885             ]
  4903 	    ]
  4886         ].
  4904 	].
  4887 
  4905 
  4888         result := self class basicNew numberOfDigits:newLen.
  4906 	result := self class basicNew numberOfDigits:newLen.
  4889         result sign:newSign.
  4907 	result sign:newSign.
  4890         resultDigitByteArray := result digitBytes.
  4908 	resultDigitByteArray := result digitBytes.
  4891 
  4909 
  4892         index := 1.
  4910 	index := 1.
  4893         carry := 0.
  4911 	carry := 0.
  4894 
  4912 
  4895         done := false.
  4913 	done := false.
  4896         [done] whileFalse:[
  4914 	[done] whileFalse:[
  4897             sum := carry.
  4915 	    sum := carry.
  4898             (index <= len1) ifTrue:[
  4916 	    (index <= len1) ifTrue:[
  4899                 sum := sum + (digitByteArray basicAt:index).
  4917 		sum := sum + (digitByteArray basicAt:index).
  4900                 (index <= len2) ifTrue:[
  4918 		(index <= len2) ifTrue:[
  4901                     sum := sum + (otherDigitByteArray basicAt:index)
  4919 		    sum := sum + (otherDigitByteArray basicAt:index)
  4902                 ]
  4920 		]
  4903             ] ifFalse:[
  4921 	    ] ifFalse:[
  4904                 (index <= len2) ifTrue:[
  4922 		(index <= len2) ifTrue:[
  4905                     sum := sum + (otherDigitByteArray basicAt:index)
  4923 		    sum := sum + (otherDigitByteArray basicAt:index)
  4906                 ] ifFalse:[
  4924 		] ifFalse:[
  4907                     "end reached"
  4925 		    "end reached"
  4908                     done := true
  4926 		    done := true
  4909                 ]
  4927 		]
  4910             ].
  4928 	    ].
  4911             (sum >= 16r100) ifTrue:[
  4929 	    (sum >= 16r100) ifTrue:[
  4912                 carry := 1.
  4930 		carry := 1.
  4913                 sum := sum - 16r100
  4931 		sum := sum - 16r100
  4914             ] ifFalse:[
  4932 	    ] ifFalse:[
  4915                 carry := 0
  4933 		carry := 0
  4916             ].
  4934 	    ].
  4917             resultDigitByteArray basicAt:index put:sum.
  4935 	    resultDigitByteArray basicAt:index put:sum.
  4918             index := index + 1
  4936 	    index := index + 1
  4919         ].
  4937 	].
  4920     ].
  4938     ].
  4921 
  4939 
  4922     ^ result compressed
  4940     ^ result compressed
  4923 
  4941 
  4924     "Modified: 11.8.1997 / 03:23:37 / cg"
  4942     "Modified: 11.8.1997 / 03:23:37 / cg"
  5470 ! !
  5488 ! !
  5471 
  5489 
  5472 !LargeInteger class methodsFor:'documentation'!
  5490 !LargeInteger class methodsFor:'documentation'!
  5473 
  5491 
  5474 version
  5492 version
  5475     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.226 2015-05-20 16:01:28 cg Exp $'
  5493     ^ '$Header$'
  5476 !
  5494 !
  5477 
  5495 
  5478 version_CVS
  5496 version_CVS
  5479     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.226 2015-05-20 16:01:28 cg Exp $'
  5497     ^ '$Header$'
  5480 ! !
  5498 ! !
  5481