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
Mesa translation of basics.c
DIRECTORY
MesaBasics USING [CHARPtr, WORDPtr],
Basics;
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 XR�positField\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;
};
ExternalNames[];
}...