869 |
869 |
870 bitAnd:anInteger |
870 bitAnd:anInteger |
871 "return the bitwise-and of the receiver and the argument, anInteger" |
871 "return the bitwise-and of the receiver and the argument, anInteger" |
872 |
872 |
873 %{ /* NOCONTEXT */ |
873 %{ /* NOCONTEXT */ |
874 |
|
875 if (__isSmallInteger(anInteger)) { |
874 if (__isSmallInteger(anInteger)) { |
876 INT v2 = __intVal(anInteger); |
875 INT v2 = __intVal(anInteger); |
877 INT v1; |
876 INT v1; |
878 #if defined(__LSBFIRST__) |
877 #if defined(__LSBFIRST__) |
879 v1 = *(INT *)(__stringVal(__INST(digitByteArray))); |
878 v1 = *(INT *)(__byteArrayVal(__INST(digitByteArray))); |
880 #else |
879 #else |
881 unsigned char *digits = (unsigned char *)(__stringVal(__INST(digitByteArray))); |
880 unsigned char *digits = (unsigned char *)(__byteArrayVal(__INST(digitByteArray))); |
882 |
881 |
883 v1 = digits[0] & 0xFF; |
882 v1 = digits[0] & 0xFF; |
884 v1 = v1 | ((digits[1] & 0xFF)<<8); |
883 v1 = v1 | ((digits[1] & 0xFF)<<8); |
885 v1 = v1 | ((digits[2] & 0xFF)<<16); |
884 v1 = v1 | ((digits[2] & 0xFF)<<16); |
886 v1 = v1 | ((digits[3] & 0xFF)<<24); |
885 v1 = v1 | ((digits[3] & 0xFF)<<24); |
887 if (sizeof(unsigned INT) == 8) { |
886 # if (__POINTER_SIZE__ == 8) |
888 v1 = v1 | ((digits[4] & 0xFF)<<32); |
887 v1 = v1 | ((digits[4] & 0xFF)<<32); |
889 v1 = v1 | ((digits[5] & 0xFF)<<40); |
888 v1 = v1 | ((digits[5] & 0xFF)<<40); |
890 v1 = v1 | ((digits[6] & 0xFF)<<48); |
889 v1 = v1 | ((digits[6] & 0xFF)<<48); |
891 v1 = v1 | ((digits[7] & 0xFF)<<56); |
890 v1 = v1 | ((digits[7] & 0xFF)<<56); |
892 } |
891 #endif |
893 #endif |
892 #endif |
894 |
893 RETURN ( __mkSmallInteger(v1 & v2) ); |
895 RETURN ( __mkSmallInteger(v1 & v2) ); |
|
896 } |
894 } |
897 %}. |
895 %}. |
898 ^ super bitAnd:anInteger |
896 ^ super bitAnd:anInteger |
899 |
897 |
900 " |
898 " |
916 Notice: the result of bitAt: on negative receivers is not |
914 Notice: the result of bitAt: on negative receivers is not |
917 defined in the language standard (since the implementation |
915 defined in the language standard (since the implementation |
918 is free to choose any internal representation for integers)" |
916 is free to choose any internal representation for integers)" |
919 |
917 |
920 %{ /* NOCONTEXT */ |
918 %{ /* NOCONTEXT */ |
921 |
|
922 if (__isSmallInteger(anIntegerIndex)) { |
919 if (__isSmallInteger(anIntegerIndex)) { |
923 INT idx = __smallIntegerVal(anIntegerIndex) - 1; |
920 INT idx = __smallIntegerVal(anIntegerIndex) - 1; |
|
921 |
924 if (idx >= 0) { |
922 if (idx >= 0) { |
925 int v1; |
923 int v1; |
926 int byteOffset = idx / 8; |
924 int byteOffset = idx / 8; |
927 int digitLen = __stringSize(__INST(digitByteArray)); |
925 int digitLen = __stringSize(__INST(digitByteArray)); |
928 |
926 |
929 if (digitLen < byteOffset) { |
927 if (digitLen < byteOffset) { |
930 RETURN(__mkSmallInteger(0)); |
928 RETURN(__mkSmallInteger(0)); |
931 } |
929 } |
932 |
930 |
933 v1 = ((unsigned char *)(__stringVal(__INST(digitByteArray))))[byteOffset]; |
931 v1 = (__byteArrayVal(__INST(digitByteArray)))[byteOffset]; |
934 if (v1 & (1 << (idx % 8))) { |
932 if (v1 & (1 << (idx % 8))) { |
935 RETURN(__mkSmallInteger(1)); |
933 RETURN(__mkSmallInteger(1)); |
936 } else { |
934 } else { |
937 RETURN(__mkSmallInteger(0)); |
935 RETURN(__mkSmallInteger(0)); |
938 } |
936 } |
940 } |
938 } |
941 %}. |
939 %}. |
942 ^ super bitAt:anIntegerIndex |
940 ^ super bitAt:anIntegerIndex |
943 |
941 |
944 " |
942 " |
945 16rFFFFFFFFFF01 bitAt:0 |
943 TestCase should:[ 16rFFFFFFFFFF01 bitAt:0 ] raise:Error |
946 16rFFFFFFFFFF01 bitAt:49 |
944 TestCase assert:( 16rFFFFFFFFFF01 bitAt:49 ) == 0 |
947 16rFFFFFFFFFF01 bitAt:1 |
945 TestCase assert:( 16rFFFFFFFFFF01 bitAt:1 ) == 1 |
948 16rFFFFFFFFFF01 bitAt:2 |
946 TestCase assert:( 16rFFFFFFFFFF01 bitAt:2 ) == 0 |
949 16rFFFFFFFFFF02 bitAt:2 |
947 TestCase assert:( 16rFFFFFFFFFF02 bitAt:2 ) == 1 |
950 16rFFFFFFFF01FF bitAt:8 |
948 TestCase assert:( 16rFFFFFFFF01FF bitAt:8 ) == 1 |
951 16rFFFFFFFF01FF bitAt:9 |
949 TestCase assert:( 16rFFFFFFFF01FF bitAt:9 ) == 1 |
952 16rFFFFFFFF01FF bitAt:10 |
950 TestCase assert:( 16rFFFFFFFF01FF bitAt:10 ) == 0 |
953 " |
951 " |
954 ! |
952 ! |
955 |
953 |
956 bitXor:anInteger |
954 bitXor:anInteger |
957 "return the bitwise-or of the receiver and the argument, anInteger. |
955 "return the bitwise-or of the receiver and the argument, anInteger. |
1010 %{ |
1008 %{ |
1011 /* |
1009 /* |
1012 * quickly advance over full 0-words |
1010 * quickly advance over full 0-words |
1013 */ |
1011 */ |
1014 if (__isByteArray(__INST(digitByteArray))) { |
1012 if (__isByteArray(__INST(digitByteArray))) { |
1015 int __sz = __intVal(sz); |
1013 int __sz = __intVal(sz); |
1016 unsigned char *__bP = (unsigned char *)(__byteArrayVal(__INST(digitByteArray))); |
1014 unsigned char *__bP = __byteArrayVal(__INST(digitByteArray)); |
1017 unsigned char *__bP0 = __bP; |
1015 unsigned char *__bP0 = __bP; |
1018 |
1016 |
1019 #ifdef __UNROLL_LOOPS__ |
1017 #ifdef __UNROLL_LOOPS__ |
1020 while (__sz > (sizeof(INT) * 4)) { |
1018 while (__sz > (sizeof(INT) * 4)) { |
1021 if ( ((INT *)__bP)[0] != 0 ) break; |
1019 if ( ((INT *)__bP)[0] != 0 ) break; |
1022 if ( ((INT *)__bP)[1] != 0 ) { |
1020 if ( ((INT *)__bP)[1] != 0 ) { |
1023 __sz -= sizeof(INT); |
1021 __sz -= sizeof(INT); |
1024 __bP += sizeof(INT); |
1022 __bP += sizeof(INT); |
1025 break; |
1023 break; |
1026 } |
1024 } |
1027 if ( ((INT *)__bP)[2] != 0 ) { |
1025 if ( ((INT *)__bP)[2] != 0 ) { |
1028 __sz -= sizeof(INT) * 2; |
1026 __sz -= sizeof(INT) * 2; |
1029 __bP += sizeof(INT) * 2; |
1027 __bP += sizeof(INT) * 2; |
1030 break; |
1028 break; |
1031 } |
1029 } |
1032 if ( ((INT *)__bP)[3] != 0 ) { |
1030 if ( ((INT *)__bP)[3] != 0 ) { |
1033 __sz -= sizeof(INT) * 3; |
1031 __sz -= sizeof(INT) * 3; |
1034 __bP += sizeof(INT) * 3; |
1032 __bP += sizeof(INT) * 3; |
1035 break; |
1033 break; |
1036 } |
1034 } |
1037 __sz -= sizeof(INT) * 4; |
1035 __sz -= sizeof(INT) * 4; |
1038 __bP += sizeof(INT) * 4; |
1036 __bP += sizeof(INT) * 4; |
1039 } |
1037 } |
1040 #endif |
1038 #endif |
1041 while (__sz > sizeof(INT)) { |
1039 while (__sz > sizeof(INT)) { |
1042 if ( ((INT *)__bP)[0] != 0 ) break; |
1040 if ( ((INT *)__bP)[0] != 0 ) break; |
1043 __sz -= sizeof(INT); |
1041 __sz -= sizeof(INT); |
1044 __bP += sizeof(INT); |
1042 __bP += sizeof(INT); |
1045 } |
1043 } |
1046 while (__sz > 0) { |
1044 while (__sz > 0) { |
1047 unsigned int c; |
1045 unsigned int c; |
1048 |
1046 |
1049 if ( (c = *__bP) != 0 ) { |
1047 if ( (c = *__bP) != 0 ) { |
1050 int bitIdx = (__bP - __bP0) * 8; |
1048 int bitIdx = (__bP - __bP0) * 8; |
1051 #ifdef __BSF |
1049 #ifdef __BSF |
1052 { |
1050 { |
1053 int index; |
1051 int index; |
1054 int t = c; |
1052 int t = c; |
1055 |
1053 |
1056 index = __BSF(t); |
1054 index = __BSF(t); |
1057 RETURN ( __mkSmallInteger(index + 1 + bitIdx) ); |
1055 RETURN ( __mkSmallInteger(index + 1 + bitIdx) ); |
1058 } |
1056 } |
1059 #else |
1057 #else |
1060 if (c & 0x0F) { |
1058 if (c & 0x0F) { |
1061 if (c & 0x03) { |
1059 if (c & 0x03) { |
1062 if (c & 0x01) { |
1060 if (c & 0x01) { |
1063 RETURN ( __mkSmallInteger( bitIdx + 1) ); |
1061 RETURN ( __mkSmallInteger( bitIdx + 1) ); |
1064 } else { |
1062 } else { |
1065 RETURN ( __mkSmallInteger( bitIdx + 2) ); |
1063 RETURN ( __mkSmallInteger( bitIdx + 2) ); |
1066 } |
1064 } |
1067 } else { |
1065 } else { |
1068 if (c & 0x04) { |
1066 if (c & 0x04) { |
1069 RETURN ( __mkSmallInteger( bitIdx + 3) ); |
1067 RETURN ( __mkSmallInteger( bitIdx + 3) ); |
1070 } else { |
1068 } else { |
1071 RETURN ( __mkSmallInteger( bitIdx + 4) ); |
1069 RETURN ( __mkSmallInteger( bitIdx + 4) ); |
1072 } |
1070 } |
1073 } |
1071 } |
1074 } else { |
1072 } else { |
1075 if (c & 0x30) { |
1073 if (c & 0x30) { |
1076 if (c & 0x10) { |
1074 if (c & 0x10) { |
1077 RETURN ( __mkSmallInteger( bitIdx + 5) ); |
1075 RETURN ( __mkSmallInteger( bitIdx + 5) ); |
1078 } else { |
1076 } else { |
1079 RETURN ( __mkSmallInteger( bitIdx + 6) ); |
1077 RETURN ( __mkSmallInteger( bitIdx + 6) ); |
1080 } |
1078 } |
1081 } else { |
1079 } else { |
1082 if (c & 0x40) { |
1080 if (c & 0x40) { |
1083 RETURN ( __mkSmallInteger( bitIdx + 7) ); |
1081 RETURN ( __mkSmallInteger( bitIdx + 7) ); |
1084 } else { |
1082 } else { |
1085 RETURN ( __mkSmallInteger( bitIdx + 8) ); |
1083 RETURN ( __mkSmallInteger( bitIdx + 8) ); |
1086 } |
1084 } |
1087 } |
1085 } |
1088 } |
1086 } |
1089 #endif |
1087 #endif |
1090 break; |
1088 break; |
1091 } |
1089 } |
1092 __sz--; |
1090 __sz--; |
1093 __bP++; |
1091 __bP++; |
1094 } |
1092 } |
1095 idx0 = __mkSmallInteger( __bP - __bP0 + 1 ); |
1093 idx0 = __mkSmallInteger( __bP - __bP0 + 1 ); |
1096 } |
1094 } |
1097 %}. |
1095 %}. |
1098 "/ never actually reached |
1096 "/ never actually reached |
1099 idx0 to:sz do:[:digitIndex | |
1097 idx0 to:sz do:[:digitIndex | |
1100 (byte := digitByteArray at:digitIndex) ~~ 0 ifTrue:[ |
1098 (byte := digitByteArray at:digitIndex) ~~ 0 ifTrue:[ |
1101 ^ (digitIndex-1)*8 + (byte lowBit) |
1099 ^ (digitIndex-1)*8 + (byte lowBit) |
1102 ] |
1100 ] |
1103 ]. |
1101 ]. |
1104 ^ 0 "/ should not happen |
1102 ^ 0 "/ should not happen |
1105 |
1103 |
1106 " |
1104 " |
1107 (1 bitShift:0) lowBit |
1105 (1 bitShift:0) lowBit |
1108 (1 bitShift:10) lowBit |
1106 (1 bitShift:10) lowBit |
1109 (1 bitShift:20) lowBit |
1107 (1 bitShift:20) lowBit |
1110 (1 bitShift:30) lowBit |
1108 (1 bitShift:30) lowBit |
1111 (1 bitShift:30) highBit |
1109 (1 bitShift:30) highBit |
1112 (1 bitShift:31) lowBit |
1110 (1 bitShift:31) lowBit |
1114 (1 bitShift:32) lowBit |
1112 (1 bitShift:32) lowBit |
1115 (1 bitShift:32) highBit |
1113 (1 bitShift:32) highBit |
1116 (1 bitShift:33) lowBit |
1114 (1 bitShift:33) lowBit |
1117 (1 bitShift:33) highBit |
1115 (1 bitShift:33) highBit |
1118 (1 bitShift:64) lowBit |
1116 (1 bitShift:64) lowBit |
1119 (1 bitShift:64) highBit |
1117 (1 bitShift:64) highBit |
1120 (1 bitShift:1000) lowBit |
1118 (1 bitShift:1000) lowBit |
1121 (1 bitShift:1000) highBit |
1119 (1 bitShift:1000) highBit |
1122 ((1 bitShift:64)-1) lowBit |
1120 ((1 bitShift:64)-1) lowBit |
1123 ((1 bitShift:64)-1) highBit |
1121 ((1 bitShift:64)-1) highBit |
1124 |
1122 |
1125 1 to:1000 do:[:idx | |
1123 1 to:1000 do:[:idx | |
1126 self assert:(( 1 bitShift:idx) lowBit = (idx+1)). |
1124 self assert:(( 1 bitShift:idx) lowBit = (idx+1)). |
1127 self assert:(( 1 bitShift:idx) lowBit = ( 1 bitShift:idx) highBit). |
1125 self assert:(( 1 bitShift:idx) lowBit = ( 1 bitShift:idx) highBit). |
1128 self assert:(( 3 bitShift:idx) lowBit = (idx+1)). |
1126 self assert:(( 3 bitShift:idx) lowBit = (idx+1)). |
1129 self assert:(( 7 bitShift:idx) lowBit = (idx+1)). |
1127 self assert:(( 7 bitShift:idx) lowBit = (idx+1)). |
1130 self assert:(( 15 bitShift:idx) lowBit = (idx+1)). |
1128 self assert:(( 15 bitShift:idx) lowBit = (idx+1)). |
1131 self assert:(( 31 bitShift:idx) lowBit = (idx+1)). |
1129 self assert:(( 31 bitShift:idx) lowBit = (idx+1)). |
1132 self assert:(( 63 bitShift:idx) lowBit = (idx+1)). |
1130 self assert:(( 63 bitShift:idx) lowBit = (idx+1)). |
1133 self assert:(( 127 bitShift:idx) lowBit = (idx+1)). |
1131 self assert:(( 127 bitShift:idx) lowBit = (idx+1)). |
1134 self assert:(( 255 bitShift:idx) lowBit = (idx+1)). |
1132 self assert:(( 255 bitShift:idx) lowBit = (idx+1)). |
1135 ] |
1133 ] |
1136 |
1134 |
1137 |num| |
1135 |num| |
1138 |
1136 |
1139 num := (1 bitShift:1000). |
1137 num := (1 bitShift:1000). |
1140 Time millisecondsToRun:[ |
1138 Time millisecondsToRun:[ |
1141 100000 timesRepeat:[ |
1139 100000 timesRepeat:[ |
1142 num lowBit |
1140 num lowBit |
1143 ] |
1141 ] |
1144 ] |
1142 ] |
1145 " |
1143 " |
1146 |
1144 |
1147 "Modified: 14.8.1997 / 11:55:34 / cg" |
1145 "Modified: 14.8.1997 / 11:55:34 / cg" |
1148 ! |
1146 ! |