RasterOpTileImpl.meta
Copyright Ó 1988, 1989, 1991, 1992 by Xerox Corporation. All rights reserved.
Michael Plass, October 1, 1991 11:22 am PDT
Willie-s, June 13, 1991 3:41 pm PDT
DIRECTORY Basics, RasterBasics, RasterOp;
RasterOpTileImpl: PROGRAM
IMPORTS Basics
EXPORTS RasterOp
~ BEGIN OPEN Basics;
DstFunc: TYPE ~ RasterBasics.DstFunc;
SrcFunc: TYPE ~ RasterBasics.SrcFunc;
BitAddress: TYPE ~ RasterBasics.BitAddress;
RawWords: TYPE ~ Basics.RawWords;
bpw: CARDINAL ~ BITS[WORD];
WordsForBits: PROC [bits: CARDINAL] RETURNS [CARDINAL] ~ INLINE {
RETURN [CARDINAL[bits+(bpw-1)]/bpw]
};
WordFloorUnitsForBits: PROC [bits: CARDINAL] RETURNS [CARDINAL] ~ INLINE {
RETURN [(CARDINAL[bits]/bpw)*CARDINAL[UNITS[WORD]]]
};
rightJustifiedOnes: ARRAY [0..bpw] OF WORD ~ InitRightJustifiedOnes[];
InitRightJustifiedOnes: PROC RETURNS [a: ARRAY [0..bpw] OF WORD] ~ {
m: WORD ¬ 0;
FOR n: CARDINAL IN [0..bpw] DO
a[n] ¬ m;
m ¬ m+m+1;
ENDLOOP;
};
RightJustifiedOnes: PROC [n: CARDINAL] RETURNS [WORD] ~ INLINE {
RETURN [BITLSHIFT[1, n]-1]
};
RightJustifiedZeros: PROC [n: [0..bpw]] RETURNS [WORD] ~ INLINE {
RETURN [BITNOT[rightJustifiedOnes[n]]]
};
Tile0: PROC [dst: BitAddress, src: LONG POINTER TO RawWords, dstBpl, src0, sSizeTile, sSize, fSize: CARDINAL] ~ {
dstLine: LONG POINTER TO ARRAY [0..4) OF WORD; -- destination line word address
ndw: CARDINAL ¬ 0; -- number of destination words per (this) line
lMask: WORD; -- mask for the leftmost dest word (ones where bits are to go)
rMask: WORD; -- mask for the rightmost dest word
srcIndex: CARDINAL ¬ src0;
SrcFetch: PROC RETURNS [WORD] ~ INLINE {RETURN[
src[srcIndex]
]};
F: PROC [s: WORD] RETURNS [WORD] ~ INLINE {RETURN[
s
]};
MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE {
RETURN [
BITXOR[BITAND[BITXOR[F[s], d], mask], d]
]
};
LineSetup: PROC ~ INLINE {
ndw ¬ WordsForBits[dst.bit + fSize];
lMask ¬ rightJustifiedOnes[bpw-dst.bit];
rMask ¬ RightJustifiedZeros[(LOOPHOLE[bpw-dst.bit-fSize, CARDINAL]) MOD bpw];
};
BBLine1: PROC ~ INLINE {
only one destination word
dstLine[0] ¬ MF[dstLine[0], SrcFetch[], BITAND[lMask, rMask]];
};
BBLine2: PROC ~ INLINE {
only 2 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[2-1] ¬ MF[dstLine[2-1], w, rMask];
};
BBLine3: PROC ~ INLINE {
only 3 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[w];
dstLine[3-1] ¬ MF[dstLine[3-1], w, rMask];
};
BBLine4: PROC ~ INLINE {
only 4 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[w];
dstLine[2] ¬ F[w];
dstLine[4-1] ¬ MF[dstLine[4-1], w, rMask];
};
BBLineN: PROC ~ INLINE {
many destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine ¬ dstLine+SIZE[WORD];
THROUGH [0..CARDINAL[ndw-2] / 4) DO
dstLine[0] ¬ F[w];
dstLine[1] ¬ F[w];
dstLine[2] ¬ F[w];
dstLine[3] ¬ F[w];
dstLine ¬ dstLine+SIZE[ARRAY [0..4) OF WORD];
ENDLOOP;
THROUGH [0..CARDINAL[ndw-2] MOD 4) DO
dstLine[0] ¬ F[w];
dstLine ¬ dstLine+SIZE[WORD];
ENDLOOP;
dstLine[0] ¬ MF[dstLine[0], w, rMask];
};
BBLine: PROC ~ INLINE { IF ndw = 1 THEN BBLine1[] ELSE BBLineN[] };
IF CARDINAL[dstBpl] MOD bpw = 0
THEN {
don't need to do whole setup for each line
dRast: CARD ~ WordFloorUnitsForBits[dstBpl];
LineSetup[];
SELECT ndw FROM
1 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine1[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
2 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine2[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
3 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine3[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
4 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine4[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
ENDCASE => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
}
ELSE {
need setup for every line
DO
LineSetup[];
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)];
dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
};
Tile1: PROC [dst: BitAddress, src: LONG POINTER TO RawWords, dstBpl, src0, sSizeTile, sSize, fSize: CARDINAL] ~ {
dstLine: LONG POINTER TO ARRAY [0..4) OF WORD; -- destination line word address
ndw: CARDINAL ¬ 0; -- number of destination words per (this) line
lMask: WORD; -- mask for the leftmost dest word (ones where bits are to go)
rMask: WORD; -- mask for the rightmost dest word
srcIndex: CARDINAL ¬ src0;
SrcFetch: PROC RETURNS [WORD] ~ INLINE {RETURN[
BITNOT[src[srcIndex]]
]};
F: PROC [s: WORD] RETURNS [WORD] ~ INLINE {RETURN[
s
]};
MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE {
RETURN [
BITXOR[BITAND[BITXOR[F[s], d], mask], d]
]
};
LineSetup: PROC ~ INLINE {
ndw ¬ WordsForBits[dst.bit + fSize];
lMask ¬ rightJustifiedOnes[bpw-dst.bit];
rMask ¬ RightJustifiedZeros[(LOOPHOLE[bpw-dst.bit-fSize, CARDINAL]) MOD bpw];
};
BBLine1: PROC ~ INLINE {
only one destination word
dstLine[0] ¬ MF[dstLine[0], SrcFetch[], BITAND[lMask, rMask]];
};
BBLine2: PROC ~ INLINE {
only 2 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[2-1] ¬ MF[dstLine[2-1], w, rMask];
};
BBLine3: PROC ~ INLINE {
only 3 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[w];
dstLine[3-1] ¬ MF[dstLine[3-1], w, rMask];
};
BBLine4: PROC ~ INLINE {
only 4 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[w];
dstLine[2] ¬ F[w];
dstLine[4-1] ¬ MF[dstLine[4-1], w, rMask];
};
BBLineN: PROC ~ INLINE {
many destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine ¬ dstLine+SIZE[WORD];
THROUGH [0..CARDINAL[ndw-2] / 4) DO
dstLine[0] ¬ F[w];
dstLine[1] ¬ F[w];
dstLine[2] ¬ F[w];
dstLine[3] ¬ F[w];
dstLine ¬ dstLine+SIZE[ARRAY [0..4) OF WORD];
ENDLOOP;
THROUGH [0..CARDINAL[ndw-2] MOD 4) DO
dstLine[0] ¬ F[w];
dstLine ¬ dstLine+SIZE[WORD];
ENDLOOP;
dstLine[0] ¬ MF[dstLine[0], w, rMask];
};
BBLine: PROC ~ INLINE { IF ndw = 1 THEN BBLine1[] ELSE BBLineN[] };
IF CARDINAL[dstBpl] MOD bpw = 0
THEN {
don't need to do whole setup for each line
dRast: CARD ~ WordFloorUnitsForBits[dstBpl];
LineSetup[];
SELECT ndw FROM
1 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine1[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
2 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine2[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
3 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine3[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
4 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine4[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
ENDCASE => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
}
ELSE {
need setup for every line
DO
LineSetup[];
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)];
dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
};
Tile2: PROC [dst: BitAddress, src: LONG POINTER TO RawWords, dstBpl, src0, sSizeTile, sSize, fSize: CARDINAL] ~ {
dstLine: LONG POINTER TO ARRAY [0..4) OF WORD; -- destination line word address
ndw: CARDINAL ¬ 0; -- number of destination words per (this) line
lMask: WORD; -- mask for the leftmost dest word (ones where bits are to go)
rMask: WORD; -- mask for the rightmost dest word
srcIndex: CARDINAL ¬ src0;
SrcFetch: PROC RETURNS [WORD] ~ INLINE {RETURN[
src[srcIndex]
]};
F: PROC [d, s: WORD] RETURNS [WORD] ~ INLINE {RETURN[
BITAND[d, s]
]};
MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE {
RETURN [
BITXOR[BITAND[BITXOR[F[d, s], d], mask], d]
]
};
LineSetup: PROC ~ INLINE {
ndw ¬ WordsForBits[dst.bit + fSize];
lMask ¬ rightJustifiedOnes[bpw-dst.bit];
rMask ¬ RightJustifiedZeros[(LOOPHOLE[bpw-dst.bit-fSize, CARDINAL]) MOD bpw];
};
BBLine1: PROC ~ INLINE {
only one destination word
dstLine[0] ¬ MF[dstLine[0], SrcFetch[], BITAND[lMask, rMask]];
};
BBLine2: PROC ~ INLINE {
only 2 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[2-1] ¬ MF[dstLine[2-1], w, rMask];
};
BBLine3: PROC ~ INLINE {
only 3 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[3-1] ¬ MF[dstLine[3-1], w, rMask];
};
BBLine4: PROC ~ INLINE {
only 4 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[4-1] ¬ MF[dstLine[4-1], w, rMask];
};
BBLineN: PROC ~ INLINE {
many destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine ¬ dstLine+SIZE[WORD];
THROUGH [0..CARDINAL[ndw-2] / 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[3] ¬ F[dstLine[3], w];
dstLine ¬ dstLine+SIZE[ARRAY [0..4) OF WORD];
ENDLOOP;
THROUGH [0..CARDINAL[ndw-2] MOD 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine ¬ dstLine+SIZE[WORD];
ENDLOOP;
dstLine[0] ¬ MF[dstLine[0], w, rMask];
};
BBLine: PROC ~ INLINE { IF ndw = 1 THEN BBLine1[] ELSE BBLineN[] };
IF CARDINAL[dstBpl] MOD bpw = 0
THEN {
don't need to do whole setup for each line
dRast: CARD ~ WordFloorUnitsForBits[dstBpl];
LineSetup[];
SELECT ndw FROM
1 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine1[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
2 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine2[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
3 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine3[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
4 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine4[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
ENDCASE => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
}
ELSE {
need setup for every line
DO
LineSetup[];
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)];
dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
};
Tile3: PROC [dst: BitAddress, src: LONG POINTER TO RawWords, dstBpl, src0, sSizeTile, sSize, fSize: CARDINAL] ~ {
dstLine: LONG POINTER TO ARRAY [0..4) OF WORD; -- destination line word address
ndw: CARDINAL ¬ 0; -- number of destination words per (this) line
lMask: WORD; -- mask for the leftmost dest word (ones where bits are to go)
rMask: WORD; -- mask for the rightmost dest word
srcIndex: CARDINAL ¬ src0;
SrcFetch: PROC RETURNS [WORD] ~ INLINE {RETURN[
BITNOT[src[srcIndex]]
]};
F: PROC [d, s: WORD] RETURNS [WORD] ~ INLINE {RETURN[
BITAND[d, s]
]};
MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE {
RETURN [
BITXOR[BITAND[BITXOR[F[d, s], d], mask], d]
]
};
LineSetup: PROC ~ INLINE {
ndw ¬ WordsForBits[dst.bit + fSize];
lMask ¬ rightJustifiedOnes[bpw-dst.bit];
rMask ¬ RightJustifiedZeros[(LOOPHOLE[bpw-dst.bit-fSize, CARDINAL]) MOD bpw];
};
BBLine1: PROC ~ INLINE {
only one destination word
dstLine[0] ¬ MF[dstLine[0], SrcFetch[], BITAND[lMask, rMask]];
};
BBLine2: PROC ~ INLINE {
only 2 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[2-1] ¬ MF[dstLine[2-1], w, rMask];
};
BBLine3: PROC ~ INLINE {
only 3 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[3-1] ¬ MF[dstLine[3-1], w, rMask];
};
BBLine4: PROC ~ INLINE {
only 4 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[4-1] ¬ MF[dstLine[4-1], w, rMask];
};
BBLineN: PROC ~ INLINE {
many destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine ¬ dstLine+SIZE[WORD];
THROUGH [0..CARDINAL[ndw-2] / 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[3] ¬ F[dstLine[3], w];
dstLine ¬ dstLine+SIZE[ARRAY [0..4) OF WORD];
ENDLOOP;
THROUGH [0..CARDINAL[ndw-2] MOD 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine ¬ dstLine+SIZE[WORD];
ENDLOOP;
dstLine[0] ¬ MF[dstLine[0], w, rMask];
};
BBLine: PROC ~ INLINE { IF ndw = 1 THEN BBLine1[] ELSE BBLineN[] };
IF CARDINAL[dstBpl] MOD bpw = 0
THEN {
don't need to do whole setup for each line
dRast: CARD ~ WordFloorUnitsForBits[dstBpl];
LineSetup[];
SELECT ndw FROM
1 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine1[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
2 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine2[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
3 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine3[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
4 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine4[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
ENDCASE => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
}
ELSE {
need setup for every line
DO
LineSetup[];
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)];
dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
};
Tile4: PROC [dst: BitAddress, src: LONG POINTER TO RawWords, dstBpl, src0, sSizeTile, sSize, fSize: CARDINAL] ~ {
dstLine: LONG POINTER TO ARRAY [0..4) OF WORD; -- destination line word address
ndw: CARDINAL ¬ 0; -- number of destination words per (this) line
lMask: WORD; -- mask for the leftmost dest word (ones where bits are to go)
rMask: WORD; -- mask for the rightmost dest word
srcIndex: CARDINAL ¬ src0;
SrcFetch: PROC RETURNS [WORD] ~ INLINE {RETURN[
src[srcIndex]
]};
F: PROC [d, s: WORD] RETURNS [WORD] ~ INLINE {RETURN[
BITOR[d, s]
]};
MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE {
RETURN [
BITOR[d, BITAND[mask, s]]
]
};
LineSetup: PROC ~ INLINE {
ndw ¬ WordsForBits[dst.bit + fSize];
lMask ¬ rightJustifiedOnes[bpw-dst.bit];
rMask ¬ RightJustifiedZeros[(LOOPHOLE[bpw-dst.bit-fSize, CARDINAL]) MOD bpw];
};
BBLine1: PROC ~ INLINE {
only one destination word
dstLine[0] ¬ MF[dstLine[0], SrcFetch[], BITAND[lMask, rMask]];
};
BBLine2: PROC ~ INLINE {
only 2 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[2-1] ¬ MF[dstLine[2-1], w, rMask];
};
BBLine3: PROC ~ INLINE {
only 3 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[3-1] ¬ MF[dstLine[3-1], w, rMask];
};
BBLine4: PROC ~ INLINE {
only 4 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[4-1] ¬ MF[dstLine[4-1], w, rMask];
};
BBLineN: PROC ~ INLINE {
many destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine ¬ dstLine+SIZE[WORD];
THROUGH [0..CARDINAL[ndw-2] / 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[3] ¬ F[dstLine[3], w];
dstLine ¬ dstLine+SIZE[ARRAY [0..4) OF WORD];
ENDLOOP;
THROUGH [0..CARDINAL[ndw-2] MOD 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine ¬ dstLine+SIZE[WORD];
ENDLOOP;
dstLine[0] ¬ MF[dstLine[0], w, rMask];
};
BBLine: PROC ~ INLINE { IF ndw = 1 THEN BBLine1[] ELSE BBLineN[] };
IF CARDINAL[dstBpl] MOD bpw = 0
THEN {
don't need to do whole setup for each line
dRast: CARD ~ WordFloorUnitsForBits[dstBpl];
LineSetup[];
SELECT ndw FROM
1 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine1[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
2 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine2[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
3 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine3[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
4 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine4[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
ENDCASE => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
}
ELSE {
need setup for every line
DO
LineSetup[];
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)];
dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
};
Tile5: PROC [dst: BitAddress, src: LONG POINTER TO RawWords, dstBpl, src0, sSizeTile, sSize, fSize: CARDINAL] ~ {
dstLine: LONG POINTER TO ARRAY [0..4) OF WORD; -- destination line word address
ndw: CARDINAL ¬ 0; -- number of destination words per (this) line
lMask: WORD; -- mask for the leftmost dest word (ones where bits are to go)
rMask: WORD; -- mask for the rightmost dest word
srcIndex: CARDINAL ¬ src0;
SrcFetch: PROC RETURNS [WORD] ~ INLINE {RETURN[
BITNOT[src[srcIndex]]
]};
F: PROC [d, s: WORD] RETURNS [WORD] ~ INLINE {RETURN[
BITOR[d, s]
]};
MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE {
RETURN [
BITOR[d, BITAND[mask, s]]
]
};
LineSetup: PROC ~ INLINE {
ndw ¬ WordsForBits[dst.bit + fSize];
lMask ¬ rightJustifiedOnes[bpw-dst.bit];
rMask ¬ RightJustifiedZeros[(LOOPHOLE[bpw-dst.bit-fSize, CARDINAL]) MOD bpw];
};
BBLine1: PROC ~ INLINE {
only one destination word
dstLine[0] ¬ MF[dstLine[0], SrcFetch[], BITAND[lMask, rMask]];
};
BBLine2: PROC ~ INLINE {
only 2 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[2-1] ¬ MF[dstLine[2-1], w, rMask];
};
BBLine3: PROC ~ INLINE {
only 3 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[3-1] ¬ MF[dstLine[3-1], w, rMask];
};
BBLine4: PROC ~ INLINE {
only 4 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[4-1] ¬ MF[dstLine[4-1], w, rMask];
};
BBLineN: PROC ~ INLINE {
many destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine ¬ dstLine+SIZE[WORD];
THROUGH [0..CARDINAL[ndw-2] / 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[3] ¬ F[dstLine[3], w];
dstLine ¬ dstLine+SIZE[ARRAY [0..4) OF WORD];
ENDLOOP;
THROUGH [0..CARDINAL[ndw-2] MOD 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine ¬ dstLine+SIZE[WORD];
ENDLOOP;
dstLine[0] ¬ MF[dstLine[0], w, rMask];
};
BBLine: PROC ~ INLINE { IF ndw = 1 THEN BBLine1[] ELSE BBLineN[] };
IF CARDINAL[dstBpl] MOD bpw = 0
THEN {
don't need to do whole setup for each line
dRast: CARD ~ WordFloorUnitsForBits[dstBpl];
LineSetup[];
SELECT ndw FROM
1 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine1[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
2 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine2[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
3 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine3[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
4 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine4[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
ENDCASE => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
}
ELSE {
need setup for every line
DO
LineSetup[];
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)];
dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
};
Tile6: PROC [dst: BitAddress, src: LONG POINTER TO RawWords, dstBpl, src0, sSizeTile, sSize, fSize: CARDINAL] ~ {
dstLine: LONG POINTER TO ARRAY [0..4) OF WORD; -- destination line word address
ndw: CARDINAL ¬ 0; -- number of destination words per (this) line
lMask: WORD; -- mask for the leftmost dest word (ones where bits are to go)
rMask: WORD; -- mask for the rightmost dest word
srcIndex: CARDINAL ¬ src0;
SrcFetch: PROC RETURNS [WORD] ~ INLINE {RETURN[
src[srcIndex]
]};
F: PROC [d, s: WORD] RETURNS [WORD] ~ INLINE {RETURN[
BITXOR[d, s]
]};
MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE {
RETURN [
BITXOR[BITAND[BITXOR[F[d, s], d], mask], d]
]
};
LineSetup: PROC ~ INLINE {
ndw ¬ WordsForBits[dst.bit + fSize];
lMask ¬ rightJustifiedOnes[bpw-dst.bit];
rMask ¬ RightJustifiedZeros[(LOOPHOLE[bpw-dst.bit-fSize, CARDINAL]) MOD bpw];
};
BBLine1: PROC ~ INLINE {
only one destination word
dstLine[0] ¬ MF[dstLine[0], SrcFetch[], BITAND[lMask, rMask]];
};
BBLine2: PROC ~ INLINE {
only 2 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[2-1] ¬ MF[dstLine[2-1], w, rMask];
};
BBLine3: PROC ~ INLINE {
only 3 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[3-1] ¬ MF[dstLine[3-1], w, rMask];
};
BBLine4: PROC ~ INLINE {
only 4 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[4-1] ¬ MF[dstLine[4-1], w, rMask];
};
BBLineN: PROC ~ INLINE {
many destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine ¬ dstLine+SIZE[WORD];
THROUGH [0..CARDINAL[ndw-2] / 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[3] ¬ F[dstLine[3], w];
dstLine ¬ dstLine+SIZE[ARRAY [0..4) OF WORD];
ENDLOOP;
THROUGH [0..CARDINAL[ndw-2] MOD 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine ¬ dstLine+SIZE[WORD];
ENDLOOP;
dstLine[0] ¬ MF[dstLine[0], w, rMask];
};
BBLine: PROC ~ INLINE { IF ndw = 1 THEN BBLine1[] ELSE BBLineN[] };
IF CARDINAL[dstBpl] MOD bpw = 0
THEN {
don't need to do whole setup for each line
dRast: CARD ~ WordFloorUnitsForBits[dstBpl];
LineSetup[];
SELECT ndw FROM
1 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine1[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
2 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine2[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
3 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine3[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
4 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine4[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
ENDCASE => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
}
ELSE {
need setup for every line
DO
LineSetup[];
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)];
dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
};
Tile7: PROC [dst: BitAddress, src: LONG POINTER TO RawWords, dstBpl, src0, sSizeTile, sSize, fSize: CARDINAL] ~ {
dstLine: LONG POINTER TO ARRAY [0..4) OF WORD; -- destination line word address
ndw: CARDINAL ¬ 0; -- number of destination words per (this) line
lMask: WORD; -- mask for the leftmost dest word (ones where bits are to go)
rMask: WORD; -- mask for the rightmost dest word
srcIndex: CARDINAL ¬ src0;
SrcFetch: PROC RETURNS [WORD] ~ INLINE {RETURN[
BITNOT[src[srcIndex]]
]};
F: PROC [d, s: WORD] RETURNS [WORD] ~ INLINE {RETURN[
BITXOR[d, s]
]};
MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE {
RETURN [
BITXOR[BITAND[BITXOR[F[d, s], d], mask], d]
]
};
LineSetup: PROC ~ INLINE {
ndw ¬ WordsForBits[dst.bit + fSize];
lMask ¬ rightJustifiedOnes[bpw-dst.bit];
rMask ¬ RightJustifiedZeros[(LOOPHOLE[bpw-dst.bit-fSize, CARDINAL]) MOD bpw];
};
BBLine1: PROC ~ INLINE {
only one destination word
dstLine[0] ¬ MF[dstLine[0], SrcFetch[], BITAND[lMask, rMask]];
};
BBLine2: PROC ~ INLINE {
only 2 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[2-1] ¬ MF[dstLine[2-1], w, rMask];
};
BBLine3: PROC ~ INLINE {
only 3 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[3-1] ¬ MF[dstLine[3-1], w, rMask];
};
BBLine4: PROC ~ INLINE {
only 4 destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[4-1] ¬ MF[dstLine[4-1], w, rMask];
};
BBLineN: PROC ~ INLINE {
many destination words
w: WORD ~ SrcFetch[];
dstLine[0] ¬ MF[dstLine[0], w, lMask];
dstLine ¬ dstLine+SIZE[WORD];
THROUGH [0..CARDINAL[ndw-2] / 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine[1] ¬ F[dstLine[1], w];
dstLine[2] ¬ F[dstLine[2], w];
dstLine[3] ¬ F[dstLine[3], w];
dstLine ¬ dstLine+SIZE[ARRAY [0..4) OF WORD];
ENDLOOP;
THROUGH [0..CARDINAL[ndw-2] MOD 4) DO
dstLine[0] ¬ F[dstLine[0], w];
dstLine ¬ dstLine+SIZE[WORD];
ENDLOOP;
dstLine[0] ¬ MF[dstLine[0], w, rMask];
};
BBLine: PROC ~ INLINE { IF ndw = 1 THEN BBLine1[] ELSE BBLineN[] };
IF CARDINAL[dstBpl] MOD bpw = 0
THEN {
don't need to do whole setup for each line
dRast: CARD ~ WordFloorUnitsForBits[dstBpl];
LineSetup[];
SELECT ndw FROM
1 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine1[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
2 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine2[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
3 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine3[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
4 => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine4[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
ENDCASE => {
DO
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + dRast;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
}
ELSE {
need setup for every line
DO
LineSetup[];
dstLine ¬ LOOPHOLE[dst.word];
BBLine[];
IF (sSize ¬ sSize - 1) = 0 THEN EXIT;
dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)];
dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw;
srcIndex ¬ srcIndex + 1;
IF srcIndex = sSizeTile THEN srcIndex ¬ 0;
ENDLOOP;
};
};
tileOp: PUBLIC ARRAY DstFunc OF ARRAY SrcFunc OF PROC [dst: BitAddress, src: LONG POINTER TO RawWords, dstBpl, src0, sSizeTile, sSize, fSize: CARDINAL] ¬ [[Tile0, Tile1], [Tile2, Tile3], [Tile4, Tile5], [Tile6, Tile7]];
END.