(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: BitSize.m3 *) (* Last Modified On Fri Apr 27 00:55:38 1990 By muller *) (* Modified On Fri Jul 14 17:02:47 1989 By kalsow *) MODULE BitSize; IMPORT CallExpr, Expr, Type, Procedure, IntegerExpr, Address, Text; IMPORT TypeExpr, ArrayType, Emit, Error, Card, Temp, Target, NamedType; VAR Z: CallExpr.MethodList; PROCEDURE Bind (<*UNUSED*> proc: Expr.T; <*UNUSED*> args: Expr.List): Type.T = BEGIN RETURN Card.T; END Bind; PROCEDURE Check (<*UNUSED*> proc: Expr.T; VAR args: Expr.List) = BEGIN CheckArg ("BITSIZE", args); END Check; PROCEDURE Compile (<*UNUSED*> proc: Expr.T; args: Expr.List): Temp.T = BEGIN RETURN Gen (args[0], 1); END Compile; PROCEDURE Fold (<*UNUSED*> proc: Expr.T; args: Expr.List): Expr.T = BEGIN RETURN GetSize (args[0], 1); END Fold; PROCEDURE CheckArg (name: Text.T; args: Expr.List) = VAR t, index, element: Type.T; BEGIN IF Expr.IsDesignator (args[0]) THEN (* ok *) ELSIF TypeExpr.Split (args[0], t) THEN IF ArrayType.Split (t, index, element) AND (index = NIL) THEN Error.ID (name, "argument cannot be an open array type"); END; ELSE Error.ID (name, "argument must be a designator or type"); END; END CheckArg; PROCEDURE Gen (e: Expr.T; unit: INTEGER): Temp.T = VAR t, index, element: Type.T; x, y: Temp.T; BEGIN x := Temp.AllocEmpty (Card.T); IF NOT TypeExpr.Split (e, t) THEN t := NamedType.Strip (Expr.TypeOf (e)); IF ArrayType.Split (t, index, element) AND (index = NIL) THEN y := Expr.Compile (e); Emit.OpIT ("{\001\nregister t@* bitsize = & @;\n", Type.Name (ArrayType.OpenImpl (t)), y); Emit.OpT ("@ = ", x); FOR i := 0 TO ArrayType.OpenDepth (t) - 1 DO Emit.OpI ("bitsize->size[@] * ", i); END; Emit.OpI ("@;\n", (Type.Size (ArrayType.OpenType (t)) + unit - 1) DIV unit); Emit.Op ("\002}\n"); Temp.Free (y); RETURN x; END; END; Emit.OpTI ("@ = @;\n", x, (Type.Size (t) + unit - 1) DIV unit); RETURN x; END Gen; PROCEDURE GetSize (e: Expr.T; unit: INTEGER): Expr.T = VAR t, index, element: Type.T; BEGIN e := Expr.ConstValue (e); IF (e = NIL) THEN RETURN NIL END; IF NOT TypeExpr.Split (e, t) THEN t := NamedType.Strip (Expr.TypeOf (e)); IF ArrayType.Split (t, index, element) AND (index = NIL) THEN RETURN NIL; END; END; RETURN IntegerExpr.New ((Type.Size (t) + unit - 1) DIV unit); END GetSize; PROCEDURE Initialize () = BEGIN Z := CallExpr.NewMethodList (1, 1, TRUE, Bind, Check, Compile, Fold, CallExpr.IsNever, (* writable *) CallExpr.IsNever(* designator *)); Procedure.Define ("BITSIZE", Z); END Initialize; BEGIN END BitSize.