DIRECTORY Basics USING [bitsPerWord, BITAND, BITOR, BITXOR, BITNOT, BITSHIFT], BitOps, BitSwOps, SwitchTypes; BitOpsImpl: CEDAR PROGRAM IMPORTS Basics EXPORTS BitOps, BitSwOps = PUBLIC BEGIN OPEN Basics, BitOps, BitSwOps; bitsPerWord: CARDINAL = Basics.bitsPerWord; wordMasks: PUBLIC ARRAY [0 .. Basics.bitsPerWord] OF CARDINAL _ ALL[BitWordZero]; doubleMasks: PUBLIC ARRAY [0 .. 2*Basics.bitsPerWord] OF BitDWord _ ALL[[BitWordZero, BitWordOnes]]; BitsPtr: TYPE = LONG POINTER TO PACKED ARRAY CARDINAL OF BOOL; WordAsBits: TYPE = PACKED ARRAY [0..LastWBit] OF BOOL; LongAsWords: TYPE = MACHINE DEPENDENT RECORD [ low: CARDINAL, high: CARDINAL]; ToS: PROC [sl: StrengthenedLevel] RETURNS [s: PACKED ARRAY StrengthIndex OF SwitchTypes.Strength] = INLINE BEGIN SELECT sl.level FROM L => {s[u] _ none; s[d] _ sl.strength}; X => {s[u] _ sl.strength; s[d] _ sl.strength}; H => {s[u] _ sl.strength; s[d] _ none}; ENDCASE => ERROR; END; ExtractBoolFWord, EBFW: PROC [container: BitWord, containerWidth, bitPosition: CARDINAL] RETURNS [result: BOOL] = { t:WordAsBits _ LOOPHOLE[container]; IF containerWidth>bitsPerWord OR bitPosition>(containerWidth-1) THEN ERROR; RETURN[t[bitPosition+bitsPerWord-containerWidth]]; }; InsertBoolInWord, IBIW: PROC [source: BOOL, container: BitWord, containerWidth, bitPosition: CARDINAL] RETURNS [newContainer: BitWord] = { t:WordAsBits _ LOOPHOLE[container]; IF containerWidth>bitsPerWord OR bitPosition>(containerWidth-1) THEN ERROR; t[bitPosition+bitsPerWord-containerWidth] _ source; RETURN[LOOPHOLE[t]]; }; ExtractBoolFDouble, EBFD: PUBLIC PROC [container: BitDWord, containerWidth, bitPosition: CARDINAL] RETURNS [result: BOOL] = TRUSTED {result _ EBFM[DESCRIPTOR[container], containerWidth, bitPosition]}; InsertBoolInDouble, IBID: PUBLIC PROC [source: BOOL, container: BitDWord, containerWidth, bitPosition: CARDINAL] RETURNS [newContainer: BitDWord] = TRUSTED { newContainer _ container; IBIM[source, DESCRIPTOR[newContainer], containerWidth, bitPosition]}; ExtractBoolFMultiple, EBFM: PROC [container: BitMWord, containerWidth, bitPosition: CARDINAL] RETURNS [result: BOOL] = TRUSTED { pos: CARDINAL _ bitPosition+LENGTH[container]*bitsPerWord-containerWidth; word: CARDINAL _ pos/bitsPerWord; IF word>=LENGTH[container] THEN ERROR; RETURN[EBFW[container[word], bitsPerWord, pos MOD bitsPerWord]]; }; InsertBoolInMultiple, IBIM: PROC [source: BOOL, container: BitMWord, containerWidth, bitPosition: CARDINAL] = TRUSTED { pos: CARDINAL _ bitPosition+LENGTH[container]*bitsPerWord-containerWidth; word: CARDINAL _ pos/bitsPerWord; IF word >= LENGTH[container] THEN ERROR; container[word] _ IBIW[source, container[word], bitsPerWord, pos MOD bitsPerWord]; }; ExtractBoolFSwitch, EBFS: PUBLIC PROC [container: SwitchMWord, containerWidth, bitPosition: CARDINAL] RETURNS [result: BOOL] = TRUSTED {result _ SELECT container[bitPosition].val FROM L => FALSE, X => ERROR, H => TRUE, ENDCASE => ERROR}; InsertBoolInSwitch, IBIS: PUBLIC PROC [source: BOOL, container: SwitchMWord, containerWidth, bitPosition: CARDINAL, si: StrengthIndex, how: BoolStrengths] = TRUSTED {container[bitPosition].s[si] _ how[source]}; SpecialInsertBoolInSwitch, SIBIS: PUBLIC PROC [source: BOOL, container: SwitchMWord, containerWidth, bitPosition: CARDINAL, how: BoolSwitches] = TRUSTED {container[bitPosition].s _ ToS[how[source]]}; ExtractBoolFSingleSwitch, EBFSS: PUBLIC PROC [container: Switch] RETURNS [result: BOOL] = {result _ SELECT container.val FROM L => FALSE, X => ERROR, H => TRUE, ENDCASE => ERROR}; InsertBoolInSingleSwitch, IBISS: PUBLIC PROC [source: BOOL, container: Switch, si: StrengthIndex, how: BoolStrengths] RETURNS [newContainer: Switch] = {newContainer _ container; newContainer.s[si] _ how[source]}; SpecialInsertBoolInSingleSwitch, SIBISS: PUBLIC PROC [source: BOOL, container: Switch, how: BoolSwitches] RETURNS [newContainer: Switch] = {newContainer _ container; newContainer.s _ ToS[how[source]]}; ExtractCardinalFWord, ECFW: PROC [container: BitWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [result: CARDINAL] = { shift: INTEGER _ INTEGER[fieldPosition] + fieldWidth - containerWidth; IF containerWidth > bitsPerWord OR shift > 0 THEN ERROR; RETURN[BITAND[BITSHIFT[container, shift], wordMasks[fieldWidth]]]; }; InsertCardinalInWord, ICIW: PROC [source: CARDINAL, container: BitWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [newContainer: BitWord] = { shift: INTEGER _ INTEGER[containerWidth] - (fieldPosition+fieldWidth); IF containerWidth > bitsPerWord OR shift < 0 THEN ERROR; RETURN[BITOR[BITSHIFT[source, shift], BITAND[BITNOT[BITSHIFT[wordMasks[fieldWidth], shift]], container]]]; }; ExtractCardinalFDouble, ECFD: PUBLIC PROC [container: BitDWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [result: CARDINAL] = TRUSTED {result _ ECFM[DESCRIPTOR[container], containerWidth, fieldPosition, fieldWidth]}; InsertCardinalInDouble, ICID: PUBLIC PROC [source: CARDINAL, container: BitDWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [newContainer: BitDWord] = TRUSTED { newContainer _ container; ICIM[source, DESCRIPTOR[newContainer], containerWidth, fieldPosition, fieldWidth]}; ExtractCardinalFMultiple, ECFM: PROC [container: BitMWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [result: CARDINAL] = TRUSTED { containerSize: INTEGER _ LENGTH[container] * bitsPerWord; endBit: INTEGER = (containerSize - containerWidth) + fieldPosition + fieldWidth-1; endWord: INTEGER = endBit/bitsPerWord; lowWidth: INTEGER = (endBit MOD bitsPerWord) + 1; IF INTEGER[containerWidth]>containerSize OR fieldPosition+fieldWidth>containerWidth THEN ERROR; result _ BITSHIFT[container[endWord], lowWidth-bitsPerWord]; IF lowWidth < INTEGER[fieldWidth] THEN result _ BITOR[BITSHIFT[container[endWord-1], lowWidth], result]; result _ BITAND[result, wordMasks[fieldWidth]]; }; InsertCardinalInMultiple, ICIM: PROC [source: CARDINAL, container: BitMWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] = TRUSTED { containerSize: INTEGER _ LENGTH[container] * bitsPerWord; endBit: INTEGER = (containerSize - containerWidth) + fieldPosition + fieldWidth-1; endWord: INTEGER = endBit/bitsPerWord; lowWidth: INTEGER = (endBit MOD bitsPerWord) + 1; lowShift: INTEGER = bitsPerWord - lowWidth; IF INTEGER[containerWidth]>containerSize OR fieldPosition+fieldWidth>containerWidth THEN ERROR; container[endWord] _ BITOR[ BITSHIFT[source, lowShift], BITAND[ BITNOT[BITSHIFT[wordMasks[fieldWidth], lowShift]], container[endWord]]]; IF lowWidth < INTEGER[fieldWidth] THEN container[endWord-1] _ BITOR[ BITSHIFT[source, -lowWidth], BITAND[ BITNOT[BITSHIFT[wordMasks[fieldWidth], -lowWidth]], container[endWord-1]]]; }; ExtractCardinalFSwitch, ECFS: PUBLIC PROC [container: SwitchMWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [result: CARDINAL] = { IF fieldWidth > bitsPerWord THEN ERROR; result _ 0; FOR i: CARDINAL IN [0 .. fieldWidth) DO result _ result * 2; IF EBFS[container, containerWidth, fieldPosition+i] THEN result _ result+1; ENDLOOP}; InsertCardinalInSwitch, ICIS: PUBLIC PROC [source: CARDINAL, container: SwitchMWord, containerWidth, fieldPosition, fieldWidth: CARDINAL, si: StrengthIndex, how: BoolStrengths] = { IF fieldWidth > bitsPerWord THEN ERROR; FOR i: CARDINAL DECREASING IN [0 .. fieldWidth) DO bit: BOOL = 0 # (source MOD 2); IBIS[bit, container, containerWidth, fieldPosition+i, si, how]; source _ source / 2; ENDLOOP}; SpecialInsertCardinalInSwitch, SICIS: PUBLIC PROC [source: CARDINAL, container: SwitchMWord, containerWidth, fieldPosition, fieldWidth: CARDINAL, how: BoolSwitches] = { IF fieldWidth > bitsPerWord THEN ERROR; FOR i: CARDINAL DECREASING IN [0 .. fieldWidth) DO bit: BOOL = 0 # (source MOD 2); SIBIS[bit, container, containerWidth, fieldPosition+i, how]; source _ source / 2; ENDLOOP}; ExtractLongFWord, ELFW: PROC [container: BitWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [result: Long] = {result _ ECFW[container, containerWidth, fieldPosition, fieldWidth]}; InsertLongInWord, ILIW: PROC [source: Long, container: BitWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [newContainer: BitWord] = {newContainer _ ILIW[source, container, containerWidth, fieldPosition, fieldWidth]}; ExtractLongFDouble, ELFD: PROC [container: BitDWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [result: Long] = TRUSTED {result _ ELFM[DESCRIPTOR[container], containerWidth, fieldPosition, fieldWidth]}; InsertLongInDouble, ILID: PROC [source: Long, container: BitDWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [newContainer: BitDWord] = TRUSTED { newContainer _ container; ILIM[source, DESCRIPTOR[newContainer], containerWidth, fieldPosition, fieldWidth]}; ExtractLongFMultiple, ELFM: PROC [container: BitMWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [result: Long] = { IF fieldWidth <= bitsPerWord THEN RETURN [ECFM[container, containerWidth, fieldPosition, fieldWidth]] ELSE TRUSTED {law: LongAsWords; rem: CARDINAL = fieldWidth - bitsPerWord; law.high _ ECFM[container, containerWidth, fieldPosition, rem]; law.low _ ECFM[container, containerWidth, fieldPosition+rem, bitsPerWord]; result _ LOOPHOLE[law]}}; InsertLongInMultiple, ILIM: PROC [source: Long, container: BitMWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] = { IF fieldWidth <= bitsPerWord THEN ICIM[source, container, containerWidth, fieldPosition, fieldWidth] ELSE TRUSTED {law: LongAsWords _ LOOPHOLE[source]; rem: CARDINAL = fieldWidth - bitsPerWord; ICIM[law.high, container, containerWidth, fieldPosition, rem]; ICIM[law.low, container, containerWidth, fieldPosition+rem, bitsPerWord]}}; ExtractLongFSwitch, ELFS: PUBLIC PROC [container: SwitchMWord, containerWidth, fieldPosition, fieldWidth: CARDINAL] RETURNS [result: Long] = { IF fieldWidth > 2*bitsPerWord THEN ERROR; result _ 0; FOR i: CARDINAL IN [0 .. 2*fieldWidth) DO result _ result * 2; IF EBFS[container, containerWidth, fieldPosition+i] THEN result _ result+1; ENDLOOP}; InsertLongInSwitch, ILIS: PUBLIC PROC [source: Long, container: SwitchMWord, containerWidth, fieldPosition, fieldWidth: CARDINAL, si: StrengthIndex, how: BoolStrengths] = { IF fieldWidth > 2*bitsPerWord THEN ERROR; FOR i: CARDINAL DECREASING IN [0 .. 2*fieldWidth) DO bit: BOOL = 0 # (source MOD 2); IBIS[bit, container, containerWidth, fieldPosition+i, si, how]; source _ source / 2; ENDLOOP}; SpecialInsertLongInSwitch, SILIS: PUBLIC PROC [source: Long, container: SwitchMWord, containerWidth, fieldPosition, fieldWidth: CARDINAL, how: BoolSwitches] = { IF fieldWidth > 2*bitsPerWord THEN ERROR; FOR i: CARDINAL DECREASING IN [0 .. 2*fieldWidth) DO bit: BOOL = 0 # (source MOD 2); SIBIS[bit, container, containerWidth, fieldPosition+i, how]; source _ source / 2; ENDLOOP}; MoveWordToWord, MWTW: PROC [sourceContainer: BitWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] RETURNS [newContainer: BitWord] = { IF sourceWidth # destinationWidth THEN ERROR; RETURN[ICIW[ECFW[sourceContainer, sourceContainerWidth, sourcePosition, sourceWidth], destinationContainer, destinationContainerWidth, destinationPosition, destinationWidth]]; }; MoveWordToDouble, MWTD: PROC [sourceContainer: BitWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitDWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] RETURNS [newContainer: BitDWord] = TRUSTED { newContainer _ destinationContainer; MWTM[sourceContainer, sourceContainerWidth, sourcePosition, sourceWidth, DESCRIPTOR[newContainer], destinationContainerWidth, destinationPosition, destinationWidth]}; MoveWordToMultiple, MWTM: PROC [sourceContainer: BitWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] = { IF sourceWidth # destinationWidth THEN ERROR; ICIM[ECFW[sourceContainer, sourceContainerWidth, sourcePosition, sourceWidth], destinationContainer, destinationContainerWidth, destinationPosition, destinationWidth]; }; ConvertWordToSwitch, CWTS: PUBLIC PROC [sourceContainer: BitWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: SwitchMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL, si: StrengthIndex, how: BoolStrengths] = TRUSTED { source: ARRAY [0 .. 0] OF CARDINAL _ [sourceContainer]; IF sourceContainerWidth > bitsPerWord THEN ERROR; CMTS[DESCRIPTOR[source], sourceContainerWidth, sourcePosition, sourceWidth, destinationContainer, destinationContainerWidth, destinationPosition, destinationWidth, si, how]}; SpecialConvertWordToSwitch, SCWTS: PUBLIC PROC [sourceContainer: BitWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: SwitchMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL, how: BoolSwitches] = TRUSTED { source: ARRAY [0 .. 0] OF CARDINAL _ [sourceContainer]; IF sourceContainerWidth > bitsPerWord THEN ERROR; SCMTS[DESCRIPTOR[source], sourceContainerWidth, sourcePosition, sourceWidth, destinationContainer, destinationContainerWidth, destinationPosition, destinationWidth, how]}; MoveDoubleToWord, MDTW: PROC [sourceContainer: BitDWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] RETURNS [newContainer: BitWord] = TRUSTED {newContainer _ MMTW[DESCRIPTOR[sourceContainer], sourceContainerWidth, sourcePosition, sourceWidth, destinationContainer, destinationContainerWidth, destinationPosition, destinationWidth]}; MoveDoubleToDouble, MDTD: PROC [sourceContainer: BitDWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitDWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] RETURNS [newContainer: BitDWord] = TRUSTED { newContainer _ destinationContainer; MMTM[DESCRIPTOR[sourceContainer], sourceContainerWidth, sourcePosition, sourceWidth, DESCRIPTOR[newContainer], destinationContainerWidth, destinationPosition, destinationWidth]}; MoveDoubleToMultiple, MDTM: PROC [sourceContainer: BitDWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] = TRUSTED {MMTM[DESCRIPTOR[sourceContainer], sourceContainerWidth, sourcePosition, sourceWidth, destinationContainer, destinationContainerWidth, destinationPosition, destinationWidth]}; ConvertDoubleToSwitch, CDTS: PROC [sourceContainer: BitDWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: SwitchMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL, si: StrengthIndex, how: BoolStrengths] = TRUSTED { IF sourceContainerWidth > 2*bitsPerWord THEN ERROR; CMTS[DESCRIPTOR[sourceContainer], sourceContainerWidth, sourcePosition, sourceWidth, destinationContainer, destinationContainerWidth, destinationPosition, destinationWidth, si, how]}; SpecialConvertDoubleToSwitch, SCDTS: PUBLIC PROC [sourceContainer: BitDWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: SwitchMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL, how: BoolSwitches] = TRUSTED { IF sourceContainerWidth > 2*bitsPerWord THEN ERROR; SCMTS[DESCRIPTOR[sourceContainer], sourceContainerWidth, sourcePosition, sourceWidth, destinationContainer, destinationContainerWidth, destinationPosition, destinationWidth, how]}; MoveMultipleToWord, MMTW: PROC [sourceContainer: BitMWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] RETURNS [newContainer: BitWord] = { IF sourceWidth # destinationWidth THEN ERROR; RETURN[ICIW[ECFM[sourceContainer, sourceContainerWidth, sourcePosition, sourceWidth], destinationContainer, destinationContainerWidth, destinationPosition, destinationWidth]]; }; MoveMultipleToDouble, MMTD: PROC [sourceContainer: BitMWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitDWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] RETURNS [newContainer: BitDWord] = TRUSTED { newContainer _ destinationContainer; MMTM[sourceContainer, sourceContainerWidth, sourcePosition, sourceWidth, DESCRIPTOR[newContainer], destinationContainerWidth, destinationPosition, destinationWidth]}; MoveMultipleToMultiple, MMTM: PROC [sourceContainer: BitMWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] = { IF destinationWidth # sourceWidth THEN ERROR; IF destinationWidth <= bitsPerWord THEN ICIM[ ECFM[sourceContainer, sourceContainerWidth, sourcePosition, sourceWidth], destinationContainer, destinationContainerWidth, destinationPosition, destinationWidth] ELSE TRUSTED { sourcePad: INTEGER = LENGTH[sourceContainer]*bitsPerWord - sourceContainerWidth; destPad: INTEGER = LENGTH[destinationContainer]*bitsPerWord - destinationContainerWidth; firstDest: INTEGER = (destPad+destinationPosition) / bitsPerWord; lastDest: INTEGER = (destPad+destinationPosition + destinationWidth - 1) / bitsPerWord; delta: INTEGER = (sourcePad+sourcePosition) - (destPad+destinationPosition); l: INTEGER = LENGTH[sourceContainer] - 1; db1: INTEGER _ delta MOD bitsPerWord; dw1: INTEGER _ delta / bitsPerWord; db2, dw2: INTEGER; firstBits: INTEGER = bitsPerWord - ((destPad+destinationPosition) MOD bitsPerWord); nextBits: INTEGER = bitsPerWord-1 - ((destPad + destinationPosition + destinationWidth - 1) MOD bitsPerWord); IF dw1*bitsPerWord+db1 # delta THEN ERROR; IF delta < 0 THEN {db1 _ db1 + bitsPerWord; dw1 _ dw1 - 1}; db2 _ db1 - bitsPerWord; dw2 _ dw1 + 1; FOR destIndex: INTEGER IN [firstDest .. lastDest] DO dest: CARDINAL _ BITOR[ BITSHIFT[sourceContainer[MAX[destIndex + dw1, 0]], db1], BITSHIFT[sourceContainer[MIN[destIndex + dw2, l]], db2]]; IF destIndex = firstDest THEN destinationContainer[destIndex] _ BITOR[ BITAND[dest, wordMasks[firstBits]], BITAND[destinationContainer[destIndex], BITNOT[wordMasks[firstBits]]]] ELSE IF destIndex = lastDest THEN destinationContainer[destIndex] _ BITOR[ BITAND[dest, BITNOT[wordMasks[nextBits]]], BITAND[destinationContainer[destIndex], wordMasks[nextBits]]] ELSE destinationContainer[destIndex] _ dest; ENDLOOP; }; }; ConvertMultipleToSwitch, CMTS: PUBLIC PROC [sourceContainer: BitMWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: SwitchMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL, si: StrengthIndex, how: BoolStrengths] = TRUSTED { bits: BitsPtr _ LOOPHOLE[@sourceContainer[0]]; bitsOff: CARDINAL = (bitsPerWord - (sourceContainerWidth MOD bitsPerWord)) MOD bitsPerWord; IF sourceWidth # destinationWidth THEN ERROR; IF sourceWidth > sourceContainerWidth THEN ERROR; IF destinationWidth > destinationContainerWidth THEN ERROR; FOR i: CARDINAL IN [0 .. sourceWidth) DO destinationContainer[destinationPosition+i].s[si] _ how[bits[bitsOff+sourcePosition+i]]; ENDLOOP}; SpecialConvertMultipleToSwitch, SCMTS: PROC [sourceContainer: BitMWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: SwitchMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL, how: BoolSwitches] = TRUSTED { bits: BitsPtr _ LOOPHOLE[@sourceContainer[0]]; bitsOff: CARDINAL = (bitsPerWord - (sourceContainerWidth MOD bitsPerWord)) MOD bitsPerWord; IF sourceWidth # destinationWidth THEN ERROR; IF sourceWidth > sourceContainerWidth THEN ERROR; IF destinationWidth > destinationContainerWidth THEN ERROR; FOR i: CARDINAL IN [0 .. sourceWidth) DO destinationContainer[destinationPosition+i].s _ ToS[how[bits[bitsOff+sourcePosition+i]]]; ENDLOOP}; ConvertSwitchToWord, CSTW: PUBLIC PROC [sourceContainer: SwitchMWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] RETURNS [newContainer: BitWord] = TRUSTED { dest: ARRAY [0 .. 0] OF CARDINAL _ [destinationContainer]; IF destinationContainerWidth > bitsPerWord THEN ERROR; CSTM[sourceContainer, sourceContainerWidth, sourcePosition, sourceWidth, DESCRIPTOR[dest], destinationContainerWidth, destinationPosition, destinationWidth]; newContainer _ dest[0]}; ConvertSwitchToDouble, CSTD: PUBLIC PROC [sourceContainer: SwitchMWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitDWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] RETURNS [newContainer: BitDWord] = TRUSTED { IF destinationContainerWidth > 2*bitsPerWord THEN ERROR; newContainer _ destinationContainer; CSTM[sourceContainer, sourceContainerWidth, sourcePosition, sourceWidth, DESCRIPTOR[newContainer], destinationContainerWidth, destinationPosition, destinationWidth]}; ConvertSwitchToMultiple, CSTM: PUBLIC PROC [sourceContainer: SwitchMWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: BitMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] = TRUSTED { bits: BitsPtr = LOOPHOLE[@destinationContainer[0]]; bitsOff: CARDINAL = (bitsPerWord - (destinationContainerWidth MOD bitsPerWord)) MOD bitsPerWord; IF sourceWidth # destinationWidth THEN ERROR; IF sourceWidth > sourceContainerWidth THEN ERROR; IF destinationWidth > destinationContainerWidth THEN ERROR; FOR i: CARDINAL IN [0 .. sourceWidth) DO bits[bitsOff+destinationPosition+i] _ SELECT sourceContainer[sourcePosition+i].val FROM L => FALSE, X => ERROR, H => TRUE, ENDCASE => ERROR; ENDLOOP}; MoveSwitchToSwitch, MSTS: PUBLIC PROC [sourceContainer: SwitchMWord, sourceContainerWidth, sourcePosition, sourceWidth: CARDINAL, destinationContainer: SwitchMWord, destinationContainerWidth, destinationPosition, destinationWidth: CARDINAL] = TRUSTED { IF sourceWidth # destinationWidth THEN ERROR; IF sourceWidth > sourceContainerWidth THEN ERROR; IF destinationWidth > destinationContainerWidth THEN ERROR; FOR i: CARDINAL IN [0 .. destinationWidth) DO destinationContainer[destinationPosition+i] _ sourceContainer[sourcePosition+i]; ENDLOOP}; WordAND, WAND: PROC [op1, op2: BitWord] RETURNS [result: BitWord] = {result _ BITAND[op1, op2]}; WordOR, WOR: PROC [op1, op2: BitWord] RETURNS [result: BitWord] = {result _ BITOR[op1, op2]}; WordXOR, WXOR: PROC [op1, op2: BitWord] RETURNS [result: BitWord] = {result _ BITXOR[op1, op2]}; WordNOT, WNOT: PROC [op: BitWord, containerWidth: CARDINAL] RETURNS [result: BitWord] = {result _ BITAND[wordMasks[containerWidth], BITNOT[op]]}; WordShift, WShift: PROC [op: BitWord, containerWidth: CARDINAL, shift: INTEGER] RETURNS [result: BitWord] = {result _ BITAND[wordMasks[containerWidth], BITSHIFT[op, shift]]}; DoubleAND, DAND: PROC [op1, op2: BitDWord] RETURNS [result: BitDWord] = {result _ [BITAND[op1[0], op2[0]], BITAND[op1[1], op2[1]]]}; DoubleOR, DOR: PROC [op1, op2: BitDWord] RETURNS [result: BitDWord] = {result _ [BITOR[op1[0], op2[0]], BITOR[op1[1], op2[1]]]}; DoubleXOR, DXOR: PROC [op1, op2: BitDWord] RETURNS [result: BitDWord] = {result _ [BITXOR[op1[0], op2[0]], BITXOR[op1[1], op2[1]]]}; DoubleNOT, DNOT: PROC [op: BitDWord, containerWidth: CARDINAL] RETURNS [result: BitDWord] = { IF containerWidth>bitsPerWord THEN result _ [BITAND[wordMasks[containerWidth-bitsPerWord], BITNOT[op[0]]], BITNOT[op[1]]] ELSE result _ [0, BITAND[wordMasks[containerWidth], BITNOT[op[1]]]]}; DoubleShift, DShift: PROC [op: BitDWord, containerWidth: CARDINAL, shift: INTEGER] RETURNS [result: BitDWord] = { SELECT shift FROM >0 => { result[0] _ BITOR[BITSHIFT[op[0], shift], BITSHIFT[op[1], shift-bitsPerWord]]; result[1] _ BITSHIFT[op[1], shift]; }; <0 => { result[0] _ BITSHIFT[op[0], shift]; result[1] _ BITOR[BITSHIFT[op[1], shift], BITSHIFT[op[0], bitsPerWord+shift]]; }; =0 => RETURN[op]; ENDCASE; IF containerWidth>bitsPerWord THEN result[0] _ BITAND[result[0], wordMasks[containerWidth-bitsPerWord]] ELSE {result[0] _ 0; result[1] _ BITAND[result[1], wordMasks[containerWidth]]}; }; MulitipleAND, MAND: PROC [op1: BitMWord, op2: BitMWord, result: BitMWord] = TRUSTED { IF LENGTH[op1]#LENGTH[op2] OR LENGTH[op1]#LENGTH[result] THEN ERROR; FOR i:CARDINAL IN [0..LENGTH[op1]) DO result[i] _ BITAND[op1[i], op2[i]]; ENDLOOP; }; MulitipleOR, MOR: PROC [op1: BitMWord, op2: BitMWord, result: BitMWord] = TRUSTED { IF LENGTH[op1]#LENGTH[op2] OR LENGTH[op1]#LENGTH[result] THEN ERROR; FOR i:CARDINAL IN [0..LENGTH[op1]) DO result[i] _ BITOR[op1[i], op2[i]]; ENDLOOP; }; MulitipleXOR, MXOR: PROC [op1: BitMWord, op2: BitMWord, result: BitMWord] = TRUSTED { IF LENGTH[op1]#LENGTH[op2] OR LENGTH[op1]#LENGTH[result] THEN ERROR; FOR i:CARDINAL IN [0..LENGTH[op1]) DO result[i] _ BITXOR[op1[i], op2[i]]; ENDLOOP; }; MulitipleNOT, MNOT: PROC [op: BitMWord, containerWidth: CARDINAL, result: BitMWord] = TRUSTED { IF LENGTH[op]#LENGTH[result] THEN ERROR; FOR i:CARDINAL IN [0..LENGTH[op]) DO result[i] _ BITNOT[op[i]]; ENDLOOP; op[0] _ BITAND[op[0], wordMasks[containerWidth - (LENGTH[op] -1) * bitsPerWord]] }; MulitipleShift, MShift: PROC [op: BitMWord, containerWidth: CARDINAL, shift: INTEGER, result: BitMWord] = TRUSTED { IF LENGTH[op]#LENGTH[result] THEN ERROR; SELECT shift FROM <0 => { FOR i: CARDINAL _ LENGTH[op], i-1 UNTIL i=0 DO result[i] _ BITOR[BITSHIFT[op[i], shift], BITSHIFT[op[i-1], bitsPerWord+shift]]; ENDLOOP; result[0] _ BITSHIFT[op[0], shift]; }; >0 => { FOR i:CARDINAL IN [0..LENGTH[op]-1) DO result[i] _ BITOR[BITSHIFT[op[i], shift], BITSHIFT[op[i+1], shift-bitsPerWord]]; ENDLOOP; result[LENGTH[op]-1] _ BITSHIFT[op[LENGTH[op]-1], shift]; }; =0 => FOR i:CARDINAL IN [0..LENGTH[op]) DO result[i] _ op[i]; ENDLOOP; ENDCASE; op[0] _ BITAND[op[0], wordMasks[containerWidth - (LENGTH[op] -1) * bitsPerWord]] }; Start: PROC = BEGIN n: CARDINAL _ 0; wordMasks[0] _ doubleMasks[0][1] _ 0; FOR i: CARDINAL IN [1 .. bitsPerWord] DO wordMasks[i] _ doubleMasks[bitsPerWord+i][0] _ doubleMasks[i][1] _ n _ n + n+ 1; ENDLOOP; END; Start[]; END. ¾BitOpsImpl.mesa Last edited by: Barth, April 12, 1984 2:22:54 pm PST Last Edited by: Spreitzer, May 3, 1984 6:31:49 pm PDT ExtractCardinalFSingleSwitch, ECFSS: PUBLIC PROC [container: Switch] RETURNS [result: [0..1]] = {result _ SELECT container.val FROM L => 0, X => ERROR, H => 1, ENDCASE => ERROR}; InsertCardinalInSingleSwitch, ICISS: PUBLIC PROC [source: [0..1], container: Switch, si: StrengthIndex, how: BoolStrengths] RETURNS [newContainer: Switch] = {newContainer _ container; newContainer.s[si] _ how[source=1]}; FOR i: INTEGER IN [(destPad+destinationPosition) +.. destinationWidth) DO destBits[i] _ sourceBits[i + (sourcePad+sourcePosition - (destPad+destinationPosition))] ENDLOOP; Ê9– "cedar" style˜Icode™K™4Jšœ5™5K˜šÏk ˜ Kš œœœœœœœ˜DKšœ˜K˜ Kšœ ˜ —K˜šÐbx œœ˜Kšœ˜Kšœ˜—K˜Kšœœœ˜+K˜Kšœ œ˜+K˜Kš œ œœœœœ˜QKš œ œœœ œ˜dK˜Kšœ œœœœœœœœœ˜>Kš œ œœœœœ˜6š œ œœ œœ˜.Kšœœ˜Kšœœ˜—K˜š Ïnœœœœœœ˜jKš˜šœ ˜Kšœ&˜'Kšœ-˜.Kšœ&˜'Kšœœ˜—Kšœ˜—K˜š ÏbœÐbkœœ3œœ œ˜sKšœœ ˜#Kšœœ œœ˜KKšœ,˜2Kšœ˜—K˜š  œ¡œœ œ3œœ˜ŠKšœœ ˜#Kšœœ œœ˜KKšœ3˜3Kšœœ˜Kšœ˜—K˜š œ¡œœœ4œœ œ˜{Kšœ œ œ+˜L—K˜š œ¡œœœ œ4œœœ˜Kšœ˜Kšœ œ.˜E—K˜š œ¡œœ4œœ œœ˜€Kšœœœ'˜IKšœœ˜!Kšœœ œœ˜&Kšœœ#œ˜@Kšœ˜—K˜š  œ¡œœ œ4œœ˜wKšœœœ'˜IKšœœ˜!Kšœ œ œœ˜(Kšœœ+œ˜RKšœ˜—K˜š œ¡œœœ7œœ œ˜~šœ œ˜8Kšœœœœœœœœ˜5——K˜š  œ¡œœœ œ7œ+˜¤Kšœ-˜-—K˜š  œ¡œœœ œ7œ˜˜Kšœ.˜.—K˜š  œ¡œœœœ œ˜YKšœ œœœœœœœœœœ˜Y—K˜š  œ¡œœœ œ<œ˜–K˜=—K˜š  œ¡œœœ œ(œ˜ŠKšœ>˜>—K˜š  œ¡œœAœœ œ˜‰Kšœœœ.˜FKšœœ œœ˜8Kšœœœ,˜BK˜—K˜š  œ¡œœ œAœœ˜ Kšœœœ.˜FKšœœ œœ˜8Kš œœœœœœ.˜jK˜—K˜š œ¡œœœBœœ œ˜‘Kšœ œ œ9˜Z—K˜š œ¡œœœ œBœœœ˜³Kšœ˜Kšœ œ<˜S—K˜š œ¡œœBœœ œœ˜–Kšœœœ˜9KšœœC˜RKšœ œ˜&Kšœ œ œ˜1Kš œœœ)œœ˜_Kšœ œ+˜˜dšœœœ ˜2Kšœœ˜)Kšœ:˜>KšœG˜K——K˜š  œ¡œœœEœœ˜ŽKšœœœ˜)K˜ šœœœ˜)K˜Kšœœ-œ˜KKšœ˜ ——K˜š  œ¡œœœSœ,˜¬Kšœœœ˜)š œœ œœ˜4Kšœœœ˜Kšœ;˜?K˜Kšœ˜ ——K˜š  œ¡œœœSœ˜ Kšœœœ˜)š œœ œœ˜4Kšœœœ˜Kšœ7˜˜LKšœœœ˜)Kšœœ œ ˜&Kšœœ˜#Kšœ œ˜Kšœ œ0œ˜SKšœ œKœ˜mKšœœœ˜*Kšœ œ*˜;Kšœ'˜'šœ œœ˜4šœœœ˜Kšœœ˜8Kšœœ˜9—šœœ#œ˜FKšœ˜#Kšœ"œ˜F—šœœœ#œ˜JKšœœ˜*Kšœ7˜=—Kšœ(˜,Kšœ˜—K˜—Kšœ˜—K˜š œ¡œœœPœgœ+œ˜¥Kšœœ˜.Kšœ œ(œœ ˜[Kšœ œœ˜-Kšœ$œœ˜1Kšœ.œœ˜;šœœœ˜(KšœX˜XKšœ˜ ——K˜š  œ¡œœPœgœœ˜’Kšœœ˜.Kšœ œ(œœ ˜[Kšœ œœ˜-Kšœ$œœ˜1Kšœ.œœ˜;šœœœ˜(KšœY˜YKšœ˜ ——K˜š œ¡œœœSœcœœœ˜™Kšœœ œœ˜:Kšœ)œœ˜6KšœE œJ˜Kšœ˜—K˜š œ¡œœœSœdœœœ˜Kšœ+œœ˜8Kšœ$˜$KšœE œS˜¦—K˜š œ¡œœœSœdœœ˜þKšœœ˜3Kšœ œ-œœ ˜`Kšœ œœ˜-Kšœ$œœ˜1Kšœ.œœ˜;šœœœ˜(šœ&œ'˜WKšœœœœœœœœ˜4—Kšœ˜ ——K˜š œ¡œœœSœgœœ˜üKšœ œœ˜-Kšœ$œœ˜1Kšœ.œœ˜;šœœœ˜-KšœP˜PKšœ˜ ——K˜š œ¡œœœ˜CKšœ œ ˜—K˜š œ¡œœœ˜AKšœ œ ˜—K˜š œ¡œœœ˜CKšœ œ ˜—K˜š  œ¡œœœœ˜XKšœ œœ˜9—K˜š   œÐbnœœœ œœ˜lKšœ œœ˜B—K˜š  œ¡œœœ˜GKšœ œœ˜<—K˜š œ¡œœœ˜EKšœ œœ˜:—K˜š  œ¡œœœ˜GKšœ œœ˜<—K˜š   œ¡œœ œœ˜]Kš œœ œ(œ œ˜yKšœœœ ˜E—K˜š   œ¢œœ œ œœ˜qšœ˜˜Jšœ œœœ˜NJšœ œ˜#J˜—J˜Jšœ œ˜#šœ œœœ˜NJ˜—Jšœœ˜Jšœ˜—Jšœœ œ2˜gJšœœ(˜OJ˜—K˜š  œ¡œœ4œ˜UKšœœœœœœ œœ˜Dš œœœœ˜%Kšœ œ˜#Kšœ˜—Kšœ˜—K˜š  œ¡œœ4œ˜SKšœœœœœœ œœ˜Dš œœœœ˜%Kšœ œ˜"Kšœ˜—Kšœ˜—K˜š  œ¡œœ4œ˜UKšœœœœœœ œœ˜Dš œœœœ˜%Kšœ œ˜#Kšœ˜—Kšœ˜—K˜š   œ¡œœ œœ˜_Kš œœœ œœ˜(š œœœœ˜$Kšœ œ˜Kšœ˜—Kšœœ$œ˜PKšœ˜—K˜š  œ¢œœ œ œœ˜sKš œœœ œœ˜(šœ˜šœ˜š œœœ œ˜.Jšœ œœœ˜PJšœ˜—Jšœ œ˜#J˜—šœ˜š œœœœ˜&Jšœ œœœ˜PKšœ˜—Jšœœ œœ˜9Jšœ˜—š œœœœœ˜*Kšœ˜Kšœ˜—Jšœ˜—Kšœœ$œ˜PKšœ˜—K˜šŸœœ˜ Kš˜Kšœœ˜K˜%šœœœ˜(˜K˜K˜K˜ —Kšœ˜—Kšœ˜—K˜K˜K˜Kšœ˜—…—gš„‘