diff -r a6a3e7a673a4 -r 38c8767f98f2 LargeInteger.st --- 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 $' ! !