Checksum.mesa
For Portable Cedar
Copyright Ó 1985, 1988, 1991 by Xerox Corporation. All rights reserved.
Forrest, October 4, 1980 2:03 PM
Russ Atkinson (RRA) January 29, 1985 0:37:17 am PST
Carl Hauser, January 14, 1988 2:15:24 pm PST
Willie-s, May 14, 1991 4:54 pm PDT
Doug Wyatt, August 27, 1991 1:52 pm PDT
DIRECTORY
Basics, Basics16;
Checksum: CEDAR DEFINITIONS IMPORTS Basics ~ BEGIN
bitsPerHalfWord: NAT ~ Basics16.bitsPerWord;
bytesPerHalfWord: NAT ~ Basics16.bytesPerWord;
ComputeChecksum:
PROC [
cs:
CARD16 ¬ 0, nHalfWords:
CARDINAL, p:
POINTER, offset:
CARDINAL ¬ 0]
RETURNS [checksum:
CARD16];
... produces a checksum for nHalfWords starting at offset halfwords from p. Start with initial value cs (useful if forming a single checksum for discontinuous areas of memory). Note that since these checksums must be backward compatible they are 16 bit checksums computed over an integral number of 16 bit halfwords, even on a 32 bit machine.
I would like to add a mathematical definition of the checksum being computed-- chh.
ComputeChecksumINLINE:
PROC[
cs:
CARD16 ¬ 0, nHalfWords:
CARDINAL, p:
POINTER, offset:
CARDINAL ¬ 0]
RETURNS [checksum:
CARD16]
= INLINE { RETURN[ComputeChecksumSoftware[cs, nHalfWords, p, offset]] };
ComputeChecksumINLINE for when you just can't afford a procedure call; beware of the debugging liabilities caused by large INLINE procedures.
ComputeChecksumSoftware is provided as documentation and an initial implementation.
On the Dorado, this implementation is 180 times slower than the microcode at computing the checksum for 32767 characters and it takes 1.8 seconds (vs. 10 ms).
ComputeChecksumSoftware:
PROC [
cs:
CARD16 ¬ 0, nHalfWords:
CARDINAL, p:
POINTER, offset:
CARDINAL]
RETURNS [checksum:
CARD16]
=
TRUSTED
INLINE {
phw: POINTER TO Basics16.RawWords ¬ LOOPHOLE[p];
FOR i:
CARDINAL
IN [offset..nHalfWords+offset)
DO
t: CARD32;
w: CARD32 = phw[i];
cs ← ((cs ONESADD p^) LEFTROTATE 1) -- implemented by:
t ¬ cs + w;
t ¬ Basics.LowHalf[t] + Basics.HighHalf[t];
t ¬ 2*t;
cs ¬ Basics.LowHalf[t] + Basics.HighHalf[t];
ENDLOOP;
IF cs = 177777B THEN cs ¬ 0;
RETURN[cs];
};
END.