<<>> <> <> DIRECTORY Commander, GenericCall, IO; GenericCallImpl: PROGRAM IMPORTS Commander, IO EXPORTS GenericCall = BEGIN OPEN GenericCall; Unimplemented: PUBLIC ERROR = CODE; BadArgs: PUBLIC ERROR = CODE; Word: TYPE ~ CARD; PointerFitsInWord: BOOL[TRUE..TRUE] ~ (BITS[POINTER] <= BITS[Word]); Words: TYPE ~ REF WordSeq; WordSeq: TYPE ~ RECORD [words: SEQUENCE size: NAT OF Word]; RecordLayout: TYPE ~ RECORD [ words: NAT, ws: Words, pa: POINTER TO ARRAY [0..maxDirectCedarArgWords-1] OF Word, fields: ArgFields]; ArgFields: TYPE ~ REF ArgFieldSeq; ArgFieldSeq: TYPE ~ RECORD [SEQUENCE length: NAT OF ArgField]; ArgField: TYPE ~ RECORD [ address: Pointer, bitOffset: Size, bits: Size, variant: SELECT kind: * FROM direct => [], indirect => [ws: Words, bitOffset2: Size, bits2: Size], ENDCASE]; PM: PROC [p: POINTER] RETURNS [Pointer] ~ INLINE {RETURN [LOOPHOLE[p]]}; MP: PROC [p: Pointer] RETURNS [POINTER] ~ INLINE {RETURN [LOOPHOLE[p]]}; CM: PROC [c: CARD] RETURNS [Pointer] ~ INLINE {RETURN [c]}; IM: PROC [i: INT] RETURNS [Pointer] ~ INLINE {RETURN [LOOPHOLE[i]]}; NcM: PROC [c: CARD] RETURNS [Pointer] <> ~ INLINE {RETURN [c]}; NiM: PROC [i: INT] RETURNS [Pointer] <> ~ INLINE {RETURN [LOOPHOLE[i]]}; maxDirectCedarArgWords: NAT ~ 16; maxDirectCedarRetWords: NAT ~ 1; Call: PUBLIC PROC [proc: ProcRep, formalArgSizes, formalRetSizes: SizeList, actualArgs, actualRets: Fields] ~ { formalArgLay: RecordLayout ~ Layout[formalArgSizes, actualArgs.length, maxDirectCedarArgWords, TRUE]; formalRetLay: RecordLayout ~ Layout[formalRetSizes, actualRets.length, maxDirectCedarRetWords, FALSE]; indirectCedarArgs: BOOL ~ formalArgLay.words > maxDirectCedarArgWords; indirectCedarRets: BOOL ~ formalRetLay.words > maxDirectCedarRetWords; nested: BOOL ~ SELECT proc.flag FROM CM[0] => FALSE, CM[1] => TRUE, ENDCASE => ERROR; argCopy: RecordLayout _ formalArgLay; retCopy: RecordLayout _ formalRetLay; CopyRecord[Argify[actualArgs], formalArgLay.fields]; SELECT TRUE FROM nested AND indirectCedarArgs AND indirectCedarRets => { Local: PROC [retPtr, argPtr: POINTER] ~ LOOPHOLE[proc]; Local[formalRetLay.pa, formalArgLay.pa]}; nested AND indirectCedarArgs AND ~indirectCedarRets => { Local: PROC [argPtr: POINTER] RETURNS [Word] ~ LOOPHOLE[proc]; formalRetLay.pa[0] _ Local[formalArgLay.pa]}; nested AND ~indirectCedarArgs AND indirectCedarRets => { Local: PA16R2T ~ LOOPHOLE[proc]; ra: POINTER TO ARRAY [0..1] OF Word ~ LOOPHOLE[formalRetLay.pa]; IF formalArgLay.words < maxDirectCedarArgWords THEN formalArgLay.pa[formalArgLay.words] _ LOOPHOLE[Local]; ra^ _ Local[formalArgLay.pa[0], formalArgLay.pa[1], formalArgLay.pa[2], formalArgLay.pa[3], formalArgLay.pa[4], formalArgLay.pa[5], formalArgLay.pa[6], formalArgLay.pa[7], formalArgLay.pa[8], formalArgLay.pa[9], formalArgLay.pa[10], formalArgLay.pa[11], formalArgLay.pa[12], formalArgLay.pa[13], formalArgLay.pa[14], formalArgLay.pa[15] ]}; nested AND ~indirectCedarArgs AND ~indirectCedarRets => { Local: PA16R1T ~ LOOPHOLE[proc]; IF formalArgLay.words < maxDirectCedarArgWords THEN formalArgLay.pa[formalArgLay.words] _ LOOPHOLE[Local]; formalRetLay.pa[0] _ Local[formalArgLay.pa[0], formalArgLay.pa[1], formalArgLay.pa[2], formalArgLay.pa[3], formalArgLay.pa[4], formalArgLay.pa[5], formalArgLay.pa[6], formalArgLay.pa[7], formalArgLay.pa[8], formalArgLay.pa[9], formalArgLay.pa[10], formalArgLay.pa[11], formalArgLay.pa[12], formalArgLay.pa[13], formalArgLay.pa[14], formalArgLay.pa[15] ]}; ~nested AND indirectCedarArgs AND indirectCedarRets => { (LOOPHOLE[proc, PROC [retPtr, argPtr: POINTER]])[formalRetLay.pa, formalArgLay.pa]}; ~nested AND indirectCedarArgs AND ~indirectCedarRets => { formalRetLay.pa[0] _ (LOOPHOLE[proc, PROC [argPtr: POINTER] RETURNS [Word] ])[ formalArgLay.pa ]}; ~nested AND ~indirectCedarArgs AND indirectCedarRets => { ra: POINTER TO ARRAY [0..1] OF Word ~ LOOPHOLE[formalRetLay.pa]; IF formalArgLay.words < maxDirectCedarArgWords THEN formalArgLay.pa[formalArgLay.words] _ LOOPHOLE[proc]; ra^ _ (LOOPHOLE[proc, PA16R2T])[formalArgLay.pa[0], formalArgLay.pa[1], formalArgLay.pa[2], formalArgLay.pa[3], formalArgLay.pa[4], formalArgLay.pa[5], formalArgLay.pa[6], formalArgLay.pa[7], formalArgLay.pa[8], formalArgLay.pa[9], formalArgLay.pa[10], formalArgLay.pa[11], formalArgLay.pa[12], formalArgLay.pa[13], formalArgLay.pa[14], formalArgLay.pa[15] ]}; ~nested AND ~indirectCedarArgs AND ~indirectCedarRets => { IF formalArgLay.words < maxDirectCedarArgWords THEN formalArgLay.pa[formalArgLay.words] _ LOOPHOLE[proc]; formalRetLay.pa[0] _ (LOOPHOLE[proc, PA16R1T])[ formalArgLay.pa[0], formalArgLay.pa[1], formalArgLay.pa[2], formalArgLay.pa[3], formalArgLay.pa[4], formalArgLay.pa[5], formalArgLay.pa[6], formalArgLay.pa[7], formalArgLay.pa[8], formalArgLay.pa[9], formalArgLay.pa[10], formalArgLay.pa[11], formalArgLay.pa[12], formalArgLay.pa[13], formalArgLay.pa[14], formalArgLay.pa[15] ]}; ENDCASE => ERROR; CopyRecord[formalRetLay.fields, Argify[actualRets]]; RETURN}; Layout: PROC [sizes: SizeList, length, minWs: NAT, mayIndirect: BOOL] RETURNS [RecordLayout] ~ { fields: ArgFields ~ NEW [ArgFieldSeq[length]]; wc: Size _ 0; k: NAT _ 0; FOR sl: SizeList _ sizes, sl.rest WHILE sl#NIL DO bts: Size ~ sl.first; wds: Size _ (bts+bitsPerWord-1)/bitsPerWord; SELECT TRUE FROM wds=0 => ERROR BadArgs; wds=1 => fields[k] _ [NcM[wc*unitsPerWord], bitsPerWord-bts, bts, direct[]]; NOT mayIndirect => fields[k] _ [NcM[wc*unitsPerWord], 0, bts, direct[]]; ENDCASE => { ws: Words ~ NEW[WordSeq[wds]]; FOR i: Size IN [0..ws.size) DO ws[i] _ 0 ENDLOOP; fields[k] _ [NcM[wc*unitsPerWord], 0, bitsPerWord, indirect[ws, 0, bts]]; wds _ 1}; wc _ wc + wds; k _ k + 1; ENDLOOP; IF k # length THEN ERROR; {ws: Words ~ NEW[WordSeq[MAX[minWs, wc]]]; base: Pointer--will have to change when Pointer becomes POINTER-- ~ LOOPHOLE[@ws[0]]; FOR i: Size IN [0..ws.size) DO ws[i] _ 0 ENDLOOP; FOR j: NAT IN [0..fields.length) DO fields[j].address _ fields[j].address + base; WITH fields[j] SELECT FROM x: direct ArgField => NULL; x: indirect ArgField => MP[fields[j].address]^ _ @x.ws[0]; ENDCASE => ERROR; ENDLOOP; RETURN [[wc, ws, LOOPHOLE[base], fields]]}}; RawWords: TYPE ~ RECORD [SEQUENCE COMPUTED CARD OF Word]; RawBits: TYPE ~ RECORD [PACKED SEQUENCE COMPUTED CARD OF BOOL]; CopyRecord: PROC [from, to: ArgFields] ~ { IF from.length # to.length THEN ERROR; FOR i: NAT IN [0 .. from.length) DO ff: Field ~ Fieldify[from[i]]; tf: Field ~ Fieldify[to[i]]; IF ff.bits # tf.bits THEN ERROR; IF tf.bitOffset=ff.bitOffset THEN { fp: LONG POINTER TO RawWords ~ LOOPHOLE[ff.address]; tp: LONG POINTER TO RawWords ~ LOOPHOLE[tf.address]; wds: Size ~ (ff.bits+ff.bitOffset+bitsPerWord-1)/bitsPerWord; FOR j: Size IN [0..wds) DO tp[j] _ fp[j] ENDLOOP; } ELSE { fp: LONG POINTER TO RawBits ~ LOOPHOLE[ff.address]; tp: LONG POINTER TO RawBits ~ LOOPHOLE[tf.address]; fi: CARD _ ff.bitOffset; FOR ti: CARD IN [tf.bitOffset..tf.bitOffset+tf.bits) DO tp[ti] _ fp[fi]; fi _ fi.SUCC; ENDLOOP; }; ENDLOOP; RETURN}; Fieldify: PROC [af: ArgField] RETURNS [Field] ~ { WITH af SELECT FROM direct => RETURN [[address, bitOffset, bits]]; indirect => RETURN [[PM[@ws[0]], bitOffset2, bits2]]; ENDCASE => ERROR}; Argify: PROC [fs: Fields] RETURNS [afs: ArgFields] ~ { afs _ NEW [ArgFieldSeq[fs.length]]; FOR i: NAT IN [0 .. fs.length) DO afs[i] _ [fs[i].address, fs[i].bitOffset, fs[i].bits, direct[]]; ENDLOOP; RETURN}; Seqifields: PUBLIC PROC [fl: FieldList] RETURNS [fs: Fields] ~ { length, i: NAT _ 0; FOR flt: FieldList _ fl, flt.rest WHILE flt#NIL DO length _ length+1 ENDLOOP; fs _ NEW [FieldSeq[length]]; FOR fl _ fl, fl.rest WHILE fl#NIL DO fs[i] _ fl.first; i _ i+1 ENDLOOP; RETURN}; ListCall: PROC [proc: ProcRep, formalArgSizes, formalRetSizes: SizeList, actualArgs, actualRets: FieldList] ~ { Call[proc, formalArgSizes, formalRetSizes, Seqifields[actualArgs], Seqifields[actualRets]]; RETURN}; WordPair: TYPE ~ RECORD [e0, e1: Word]; BitPair: TYPE ~ RECORD [e0, e1: BOOL]; PackedBitPair: TYPE ~ MACHINE DEPENDENT RECORD [e0, e1: BOOL]; PBQ: TYPE ~ PACKED RECORD [p0, p1: PackedBitPair]; EmptyWords: TYPE ~ RECORD []; MixedWords: TYPE ~ RECORD [w1: Word, e2: EmptyWords, w3: Word]; PA16R0T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16: Word]; PA17R0T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17: Word]; PA15R1T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15: Word] RETURNS [Word]; PA16R1T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16: Word] RETURNS [Word]; PA17R1T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17: Word] RETURNS [Word]; PA15R2T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15: Word] RETURNS [ARRAY [0..1] OF Word]; PA16R2T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16: Word] RETURNS [ARRAY [0..1] OF Word]; PA17R2T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17: Word] RETURNS [ARRAY [0..1] OF Word]; PA16dT: TYPE ~ PROC [a1, a2, a3, a4: Word, a56: WordPair, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16: Word] RETURNS [Word]; <> <> <> PAMRMT: TYPE ~ PROC [a1: Word, a23: WordPair, a45: BitPair, a67, a89: PackedBitPair] RETURNS [r1: Word, r23: WordPair, r45: BitPair, r67, r89: PackedBitPair]; PA16R4T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16: Word] RETURNS [ARRAY [0..4) OF Word]; PA16R16T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16: Word] RETURNS [ARRAY [0..16) OF Word]; PA16R64T: TYPE ~ PROC [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16: Word] RETURNS [ARRAY [0..64) OF Word]; Demo: Commander.CommandProc ~ TRUSTED { in: IO.STREAM ~ IO.RIS[cmd.commandLine]; key: REF ANY _ NIL; w2: ARRAY [0..1] OF Word; v2: ARRAY [0..1] OF Word _ [1, 2]; u2: ARRAY [0..1] OF Word _ [3, 4]; t2: ARRAY [0..1] OF Word _ [837, 17701]; x, y: Word _ 47; b2A: BitPair _ [TRUE, FALSE]; b2B: BitPair _ [TRUE, FALSE]; pbX: PackedBitPair _ [FALSE, TRUE]; pbY: PackedBitPair _ [TRUE, FALSE]; pbW: PackedBitPair _ [FALSE, FALSE]; pbZ: PackedBitPair _ [TRUE, TRUE]; ary17: ARRAY [1..17] OF CARDINAL _ ALL[0]; LPA16R0V: PA16R0T ~ {x _ a16}; LPA17R0V: PA17R0T ~ {x _ a17}; LPA15R1V: PA15R1T ~ {RETURN [a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15]}; LPA16R1V: PA16R1T ~ {RETURN [a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15+a16]}; LPA17R1V: PA17R1T ~ {RETURN [a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15+a16+a17]}; LPA15R2V: PA15R2T ~ {RETURN [[a1, a15]]}; LPA16R2V: PA16R2T ~ {RETURN [[a1, a16]]}; LPA17R2V: PA17R2T ~ {RETURN [[a1, a17]]}; LPA17R2Vb: PA17R2T ~ {RETURN [[10, v2[0]]]}; LPA16dV: PA16dT ~ {RETURN [a1+a56.e1+a16]}; LPAMRMV: PAMRMT ~ {RETURN [v2[1], [t2[0], t2[1]], [a67.e0, a67.e1], [a45.e0, a45.e1], a89]}; sa17: SizeList _ NIL; key _ in.GetRefAny[!IO.Error, IO.EndOfStream => CONTINUE]; IF key=NIL THEN RETURN [$Failure, "Usage: GenericCallDemo $key"]; FOR i: NAT IN [1..17] DO ary17[i] _ i; sa17 _ CONS[BITS[Word], sa17] ENDLOOP; w2 _ LPA17R2V[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 16]; <> LPA16R0V[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]; [x, [w2[0], w2[1]]] _ PAMRMV[x, [13, v2[1]], [FALSE, TRUE], [TRUE, FALSE], [FALSE, TRUE]]; SELECT key FROM $la17r2 => { ListCall[ LOOPHOLE[LPA17R2V], sa17, LIST[2*BITS[Word]], LIST[[PM[@ary17[1]], 0, 32], [PM[@ary17[2]], 0, 32], [PM[@ary17[3]], 0, 32], [PM[@ary17[4]], 0, 32], [PM[@ary17[5]], 0, 32], [PM[@ary17[6]], 0, 32], [PM[@ary17[7]], 0, 32], [PM[@ary17[8]], 0, 32], [PM[@ary17[9]], 0, 32], [PM[@ary17[10]], 0, 32], [PM[@ary17[11]], 0, 32], [PM[@ary17[12]], 0, 32], [PM[@ary17[13]], 0, 32], [PM[@ary17[14]], 0, 32], [PM[@ary17[15]], 0, 32], [PM[@ary17[16]], 0, 32], [PM[@ary17[17]], 0, 32] ], LIST[[PM[@u2], 0, 64]] ]; cmd.out.PutFL["After LPA17R2V, u2=[%g, %g] (should=[1, 17])\n", LIST[ [cardinal[u2[0]]], [cardinal[u2[1]]] ]]; }; $la17r1 => { ListCall[ LOOPHOLE[LPA17R1V], sa17, LIST[BITS[Word]], LIST[[PM[@ary17[1]], 0, 32], [PM[@ary17[2]], 0, 32], [PM[@ary17[3]], 0, 32], [PM[@ary17[4]], 0, 32], [PM[@ary17[5]], 0, 32], [PM[@ary17[6]], 0, 32], [PM[@ary17[7]], 0, 32], [PM[@ary17[8]], 0, 32], [PM[@ary17[9]], 0, 32], [PM[@ary17[10]], 0, 32], [PM[@ary17[11]], 0, 32], [PM[@ary17[12]], 0, 32], [PM[@ary17[13]], 0, 32], [PM[@ary17[14]], 0, 32], [PM[@ary17[15]], 0, 32], [PM[@ary17[16]], 0, 32], [PM[@ary17[17]], 0, 32] ], LIST[[PM[@x], 0, 32]] ]; cmd.out.PutFL["After LPA17R1V, x=%g (should=153)\n", LIST[ [cardinal[x]] ]]; }; $la16r1 => { ListCall[ LOOPHOLE[LPA16R1V], sa17.rest, LIST[BITS[Word]], LIST[[PM[@ary17[1]], 0, 32], [PM[@ary17[2]], 0, 32], [PM[@ary17[3]], 0, 32], [PM[@ary17[4]], 0, 32], [PM[@ary17[5]], 0, 32], [PM[@ary17[6]], 0, 32], [PM[@ary17[7]], 0, 32], [PM[@ary17[8]], 0, 32], [PM[@ary17[9]], 0, 32], [PM[@ary17[10]], 0, 32], [PM[@ary17[11]], 0, 32], [PM[@ary17[12]], 0, 32], [PM[@ary17[13]], 0, 32], [PM[@ary17[14]], 0, 32], [PM[@ary17[15]], 0, 32], [PM[@ary17[16]], 0, 32] ], LIST[[PM[@x], 0, 32]] ]; cmd.out.PutFL["After LPA16R1V, x=%g (should=136)\n", LIST[ [cardinal[x]] ]]; }; $lamrm => { cmd.out.PutFL["Before PAMRMV, v2[1]=%g, t2=[%g, %g], b2A=[%g, %g], pbX=[%g, %g]\n", LIST[ [cardinal[v2[1]]], [cardinal[t2[0]]], [cardinal[t2[1]]], [boolean[b2A.e0]], [boolean[b2A.e1]], [boolean[pbX.e0]], [boolean[pbX.e1]] ]]; ListCall[ LOOPHOLE[LPAMRMV], LIST[BITS[Word], BITS[WordPair], BITS[BitPair], BITS[PackedBitPair], BITS[PackedBitPair]], LIST[BITS[Word], BITS[WordPair], BITS[BitPair], BITS[PackedBitPair], BITS[PackedBitPair]], LIST[[PM[@x], 0, 32], [PM[@v2], 0, 64], [PM[@b2A], 0, 64], [PM[@pbX], 30, 2], [PM[@pbY], 30, 2]], LIST[[PM[@y], 0, 32], [PM[@u2], 0, 64], [PM[@b2B], 0, 64], [PM[@pbW], 30, 2], [PM[@pbZ], 30, 2]] ]; cmd.out.PutFL["After LPAMRMV, y=%g, u2=[%g, %g], b2B=[%g, %g], pbW=[%g, %g]\n", LIST[ [cardinal[y]], [cardinal[u2[0]]], [cardinal[u2[1]]], [boolean[b2B.e0]], [boolean[b2B.e1]], [boolean[pbW.e0]], [boolean[pbW.e1]] ]]; }; $ga17r2 => { ListCall[ LOOPHOLE[PA17R2V], sa17, LIST[2*BITS[Word]], LIST[[PM[@ary17[1]], 0, 32], [PM[@ary17[2]], 0, 32], [PM[@ary17[3]], 0, 32], [PM[@ary17[4]], 0, 32], [PM[@ary17[5]], 0, 32], [PM[@ary17[6]], 0, 32], [PM[@ary17[7]], 0, 32], [PM[@ary17[8]], 0, 32], [PM[@ary17[9]], 0, 32], [PM[@ary17[10]], 0, 32], [PM[@ary17[11]], 0, 32], [PM[@ary17[12]], 0, 32], [PM[@ary17[13]], 0, 32], [PM[@ary17[14]], 0, 32], [PM[@ary17[15]], 0, 32], [PM[@ary17[16]], 0, 32], [PM[@ary17[17]], 0, 32] ], LIST[[PM[@u2], 0, 64]] ]; cmd.out.PutFL["After PA17R2V, u2=[%g, %g] (should=[3, 33])\n", LIST[ [cardinal[u2[0]]], [cardinal[u2[1]]] ]]; }; $ga17r1 => { ListCall[ LOOPHOLE[PA17R1V], sa17, LIST[BITS[Word]], LIST[[PM[@ary17[1]], 0, 32], [PM[@ary17[2]], 0, 32], [PM[@ary17[3]], 0, 32], [PM[@ary17[4]], 0, 32], [PM[@ary17[5]], 0, 32], [PM[@ary17[6]], 0, 32], [PM[@ary17[7]], 0, 32], [PM[@ary17[8]], 0, 32], [PM[@ary17[9]], 0, 32], [PM[@ary17[10]], 0, 32], [PM[@ary17[11]], 0, 32], [PM[@ary17[12]], 0, 32], [PM[@ary17[13]], 0, 32], [PM[@ary17[14]], 0, 32], [PM[@ary17[15]], 0, 32], [PM[@ary17[16]], 0, 32], [PM[@ary17[17]], 0, 32] ], LIST[[PM[@y], 0, 32]] ]; cmd.out.PutFL["After PA17R1V, y=%g (should=18)\n", LIST[ [cardinal[y]] ]]; }; $ga16r1 => { ListCall[ LOOPHOLE[PA16R1V], sa17.rest, LIST[BITS[Word]], LIST[[PM[@ary17[1]], 0, 32], [PM[@ary17[2]], 0, 32], [PM[@ary17[3]], 0, 32], [PM[@ary17[4]], 0, 32], [PM[@ary17[5]], 0, 32], [PM[@ary17[6]], 0, 32], [PM[@ary17[7]], 0, 32], [PM[@ary17[8]], 0, 32], [PM[@ary17[9]], 0, 32], [PM[@ary17[10]], 0, 32], [PM[@ary17[11]], 0, 32], [PM[@ary17[12]], 0, 32], [PM[@ary17[13]], 0, 32], [PM[@ary17[14]], 0, 32], [PM[@ary17[15]], 0, 32], [PM[@ary17[16]], 0, 32] ], LIST[[PM[@y], 0, 32]] ]; cmd.out.PutFL["After PA16R1V, y=%g (should=34)\n", LIST[ [cardinal[y]] ]]; }; $gamrm => { cmd.out.PutFL["Before PAMRMV, x=%g, v2=[%g, %g], b2A=[%g, %g], pbX=[%g, %g]\n", LIST[ [cardinal[x]], [cardinal[v2[0]]], [cardinal[v2[1]]], [boolean[b2A.e0]], [boolean[b2A.e1]], [boolean[pbX.e0]], [boolean[pbX.e1]] ]]; ListCall[ LOOPHOLE[PAMRMV], LIST[BITS[Word], BITS[WordPair], BITS[BitPair], BITS[PackedBitPair], BITS[PackedBitPair]], LIST[BITS[Word], BITS[WordPair], BITS[BitPair], BITS[PackedBitPair], BITS[PackedBitPair]], LIST[[PM[@x], 0, 32], [PM[@v2], 0, 64], [PM[@b2A], 0, 64], [PM[@pbX], 30, 2], [PM[@pbY], 30, 2]], LIST[[PM[@y], 0, 32], [PM[@u2], 0, 64], [PM[@b2B], 0, 64], [PM[@pbW], 30, 2], [PM[@pbZ], 30, 2]] ]; cmd.out.PutFL["After PAMRMV, x=%g, v2=[%g, %g], b2A=[%g, %g], pbX=[%g, %g]\n", LIST[ [cardinal[x]], [cardinal[v2[0]]], [cardinal[v2[1]]], [boolean[b2A.e0]], [boolean[b2A.e1]], [boolean[pbX.e0]], [boolean[pbX.e1]] ]]; cmd.out.PutFL["After PAMRMV, y=%g, u2=[%g, %g], b2B=[%g, %g], pbW=[%g, %g]\n", LIST[ [cardinal[y]], [cardinal[u2[0]]], [cardinal[u2[1]]], [boolean[b2B.e0]], [boolean[b2B.e1]], [boolean[pbW.e0]], [boolean[pbW.e1]] ]]; }; ENDCASE => cmd.out.PutRope["$key should be one of: $la17r2, $la17r1, $la16r1, $lamrm, $ga17r2, $ga17r1, $ga16r1, $gamrm.\n"]; RETURN}; PA16R0V: PA16R0T ~ {mw.w1 _ a16}; PA17R0V: PA17R0T ~ {mw.w1 _ a17}; PA15R1V: PA15R1T ~ {RETURN [a1+a15]}; PA16R1V: PA16R1T ~ {RETURN [a1+a2+a15+a16]}; PA17R1V: PA17R1T ~ {RETURN [a1+a17]}; PA15R2V: PA15R2T ~ {RETURN [[a1, a15]]}; PA16R2V: PA16R2T ~ {RETURN [[a1, a16]]}; PA17R2V: PA17R2T ~ {RETURN [[a1+a2, a16+a17]]}; PA16dV: PA16dT ~ {RETURN [a1+a56.e1+a16]}; <> <> PAMRMV: PAMRMT ~ {RETURN [a23.e0, [a23.e1, a1], [a67.e0, a67.e1], [a45.e0, a45.e1], a89]}; mw: MixedWords _ [7, [], 3]; Commander.Register["GenericCallDemo", Demo, "- for internal use only"]; END.