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 ]; 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]] }; 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] ~ TRUSTED MACHINE CODE { "*#define XRM_BITLSHIFT(x, y) ((word)(x) << (word)(y)).XRM_BITLSHIFT" }; BITRSHIFT: PROC [value: WORD, count: [0..bitsPerWord)] RETURNS [WORD] ~ TRUSTED MACHINE CODE { "*#define XRM_BITRSHIFT(x, y) ((word)(x) >> (word)(y)).XRM_BITRSHIFT" }; BITSHIFT: PROC [value: WORD, count: INTEGER] RETURNS [WORD] ~ 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" }; 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. δ Basics.mesa For Sun-3, Sun-4, and other big-endian, 32-bit processors Copyright Σ 1985, 1988, 1989, 1991 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) February 27, 1985 8:10:50 pm PST Carl Hauser, July 11, 1988 3:12:38 pm PDT JKF August 26, 1988 12:50:28 pm PDT Willie-s, July 25, 1991 2:56 pm PDT Michael Plass, September 27, 1991 9:29 am PDT Doug Wyatt, August 27, 1991 4:38 pm PDT Commonly-used types and values Caution: bytes and bits not necessarily in significance order! Caution: bytes and bits not necessarily in significance order! ... describes the byte sequence base[startIndex..startIndex+count). Arithmetic utilities ... cheaply tests whether n is odd; equivalent to (but faster than) (n MOD 2)#0. Bounds checking Effect is ... ERROR RuntimeError.BoundsFault; Effect is ... { IF ptr=NIL THEN ERROR RuntimeError.NilFault; RETURN[ptr] }; Control links Logic utilities ... left-shifts the value by the count. ... right-shifts the value by the count. ... 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. Block copying utilities Copies a block of words: for all i in [0..count), dst[i] ¬ src[i]. The order of transfer is unspecified; destination and source should be disjoint. Moves a block of words: ripples in proper order if destination and source overlap. Fills a block of words with a constant: for all i in [0..count), dst[i] ¬ value. Copies a block of bytes: for all i in [0..count), dstBase[dstStart+i] ¬ srcBase[srcStart+i]. The order of transfer is unspecified; destination and source should be disjoint. Moves a block of bytes: ripples in proper order if destination and source overlap. Fills a block of bytes with a constant: for all i in [0..count), dstBase[dstStart+i] ¬ value. Retained for compatibility. The effect is ... nBytes ¬ MIN[ MAX[to.startIndex, to.stopIndexPlusOne] - to.startIndex, MAX[from.startIndex, from.stopIndexPlusOne] - from.startIndex ]; MoveBytes[to.blockPointer, to.startIndex, from.blockPointer, from.startIndex, nBytes]; 32 and 16 bit types and operations Caution: bits not necessarily in significance order! Caution: bits not necessarily in significance order! Endian types and operations These definitions are for things that "go on the wire"; well, mostly communication, but arguably anything that has an external representation that passes between machines, e.g. tape drives and floppy disks. Some machines are big endian, some are little endian... Dorados, DLions, IBM 360s, Motorola 68000s, and SPARCs are big endian; PDP-11s, VAXes and Intel are little endian. PrincOps LONGs are word swapped from a clean big endian viewpoint. Beware: Many Cedar programs, in particular RPC, send raw PrincOps (word swapped) LONGs on the wire. Don't use CARD, CARDINAL, INT, INTEGER, WORD, or subranges bigger than a BYTE in the definition of any record going to or coming from the wire. Enumerated types bigger than a BYTE (ErrorCodes, for example) won't work either. Carl Hauser, October 13, 1986 11:23:32 am PDT Working on conversion for Dragon . changes to: LongNumber reordered contained words, bytes and bits; renamed the tags and subfields ShortNumber retyped the subfields; renamed the tags and subfields UnsafeBlock retyped the base field. Carl Hauser, June 11, 1987 4:10:57 pm PDT added the Endian types and operations. Carl Hauser, March 24, 1988 11:07:21 am PST Removed VM parameters. Get them from the VM interface. Jim Foote, August 26, 1988 10:50:59 am PDT Added FillBytes, changed Fill to FillWords, added IsBound. Michael Plass, August 2, 1991 11:54:50 am PDT Moved the (unimplemented) arithmetic section to the (new) BasicArithmetic interface. Removed the ERROR declarations; they were unused and redundant with RuntimeError. ΚŠ–(cedarcode) style•NewlineDelimiter ™codešœ ™ KšΟb9™9Kšœ ΟeœC™NJ™4K™)K™#K™#K™-K™'—K˜KšΟnœΟkœ  œ œ˜"head™Kšœ  œ œ œ˜Kšœ  œ œ œ˜Kšœ œ œ œΟc˜4Kšœ œ œ œ‘˜7Kšœ œ œ œ˜ šœ œ œ œ˜"K˜—Kšœ œ œ‘˜LKšœ œ œ˜-Kšœ œ œ˜/Kšœ œ œ˜/šœ œ œ˜1K˜—Kšœ  œ˜Kšœ œ˜%Kšœ œ˜!šœ œ˜'K™—š œ œ œ  œ œ‘˜;š œ œ ˜Kš œ œ‘ Πck‘’‘’‘’‘˜;Kš œ  œ‘ ’‘’‘’‘’‘˜6Kš œ œ‘ ’‘’‘’‘’‘˜7Kš œ œ œ œ œ˜9š œ œ œ œ œ˜6K™>—Kš ˜—Kšœ˜K˜—š œ œ œ  œ œ‘˜=š œ œ ˜Kšœ œ˜Kšœ  œ˜Kšœ œ˜Kš œ œ œ œ œ˜:š œ œ œ œ œ˜7K™>—Kš ˜—Kšœ˜K˜—Kšœ œ(˜?šœ  œ%˜5K™—Kšœ  œ œ œ œ œ œ œ˜9Kšœ  œ œ œ œ œ œ œ˜9Kšœ  œ œ œ œ œ œ œ˜@Kšœ  œ œ œ œ œ œ œ˜@šœ  œ œ œ œ œ œ œ˜IK™—šœ  œ œ˜Kšœ œ œ  œ˜ Kšœ  œ˜Kšœ œ˜Kšœ˜KšœC™CK™——šœ™šŸ œ œ œ œ ˜3Kšœ œ œ œ œ œ œ œ  œ ˜JK˜—šŸ œ œ œ œ ˜1šœ œ œ œ œ œ œ œ  œ ˜JK™——šŸ œ œ œ  œ œ œ  œ œ œ  œ œ ˜”Kšœ  œ œ œ˜0K˜—š Ÿœ œ œ œ œ˜&Kš œ œ œ œ œ˜#KšœG œ™PK™—š Ÿœ œ œ œ œ˜$Kšœ œ œ  œ˜+——™š Ÿ œ œ  œ œ œ œ˜6Kšœ œ œ ˜K˜—š Ÿ œ œ œ œ œ˜3Kš œ œ œ œ œ ˜CK˜—šŸœ œ œ  œ œ œ œ œ˜Mšœ œ˜ Kš œ œ œ  œ˜8Kš œ œ˜Kšœ˜—K˜—šŸœ ˜Kšœ œ  œ˜Iasciišœ˜Kšœ˜Kšœ œ™-K˜—š Ÿœ œ œ œ œ˜0Kšœ œ  œ˜Mšœ ˜ Kšœ˜Kš œ œ œ œ œ‘œ œ™K——šœ ™ šŸœ œ œ œ œ œ œ œ˜:Kšœ œ œ œ˜Mšœ ˜ Kšœ˜——šœ™š Πbkœ œ œ œ œ œ˜(Kšœ œ œ œ˜MšœB˜BKšœ˜K˜—š £œ œ œ œ œ œ˜'Kšœ œ œ œ˜Mšœ@˜@Kšœ˜K˜—š £œ œ œ œ œ œ˜(Kšœ œ œ œ˜MšœB˜BKšœ˜K˜—š £œ œ œ œ œ˜"Kšœ œ œ œ˜MšœΟfœ˜3Kšœ˜K˜—š Πkn œ œ  œ œ œ˜EKšœ)™)Kšœ œ œ œ˜Mšœ€œ€œ˜EK˜K˜—š ₯ œ œ  œ œ œ˜EKšœ)™)Kšœ œ œ œ˜Mšœ€œ€œ˜EK˜K™—š ₯œ œ  œ  œ œ œ˜;Kšœ…™…Kšœ œ œ œ˜Mšœ˜K˜——šœ™šŸ œ œ œ œ œ œ œ œ˜_Kšœ  œ  œ˜Mšœ˜Kšœ˜KšœB™BK™PK˜—šŸ œ œ œ œ œ œ œ œ˜_Kšœ  œ  œ˜Mšœ˜Kšœ˜KšœR™RK˜—šŸ œ œ œ œ œ œ  œ˜QKšœ  œ  œ˜Mšœ˜Kšœ˜KšœP™PK™—šŸ œ œ œ  œ œ œ  œ œ œ  œ˜‡Kšœ  œ  œ˜Mšœ˜Kšœ˜Kšœ\™\K™PK˜—šŸ œ œ œ  œ œ œ  œ œ œ  œ˜‡Kšœ  œ  œ˜Mšœ˜Kšœ˜KšœR™RK˜—šŸ œ œ œ  œ œ œ  œ  œ˜eKšœ  œ  œ˜Mšœ˜Kšœ˜Kšœ]™]K™—šŸœ œ œ  œ œ œ  œ œ œ  œ˜„Kšœ  œ œ œ˜-K˜—šŸœ œ œ  œ œ œ  œ œ œ  œ˜„Kšœ  œ œ œ˜-K˜—šŸœ œ œ  œ œ œ  œ  œ˜cKšœ  œ œ œ˜-K˜—š œ œ œ œ  œ˜\K˜—š Ÿœ œ œ œ  œ˜HKšœ œ  œ˜Mšœ˜Kšœ˜™.šœ  œ™ Kš œ5™8Kš œ:™=Kšœ™—KšœV™V—K˜——šœ"™"Kšœ  œ ‘˜8š œ œ œ  œ œ‘ ˜4š œ œ ˜Kšœ œ˜Kšœ  œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜ š œ œ œ  œ œ˜-K™4—Kš œ  œ œ‘&’‘’‘˜VKš ˜—Kšœ˜K™—š œ œ œ  œ œ‘ ˜4š œ œ ˜Kšœ œ˜Kšœ  œ˜Kšœ œ˜š œ œ œ  œ œ˜-K™4—Kš ˜—Kšœ˜K˜—š Ÿœ œ œ œ œ˜*Kšœ œ œ œ ˜!K˜—š Ÿœ œ œ œ œ˜+Kšœ œ œ˜K˜—š Ÿœ œ œ œ œ˜(Kšœ œ œ œ ˜ K˜—š Ÿœ œ œ œ œ˜)Kšœ œ œ ˜K˜——™Kš  œ œ œ  œ œ  œ˜6š  œ œ œ  œ œ  œ˜7K™ΞKšœͺ™ͺKšœ Οsœb œ#¦œ™§Kš œ  œ œ œ œ œc œ-™αK™—š Ÿ œ œ œ œ œ˜-Kšœ œ œ œ˜!K˜—š Ÿ œ œ œ œ œ˜+Kšœ œ œ œ˜!K˜—š Ÿ œ œ œ œ œ˜-Kšœ œ œ œ˜!K˜—š Ÿ œ œ œ œ œ˜+Kšœ œ œ œ˜!K˜—š Ÿ œ œ œ œ œ˜-Kšœ œ œ œ˜!K˜—š Ÿ œ œ œ œ œ˜+Kšœ œ œ œ˜!K˜—š Ÿ œ œ œ œ œ˜-Kšœ œ œ œ˜!K˜—š Ÿ œ œ œ œ œ˜+Kšœ œ˜ Kš œ œ œ  œ œ˜6Kš œ ˜Kšœ˜K˜——K˜š œ˜K™™-K™"šœ ™ KšΟr œ*§œ§™UKš§ œ§œ§™BKš§ œ™#——™)Kš§&™&—™+Kšœ5§™6—™*Kšœ9§™:—™-K™TK™Q—K™——…—T<Β