LargeInteger.st
changeset 12121 38c8767f98f2
parent 11959 1ff0e6f908d9
child 12746 10866527a1ab
--- a/LargeInteger.st	Sun Oct 04 22:08:00 2009 +0200
+++ b/LargeInteger.st	Sun Oct 04 23:07:18 2009 +0200
@@ -872,128 +872,139 @@
 
 %{  /* NOCONTEXT */
     if (__isSmallInteger(anInteger)) {
-	INT v2 = __intVal(anInteger);
-	INT v1;
+        INT v2 = __intVal(anInteger);
+        INT v1;
 #if defined(__LSBFIRST__)
-	v1 = *(INT *)(__byteArrayVal(__INST(digitByteArray)));
+        v1 = *(INT *)(__byteArrayVal(__INST(digitByteArray)));
 #else
-	unsigned char *digits = (unsigned char *)(__byteArrayVal(__INST(digitByteArray)));
-
-	v1 = digits[0] & 0xFF;
-	v1 = v1 | ((digits[1] & 0xFF)<<8);
-	v1 = v1 | ((digits[2] & 0xFF)<<16);
-	v1 = v1 | ((digits[3] & 0xFF)<<24);
+        unsigned char *digits = (unsigned char *)(__byteArrayVal(__INST(digitByteArray)));
+
+        v1 = digits[0] & 0xFF;
+        v1 = v1 | ((digits[1] & 0xFF)<<8);
+        v1 = v1 | ((digits[2] & 0xFF)<<16);
+        v1 = v1 | ((digits[3] & 0xFF)<<24);
 # if (__POINTER_SIZE__ == 8)
-	v1 = v1 | ((digits[4] & 0xFF)<<32);
-	v1 = v1 | ((digits[5] & 0xFF)<<40);
-	v1 = v1 | ((digits[6] & 0xFF)<<48);
-	v1 = v1 | ((digits[7] & 0xFF)<<56);
+        v1 = v1 | ((digits[4] & 0xFF)<<32);
+        v1 = v1 | ((digits[5] & 0xFF)<<40);
+        v1 = v1 | ((digits[6] & 0xFF)<<48);
+        v1 = v1 | ((digits[7] & 0xFF)<<56);
  #endif
 #endif
-	RETURN ( __mkSmallInteger(v1 & v2) );
+        RETURN ( __mkSmallInteger(v1 & v2) );
     }
 
     if (__isLargeInteger(anInteger)) {
-	OBJ _myDigitByteArray = __INST(digitByteArray);
-	OBJ _otherDigitByteArray = __LargeIntegerInstPtr(anInteger)->l_digits;
-
-	if (__isByteArray(_myDigitByteArray)
-	 && __isByteArray(_otherDigitByteArray)) {
-	    unsigned char *pDigits1, *pDigits2;
-	    int size1, size2, minSize;
-	    union {
-		double d;                    // force align
-		unsigned char chars[2048+8];
-	    } buffer;
-	    unsigned char *pRslt;
-	    OBJ newDigits, newLarge;
-
-	    pDigits1 = (unsigned char *)(__byteArrayVal(_myDigitByteArray));
-	    pDigits2 = (unsigned char *)(__byteArrayVal(_otherDigitByteArray));
-	    pRslt = (void *)(buffer.chars);
-
-	    size1 = __byteArraySize(_myDigitByteArray);
-	    size2 = __byteArraySize(_otherDigitByteArray);
-	    minSize = (size1 < size2) ? size1 : size2;
-	    if (minSize <= sizeof(buffer.chars)) {
-		int n = minSize;
-
-	    /* not worth it - but a nice try and first testbed for mmx... */
+        OBJ _myDigitByteArray = __INST(digitByteArray);
+        OBJ _otherDigitByteArray = __LargeIntegerInstPtr(anInteger)->l_digits;
+
+        if (__isByteArray(_myDigitByteArray)
+         && __isByteArray(_otherDigitByteArray)) {
+            unsigned char *pDigits1, *pDigits2;
+            int size1, size2, minSize;
+            union {
+                double d;                    // force align
+                unsigned char chars[2048+8];
+            } buffer;
+            unsigned char *pRslt;
+            OBJ newDigits, newLarge;
+
+            pDigits1 = (unsigned char *)(__byteArrayVal(_myDigitByteArray));
+            pDigits2 = (unsigned char *)(__byteArrayVal(_otherDigitByteArray));
+            pRslt = (void *)(buffer.chars);
+
+            size1 = __byteArraySize(_myDigitByteArray);
+            size2 = __byteArraySize(_otherDigitByteArray);
+            minSize = (size1 < size2) ? size1 : size2;
+            if (minSize <= sizeof(buffer.chars)) {
+                int n = minSize;
+
+            /* not worth it - but a nice try and first testbed for mmx... */
 #define x__USE_MMX__
 #ifdef __USE_MMX__
 #ifdef __VISUALC__
-		if (((INT)pRslt & 7) == 0) {    // 8-byte aligned
-		    if (((INT)pDigits1 & 7) == ((INT)pDigits2 & 7)) {   // same align
-			while (((INT)pDigits1 & 7) && (n >= sizeof(int))) {
-			    ((int *)pRslt)[0] = ((int *)pDigits1)[0] & ((int *)pDigits2)[0];
-			    pRslt += sizeof(int);
-			    pDigits1 += sizeof(int);
-			    pDigits2 += sizeof(int);
-			    pDigits2 += sizeof(int);
-			    n -= sizeof(int);
-			}
-			for (; n >= 8; n -= 8) {
-			    __asm {
-				mov eax, pDigits1
-				movq mm0, [eax]
-				mov eax, pDigits2
-				movq mm1, [eax]
-				pand mm0, mm1
-				mov eax, pRslt
-				movq [eax], mm0
-			    }
-			    pDigits1 += 8;
-			    pDigits2 += 8;
-			    pRslt += 8;
-			}
-			__asm {
-			    emms ; switch back to FPU state.
-			}
-		    }
-		}
+                if (((INT)pRslt & 7) == 0) {    // 8-byte aligned
+                    if (((INT)pDigits1 & 7) == ((INT)pDigits2 & 7)) {   // same align
+                        while (((INT)pDigits1 & 7) && (n >= sizeof(int))) {
+                            ((int *)pRslt)[0] = ((int *)pDigits1)[0] & ((int *)pDigits2)[0];
+                            pRslt += sizeof(int);
+                            pDigits1 += sizeof(int);
+                            pDigits2 += sizeof(int);
+                            pDigits2 += sizeof(int);
+                            n -= sizeof(int);
+                        }
+                        for (; n >= 8; n -= 8) {
+                            __asm {
+                                mov eax, pDigits1
+                                movq mm0, [eax]
+                                mov eax, pDigits2
+                                movq mm1, [eax]
+                                pand mm0, mm1
+                                mov eax, pRslt
+                                movq [eax], mm0
+                            }
+                            pDigits1 += 8;
+                            pDigits2 += 8;
+                            pRslt += 8;
+                        }
+                        __asm {
+                            emms ; switch back to FPU state.
+                        }
+                    }
+                }
 #endif /* __VISUALC__ */
 #endif /* __USE_MMX__ */
 
-		for (; n >= sizeof(INT)*4; n -= sizeof(INT)*4) {
-		    ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0];
-		    ((INT *)pRslt)[1] = ((INT *)pDigits1)[1] & ((INT *)pDigits2)[1];
-		    ((INT *)pRslt)[2] = ((INT *)pDigits1)[2] & ((INT *)pDigits2)[2];
-		    ((INT *)pRslt)[3] = ((INT *)pDigits1)[3] & ((INT *)pDigits2)[3];
-		    pRslt += sizeof(INT)*4;
-		    pDigits1 += sizeof(INT)*4;
-		    pDigits2 += sizeof(INT)*4;
-		}
-		for (; n >= sizeof(INT); n -= sizeof(INT)) {
-		    ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0];
-		    pRslt += sizeof(INT);
-		    pDigits1 += sizeof(INT);
-		    pDigits2 += sizeof(INT);
-		}
-		for (; n > 0; n--) {
-		    *pRslt = *pDigits1 & *pDigits2;
-		    pRslt++;
-		    pDigits1++;
-		    pDigits2++;
-		}
-		// normalize
-		while ((pRslt[-1]==0) && (pRslt > buffer.chars)) {
-		    pRslt--;
-		}
-		// allocate result
-		newDigits = __MKBYTEARRAY(buffer.chars, (pRslt-buffer.chars));
-		if (newDigits) {
-		    __PROTECT__(newDigits);
-		    newLarge = __STX___new(sizeof(struct __LargeInteger));
-		    __UNPROTECT__(newDigits);
-		    if (newLarge) {
-			__InstPtr(newLarge)->o_class = LargeInteger; __STORE(newLarge, LargeInteger);
-			__LargeIntegerInstPtr(newLarge)->l_digits = newDigits; __STORE(newLarge, newDigits);
-			__LargeIntegerInstPtr(newLarge)->l_sign = __MKSMALLINT(1);
-			RETURN (newLarge);
-		    }
-		}
-	    }
-	}
+                for (; n >= sizeof(INT)*4; n -= sizeof(INT)*4) {
+                    ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0];
+                    ((INT *)pRslt)[1] = ((INT *)pDigits1)[1] & ((INT *)pDigits2)[1];
+                    ((INT *)pRslt)[2] = ((INT *)pDigits1)[2] & ((INT *)pDigits2)[2];
+                    ((INT *)pRslt)[3] = ((INT *)pDigits1)[3] & ((INT *)pDigits2)[3];
+                    pRslt += sizeof(INT)*4;
+                    pDigits1 += sizeof(INT)*4;
+                    pDigits2 += sizeof(INT)*4;
+                }
+                for (; n >= sizeof(INT); n -= sizeof(INT)) {
+                    ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0];
+                    pRslt += sizeof(INT);
+                    pDigits1 += sizeof(INT);
+                    pDigits2 += sizeof(INT);
+                }
+                for (; n > 0; n--) {
+                    *pRslt = *pDigits1 & *pDigits2;
+                    pRslt++;
+                    pDigits1++;
+                    pDigits2++;
+                }
+                // normalize
+                while ((pRslt[-1]==0) && (pRslt > buffer.chars)) {
+                    pRslt--;
+                }
+
+                // allocate result
+                n = pRslt-buffer.chars;
+                if (n <= sizeof(INT)) {
+                    INT val = 0;
+
+                    // make it a smallInteger / 32bitInteger
+                    while (n > 0) {
+                        val = (val << 8) + buffer.chars[--n];
+                    }
+                    RETURN (__MKUINT(val));
+                }
+                newDigits = __MKBYTEARRAY(buffer.chars, n);
+                if (newDigits) {
+                    __PROTECT__(newDigits);
+                    newLarge = __STX___new(sizeof(struct __LargeInteger));
+                    __UNPROTECT__(newDigits);
+                    if (newLarge) {
+                        __InstPtr(newLarge)->o_class = LargeInteger; __STORE(newLarge, LargeInteger);
+                        __LargeIntegerInstPtr(newLarge)->l_digits = newDigits; __STORE(newLarge, newDigits);
+                        __LargeIntegerInstPtr(newLarge)->l_sign = __MKSMALLINT(1);
+                        RETURN (newLarge);
+                    }
+                }
+            }
+        }
     }
 %}.
     ^ super bitAnd:anInteger
@@ -4942,5 +4953,9 @@
 !LargeInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.196 2009-09-16 22:26:31 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.197 2009-10-04 21:07:18 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.197 2009-10-04 21:07:18 cg Exp $'
 ! !