FieldUnit.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) January 23, 1986 12:05:14 pm PST
DIRECTORY
DragOpsCross USING [FieldDescriptor, OnesWord, Word, ZerosWord],
DragOpsCrossUtils USING [DoubleWordShiftLeft, DragAnd, DragNot, DragOr, SingleWordShiftLeft, SingleWordShiftRight];
FieldUnit: CEDAR PROGRAM
IMPORTS DragOpsCrossUtils
= BEGIN OPEN DragOpsCrossUtils;
FieldDescriptor: TYPE = DragOpsCross.FieldDescriptor;
Word: TYPE = DragOpsCross.Word;
ZerosWord: Word = DragOpsCross.ZerosWord;
OnesWord: Word = DragOpsCross.OnesWord;
Operate: PROC [Left,Right: Word, fd: FieldDescriptor] RETURNS [out: Word] = {
shifter: Word = DoubleWordShiftLeft[Left, Right, fd.shift];
The shifter output has the input double word shifted left by fd.shift bits
mask: Word ← SingleWordShiftRight[OnesWord, 32-fd.mask];
The default mask has fd.mask 1s right-justified in the word
IF fd.insert THEN
mask ← DragAnd[mask, SingleWordShiftLeft[OnesWord, fd.shift]];
fd.insert => clear rightmost fd.shift bits of the mask
out ← DragAnd[mask, shifter];
1 bits in the mask select the shifter output
IF fd.insert THEN out ← DragOr[out, DragAnd[DragNot[mask], Right]];
fd.backR => 0 bits in the mask select bits from Right to OR in to the result
};
END.
Definitions used from DragOpsCross
FieldDescriptor: TYPE = MACHINE DEPENDENT RECORD [
reserved: [0..15] ← 0,
reserved bits, not currently used, but must be 0s
insert: BOOL,
governs choice of background and low bits of mask
mask: [0..31],
31-mask gives # of leading 0s in the mask
shift: [0..32]
gives # of bits to left-shift the double word
];
Here is some pseudo-Mesa that describes the output of the FieldUnit. Assume that boolean operations work on type Word, and ** denotes exponentiation, and arithmetic is infinite precision.
FieldUnit: PROC [Left, Right: Word, fd: FieldDescriptor] RETURNS [output: Word] = {
background: Word =
IF insert THEN Right ELSE ZerosWord;
masker: Word =
2**(mask+1)-1 XOR
IF insert THEN 2**MIN[shift, mask] - 1 ELSE ZerosWord;
shifter: Word =
(DoubleWord[Left, Right] * 2**shift) AND OnesWord;
FOR i: FiveBitIndex IN FiveBitIndex DO
output[i] ← IF masker[i] THEN shifter[i] ELSE background[i];
ENDLOOP;
};
Word: TYPE = PACKED ARRAY [0..bitsPerWord) OF BOOL;
ZerosWord: Word = LOOPHOLE[LONG[0]];
OnesWord: Word = LOOPHOLE[LONG[-1]];
Definitions used from DragOpsCrossUtils
DoubleWordShiftLeft: PROC
[w0,w1: Word, dist: SixBitIndex] RETURNS [Word] = TRUSTED INLINE {
This procedure shifts two Dragon words left by dist bits and returns the leftmost word.
<< code omitted >>
};
SingleWordShiftLeft: PROC
[word: Word, dist: SixBitIndex] RETURNS [Word] = TRUSTED INLINE {
This procedure shifts one Dragon word left by dist bits and returns the shifted word.
<< code omitted >>
};
SingleWordShiftRight: PROC
[word: Word, dist: SixBitIndex] RETURNS [Word] = TRUSTED INLINE {
This procedure shifts one Dragon word right by dist bits and returns the shifted word.
<< code omitted >>
};
DragAnd: PROC [a,b: Word] RETURNS [Word] = INLINE {
This procedure is a 32-bit AND
<< code omitted >>
};
DragOr: PROC [a,b: Word] RETURNS [Word] = INLINE {
This procedure is a 32-bit OR
<< code omitted >>
};