DIRECTORY Basics, RasterBasics, RasterOp; RasterOpForwardImpl: PROGRAM IMPORTS Basics EXPORTS RasterOp ~ BEGIN OPEN Basics; bpw: CARDINAL ~ BITS[WORD]; BitOff: TYPE = [0..bpw); BitCount: TYPE = [0..bpw]; DstFunc: TYPE ~ RasterBasics.DstFunc; SrcFunc: TYPE ~ RasterBasics.SrcFunc; BitAddress: TYPE ~ RasterBasics.BitAddress; RawWords: TYPE ~ Basics.RawWords; RawWordsPtr: TYPE ~ LONG POINTER TO RawWords; WordPtr: TYPE = LONG POINTER TO 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]]] }; CombineUnderMask: PROC [mask, onesSrc, zerosSrc: WORD] RETURNS [WORD] ~ INLINE { RETURN [BITXOR[BITAND[BITXOR[onesSrc, zerosSrc], mask], zerosSrc]] }; rightJustifiedOnes: ARRAY BitCount OF WORD ~ InitRightJustifiedOnes[]; InitRightJustifiedOnes: PROC RETURNS [a: ARRAY BitCount OF WORD] ~ { m: WORD ¬ 0; FOR n: CARDINAL IN BitCount DO a[n] ¬ m; m ¬ m+m+1; ENDLOOP; }; RightJustifiedZeros: PROC [n: BitCount] RETURNS [WORD] ~ INLINE { RETURN [BITNOT[rightJustifiedOnes[n]]] }; Forward0: PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ~ { MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE { RETURN [ BITXOR[BITAND[BITXOR[ s, d], mask], d] ] }; DoUniformLines: PROC [count: CARDINAL, dstPtr: WordPtr, dstBit: BitOff, srcPtr: WordPtr, srcBit: BitOff] ~ { dRast: CARD ~ WordFloorUnitsForBits[dstBpl]; sRast: CARD ~ WordFloorUnitsForBits[srcBpl]; ndw: CARDINAL ~ WordsForBits[dstBit + fSize]; lMask: WORD ~ rightJustifiedOnes[bpw-dstBit]; rMask: WORD ~ RightJustifiedZeros[ (LOOPHOLE[bpw-dstBit-fSize, CARDINAL]) MOD bpw]; lSA: BitOff ~ (LOOPHOLE[srcBit-dstBit, CARDINAL]) MOD bpw; -- left shift amount w: WORD ¬ 0; -- source word, aligned with destination dstLine: RawWordsPtr ¬ NIL; -- destination line word address srcLine: RawWordsPtr ¬ NIL; -- source line word address Inner0: PROC = INLINE { fetchLastWord: BOOL ~ TRUE; FetchNext: PROC ~ INLINE { w ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { w ¬ srcLine[wordOffset]; }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ srcLine[wordOffset]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ w; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ w; FetchNextOff[2]; dstLine[2] ¬ w; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ w; FetchNextOff[1]; dstLine[1] ¬ w; FetchNextOff[2]; dstLine[2] ¬ w; FetchNextOff[3]; dstLine[3] ¬ w; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ w; FetchNextOff[1]; dstLine[1] ¬ w; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ w; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; Inner1: PROC = INLINE { hi: WORD; -- left unshifted source word lo: WORD ¬ 0; -- right unshifted source word rSA: BitOff = bpw - lSA; nsw: CARDINAL = WordsForBits[srcBit + fSize]; fetchLastWord: BOOL = IF srcBit >= dstBit THEN (nsw>ndw) ELSE (nsw>=ndw); FetchNext: PROC ~ INLINE { hi ¬ lo; lo ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { hi ¬ lo; lo ¬ srcLine[wordOffset]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ BITLSHIFT[lo, lSA]; IF fetch THEN w ¬ w + BITRSHIFT[srcLine[wordOffset], rSA]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; IF srcBit >= dstBit THEN FetchNext[]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ w; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ w; FetchNextOff[2]; dstLine[2] ¬ w; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ w; FetchNextOff[1]; dstLine[1] ¬ w; FetchNextOff[2]; dstLine[2] ¬ w; FetchNextOff[3]; dstLine[3] ¬ w; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ w; FetchNextOff[1]; dstLine[1] ¬ w; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ w; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; IF lSA = 0 THEN { Inner0[] } ELSE { Inner1[] }; }; IF BITOR[sSize, fSize] # 0 THEN { IF dstBpl MOD bpw = 0 AND srcBpl MOD bpw = 0 THEN { DoUniformLines[sSize, dst.word, dst.bit, src.word, src.bit]; } ELSE { DO DoUniformLines[1, dst.word, dst.bit, src.word, src.bit]; IF (sSize ¬ sSize - 1) = 0 THEN EXIT; dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)]; dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw; src.word ¬ src.word + WordFloorUnitsForBits[(src.bit+srcBpl)]; src.bit ¬ CARDINAL[(src.bit+srcBpl)] MOD bpw; ENDLOOP; }; }; }; Forward1: PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ~ { MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE { RETURN [ BITXOR[BITAND[BITXOR[BITNOT[ s], d], mask], d] ] }; DoUniformLines: PROC [count: CARDINAL, dstPtr: WordPtr, dstBit: BitOff, srcPtr: WordPtr, srcBit: BitOff] ~ { dRast: CARD ~ WordFloorUnitsForBits[dstBpl]; sRast: CARD ~ WordFloorUnitsForBits[srcBpl]; ndw: CARDINAL ~ WordsForBits[dstBit + fSize]; lMask: WORD ~ rightJustifiedOnes[bpw-dstBit]; rMask: WORD ~ RightJustifiedZeros[ (LOOPHOLE[bpw-dstBit-fSize, CARDINAL]) MOD bpw]; lSA: BitOff ~ (LOOPHOLE[srcBit-dstBit, CARDINAL]) MOD bpw; -- left shift amount w: WORD ¬ 0; -- source word, aligned with destination dstLine: RawWordsPtr ¬ NIL; -- destination line word address srcLine: RawWordsPtr ¬ NIL; -- source line word address Inner0: PROC = INLINE { fetchLastWord: BOOL ~ TRUE; FetchNext: PROC ~ INLINE { w ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { w ¬ srcLine[wordOffset]; }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ srcLine[wordOffset]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITNOT[ w]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITNOT[ w]; FetchNextOff[2]; dstLine[2] ¬ BITNOT[ w]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITNOT[ w]; FetchNextOff[1]; dstLine[1] ¬ BITNOT[ w]; FetchNextOff[2]; dstLine[2] ¬ BITNOT[ w]; FetchNextOff[3]; dstLine[3] ¬ BITNOT[ w]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITNOT[ w]; FetchNextOff[1]; dstLine[1] ¬ BITNOT[ w]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITNOT[ w]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; Inner1: PROC = INLINE { hi: WORD; -- left unshifted source word lo: WORD ¬ 0; -- right unshifted source word rSA: BitOff = bpw - lSA; nsw: CARDINAL = WordsForBits[srcBit + fSize]; fetchLastWord: BOOL = IF srcBit >= dstBit THEN (nsw>ndw) ELSE (nsw>=ndw); FetchNext: PROC ~ INLINE { hi ¬ lo; lo ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { hi ¬ lo; lo ¬ srcLine[wordOffset]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ BITLSHIFT[lo, lSA]; IF fetch THEN w ¬ w + BITRSHIFT[srcLine[wordOffset], rSA]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; IF srcBit >= dstBit THEN FetchNext[]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITNOT[ w]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITNOT[ w]; FetchNextOff[2]; dstLine[2] ¬ BITNOT[ w]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITNOT[ w]; FetchNextOff[1]; dstLine[1] ¬ BITNOT[ w]; FetchNextOff[2]; dstLine[2] ¬ BITNOT[ w]; FetchNextOff[3]; dstLine[3] ¬ BITNOT[ w]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITNOT[ w]; FetchNextOff[1]; dstLine[1] ¬ BITNOT[ w]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITNOT[ w]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; IF lSA = 0 THEN { Inner0[] } ELSE { Inner1[] }; }; IF BITOR[sSize, fSize] # 0 THEN { IF dstBpl MOD bpw = 0 AND srcBpl MOD bpw = 0 THEN { DoUniformLines[sSize, dst.word, dst.bit, src.word, src.bit]; } ELSE { DO DoUniformLines[1, dst.word, dst.bit, src.word, src.bit]; IF (sSize ¬ sSize - 1) = 0 THEN EXIT; dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)]; dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw; src.word ¬ src.word + WordFloorUnitsForBits[(src.bit+srcBpl)]; src.bit ¬ CARDINAL[(src.bit+srcBpl)] MOD bpw; ENDLOOP; }; }; }; Forward2: PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ~ { MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE { RETURN [ BITXOR[BITAND[BITXOR[BITAND[d, s], d], mask], d] ] }; DoUniformLines: PROC [count: CARDINAL, dstPtr: WordPtr, dstBit: BitOff, srcPtr: WordPtr, srcBit: BitOff] ~ { dRast: CARD ~ WordFloorUnitsForBits[dstBpl]; sRast: CARD ~ WordFloorUnitsForBits[srcBpl]; ndw: CARDINAL ~ WordsForBits[dstBit + fSize]; lMask: WORD ~ rightJustifiedOnes[bpw-dstBit]; rMask: WORD ~ RightJustifiedZeros[ (LOOPHOLE[bpw-dstBit-fSize, CARDINAL]) MOD bpw]; lSA: BitOff ~ (LOOPHOLE[srcBit-dstBit, CARDINAL]) MOD bpw; -- left shift amount w: WORD ¬ 0; -- source word, aligned with destination dstLine: RawWordsPtr ¬ NIL; -- destination line word address srcLine: RawWordsPtr ¬ NIL; -- source line word address Inner0: PROC = INLINE { fetchLastWord: BOOL ~ TRUE; FetchNext: PROC ~ INLINE { w ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { w ¬ srcLine[wordOffset]; }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ srcLine[wordOffset]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], w]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITAND[dstLine[2], w]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITAND[dstLine[2], w]; FetchNextOff[3]; dstLine[3] ¬ BITAND[dstLine[3], w]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], w]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], w]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; Inner1: PROC = INLINE { hi: WORD; -- left unshifted source word lo: WORD ¬ 0; -- right unshifted source word rSA: BitOff = bpw - lSA; nsw: CARDINAL = WordsForBits[srcBit + fSize]; fetchLastWord: BOOL = IF srcBit >= dstBit THEN (nsw>ndw) ELSE (nsw>=ndw); FetchNext: PROC ~ INLINE { hi ¬ lo; lo ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { hi ¬ lo; lo ¬ srcLine[wordOffset]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ BITLSHIFT[lo, lSA]; IF fetch THEN w ¬ w + BITRSHIFT[srcLine[wordOffset], rSA]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; IF srcBit >= dstBit THEN FetchNext[]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], w]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITAND[dstLine[2], w]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITAND[dstLine[2], w]; FetchNextOff[3]; dstLine[3] ¬ BITAND[dstLine[3], w]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], w]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], w]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; IF lSA = 0 THEN { Inner0[] } ELSE { Inner1[] }; }; IF BITOR[sSize, fSize] # 0 THEN { IF dstBpl MOD bpw = 0 AND srcBpl MOD bpw = 0 THEN { DoUniformLines[sSize, dst.word, dst.bit, src.word, src.bit]; } ELSE { DO DoUniformLines[1, dst.word, dst.bit, src.word, src.bit]; IF (sSize ¬ sSize - 1) = 0 THEN EXIT; dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)]; dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw; src.word ¬ src.word + WordFloorUnitsForBits[(src.bit+srcBpl)]; src.bit ¬ CARDINAL[(src.bit+srcBpl)] MOD bpw; ENDLOOP; }; }; }; Forward3: PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ~ { MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE { RETURN [ BITXOR[BITAND[BITXOR[BITAND[d, BITNOT[ s]], d], mask], d] ] }; DoUniformLines: PROC [count: CARDINAL, dstPtr: WordPtr, dstBit: BitOff, srcPtr: WordPtr, srcBit: BitOff] ~ { dRast: CARD ~ WordFloorUnitsForBits[dstBpl]; sRast: CARD ~ WordFloorUnitsForBits[srcBpl]; ndw: CARDINAL ~ WordsForBits[dstBit + fSize]; lMask: WORD ~ rightJustifiedOnes[bpw-dstBit]; rMask: WORD ~ RightJustifiedZeros[ (LOOPHOLE[bpw-dstBit-fSize, CARDINAL]) MOD bpw]; lSA: BitOff ~ (LOOPHOLE[srcBit-dstBit, CARDINAL]) MOD bpw; -- left shift amount w: WORD ¬ 0; -- source word, aligned with destination dstLine: RawWordsPtr ¬ NIL; -- destination line word address srcLine: RawWordsPtr ¬ NIL; -- source line word address Inner0: PROC = INLINE { fetchLastWord: BOOL ~ TRUE; FetchNext: PROC ~ INLINE { w ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { w ¬ srcLine[wordOffset]; }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ srcLine[wordOffset]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], BITNOT[ w]]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITAND[dstLine[2], BITNOT[ w]]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITAND[dstLine[2], BITNOT[ w]]; FetchNextOff[3]; dstLine[3] ¬ BITAND[dstLine[3], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; Inner1: PROC = INLINE { hi: WORD; -- left unshifted source word lo: WORD ¬ 0; -- right unshifted source word rSA: BitOff = bpw - lSA; nsw: CARDINAL = WordsForBits[srcBit + fSize]; fetchLastWord: BOOL = IF srcBit >= dstBit THEN (nsw>ndw) ELSE (nsw>=ndw); FetchNext: PROC ~ INLINE { hi ¬ lo; lo ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { hi ¬ lo; lo ¬ srcLine[wordOffset]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ BITLSHIFT[lo, lSA]; IF fetch THEN w ¬ w + BITRSHIFT[srcLine[wordOffset], rSA]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; IF srcBit >= dstBit THEN FetchNext[]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], BITNOT[ w]]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITAND[dstLine[2], BITNOT[ w]]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITAND[dstLine[2], BITNOT[ w]]; FetchNextOff[3]; dstLine[3] ¬ BITAND[dstLine[3], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITAND[dstLine[1], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITAND[dstLine[0], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; IF lSA = 0 THEN { Inner0[] } ELSE { Inner1[] }; }; IF BITOR[sSize, fSize] # 0 THEN { IF dstBpl MOD bpw = 0 AND srcBpl MOD bpw = 0 THEN { DoUniformLines[sSize, dst.word, dst.bit, src.word, src.bit]; } ELSE { DO DoUniformLines[1, dst.word, dst.bit, src.word, src.bit]; IF (sSize ¬ sSize - 1) = 0 THEN EXIT; dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)]; dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw; src.word ¬ src.word + WordFloorUnitsForBits[(src.bit+srcBpl)]; src.bit ¬ CARDINAL[(src.bit+srcBpl)] MOD bpw; ENDLOOP; }; }; }; Forward4: PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ~ { MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE { RETURN [ BITOR[d, BITAND[mask, s]] ] }; DoUniformLines: PROC [count: CARDINAL, dstPtr: WordPtr, dstBit: BitOff, srcPtr: WordPtr, srcBit: BitOff] ~ { dRast: CARD ~ WordFloorUnitsForBits[dstBpl]; sRast: CARD ~ WordFloorUnitsForBits[srcBpl]; ndw: CARDINAL ~ WordsForBits[dstBit + fSize]; lMask: WORD ~ rightJustifiedOnes[bpw-dstBit]; rMask: WORD ~ RightJustifiedZeros[ (LOOPHOLE[bpw-dstBit-fSize, CARDINAL]) MOD bpw]; lSA: BitOff ~ (LOOPHOLE[srcBit-dstBit, CARDINAL]) MOD bpw; -- left shift amount w: WORD ¬ 0; -- source word, aligned with destination dstLine: RawWordsPtr ¬ NIL; -- destination line word address srcLine: RawWordsPtr ¬ NIL; -- source line word address Inner0: PROC = INLINE { fetchLastWord: BOOL ~ TRUE; FetchNext: PROC ~ INLINE { w ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { w ¬ srcLine[wordOffset]; }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ srcLine[wordOffset]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], w]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITOR[dstLine[2], w]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITOR[dstLine[2], w]; FetchNextOff[3]; dstLine[3] ¬ BITOR[dstLine[3], w]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], w]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], w]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; Inner1: PROC = INLINE { hi: WORD; -- left unshifted source word lo: WORD ¬ 0; -- right unshifted source word rSA: BitOff = bpw - lSA; nsw: CARDINAL = WordsForBits[srcBit + fSize]; fetchLastWord: BOOL = IF srcBit >= dstBit THEN (nsw>ndw) ELSE (nsw>=ndw); FetchNext: PROC ~ INLINE { hi ¬ lo; lo ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { hi ¬ lo; lo ¬ srcLine[wordOffset]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ BITLSHIFT[lo, lSA]; IF fetch THEN w ¬ w + BITRSHIFT[srcLine[wordOffset], rSA]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; IF srcBit >= dstBit THEN FetchNext[]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], w]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITOR[dstLine[2], w]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITOR[dstLine[2], w]; FetchNextOff[3]; dstLine[3] ¬ BITOR[dstLine[3], w]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], w]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], w]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; IF lSA = 0 THEN { Inner0[] } ELSE { Inner1[] }; }; IF BITOR[sSize, fSize] # 0 THEN { IF dstBpl MOD bpw = 0 AND srcBpl MOD bpw = 0 THEN { DoUniformLines[sSize, dst.word, dst.bit, src.word, src.bit]; } ELSE { DO DoUniformLines[1, dst.word, dst.bit, src.word, src.bit]; IF (sSize ¬ sSize - 1) = 0 THEN EXIT; dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)]; dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw; src.word ¬ src.word + WordFloorUnitsForBits[(src.bit+srcBpl)]; src.bit ¬ CARDINAL[(src.bit+srcBpl)] MOD bpw; ENDLOOP; }; }; }; Forward5: PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ~ { MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE { RETURN [ BITOR[d, BITAND[mask, BITNOT[s]]] ] }; DoUniformLines: PROC [count: CARDINAL, dstPtr: WordPtr, dstBit: BitOff, srcPtr: WordPtr, srcBit: BitOff] ~ { dRast: CARD ~ WordFloorUnitsForBits[dstBpl]; sRast: CARD ~ WordFloorUnitsForBits[srcBpl]; ndw: CARDINAL ~ WordsForBits[dstBit + fSize]; lMask: WORD ~ rightJustifiedOnes[bpw-dstBit]; rMask: WORD ~ RightJustifiedZeros[ (LOOPHOLE[bpw-dstBit-fSize, CARDINAL]) MOD bpw]; lSA: BitOff ~ (LOOPHOLE[srcBit-dstBit, CARDINAL]) MOD bpw; -- left shift amount w: WORD ¬ 0; -- source word, aligned with destination dstLine: RawWordsPtr ¬ NIL; -- destination line word address srcLine: RawWordsPtr ¬ NIL; -- source line word address Inner0: PROC = INLINE { fetchLastWord: BOOL ~ TRUE; FetchNext: PROC ~ INLINE { w ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { w ¬ srcLine[wordOffset]; }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ srcLine[wordOffset]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], BITNOT[ w]]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITOR[dstLine[2], BITNOT[ w]]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITOR[dstLine[2], BITNOT[ w]]; FetchNextOff[3]; dstLine[3] ¬ BITOR[dstLine[3], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; Inner1: PROC = INLINE { hi: WORD; -- left unshifted source word lo: WORD ¬ 0; -- right unshifted source word rSA: BitOff = bpw - lSA; nsw: CARDINAL = WordsForBits[srcBit + fSize]; fetchLastWord: BOOL = IF srcBit >= dstBit THEN (nsw>ndw) ELSE (nsw>=ndw); FetchNext: PROC ~ INLINE { hi ¬ lo; lo ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { hi ¬ lo; lo ¬ srcLine[wordOffset]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ BITLSHIFT[lo, lSA]; IF fetch THEN w ¬ w + BITRSHIFT[srcLine[wordOffset], rSA]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; IF srcBit >= dstBit THEN FetchNext[]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], BITNOT[ w]]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITOR[dstLine[2], BITNOT[ w]]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITOR[dstLine[2], BITNOT[ w]]; FetchNextOff[3]; dstLine[3] ¬ BITOR[dstLine[3], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITOR[dstLine[1], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITOR[dstLine[0], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; IF lSA = 0 THEN { Inner0[] } ELSE { Inner1[] }; }; IF BITOR[sSize, fSize] # 0 THEN { IF dstBpl MOD bpw = 0 AND srcBpl MOD bpw = 0 THEN { DoUniformLines[sSize, dst.word, dst.bit, src.word, src.bit]; } ELSE { DO DoUniformLines[1, dst.word, dst.bit, src.word, src.bit]; IF (sSize ¬ sSize - 1) = 0 THEN EXIT; dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)]; dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw; src.word ¬ src.word + WordFloorUnitsForBits[(src.bit+srcBpl)]; src.bit ¬ CARDINAL[(src.bit+srcBpl)] MOD bpw; ENDLOOP; }; }; }; Forward6: PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ~ { MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE { RETURN [ BITXOR[BITAND[BITXOR[BITXOR[d, s], d], mask], d] ] }; DoUniformLines: PROC [count: CARDINAL, dstPtr: WordPtr, dstBit: BitOff, srcPtr: WordPtr, srcBit: BitOff] ~ { dRast: CARD ~ WordFloorUnitsForBits[dstBpl]; sRast: CARD ~ WordFloorUnitsForBits[srcBpl]; ndw: CARDINAL ~ WordsForBits[dstBit + fSize]; lMask: WORD ~ rightJustifiedOnes[bpw-dstBit]; rMask: WORD ~ RightJustifiedZeros[ (LOOPHOLE[bpw-dstBit-fSize, CARDINAL]) MOD bpw]; lSA: BitOff ~ (LOOPHOLE[srcBit-dstBit, CARDINAL]) MOD bpw; -- left shift amount w: WORD ¬ 0; -- source word, aligned with destination dstLine: RawWordsPtr ¬ NIL; -- destination line word address srcLine: RawWordsPtr ¬ NIL; -- source line word address Inner0: PROC = INLINE { fetchLastWord: BOOL ~ TRUE; FetchNext: PROC ~ INLINE { w ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { w ¬ srcLine[wordOffset]; }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ srcLine[wordOffset]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], w]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITXOR[dstLine[2], w]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITXOR[dstLine[2], w]; FetchNextOff[3]; dstLine[3] ¬ BITXOR[dstLine[3], w]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], w]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], w]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; Inner1: PROC = INLINE { hi: WORD; -- left unshifted source word lo: WORD ¬ 0; -- right unshifted source word rSA: BitOff = bpw - lSA; nsw: CARDINAL = WordsForBits[srcBit + fSize]; fetchLastWord: BOOL = IF srcBit >= dstBit THEN (nsw>ndw) ELSE (nsw>=ndw); FetchNext: PROC ~ INLINE { hi ¬ lo; lo ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { hi ¬ lo; lo ¬ srcLine[wordOffset]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ BITLSHIFT[lo, lSA]; IF fetch THEN w ¬ w + BITRSHIFT[srcLine[wordOffset], rSA]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; IF srcBit >= dstBit THEN FetchNext[]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], w]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITXOR[dstLine[2], w]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ BITXOR[dstLine[2], w]; FetchNextOff[3]; dstLine[3] ¬ BITXOR[dstLine[3], w]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], w]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], w]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; IF lSA = 0 THEN { Inner0[] } ELSE { Inner1[] }; }; IF BITOR[sSize, fSize] # 0 THEN { IF dstBpl MOD bpw = 0 AND srcBpl MOD bpw = 0 THEN { DoUniformLines[sSize, dst.word, dst.bit, src.word, src.bit]; } ELSE { DO DoUniformLines[1, dst.word, dst.bit, src.word, src.bit]; IF (sSize ¬ sSize - 1) = 0 THEN EXIT; dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)]; dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw; src.word ¬ src.word + WordFloorUnitsForBits[(src.bit+srcBpl)]; src.bit ¬ CARDINAL[(src.bit+srcBpl)] MOD bpw; ENDLOOP; }; }; }; Forward7: PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ~ { MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE { RETURN [ BITXOR[BITAND[BITXOR[BITXOR[d, BITNOT[ s]], d], mask], d] ] }; DoUniformLines: PROC [count: CARDINAL, dstPtr: WordPtr, dstBit: BitOff, srcPtr: WordPtr, srcBit: BitOff] ~ { dRast: CARD ~ WordFloorUnitsForBits[dstBpl]; sRast: CARD ~ WordFloorUnitsForBits[srcBpl]; ndw: CARDINAL ~ WordsForBits[dstBit + fSize]; lMask: WORD ~ rightJustifiedOnes[bpw-dstBit]; rMask: WORD ~ RightJustifiedZeros[ (LOOPHOLE[bpw-dstBit-fSize, CARDINAL]) MOD bpw]; lSA: BitOff ~ (LOOPHOLE[srcBit-dstBit, CARDINAL]) MOD bpw; -- left shift amount w: WORD ¬ 0; -- source word, aligned with destination dstLine: RawWordsPtr ¬ NIL; -- destination line word address srcLine: RawWordsPtr ¬ NIL; -- source line word address Inner0: PROC = INLINE { fetchLastWord: BOOL ~ TRUE; FetchNext: PROC ~ INLINE { w ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { w ¬ srcLine[wordOffset]; }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ srcLine[wordOffset]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], BITNOT[ w]]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITXOR[dstLine[2], BITNOT[ w]]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITXOR[dstLine[2], BITNOT[ w]]; FetchNextOff[3]; dstLine[3] ¬ BITXOR[dstLine[3], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; Inner1: PROC = INLINE { hi: WORD; -- left unshifted source word lo: WORD ¬ 0; -- right unshifted source word rSA: BitOff = bpw - lSA; nsw: CARDINAL = WordsForBits[srcBit + fSize]; fetchLastWord: BOOL = IF srcBit >= dstBit THEN (nsw>ndw) ELSE (nsw>=ndw); FetchNext: PROC ~ INLINE { hi ¬ lo; lo ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { hi ¬ lo; lo ¬ srcLine[wordOffset]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ BITLSHIFT[lo, lSA]; IF fetch THEN w ¬ w + BITRSHIFT[srcLine[wordOffset], rSA]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; IF srcBit >= dstBit THEN FetchNext[]; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; 2 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchLast[1, fetchLastWord]; dstLine[1] ¬ MF[dstLine[1], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 3 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], BITNOT[ w]]; FetchLast[2, fetchLastWord]; dstLine[2] ¬ MF[dstLine[2], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; 4 => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITXOR[dstLine[2], BITNOT[ w]]; FetchLast[3, fetchLastWord]; dstLine[3] ¬ MF[dstLine[3], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDCASE => { checkUnroll: [2..256] = 4; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], BITNOT[ w]]; FetchNextOff[2]; dstLine[2] ¬ BITXOR[dstLine[2], BITNOT[ w]]; FetchNextOff[3]; dstLine[3] ¬ BITXOR[dstLine[3], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], BITNOT[ w]]; FetchNextOff[1]; dstLine[1] ¬ BITXOR[dstLine[1], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ BITXOR[dstLine[0], BITNOT[ w]]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; IF lSA = 0 THEN { Inner0[] } ELSE { Inner1[] }; }; IF BITOR[sSize, fSize] # 0 THEN { IF dstBpl MOD bpw = 0 AND srcBpl MOD bpw = 0 THEN { DoUniformLines[sSize, dst.word, dst.bit, src.word, src.bit]; } ELSE { DO DoUniformLines[1, dst.word, dst.bit, src.word, src.bit]; IF (sSize ¬ sSize - 1) = 0 THEN EXIT; dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)]; dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw; src.word ¬ src.word + WordFloorUnitsForBits[(src.bit+srcBpl)]; src.bit ¬ CARDINAL[(src.bit+srcBpl)] MOD bpw; ENDLOOP; }; }; }; forwardOp: PUBLIC ARRAY DstFunc OF ARRAY SrcFunc OF PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ¬ [[Forward0, Forward1], [Forward2, Forward3], [Forward4, Forward5], [Forward6, Forward7]]; END. ό RasterOpForwardImpl.meta Copyright Σ 1988, 1989, 1990, 1991, 1992 by Xerox Corporation. All rights reserved. Michael Plass, October 1, 1991 4:37 pm PDT Russ Atkinson (RRA) March 1, 1990 4:03:19 pm PST Willie-s, June 13, 1991 4:28 pm PDT Procs number of destination words per (this) line mask for the leftmost dest word (ones where bits are to go) mask for the rightmost dest word Aligned case is simpler true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word amount to shift source words right to line them up true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the next word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word don't need to do whole setup for each line need setup for every line number of destination words per (this) line mask for the leftmost dest word (ones where bits are to go) mask for the rightmost dest word Aligned case is simpler true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word amount to shift source words right to line them up true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the next word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word don't need to do whole setup for each line need setup for every line number of destination words per (this) line mask for the leftmost dest word (ones where bits are to go) mask for the rightmost dest word Aligned case is simpler true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word amount to shift source words right to line them up true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the next word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word don't need to do whole setup for each line need setup for every line number of destination words per (this) line mask for the leftmost dest word (ones where bits are to go) mask for the rightmost dest word Aligned case is simpler true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word amount to shift source words right to line them up true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the next word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word don't need to do whole setup for each line need setup for every line number of destination words per (this) line mask for the leftmost dest word (ones where bits are to go) mask for the rightmost dest word Aligned case is simpler true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word amount to shift source words right to line them up true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the next word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word don't need to do whole setup for each line need setup for every line number of destination words per (this) line mask for the leftmost dest word (ones where bits are to go) mask for the rightmost dest word Aligned case is simpler true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word amount to shift source words right to line them up true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the next word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word don't need to do whole setup for each line need setup for every line number of destination words per (this) line mask for the leftmost dest word (ones where bits are to go) mask for the rightmost dest word Aligned case is simpler true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word amount to shift source words right to line them up true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the next word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word don't need to do whole setup for each line need setup for every line number of destination words per (this) line mask for the leftmost dest word (ones where bits are to go) mask for the rightmost dest word Aligned case is simpler true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word amount to shift source words right to line them up true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the next word at the given offset, no pointer change fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word don't need to do whole setup for each line need setup for every line Κ\#•NewlineDelimiter –(cedarcode) style™šœ™Jšœ ΟeœI™TJšœ*™*Jšœ0™0Jšœ#™#Icode˜KšΟk œ ˜)K˜—šΟnœž˜Kšžœ˜Kšžœ ˜Kšœžœžœ˜K˜šœžœžœžœ˜Kšœžœ ˜Kšœ žœ ˜K˜—Kšœ žœ˜%Kšœ žœ˜%Kšœ žœ˜+Kšœ žœ˜!Kš œ žœžœžœžœ ˜-Kš œ žœžœžœžœžœ˜%—šœ™š Ÿ œžœžœžœžœžœ˜AKšžœžœ˜#K˜K˜—š Ÿœžœžœžœžœžœ˜JKš žœžœ žœžœžœ˜3K˜K˜—š Ÿœžœžœžœžœžœ˜PKšžœžœžœžœ&˜BK˜K˜—Kšœžœ žœžœ˜Fš Ÿœžœžœžœ žœžœ˜DKšœžœ˜ šžœžœžœ ž˜K˜ K˜ Kšžœ˜—K˜K˜—š Ÿœžœžœžœžœ˜AKšžœžœ˜&K˜K˜—˜šŸœžœBžœ˜]š žœžœžœžœžœžœ˜5šžœ˜˜Kšžœžœžœ˜&K˜—K˜—K˜—šŸœžœ žœG˜lKšœžœ!˜,Kšœžœ!˜,šœžœ ˜-Jšœ+™+—šœžœ"˜-Jšœ;™;—Kšœžœ˜"————šœžœžœžœ˜0Jšœ ™ KšœžœžœžœΟc˜PKšœžœ (˜5Kšœžœ  ˜™>K˜Kšœžœžœ˜K˜—šŸ œžœžœžœ˜4Jšœ7™7K˜K˜—š Ÿ œžœžœ žœžœ˜>JšœB™BK˜K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜K˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜K˜K˜K˜K˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜K˜K˜K˜K˜K˜K˜K˜Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜K˜K˜K˜Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜K˜Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜šŸœžœžœ˜˜Kšœžœ ˜'Kšœžœ ˜,˜Jšœ2™2—Kšœžœ ˜-š œžœžœžœ žœ ˜IJšœ,™,—šŸ œžœžœ˜Jšœ>™>K˜K˜Kšœžœžœ˜Kšœž œ ž œ ˜)K˜—šŸ œžœžœžœ˜4Jšœ<™JšœB™BKšœž œ ˜Kšžœžœ ž œ˜:K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜Kšžœžœ ˜%K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜K˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜K˜K˜K˜K˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜K˜K˜K˜K˜K˜K˜K˜Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜K˜K˜K˜Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜K˜Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜—Kšžœ žœžœ˜/K˜šžœžœžœ˜!šžœžœ žœžœ˜,šžœ˜Jšœ*™*K˜Kšœ žœžœ˜-K˜>Kšœ žœžœ˜-Kšžœ˜—K˜——K˜—K˜K˜šŸœžœBžœ˜]š žœžœžœžœžœžœ˜5šžœ˜˜Kšžœžœžœžœ˜.K˜—K˜—K˜—šŸœžœ žœG˜lKšœžœ!˜,Kšœžœ!˜,šœžœ ˜-Jšœ+™+—šœžœ"˜-Jšœ;™;—Kšœžœ˜"———šœžœžœžœ˜0Jšœ ™ Kšœžœžœžœ ˜PKšœžœ (˜5Kšœžœ  ˜™>K˜Kšœžœžœ˜K˜—šŸ œžœžœžœ˜4Jšœ7™7K˜K˜—š Ÿ œžœžœ žœžœ˜>JšœB™BK˜K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜K˜K˜Kšœ žœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ˜K˜Kšœ žœ˜K˜Kšœ žœ˜K˜Kšœ žœ˜Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ˜K˜Kšœ žœ˜Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ˜Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜šŸœžœžœ˜˜Kšœžœ ˜'Kšœžœ ˜,˜Jšœ2™2—Kšœžœ ˜-š œžœžœžœ žœ ˜IJšœ,™,—šŸ œžœžœ˜Jšœ>™>K˜K˜Kšœžœžœ˜Kšœž œ ž œ ˜)K˜—šŸ œžœžœžœ˜4Jšœ<™JšœB™BKšœž œ ˜Kšžœžœ ž œ˜:K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜Kšžœžœ ˜%K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜K˜K˜Kšœ žœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ˜K˜Kšœ žœ˜K˜Kšœ žœ˜K˜Kšœ žœ˜Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ˜K˜Kšœ žœ˜Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ˜Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜—Kšžœ žœžœ˜/K˜šžœžœžœ˜!šžœžœ žœžœ˜,šžœ˜Jšœ*™*K˜Kšœ žœžœ˜-K˜>Kšœ žœžœ˜-Kšžœ˜—K˜——K˜—K˜K˜šŸœžœBžœ˜]š žœžœžœžœžœžœ˜5šžœ˜˜Kšžœžœžœžœ˜1K˜—K˜—K˜—šŸœžœ žœG˜lKšœžœ!˜,Kšœžœ!˜,šœžœ ˜-Jšœ+™+—šœžœ"˜-Jšœ;™;—Kšœžœ˜"———šœžœžœžœ˜0Jšœ ™ Kšœžœžœžœ ˜PKšœžœ (˜5Kšœžœ  ˜™>K˜Kšœžœžœ˜K˜—šŸ œžœžœžœ˜4Jšœ7™7K˜K˜—š Ÿ œžœžœ žœžœ˜>JšœB™BK˜K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜$K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜$K˜K˜Kšœ žœ˜$K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ˜$K˜Kšœ žœ˜$K˜Kšœ žœ˜$K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ˜$K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜šŸœžœžœ˜˜Kšœžœ ˜'Kšœžœ ˜,˜Jšœ2™2—Kšœžœ ˜-š œžœžœžœ žœ ˜IJšœ,™,—šŸ œžœžœ˜Jšœ>™>K˜K˜Kšœžœžœ˜Kšœž œ ž œ ˜)K˜—šŸ œžœžœžœ˜4Jšœ<™JšœB™BKšœž œ ˜Kšžœžœ ž œ˜:K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜Kšžœžœ ˜%K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜$K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜$K˜K˜Kšœ žœ˜$K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ˜$K˜Kšœ žœ˜$K˜Kšœ žœ˜$K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ˜$K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜—Kšžœ žœžœ˜/K˜šžœžœžœ˜!šžœžœ žœžœ˜,šžœ˜Jšœ*™*K˜Kšœ žœžœ˜-K˜>Kšœ žœžœ˜-Kšžœ˜—K˜——K˜—K˜K˜šŸœžœBžœ˜]š žœžœžœžœžœžœ˜5šžœ˜˜Kš žœžœžœžœžœ˜9K˜—K˜—K˜—šŸœžœ žœG˜lKšœžœ!˜,Kšœžœ!˜,šœžœ ˜-Jšœ+™+—šœžœ"˜-Jšœ;™;—Kšœžœ˜"———šœžœžœžœ˜0Jšœ ™ Kšœžœžœžœ ˜PKšœžœ (˜5Kšœžœ  ˜™>K˜Kšœžœžœ˜K˜—šŸ œžœžœžœ˜4Jšœ7™7K˜K˜—š Ÿ œžœžœ žœžœ˜>JšœB™BK˜K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜,K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜,K˜K˜Kšœ žœ žœ˜,K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜šŸœžœžœ˜˜Kšœžœ ˜'Kšœžœ ˜,˜Jšœ2™2—Kšœžœ ˜-š œžœžœžœ žœ ˜IJšœ,™,—šŸ œžœžœ˜Jšœ>™>K˜K˜Kšœžœžœ˜Kšœž œ ž œ ˜)K˜—šŸ œžœžœžœ˜4Jšœ<™JšœB™BKšœž œ ˜Kšžœžœ ž œ˜:K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜Kšžœžœ ˜%K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜,K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜,K˜K˜Kšœ žœ žœ˜,K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜—Kšžœ žœžœ˜/K˜šžœžœžœ˜!šžœžœ žœžœ˜,šžœ˜Jšœ*™*K˜Kšœ žœžœ˜-K˜>Kšœ žœžœ˜-Kšžœ˜—K˜——K˜—K˜K˜šŸœžœBžœ˜]š žœžœžœžœžœžœ˜5šžœ˜˜Kšžœžœ ˜K˜—K˜—K˜—šŸœžœ žœG˜lKšœžœ!˜,Kšœžœ!˜,šœžœ ˜-Jšœ+™+—šœžœ"˜-Jšœ;™;—Kšœžœ˜"———šœžœžœžœ˜0Jšœ ™ Kšœžœžœžœ ˜PKšœžœ (˜5Kšœžœ  ˜™>K˜Kšœžœžœ˜K˜—šŸ œžœžœžœ˜4Jšœ7™7K˜K˜—š Ÿ œžœžœ žœžœ˜>JšœB™BK˜K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜#K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜#K˜K˜Kšœ žœ˜#K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ˜#K˜Kšœ žœ˜#K˜Kšœ žœ˜#K˜Kšœ žœ˜#Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ˜#K˜Kšœ žœ˜#Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ˜#Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜šŸœžœžœ˜˜Kšœžœ ˜'Kšœžœ ˜,˜Jšœ2™2—Kšœžœ ˜-š œžœžœžœ žœ ˜IJšœ,™,—šŸ œžœžœ˜Jšœ>™>K˜K˜Kšœžœžœ˜Kšœž œ ž œ ˜)K˜—šŸ œžœžœžœ˜4Jšœ<™JšœB™BKšœž œ ˜Kšžœžœ ž œ˜:K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜Kšžœžœ ˜%K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜#K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜#K˜K˜Kšœ žœ˜#K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ˜#K˜Kšœ žœ˜#K˜Kšœ žœ˜#K˜Kšœ žœ˜#Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ˜#K˜Kšœ žœ˜#Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ˜#Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜—Kšžœ žœžœ˜/K˜šžœžœžœ˜!šžœžœ žœžœ˜,šžœ˜Jšœ*™*K˜Kšœ žœžœ˜-K˜>Kšœ žœžœ˜-Kšžœ˜—K˜——K˜—K˜K˜šŸœžœBžœ˜]š žœžœžœžœžœžœ˜5šžœ˜˜Kšžœžœžœ˜!K˜—K˜—K˜—šŸœžœ žœG˜lKšœžœ!˜,Kšœžœ!˜,šœžœ ˜-Jšœ+™+—šœžœ"˜-Jšœ;™;—Kšœžœ˜"———šœžœžœžœ˜0Jšœ ™ Kšœžœžœžœ ˜PKšœžœ (˜5Kšœžœ  ˜™>K˜Kšœžœžœ˜K˜—šŸ œžœžœžœ˜4Jšœ7™7K˜K˜—š Ÿ œžœžœ žœžœ˜>JšœB™BK˜K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜+K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜+K˜K˜Kšœ žœ žœ˜+K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ žœ˜+K˜Kšœ žœ žœ˜+K˜Kšœ žœ žœ˜+K˜Kšœ žœ žœ˜+Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ žœ˜+K˜Kšœ žœ žœ˜+Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ žœ˜+Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜šŸœžœžœ˜˜Kšœžœ ˜'Kšœžœ ˜,˜Jšœ2™2—Kšœžœ ˜-š œžœžœžœ žœ ˜IJšœ,™,—šŸ œžœžœ˜Jšœ>™>K˜K˜Kšœžœžœ˜Kšœž œ ž œ ˜)K˜—šŸ œžœžœžœ˜4Jšœ<™JšœB™BKšœž œ ˜Kšžœžœ ž œ˜:K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜Kšžœžœ ˜%K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜+K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜+K˜K˜Kšœ žœ žœ˜+K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ žœ˜+K˜Kšœ žœ žœ˜+K˜Kšœ žœ žœ˜+K˜Kšœ žœ žœ˜+Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ žœ˜+K˜Kšœ žœ žœ˜+Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ žœ˜+Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜—Kšžœ žœžœ˜/K˜šžœžœžœ˜!šžœžœ žœžœ˜,šžœ˜Jšœ*™*K˜Kšœ žœžœ˜-K˜>Kšœ žœžœ˜-Kšžœ˜—K˜——K˜—K˜K˜šŸœžœBžœ˜]š žœžœžœžœžœžœ˜5šžœ˜˜Kšžœžœžœžœ˜1K˜—K˜—K˜—šŸœžœ žœG˜lKšœžœ!˜,Kšœžœ!˜,šœžœ ˜-Jšœ+™+—šœžœ"˜-Jšœ;™;—Kšœžœ˜"———šœžœžœžœ˜0Jšœ ™ Kšœžœžœžœ ˜PKšœžœ (˜5Kšœžœ  ˜™>K˜Kšœžœžœ˜K˜—šŸ œžœžœžœ˜4Jšœ7™7K˜K˜—š Ÿ œžœžœ žœžœ˜>JšœB™BK˜K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜$K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜$K˜K˜Kšœ žœ˜$K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ˜$K˜Kšœ žœ˜$K˜Kšœ žœ˜$K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ˜$K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜šŸœžœžœ˜˜Kšœžœ ˜'Kšœžœ ˜,˜Jšœ2™2—Kšœžœ ˜-š œžœžœžœ žœ ˜IJšœ,™,—šŸ œžœžœ˜Jšœ>™>K˜K˜Kšœžœžœ˜Kšœž œ ž œ ˜)K˜—šŸ œžœžœžœ˜4Jšœ<™JšœB™BKšœž œ ˜Kšžœžœ ž œ˜:K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜Kšžœžœ ˜%K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜$K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ˜$K˜K˜Kšœ žœ˜$K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ˜$K˜Kšœ žœ˜$K˜Kšœ žœ˜$K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ˜$K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ˜$Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜—Kšžœ žœžœ˜/K˜šžœžœžœ˜!šžœžœ žœžœ˜,šžœ˜Jšœ*™*K˜Kšœ žœžœ˜-K˜>Kšœ žœžœ˜-Kšžœ˜—K˜——K˜—K˜K˜šŸœžœBžœ˜]š žœžœžœžœžœžœ˜5šžœ˜˜Kš žœžœžœžœžœ˜9K˜—K˜—K˜—šŸœžœ žœG˜lKšœžœ!˜,Kšœžœ!˜,šœžœ ˜-Jšœ+™+—šœžœ"˜-Jšœ;™;—Kšœžœ˜"———šœžœžœžœ˜0Jšœ ™ Kšœžœžœžœ ˜PKšœžœ (˜5Kšœžœ  ˜™>K˜Kšœžœžœ˜K˜—šŸ œžœžœžœ˜4Jšœ7™7K˜K˜—š Ÿ œžœžœ žœžœ˜>JšœB™BK˜K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜,K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜,K˜K˜Kšœ žœ žœ˜,K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜šŸœžœžœ˜˜Kšœžœ ˜'Kšœžœ ˜,˜Jšœ2™2—Kšœžœ ˜-š œžœžœžœ žœ ˜IJšœ,™,—šŸ œžœžœ˜Jšœ>™>K˜K˜Kšœžœžœ˜Kšœž œ ž œ ˜)K˜—šŸ œžœžœžœ˜4Jšœ<™JšœB™BKšœž œ ˜Kšžœžœ ž œ˜:K˜—šŸ œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜Kšžœžœ ˜%K˜—K˜—šžœž˜˜Jšœ7™7Kšœ žœžœ˜&šžœ˜šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜——šž˜šž˜K˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜K˜K˜K˜Kšž˜———K˜—˜˜šž˜K˜K˜Kšœ žœ˜&K˜K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜,K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜˜šž˜K˜K˜Kšœ žœ˜&˜K˜Kšœ žœ žœ˜,K˜K˜Kšœ žœ žœ˜,K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜—K˜—šžœ˜ K˜šž˜Kšœžœžœžœ˜)K˜K˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜ Kšžœ˜—šžœ žœ˜K˜Kšœ žœ žœ˜,K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜ K˜—šžœžœ˜Jšœ™K˜Kšœ žœ žœ˜,Kšœžœžœ˜Kšœžœžœ˜K˜—K˜Kšœ žœ˜&Kšžœ žœžœ˜K˜K˜K˜Kšžœ˜—K˜——K˜—K˜—Kšžœ žœžœ˜/K˜šžœžœžœ˜!šžœžœ žœžœ˜,šžœ˜Jšœ*™*K˜Kšœ žœžœ˜-K˜>Kšœ žœžœ˜-Kšžœ˜—K˜——K˜—K˜K˜K˜šœ žœžœ žœžœ žœžœBžœ]˜ίK˜——Kšžœ˜K˜K˜—…—ν¦fΕ