-- RTCommon.Mesa
-- last edited May 12, 1983 5:24 pm by Paul Rovner
-- Last Edited by: Levin, August 8, 1983 5:07 pm

DIRECTORY
Basics USING[BITSHIFT, BITOR, BITAND, LongNumber],
PrincOpsUtils USING[LowHalf, HighHalf];

RTCommon: DEFINITIONS
IMPORTS Basics, PrincOpsUtils
= BEGIN
OPEN Basics;


-- TYPEs

Field: TYPE = RECORD[bitFirst: [0..15], bitCount: [0..32]];


-- Constants

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];


-- Procedures

RepPtrAddr: PROC[ptr: LONG POINTER] RETURNS[LONG CARDINAL] = INLINE
{RETURN[LOOPHOLE[ptr]]};
RepAddrPtr: PROC[addr: LONG CARDINAL] RETURNS[LONG POINTER] = INLINE
{RETURN[LOOPHOLE[addr]]};
RepAddrRef: PROC[addr: LONG CARDINAL] RETURNS[REF ANY] = INLINE
{RETURN[LOOPHOLE[addr]]};

FetchField: PROC[ptr: LONG POINTER, field: Field] RETURNS[CARDINAL] = INLINE
{OPEN field;
RETURN[BITSHIFT[BITSHIFT[ptr^, bitFirst], bitCount-16]]};

FetchFieldLong: PROC[ptr: LONG POINTER, field: Field] RETURNS[LONG CARDINAL] = 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: PROCEDURE[lo, hi: CARDINAL] RETURNS[lc: LONG CARDINAL] = INLINE
{LOOPHOLE[lc, num LongNumber] ← [num[highbits: hi, lowbits: lo]]};


StoreField: PROC[ptr: LONG POINTER, field: Field, newValue: CARDINAL] = INLINE
{OPEN field;
bitOffset: [0..16] = 16-(bitFirst+bitCount);
ptr^ ← BITOR[ BITAND[ptr^, LMasks[bitFirst]+RMasks[bitOffset]],
BITSHIFT[BITAND[newValue, RMasks[bitCount]], bitOffset]]};

StoreFieldLong: PROC[ptr: LONG POINTER, field: Field, newValue: LONG CARDINAL] = 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]}};

ShortenLongCardinal: PROC[lc: LONG CARDINAL] RETURNS[CARDINAL] = INLINE
-- obsolete
{RETURN[lc]};

ShortenLongPointer: PROC[lp: LONG POINTER] RETURNS[POINTER] = INLINE
{local: UNSPECIFIED;
IF PrincOpsUtils.HighHalf[lp] # PrincOpsUtils.HighHalf[@local] THEN ERROR;
RETURN[PrincOpsUtils.LowHalf[lp]]};

ShortenLongInteger: PROC[li: LONG INTEGER] RETURNS[INTEGER] = INLINE
-- obsolete
{RETURN[li]};

END.