(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: WordRotate.i3 *) (* Last Modified On Tue Jun 30 09:36:32 PDT 1992 By kalsow *) (* Modified On Thu May 17 08:59:11 1990 By muller *) MODULE WordRotate; IMPORT Word, CallExpr, Expr, Type, Procedure, Emit, Target, BuiltinArgs; IMPORT Int, IntegerExpr, Formal, Value, Temp, ProcType; VAR Z, ZL, ZR: CallExpr.MethodList; VAR formals, formalsLR: ARRAY [0..1] 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 CheckLR (<*UNUSED*> proc: Expr.T; VAR args: Expr.List; VAR cs: Expr.CheckState): Type.T = BEGIN EVAL Formal.CheckArgs (cs, args, formalsLR); RETURN Int.T; END CheckLR; PROCEDURE Compile (<*UNUSED*> proc: Expr.T; args: Expr.List): Temp.T = VAR t1, t2, t3, t4, t6, t7: Temp.T; BEGIN t1 := Expr.Compile (args[0]); t2 := Expr.Compile (args[1]); t3 := Temp.AllocEmpty (Int.T); t4 := Temp.AllocEmpty (Int.T); t6 := Temp.Alloc (args[0]); t7 := Temp.Alloc (args[1]); Emit.OpTT ("@ = @;\n", t6, t1); Emit.OpTT ("@ = @;\n", t7, t2); Emit.OpTT ("if (@ < 0)\n\001{ @ = ", t7, t3); Emit.OpI ("@ - ", Target.INTSIZE); Emit.OpTI ("((- @) % @); }\n", t7, Target.INTSIZE); Emit.OpTT ("\002else\n\001{ @ = @ % ", t3, t7); Emit.OpI ("@;\n\002}\n", Target.INTSIZE); Emit.OpTTT ("@ = (((unsigned)@) << @) | ", t4, t6, t3); Emit.OpT ("(((unsigned)@) >> ", t6); Emit.OpIT ("(@ - @));\n", Target.INTSIZE, t3); Temp.Free (t1); Temp.Free (t2); Temp.Free (t3); Temp.Free (t6); Temp.Free (t7); RETURN t4; END Compile; PROCEDURE CompileL (<*UNUSED*> proc: Expr.T; args: Expr.List): Temp.T = VAR t1, t2, t4, t6, t7: Temp.T; BEGIN t1 := Expr.Compile (args[0]); t2 := Expr.Compile (args[1]); t4 := Temp.AllocEmpty (Int.T); t6 := Temp.Alloc (args[0]); t7 := Temp.Alloc (args[1]); Emit.OpTT ("@ = @;\n", t6, t1); Emit.OpTT ("@ = @;\n", t7, t2); Emit.OpTTT ("@ = (((unsigned)@) << @) | ", t4, t6, t7); Emit.OpT ("(((unsigned)@) >> ", t6); Emit.OpIT ("(@ - @));\n", Target.INTSIZE, t7); Temp.Free (t1); Temp.Free (t2); Temp.Free (t6); Temp.Free (t7); RETURN t4; END CompileL; PROCEDURE CompileR (<*UNUSED*> proc: Expr.T; args: Expr.List): Temp.T = VAR t1, t2, t4, t6, t7: Temp.T; BEGIN t1 := Expr.Compile (args[0]); t2 := Expr.Compile (args[1]); t4 := Temp.AllocEmpty (Int.T); t6 := Temp.Alloc (args[0]); t7 := Temp.Alloc (args[1]); Emit.OpTT ("@ = @;\n", t6, t1); Emit.OpTT ("@ = @;\n", t7, t2); Emit.OpTT ("@ = (((unsigned)@) <<", t4, t6); Emit.OpIT ("(@ - @)) | ", Target.INTSIZE, t7); Emit.OpTT ("(((unsigned)@) >> @);\n", t6, t7); Temp.Free (t1); Temp.Free (t2); Temp.Free (t6); Temp.Free (t7); RETURN t4; END CompileR; PROCEDURE Fold (<*UNUSED*> proc: Expr.T; args: Expr.List): Expr.T = VAR e0, e1: Expr.T; w0: Word.T; i1: INTEGER; BEGIN e0 := Expr.ConstValue (args[0]); e1 := Expr.ConstValue (args[1]); IF (e0 # NIL) AND IntegerExpr.Split (e0, w0) AND (e1 # NIL) AND IntegerExpr.Split (e1, i1) THEN RETURN IntegerExpr.New (Word.Rotate (w0, i1)); ELSE RETURN NIL; END; END Fold; PROCEDURE FoldL (<*UNUSED*> proc: Expr.T; args: Expr.List): Expr.T = VAR e0, e1: Expr.T; w0: Word.T; i1: INTEGER; BEGIN e0 := Expr.ConstValue (args[0]); e1 := Expr.ConstValue (args[1]); IF (e0 # NIL) AND IntegerExpr.Split (e0, w0) AND (e1 # NIL) AND IntegerExpr.Split (e1, i1) THEN RETURN IntegerExpr.New (Word.LeftRotate (w0, i1)); ELSE RETURN NIL; END; END FoldL; PROCEDURE FoldR (<*UNUSED*> proc: Expr.T; args: Expr.List): Expr.T = VAR e0, e1: Expr.T; w0: Word.T; i1: INTEGER; BEGIN e0 := Expr.ConstValue (args[0]); e1 := Expr.ConstValue (args[1]); IF (e0 # NIL) AND IntegerExpr.Split (e0, w0) AND (e1 # NIL) AND IntegerExpr.Split (e1, i1) THEN RETURN IntegerExpr.New (Word.RightRotate (w0, i1)); ELSE RETURN NIL; END; END FoldR; PROCEDURE Initialize () = BEGIN formals[0] := BuiltinArgs.f1; formals[1] := BuiltinArgs.f13; Z := CallExpr.NewMethodList (2, 2, TRUE, TRUE, Int.T, NIL, Check, Compile, Fold, CallExpr.IsNever, (* writable *) CallExpr.IsNever, (* designator *) CallExpr.NotWritable (* noteWriter *)); Procedure.Define ("Rotate", Z, FALSE, ProcType.New (formals, Int.T)); formalsLR[0] := BuiltinArgs.f1; formalsLR[1] := BuiltinArgs.f14; ZL := CallExpr.NewMethodList (2, 2, TRUE, TRUE, Int.T, NIL, CheckLR, CompileL, FoldL, CallExpr.IsNever, (* writable *) CallExpr.IsNever, (* designator *) CallExpr.NotWritable (* noteWriter *)); Procedure.Define ("LeftRotate", ZL, FALSE, ProcType.New (formalsLR, Int.T)); ZR := CallExpr.NewMethodList (2, 2, TRUE, TRUE, Int.T, NIL, CheckLR, CompileR, FoldR, CallExpr.IsNever, (* writable *) CallExpr.IsNever, (* designator *) CallExpr.NotWritable (* noteWriter *)); Procedure.Define ("RightRotate", ZR, FALSE, ProcType.New (formalsLR, Int.T)); END Initialize; BEGIN END WordRotate.