MesaBasicsImpl.mesa
Copyright Ó 1989, 1990, 1991, 1992 by Xerox Corporation. All rights reserved.
JKF August 13, 1990 12:20:32 pm PDT -- added EqualFields from Akira
Christian Jacobi, October 12, 1992 2:01 pm PDT
Willie-s, August 5, 1991 5:31 pm PDT
Michael Plass, October 1, 1991 12:27 pm PDT
MesaBasicsImpl:
PROGRAM
IMPORTS Basics
EXPORTS MesaBasics
= {
upw: CARDINAL = UNITS[WORD];
bitsPerWord: CARDINAL = BITS[WORD];
WORDPtr: TYPE ~ MesaBasics.WORDPtr;
CHARPtr: TYPE = MesaBasics.CHARPtr;
ExternalNames:
PROC [] =
TRUSTED
MACHINE
CODE {
"^ExternalNames\n";
"MoveWords XR←MoveWords\n";
"MoveWordsDisjoint XR←MoveWordsDisjoint\n";
"EqualWords XR𡤎qualWords\n";
"MoveBytes XR←MoveBytes\n";
"MoveBytesDisjoint XR←MoveBytesDisjoint\n";
"ExtractField XR𡤎xtractField\n";
"DepositField XRpositField\n";
"MoveField XR←MoveField\n";
"EqualFields XR𡤎qualFields\n";
"FillFields XR𡤏illFields\n";
"FillLongFields XR𡤏illLongFields\n";
"FillWords XR𡤏illWords\n";
"FillLongWords XR𡤏illLongWords\n";};
MoveWords:
PUBLIC
PROC [dst, src: WORDPtr, len:
CARDINAL] = {
MoveWords Moves len words (where a word is an 'int') from src to dst. The caller does not assure disjointness.
Basics.MoveWords[dst: LOOPHOLE[dst], src: LOOPHOLE[src], count: len];
};
MoveWordsDisjoint:
PUBLIC
PROC [dst, src: WORDPtr, len:
CARDINAL] = {
MoveWordsDisjoint Moves len words (where a word is an 'int') from src to dst. For efficiency, the caller assures disjointedness.
IF
LOOPHOLE[dst,
CARD]
MOD 4 +
LOOPHOLE[src,
CARD]
MOD 4 = 0
THEN {
both pointers are word-aligned!
Basics.CopyWords[dst: LOOPHOLE[dst], src: LOOPHOLE[src], count: len];
}
ELSE {
Misaligned arguments (should this ever happen)?
MoveBytes[LOOPHOLE[dst], LOOPHOLE[src], len * BYTES[WORD]]
};
};
Tests the two multi-word variables for equality.
EqualWords:
PUBLIC
PROC [src1, src2: WORDPtr, len:
CARDINAL]
RETURNS[
CARD] = {
c: Basics.Comparison ~ Basics.CompareBits[
aBase: LOOPHOLE[src1], aStart: 0,
bBase: LOOPHOLE[src2], bStart: 0,
count: len * BITS[WORD]
];
RETURN [ORD[c=equal]]
};
MoveBytes:
PUBLIC
PROC [dest, src: CHARPtr, len:
CARDINAL] = {
MoveBytes Moves len bytes from src to dest, and returns src. No assumptions are made about disjointedness. The pointers are not necessarily aligned on word boundaries
check: [4..4] ~ BYTES[WORD];
dstStart: CARD ~ LOOPHOLE[dest, CARD] MOD BYTES[WORD];
srcStart: CARD ~ LOOPHOLE[src, CARD] MOD BYTES[WORD];
destWP: CARD ~ LOOPHOLE[dest, CARD]-dstStart;
srcWP: CARD ~ LOOPHOLE[src, CARD]-srcStart;
Basics.MoveBytes[
dstBase: LOOPHOLE[destWP], dstStart: dstStart,
srcBase: LOOPHOLE[srcWP], srcStart: srcStart,
count: len
]
};
MoveBytesDisjoint:
PUBLIC
PROC [dest, src: CHARPtr, len:
CARDINAL] = {
MoveBytesDisjoint Moves len bytes from src to dest, and returns src. For efficiency, the caller assures disjointedness.
check: [4..4] ~ BYTES[WORD];
dstStart: CARD ~ LOOPHOLE[dest, CARD] MOD BYTES[WORD];
srcStart: CARD ~ LOOPHOLE[src, CARD] MOD BYTES[WORD];
destWP: CARD ~ LOOPHOLE[dest, CARD]-dstStart;
srcWP: CARD ~ LOOPHOLE[src, CARD]-srcStart;
Basics.CopyBytes[
dstBase: LOOPHOLE[destWP], dstStart: dstStart,
srcBase: LOOPHOLE[srcWP], srcStart: srcStart,
count: len
];
};
ExtractField:
PUBLIC
PROC [base: WORDPtr, offset:
INT, bits:
CARD]
RETURNS [
WORD] = {
ExtractField Extracts the field from any base pointer (pointer to word) at any bit offset. The word given has the bits right-justified. The other bits are set to zero.
w: WORD ¬ 0;
WHILE offset < 0
DO
offset ¬ offset + BITS[WORD];
base ¬ base - SIZE[WORD];
ENDLOOP;
Basics.CopyBits[
dstBase: LOOPHOLE[@w], dstStart: BITS[WORD]-bits,
srcBase: LOOPHOLE[base], srcStart: offset,
count: bits
];
RETURN[w];
};
DepositField:
PUBLIC
PROC[base: WORDPtr, offset:
INT, bits:
CARD, w:
WORD] = {
DepositField Deposits the field to any base pointer at any bit offset. The word given has the bits right-justified. The other bits are ignored.
WHILE offset < 0
DO
offset ¬ offset + BITS[WORD];
base ¬ base - SIZE[WORD];
ENDLOOP;
Basics.CopyBits[
dstBase: LOOPHOLE[base], dstStart: offset,
srcBase: LOOPHOLE[@w], srcStart: BITS[WORD]-bits,
count: bits
];
};
MoveField:
PUBLIC
PROC [dst: WORDPtr, dstOffset:
INT, src: WORDPtr, srcOffset:
INT, bits:
CARD] = {
MoveField Moves 'bits' bits from src to dest.
WHILE dstOffset < 0
DO
dstOffset ¬ dstOffset + BITS[WORD];
dst ¬ dst - SIZE[WORD];
ENDLOOP;
WHILE srcOffset < 0
DO
srcOffset ¬ srcOffset + BITS[WORD];
src ¬ src - SIZE[WORD];
ENDLOOP;
Basics.CopyBits[
dstBase: LOOPHOLE[dst], dstStart: dstOffset,
srcBase: LOOPHOLE[src], srcStart: srcOffset,
count: bits
];
};
EqualFields:
PUBLIC
PROC[x: WORDPtr, xOffset:
INT, y: WORDPtr, yOffset:
INT, bits:
CARD]
RETURNS [
INT] = {
EqualFields Tests bitfields for equality.
WHILE xOffset < 0
DO
xOffset ¬ xOffset + BITS[WORD];
x ¬ x - SIZE[WORD];
ENDLOOP;
WHILE yOffset < 0
DO
yOffset ¬ yOffset + BITS[WORD];
y ¬ y - SIZE[WORD];
ENDLOOP;
RETURN [ORD[Basics.CompareBits[LOOPHOLE[x], xOffset, LOOPHOLE[y], yOffset, bits]=equal]]
};
FillFields:
PUBLIC
PROC [dst: WORDPtr, dstOffset:
INT, bits:
CARD, times:
CARD, value:
CARD] = {
FillLongFields[dst, dstOffset, LOOPHOLE[@value], bitsPerWord - bits, bits, times];
};
FillLongFields:
PUBLIC
PROC [dst: WORDPtr, dstOffset:
INT, src: WORDPtr, srcOffset:
INT, bits:
CARD, times:
CARD] = {
FillLongFields Fills contiguous fields that each are bits wide in the dst address (plus dstOffset bits) for times number of fields. The fill value is taken from the src address (plus srcOffset bits).
WHILE dstOffset < 0
DO
dstOffset ¬ dstOffset + BITS[WORD];
dst ¬ dst - SIZE[WORD];
ENDLOOP;
WHILE srcOffset < 0
DO
srcOffset ¬ srcOffset + BITS[WORD];
src ¬ src - SIZE[WORD];
ENDLOOP;
WHILE times > 0
DO
Basics.CopyBits[
dstBase: LOOPHOLE[dst], dstStart: dstOffset,
srcBase: LOOPHOLE[src], srcStart: srcOffset,
count: bits
];
dstOffset ¬ dstOffset + bits;
times ¬ times - 1;
ENDLOOP;
};
FillWords:
PUBLIC
PROC[dst: WORDPtr, times:
CARD, value:
CARD] = {
FillWords Fills times words at the destination with value.
IF
LOOPHOLE[dst,
CARD]
MOD 4 # 0
THEN {
WHILE times > 0
DO
[] ¬ MoveWords[dst, LOOPHOLE[@value], 1];
dst ¬ dst + upw;
times ¬ times - 1;
ENDLOOP;
}
ELSE {
Basics.FillWords[dst: LOOPHOLE[dst], count: times, value: value];
};
};
FillLongWords:
PUBLIC
PROC[dst, src: WORDPtr, nWords, times:
CARD] = {
FillLongWords Fills times nWords fields at the destination (dst) with the nWords field at the src.
IF (nWords = 1) THEN FillWords[dst, times, src[0]]
ELSE
WHILE times > 0
DO
[] ¬ MoveWords[dst, src, nWords];
dst ¬ dst + nWords*upw;
times ¬ times - 1;
ENDLOOP;
};
}...