DIRECTORY Basics, BlockRotate; BlockRotateImpl: CEDAR PROGRAM IMPORTS Basics EXPORTS BlockRotate = BEGIN WordPtr: TYPE = POINTER TO WORD; RawBytesPtr: TYPE = POINTER TO RawBytes; RawBytes: TYPE = Basics.RawBytes; RotateLeft: PUBLIC UNSAFE PROC [src: WordPtr, srcPitch: INTEGER, dst: WordPtr, dstPitch: INTEGER] RETURNS [nz: WORD] = UNCHECKED { dstInc: INTEGER = dstPitch*8; dst _ dst + (BITS[WORD]-1)*dstPitch; src _ src + (BITS[WORD]-1)*srcPitch; dstPitch _ - dstPitch; srcPitch _ - srcPitch; nz ¬ Rotate8x32[LOOPHOLE[src], 0, srcPitch, dst, dstPitch]; FOR i: [0..BYTES[WORD]) IN (0..BYTES[WORD]) DO  dst _ dst - dstInc; nz ¬ Basics.BITOR[nz, Rotate8x32[LOOPHOLE[src], &i, srcPitch, dst, dstPitch]]; ENDLOOP; }; RotateRight: PUBLIC UNSAFE PROC [src: WordPtr, srcPitch: INTEGER, dst: WordPtr, dstPitch: INTEGER] RETURNS [nz: WORD] = UNCHECKED { dstInc: INTEGER = dstPitch*8; nz ¬ Rotate8x32[LOOPHOLE[src], 0, srcPitch, dst, dstPitch]; FOR i: [0..BYTES[WORD]) IN (0..BYTES[WORD]) DO  dst _ dst + dstInc; nz ¬ Basics.BITOR[nz, Rotate8x32[LOOPHOLE[src], &i, srcPitch, dst, dstPitch]]; ENDLOOP; }; Rotate8x32: PUBLIC UNSAFE PROC [src: RawBytesPtr, srcOff: INTEGER, srcPitch: INTEGER, dst: WordPtr, dstPitch: INTEGER] RETURNS [nz: WORD] = UNCHECKED { BEGIN Inner: PROC [x: [0..8), d: [0..8)] = { y: [0..8) = x+d;  w _ Basics.BITAND[w&x, mask]; w&x _ Basics.BITAND[mask, Basics.BITRSHIFT[w&x, &d]]; w&x _ w&x + Basics.BITAND[Basics.BITNOT[mask], w&y]; w&y _ w + Basics.BITLSHIFT[Basics.BITAND[mask, w&y], &d];  };  w, w0, w1, w2, w3, w4, w5, w6, w7, mask: WORD; off: INTEGER _ srcOff;  FOR j: [0..BYTES[WORD]) IN [0..BYTES[WORD]) DO shift: NAT = j*8; FOR i: [0..8) IN [0..8) DO IF i # 0 OR j # 0 THEN {  off _ off + srcPitch;  }; IF j = 0 THEN {  w&i _ src[off];  } ELSE {  w _ src[off]; w&i _ w&i + Basics.BITLSHIFT[w, &shift];  }; ENDLOOP; ENDLOOP; nz ¬ Basics.BITOR[Basics.BITOR[Basics.BITOR[Basics.BITOR[Basics.BITOR[Basics.BITOR[Basics.BITOR[w0, w1], w2], w3], w4], w5], w6], w7]; IF nz # 0 THEN { mask _ 55555555h;  Inner[0, 1]; Inner[2, 1]; Inner[4, 1]; Inner[6, 1];  mask _ 33333333h;  Inner[0, 2]; Inner[1, 2]; Inner[4, 2]; Inner[5, 2];  mask _ 0f0f0f0fh;  Inner[0, 4]; Inner[1, 4]; Inner[2, 4]; Inner[3, 4];  }; off _ dstPitch*2; dst^ _ w0; (dst+dstPitch)^ _ w1; dst _ dst + off; dst^ _ w2; (dst+dstPitch)^ _ w3; dst _ dst + off; dst^ _ w4; (dst+dstPitch)^ _ w5; dst _ dst + off; dst^ _ w6; (dst+dstPitch)^ _ w7; END; }; END. Z BlockRotateImpl.meta Copyright Σ 1991, 1992 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) October 23, 1991 3:12 pm PDT Michael Plass, March 6, 1992 1:23 pm PST Fetch section: fetch 32 bytes and assemble into 8 registers Rotate section: recursively rotate using 2*2, 4*4, 8*8 cells Store section: store the 8 registers ΚR•NewlineDelimiter ™code™Kšœ Οeœ7™BK™0K™(—K˜šΟk ˜ K˜K˜—šΟnœžœž˜Kšžœ˜Kšžœ ˜Kšœž˜—K˜Kš œ žœžœžœžœ˜ šœ žœžœžœ ˜(Kšœ žœ˜!—K˜šŸ œžœžœžœžœžœžœžœž œ˜‚Kšœžœ˜Kšœ žœžœ˜%Kšœ žœžœ˜%Kšœ˜Kšœ˜Kšœœœ žœ#˜;šΟtžœžœžœžœžœžœž ˜1K˜Kšœ žœœœ žœ%˜NKš žœ ˜ —K˜K˜—šŸ œžœžœžœžœžœžœžœž œ˜ƒKšœžœ˜Kšœœœ žœ#˜;š žœžœžœžœžœžœž ˜1K˜Kšœ žœœœ žœ%˜NKš žœ ˜ —K˜K˜—šŸ œžœžœžœžœ žœžœžœžœž œ˜—š ž˜šŸœžœ˜&Kš œ  ˜Kšœ žœ ˜Kšœ žœž œ ˜5Kšœžœžœ ˜4Kšœž œžœ˜9Kš œ ˜—Kšœ)žœ˜.Kšœž œ˜K˜K™;K™š žœžœžœžœžœžœž˜0Kšœžœ˜šžœ žœž˜Kš žœžœžœ œ œ˜5šžœ˜šžœ ˜Kšœ ˜—šž ˜Kšœ!ž œ  ˜;——Kšžœ˜—Kšžœ ˜ —˜Kšœžœžœžœžœžœžœžœ'˜—šžœžœ˜K˜K™