--- 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 $'
! !