(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: WordInsert.m3 *) (* Last Modified On Tue Jun 30 09:34:56 PDT 1992 By kalsow *) (* Modified On Thu Mar 7 20:20:02 1991 By muller *) MODULE WordInsert; IMPORT Word, CallExpr, Expr, Type, Procedure, Emit, Fault; IMPORT Int, IntegerExpr, ProcType, Error; IMPORT Target, Value, Formal, BuiltinArgs, Temp, Host; VAR Z: CallExpr.MethodList; VAR formals: ARRAY [0..3] OF Value.T; PROCEDURE Check (<*UNUSED*> proc: Expr.T; VAR args: Expr.List; VAR cs: Expr.CheckState): Type.T = BEGIN EVAL Formal.CheckArgs (cs, args, formals); RETURN Int.T; END Check; PROCEDURE Compile (<*UNUSED*> proc: Expr.T; args: Expr.List): Temp.T = VAR t1, t2, t3, t4, tx, ty, ti, tn, tm, to: Temp.T; BEGIN t1 := Expr.Compile (args[0]); t2 := Expr.Compile (args[1]); t3 := Expr.Compile (args[2]); t4 := Expr.Compile (args[3]); tx := Temp.AllocEmpty (Int.T); ty := Temp.AllocEmpty (Int.T); ti := Temp.AllocEmpty (Int.T); tn := Temp.AllocEmpty (Int.T); tm := Temp.AllocEmpty (Int.T); to := Temp.AllocEmpty (Int.T); Emit.OpTT ("@ = @;\n", tx, t1); Emit.OpTT ("@ = @;\n", ty, t2); Emit.OpTT ("@ = @;\n", ti, t3); Emit.OpTT ("@ = @;\n", tn, t4); IF Host.doRangeChk THEN Emit.OpTT ("if (@ + @ > ", ti, tn); Emit.OpI ("@) ", Target.INTSIZE); Fault.Range (); END; Emit.OpTI ("if (@ == @)\n\001", ti, Target.INTSIZE); Emit.OpTT ("{ @ = @; }\n", to, tx); Emit.OpTT ("\002else if ((@+@) == ", ti, tn); Emit.OpI ("@) {\n\001", Target.INTSIZE); Emit.OpTTT ("@ = ((~((unsigned) (~0) << @)) & @) ", to, ti, tx); Emit.OpTT ("| ((unsigned)@ << @); }\n", ty, ti); Emit.Op ("\002else {\n\001"); Emit.OpTTT ("@ = ((unsigned)(~0) << (@+@)) | ", tm, tn, ti); Emit.OpT ("(~ ((unsigned)(~0) << @));\n", ti); Emit.OpTTT ("@ = (@ & @) | ", to, tm, tx); Emit.OpTTT ("((@ << @) & (~@));\n\002}\n", ty, ti, tm); Temp.Free (t1); Temp.Free (t2); Temp.Free (t3); Temp.Free (t4); Temp.Free (tx); Temp.Free (ty); Temp.Free (ti); Temp.Free (tn); Temp.Free (tm); RETURN to; END Compile; PROCEDURE Fold (<*UNUSED*> proc: Expr.T; args: Expr.List): Expr.T = VAR e0, e1, e2, e3: Expr.T; w0, w1: Word.T; i2, i3: INTEGER; BEGIN e0 := Expr.ConstValue (args[0]); e1 := Expr.ConstValue (args[1]); e2 := Expr.ConstValue (args[2]); e3 := Expr.ConstValue (args[3]); IF (e0 = NIL) OR ( NOT IntegerExpr.Split (e0, w0)) OR (e1 = NIL) OR ( NOT IntegerExpr.Split (e1, w1)) OR (e2 = NIL) OR ( NOT IntegerExpr.Split (e2, i2)) OR (e3 = NIL) OR ( NOT IntegerExpr.Split (e3, i3)) THEN RETURN NIL; END; IF (i2 + i3 > Target.INTSIZE) THEN Error.Msg ("Word.Insert: i+n > Word.Size"); w0 := 0; w1 := 0; END; RETURN IntegerExpr.New (Word.Insert (w0, w1, i2, i3)); END Fold; PROCEDURE Initialize () = BEGIN formals[0] := BuiltinArgs.f1; formals[1] := BuiltinArgs.f5; formals[2] := BuiltinArgs.f11; formals[3] := BuiltinArgs.f12; Z := CallExpr.NewMethodList (4, 4, TRUE, TRUE, Int.T, NIL, Check, Compile, Fold, CallExpr.IsNever, (* writable *) CallExpr.IsNever, (* designator *) CallExpr.NotWritable (* noteWriter *)); Procedure.Define ("Insert", Z, FALSE, ProcType.New (formals, Int.T)); END Initialize; BEGIN END WordInsert.