<> <> DIRECTORY Mopcodes; DragOpsImpl: CEDAR PROGRAM = BEGIN OPEN Mopcodes; <> FourBits: TYPE = [0..15]; FiveBits: TYPE = [0..31]; Word: TYPE = PACKED ARRAY FiveBits OF BOOL; ZerosWord: Word _ ALL[FALSE]; OnesWord: Word _ ALL[TRUE]; Half: TYPE = PACKED ARRAY FourBits OF BOOL; TwoHalves: TYPE = ARRAY [0..1] OF Half; TwoWords: TYPE = ARRAY [0..1] OF Word; FourHalves: TYPE = ARRAY [0..3] OF Half; ShiftOp: TYPE = MACHINE DEPENDENT {shift(0), extract(1), insert(2), rCycle(3)}; FieldDescriptor: TYPE = MACHINE DEPENDENT RECORD [ pq: BOOL, -- governs whether shift distance is from k or q mask: FiveBits, -- controls the mask generation op: ShiftOp, -- controls which operation is performed shiftSign: BOOL, -- gives the shift sign shift: FiveBits]; -- gives the shift distance <<>> <> FieldUnit: PROC [t,m: Word, q: FieldDescriptor, k: FieldDescriptor] RETURNS [u: Word] = { <> op: ShiftOp _ k.op; fd: FieldDescriptor _ IF k.pq THEN q ELSE k; -- may take specs from q register maskSpec: FiveBits _ IF op = shift THEN fd.shift ELSE fd.mask; shiftSpec: FiveBits _ fd.shift; invertMask: BOOL _ FALSE; su, mu, imu: Word; SELECT op FROM extract => invertMask _ TRUE; shift => invertMask _ fd.shiftSign; insert => m _ t; rCycle => invertMask _ TRUE; ENDCASE => ERROR; su _ ShiftUnit[t, m, shiftSpec, op = rCycle]; mu _ MaskUnit[maskSpec, op # shift]; imu _ WordNot[mu]; u _ WordAnd[su, IF invertMask THEN imu ELSE mu]; IF op = insert THEN u _ WordOr[WordAnd[imu, m], u]; }; ShiftUnit: PROC [w0,w1: Word, shiftSpec: FiveBits, rcyc: BOOL] RETURNS [su: Word] = { <> dist: FiveBits _ shiftSpec; IF rcyc THEN IF dist = 0 THEN RETURN [w1] ELSE dist _ 32-shiftSpec; su _ DoubleWordShiftLeft[w0, w1, dist]; }; MaskUnit: PROC [maskSpec: FiveBits, ms0: BOOL] RETURNS [mu: Word] = { <> IF maskSpec = 0 AND ms0 THEN RETURN [ZerosWord]; mu _ DoubleWordShiftLeft[OnesWord, ZerosWord, maskSpec]; }; <<>> <> WordNot: PROC [w: Word] RETURNS [Word] = { <> RETURN[HalvesToWord[HalfNot[LeftHalf[w]], HalfNot[RightHalf[w]]]]; }; WordAnd: PROC [w0,w1: Word] RETURNS [Word] = { <> RETURN[HalvesToWord[ HalfAnd[LeftHalf[w0], LeftHalf[w1]], HalfAnd[RightHalf[w0], RightHalf[w1]]]]; }; WordOr: PROC [w0,w1: Word] RETURNS [Word] = { <> RETURN[HalvesToWord[ HalfOr[LeftHalf[w0], LeftHalf[w1]], HalfOr[RightHalf[w0], RightHalf[w1]]]]; }; DoubleWordShiftLeft: PROC [w0,w1: Word, dist: FiveBits] RETURNS [Word] = { <> SELECT dist FROM 0 => RETURN [w0]; < 16 => RETURN [HalvesToWord[ HalfOr[HalfShift[LeftHalf[w0], dist], HalfShift[RightHalf[w0], dist-16]], HalfOr[HalfShift[RightHalf[w0], dist], HalfShift[LeftHalf[w1], dist-16]]]]; 16 => RETURN [HalvesToWord[RightHalf[w0], LeftHalf[w1]]]; ENDCASE => { < 16>> RETURN [HalvesToWord[ HalfOr[HalfShift[RightHalf[w0], dist-16], HalfShift[LeftHalf[w1], dist-32]], HalfOr[HalfShift[LeftHalf[w1], dist-16], HalfShift[RightHalf[w1], dist-32]]]]; }; }; WordAdd: PROC [w0,w1: Word] RETURNS [Word] = { RETURN [IntToWord[WordToInt[w0]+WordToInt[w1]]]; }; WordSub: PROC [w0,w1: Word] RETURNS [Word] = { RETURN [IntToWord[WordToInt[w0]-WordToInt[w1]]]; }; <<>> <> <> <> CARD: TYPE = LONG CARDINAL; HalvesToWord: PROC [h0,h1: Half] RETURNS [Word] = TRUSTED INLINE { RETURN[LOOPHOLE[TwoHalves[h0,h1], Word]]; }; HighHalf: PROC [w: Word] RETURNS [Half] = TRUSTED INLINE { RETURN[LOOPHOLE[w, TwoHalves][0]]; }; LowHalf: PROC [w: Word] RETURNS [Half] = TRUSTED INLINE { RETURN[LOOPHOLE[w, TwoHalves][1]]; }; LeftHalf: PROC [w: Word] RETURNS [Half] = TRUSTED INLINE { RETURN[LOOPHOLE[w, TwoHalves][0]]; }; RightHalf: PROC [w: Word] RETURNS [Half] = TRUSTED INLINE { RETURN[LOOPHOLE[w, TwoHalves][1]]; }; WordToInt: PROC [w: Word] RETURNS [INT] = TRUSTED MACHINE CODE { Mopcodes.zEXCH; }; WordToCard: PROC [w: Word] RETURNS [CARD] = TRUSTED MACHINE CODE { Mopcodes.zEXCH; }; IntToWord: PROC [int: INT] RETURNS [Word] = TRUSTED MACHINE CODE { Mopcodes.zEXCH; }; CardToWord: PROC [card: CARD] RETURNS [Word] = TRUSTED MACHINE CODE { Mopcodes.zEXCH; }; HalfNot: PROC [h: Half] RETURNS [nh: Half] = TRUSTED MACHINE CODE { <> Mopcodes.zLIN1; Mopcodes.zXOR }; HalfAnd: PROC [h0,h1: Half] RETURNS [h: Half] = TRUSTED MACHINE CODE { <> Mopcodes.zAND; }; HalfOr: PROC [h0,h1: Half] RETURNS [h: Half] = TRUSTED MACHINE CODE { <> Mopcodes.zOR; }; HalfShift: PROC [h: Half, dist: INTEGER] RETURNS [Half] = TRUSTED MACHINE CODE { <= 0) or right (if dist <= 0).>> Mopcodes.zSHIFT; }; <<>> <> W2I: PROC [w: Word] RETURNS [INT] = TRUSTED { <> RETURN[WordToInt[w]]; }; W2C: PROC [w: Word] RETURNS [CARD] = TRUSTED { <> RETURN[WordToCard[w]]; }; I2W: PROC [int: INT] RETURNS [Word] = TRUSTED { <> RETURN[IntToWord[int]]; }; C2W: PROC [card: CARD] RETURNS [Word] = TRUSTED { <> RETURN[CardToWord[card]]; }; END.