%recordformat Constfm(%integer N, Store, Type, V1, R1, V2, R2)
%constinteger Const Zero    = 1,     {constant is zero}
              Const Mone    = 2,     {constant is minus one}
              Const Rot     = 3,     {get with one rotate}
              Const Not Rot = 4,     {get with two rotates}
              Const None    = 5      {must go via store}

%routine Test Assigned
   Dir1(Dir Assigned);  Ca = Ca+4;  Refs = Refs+1
%end

%routine Float(%record(Stackfm)%name V, %integer R)
   %integer N
   %longreal Long
   R = FPR %if R = AnyF
   %if Iconst(V) %start
      %if 0 <= V_Disp <= 5 %or V_Disp = 10 %start
         N = V_Disp;  N = 7 %if V_Disp = 10
         Plant9(MVF ! Small Constant, 0, R, N)
      %else %if -5 <= V_Disp <= 0 %or V_Disp = -10
         N = -V_Disp;  N = 7 %if N = 10
         Plant9(MNF ! Small Constant, 0, R, N)
      %else
         Long = V_Disp;  V_Rval = Long
         Convert Format(V, Lreals)
         Store Real Constant(V)
         Dir4(Dir Real Load, Actual(R), V_Disp, 1);  Forget(R)
         Refs = Refs+1;  Ca = Ca+4
      %finish
   %else
      Loadup(V)
      Plant7(FLT, R, V_Base, 0);  Release(V_Base)
   %finish
   V_Type = Lreals;  V_Form = Address
   V_Base = R;       V_Disp = 0
   V_Area = 0
   Claim(R)
%end

%routine Load Safely(%record(Stackfm)%name V, %integer R)
   %if R = Any %start
      Load Protected(V)
   %else %if R = AnyF
      Float(V, AnyF) %unless Floating(V)
      Load Protected(V)
   %else
      Hazard(R) %unless Activity(R) = 1 %and V_Base = R
      Load(V, R)
   %finish
%end

%routine Characterise Constant(%integer N, %record(Constfm)%name C)
   %integer Sh, V, S, X
   %constbytearray Bits(0:15) = 0, 1, 1, 2, 1, 2, 2, 3,
                                1, 2, 2, 3, 2, 3, 3, 4
   C_N = N
   V = N
   %if V = 0 %start
      C_Type = Const Zero;  %return
   %else %if V = -1
      C_Type = Const Mone;  %return
   %else
      X = V;  S = 0          {count 1 bits}
      %cycle
         S = S+Bits(X&15);  X = X>>4
      %repeat %until X = 0

      C_Type = Const Rot
      C_Type = Const Not Rot %and V = ~V %if S > 16

      %if V # 0 %start
         Sh = 16
         Sh = Sh-1 %and V = V>>2 %while V&3 = 0
         C_R1 = Sh&15;  C_V1 = V&255;  V = V>>8
         C_R2 = 0;   C_V2 = 0
         %if V # 0 %start
            Sh = Sh-4
            Sh = Sh-1 %and V = V>>2 %while V&3 = 0
            C_R2 = Sh&15;  C_V2 = V&255;  V = V>>8
         %finish
      %finish
      C_Type = Const None %if V # 0
   %finish
%end

%routine Now in Register(%record(Stackfm)%name V, %integer R, Inherit)
   Remember(R, V) %if Inherit # 0
   %if V_Index ## Nil %start
      Release and Drop(V_Index);  V_Index == Nil
   %finish
   %if V_Record ## Nil %start
      Release and Drop(V_Record);  V_Record == Nil
   %finish
   Release(V_Base)
   V_Data = 0;  V_Base = R;  V_Form = Address;  V_Type = Rtype(R)
   Claim(R)
%end

%routine Simple Load(%record(Stackfm)%name V, %integer R)
   %record(Stackfm)%name W, B1, B2
   %record(Constfm)      C
   %integer P, N, X, T, Check

   Optimise(V, 1)
   %if InReg(V) %start
      %return %if V_Base = R %or (R = Any %and V_Base <= Any) %c
                             %or (R = AnyF %and V_Base >= F0)
   %finish

   %if R = Any %then R = Gpr %else %if R = AnyF %then R = Fpr
   Hazard(R) %unless V_Base = R %and Activity(R) = 1

   Simplify(V)

   Float(V, R) %and %return %if R >= F0 %and %not Floating(V)

   %if Iconst(V) %start
      Characterise Constant(V_Disp, C)
      %if C_Type = Const Zero  %start
         Plant1(MOV, 0, R, Rot(0, 0))
      %else %if C_Type = Const Mone
         Plant1(MVN, 0, R, Rot(0, 0))
      %else %if C_Type = Const Rot
         Plant1(MOV, 0, R, Rot(C_V1, C_R1))
         Plant1(ORR, R, R, Rot(C_V2, C_R2)) %if C_V2 # 0
      %else %if C_Type = Const Not Rot
         Plant1(MVN, 0, R, Rot(C_V1, C_R1))
         Plant1(EOR, R, R, Rot(C_V2, C_R2)) %if C_V2 # 0
      %else{%if C_Type = Const None}
         Constant Base = (Constant Base+3)&(\3)
         W == Literal(Constant Base);  W_Form = Direct;  W_Area = Constant Area
         Select Constant Area
         Dump Word(C_N)
         Select Code Area
         Dir3(Dir Const Load, Actual(R), Constant Base-4);  Forget(R)
         Refs = Refs+1;  Ca = Ca+4
         Release and Drop(W)
      %finish
      Now in Register(V, R, 1)
   %else %if V_Form = Address
      %if InReg(V) %start
         %if V_Type >= Reals %start
            Plant9(MVF, 0, R, V_Base)
         %else
            Plant1(MOV, 0, R, Just(V_Base))
         %finish
         Now in Register(V, R, 1)
         %return
      %finish
      %if V_Type >= Reals %start
         Store Real Constant(V)
         Dir4(Dir Real Load, Actual(R), V_Disp, 1);  Forget(R)
         Refs = Refs+1;  Ca = Ca+4
         Remember(R, V)
         Now in Register(V, R, 1)
         %return
      %finish
      %if V_Area = Constant Area %start
         Dir3(Dir Const Addr, Actual(R), V_Disp);  Forget(R)
         Refs = Refs+1;  Ca = Ca+4
         Now in Register(V, R, 1)
         %return
      %finish
      %if V_Index ## NIL %start
         %if V_Record ## NIL %and V_Base = 0 %start
            Loadup(V_Record)
            V_Base = V_Record_Base
            Drop(V_Record);  V_Record == NIL
         %finish
         %if V_Base = 0 %start
            Not in Yet
         %else
            P = Power(V_Xsize)
            %if P >= 0 %start         {can use logical shift}
               Loadup(V_Index)
               Plant1(ADD, V_Base, R, Ishift(V_Index_Base, P, Logical Left))
            %else                     {must use multiply}
               Operate(MULx, V_Index, Literal(V_Xsize))
               Loadup(V_Index);  V_Xsize = 1
               Plant1(ADD, V_Base, R, Just(V_Index_Base))
            %finish
         %finish
         {at this point R contains BASE + scaled*INDEX}
         %if V_Disp > 0 %start
            Characterise Constant(V_Disp, C)
            %if C_Type = Const Rot %start
               Plant1(ADD, R, R, Rot(C_V1, C_R1))
               Plant1(ADD, R, R, Rot(C_V2, C_R2)) %if C_V2 # 0
            %else %if C_Type = Const None
   Nasty:      Constant Base = (Constant Base+3)&(\3)
               Select Constant Area
               Dump Word(V_Disp)
               Select Code Area
               X = GPR
               Dir3(Dir Const Load, Actual(X), Constant Base-4);  Forget(X)
               Refs = Refs+1;  Ca = Ca+4
               Plant1(ADD, V_Base, R, Just(X))
            %else
               Fail("Bad displacement")
            %finish
         %else %if V_Disp < 0
            Characterise Constant(-V_Disp, C)
            %if C_Type = Const Rot %start
               Plant1(SUB, R, R, Rot(C_V1, C_R1))
               Plant1(SUB, R, R, Rot(C_V2, C_R2)) %if C_V2 # 0
            %else %if C_Type = Const None
               W == Literal(V_Disp);  W_Form = Direct;  W_Base = Pc
               Loadup(W)
               Plant1(SUB, R, R, Just(W_Base))
               Release and Drop(W)
            %else
               ->Nasty
            %finish
         %finish
      %else            {V_Index==NIL}
         N = V_Disp;  P = ADD
         N = -N %and  P = SUB %if N < 0
         Characterise Constant(N, C)
         %if C_Type = Const Zero  %start
            Plant1(MOV, 0, R, Just(V_Base))
         %else %if C_Type = Const Rot
            Plant1(P, V_Base, R, Rot(C_V1, C_R1))
            Plant1(P,      R, R, Rot(C_V2, C_R2)) %if C_V2 # 0
         %else %if C_Type = Const None
            W == Literal(C_N);  Loadup(W)
            Plant1(P, V_Base, R, Just(W_Base))
            Release and Drop(W)
         %else
            Fail("negate error")
         %finish
      %finish
      Now in Register(V, R, 1)
   %else %if V_Form = Direct
      Check = V_Flags & Checkable
      Check = 0 %if Unassigned = 0 %or V_Flags & Known Ass # 0
      %if V_Area # 0 %start
         %if V_Area = Constant Area %start
            %if V_Type = Integers %start
               Dir3(Dir Const Load, Actual(R), V_Disp)
            %else %if V_Type = Lreals
               Dir4(Dir Real Load, Actual(R), V_Disp, 1)
            %else %if V_Type = Reals
               Dir4(Dir Real Load, Actual(R), V_Disp, 0)
            %else %if V_Type = Bytes %or V_Type = Shorts
               T = V_Type
               Amap(V);  Load(V, R)
               V_Type = T;  V_Form = Direct;  Load(V, R)
               %return
            %else
               Fail("Bad constant type")
            %finish
            Refs = Refs+1;  Ca = Ca+4
            Forget(R)
            Now in Register(V, R, 1)
            %return
         %finish
         %if V_Area < 0 %start
            Fail("Bad external spec type") %if V_Type # Integers
            Dir3(Dir Spec Load, Actual(R), -V_Area);  Forget(R)
            Refs = Refs+1;  Ca = Ca+4
            Now in Register(V, R, 1)
            %return
         %finish
      %finish

      %if V_Type = Bytes %start
         Plant2(LDR, R, V)
         Now in Register(V, R, 1)
         %if Check # 0 %start
            Plant1(CMP ! Scc, R, 0, Immediate(16_80))
            Test Assigned
         %finish
      %else %if V_Type = Shorts
         Simplify(V)
         %if V_Index ## NIL %or V_Record ## NIL %start
            Loadup Address(V);  V_Type = Shorts;  V_Form = Direct
         %finish
         {Be careful to load [base+1] before [base+0] to leave}
         {the possibility of auto increment}
         B1 == Copy(V);  Advance(B1, Bytes, 0)    {low byte}
         B2 == Copy(V);  Advance(B2, Bytes, 1)    {high byte}
         B1_Flags = B1_Flags ! Known Ass
         B2_Flags = B2_Flags ! Known Ass
         Load(B2, R14);  Load(B1, R);  Loadup(B2) {in case of hazard}
         %if Check # 0 %start
            Plant1(CMP ! Scc,           B1_Base, 0, Immediate(16_80))
            Plant1(CMP ! Scc ! Cond EQ, B2_Base, 0, Immediate(16_80))
            Test Assigned
         %finish
         Plant1(MOV, 0, B2_Base, Ishift(B2_Base, 24, Logical Left))
         Plant1(ORR, B1_Base, R, Ishift(B2_Base, 16, Arithmetic Right))
         Release and Drop Pair(B1, B2)
         Now in Register(V, R, 1)
      %else %if V_Type = Reals
         Plant6(LDFS, R, V)
         Now in Register(V, R, 1)
         %if Check # 0 %start
            B1 == Literal(0)
            B1_Type = Lreals;  B1_Form = Direct;  B1_Base = SB
            Loadup(B1);  Release and Drop(B1)
            Plant8(CMF, B1_Base, R)
            Test Assigned
         %finish
      %else %if V_Type = Lreals
         Plant6(LDFD, R, V)
         Now in Register(V, R, 1)
         %if Check # 0 %start
            B1 == Literal(0)
            B1_Type = Lreals;  B1_Form = Direct;  B1_Base = SB
            Loadup(B1);  Release and Drop(B1)
            Plant8(CMF, B1_Base, R)
            Test Assigned
         %finish
      %else
         Plant2(LDR, R, V)                 {default to integer}
         Now in Register(V, R, 1)
         %if Check # 0 %start
            B1 == Literal(0)
            B1_Form = Direct;  B1_Base = SB
            Loadup(B1);  Release and Drop(B1)
            Plant1(CMP ! Scc, B1_Base, 0, Just(R))
            Test Assigned
         %finish
      %finish
   %else %if V_Form = AutoD
      Plant2(LDR, R, V);  Forget(V_Base)
      Now in Register(V, R, 1)
   %else %if V_Form = AutoI
      Plant2(LDR, R, V);  Forget(V_Base)
      Now in Register(V, R, 1)
   %else
      Fail("Unknown type for LOAD")
   %finish
%end

%routine Multiply(%record(Stackfm)%name V, W, %integer R)
   {BEWARE: this uses TEST ZERO and can there for alter INVERT, but}
   {        multiply can occur during a condition evaluation therefore}
   {        INVERT needs to be preserved across this call}

   %routine Cmul(%integer From, To, By)
      %integer X, Op, With, T
      %if       By&1 = 0 %start
         Op = MOV;  With = 0
      %else %if By&3 = 1
         Op = ADD;  With = From
      %else    {By&3 = 3}
         By = By+1
         Op = RSB;  With = From
      %finish
      X = 0;  X = X+1 %and By = By>>1 %until By&1 # 0
      %if By = 1 %start
         T = From
      %else
         T = Gpr
         Cmul(From, T, By)
      %finish
      Plant1(Op, With, To, Ishift(T, X, Logical Left))
   %end

   %integer L, Inv
   %record(Stackfm)%name Z
   %if Iconst(W) %start
      Load Safely(V, R)
      Fail("Zero multiply") %if W_Disp = 0
      Cmul(V_Base, V_Base, W_Disp)
   %else
      Optimise(V, 1)
      Optimise(W, 1)
      Z == Literal(0)
      %if R = Any %or R = AnyF %or Activity(R) # 0 %start {SCR/87/448}
         Load Protected(Z)
      %else
         Load(Z, R)
      %finish
      Load Protected(V)
      Load Protected(W)
      Inv = Invert;  Invert = 0
      L = New label
      Define Label(L)
      Plant1(MOV!Scc,            0, W_Base, Ishift(W_Base, 1, Logical Right))
      Plant1(ADD ! Cond CS, Z_Base, Z_Base, Just(V_Base))
      Plant1(MOV,                0, V_Base, Ishift(V_Base, 1, Logical Left))
      Jump To(L, NE)
      Release(V_Base);  V_Base = Z_Base;  Drop(Z)
      Load(V, R)
      Invert = Inv
   %finish
   Release and Drop(W)
%end

%routine Divide(%record(Stackfm)%name V, W, %integer R, Q, U)
   {Q = 0 for quotient, 1 for remainder}
   {U = 0 for unsigned}
   %integer P, L, Op
   %if (Q = 0 %or U = 0) %and Iconst(W) %start
      P = Power(W_Disp)
      %if P > 0 %start
         %if U = 0 %start        {unsigned}
            %if Q = 0 %start     {divide}
               W_Disp = P
               Op = RSHx
            %else                {REM}
               W_Disp = \((-1)<<P)
               Op = ANDx
            %finish
            Operate(Op, V, W)
            Load(V, R)
            %return
         %finish
         %if P <= 8 %start
            Load Safely(V, R)
            Plant1(CMP!Scc, V_Base, 0, Nothing)
            L = New Label
            Jump To(L, GE)
            Plant1(ADD, V_Base, V_Base, Rot(W_Disp-1, 0))
            Define label(L)
            Plant1(MOV, 0, V_Base, Ishift(V_Base, P, Arithmetic Right))
            Drop(W)
            %return
         %finish
      %finish
   %finish
   %if U = 0 %then Op = Prim Udiv %else Op = Prim Div
   Load Safely(V, R1)
   Load Pair(V, R1, W, R2)
   Prim(Op)
   %if Q = 0 %start      {quotient wanted}
      Release(R1);  Claim(R0);  V_Base = R0
   %finish
   Load(V, R)
   Release and Drop(W)
%end

%routine Complex Load(%record(Stackfm)%name V, %integer R)
   %switch C,C2(NOTx:REXPx)
   %constintegerarray Real Op(RNEGx:REXPx) = MNF, ABS, ADF, SUF, MUF, DVF, POW
   %record(Stackfm)%name W, B
   %record(Constfm)      Cx
   %integer Oper, Op, Reg2, N, Pa

   W == V_Link;  V_Link == NIL
   Oper = V_Oper;  V_Oper = 0

   %if Oper >= RNEGx %or R >= F0 %start
      Fail("real load?") %if R <= Any
      %if Oper = REXPx %start
         Load Safely(V, F0)
         Load Pair(V, F0, W, R0)
         Prim(Real Exp)
         Release and Drop(W)       {done here in case of HAZARD corrupting it}
         Load(V, R)
         %return
      %finish
      %if Oper < RNEGx %start
         V_Link == W;  V_Oper = Oper;  Load(V, Any)  {integer operation}
         Load(V, R)
         %return
      %finish
      Load Safely(V, R)
      Op = Real Op(Oper)
      %if W == NIL %start     {neg, abs}
         Plant9(Op, 0, V_Base, V_Base)
      %else
         %if Iconst(W) %and (0 <= W_Disp <= 5 %or W_Disp = 10) %start
            Reg2 = W_Disp;  Reg2 = 7 %if Reg2 = 10
            Op = Op ! Small Constant
         %else
            Load(W, AnyF)
            Reg2 = W_Base
         %finish
         Plant9(Op, V_Base, V_Base, Reg2)
      %finish
      ->OK
   %finish

   %if Oper = EXPx %start
      Load Safely(V, R1)
      Load Pair(V, R1, W, R2)
      Prim(IntExp)
      Release and Drop(W)       {done here in case of HAZARD}
      Load(V, R)
      %return
   %finish

   %if Oper = MODx %start
      Load Safely(V, R1)
      Load Pair(V, R1, W, R2)
      Prim(MODULUS)
      Release and Drop(W)
      %return
   %finish

   Multiply(V, W, R)       %and %return %if Oper = MULx
   Divide  (V, W, R, 0, 1) %and %return %if Oper = DIVx
   Divide  (V, W, R, 1, 1) %and %return %if Oper = REMx
   Divide  (V, W, R, 0, 0) %and %return %if Oper = UDIVx
   Divide  (V, W, R, 1, 0) %and %return %if Oper = UREMx

   %if Oper = SUBx %and Iconst(V) %start
      Characterise Constant(V_Disp, Cx)
      %if Cx_Type = Const Rot %start
         Load(W, R);  R = W_Base
         Plant1(RSB, W_Base, R, Rot(Cx_V1, Cx_R1))
         Plant1(ADD, R,      R, Rot(Cx_V2, Cx_R2)) %if Cx_V2 # 0;  ->OK Set
      %else %if Cx_Type = Const Mone
         Load Safely(W, R);  R = W_Base
         Plant1(MVN, 0,      R, Just(W_Base))
 OK Set: V_Base = R;  V_Disp = 0;  W_Base = 0;  ->OK
      %finish
   %finish

   %if Pending Auto # 0 %and  Oper = ADDx %and Iconst(W) %c
                        %and -4095 <= W_Disp <= 4095 %start
      Pa = Pending Auto               {the optimise will destroy it}
      Optimise(V, 1)
      %if Inreg(V) %and V_Base = Pa %c
                   %and (Pending Auto N = 0 %or |W_Disp>>2| <= 255) %start
         Dir3(Dir Modify, Ca-Pending Auto Ca, W_Disp>>Pending Auto N)
         Forget(Pa)
         Drop(W)
         Load Safely(V, R)
         %return
      %finish
   %finish

   %if V_Type = Shorts %and (Oper = ANDx %or Oper = BICx) %and Iconst(W) %start
      N = W_Disp
      N = \N %if Oper = BICx
      %if N>>16 = 0 %start
         Release and Drop(W)
         %if N <= 255 %start
            Advance(V, Bytes, 0)                     {low byte}
            Operate(ANDx, V, Literal(N)) %if N # 255
            Load(V, R)
         %else %if N&255 = 0
            V_Oper = 0;  V_Link = 0
            Advance(V, Bytes, 1)  {high byte}
            Operate(ANDx, V, Literal(N>>8)) %if N>>8 # 255
            Operate(LSHx, V, Literal(8))
            Load(V, R)
         %else
            B == Copy(V);  Advance(B, Bytes, 1)  {high byte}
            Operate(ANDx, B, Literal(N>>8)) %if N>>8 # 255
            Advance(V, Bytes, 0)                     {low byte}
            Operate(ANDx, V, Literal(N&255)) %if N&255 # 255
            {be careful to load [b+1] before [b+0] to leave}
            {the possibility of auto increment}
            Loadup(B);  Load Safely(V, R)
            Loadup(B);  Load Safely(V, R)        {in case of hazard}
            Plant1(ORR, V_Base, V_Base, Ishift(B_Base, 8, Logical Left))
            Release and Drop(B)
         %finish
         %return
      %finish
   %finish

   Load Safely(V, R);  R = V_Base
   %if W ## NIL %start
      %if Iconst(W) %start
         %if Oper = EXTx %start
            Plant1(MOV, 0, R, Ishift(V_Base, W_Disp&16_FFFF, Logical Right))
            N = (-1)<<(W_Disp>>16)
            Plant1(AND, R, R, Immediate(\N))
            ->OK
         %finish
         %if Oper = ANDx %and Immediate(W_Disp) < 0 %start
            Oper = BICx;  W_Disp = \W_Disp
         %finish
         Characterise Constant(W_Disp, Cx)
         %if Cx_Type = Const Mone %start
            Plant1(SUB, V_Base, R, Rot(1, 0))    %and ->OK %if Oper = ADDx
            Plant1(ADD, V_Base, R, Rot(1, 0))    %and ->OK %if Oper = SUBx
            Plant1(MVN, 0,      R, Just(V_Base)) %and ->OK %if Oper = XORx
         %else %if Cx_Type = Const Rot
            ->C2(Oper)

C2(ADDx):   Op = ADD;  ->C2OK
C2(SUBx):   Op = SUB;  ->C2OK
C2(BICx):   Op = BIC;  ->C2OK
C2( ORx):   Op = ORR;  ->C2OK
C2(XORx):   Op = EOR;  ->C2OK
C2(ANDx):   Op = AND %and ->C2OK %if Cx_V2 = 0
            ->Hard

C2OK:       Plant1(Op, V_Base, R, Rot(Cx_V1, Cx_R1))
            Plant1(Op, R,      R, Rot(Cx_V2, Cx_R2)) %if Cx_V2 # 0
            ->OK

C2(LSHx):   Warn(1, "Dubious shift") %if W_Disp>>5 # 0
            Plant1(MOV, 0,      R, Ishift(V_Base, W_Disp&31, Logical Left));   ->OK
C2(RSHx):   Warn(1, "Dubious shift") %if W_Disp>>5 # 0
            Plant1(MOV, 0,      R, Ishift(V_Base, W_Disp&31, Logical Right));  ->OK
         %else %if Cx_Type = Const Not Rot
            Characterise Constant(-W_Disp, Cx)
            ->Hard %unless Cx_Type = Const Rot
            Op = SUB %and ->C2OK %if Oper = ADDx
            Op = ADD %and ->C2OK %if Oper = SUBx
            Warn(1, "Dubious shift") %if Oper = RSHx %or Oper = LSHx
         %finish
      %finish
   %finish

Hard:
C2(*):

   Loadup(W) %unless W == NIL
   ->C(Oper)

C(NOTx): Plant1(MVN,         0, R, Just(V_Base));  ->OUT
C(NEGx): Plant1(RSB,   V_Base,  R, Nothing);       ->OUT
C(ABSx): Plant1(ADD!Scc,     R, R, Nothing)   {set CC}    {SCR/87/422}
         %begin
            %integer Label
            Label = New Label
            Jump To(Label, GE)
            Plant1(RSB, R, R, Nothing)
            Define Label(Label)
         %end
         ->OUT

C(ADDx): Plant1(ADD, V_Base, R, Just(W_Base));  ->OK
C(SUBx): Plant1(SUB, V_Base, R, Just(W_Base));  ->OK
C(BICx): Plant1(BIC, V_Base, R, Just(W_Base));  ->OK
C(ANDx): Plant1(AND, V_Base, R, Just(W_Base));  ->OK
C( ORx): Plant1(ORR, V_Base, R, Just(W_Base));  ->OK
C(XORx): Plant1(EOR, V_Base, R, Just(W_Base));  ->OK
C(LSHx): Plant1(MOV, 0,      R, Rshift(V_Base, W_Base, Logical Left  R));  ->OK
C(RSHx): Plant1(MOV, 0,      R, Rshift(V_Base, W_Base, Logical Right R));  ->OK

C(*):    Not in Yet

OK:      Release and Drop(W) %if W ## NIL
OUT:
%end

%routine Load(%record(Stackfm)%name V, %integer R)
!  Monitor(V, "->Load ".RegId(R)) %if Diag&MonMove # 0
   %if V_Oper = 0 %then Simple  Load(V, R) %c
                  %else Complex Load(V, R)
   Monitor(V, "<-Load") %if Diag&MonMove # 0
%end

%routine Load Pair(%record(Stackfm)%name A, %integer Ar,
                   %record(Stackfm)%name B, %integer Br)
   %if B_Oper # 0 %or B_Record ## NIL %or B_Index ## NIL %start
      Load(B, Br)
      Load(A, Ar)
      Load(B, Br)
   %else
      Load(A, Ar)
      Load(B, Br)
      Load(A, Ar)
   %finish
%end

%routine Load Trio(%record(Stackfm)%name A, %integer Ar,
                   %record(Stackfm)%name B, %integer Br,
                   %record(Stackfm)%name C, %integer Cr)
   %if B_Oper # 0 %or B_Record ## NIL %or B_Index ## NIL %start
      Load(B, Br)
      Load Pair(A, Ar, C, Cr)
   %else %if C_Oper # 0 %or C_Record ## NIL %or C_Index ## NIL
      Load(C, Br)
      Load Pair(A, Ar, B, Br)
   %else
      Load(A, Ar)
      Load Pair(B, Br, C, Cr)
   %finish
   Load(A, Ar);  Load(B, Br);  Load(C, Cr)
%end
%endoffile
