GenericCallImpl.mesa
Last tweaked by Mike Spreitzer on December 18, 1989 4:31:07 pm PST
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]
Use this instead of CM when syntactic type of actual arg is INT and arg is expected to be fit in NAT; the call effects the bounds check.
~ INLINE {RETURN [c]};
NiM: PROC [i: INT] RETURNS [Pointer]
Use this instead of IM when syntactic type of actual arg is CARD and arg is expected to be fit in NAT; the call effects the bounds check.
~ 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];
PA16eT: TYPE ~ PROC [a1, a2, a3, a4: Word, a5: EmptyWords, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16: Word] RETURNS [Word];
PA17eT: TYPE ~ PROC [a1, a2, a3, a4: Word, a5: EmptyWords, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17: Word] RETURNS [Word];
PA1RMT: TYPE ~ PROC [a1: Word] RETURNS [w1: Word, e2: EmptyWords, w3: 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 ANYNIL;
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 CARDINALALL[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];
v2 ← LPA17R2Vb[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]};
PA16eV: PA16eT ~ {RETURN [a1+a16]};
PA17eV: PA17eT ~ {RETURN [a1+a17]};
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.