<<>> <> <> <> <> <> <> <> <> <> Basics: CEDAR DEFINITIONS ~ BEGIN <> bitsPerByte: NAT ~ BITS[BYTE]; bitsPerWord: NAT ~ BITS[WORD]; bitsPerLongWord: NAT ~ BITS[CARD]; -- = bitsPerWord! bitsPerDWord: NAT ~ BITS[DWORD]; -- = 2*bitsPerLongWord bytesPerWord: NAT ~ BYTES[WORD]; bytesPerDWord: NAT ~ BYTES[DWORD]; logBitsPerByte: NAT ~ BITS[[0..bitsPerByte)]; -- LogBase2[bitsPerByte] (= 3) logBitsPerWord: NAT ~ BITS[[0..bitsPerWord)]; logBitsPerDWord: NAT ~ BITS[[0..bitsPerDWord)]; logBytesPerWord: NAT ~ BITS[[0..bytesPerWord)]; logBytesPerDWord: NAT ~ BITS[[0..bytesPerDWord)]; bitsPerChar: NAT ~ bitsPerByte; logBitsPerChar: NAT ~ logBitsPerByte; charsPerWord: NAT ~ bytesPerWord; logCharsPerWord: NAT ~ logBytesPerWord; <<>> Word: TYPE ~ MACHINE DEPENDENT RECORD [ -- bitsPerWord bits SELECT OVERLAID * FROM card => [card: CARD], -- assert BITS[CARD] = BITS[CARDINAL] int => [int: INT], -- assert BITS[INT] = BITS[INTEGER] real => [real: REAL], -- assert BITS[REAL] = BITS[WORD] bytes => [bytes: PACKED ARRAY [0..bytesPerWord) OF BYTE], bits => [bits: PACKED ARRAY [0..bitsPerWord) OF BOOL], <> ENDCASE ]; DWord: TYPE ~ MACHINE DEPENDENT RECORD [ -- bitsPerDWord bits SELECT OVERLAID * FROM card => [card: DCARD], int => [int: DINT], real => [real: DREAL], bytes => [bytes: PACKED ARRAY [0..bytesPerDWord) OF BYTE], bits => [bits: PACKED ARRAY [0..bitsPerDWord) OF BOOL], <> ENDCASE ]; PartialComparison: TYPE ~ {less, equal, greater, incomparable}; Comparison: TYPE ~ PartialComparison [less..greater]; <<>> RawWords: TYPE ~ RECORD [SEQUENCE COMPUTED CARD OF WORD]; RawCards: TYPE ~ RECORD [SEQUENCE COMPUTED CARD OF CARD]; RawBytes: TYPE ~ RECORD [PACKED SEQUENCE COMPUTED CARD OF BYTE]; RawChars: TYPE ~ RECORD [PACKED SEQUENCE COMPUTED CARD OF CHAR]; RawBits: TYPE ~ RECORD [PACKED SEQUENCE COMPUTED CARD OF CARDINAL[0..1]]; <<>> UnsafeBlock: TYPE ~ RECORD [ base: POINTER TO RawBytes ¬ NIL, startIndex: INT ¬ 0, count: INT ¬ 0 ]; <<... describes the byte sequence base[startIndex..startIndex+count).>> <<>> <> CompareCard: PROC [a, b: CARD] RETURNS [Comparison] ~ INLINE { RETURN[IF a=b THEN equal ELSE IF a>b THEN greater ELSE less] }; CompareInt: PROC [a, b: INT] RETURNS [Comparison] ~ INLINE { RETURN[IF a=b THEN equal ELSE IF a>b THEN greater ELSE less] }; <<>> CompareBits: UNSAFE PROC [ aBase: POINTER TO RawBits, aStart: CARD, bBase: POINTER TO RawBits, bStart: CARD, count: CARDINAL] RETURNS [Comparison] ~ UNCHECKED MACHINE CODE {"Basics_CompareBits"}; OddCard: PROC [n: CARD] RETURNS [BOOL] ~ INLINE { RETURN [VAL[n MOD 2]] }; <<... cheaply tests whether n is odd; equivalent to (but faster than) (n MOD 2)#0.>> <<>> OddInt: PROC [n: INT] RETURNS [BOOL] ~ INLINE { RETURN [OddCard[LOOPHOLE[n]]] }; <> NonNegative: PROC [value: INT] RETURNS [[0..INT.LAST]] ~ INLINE { RETURN[value] }; BoundsCheck: PROC [arg, limit: WORD] RETURNS [WORD] ~ INLINE { IF arg >= limit THEN RaiseBoundsFault[]; RETURN [arg] }; BoundsCheckInt: PROC [arg: INT, limit: [0..INT.LAST]] RETURNS [[0..INT.LAST)] ~ INLINE { IF LOOPHOLE[arg, CARD] >= limit THEN RaiseBoundsFault[]; RETURN [LOOPHOLE[arg]]; }; RaiseBoundsFault: PROC ~ TRUSTED MACHINE CODE { "XR_RaiseBoundsFault" }; <> NilCheck: PROC [ptr: POINTER] RETURNS [POINTER] ~ TRUSTED MACHINE CODE { "XR_NilCheck" }; <> <> IsBound: PROC [proc: PROC ANY RETURNS ANY] RETURNS [BOOL] ~ TRUSTED MACHINE CODE { "XR_IsBound" }; <> BITAND: PROC [WORD, WORD] RETURNS [WORD] ~ TRUSTED MACHINE CODE { "*#define XRM_BITAND(x, y) (((word)(x)) & ((word)(y))).XRM_BITAND" }; BITOR: PROC [WORD, WORD] RETURNS [WORD] ~ TRUSTED MACHINE CODE { "*#define XRM_BITOR(x, y) (((word)(x)) | ((word)(y))).XRM_BITOR" }; BITXOR: PROC [WORD, WORD] RETURNS [WORD] ~ TRUSTED MACHINE CODE { "*#define XRM_BITXOR(x, y) (((word)(x)) ^ ((word)(y))).XRM_BITXOR" }; BITNOT: PROC [WORD] RETURNS [WORD] ~ TRUSTED MACHINE CODE { "*#define XRM_BITNOT(x) (~((word)(x))).XRM_BITNOT" }; BITLSHIFT: PROC [value: WORD, count: [0..bitsPerWord)] RETURNS [WORD] <<... left-shifts the value by the count. >> ~ TRUSTED MACHINE CODE { "*#define XRM_BITLSHIFT(x, y) ((word)(x) << (word)(y)).XRM_BITLSHIFT" }; BITRSHIFT: PROC [value: WORD, count: [0..bitsPerWord)] RETURNS [WORD] <<... right-shifts the value by the count. >> ~ TRUSTED MACHINE CODE { "*#define XRM_BITRSHIFT(x, y) ((word)(x) >> (word)(y)).XRM_BITRSHIFT" }; <<>> BITSHIFT: PROC [value: WORD, count: INTEGER] RETURNS [WORD] <<... shifts the value by the count. If count is positive, the shift is to the left. If count is negative, the shift is to the right.>> ~ TRUSTED MACHINE CODE { "Basics_BITSHIFT" }; <> CopyWords: UNSAFE PROC [ dst: POINTER TO RawWords, src: POINTER TO RawWords, count: CARDINAL] ~ UNCHECKED MACHINE CODE { "Basics_CopyWords" }; <> <> MoveWords: UNSAFE PROC [ dst: POINTER TO RawWords, src: POINTER TO RawWords, count: CARDINAL] ~ UNCHECKED MACHINE CODE { "Basics_MoveWords" }; <> FillWords: UNSAFE PROC [ dst: POINTER TO RawWords, count: CARDINAL, value: WORD] ~ UNCHECKED MACHINE CODE { "Basics_FillWords" }; <> <<>> CopyBytes: UNSAFE PROC [ dstBase: POINTER TO RawBytes, dstStart: CARD, srcBase: POINTER TO RawBytes, srcStart: CARD, count: CARDINAL] ~ UNCHECKED MACHINE CODE { "Basics_CopyBytes" }; <> <> MoveBytes: UNSAFE PROC [ dstBase: POINTER TO RawBytes, dstStart: CARD, srcBase: POINTER TO RawBytes, srcStart: CARD, count: CARDINAL] ~ UNCHECKED MACHINE CODE { "Basics_MoveBytes" }; <> FillBytes: UNSAFE PROC [ dstBase: POINTER TO RawBytes, dstStart: CARD, count: CARDINAL, value: BYTE] ~ UNCHECKED MACHINE CODE { "Basics_FillBytes" }; <> <<>> CopyBits: UNSAFE PROC [ dstBase: POINTER TO RawBits, dstStart: CARD, srcBase: POINTER TO RawBits, srcStart: CARD, count: CARDINAL] ~ UNCHECKED MACHINE CODE {"Basics_CopyBits"}; MoveBits: UNSAFE PROC [ dstBase: POINTER TO RawBits, dstStart: CARD, srcBase: POINTER TO RawBits, srcStart: CARD, count: CARDINAL] ~ UNCHECKED MACHINE CODE {"Basics_MoveBits"}; FillBits: UNSAFE PROC [ dstBase: POINTER TO RawBits, dstStart: CARD, count: CARDINAL, value: WORD] ~ UNCHECKED MACHINE CODE {"Basics_FillBits"}; ByteBltBlock: TYPE ~ RECORD [blockPointer: POINTER, startIndex, stopIndexPlusOne: CARDINAL]; ByteBlt: UNSAFE PROC [to, from: ByteBltBlock] RETURNS [nBytes: CARDINAL] ~ TRUSTED MACHINE CODE { "Basics_ByteBlt" }; <> <> <> <> <<];>> <> <<32 and 16 bit types and operations>> LongNumber: TYPE ~ Word32; -- for backward compatibility Word32: TYPE ~ MACHINE DEPENDENT RECORD [ -- 32 bits SELECT OVERLAID * FROM card => [card: CARD32], int => [int: INT32], real => [real: REAL32], pair => [hi, lo: CARD16], bytes => [hh, hl, lh, ll: BYTE], bits => [bits: PACKED ARRAY [0..32) OF BOOL], <> lc => [lc: CARD], li => [li: INT], -- for backward compatibility; assert BITS[CARD]=32 ENDCASE ]; <<>> Word16: TYPE ~ MACHINE DEPENDENT RECORD [ -- 16 bits SELECT OVERLAID * FROM card => [card: CARD16], int => [int: INT16], pair => [hi, lo: BYTE], bits => [bits: PACKED ARRAY [0..16) OF BOOL], <> ENDCASE ]; LowHalf: PROC [n: CARD32] RETURNS [CARD16] ~ INLINE { RETURN[n MOD 2**16] }; HighHalf: PROC [n: CARD32] RETURNS [CARD16] ~ INLINE { RETURN[n / 2**16] }; LowByte: PROC [n: CARD16] RETURNS [BYTE] ~ INLINE { RETURN[n MOD 2**8] }; HighByte: PROC [n: CARD16] RETURNS [BYTE] ~ INLINE { RETURN[n / 2**8] }; <> HWORD: TYPE ~ MACHINE DEPENDENT RECORD [hi, lo: BYTE]; FWORD: TYPE ~ MACHINE DEPENDENT RECORD [hi, lo: HWORD]; <> <> <> <> <<>> FFromCard32: PROC [n: CARD32] RETURNS [FWORD] ~ INLINE { RETURN[LOOPHOLE[n]] }; FFromInt32: PROC [n: INT32] RETURNS [FWORD] ~ INLINE { RETURN[LOOPHOLE[n]] }; Card32FromF: PROC [f: FWORD] RETURNS [CARD32] ~ INLINE { RETURN[LOOPHOLE[f]] }; Int32FromF: PROC [f: FWORD] RETURNS [INT32] ~ INLINE { RETURN[LOOPHOLE[f]] }; HFromCard16: PROC [n: CARD16] RETURNS [HWORD] ~ INLINE { RETURN[LOOPHOLE[n]] }; HFromInt16: PROC [n: INT16] RETURNS [HWORD] ~ INLINE { RETURN[LOOPHOLE[n]] }; Card16FromH: PROC [h: HWORD] RETURNS [CARD16] ~ INLINE { RETURN[LOOPHOLE[h]] }; Int16FromH: PROC [h: HWORD] RETURNS [INT16] ~ INLINE { temp: PACKED RECORD[h0, h1: INT16] ~ [0, LOOPHOLE[h]]; RETURN[temp.h1] }; END. <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>>