TestBB.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Willie-Sue, September 12, 1986 4:55:02 pm PDT
DIRECTORY
AllocatorOps,
Basics,
Commander,
CommandTool,
Convert,
CountedVM USING [Handle, Free, SimpleAllocate],
IO,
Rope,
SampleMapOps,
SlowSampleMapOps,
Process,
PrincOps,
Random,
SafeStorage USING [ReclaimCollectibleObjects];
TestBB: CEDAR PROGRAM
IMPORTS
SampleMapOps, SlowSampleMapOps,
AllocatorOps, Basics, Commander, CommandTool, Convert, CountedVM, IO,
Process, Random, SafeStorage
~ BEGIN OPEN SampleMapOps;
AnotEqSA: SIGNAL[which: ATOM] = CODE;
BnotEqSB: SIGNAL[which: ATOM] = CODE;
DoubleCopyFailed: SIGNAL[first, num: LONG CARDINAL] = CODE;
LastOp: TYPE = {none, putSample, move, transfer, fill, tile, rotate};
lastOp: LastOp;
simplePattern: BOOLFALSE;
CountVec: TYPE = ARRAY LastOp OF INT;
doOpCountVec: CountVec;
wordsPerPage: NAT = PrincOps.wordsPerPage;
LongTest: PROC [cmd: Commander.Handle ← NIL, n: INT ← 100, m: INT ← 100,
 seed: INT ← 31415, maxSize: NAT ← 2048] RETURNS[CountVec] ~ {
BEGIN ENABLE ABORTED => GOTO exit;
random: Random.RandomStream ← Random.Create[seed: seed];
SkewedRand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ {
RETURN [random.ChooseInt[0, max]*random.ChooseInt[0, max]/max+1]
};
doOpCountVec ← [0, 0, 0, 0, 0, 0, 0];
FOR i: INT IN [0..n) DO
bitsPerSample: CARDINAL ← random.ChooseInt[1, 16];
aSize: CVEC ~ [SkewedRand[maxSize], SkewedRand[maxSize]];
bSize: CVEC ~ [SkewedRand[(maxSize+1)/2], SkewedRand[(maxSize+2)/3]];
a: SampleMap;
b: SampleMap;
t1, st1: SampleMap;
nWords: LONG CARDINAL;
IF cmd # NIL THEN cmd.out.PutChar[IF i MOD 10 = 0 THEN '! ELSE '~];
a ← SlowSampleMapOps.Create[sSize: aSize.s, fSize: aSize.f, bitsPerSample: bitsPerSample];
b ← SlowSampleMapOps.Create[sSize: bSize.s, fSize: bSize.f, bitsPerSample: bitsPerSample];
t1 ← SlowSampleMapOps.CreateZ[sSize: aSize.s, fSize: aSize.f, bitsPerSample: bitsPerSample];
st1 ← SlowSampleMapOps.CreateZ[sSize: aSize.s, fSize: aSize.f, bitsPerSample: bitsPerSample];
RunTest[a, b, seed, m];
a ← b ← NIL;
RunTest[a, b, t1, st1, seed, m, nWords];
a ← b ← t1 ← st1 ← NIL;
SafeStorage.ReclaimCollectibleObjects[suspendMe: FALSE];
ENDLOOP;
EXITS
exit => NULL;
END;
RETURN[doOpCountVec];
};
RunTest: PROC [a, b: SampleMap, seed: INT ← 314159, n: INT ← 1000] ~ {
a, b, t1, st1: SampleMap, seed: INT ← 314159, n: INT ← 1000, nWords: LONG CARDINAL] ~ {
random: Random.RandomStream ← Random.Create[seed: seed];
sa, sb: SampleMap;
num, first: LONG CARDINAL;
try a real simple things first
SlowSampleMapOps.DoubleCopy[to: t1, slowTo: st1, from: a, destStart: [0, 0]];
[first, num] ← TestEquality[t1, st1, nWords];
IF num # 0 THEN SIGNAL DoubleCopyFailed[first, num];
AddressInit[a, 1, Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo];
AddressInit[b, -1, Basics.DoubleShiftRight[LOOPHOLE[b.base.word], 8].lo];
sa ← SlowSampleMapOps.Copy[[a]];
IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$first];
sb ← SlowSampleMapOps.Copy[[b]];
IF NOT Equal[[sb],[b]] THEN SIGNAL BnotEqSB[$first];
IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterSb];
FOR i: INT IN [0..n) DO
rand: CARDINAL ← random.ChooseInt[0, CARDINAL.LAST];
function: Function;
op: LastOp;
IF simplePattern THEN {
ax: WORD;
AddressInit[a, 1, ax ← Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo];
AddressInit[sa, 1, ax];
AddressInit[b, -1, ax ← Basics.DoubleShiftRight[LOOPHOLE[b.base.word], 8].lo];
AddressInit[sb, -1, ax];
};
[function, op] ← DoOp[a, b, sa, sb, rand];
IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterDoOp];
IF NOT Equal[[sb],[b]] THEN SIGNAL BnotEqSB[$afterDoOp];
{t: SampleMap ← a; a ← b; b ← t};
{t: SampleMap ← sa; sa ← sb; sb ← t};
Process.CheckForAbort[];
ENDLOOP;
FreeCountedVM[a, b, sa, sb];
a ← b ← sa ← sb ← NIL;
};
SkewTest: PROC [cmd: Commander.Handle ← NIL, n: INT ← 100, m: INT ← 100,
 seed: INT ← 31415, maxSize: NAT ← 2048] RETURNS[CountVec] ~ {
BEGIN ENABLE ABORTED => GOTO exit;
random: Random.RandomStream ← Random.Create[seed: seed];
SkewedRand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ {
RETURN [random.ChooseInt[0, max]*random.ChooseInt[0, max]/max+1]
};
doOpCountVec ← [0, 0, 0, 0, 0, 0, 0];
FOR i: INT IN [0..n) DO
bitsPerSample: CARDINAL ← random.ChooseInt[1, 16];
aSize: CVEC ~ [SkewedRand[maxSize], SkewedRand[maxSize]];
bSize: CVEC ~ [SkewedRand[(maxSize+1)/2], SkewedRand[(maxSize+2)/3]];
a: SampleMap;
b: SampleMap;
IF cmd # NIL THEN cmd.out.PutChar[IF i MOD 10 = 0 THEN '! ELSE '~];
-- FunnyCreate makes odd sized SampleMaps
a ← FunnyCreate[sSize: aSize.s, fSize: aSize.f, bitsPerSample: bitsPerSample];
b ← FunnyCreate[sSize: bSize.s, fSize: bSize.f, bitsPerSample: bitsPerSample];
RunSkewTest[a, b, seed, m];
a ← b ← NIL;
SafeStorage.ReclaimCollectibleObjects[suspendMe: FALSE];
ENDLOOP;
EXITS
exit => NULL;
END;
RETURN[doOpCountVec];
};
RunSkewTest: PROC [a, b: SampleMap, seed: INT ← 314159, n: INT ← 1000] ~ {
random: Random.RandomStream ← Random.Create[seed: seed];
sa, sb: SampleMap;
AddressInit[a, 1, Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo];
AddressInit[b, -1, Basics.DoubleShiftRight[LOOPHOLE[b.base.word], 8].lo];
sa ← SlowSampleMapOps.Copy[[a]];
IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$first];
sb ← SlowSampleMapOps.Copy[[b]];
IF NOT Equal[[sb],[b]] THEN SIGNAL BnotEqSB[$first];
IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterSb];
FOR i: INT IN [0..n) DO
rand: CARDINAL ← random.ChooseInt[0, CARDINAL.LAST];
function: Function;
op: LastOp;
IF simplePattern THEN {
ax: WORD;
AddressInit[a, 1, ax ← Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo];
AddressInit[sa, 1, ax];
AddressInit[b, -1, ax ← Basics.DoubleShiftRight[LOOPHOLE[b.base.word], 8].lo];
AddressInit[sb, -1, ax];
};
[function, op] ← DoSkewOp[a, b, sa, sb, rand];
IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterDoOp];
IF NOT Equal[[sb],[b]] THEN SIGNAL BnotEqSB[$afterDoOp];
{t: SampleMap ← a; a ← b; b ← t};
{t: SampleMap ← sa; sa ← sb; sb ← t};
Process.CheckForAbort[];
ENDLOOP;
FreeCountedVM[a, b, sa, sb];
a ← b ← sa ← sb ← NIL;
};
DoFillTest: PROC[cmd: Commander.Handle ← NIL, n: INT ← 100,
 seed: INT ← 31415, maxSize: NAT ← 2048] RETURNS[count: INT] ~ {
BEGIN ENABLE ABORTED => GOTO exit;
random: Random.RandomStream ← Random.Create[seed: seed];
SkewedRand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ {
RETURN [random.ChooseInt[0, max]*random.ChooseInt[0, max]/max+1]
};
count ← 0;
FOR i: INT IN [0..n) DO
bitsPerSample: CARDINAL ← random.ChooseInt[1, 4];
aSize: CVEC ~ [SkewedRand[maxSize], SkewedRand[maxSize]];
bSize: CVEC ~ [SkewedRand[(maxSize+1)/2], SkewedRand[(maxSize+2)/3]];
a, sa, b, sb: SampleMap;
IF cmd # NIL THEN cmd.out.PutChar[IF i MOD 10 = 0 THEN '! ELSE '~];
a ← SlowSampleMapOps.Create[sSize: aSize.s, fSize: aSize.f, bitsPerSample: bitsPerSample];
b ← SlowSampleMapOps.Create[sSize: bSize.s, fSize: bSize.f, bitsPerSample: bitsPerSample];
AddressInit[a, 1, Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo];
AddressInit[b, -1, Basics.DoubleShiftRight[LOOPHOLE[b.base.word], 8].lo];
sa ← SlowSampleMapOps.Copy[[a]];
IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$first];
sb ← SlowSampleMapOps.Copy[[b]];
IF NOT Equal[[sb],[b]] THEN SIGNAL BnotEqSB[$first];
IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterSb];
AlwaysDoFill[a, b, sa, sb, seed];
IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterDoFill];
a ← b ← NIL;
count ← count + 1;
ENDLOOP;
EXITS
exit => NULL;
END;
};
DoOp: PROC [a, b, sa, sb: SampleMap, seed: CARDINAL]
RETURNS[function: Function, lop: LastOp] ~ {
Rand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ {
seed ← seed * 3141 + 3;
RETURN [Basics.HighHalf[Basics.LongMult[max+1, seed]]];
};
RandV: PROC [max: CVEC] RETURNS [CVEC] ~ {RETURN [[Rand[max.s], Rand[max.f]]]};
aMin: CVEC ~ [Rand[a.sSize], Rand[a.fSize]];
aSize: CVEC ~ [Rand[a.sSize-aMin.s], Rand[a.fSize-aMin.f]];
ad: CVEC ~ [Rand[a.sSize-aSize.s], Rand[a.fSize-aSize.f]];
bMin: CVEC ~ [Rand[b.sSize-1], Rand[b.fSize-1]];
bSize: CVEC ~ [Rand[b.sSize-bMin.s-1]+1, Rand[b.fSize-bMin.f-1]+1];
value: CARDINAL ← Rand[Basics.BITSHIFT[1, a.bitsPerSample]-1];
op: NAT = Rand[5];
function ← [VAL[Rand[3]], VAL[Rand[1]]];
SELECT op FROM
0 => IF a.sSize > 0 AND a.fSize > 0 THEN {
randVec: CVEC = RandV[[a.sSize-1, a.fSize-1]];
PutSample[sampleMap: a, index: randVec, value: value, function: function];
SlowSampleMapOps.PutSample[sampleMap: sa, index: randVec, value: value, function: function, goodDest: a];
lastOp ← putSample;
} ELSE lastOp ← none;
1 => {
Move[sampleMap: a, destStart: aMin, sourceStart: ad, size: aSize, function: function];
SlowSampleMapOps.Move[sampleMap: sa, destStart: aMin, sourceStart: ad, size: aSize, function: function, goodDest: a];
lastOp ← move;
};
2 => {
Transfer[dest: a, destStart: aMin, source: [b, bMin, bSize], function: function];
SlowSampleMapOps.Transfer[dest: sa, destStart: aMin, source: [sb, bMin, bSize], function: function, goodDest: a];
lastOp ← transfer;
};
3 => {
IF value = 0 THEN value ← 123456B;  -- don't want 0 gray fill
Fill[dest: [a, aMin, aSize], value: value, function: function];
SlowSampleMapOps.Fill[dest: [sa, aMin, aSize], value: value, function: function, goodDest: [a, aMin, aSize] ];
lastOp ← fill;
};
4 => {
s0: INTEGERINTEGER[Rand[100]]-50;
f0: INTEGERINTEGER[Rand[100]]-50;
phase: NAT ← Rand[bSize.f]*Rand[1];
tile: SampleMap ~ FromSubMap[[b, bMin, bSize]];
slowTile: SampleMap ~ FromSubMap[[sb, bMin, bSize]];
IF tile.sSize > 0 AND tile.fSize > 0 THEN {
lastOp ← tile;
TileBox[dest: a, start: aMin, size: aSize, source: tile, s0: s0, f0: f0, phase: phase, function: function];
SlowSampleMapOps.TileBox[dest: sa, start: aMin, size: aSize, source: slowTile, s0: s0, f0: f0, phase: phase, function: function, goodDest: a];
} ELSE lastOp ← none;
};
5 => {
Rot[FromSubMap[[a, aMin, aSize]], FromSubMap[[b, bMin, bSize]],
FromSubMap[[sa, aMin, aSize]], FromSubMap[[b, bMin, bSize]] ];
lastOp ← rotate;
};
ENDCASE => ERROR;
doOpCountVec[lastOp] ← doOpCountVec[lastOp] + 1;
RETURN[function, lastOp];
};
FreeCountedVM: PROC[a, b, c, d: SampleMap] = TRUSTED {
WITH a.ref SELECT FROM
x: CountedVM.Handle => CountedVM.Free[x];
ENDCASE => NULL;
WITH b.ref SELECT FROM
x: CountedVM.Handle => CountedVM.Free[x];
ENDCASE => NULL;
WITH c.ref SELECT FROM
x: CountedVM.Handle => CountedVM.Free[x];
ENDCASE => NULL;
WITH d.ref SELECT FROM
x: CountedVM.Handle => CountedVM.Free[x];
ENDCASE => NULL;
a.ref ← b.ref ← c.ref ← d.ref ← NIL;
};
FunnyCreate: PROC [sSize: CARDINAL, fSize: CARDINAL, bitsPerSample: [0..Basics.bitsPerWord]] RETURNS [SampleMap] ~ {
bitsPerLine: NAT ~ Basics.LongMult[fSize, bitsPerSample];
nWords: LONG CARDINAL ~ (Basics.LongMult[sSize, bitsPerLine]+15)/16;
vm: CountedVM.Handle ~ CountedVM.SimpleAllocate[words: nWords];
TRUSTED {RETURN [UnsafeCreate[
sSize: sSize,
fSize: fSize,
bitsPerSample: bitsPerSample,
bitsPerLine: bitsPerLine,
base: [word: vm.pointer, bit: 0],
nWords: vm.words,
ref: vm
]]};
};
Rot: PROC [a, b, sa, sb: SampleMap] ~ {
rowSize: NAT ~ MIN[a.sSize, b.fSize];
buf: Buffer ~ ObtainBuffer[rowSize];
IF rowSize > 0 THEN FOR i: NAT IN [0..MIN[a.fSize, b.sSize]) DO
Get[buffer: buf, sampleMap: b, s: i];
Flip[buf];
Put[buffer: buf, sampleMap: a, s: 0, f: i, ds: 1, df: 0];
Get[buffer: buf, sampleMap: sb, s: i];
Flip[buf];
SlowSampleMapOps.Put[buffer: buf, sampleMap: sa, s: 0, f: i, ds: 1, df: 0, goodDest: a];
ENDLOOP;
ReleaseBuffer[buf];
};
SkewRotate: PROC [a, b, sa, sb: SampleMap] ~ {
rowSize: NAT ~ MIN[a.sSize, b.fSize];
buf: Buffer ~ ObtainBuffer[rowSize];
IF rowSize > 0 THEN FOR i: NAT IN [0..MIN[a.fSize, b.sSize]) DO
Get[buffer: buf, sampleMap: b, s: i];
Flip[buf];
Put[buffer: buf, sampleMap: a, s: 0, f: i, ds: 1, df: 0];
Get[buffer: buf, sampleMap: sb, s: i];
Flip[buf];
SlowSampleMapOps.Put[buffer: buf, sampleMap: sa, s: 0, f: i, ds: 1, df: 0, goodDest: NIL];
ENDLOOP;
ReleaseBuffer[buf];
};
AlwaysDoFill: PROC [a, b, sa, sb: SampleMap, seed: CARDINAL] ~ {
Rand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ {
seed ← seed * 3141 + 3;
RETURN [Basics.HighHalf[Basics.LongMult[max+1, seed]]];
};
RandV: PROC [max: CVEC] RETURNS [CVEC] ~ {RETURN [[Rand[max.s], Rand[max.f]]]};
aMin: CVEC ~ [Rand[a.sSize], Rand[a.fSize]];
aSize: CVEC ~ [Rand[a.sSize-aMin.s], Rand[a.fSize-aMin.f]];
ad: CVEC ~ [Rand[a.sSize-aSize.s], Rand[a.fSize-aSize.f]];
bMin: CVEC ~ [Rand[b.sSize-1], Rand[b.fSize-1]];
bSize: CVEC ~ [Rand[b.sSize-bMin.s-1]+1, Rand[b.fSize-bMin.f-1]+1];
value: CARDINAL ← Rand[Basics.BITSHIFT[1, a.bitsPerSample]-1];
function: Function ← [null, complement];
IF value = 0 THEN value ← 123456B;  -- don't want 0 gray fill
Fill[dest: [a, aMin, aSize], value: value, function: function];
SlowSampleMapOps.Fill[dest: [sa, aMin, aSize], value: value, function: function, goodDest: [a, aMin, aSize] ];
};
DoSkewOp: PROC [a, b, sa, sb: SampleMap, seed: CARDINAL]
RETURNS[function: Function, lop: LastOp] ~ {
Rand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ {
seed ← seed * 3141 + 3;
RETURN [Basics.HighHalf[Basics.LongMult[max+1, seed]]];
};
RandV: PROC [max: CVEC] RETURNS [CVEC] ~ {RETURN [[Rand[max.s], Rand[max.f]]]};
aMin: CVEC ~ [Rand[a.sSize], Rand[a.fSize]];
aSize: CVEC ~ [Rand[a.sSize-aMin.s], Rand[a.fSize-aMin.f]];
ad: CVEC ~ [Rand[a.sSize-aSize.s], Rand[a.fSize-aSize.f]];
bMin: CVEC ~ [Rand[b.sSize-1], Rand[b.fSize-1]];
bSize: CVEC ~ [Rand[b.sSize-bMin.s-1]+1, Rand[b.fSize-bMin.f-1]+1];
value: CARDINAL ← Rand[Basics.BITSHIFT[1, a.bitsPerSample]-1];
op: NAT = Rand[5];
function ← [VAL[Rand[3]], VAL[Rand[1]]];
SELECT op FROM
0 => IF a.sSize > 0 AND a.fSize > 0 THEN {
randVec: CVEC = RandV[[a.sSize-1, a.fSize-1]];
PutSample[sampleMap: a, index: randVec, value: value, function: function];
SlowSampleMapOps.PutSample[sampleMap: sa, index: randVec, value: value, function: function, goodDest: NIL];
lastOp ← putSample;
} ELSE lastOp ← none;
1 => {
Move[sampleMap: a, destStart: aMin, sourceStart: ad, size: aSize, function: function];
SlowSampleMapOps.Move[sampleMap: sa, destStart: aMin, sourceStart: ad, size: aSize, function: function, goodDest: NIL];
lastOp ← move;
};
2 => {
Transfer[dest: a, destStart: aMin, source: [b, bMin, bSize], function: function];
SlowSampleMapOps.Transfer[dest: sa, destStart: aMin, source: [sb, bMin, bSize], function: function, goodDest: NIL];
lastOp ← transfer;
};
3 => {
IF value = 0 THEN value ← 123456B;  -- don't want 0 gray fill
Fill[dest: [a, aMin, aSize], value: value, function: function];
SlowSampleMapOps.Fill[dest: [sa, aMin, aSize], value: value, function: function, goodDest: [NIL, [0, 0], [0, 0] ] ];
lastOp ← fill;
};
4 => {
s0: INTEGERINTEGER[Rand[100]]-50;
f0: INTEGERINTEGER[Rand[100]]-50;
phase: NAT ← Rand[bSize.f]*Rand[1];
tile: SampleMap ~ FromSubMap[[b, bMin, bSize]];
slowTile: SampleMap ~ FromSubMap[[sb, bMin, bSize]];
IF tile.sSize > 0 AND tile.fSize > 0 THEN {
lastOp ← tile;
TileBox[dest: a, start: aMin, size: aSize, source: tile, s0: s0, f0: f0, phase: phase, function: function];
SlowSampleMapOps.TileBox[dest: sa, start: aMin, size: aSize, source: slowTile, s0: s0, f0: f0, phase: phase, function: function, goodDest: NIL];
} ELSE lastOp ← none;
};
5 => {
SkewRotate[FromSubMap[[a, aMin, aSize]], FromSubMap[[b, bMin, bSize]],
FromSubMap[[sa, aMin, aSize]], FromSubMap[[b, bMin, bSize]] ];
lastOp ← rotate;
};
ENDCASE => ERROR;
doOpCountVec[lastOp] ← doOpCountVec[lastOp] + 1;
RETURN[function, lastOp];
};
AddressInit: PROC[a: SampleMap, inc: INTEGER, value: WORD] = TRUSTED {
sBase: LONG POINTER TO WORDLOOPHOLE[a.base.word];
wordsRemaining, nWords: LONG CARDINAL;
WITH a.ref SELECT FROM
x: CountedVM.Handle => nWords ← x.words;
ENDCASE => nWords ←
SampleMapOps.ComputeWords[sSize: a.sSize, fSize: a.fSize, bitsPerSample: a.bitsPerSample];
IF nWords < 256 THEN {
FOR j: LONG CARDINAL IN [0..nWords) DO
sBase^ ← value;
sBase ← sBase + 1;
value ← value + inc;
ENDLOOP;
RETURN
};
FOR i: LONG CARDINAL ← 0, i+wordsPerPage UNTIL i >= nWords - 1 DO
this: WORD ← value;
IF nWords >= 511 THEN IF AllocatorOps.quantumMap[LOOPHOLE[value]] THEN ERROR;
IF wordsRemaining < wordsPerPage THEN {
FOR j: LONG CARDINAL IN [0..wordsRemaining) DO
sBase^ ← this;
sBase ← sBase + 1;
this ← this + inc;
ENDLOOP
}
ELSE { FOR j: INTEGER IN [0..wordsPerPage) DO
sBase^ ← this;
sBase ← sBase + 1;
this ← this + inc;
ENDLOOP;
};
value ← value + 1;
wordsRemaining ← wordsRemaining - wordsPerPage;
ENDLOOP;
};
MakeAddressPattern: PROC[a, sa: SampleMap, inc: INTEGER] = TRUSTED {
sBase: LONG POINTER TO WORDLOOPHOLE[a.base.word];
tBase: LONG POINTER TO WORDLOOPHOLE[sa.base.word];
value: WORD ← Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo;
nWords: LONG CARDINAL =
SampleMapOps.ComputeWords[sSize: a.sSize, fSize: a.fSize, bitsPerSample: a.bitsPerSample];
wordsRemaining: LONG CARDINAL ← nWords;
IF nWords < 256 THEN {
FOR j: LONG CARDINAL IN [0..nWords) DO
sBase^ ← tBase^ ← value;
sBase ← sBase + 1;
tBase ← tBase + 1;
value ← value + inc;
ENDLOOP;
RETURN
};
FOR i: LONG CARDINAL ← 0, i+wordsPerPage UNTIL i >= nWords - 1 DO
this: WORD ← value;
IF nWords >= 511 THEN IF AllocatorOps.quantumMap[LOOPHOLE[value]] THEN ERROR;
IF wordsRemaining < wordsPerPage THEN {
FOR j: LONG CARDINAL IN [0..wordsRemaining) DO
sBase^ ← tBase^ ← this;
sBase ← sBase + 1;
tBase ← tBase + 1;
this ← this + inc;
ENDLOOP
}
ELSE { FOR j: INTEGER IN [0..wordsPerPage) DO
sBase^ ← tBase^ ← this;
sBase ← sBase + 1;
tBase ← tBase + 1;
this ← this + inc;
ENDLOOP;
};
wordsRemaining ← wordsRemaining - wordsPerPage;
value ← value + 1;
ENDLOOP;
};
MakeSimpleUpPattern: PROC[a, sa: SampleMap] = TRUSTED {
sBase: LONG POINTER TO WORDLOOPHOLE[a.base.word];
tBase: LONG POINTER TO WORDLOOPHOLE[sa.base.word];
nWords: LONG CARDINAL =
SampleMapOps.ComputeWords[sSize: a.sSize, fSize: a.fSize, bitsPerSample: a.bitsPerSample];
FOR i: LONG CARDINAL IN [0.. nWords) DO
sBase^ ← tBase^ ← LOOPHOLE[i, Basics.LongNumber].lo;
sBase ← sBase + 1;
tBase ← tBase + 1;
ENDLOOP;
};
MakeSimpleDownPattern: PROC[a, sa: SampleMap] = TRUSTED {
sBase: LONG POINTER TO WORDLOOPHOLE[a.base.word];
tBase: LONG POINTER TO WORDLOOPHOLE[sa.base.word];
nWords: LONG CARDINAL =
SampleMapOps.ComputeWords[sSize: a.sSize, fSize: a.fSize, bitsPerSample: a.bitsPerSample];
val: WORD ← 177777B;
FOR i: LONG CARDINAL IN [0.. nWords) DO
sBase^ ← tBase^ ← val;
sBase ← sBase + 1;
tBase ← tBase + 1;
val ← val - 1;
ENDLOOP;
};
MakePattern: PROC[s, t: SampleMap, nWords: LONG CARDINAL, value: WORD] = TRUSTED {
sBase: LONG POINTER TO WORDLOOPHOLE[s.base.word];
tBase: LONG POINTER TO WORDLOOPHOLE[t.base.word];
alt: WORDIF value = 0 THEN 0 ELSE Basics.BITNOT[value];
alt2: WORDIF value = 0 THEN 0 ELSE Basics.BITSHIFT[value, -3];
temp: WORD ← alt2;
FOR i: LONG CARDINAL IN [0..nWords/2) DO
sBase^ ← value;
tBase^ ← value;
sBase ← sBase + 1;
tBase ← tBase + 1;
sBase^ ← alt;
tBase^ ← alt;
sBase ← sBase + 1;
tBase ← tBase + 1;
temp ← value;
value ← alt;
alt ← alt2;
alt2 ← temp;
ENDLOOP;
};
ReallyCopy: PROC[from, to: SampleMap, nWords: INT] = TRUSTED {
fromBase: LONG POINTER TO WORDLOOPHOLE[from.base.word];
toBase: LONG POINTER TO WORDLOOPHOLE[to.base.word];
FOR i: INT IN [0..nWords) DO
toBase^ ← fromBase^;
toBase ← toBase + 1;
fromBase ← fromBase + 1;
ENDLOOP;
};
TestEquality: PROC[a, sa: SampleMap, nWords: LONG CARDINAL]
RETURNS[firstBad, num: LONG CARDINAL] = TRUSTED {
aBase: LONG POINTER TO WORDLOOPHOLE[a.base.word];
saBase: LONG POINTER TO WORDLOOPHOLE[sa.base.word];
firstBad ← num ← 0;
FOR i: LONG CARDINAL IN [0..nWords) DO
IF aBase^ # saBase^ THEN IF (num ← num + 1) = 1 THEN firstBad ← i;
aBase ← aBase + 1;
saBase ← saBase + 1;
ENDLOOP;
};
Srt: Commander.CommandProc = {
cv: CountVec;
m, n: INT ← 0;
[] ← CommandTool.Parse[cmd];
m ← IntFromCmd[cmd];
IF m = -1 THEN RETURN;
n ← IntFromCmd[cmd];
IF n = -1 THEN RETURN;
cv ← LongTest[cmd, m, n];
cmd.out.PutF["\nnone: %g, putSample: %g, move: %g, transfer: %g, ",
IO.int[cv[none]], IO.int[cv[putSample]], IO.int[cv[move]], IO.int[cv[transfer]] ];
cmd.out.PutF["fill: %g, tile: %g, rotate: %g\n",
IO.int[cv[fill]], IO.int[cv[tile]], IO.int[cv[rotate]] ];
};
Skew: Commander.CommandProc = {
cv: CountVec;
m, n: INT ← 0;
[] ← CommandTool.Parse[cmd];
m ← IntFromCmd[cmd];
IF m = -1 THEN RETURN;
n ← IntFromCmd[cmd];
IF n = -1 THEN RETURN;
cv ← SkewTest[cmd, m, n];
cmd.out.PutF["\nnone: %g, putSample: %g, move: %g, transfer: %g, ",
IO.int[cv[none]], IO.int[cv[putSample]], IO.int[cv[move]], IO.int[cv[transfer]] ];
cmd.out.PutF["fill: %g, tile: %g, rotate: %g\n",
IO.int[cv[fill]], IO.int[cv[tile]], IO.int[cv[rotate]] ];
};
FillTest: Commander.CommandProc = {
n, done: INT ← 0;
[] ← CommandTool.Parse[cmd];
n ← IntFromCmd[cmd];
IF n = -1 THEN RETURN;
done ← DoFillTest[cmd, n];
cmd.out.PutF["\n %g fill tests done\n", IO.int[done] ];
};
IntFromCmd: PROC[cmd: Commander.Handle] RETURNS[n: INT] = {
arg: Rope.ROPE = CommandTool.NextArgument[cmd];
n ← -1;
n ← Convert.IntFromRope[arg ! Convert.Error => CONTINUE ];
IF n = -1 THEN
cmd.out.PutF["\nCouldn't parse \"%g\" as a number - quitting\n", IO.rope[arg] ]
};
Commander.Register["srt", Srt, "Run tests of BitBltOpsImpl"];
Commander.Register["skew", Skew, "Run skew tests of BitBltOpsImpl"];
Commander.Register["fill", FillTest, "Run fill tests of BitBltOpsImpl"];
END.