LargeInteger.st
branchjv
changeset 18112 0d7ac9096619
parent 18084 ab5b38bd8f81
parent 15838 314ffd3696d3
child 18117 eb433f2c42b2
--- a/LargeInteger.st	Tue Dec 03 16:54:12 2013 +0000
+++ b/LargeInteger.st	Thu Dec 05 09:52:02 2013 +0000
@@ -3940,8 +3940,8 @@
         unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
         unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
         unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
-        unsigned char *_p1, *_p2, *_pResult, *_pResult0, *_pResult1, *_p1Last, *_p2Last;
-        unsigned char *_pResultLast1;
+        unsigned char *_p1, *_pResult0, *_p1Last, *_p2Last, *_pResultLast;
+        unsigned char *_pResultLastShort, *_pResultLastInt;
         unsigned INT _v;
         int _len1 = __intVal(len1);
         int _len2 = __intVal(len2);
@@ -3949,6 +3949,7 @@
         _p1Last = myBytes    + _len1 - 1;  /* the last byte */
         _p2Last = otherBytes + _len2 - 1;  /* the last byte */
         _pResult0 = resultBytes;
+        _pResultLast = resultBytes + _len1 + _len2 - 1; /* the last byte */
 
         /*
          *        aaa...aaa      f1[0] * f2
@@ -3963,27 +3964,29 @@
         _p1 = myBytes;
 
 #if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8)
+        _pResultLastInt = _pResultLast - 3;   /* the last int */
+
         /* loop over ints of f1 */
-        for (; _p1 < _p1Last-3; _p1 += 4, _pResult0 += 4) {
+        for (; _p1 <= (_p1Last-3); _p1 += 4, _pResult0 += 4) {
+            unsigned char *_pResult, *_p2;
             unsigned INT word1 = ((unsigned int *)_p1)[0];
 
             _pResult = _pResult0;
             _p2 = otherBytes;
 
             /* loop over ints of f2 */
-            while (_p2 < (_p2Last-3)) {
-                _v = (word1 * ((unsigned int *)_p2)[0]) + ((unsigned int *)_pResult)[0];
+            while (_p2 <= (_p2Last-3)) {
+                _v = (word1 * (unsigned INT)(((unsigned int *)_p2)[0])) + ((unsigned INT)((unsigned int *)_pResult)[0]);
                 ((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
                 _v >>= 32; /* now _v contains the carry*/
                 _pResult += 4;
                 if (_v) {
-                    unsigned char *_pResultLast3;
+                    unsigned char *_pResult1;
 
                     /* distribute carry - int-wise, then byte-wise */
-                    _pResultLast3 = _pResult0 + _len1 + _len2 - 1 - 3;
                     for (_pResult1 = _pResult; _v; _pResult1 += 4) {
-                        if (_pResult1 > _pResultLast3) break;
-                        _v += ((unsigned int *)_pResult1)[0];
+                        if (_pResult1 > _pResultLastInt) break;
+                        _v += (unsigned INT)(((unsigned int *)_pResult1)[0]);
                         ((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
                         _v >>= 32;
                     }
@@ -3998,21 +4001,15 @@
 
             /* possible odd highByte of f2 */
             while (_p2 <= _p2Last) {
-                _v = (word1 * _p2[0]) + ((unsigned int *)_pResult)[0];
-                ((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
-                _v >>= 32; /* now _v contains the carry*/
-                _pResult += 4;
+                _v = (word1 * (unsigned INT)((unsigned char *)_p2[0])) + (unsigned INT)((unsigned char *)_pResult[0]);
+
+                ((unsigned char *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
+                _v >>= 8; /* now _v contains the carry*/
+                _pResult++;
                 if (_v) {
-                    unsigned char *_pResultLast3;
-
-                    /* distribute carry - int-wise, then byte-wise */
-                    _pResultLast3 = _pResult0 + _len1 + _len2 - 1 - 3;
-                    for (_pResult1 = _pResult; _v; _pResult1 += 4) {
-                        if (_pResult1 > _pResultLast3) break;
-                        _v += ((unsigned int *)_pResult1)[0];
-                        ((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
-                        _v >>= 32;
-                    }
+                    unsigned char *_pResult1 = _pResult;
+
+                    /* distribute carry byte-wise */
                     for (; _v; _pResult1++) {
                         _v += _pResult1[0];
                         _pResult1[0] = _v /* & 0xFF */;
@@ -4024,8 +4021,11 @@
         }
 #endif /* 64bit */
 
-        /* loop over shorts of f1 */
+        /* possible odd high short of f1 (or shortLoop, if not 64bit) */
+        _pResultLastShort = _pResultLast - 1; /* the last short */
+
         for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
+            unsigned char *_pResult, *_p2;
             unsigned int short1 = ((unsigned short *)_p1)[0];
 
 #if !defined(__LSBFIRST__)
@@ -4054,12 +4054,13 @@
                 _v >>= 16; /* now _v contains the carry*/
                 _pResult += 2;
                 if (_v) {
+                    unsigned char *_pResult1;
+
                     /* distribute carry - short-wise, then byte-wise */
                     _pResult1 = _pResult;
 #if defined(__LSBFIRST__)
-                    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
                     for (; _v; _pResult1 += 2) {
-                        if (_pResult1 > _pResultLast1) break;
+                        if (_pResult1 > _pResultLastShort) break;
                         _v += ((unsigned short *)_pResult1)[0];
                         ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
                         _v >>= 16;
@@ -4091,12 +4092,13 @@
                 _v >>= 16; /* now _v contains the carry*/
                 _pResult += 2;
                 if (_v) {
+                    unsigned char *_pResult1;
+
                     /* distribute carry - short-wise, then byte-wise */
                     _pResult1 = _pResult;
 #if defined(__LSBFIRST__)
-                    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
                     for (; _v; _pResult1 += 2) {
-                        if (_pResult1 > _pResultLast1) break;
+                        if (_pResult1 > _pResultLastShort) break;
                         _v += ((unsigned short *)_pResult1)[0];
                         ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
                         _v >>= 16;
@@ -4112,8 +4114,9 @@
             }
         }
 
-        /* possible odd highByte of f1 (or byteLoop, if not __LSBFIRST__) */
+        /* possible odd highByte of f1 (or byteLoop, if above is ever disabled) */
         for (; _p1 <= _p1Last; _p1++, _pResult0++) {
+            unsigned char *_pResult, *_p2;
             unsigned int byte1 = _p1[0];
 
             _pResult = _pResult0;
@@ -4139,12 +4142,13 @@
                 _v >>= 16; /* now _v contains the carry*/
                 _pResult += 2;
                 if (_v) {
+                    unsigned char *_pResult1;
+
                     /* distribute carry - short-wise, then byte-wise */
                     _pResult1 = _pResult;
 #if defined(__LSBFIRST__)
-                    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
                     for (_pResult1 = _pResult; _v; _pResult1 += 2) {
-                        if (_pResult1 > _pResultLast1) break;
+                        if (_pResult1 > _pResultLastShort) break;
                         _v += ((unsigned short *)_pResult1)[0];
                         ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
                         _v >>= 16;
@@ -4166,6 +4170,8 @@
                 _v >>= 8; /* now _v contains the carry*/
                 _pResult++;
                 if (_v) {
+                    unsigned char *_pResult1;
+
                     /* distribute carry */
                     for (_pResult1 = _pResult; _v; _pResult1++) {
                         _v += _pResult1[0];
@@ -5227,10 +5233,10 @@
 !LargeInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.213 2013-08-12 10:09:58 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.214 2013-12-02 18:10:35 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.213 2013-08-12 10:09:58 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.214 2013-12-02 18:10:35 cg Exp $'
 ! !