<<>> <> <> <> <> 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.