<> <> <> <> <> <> <> DIRECTORY Basics USING[BITSHIFT, BITOR, BITAND, CARD, LongNumber], PrincOpsUtils USING[LowHalf, HighHalf]; RTCommon: DEFINITIONS IMPORTS Basics, PrincOpsUtils = BEGIN <> CARD: TYPE = Basics.CARD; LongNumber: TYPE = Basics.LongNumber; Field: TYPE = RECORD[bitFirst: [0..15], bitCount: [0..32]]; <> LMasks: ARRAY [0..16] OF WORD = [ 0, 100000B, 140000B, 160000B, 170000B, 174000B, 176000B, 177000B, 177400B, 177600B, 177700B, 177740B, 177760B, 177770B, 177774B, 177776B, 177777B]; RMasks: ARRAY [0..16] OF WORD = [ 0, 1, 3, 7, 17B, 37B, 77B, 177B, 377B, 777B, 1777B, 3777B, 7777B, 17777B, 37777B, 77777B, 177777B]; <> RepPtrAddr: PROC[ptr: LONG POINTER] RETURNS[CARD] = INLINE { RETURN[LOOPHOLE[ptr]] }; RepAddrPtr: PROC[addr: CARD] RETURNS[LONG POINTER] = INLINE { RETURN[LOOPHOLE[addr]] }; RepAddrRef: PROC[addr: CARD] RETURNS[REF ANY] = INLINE { RETURN[LOOPHOLE[addr]] }; FetchField: PROC[ptr: LONG POINTER, field: Field] RETURNS[CARDINAL] = INLINE { OPEN field; RETURN[Basics.BITSHIFT[Basics.BITSHIFT[ptr^, bitFirst], bitCount-16]] }; FetchFieldLong: PROC[ptr: LONG POINTER, field: Field] RETURNS[CARD] = INLINE { OPEN field; IF bitFirst+bitCount <= 16 THEN RETURN[FetchField[ptr, field]] ELSE RETURN[ MakeLongCardinal[ptr^, FetchField[ptr+1, [bitFirst: bitFirst, bitCount: bitCount-16]]]]; }; MakeLongCardinal: PROC[lo, hi: CARDINAL] RETURNS[CARD] = INLINE { ln: LongNumber = LongNumber[num[highbits: hi, lowbits: lo]]; RETURN[ln.lc]; }; StoreField: PROC[ptr: LONG POINTER, field: Field, newValue: CARDINAL] = INLINE { OPEN field; bitOffset: [0..16] = 16-(bitFirst+bitCount); ptr^ _ Basics.BITOR[Basics.BITAND[ptr^, LMasks[bitFirst]+RMasks[bitOffset]], Basics.BITSHIFT[Basics.BITAND[newValue, RMasks[bitCount]], bitOffset]] }; StoreFieldLong: PROC[ptr: LONG POINTER, field: Field, newValue: CARD] = INLINE { OPEN field; IF bitFirst+bitCount <= 16 THEN StoreField[ptr, field, newValue] ELSE { ptr^ _ LOOPHOLE[newValue, LongNumber].lowbits; StoreField[ptr+1, [bitFirst: bitFirst, bitCount: bitCount-16], LOOPHOLE[newValue, LongNumber].highbits]; }; }; ShortenLongPointer: PROC[lp: LONG POINTER] RETURNS[POINTER] = INLINE { local: WORD; IF PrincOpsUtils.HighHalf[lp] # PrincOpsUtils.HighHalf[@local] THEN ERROR; RETURN[PrincOpsUtils.LowHalf[lp]]; }; END.