6.5.6 Bitwise operations

and ( w1 w2 – w ) core “and”
or ( w1 w2 – w ) core “or”
xor ( w1 w2 – w ) core “x-or”
invert ( w1 – w2 ) core “invert”
mux ( u1 u2 u3 – u ) gforth-1.0 “mux”

Multiplex: For every bit in u3: for a 1 bit, select the corresponding bit from u1, otherwise the corresponding bit from u2. E.g., %0011 %1100 %1010 mux gives %0110

lshift ( u1 u – u2 ) core “l-shift”

Shift u1 left by u bits.

rshift ( u1 u – u2 ) core “r-shift”

Shift u1 (cell) right by u bits, filling the shifted-in bits with zero (logical/unsigned shift).

arshift ( n1 u – n2 ) gforth-1.0 “ar-shift”

Shift n1 (cell) right by u bits, filling the shifted-in bits from the sign bit of n1 (arithmetic shift).

dlshift ( ud1 u – ud2 ) gforth-1.0 “dlshift”

Shift ud1 (double-cell) left by u bits.

drshift ( ud1 u – ud2 ) gforth-1.0 “drshift”

Shift ud1 (double-cell) right by u bits, filling the shifted-in bits with zero (logical/unsigned shift).

darshift ( d1 u – d2 ) gforth-1.0 “darshift”

Shift d1 (double-cell) right by u bits, filling the shifted-in bits from the sign bit of d1 (arithmetic shift).

2* ( n1 – n2 ) core “two-star”

Shift left by 1; also works on unsigned numbers

2/ ( n1 – n2 ) core “two-slash”

Arithmetic shift right by 1. For signed numbers this is a floored division by 2 (note that / is symmetric on some systems, but 2/ always floors).

d2* ( d1 – d2 ) double “d-two-star”

Shift double-cell left by 1; also works on unsigned numbers

d2/ ( d1 – d2 ) double “d-two-slash”

Arithmetic shift right by 1. For signed numbers this is a floored division by 2.

>pow2 ( u1 – u2 ) gforth-1.0 “to-pow2”

u2 is the lowest power-of-2 number with u2>=u1.

log2 ( u – n ) gforth-1.0 “log2”

N is the rounded-down binary logarithm of u, i.e., the index of the first set bit; if u=0, n=-1.

pow2? ( u – f  ) gforth-1.0 “pow-two-query”

f is true iff u is a power of two, i.e., there is exactly one bit set in u.

ctz ( x – u  ) gforth-1.0 “c-t-z”

count trailing zeros in binary representation of x

Unlike most other operations, rotation of narrower units cannot easily be synthesized from rotation of wider units, so using cell-wide and double-wide rotation operations means that the results depend on the cell width. For published algorithms or cell-width-independent results, you usually need to use a fixed-width rotation operation.

wrol ( u1 u – u2 ) gforth-1.0 “wrol”

Rotate the least significant 16 bits of u1 left by u bits, set the other bits to 0.

wror ( u1 u – u2 ) gforth-1.0 “wror”

Rotate the least significant 16 bits of u1 right by u bits, set the other bits to 0.

lrol ( u1 u – u2 ) gforth-1.0 “lrol”

Rotate the least significant 32 bits of u1 left by u bits, set the other bits to 0.

lror ( u1 u – u2 ) gforth-1.0 “lror”

Rotate the least significant 32 bits of u1 right by u bits, set the other bits to 0.

rol ( u1 u – u2 ) gforth-1.0 “rol”

Rotate all bits of u1 left by u bits.

ror ( u1 u – u2 ) gforth-1.0 “ror”

Rotate all bits of u1 right by u bits.

drol ( ud1 u – ud2 ) gforth-1.0 “drol”

Rotate all bits of ud1 (double-cell) left by u bits.

dror ( ud1 u – ud2 ) gforth-1.0 “dror”

Rotate all bits of ud1 (double-cell) right by u bits.