Last modified on Tue May 4 10:58:30 PDT 1993 by swart
INTERFACEAn interface useful for writing code that has to explicitly deal with byte ordering and/or word length issues.Swap ;
TYPE Endian = {Big, Little}; VAR endian: Endian; (* This variable is set at initialization. If the endian is not one of Big or Little, initialization will generate a checked runtime error. *) CONST FirstInt32 = -1 - 16_7FFFFFFF; (* This value is computed in such a way that it will have the same value on a 32 bit machine and on a 64 bit machine. On a 32 bit 2's complement machine this is FIRST(INTEGER). *) TYPE Int32 = BITS 32 FOR [FirstInt32 .. 16_7FFFFFFF]; (* The subrange of integer that can be represented in an INTEGER on a 32 bit 2's complement machine. *) PROCEDURE Swap4 (i: Int32): Int32; (* Swaps the bottom four bytes of the argument leaving any remaining bytes, which should just hold the sign bits, as they were. *) TYPE Int16 = BITS 16 FOR [-16_8000 .. 16_7FFF]; PROCEDURE Swap2 (i: Int16): Int16; (* Swaps the bottom two bytes of the argument leaving any remaining bytes, which should just hold the sign bits, as they were. *) TYPE UInt16 = BITS 16 FOR [0 .. 16_FFFF]; PROCEDURE Swap2U (i: UInt16): UInt16; (* Swaps the bottom two bytes of the argument setting the remaining bytes to zero. *) TYPE Int64On32 = RECORD a, b: Int32; END; Int64Pad = BITS 64 - BITSIZE(INTEGER) FOR SET OF [0 .. 63 - BITSIZE(INTEGER)]; Int64On64 = RECORD v : INTEGER; pad: Int64Pad := Int64Pad{}; END;These are two 64 bit types that are useful when writing code that deals with 64 bit integers and checks at runtime which type to use. Since each type is always 64 bits long the compiler will not complain about LOOPHOLEs in the piece of the code that is not being executed.
Note a compiler bug precludes using record constructors for Int64On64.
PROCEDURE Swap8(READONLY i: Int64On32): Int64On32; (* Equivalent to Int64On32{a := Swap4(i.b); b := Swap4(i.a)}. *) PROCEDURE SwapInt(i: INTEGER): INTEGER; (* Swaps all of the bytes of the given integer argument. *) END Swap.