alpha large*large speedup
authorClaus Gittinger <cg@exept.de>
Wed, 26 May 1999 23:10:23 +0200
changeset 4231 5e9e9319a9de
parent 4230 e1cfaecf453c
child 4232 4c3f4c53f30e
alpha large*large speedup
LargeInt.st
LargeInteger.st
--- a/LargeInt.st	Wed May 26 22:22:08 1999 +0200
+++ b/LargeInt.st	Wed May 26 23:10:23 1999 +0200
@@ -2725,139 +2725,183 @@
      && __isByteArray(otherDigitByteArray)
      && __isByteArray(resultDigitByteArray)
      && __bothSmallInteger(len1, len2)) {
-	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 INT _v;
-	int _len1 = __intVal(len1);
-	int _len2 = __intVal(len2);
-
-	_p1Last = myBytes    + _len1 - 1;  /* the last byte */
-	_p2Last = otherBytes + _len2 - 1;  /* the last byte */
-	_pResult0 = resultBytes;
-
-	/*
-	 *        aaa...aaa      f1[0] * f2
-	 *       bbb...bbb       f1[1] * f2
-	 *      ccc...ccc        f1[2] * f2
-	 *     ...
-	 *    xxx...xxx          f1[high] * f2
-	 *
-	 * start short-wise
-	 * bounds: (16rFFFF * 16rFFFF) + 16rFFFF -> FFFF0000
-	 */
-	_p1 = myBytes;
+        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 INT _v;
+        int _len1 = __intVal(len1);
+        int _len2 = __intVal(len2);
+
+        _p1Last = myBytes    + _len1 - 1;  /* the last byte */
+        _p2Last = otherBytes + _len2 - 1;  /* the last byte */
+        _pResult0 = resultBytes;
+
+        /*
+         *        aaa...aaa      f1[0] * f2
+         *       bbb...bbb       f1[1] * f2
+         *      ccc...ccc        f1[2] * f2
+         *     ...
+         *    xxx...xxx          f1[high] * f2
+         *
+         * start short-wise
+         * bounds: (16rFFFF * 16rFFFF) + 16rFFFF -> FFFF0000
+         */
+        _p1 = myBytes;
+
+#if defined(alpha64)
+        /* loop over ints of f1 */
+        for (; _p1 < _p1Last-2; _p1 += 4, _pResult0 += 4) {
+            unsigned INT word1 = ((unsigned int *)_p1)[0];
+
+            _pResult = _pResult0;
+            _p2 = otherBytes;
+
+            /* loop over ints of f2 */
+            while (_p2 < (_p2Last-2)) {
+                _v = (word1 * ((unsigned int *)_p2)[0]) + ((unsigned int *)_pResult)[0];
+                ((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
+                _v >>= 32; /* now _v contains the carry*/
+                _pResult += 4;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2 += 4;
+            }
+
+            /* 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;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2++;
+            }
+        }
+#endif /* alpha64 */
 
 #if defined(__LSBFIRST) || defined(alpha) || defined(i386)
-	/* loop over shorts of f1 */
-	for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
-	    unsigned int short1 = ((unsigned short *)_p1)[0];
-
-	    _pResult = _pResult0;
-	    _p2 = otherBytes;
-
-	    /* loop over shorts of f2 */
-	    while (_p2 < _p2Last) {
-		_v = (short1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
-		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
-		_v >>= 16; /* now _v contains the carry*/
-		_pResult += 2;                
-		if (_v) {
-		    /* distribute carry */
-		    for (_pResult1 = _pResult; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2 += 2;
-	    }
-
-	    /* possible odd highByte of f2 */
-	    if (_p2 <= _p2Last) {
-		_v = (short1 * _p2[0]) + ((unsigned short *)_pResult)[0];
-		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
-		_v >>= 16; /* now _v contains the carry*/
-		_pResult += 2;                
-		if (_v) {
-		    /* distribute carry */
-		    for (_pResult1 = _pResult; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2++;
-	    }
-	}
+        /* loop over shorts of f1 */
+        for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
+            unsigned int short1 = ((unsigned short *)_p1)[0];
+
+            _pResult = _pResult0;
+            _p2 = otherBytes;
+
+            /* loop over shorts of f2 */
+            while (_p2 < _p2Last) {
+                _v = (short1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
+                ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+                _v >>= 16; /* now _v contains the carry*/
+                _pResult += 2;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2 += 2;
+            }
+
+            /* possible odd highByte of f2 */
+            if (_p2 <= _p2Last) {
+                _v = (short1 * _p2[0]) + ((unsigned short *)_pResult)[0];
+                ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+                _v >>= 16; /* now _v contains the carry*/
+                _pResult += 2;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2++;
+            }
+        }
 #endif /* LSBFIRST */
 
-	/* possible odd highByte of f1 (or byteLoop, if not LSBFIRST) */
-	for (; _p1 <= _p1Last; _p1++, _pResult0++) {
-	    unsigned int byte1 = _p1[0];
-
-	    _pResult = _pResult0;
-	    _p2 = otherBytes;
+        /* possible odd highByte of f1 (or byteLoop, if not LSBFIRST) */
+        for (; _p1 <= _p1Last; _p1++, _pResult0++) {
+            unsigned int byte1 = _p1[0];
+
+            _pResult = _pResult0;
+            _p2 = otherBytes;
 
 #if defined(__LSBFIRST) || defined(alpha) || defined(i386)
-	    /* loop over shorts of f2 */
-	    while (_p2 < _p2Last) {
-		_v = (byte1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
-		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
-		_v >>= 16; /* now _v contains the carry*/
-		_pResult += 2;                
-		if (_v) {
-		    /* distribute carry */
-		    for (_pResult1 = _pResult; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2 += 2;
-	    }
+            /* loop over shorts of f2 */
+            while (_p2 < _p2Last) {
+                _v = (byte1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
+                ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+                _v >>= 16; /* now _v contains the carry*/
+                _pResult += 2;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2 += 2;
+            }
 #endif /* __LSBFIRST */
 
-	    /* possible odd highByte of f2 (or byteLoop, if not LSBFIRST) */
-	    while (_p2 <= _p2Last) {
-		_v = (byte1 * _p2[0]) + _pResult[0];
-		_pResult[0] = _v /* & 0xFF */;
-		_v >>= 8; /* now _v contains the carry*/
-		_pResult++;                
-		if (_v) {
-		    /* distribute carry */
-		    for (_pResult1 = _pResult; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2++;
-	    }
-	}
-	ok = true;
+            /* possible odd highByte of f2 (or byteLoop, if not LSBFIRST) */
+            while (_p2 <= _p2Last) {
+                _v = (byte1 * _p2[0]) + _pResult[0];
+                _pResult[0] = _v /* & 0xFF */;
+                _v >>= 8; /* now _v contains the carry*/
+                _pResult++;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2++;
+            }
+        }
+        ok = true;
     }
 %}.
     ok ifFalse:[
-	1 to:len1 do:[:index1 |
-	    1 to:len2 do:[:index2 |
-		dstIndex := index1 + index2 - 1.
-		prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
-		prod := prod + (resultDigitByteArray basicAt:dstIndex).
-		resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
-		carry := prod bitShift:-8.
-		carry ~~ 0 ifTrue:[
-		    idx := dstIndex + 1.
-		    [carry ~~ 0] whileTrue:[
-			v := (resultDigitByteArray basicAt:idx) + carry.
-			resultDigitByteArray basicAt:idx put:(v bitAnd:255).
-			carry := v bitShift:-8.
-			idx := idx + 1
-		    ]
-		]
-	    ]
-	].
+        1 to:len1 do:[:index1 |
+            1 to:len2 do:[:index2 |
+                dstIndex := index1 + index2 - 1.
+                prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
+                prod := prod + (resultDigitByteArray basicAt:dstIndex).
+                resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
+                carry := prod bitShift:-8.
+                carry ~~ 0 ifTrue:[
+                    idx := dstIndex + 1.
+                    [carry ~~ 0] whileTrue:[
+                        v := (resultDigitByteArray basicAt:idx) + carry.
+                        resultDigitByteArray basicAt:idx put:(v bitAnd:255).
+                        carry := v bitShift:-8.
+                        idx := idx + 1
+                    ]
+                ]
+            ]
+        ].
     ].
     ^ result compressed
 !
@@ -3541,5 +3585,5 @@
 !LargeInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Attic/LargeInt.st,v 1.109 1999-05-26 20:22:08 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Attic/LargeInt.st,v 1.110 1999-05-26 21:10:23 cg Exp $'
 ! !
--- a/LargeInteger.st	Wed May 26 22:22:08 1999 +0200
+++ b/LargeInteger.st	Wed May 26 23:10:23 1999 +0200
@@ -2725,139 +2725,183 @@
      && __isByteArray(otherDigitByteArray)
      && __isByteArray(resultDigitByteArray)
      && __bothSmallInteger(len1, len2)) {
-	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 INT _v;
-	int _len1 = __intVal(len1);
-	int _len2 = __intVal(len2);
-
-	_p1Last = myBytes    + _len1 - 1;  /* the last byte */
-	_p2Last = otherBytes + _len2 - 1;  /* the last byte */
-	_pResult0 = resultBytes;
-
-	/*
-	 *        aaa...aaa      f1[0] * f2
-	 *       bbb...bbb       f1[1] * f2
-	 *      ccc...ccc        f1[2] * f2
-	 *     ...
-	 *    xxx...xxx          f1[high] * f2
-	 *
-	 * start short-wise
-	 * bounds: (16rFFFF * 16rFFFF) + 16rFFFF -> FFFF0000
-	 */
-	_p1 = myBytes;
+        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 INT _v;
+        int _len1 = __intVal(len1);
+        int _len2 = __intVal(len2);
+
+        _p1Last = myBytes    + _len1 - 1;  /* the last byte */
+        _p2Last = otherBytes + _len2 - 1;  /* the last byte */
+        _pResult0 = resultBytes;
+
+        /*
+         *        aaa...aaa      f1[0] * f2
+         *       bbb...bbb       f1[1] * f2
+         *      ccc...ccc        f1[2] * f2
+         *     ...
+         *    xxx...xxx          f1[high] * f2
+         *
+         * start short-wise
+         * bounds: (16rFFFF * 16rFFFF) + 16rFFFF -> FFFF0000
+         */
+        _p1 = myBytes;
+
+#if defined(alpha64)
+        /* loop over ints of f1 */
+        for (; _p1 < _p1Last-2; _p1 += 4, _pResult0 += 4) {
+            unsigned INT word1 = ((unsigned int *)_p1)[0];
+
+            _pResult = _pResult0;
+            _p2 = otherBytes;
+
+            /* loop over ints of f2 */
+            while (_p2 < (_p2Last-2)) {
+                _v = (word1 * ((unsigned int *)_p2)[0]) + ((unsigned int *)_pResult)[0];
+                ((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
+                _v >>= 32; /* now _v contains the carry*/
+                _pResult += 4;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2 += 4;
+            }
+
+            /* 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;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2++;
+            }
+        }
+#endif /* alpha64 */
 
 #if defined(__LSBFIRST) || defined(alpha) || defined(i386)
-	/* loop over shorts of f1 */
-	for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
-	    unsigned int short1 = ((unsigned short *)_p1)[0];
-
-	    _pResult = _pResult0;
-	    _p2 = otherBytes;
-
-	    /* loop over shorts of f2 */
-	    while (_p2 < _p2Last) {
-		_v = (short1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
-		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
-		_v >>= 16; /* now _v contains the carry*/
-		_pResult += 2;                
-		if (_v) {
-		    /* distribute carry */
-		    for (_pResult1 = _pResult; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2 += 2;
-	    }
-
-	    /* possible odd highByte of f2 */
-	    if (_p2 <= _p2Last) {
-		_v = (short1 * _p2[0]) + ((unsigned short *)_pResult)[0];
-		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
-		_v >>= 16; /* now _v contains the carry*/
-		_pResult += 2;                
-		if (_v) {
-		    /* distribute carry */
-		    for (_pResult1 = _pResult; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2++;
-	    }
-	}
+        /* loop over shorts of f1 */
+        for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
+            unsigned int short1 = ((unsigned short *)_p1)[0];
+
+            _pResult = _pResult0;
+            _p2 = otherBytes;
+
+            /* loop over shorts of f2 */
+            while (_p2 < _p2Last) {
+                _v = (short1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
+                ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+                _v >>= 16; /* now _v contains the carry*/
+                _pResult += 2;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2 += 2;
+            }
+
+            /* possible odd highByte of f2 */
+            if (_p2 <= _p2Last) {
+                _v = (short1 * _p2[0]) + ((unsigned short *)_pResult)[0];
+                ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+                _v >>= 16; /* now _v contains the carry*/
+                _pResult += 2;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2++;
+            }
+        }
 #endif /* LSBFIRST */
 
-	/* possible odd highByte of f1 (or byteLoop, if not LSBFIRST) */
-	for (; _p1 <= _p1Last; _p1++, _pResult0++) {
-	    unsigned int byte1 = _p1[0];
-
-	    _pResult = _pResult0;
-	    _p2 = otherBytes;
+        /* possible odd highByte of f1 (or byteLoop, if not LSBFIRST) */
+        for (; _p1 <= _p1Last; _p1++, _pResult0++) {
+            unsigned int byte1 = _p1[0];
+
+            _pResult = _pResult0;
+            _p2 = otherBytes;
 
 #if defined(__LSBFIRST) || defined(alpha) || defined(i386)
-	    /* loop over shorts of f2 */
-	    while (_p2 < _p2Last) {
-		_v = (byte1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
-		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
-		_v >>= 16; /* now _v contains the carry*/
-		_pResult += 2;                
-		if (_v) {
-		    /* distribute carry */
-		    for (_pResult1 = _pResult; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2 += 2;
-	    }
+            /* loop over shorts of f2 */
+            while (_p2 < _p2Last) {
+                _v = (byte1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
+                ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+                _v >>= 16; /* now _v contains the carry*/
+                _pResult += 2;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2 += 2;
+            }
 #endif /* __LSBFIRST */
 
-	    /* possible odd highByte of f2 (or byteLoop, if not LSBFIRST) */
-	    while (_p2 <= _p2Last) {
-		_v = (byte1 * _p2[0]) + _pResult[0];
-		_pResult[0] = _v /* & 0xFF */;
-		_v >>= 8; /* now _v contains the carry*/
-		_pResult++;                
-		if (_v) {
-		    /* distribute carry */
-		    for (_pResult1 = _pResult; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2++;
-	    }
-	}
-	ok = true;
+            /* possible odd highByte of f2 (or byteLoop, if not LSBFIRST) */
+            while (_p2 <= _p2Last) {
+                _v = (byte1 * _p2[0]) + _pResult[0];
+                _pResult[0] = _v /* & 0xFF */;
+                _v >>= 8; /* now _v contains the carry*/
+                _pResult++;                
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2++;
+            }
+        }
+        ok = true;
     }
 %}.
     ok ifFalse:[
-	1 to:len1 do:[:index1 |
-	    1 to:len2 do:[:index2 |
-		dstIndex := index1 + index2 - 1.
-		prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
-		prod := prod + (resultDigitByteArray basicAt:dstIndex).
-		resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
-		carry := prod bitShift:-8.
-		carry ~~ 0 ifTrue:[
-		    idx := dstIndex + 1.
-		    [carry ~~ 0] whileTrue:[
-			v := (resultDigitByteArray basicAt:idx) + carry.
-			resultDigitByteArray basicAt:idx put:(v bitAnd:255).
-			carry := v bitShift:-8.
-			idx := idx + 1
-		    ]
-		]
-	    ]
-	].
+        1 to:len1 do:[:index1 |
+            1 to:len2 do:[:index2 |
+                dstIndex := index1 + index2 - 1.
+                prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
+                prod := prod + (resultDigitByteArray basicAt:dstIndex).
+                resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
+                carry := prod bitShift:-8.
+                carry ~~ 0 ifTrue:[
+                    idx := dstIndex + 1.
+                    [carry ~~ 0] whileTrue:[
+                        v := (resultDigitByteArray basicAt:idx) + carry.
+                        resultDigitByteArray basicAt:idx put:(v bitAnd:255).
+                        carry := v bitShift:-8.
+                        idx := idx + 1
+                    ]
+                ]
+            ]
+        ].
     ].
     ^ result compressed
 !
@@ -3541,5 +3585,5 @@
 !LargeInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.109 1999-05-26 20:22:08 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.110 1999-05-26 21:10:23 cg Exp $'
 ! !