tuned some doubleWordAt methods;
authorClaus Gittinger <cg@exept.de>
Wed, 03 Mar 1999 16:11:12 +0100
changeset 4019 c9284ca27a4a
parent 4018 b4bb0f43d6a7
child 4020 e73a3c919ac0
tuned some doubleWordAt methods; eliminated duplicate code
ByteArray.st
UIBytes.st
UninterpretedBytes.st
--- a/ByteArray.st	Mon Mar 01 23:51:44 1999 +0100
+++ b/ByteArray.st	Wed Mar 03 16:11:12 1999 +0100
@@ -414,124 +414,6 @@
     ^ super basicAt:index put:value
 !
 
-doubleWordAt:index
-    "return the 4-bytes starting at index as an (unsigned) Integer.
-     The value is retrieved in the machines natural byte order.
-     Q: should it return a signed value ? (see ByteArray>>signedDoubleWordAt:)"
-
-%{  /* NOCONTEXT */
-
-    REGISTER int indx;
-    int nIndex;
-    union {
-	unsigned char u_char[4];
-	unsigned int u_uint;
-    } val;
-    OBJ cls;
-    unsigned char *byteP;
-
-    if (__isSmallInteger(index)) {
-	indx = __intVal(index);
-	if (indx > 0) {
-	    if ((cls = __qClass(self)) != @global(ByteArray))
-		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
-	    nIndex = __byteArraySize(self);
-	    if ((indx+3) <= nIndex) {
-		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
-#if defined(i386) || defined(UNALIGNED_FETCH_OK)
-		val.u_uint = ((unsigned int *)(byteP))[0];
-#else
-		if (((unsigned INT)byteP & 3) == 0) {
-		    /* aligned fetch */
-		    val.u_uint = ((unsigned int *)(byteP))[0];
-		} else {
-		    /* unaligned fetch */
-		    val.u_char[0] = byteP[0];
-		    val.u_char[1] = byteP[1];
-		    val.u_char[2] = byteP[2];
-		    val.u_char[3] = byteP[3];
-		}
-#endif
-		if ((val.u_uint >= 0) && (val.u_uint <= _MAX_INT)) {
-		    RETURN ( __MKSMALLINT(val.u_uint) );
-		}
-		RETURN ( __MKULARGEINT(val.u_uint) );
-	    }
-	}
-    }
-%}.
-    ^ SubscriptOutOfBoundsSignal raise.
-
-    "
-     |b|
-
-     b := ByteArray withAll:#(1 2 3 4).
-     (b doubleWordAt:1) printStringRadix:16   
-    "
-!
-
-doubleWordAt:index MSB:msb
-    "return the 4-bytes starting at index as an (unsigned) Integer.
-     The value is retrieved MSB-first, if the msb-arg is true;
-     LSB-first otherwise.
-     Q: should it return a signed value ? (see ByteArray>>signedDoubleWordAt:)"
-
-%{  /* NOCONTEXT */
-
-    REGISTER int indx;
-    int nIndex;
-    int val;
-    OBJ cls;
-    unsigned char *byteP;
-
-    if (__isSmallInteger(index)) {
-	indx = __intVal(index);
-	if (indx > 0) {
-	    if ((cls = __qClass(self)) != @global(ByteArray))
-		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
-	    nIndex = __byteArraySize(self);
-	    if ((indx+3) <= nIndex) {
-		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
-		if (msb == true) {
-		    /*
-		     * most significant byte first (i.e sparc order)
-		     */
-		    val = byteP[0];
-		    val = (val << 8) + byteP[1];
-		    val = (val << 8) + byteP[2];
-		    val = (val << 8) + byteP[3];
-		} else {
-		    /*
-		     * least significant byte first (i.e i386/alpha order)
-		     */
-#if  defined(i386) /* actually: LSBFIRST && UNALIGNED_FETCH_OK*/
-		    val = ((int *)byteP)[0];
-#else
-		    val = byteP[3];
-		    val = (val << 8) + byteP[2];
-		    val = (val << 8) + byteP[1];
-		    val = (val << 8) + byteP[0];
-#endif
-		}
-		if ((val >= 0) && (val <= _MAX_INT)) {
-		    RETURN ( __MKSMALLINT(val) );
-		}
-		RETURN ( __MKULARGEINT(val) );
-	    }
-	}
-    }
-%}.
-    ^ SubscriptOutOfBoundsSignal raise.
-
-    "
-     |b|
-
-     b := ByteArray withAll:#(1 2 3 4).
-     (b doubleWordAt:1 MSB:true) printStringRadix:16.   
-     (b doubleWordAt:1 MSB:false) printStringRadix:16   
-    "
-!
-
 doubleWordAt:index put:value
     "set the 4-bytes starting at index from the (unsigned) Integer value.
      The value should be in the range 0 to 16rFFFFFFFF
@@ -2167,5 +2049,5 @@
 !ByteArray class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.101 1998-07-28 19:46:27 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.102 1999-03-03 15:11:12 cg Exp $'
 ! !
--- a/UIBytes.st	Mon Mar 01 23:51:44 1999 +0100
+++ b/UIBytes.st	Wed Mar 03 16:11:12 1999 +0100
@@ -99,39 +99,6 @@
 "
 ! !
 
-!UninterpretedBytes class methodsFor:'initialization'!
-
-checkByteOrder
-    "initialize our current byteOrder.
-     Must be called at system init time and on snapshot restart"
-
-    IsBigEndian := self isBigEndian.
-
-    "Created: / 5.3.1998 / 14:51:41 / stefan"
-!
-
-initialize
-    "get the byte order"
-
-    self checkByteOrder.
-
-    "want to be informed when returning from snapshot"
-    ObjectMemory dependents addDependent:self
-
-    "Created: / 5.3.1998 / 14:46:31 / stefan"
-    "Modified: / 5.3.1998 / 14:53:28 / stefan"
-!
-
-update:something with:aParameter from:changedObject
-    "handle image restarts and reget the byte order"
-
-    (something == #returnFromSnapshot) ifTrue:[
-        self checkByteOrder.
-    ]
-
-    "Created: / 5.3.1998 / 14:55:13 / stefan"
-! !
-
 !UninterpretedBytes class methodsFor:'instance creation'!
 
 from:aCollection
@@ -146,7 +113,10 @@
 isBigEndian
     "return true, if words/shorts store the most-significant
      byte first (MSB), false if least-sign.-first (LSB). 
-     I.e. false for vax, intel; true for m68k, sun."
+     I.e. false for vax, intel; true for m68k, sun.
+
+     Notice: UninterpretedBytes isBigEndian
+             this is inlined both by stc and the jit compiler"
 
 %{  /* NOCONTEXT */
 
@@ -164,8 +134,8 @@
      *    constant for systems where this is known.
      */
     union {
-	unsigned int   u_l;
-	char           u_c[sizeof(int)];
+        unsigned int   u_l;
+        char           u_c[sizeof(int)];
     } u;
 
     u.u_l = 0x87654321;
@@ -634,7 +604,7 @@
 
     |w|
 
-    w := self unsignedLongLongAt:index bigEndian:IsBigEndian.
+    w := self unsignedLongLongAt:index bigEndian:(UninterpretedBytes isBigEndian).
     (w > (16r7FFFFFFFFFFFFFFF)) ifTrue:[
         ^ w - (16r10000000000000000)
     ].
@@ -717,15 +687,15 @@
 
     l := LargeInteger basicNew numberOfDigits:8.
     msb ifTrue:[
-	bIdx := index + 7.
-	delta := -1
+        bIdx := index + 7.
+        delta := -1
     ] ifFalse:[
-	bIdx := index.
-	delta := 1
+        bIdx := index.
+        delta := 1
     ].
     1 to:8 do:[:i |
-	l digitAt:i put:(self basicAt:bIdx).
-	bIdx := bIdx + delta
+        l digitAt:i put:(self basicAt:bIdx).
+        bIdx := bIdx + delta
     ].
     ^ l compressed
 
@@ -813,7 +783,7 @@
      The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
      The value is stored in natural byte order."
 
-    ^ self unsignedLongLongAt:index put:anInteger bigEndian:IsBigEndian
+    ^ self unsignedLongLongAt:index put:anInteger bigEndian:(UninterpretedBytes isBigEndian)
 
     "Created: / 5.3.1998 / 14:44:00 / stefan"
     "Modified: / 5.3.1998 / 15:02:32 / stefan"
@@ -876,23 +846,44 @@
         __fetchBytePointerAndSize__(self, &cp, &sz);
         if (cp) {
             unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
+            int iVal;
 
             if ((idx+(sizeof(int)-1)) < sz) {
                 cp += idx;
-                /*
-                 * aligned
+
+#if defined(i386) || defined(UNALIGNED_FETCH_OK)
+                /* aligned or not - we dont care
+                 * (i386 can fetch unaligned)
                  */
+                iVal = ((int *)cp)[0];
+#else
                 if (((INT)cp & (sizeof(int)-1)) == 0) {
-                    int iVal = ((int *)cp)[0];
-
-                    RETURN (__MKUINT(iVal));
+                    /*
+                     * aligned
+                     */
+                    iVal = ((int *)cp)[0];
+                } else {
+                    union {
+                        char c[4];
+                        int  i;
+                    } u;
+                    u.c[0] = cp[0];
+                    u.c[1] = cp[1];
+                    u.c[2] = cp[2];
+                    u.c[3] = cp[3];
+                    iVal = u.i;
                 }
+#endif
+                if ((iVal >= 0) && (iVal <= _MAX_INT)) {
+                    RETURN ( __MKSMALLINT(iVal) );
+                }
+                RETURN ( __MKULARGEINT(iVal) );
             }
         }
     }
 %}.
 
-    ^ self doubleWordAt:index MSB:IsBigEndian
+    ^ self doubleWordAt:index MSB:(UninterpretedBytes isBigEndian)
 
     "
      |b|
@@ -912,41 +903,102 @@
      Subclasses may redefine this for better performance."
 
     |val 
-     ival "{ XXClass: SmallInteger }"
+     ival "{ Class: SmallInteger }"
+     t    "{ Class: SmallInteger }"
      i    "{ Class: SmallInteger }"
      b1   "{ Class: SmallInteger }"
      b2   "{ Class: SmallInteger }"
      b3   "{ Class: SmallInteger }"
      b4   "{ Class: SmallInteger }"|
 
+%{
+    /*
+     * handle the most common cases fast ...
+     */
+    if (__isSmallInteger(index)) {
+        unsigned char *cp;
+        int sz;
+
+        __fetchBytePointerAndSize__(self, &cp, &sz);
+        if (cp) {
+            unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
+            int iVal;
+
+            if ((idx+(sizeof(int)-1)) < sz) {
+                cp += idx;
+
+                if (msb == true) {
+#ifdef __MSBFIRST
+                    if (((INT)cp & (sizeof(int)-1))== 0) {
+                        /*
+                         * aligned
+                         */
+                        iVal = ((int *)cp)[0];
+                    } else
+#endif
+                    {
+                        iVal = cp[0];
+                        iVal = (iVal << 8) | cp[1];
+                        iVal = (iVal << 8) | cp[2];
+                        iVal = (iVal << 8) | cp[3];
+                    }
+                } else {
+#ifdef i386
+                    /*
+                     * aligned or not - we dont care
+                     * (i386 can fetch unaligned)
+                     */
+                    iVal = ((int *)cp)[0];
+#else
+# ifdef __LSBFIRST
+                    if (((INT)cp & (sizeof(int)-1))== 0) {
+                        /*
+                         * aligned
+                         */
+                        iVal = ((int *)cp)[0];
+                    } else
+# endif
+                    {
+                        iVal = cp[3];
+                        iVal = (iVal << 8) | cp[2];
+                        iVal = (iVal << 8) | cp[1];
+                        iVal = (iVal << 8) | cp[0];
+                    }
+#endif
+                }
+                RETURN (__MKUINT(iVal));
+            }
+        }
+    }
+%}.
+
+    "/ fallBack code - non ByteArray-like receiver
+    "/ or funny index
+
     i := index.
     b1 := self at:i.
     b2 := self at:(i+1).
     b3 := self at:(i+2).
     b4 := self at:(i+3).
 
-    msb ifTrue:[
-        ival := b1.
-        ival := (ival bitShift:8) + b2.
-        ival := (ival bitShift:8) + b3.
-        val := (ival bitShift:8) + b4.
-    ] ifFalse:[
-        ival := b4.
-        ival := (ival bitShift:8) + b3.
-        ival := (ival bitShift:8) + b2.
-        val := (ival bitShift:8) + b1.
+    msb ifFalse:[
+        t := b4. b4 := b1. b1 := t.
+        t := b3. b3 := b2. b2 := t.
     ].
+    ival := b1.
+    ival := (ival bitShift:8) + b2.
+    ival := (ival bitShift:8) + b3.
+    val := (ival bitShift:8) + b4.
     ^ val
 
     "
      |b|
 
      b := ByteArray withAll:#(1 2 3 4).
-     (b doubleWordAt:1 MSB:true) printStringRadix:16.   
-     (b doubleWordAt:1 MSB:false) printStringRadix:16   
+     (b doubleWordAt:1 MSB:true) printStringRadix:16.       
+     (b doubleWordAt:1 MSB:false) printStringRadix:16        
     "
 
-    "Modified: / 21.1.1998 / 17:42:30 / cg"
 !
 
 doubleWordAt:index put:value
@@ -957,7 +1009,7 @@
      The value is stored in the machines natural byte order.
      Subclasses may redefine this for better performance."
 
-    ^ self doubleWordAt:index put:value MSB:IsBigEndian
+    ^ self doubleWordAt:index put:value MSB:(UninterpretedBytes isBigEndian)
 
     "
      |b|
@@ -1015,7 +1067,7 @@
      accessing the memory as an array of doubleWord entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self doubleWordAtDoubleWordIndex:index MSB:IsBigEndian
+    ^ self doubleWordAtDoubleWordIndex:index MSB:(UninterpretedBytes isBigEndian)
 
     "Created: / 21.1.1998 / 17:43:53 / cg"
     "Modified: / 5.3.1998 / 14:58:06 / stefan"
@@ -1040,7 +1092,7 @@
      accessing the memory as an array of doubleWord entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self doubleWordAtDoubleWordIndex:index put:value MSB:IsBigEndian
+    ^ self doubleWordAtDoubleWordIndex:index put:value MSB:(UninterpretedBytes isBigEndian)
 
     "Created: / 21.1.1998 / 17:44:13 / cg"
     "Modified: / 5.3.1998 / 14:58:19 / stefan"
@@ -1319,9 +1371,10 @@
     "return the 4-bytes starting at index as an (unsigned) Integer.
      The index is a smalltalk index (i.e. 1-based).
      The value is retrieved in the machines natural byte order.
-     Subclasses may redefine this for better performance."
+     Subclasses may redefine this for better performance.
+     Same as doubleWordAt: for protocol completeness"
 
-    ^ self unsignedLongAt:index bigEndian:IsBigEndian
+    ^ self doubleWordAt:index
 
     "
      |b|
@@ -1339,34 +1392,10 @@
      The index is a smalltalk index (i.e. 1-based).
      The value is retrieved MSB-first, if the msb-arg is true;
      LSB-first otherwise.
-     Subclasses may redefine this for better performance."
-
-    |val 
-     ival "{ Class: SmallInteger }"
-     i    "{ Class: SmallInteger }"
-     b1   "{ Class: SmallInteger }"
-     b2   "{ Class: SmallInteger }"
-     b3   "{ Class: SmallInteger }"
-     b4   "{ Class: SmallInteger }"|
+     Subclasses may redefine this for better performance.
+     Same as doubleWordAt:MSB: for protocol completeness"
 
-    i := index.
-    b1 := self at:i.
-    b2 := self at:(i+1).
-    b3 := self at:(i+2).
-    b4 := self at:(i+3).
-
-    msb ifTrue:[
-        ival := b1.
-        ival := (ival bitShift:8) + b2.
-        ival := (ival bitShift:8) + b3.
-        val := (ival * 256) + b4.
-    ] ifFalse:[
-        ival := b4.
-        ival := (ival bitShift:8) + b3.
-        ival := (ival bitShift:8) + b2.
-        val := (ival * 256) + b1.
-    ].
-    ^ val
+    ^ self doubleWordAt:index MSB:msb
 
     "
      |b|
@@ -1386,9 +1415,10 @@
      The value should be in the range 0 to 16rFFFFFFFF
      (for negative values, the stored value is not defined).
      The value is stored in the machines natural byte order.
-     Subclasses may redefine this for better performance."
+     Subclasses may redefine this for better performance.
+     Same as doubleWordAt:put: for protocol completeness"
 
-    ^ self unsignedLongAt:index put:value bigEndian:IsBigEndian
+    ^ self doubleWordAt:index put:value
 
     "
      |b|
@@ -1406,27 +1436,10 @@
      The index is a smalltalk index (i.e. 1-based).
      The value must be in the range 0 to 16rFFFFFFFF.
      The value is stored MSB-first if msb is true; LSB-first otherwise.
-     Subclasses may redefine this for better performance."
-
-    |i "{ Class: SmallInteger }" |
-
-    ((aNumber < 0) or:[aNumber > 16rFFFFFFFF]) ifTrue:[
-        ^ self elementBoundsError
-    ].
+     Subclasses may redefine this for better performance.
+     Same as doubleWordAt:put:MSB: for protocol completeness"
 
-    i := index.
-    msb ifTrue:[
-        self at:i     put:(aNumber digitAt:4).
-        self at:(i+1) put:(aNumber digitAt:3).
-        self at:(i+2) put:(aNumber digitAt:2).
-        self at:(i+3) put:(aNumber digitAt:1).
-    ] ifFalse:[
-        self at:i     put:(aNumber digitAt:1).
-        self at:(i+1) put:(aNumber digitAt:2).
-        self at:(i+2) put:(aNumber digitAt:3).
-        self at:(i+3) put:(aNumber digitAt:4).
-    ].
-    ^ aNumber
+    ^ self doubleWordAt:index put:aNumber MSB:msb
 
     "
      |b|
@@ -1622,7 +1635,7 @@
      This is the ST80 equivalent of #wordAt:"
 
 
-    ^ self unsignedShortAt:index bigEndian:IsBigEndian
+    ^ self unsignedShortAt:index bigEndian:(UninterpretedBytes isBigEndian)
 
     "Created: / 5.3.1998 / 11:38:25 / stefan"
     "Modified: / 5.3.1998 / 14:59:25 / stefan"
@@ -1654,7 +1667,7 @@
      The stored value must be in the range 0 .. 16rFFFF. 
      The value is stored in the machines natural byteorder."
 
-    ^ self unsignedShortAt:index put:value bigEndian:IsBigEndian
+    ^ self unsignedShortAt:index put:value bigEndian:(UninterpretedBytes isBigEndian)
 
     "
      |b|
@@ -1713,7 +1726,7 @@
      The value is retrieved in the machines natural byte order
      Subclasses may redefine this for better performance."
 
-    ^ self wordAt:index MSB:IsBigEndian
+    ^ self wordAt:index MSB:(UninterpretedBytes isBigEndian)
 
     "Modified: / 5.3.1998 / 14:59:51 / stefan"
 !
@@ -1745,7 +1758,7 @@
      The value is stored in the machines natural byteorder.
      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
 
-    ^ self wordAt:index put:value MSB:IsBigEndian
+    ^ self wordAt:index put:value MSB:(UninterpretedBytes isBigEndian)
 
     "
      |b|
@@ -1803,7 +1816,7 @@
      accessing the memory as an array of word entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self wordAtWordIndex:index MSB:IsBigEndian
+    ^ self wordAtWordIndex:index MSB:(UninterpretedBytes isBigEndian)
 
     "Created: / 21.1.1998 / 17:48:26 / cg"
     "Modified: / 5.3.1998 / 15:00:16 / stefan"
@@ -1828,7 +1841,7 @@
      accessing the memory as an array of word entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self wordAtWordIndex:index put:value MSB:IsBigEndian
+    ^ self wordAtWordIndex:index put:value MSB:(UninterpretedBytes isBigEndian)
 
     "Created: / 21.1.1998 / 17:48:34 / cg"
     "Modified: / 5.3.1998 / 15:00:27 / stefan"
@@ -1958,6 +1971,5 @@
 !UninterpretedBytes class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Attic/UIBytes.st,v 1.31 1998-11-24 17:04:36 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Attic/UIBytes.st,v 1.32 1999-03-03 15:10:51 cg Exp $'
 ! !
-UninterpretedBytes initialize!
--- a/UninterpretedBytes.st	Mon Mar 01 23:51:44 1999 +0100
+++ b/UninterpretedBytes.st	Wed Mar 03 16:11:12 1999 +0100
@@ -99,39 +99,6 @@
 "
 ! !
 
-!UninterpretedBytes class methodsFor:'initialization'!
-
-checkByteOrder
-    "initialize our current byteOrder.
-     Must be called at system init time and on snapshot restart"
-
-    IsBigEndian := self isBigEndian.
-
-    "Created: / 5.3.1998 / 14:51:41 / stefan"
-!
-
-initialize
-    "get the byte order"
-
-    self checkByteOrder.
-
-    "want to be informed when returning from snapshot"
-    ObjectMemory dependents addDependent:self
-
-    "Created: / 5.3.1998 / 14:46:31 / stefan"
-    "Modified: / 5.3.1998 / 14:53:28 / stefan"
-!
-
-update:something with:aParameter from:changedObject
-    "handle image restarts and reget the byte order"
-
-    (something == #returnFromSnapshot) ifTrue:[
-        self checkByteOrder.
-    ]
-
-    "Created: / 5.3.1998 / 14:55:13 / stefan"
-! !
-
 !UninterpretedBytes class methodsFor:'instance creation'!
 
 from:aCollection
@@ -146,7 +113,10 @@
 isBigEndian
     "return true, if words/shorts store the most-significant
      byte first (MSB), false if least-sign.-first (LSB). 
-     I.e. false for vax, intel; true for m68k, sun."
+     I.e. false for vax, intel; true for m68k, sun.
+
+     Notice: UninterpretedBytes isBigEndian
+             this is inlined both by stc and the jit compiler"
 
 %{  /* NOCONTEXT */
 
@@ -164,8 +134,8 @@
      *    constant for systems where this is known.
      */
     union {
-	unsigned int   u_l;
-	char           u_c[sizeof(int)];
+        unsigned int   u_l;
+        char           u_c[sizeof(int)];
     } u;
 
     u.u_l = 0x87654321;
@@ -634,7 +604,7 @@
 
     |w|
 
-    w := self unsignedLongLongAt:index bigEndian:IsBigEndian.
+    w := self unsignedLongLongAt:index bigEndian:(UninterpretedBytes isBigEndian).
     (w > (16r7FFFFFFFFFFFFFFF)) ifTrue:[
         ^ w - (16r10000000000000000)
     ].
@@ -717,15 +687,15 @@
 
     l := LargeInteger basicNew numberOfDigits:8.
     msb ifTrue:[
-	bIdx := index + 7.
-	delta := -1
+        bIdx := index + 7.
+        delta := -1
     ] ifFalse:[
-	bIdx := index.
-	delta := 1
+        bIdx := index.
+        delta := 1
     ].
     1 to:8 do:[:i |
-	l digitAt:i put:(self basicAt:bIdx).
-	bIdx := bIdx + delta
+        l digitAt:i put:(self basicAt:bIdx).
+        bIdx := bIdx + delta
     ].
     ^ l compressed
 
@@ -813,7 +783,7 @@
      The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
      The value is stored in natural byte order."
 
-    ^ self unsignedLongLongAt:index put:anInteger bigEndian:IsBigEndian
+    ^ self unsignedLongLongAt:index put:anInteger bigEndian:(UninterpretedBytes isBigEndian)
 
     "Created: / 5.3.1998 / 14:44:00 / stefan"
     "Modified: / 5.3.1998 / 15:02:32 / stefan"
@@ -876,23 +846,44 @@
         __fetchBytePointerAndSize__(self, &cp, &sz);
         if (cp) {
             unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
+            int iVal;
 
             if ((idx+(sizeof(int)-1)) < sz) {
                 cp += idx;
-                /*
-                 * aligned
+
+#if defined(i386) || defined(UNALIGNED_FETCH_OK)
+                /* aligned or not - we dont care
+                 * (i386 can fetch unaligned)
                  */
+                iVal = ((int *)cp)[0];
+#else
                 if (((INT)cp & (sizeof(int)-1)) == 0) {
-                    int iVal = ((int *)cp)[0];
-
-                    RETURN (__MKUINT(iVal));
+                    /*
+                     * aligned
+                     */
+                    iVal = ((int *)cp)[0];
+                } else {
+                    union {
+                        char c[4];
+                        int  i;
+                    } u;
+                    u.c[0] = cp[0];
+                    u.c[1] = cp[1];
+                    u.c[2] = cp[2];
+                    u.c[3] = cp[3];
+                    iVal = u.i;
                 }
+#endif
+                if ((iVal >= 0) && (iVal <= _MAX_INT)) {
+                    RETURN ( __MKSMALLINT(iVal) );
+                }
+                RETURN ( __MKULARGEINT(iVal) );
             }
         }
     }
 %}.
 
-    ^ self doubleWordAt:index MSB:IsBigEndian
+    ^ self doubleWordAt:index MSB:(UninterpretedBytes isBigEndian)
 
     "
      |b|
@@ -912,41 +903,102 @@
      Subclasses may redefine this for better performance."
 
     |val 
-     ival "{ XXClass: SmallInteger }"
+     ival "{ Class: SmallInteger }"
+     t    "{ Class: SmallInteger }"
      i    "{ Class: SmallInteger }"
      b1   "{ Class: SmallInteger }"
      b2   "{ Class: SmallInteger }"
      b3   "{ Class: SmallInteger }"
      b4   "{ Class: SmallInteger }"|
 
+%{
+    /*
+     * handle the most common cases fast ...
+     */
+    if (__isSmallInteger(index)) {
+        unsigned char *cp;
+        int sz;
+
+        __fetchBytePointerAndSize__(self, &cp, &sz);
+        if (cp) {
+            unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
+            int iVal;
+
+            if ((idx+(sizeof(int)-1)) < sz) {
+                cp += idx;
+
+                if (msb == true) {
+#ifdef __MSBFIRST
+                    if (((INT)cp & (sizeof(int)-1))== 0) {
+                        /*
+                         * aligned
+                         */
+                        iVal = ((int *)cp)[0];
+                    } else
+#endif
+                    {
+                        iVal = cp[0];
+                        iVal = (iVal << 8) | cp[1];
+                        iVal = (iVal << 8) | cp[2];
+                        iVal = (iVal << 8) | cp[3];
+                    }
+                } else {
+#ifdef i386
+                    /*
+                     * aligned or not - we dont care
+                     * (i386 can fetch unaligned)
+                     */
+                    iVal = ((int *)cp)[0];
+#else
+# ifdef __LSBFIRST
+                    if (((INT)cp & (sizeof(int)-1))== 0) {
+                        /*
+                         * aligned
+                         */
+                        iVal = ((int *)cp)[0];
+                    } else
+# endif
+                    {
+                        iVal = cp[3];
+                        iVal = (iVal << 8) | cp[2];
+                        iVal = (iVal << 8) | cp[1];
+                        iVal = (iVal << 8) | cp[0];
+                    }
+#endif
+                }
+                RETURN (__MKUINT(iVal));
+            }
+        }
+    }
+%}.
+
+    "/ fallBack code - non ByteArray-like receiver
+    "/ or funny index
+
     i := index.
     b1 := self at:i.
     b2 := self at:(i+1).
     b3 := self at:(i+2).
     b4 := self at:(i+3).
 
-    msb ifTrue:[
-        ival := b1.
-        ival := (ival bitShift:8) + b2.
-        ival := (ival bitShift:8) + b3.
-        val := (ival bitShift:8) + b4.
-    ] ifFalse:[
-        ival := b4.
-        ival := (ival bitShift:8) + b3.
-        ival := (ival bitShift:8) + b2.
-        val := (ival bitShift:8) + b1.
+    msb ifFalse:[
+        t := b4. b4 := b1. b1 := t.
+        t := b3. b3 := b2. b2 := t.
     ].
+    ival := b1.
+    ival := (ival bitShift:8) + b2.
+    ival := (ival bitShift:8) + b3.
+    val := (ival bitShift:8) + b4.
     ^ val
 
     "
      |b|
 
      b := ByteArray withAll:#(1 2 3 4).
-     (b doubleWordAt:1 MSB:true) printStringRadix:16.   
-     (b doubleWordAt:1 MSB:false) printStringRadix:16   
+     (b doubleWordAt:1 MSB:true) printStringRadix:16.       
+     (b doubleWordAt:1 MSB:false) printStringRadix:16        
     "
 
-    "Modified: / 21.1.1998 / 17:42:30 / cg"
 !
 
 doubleWordAt:index put:value
@@ -957,7 +1009,7 @@
      The value is stored in the machines natural byte order.
      Subclasses may redefine this for better performance."
 
-    ^ self doubleWordAt:index put:value MSB:IsBigEndian
+    ^ self doubleWordAt:index put:value MSB:(UninterpretedBytes isBigEndian)
 
     "
      |b|
@@ -1015,7 +1067,7 @@
      accessing the memory as an array of doubleWord entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self doubleWordAtDoubleWordIndex:index MSB:IsBigEndian
+    ^ self doubleWordAtDoubleWordIndex:index MSB:(UninterpretedBytes isBigEndian)
 
     "Created: / 21.1.1998 / 17:43:53 / cg"
     "Modified: / 5.3.1998 / 14:58:06 / stefan"
@@ -1040,7 +1092,7 @@
      accessing the memory as an array of doubleWord entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self doubleWordAtDoubleWordIndex:index put:value MSB:IsBigEndian
+    ^ self doubleWordAtDoubleWordIndex:index put:value MSB:(UninterpretedBytes isBigEndian)
 
     "Created: / 21.1.1998 / 17:44:13 / cg"
     "Modified: / 5.3.1998 / 14:58:19 / stefan"
@@ -1319,9 +1371,10 @@
     "return the 4-bytes starting at index as an (unsigned) Integer.
      The index is a smalltalk index (i.e. 1-based).
      The value is retrieved in the machines natural byte order.
-     Subclasses may redefine this for better performance."
+     Subclasses may redefine this for better performance.
+     Same as doubleWordAt: for protocol completeness"
 
-    ^ self unsignedLongAt:index bigEndian:IsBigEndian
+    ^ self doubleWordAt:index
 
     "
      |b|
@@ -1339,34 +1392,10 @@
      The index is a smalltalk index (i.e. 1-based).
      The value is retrieved MSB-first, if the msb-arg is true;
      LSB-first otherwise.
-     Subclasses may redefine this for better performance."
-
-    |val 
-     ival "{ Class: SmallInteger }"
-     i    "{ Class: SmallInteger }"
-     b1   "{ Class: SmallInteger }"
-     b2   "{ Class: SmallInteger }"
-     b3   "{ Class: SmallInteger }"
-     b4   "{ Class: SmallInteger }"|
+     Subclasses may redefine this for better performance.
+     Same as doubleWordAt:MSB: for protocol completeness"
 
-    i := index.
-    b1 := self at:i.
-    b2 := self at:(i+1).
-    b3 := self at:(i+2).
-    b4 := self at:(i+3).
-
-    msb ifTrue:[
-        ival := b1.
-        ival := (ival bitShift:8) + b2.
-        ival := (ival bitShift:8) + b3.
-        val := (ival * 256) + b4.
-    ] ifFalse:[
-        ival := b4.
-        ival := (ival bitShift:8) + b3.
-        ival := (ival bitShift:8) + b2.
-        val := (ival * 256) + b1.
-    ].
-    ^ val
+    ^ self doubleWordAt:index MSB:msb
 
     "
      |b|
@@ -1386,9 +1415,10 @@
      The value should be in the range 0 to 16rFFFFFFFF
      (for negative values, the stored value is not defined).
      The value is stored in the machines natural byte order.
-     Subclasses may redefine this for better performance."
+     Subclasses may redefine this for better performance.
+     Same as doubleWordAt:put: for protocol completeness"
 
-    ^ self unsignedLongAt:index put:value bigEndian:IsBigEndian
+    ^ self doubleWordAt:index put:value
 
     "
      |b|
@@ -1406,27 +1436,10 @@
      The index is a smalltalk index (i.e. 1-based).
      The value must be in the range 0 to 16rFFFFFFFF.
      The value is stored MSB-first if msb is true; LSB-first otherwise.
-     Subclasses may redefine this for better performance."
-
-    |i "{ Class: SmallInteger }" |
-
-    ((aNumber < 0) or:[aNumber > 16rFFFFFFFF]) ifTrue:[
-        ^ self elementBoundsError
-    ].
+     Subclasses may redefine this for better performance.
+     Same as doubleWordAt:put:MSB: for protocol completeness"
 
-    i := index.
-    msb ifTrue:[
-        self at:i     put:(aNumber digitAt:4).
-        self at:(i+1) put:(aNumber digitAt:3).
-        self at:(i+2) put:(aNumber digitAt:2).
-        self at:(i+3) put:(aNumber digitAt:1).
-    ] ifFalse:[
-        self at:i     put:(aNumber digitAt:1).
-        self at:(i+1) put:(aNumber digitAt:2).
-        self at:(i+2) put:(aNumber digitAt:3).
-        self at:(i+3) put:(aNumber digitAt:4).
-    ].
-    ^ aNumber
+    ^ self doubleWordAt:index put:aNumber MSB:msb
 
     "
      |b|
@@ -1622,7 +1635,7 @@
      This is the ST80 equivalent of #wordAt:"
 
 
-    ^ self unsignedShortAt:index bigEndian:IsBigEndian
+    ^ self unsignedShortAt:index bigEndian:(UninterpretedBytes isBigEndian)
 
     "Created: / 5.3.1998 / 11:38:25 / stefan"
     "Modified: / 5.3.1998 / 14:59:25 / stefan"
@@ -1654,7 +1667,7 @@
      The stored value must be in the range 0 .. 16rFFFF. 
      The value is stored in the machines natural byteorder."
 
-    ^ self unsignedShortAt:index put:value bigEndian:IsBigEndian
+    ^ self unsignedShortAt:index put:value bigEndian:(UninterpretedBytes isBigEndian)
 
     "
      |b|
@@ -1713,7 +1726,7 @@
      The value is retrieved in the machines natural byte order
      Subclasses may redefine this for better performance."
 
-    ^ self wordAt:index MSB:IsBigEndian
+    ^ self wordAt:index MSB:(UninterpretedBytes isBigEndian)
 
     "Modified: / 5.3.1998 / 14:59:51 / stefan"
 !
@@ -1745,7 +1758,7 @@
      The value is stored in the machines natural byteorder.
      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
 
-    ^ self wordAt:index put:value MSB:IsBigEndian
+    ^ self wordAt:index put:value MSB:(UninterpretedBytes isBigEndian)
 
     "
      |b|
@@ -1803,7 +1816,7 @@
      accessing the memory as an array of word entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self wordAtWordIndex:index MSB:IsBigEndian
+    ^ self wordAtWordIndex:index MSB:(UninterpretedBytes isBigEndian)
 
     "Created: / 21.1.1998 / 17:48:26 / cg"
     "Modified: / 5.3.1998 / 15:00:16 / stefan"
@@ -1828,7 +1841,7 @@
      accessing the memory as an array of word entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self wordAtWordIndex:index put:value MSB:IsBigEndian
+    ^ self wordAtWordIndex:index put:value MSB:(UninterpretedBytes isBigEndian)
 
     "Created: / 21.1.1998 / 17:48:34 / cg"
     "Modified: / 5.3.1998 / 15:00:27 / stefan"
@@ -1958,6 +1971,5 @@
 !UninterpretedBytes class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.31 1998-11-24 17:04:36 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.32 1999-03-03 15:10:51 cg Exp $'
 ! !
-UninterpretedBytes initialize!