DIRECTORY Basics, BitTwiddling, PrincOps, PrincOpsUtils; BitTwiddlingImpl: CEDAR PROGRAM IMPORTS PrincOpsUtils EXPORTS BitTwiddling = {OPEN BitTwiddling; WordPtr: TYPE = LONG POINTER TO CARDINAL; disableCopy: BOOL _ FALSE; Copy: PUBLIC PROC [from, to: Ptr, bitCount: NAT, bbTable: PrincOps.BitBltTablePtr] = TRUSTED { lineWidth: NAT _ PrincOpsUtils.BITAND[(bitCount+32), -32]; bbTable^ _ [ dst: to, dstBpl: lineWidth, src: from, srcDesc: [srcBpl[lineWidth]], width: bitCount, height: 1, flags: []]; IF NOT disableCopy THEN PrincOpsUtils.BITBLT[bbTable]; bitCount _ bitCount; from _ from; }; maskAll: CARDINAL _ LAST[CARDINAL]; Equal: PUBLIC PROC [p1, p2: Ptr, bits: NAT] RETURNS [equal: BOOL] = TRUSTED { IF p1.bit = p2.bit THEN { mask: CARDINAL _ zeroFirst[p1.bit]; wordCount: NAT _ (p1.bit + bits-1)/Basics.bitsPerWord + 1; wp1: WordPtr _ LOOPHOLE[p1.word]; wp2: WordPtr _ LOOPHOLE[p2.word]; FOR i: NAT IN [1 .. wordCount] DO IF i = wordCount THEN mask _ PrincOpsUtils.BITAND[mask, lastMasks[(p1.bit + bits) MOD Basics.bitsPerWord]]; IF 0 # PrincOpsUtils.BITAND[mask, PrincOpsUtils.BITXOR[wp1^, wp2^]] THEN RETURN [FALSE]; mask _ maskAll; wp1 _ wp1 + 1; wp2 _ wp2 + 1; ENDLOOP; } ELSE { mask: CARDINAL _ zeroFirst[p2.bit]; wordCount: NAT _ (p2.bit + bits-1)/Basics.bitsPerWord + 1; wp1: WordPtr _ LOOPHOLE[p1.word]; wp2: WordPtr _ LOOPHOLE[p2.word]; residue: CARDINAL _ 0; rightPart, leftPart: INTEGER; SELECT TRUE FROM p1.bit > p2.bit => { rightPart _ p1.bit - p2.bit; residue _ PrincOpsUtils.BITSHIFT[wp1^, rightPart]; wp1 _ wp1 + 1; }; p1.bit < p2.bit => { rightPart _ p1.bit + Basics.bitsPerWord - p2.bit; residue _ 0; }; ENDCASE => ERROR; leftPart _ rightPart - Basics.bitsPerWord; FOR i: NAT IN [1 .. wordCount] DO w1: CARDINAL _ wp1^; repacked: CARDINAL; IF i = wordCount THEN mask _ PrincOpsUtils.BITAND[mask, lastMasks[(p2.bit + bits) MOD Basics.bitsPerWord]]; repacked _ PrincOpsUtils.BITOR[residue, PrincOpsUtils.BITSHIFT[w1, leftPart]]; IF 0 # PrincOpsUtils.BITAND[mask, PrincOpsUtils.BITXOR[repacked, wp2^]] THEN RETURN [FALSE]; residue _ PrincOpsUtils.BITSHIFT[w1, rightPart]; mask _ maskAll; wp1 _ wp1 + 1; wp2 _ wp2 + 1; ENDLOOP; }; equal _ TRUE; }; OffsetPtr: PUBLIC PROC [p: Ptr, bits: INT] RETURNS [q: Ptr] = TRUSTED { bo: INT _ bits + p.bit; dw: INT; bit: NAT; [dw, bit] _ FloorDivMod[bo, Basics.bitsPerWord]; q _ [word: p.word + dw, bit: bit]; }; FloorDivMod: PROC [num: INT, den: NAT] RETURNS [quot: INT, rem: INTEGER] = { quot _ num/den; rem _ num - quot*den; IF rem < 0 THEN {rem _ rem + den; quot _ quot - 1}; }; WPField: PUBLIC PROC [wp: WordPtr, f: Field] RETURNS [q: Ptr] = TRUSTED { IF wp = NIL THEN ERROR; q _ [ word: LOOPHOLE[wp + f.wordOffset, LONG POINTER], bit: f.bitOffset]; }; }. VBitTwiddlingImpl.Mesa Last Edited by: Spreitzer, April 29, 1985 9:06:27 pm PDT Κ– "cedar" style˜Icode™J™8K˜KšΟk œ/˜8K˜šΠbxœœ˜Kšœ˜Kšœ ˜K˜Kšœœ˜K˜Kš œ œœœœœ˜)K˜Kšœ œœ˜K˜š Οnœœœœ&œ˜^Kšœ œœ˜:˜ K˜Kšœ˜K˜ Kšœ˜Kšœ˜K˜ K˜ —Kšœœ œœ ˜6Kšœ˜Kšœ ˜ K˜—K˜Kšœ œœœ˜#K˜šŸœœœœœ œœ˜Mšœœ˜Kšœœ˜#Kšœ œ,˜:Kšœœ ˜!Kšœœ ˜!šœœœ˜!Kšœœœ!œ˜kKš œœœœœœ˜XK˜K˜K˜Kšœ˜—K˜—šœ˜Kšœœ˜#Kšœ œ,˜:Kšœœ ˜!Kšœœ ˜!Kšœ œ˜Kšœœ˜šœœ˜šœ˜Kšœ˜Kšœœ˜2Kšœ˜Kšœ˜—šœ˜Kšœ1˜1K˜ Kšœ˜—Kšœœ˜—Kšœ*˜*šœœœ˜!Kšœœ˜Kšœ œ˜Kšœœœ!œ˜kKšœœœ˜NKš œœœœœœ˜\Kšœœ˜0K˜K˜K˜Kšœ˜—K˜—Kšœœ˜ K˜—K˜š Ÿ œœœœœ œ˜GKšœœ˜Kšœœ˜Kšœœ˜ Kšœ0˜0Kšœ"˜"K˜—K˜šŸ œœœœœœœ˜LK˜K˜Kšœ œ$˜3K˜—K˜š Ÿœœœœ œ˜IKšœœœœ˜˜Kšœœœœ˜0Kšœ˜—K˜—K˜K˜——…— ¬!