IN: classes.struct.bit-accessors
! Bitfield accessors are little-endian on all platforms
-! Why not? It's platform-dependent in C
+! Why not? It's unspecified in C
: ones-between ( start end -- n )
[ 2^ 1 - ] bi@ swap bitnot bitand ;
[ t ] [ [ alien-unsigned-1 255 bitand ] { bitand fixnum-bitand } inlined? ] unit-test
[ t ] [ [ alien-unsigned-1 255 swap bitand ] { bitand fixnum-bitand } inlined? ] unit-test
+
+[ t ] [ [ { fixnum } declare 256 rem -256 bitand ] { fixnum-bitand } inlined? ] unit-test
+[ t ] [ [ { fixnum } declare 250 rem -256 bitand ] { fixnum-bitand } inlined? ] unit-test
+[ f ] [ [ { fixnum } declare 257 rem -256 bitand ] { fixnum-bitand } inlined? ] unit-test
: simplify-bitand? ( value -- ? )
value-info literal>> positive-fixnum? ;
+: all-ones? ( int -- ? )
+ dup 1 + bitand zero? ; inline
+
: redundant-bitand? ( var 111... -- ? )
- [ value-info ] bi@ { [
- nip literal>>
- { [ positive-fixnum? ] [ dup 1 + bitand zero? ] } 1&&
- ] [
- [ interval>> ] [ literal>> ] bi* 0 swap [a,b] interval-subset?
- ] } 2&& ;
+ [ value-info ] bi@ [ interval>> ] [ literal>> ] bi* {
+ [ nip integer? ]
+ [ nip all-ones? ]
+ [ 0 swap [a,b] interval-subset? ]
+ } 2&& ;
+
+: (zero-bitand?) ( value-info value-info' -- ? )
+ [ interval>> ] [ literal>> ] bi* {
+ [ nip integer? ]
+ [ nip bitnot all-ones? ]
+ [ 0 swap bitnot [a,b] interval-subset? ]
+ } 2&& ;
+
+: zero-bitand? ( var1 var2 -- ? )
+ [ value-info ] bi@
+ { [ (zero-bitand?) ] [ swap (zero-bitand?) ] } 2|| ;
{
bitand-integer-integer
} [
[
{
+ {
+ [ dup in-d>> first2 zero-bitand? ]
+ [ drop [ 2drop 0 ] ]
+ }
{
[ dup in-d>> first2 redundant-bitand? ]
[ drop [ drop ] ]