(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: WordExtract.m3 *) (* Last Modified On Sat May 19 08:22:49 1990 By muller *) (* Modified On Fri Aug 4 09:34:50 1989 By kalsow *) MODULE WordExtract; IMPORT Word, CallExpr, Expr, Type, Procedure, Emit; IMPORT Int, IntegerExpr, ProcType, String, Error; IMPORT Target, Value, Formal, BuiltinArgs, Temp; VAR Z: CallExpr.MethodList; formals: ARRAY [0..2] OF Value.T; PROCEDURE Bind (<*UNUSED*> proc: Expr.T; <*UNUSED*> args: Expr.List): Type.T = BEGIN RETURN Int.T; END Bind; PROCEDURE Check (<*UNUSED*> proc: Expr.T; VAR args: Expr.List) = BEGIN IF Formal.CheckArgs (args, formals) THEN END; END Check; PROCEDURE Compile (<*UNUSED*> proc: Expr.T; args: Expr.List): Temp.T = VAR t1, t2, t3, t4, t5, t6, t7: Temp.T; BEGIN t1 := Expr.Compile (args[0]); t2 := Expr.Compile (args[1]); t3 := Expr.Compile (args[2]); t4 := Temp.AllocEmpty (Int.T); t5 := Temp.Alloc (args[1]); t6 := Temp.Alloc (args[2]); t7 := Temp.Alloc (args[0]); Emit.OpTT ("@ = @;\n", t5, t2); Emit.OpTT ("@ = @;\n", t6, t3); Emit.OpTT ("@ = @;\n", t7, t1); Emit.OpTT ("if (@ + @ > ", t5, t6); Emit.OpI ("@) RANGEFAULT;\n", Target.INTSIZE); Emit.OpTT ("@ = (@ ", t4, t6); Emit.OpIT ("== @) ? @ : ", Target.INTSIZE, t7); Emit.OpTI ("((@ == @) ? 0 : ", t5, Target.INTSIZE); Emit.OpTT ("( (((unsigned)@) >> @) & ", t7, t5); Emit.OpT ("~(((unsigned) (~0)) << @) ));\n", t6); Temp.Free (t1); Temp.Free (t2); Temp.Free (t3); Temp.Free (t5); Temp.Free (t6); Temp.Free (t7); RETURN t4; END Compile; PROCEDURE Fold (<*UNUSED*> proc: Expr.T; args: Expr.List): Expr.T = VAR e0, e1, e2: Expr.T; w0: Word.T; i1, i2: INTEGER; BEGIN e0 := Expr.ConstValue (args[0]); e1 := Expr.ConstValue (args[1]); e2 := Expr.ConstValue (args[2]); IF (e0 = NIL) OR ( NOT IntegerExpr.Split (e0, w0)) OR (e1 = NIL) OR ( NOT IntegerExpr.Split (e1, i1)) OR (e2 = NIL) OR ( NOT IntegerExpr.Split (e2, i2)) THEN RETURN NIL; END; IF (i1 + i2 > Target.INTSIZE) THEN Error.Msg ("Word.Extract: i+n > Word.Size"); i1 := 0; i2 := 0; END; RETURN IntegerExpr.New (Word.Extract (w0, i1, i2)); END Fold; PROCEDURE Initialize () = BEGIN formals[0] := BuiltinArgs.f1; formals[1] := BuiltinArgs.f9; formals[2] := BuiltinArgs.f10; Z := CallExpr.NewMethodList (3, 3, TRUE, Bind, Check, Compile, Fold, CallExpr.IsNever, (* writable *) CallExpr.IsNever(* designator *)); Procedure.Define ("Extract", Z, ProcType.New (formals, Int.T)); END Initialize; BEGIN END WordExtract.