{Begin SubSec Logical Arithmetic Functions}
{Title SubSec Logical Arithmetic Functions}
{Text

The following "logical" arithmetic functions are derived from Common Lisp, and have both macro and function definitions (the macros are for speed in running of compiled code).  The following code equivalences are primarily for definitional purposes, and should not be considered an implementation (especially since the real implementation tends to be faster and less "consy" than would be apparent from the code here).

{FnDef {Name LOGNOT} {Args N}
{Text
{lisp (LOGXOR {arg N} -1)}
}}


{FnDef {Name BITTEST} {Args N MASK}
{Text
{lisp (NOT (ZEROP (LOGAND {arg N} {arg MASK})))}
}}


{FnDef {Name BITCLEAR} {Args N MASK}
{Text
{lisp (LOGAND {arg N} (LOGNOT {arg MASK}))}
}}


{FnDef {Name BITSET} {Args N MASK}
{Text
{lisp (LOGOR {arg N} {arg MASK})}
}}


{FnDef {Name MASK.1'S} {Args POSITION SIZE}
{Text
{lispcode
(LLSH (SUB1 (EXPT 2 {arg SIZE}))
       {arg POSITION})}
}}


{FnDef {Name MASK.0'S} {Args POSITION SIZE}
{Text
{lisp (LOGNOT (MASK.1'S {arg POSITION} {arg SIZE}))}
}}


{FnDef {Name LOADBYTE} {Args N POSITION SIZE}
{Text
{lispcode
(LOGAND (LRSH {arg N} {arg POSITION})
        (MASK.1'S 0 {arg SIZE}))}
}}


{FnDef {Name DEPOSITBYTE} {Args N POSITION SIZE BYTE}
{Text
{lispcode
(LOGOR (BITCLEAR {arg N} (MASK.1'S {arg POSITION} {arg SIZE}))
       (LLSH (LOGAND {arg BYTE} (MASK.1'S 0 {arg SIZE}))
             {arg POSITION}))}
}}



{FnDef {Name ROT} {Args X N FIELDSIZE}
{Text
"Rotate bits in field".  This is a slight extension of the CommonLisp {lisp ROT} function.   It performs a bitwise left-rotation of the integer {arg X}, by {arg N} places, within a field of {arg FIELDSIZE} bits wide.  Bits being shifted out of the position selected by {lisp (EXPT 2 (SUB1 {arg FIELDSIZE}))} will flow into the "units" position.

The optional argument {arg FIELDSIZE} defaults to the "cell" size (the integerlength of the current maximum {lisp FIXP}), and must either be a positive integer, or else be one of the litatoms {lisp CELL} or {lisp WORD}.  In the latter two cases the appropriate numerical values are respectively substituted.  A macro optimizes the case where {arg FIELDSIZE} is {lisp WORD} and {arg N} is 1.
}}



The notion of a "byte specifier" has been added; from a pair of positon and 
size arguments, a byte-spec is constructed by the macro {mac BYTE} [note reversal of arguments as compare with above functions]:

{MacDef {Name BYTE} {Args SIZE POSITION}
{Text
Constructs and returns a "byte specifier" containing {arg SIZE} and {arg POSITION}.
}}

{note [currently, byte-specs are implemented as a typerecord; Common Lisp
leaves unspecified whether there are any range limitations on "size" or "pos"]}


{MacDef {Name BYTESIZE} {Args BYTESPEC}
{Text
Returns the {arg SIZE} componant of the "byte specifier" {arg BYTESPEC}.
}}


{MacDef {Name BYTEPOSITION} {Args BYTESPEC}
{Text
Returns the {arg POSITION} componant of the "byte specifier" {arg BYTESPEC}.
}}

Two more "byte" functions are provided (with compiler macro support for efficiency):

{FnDef {Name LDB} {Args BYTESPEC VAL}
{Text
{lispcode
(LOADBYTE {arg VAL}
          (BYTEPOSITION {arg BYTESPEC})
          (BYTESIZE {arg BYTESPEC}))}
}}

{FnDef {Name DPB} {Args N BYTESPEC VAL}
{Text
{lispcode
(DEPOSITBYTE {arg VAL}
             (BYTEPOSITION {arg BYTESPEC}) 
             (BYTESIZE {arg BYTESPEC}) 
             {arg N})}
}}



}{End SubSec Logical Arithmetic Functions}