Copyright (C) 1994, Digital Equipment Corp.
UNSAFE MODULE; IMPORT FloatMode, Word; CONST Bits = ARRAY [0..3] OF INTEGER { 8, 16, 32, 64 }; VAR init_done := FALSE; local : T; PROCEDURE RTPacking Local (): T = VAR a: RECORD ch: CHAR; x: EXTENDED; END; b: RECORD ch: CHAR; x: RECORD ch: CHAR; END; END; i: INTEGER := 1; x: ADDRESS := ADR (i); p: UNTRACED REF CHAR := x; BEGIN IF NOT init_done THEN local.word_size := SizeOf (ADRSIZE (INTEGER)); local.max_align := SizeOf (ADR (a.x) - ADR (a.ch)); local.struct_align := SizeOf (ADR (b.x) - ADR (b.ch)); local.little_endian := (p^ = VAL (1, CHAR)); local.float := FloatKind.IEEE; IF NOT FloatMode.IEEE THEN local.float := FloatKind.VAX; END; init_done := TRUE; END; RETURN local; END Local; PROCEDURESizeOf (n: INTEGER): CARDINAL = BEGIN (* convert address units to bits *) n := n DIV ADRSIZE(CHAR) * BITSIZE(CHAR); (* look for a known size *) FOR i := FIRST (Bits) TO LAST (Bits) DO IF (Bits[i] = n) THEN RETURN n; END; END; <*ASSERT FALSE*> END SizeOf; PROCEDUREEncode (READONLY t: T): INTEGER = VAR n := 0; BEGIN n := Word.Or (Word.Shift (n, 2), BitSize (t.word_size)); n := Word.Or (Word.Shift (n, 2), BitSize (t.max_align)); n := Word.Or (Word.Shift (n, 2), BitSize (t.struct_align)); n := Word.Or (Word.Shift (n, 1), ORD (t.little_endian)); n := Word.Or (Word.Shift (n, 2), ORD (t.float)); RETURN n; END Encode; PROCEDUREDecode (i: INTEGER): T = VAR t: T; BEGIN t.float := VAL (Word.And (i, 3), FloatKind); i := Word.Shift (i, -2); t.little_endian := VAL (Word.And (i, 1), BOOLEAN); i := Word.Shift (i, -1); t.struct_align := Bits[Word.And (i, 3)]; i := Word.Shift (i, -2); t.max_align := Bits[Word.And (i, 3)]; i := Word.Shift (i, -2); t.word_size := Bits[Word.And (i, 3)]; i := Word.Shift (i, -2); <*ASSERT i = 0*> RETURN t; END Decode; PROCEDUREBitSize (n: CARDINAL): CARDINAL = BEGIN FOR i := FIRST (Bits) TO LAST (Bits) DO IF (Bits[i] = n) THEN RETURN i; END; END; <*ASSERT FALSE*> END BitSize; BEGIN END RTPacking.