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 => { 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 { 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. ¶DragOpsImpl.mesa Russ Atkinson, June 16, 1983 9:11 am T Y P E S Field Unit Operations This procedure specifies the behavior of the Field Unit under control of a given FieldDescriptor, k. The Q register's low-order bits are also available as input as a FieldDescriptor. The inputs t & m are determined by the IFU. This procedure specifies the operation of the shift unit in the EU. The idea is to left shift the 64-bit quantity given by w0 & w1 by shiftSpec bits (unless rcyc, in which case we shift left by 32-shiftSpec bits). By convention, w0 is more left than w1. This procedure specifies the operation of the mask unit in the EU. The idea is to generate a mask with maskSpec low-order bits of 0s, the remaining bits being 1s, unless maskSpec = 0 AND ms0, in which case, the mask is all 0s. Dragon Primitives This procedure is just a convenience to invert a Dragon word. This procedure is just a convenience to AND two Dragon words. This procedure is just a convenience to OR two Dragon words. This procedure shifts two Dragon words left by dist bits and returns the leftmost word. It is useful in the ShiftUnit and the MaskUnit. dist > 16 Dragon/Dorado conversions Note: all conversions to/from host format are below this line, except for the implicit assumption that anything less than or equal to 16 bits needs no conversion (i.e., bytes, field descriptors). Note: the Dragon convention is to have the low order half word (16 bits) in the right half of the word (32 bits), while the Dorado convention is to have the low order word (16 bits) in the left half of the doubleword (32 bits). This procedure is just a convenience to invert a half word. This procedure is just a convenience to AND two half words. This procedure is just a convenience to OR two half words. This procedure is just a half word shift left (if dist >= 0) or right (if dist <= 0). Debugging aids Useful for debugging Useful for debugging Useful for debugging Useful for debugging Ê(˜šœ™Jšœ$™$—J˜šÏk ˜ Jšœ ˜ J˜—šÏb œ ˜Jšœœœ ˜—J˜šœ ™ J˜Jšœ œ ˜Jšœ œ ˜š œœœœ œœ˜+Jšœœœ˜Jšœœœ˜—Jš œœœœ œœ˜+Jšœ œœœ˜'Jšœ œœœ˜&Jšœ œœœ˜(J˜Jšœ œœ œ.˜Oš œœœ œœ˜2J–24 sp tabStopsšœœÏc0˜:J–24 sp tabStopsšœŸ˜/J–24 sp tabStopsšœ Ÿ(˜5J–24 sp tabStopsšœ œŸ˜(J–24 sp tabStopsšœŸ˜-—J˜—I pagebreak™šœ™J˜šÏn œœ5œ˜YJšœä™äJšœ˜JšœœœœŸ!˜OJšœœ œ œ ˜>Jšœ˜Jšœ œœ˜J˜šœ˜Jšœœ˜Jšœ#˜#Jšœ˜Jšœœ˜Jšœœ˜—Jšœ-˜-Jšœ$˜$Jšœ˜Jšœœ œœ˜0Jšœ œ ˜3J˜J˜—š  œœ*œœ˜UJšœÿ™ÿJšœ˜šœ˜ šœ ˜ Jšœœ˜Jšœ˜——Jšœ'˜'J˜J˜—š œœœœ˜EJšœ¸œ)™äJšœœœœ ˜0Jšœ8˜8Jšœ˜J˜——K™šœ™J˜š œœ œ ˜*Jšœ=™=Jšœ<˜BJ˜J˜—š œœœ ˜.Jšœ=™=šœ˜Jšœ$˜$Jšœ(˜(—J˜J˜—š œœœ ˜-Jšœ<™<šœ˜Jšœ#˜#Jšœ'˜'—J˜J˜—š œœœ ˜JJšœˆ™ˆšœ˜Jšœœ˜˜šœ˜JšœI˜IJšœK˜K——šœ˜Jšœ-˜3—šœ˜ Jšœ ™ šœ˜JšœL˜LJšœN˜N—J˜——J˜J˜—š œœœ ˜.Jšœ*˜0J˜J˜—š œœœ ˜.Jšœ*˜0J˜J˜——K™šœ™J™ÃJ™ãJ˜šœœœœ˜J˜—š   œœœ œœ˜BJšœœ˜)J˜J˜—š  œœ œ œœ˜:Jšœœ˜"J˜J˜—š  œœ œ œœ˜9Jšœœ˜"J˜J˜—š  œœ œ œœ˜:Jšœœ˜"J˜J˜—š   œœ œ œœ˜;Jšœœ˜"J˜J˜—š  œœ œœœœœ˜@J˜J˜J˜—š  œœ œœœœœ˜BJ˜J˜J˜—š  œœœœ œœœ˜BJ˜J˜J˜—š  œœœœ œœœ˜EJ˜J˜J˜—š  œœ œœœ˜CJšœ;™;J˜J˜ J˜J˜—š  œœœ œœ˜FJšœ;™;Jšœ˜J˜J˜—š  œœœ œœ˜EJšœ:™:Jšœ ˜ J˜J˜—š   œœœœ œœ˜PJšœU™UJšœ˜J˜J˜——K™™J˜š  œœ œœœ˜-Jšœ™Jšœ˜J˜J˜—š  œœ œœœ˜.Jšœ™Jšœ˜J˜J˜—š  œœœœ œ˜/Jšœ™Jšœ˜J˜J˜—š  œœœœ œ˜1Jšœ™Jšœ˜J˜J˜——Jšœ˜J˜—…—ö!Ô