DIRECTORY Basics; BitOps: CEDAR DEFINITIONS = BEGIN BitWord: TYPE = CARDINAL; BitDWord: TYPE = LONG CARDINAL; BitQWord: TYPE = ARRAY [0 .. 4) OF CARDINAL; BitMWord: TYPE = LONG DESCRIPTOR FOR ARRAY CARDINAL OF BitWord; Long: TYPE = LONG CARDINAL; bitsPerWord: NAT = Basics.bitsPerWord; bitsPerDWord: NAT = 2*Basics.bitsPerWord; bitsPerQWord: NAT = 4*Basics.bitsPerWord; LastWBit: NAT = bitsPerWord - 1; LastDBit: NAT = bitsPerDWord - 1; LastQBit: NAT = bitsPerQWord - 1; BitWordZero: BitWord = 0; BitWordOnes: BitWord = 65535; BitDWordZero: BitDWord = 0; BitDWordOnes: BitDWord = 4294967295; BitQWordZero: BitQWord = [0, 0, 0, 0]; BitQWordOnes: BitQWord = [BitWordOnes, BitWordOnes, BitWordOnes, BitWordOnes]; ODD: PROC [i: INT] RETURNS [BOOL]; EVEN: PROC [i: INT] RETURNS [BOOL]; Log2: PROC [n: INT] RETURNS [INT]; -- Floor of Log2 NBits: PROC [n: INT] RETURNS [INT]; TwoToThe: PROC [x: INT] RETURNS [INT]; TwoToTheLog2: PROC [n: INT] RETURNS [INT]; ExtractBoolFWord, EBFW: PROC [container: BitWord, bitPosition: NAT, containerWidth: NAT _ bitsPerWord] RETURNS [result: BOOL]; InsertBoolInWord, IBIW: PROC [source: BOOL, container: BitWord, bitPosition: NAT, containerWidth: NAT _ bitsPerWord] RETURNS [newContainer: BitWord]; ExtractBoolFDouble, EBFD: PROC [container: BitDWord, bitPosition: NAT, containerWidth: NAT _ bitsPerDWord] RETURNS [result: BOOL]; InsertBoolInDouble, IBID: PROC [source: BOOL, container: BitDWord, bitPosition: NAT, containerWidth: NAT _ bitsPerDWord] RETURNS [newContainer: BitDWord]; ExtractBoolFQuad, EBFQ: PROC [container: BitQWord, bitPosition: NAT, containerWidth: NAT _ bitsPerQWord] RETURNS [result: BOOL]; InsertBoolInQuad, IBIQ: PROC [source: BOOL, container: BitQWord, bitPosition: NAT, containerWidth: NAT _ bitsPerQWord] RETURNS [newContainer: BitQWord]; ExtractBoolFMultiple, EBFM: PROC [container: BitMWord, bitPosition: NAT, containerWidth: NAT] RETURNS [result: BOOL]; InsertBoolInMultiple, IBIM: PROC [source: BOOL, container: BitMWord, bitPosition: NAT, containerWidth: NAT]; ExtractCardinalFWord, ECFW: PROC [container: BitWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerWord] RETURNS [result: CARDINAL]; InsertCardinalInWord, ICIW: PROC [source: CARDINAL, container: BitWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerWord] RETURNS [newContainer: BitWord]; ExtractCardinalFDouble, ECFD: PROC [container: BitDWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerDWord] RETURNS [result: CARDINAL]; InsertCardinalInDouble, ICID: PROC [source: CARDINAL, container: BitDWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerDWord] RETURNS [newContainer: BitDWord]; ExtractCardinalFQuad, ECFQ: PROC [container: BitQWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerQWord] RETURNS [result: CARDINAL]; InsertCardinalInQuad, ICIQ: PROC [source: CARDINAL, container: BitQWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerQWord] RETURNS [newContainer: BitQWord]; ExtractCardinalFMultiple, ECFM: PROC [container: BitMWord, fieldPosition, fieldWidth, containerWidth: NAT] RETURNS [result: CARDINAL]; InsertCardinalInMultiple, ICIM: PROC [source: CARDINAL, container: BitMWord, fieldPosition, fieldWidth, containerWidth: NAT]; ExtractLongFWord, ELFW: PROC [container: BitWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerWord] RETURNS [result: Long]; InsertLongInWord, ILIW: PROC [source: Long, container: BitWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerWord] RETURNS [newContainer: BitWord]; ExtractLongFDouble, ELFD: PROC [container: BitDWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerDWord] RETURNS [result: Long]; InsertLongInDouble, ILID: PROC [source: Long, container: BitDWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerDWord] RETURNS [newContainer: BitDWord]; ExtractLongFQuad, ELFQ: PROC [container: BitQWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerQWord] RETURNS [result: Long]; InsertLongInQuad, ILIQ: PROC [source: Long, container: BitQWord, fieldPosition, fieldWidth: NAT, containerWidth: NAT _ bitsPerQWord] RETURNS [newContainer: BitQWord]; ExtractLongFMultiple, ELFM: PROC [container: BitMWord, fieldPosition, fieldWidth, containerWidth: NAT] RETURNS [result: Long]; InsertLongInMultiple, ILIM: PROC [source: Long, container: BitMWord, fieldPosition, fieldWidth, containerWidth: NAT]; WordAND, WAND: PROC [op1, op2: BitWord] RETURNS [result: BitWord]; WordOR, WOR: PROC [op1, op2: BitWord] RETURNS [result: BitWord]; WordXOR, WXOR: PROC [op1, op2: BitWord] RETURNS [result: BitWord]; WordNOT, WNOT: PROC [op: BitWord, containerWidth: NAT _ bitsPerWord] RETURNS [result: BitWord]; WordShift, WShift: PROC [op: BitWord, shift: INTEGER, containerWidth: NAT _ bitsPerWord] RETURNS [result: BitWord]; DoubleAND, DAND: PROC [op1, op2: BitDWord] RETURNS [result: BitDWord]; DoubleOR, DOR: PROC [op1, op2: BitDWord] RETURNS [result: BitDWord]; DoubleXOR, DXOR: PROC [op1, op2: BitDWord] RETURNS [result: BitDWord]; DoubleNOT, DNOT: PROC [op: BitDWord, containerWidth: NAT _ bitsPerDWord] RETURNS [result: BitDWord]; DoubleShift, DShift: PROC [op: BitDWord, shift: INTEGER, containerWidth: NAT _ bitsPerDWord] RETURNS [result: BitDWord]; QuadAND, QAND: PROC [op1, op2: BitQWord] RETURNS [result: BitQWord]; QuadOR, QOR: PROC [op1, op2: BitQWord] RETURNS [result: BitQWord]; QuadXOR, QXOR: PROC [op1, op2: BitQWord] RETURNS [result: BitQWord]; QuadNOT, QNOT: PROC [op: BitQWord, containerWidth: NAT _ bitsPerQWord] RETURNS [result: BitQWord]; QuadShift, QShift: PROC [op: BitQWord, shift: INTEGER, containerWidth: NAT _ bitsPerQWord] RETURNS [result: BitQWord]; MulitipleAND, MAND: PROC [op1: BitMWord, op2: BitMWord, result: BitMWord]; MulitipleOR, MOR: PROC [op1: BitMWord, op2: BitMWord, result: BitMWord]; MulitipleXOR, MXOR: PROC [op1: BitMWord, op2: BitMWord, result: BitMWord]; MulitipleNOT, MNOT: PROC [op: BitMWord, containerWidth: NAT, result: BitMWord]; MulitipleShift, MShift: PROC [op: BitMWord, shift: INTEGER, containerWidth: NAT, result: BitMWord]; wordMasks: ARRAY [0 .. bitsPerWord] OF BitWord; doubleMasks: ARRAY [0 .. bitsPerDWord] OF BitDWord; quadMasks: ARRAY [0 .. bitsPerQWord] OF BitQWord; END. VBitOps.mesa Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved. Barth, August 7, 1986 6:04:44 pm PDT Spreitzer, March 19, 1984 8:59:08 pm PST Bertrand Serlet March 28, 1987 11:30:05 pm PST Theory This is an interface for extracting and inserting bit fields and a few other miscellaneous operations. Extractors/insertors mediate between containers and "external" TYPEs. There are four kinds of containers: CARDINAL, LONG CARDINAL, 4 element ARRAY OF CARDINAL, and ARRAY OF CARDINAL. There are three external TYPEs: BOOLEAN, CARDINAL, and LONG CARDINAL (a.k.a. Long). Thus, there are 2*4*3 = 24 of these procedures. Increasing index means decreasing significance (the most significant bit is numbered 0). The least significant bit of a field is stored in the least significant bit of a container so that Mesa operations can be performed directly on containers which are 16 or 32 bits wide. Because of the method of numbering the bits and the alignment requirements the field width must be passed to each operation in order to compute how the bits in the containers are numbered. There are also some boolean operations defined upon the containers. The containers The externals BOOL and CARDINAL already exist! Handy constants Predicates Log2 Extraction and Insertion procedures Definition of parameters and results: container: The array of bits that the field is inserted into or extracted from. containerWidth: The number of bits being used in the container. Must be less than or equal to the maximum size which the container can hold. bitPosition, fieldPosition: The position of the bit, or most significant bit of a field, within the container. The most significant bit is labeled bit zero and the least significant bit is labeled as the field width - 1. fieldWidth: The width of the field in bits. The last bit position of a field is fieldPosition + fieldWidth - 1. source: An argument to insertion procedures. It is the value assigned to the described field. result: The value of the described field. It is returned by the extraction procedures. newContainer: The updated container returned by insertion procedures except for the multiple word procedures which utilize a call by address argument mechanism rather than a call by value mechanism. Bools Cardinals Longs Handy operations for containers Masking Arrays Indexed by number of right-justified ones ÊS˜codešœ ™ KšœB™BK™$K™(K™.—K˜KšÏk œ˜K˜KšÏnœœ œœ˜"headšœ™Ibodyšœf™fMšœkœœœ œœœœœœ#œœœœ@™½MšœÐ™ÐM™C—šœ™Kšœ œœ˜Kšœ œœœ˜Kš œ œœ œœ˜,Kšœ œœ œœœœœ ˜?—šœ ™ Jšœ ™ Kšœœœœ˜—™Kšœ œ˜&Kšœœ˜)Kšœœ˜)Kšœ œ˜ Kšœ œ˜!Kšœ œ˜!K˜Kšœ˜Kšœ˜K˜Kšœ$˜$Kšœ&˜&KšœN˜N—šœ ™ š Ðbkœœœœœ˜"J˜—Jš Ÿœœœœœ˜#—šœ™š žœœœœœÏc˜3J˜—š žœœœœœ˜#J˜—š žœœœœœ˜&J˜—Jš ž œœœœœ˜*—šœ#™#™%M™OMšœ™MšœÝ™ÝMšœp™pMšœ^™^MšœW™WMšœÆ™Æ—™šÏbœŸœœ#œœ œ œ˜~K˜—š¡œŸœœ œ#œœ œ˜•K˜—š¡œŸœœ$œœœ œ˜‚K˜—š¡œŸœœ œ$œœœ˜šK˜—š¡œŸœœ$œœœ œ˜€K˜—š¡œŸœœ œ$œœœ˜˜K˜—š¡œŸœœ$œœœ œ˜uK˜—Kš ¡œŸœœ œ$œœ˜l—šœ ™ š¡œŸœœ1œœ œ œ˜”K˜—š¡œŸœœ œ1œœ œ˜«K˜—š¡œŸœœ2œœœ œ˜˜K˜—š¡œŸœœ œ2œœœ˜°K˜—š¡œŸœœ2œœœ œ˜–K˜—š¡œŸœœ œ2œœœ˜®K˜—š ¡œŸœœBœœ œ˜†K˜—Kš ¡œŸœœ œBœ˜}—™š ¡œŸœœ1œœ œ˜ŒK˜—š ¡œŸœœ?œœ œ˜£K˜—š ¡œŸœœ2œœœ˜K˜—š ¡œŸœœ@œœœ˜¨K˜—š ¡œŸœœ2œœœ˜ŽK˜—š ¡œŸœœ@œœœ˜¦K˜—š ¡œŸœœBœœ˜~K˜—Kš¡œŸœœPœ˜u——™š¡œŸœœœ˜BK˜—š¡œŸœœœ˜@K˜—š¡œŸœœœ˜BK˜—š ¡œŸœœœ œ˜_K˜—š ¡ œŸœœœœ œ˜sK˜—š¡ œŸœœœ˜FK˜—š¡œŸœœœ˜DK˜—š¡ œŸœœœ˜FK˜—š ¡ œŸœœ œœ˜dK˜—š ¡ œŸœœœœœ˜xK˜—š¡œŸœœœ˜DK˜—š¡œŸœœœ˜BK˜—š¡œŸœœœ˜DK˜—š ¡œŸœœ œœ˜bK˜—š ¡ œŸœœœœœ˜vK˜—š¡ œŸœœ2˜JK˜—š¡ œŸœœ2˜HK˜—š¡ œŸœœ2˜JK˜—š¡ œŸœœ œ˜OK˜—Kš ¡œŸœœœœ˜c—™Kšœ œœ ˜/Kšœ œœ ˜3šœ œœ ˜1K™)—K˜—Kšœ˜K˜—…—¨*Q