!Revision history: ! 3-Jul-87 PSR corrected assigning longreal values to real locations ! - string(*)names were not being passed to %names properly %routine Store(%record(Stackfm)%name R, L) %unless R_Oper = 0 %and Same(L, R) %start %if L_Type = Records %start Record Assign(R, L) %else %if L_Type = Strings String Assign(R, L) %else %if L_Type = Sets Set Assign(R, L) %else Move(R, L) %finish %finish %end %routine Assign Procedure(%record(Stackfm)%name R, L) {A procedure parameter is a pointer to a tw0-word vector} {There are four cases} {1. The procedure is an external - } {2. The procedure is a parameter - pass the pointer} {3. The procedure is a safe local - pass and mark the parameter} { as needing an external entry} {4. The procedure is dangerous - pass and work hard} %integer Mask %record(Stackfm)%name W, V %if R_Flags&Xproc Spec # 0 %start {case 1 - an external} Hazard(R2) Dir2(Dir xThunk, R_Disp) { load @vector into R13} Refs = Refs+1; Ca = Ca+4 R == Register(R13) %else %if R_Flags&Parameter # 0 {case 2 - already a parameter} R_Type = Integers; R_Form = Direct; R_Area = 0 R == Copy(R) %else %if R_Flags&XprocDef # 0 {case 3 - simplified} Hazard(R13) Dir2(Dir Thunk, R_Disp) { load @vector into R13} Refs = Refs+1; Ca = Ca+4 R == Register(R13) %else {cases 3 & 4} Hazard(R13) Dir2(Dir Thunk, R_Disp) {Load @Ep into R13} Ca = Ca+4; Refs = Refs+1 Claim(R13) Mask = 2_0010 0100 0000 0000 {R10, R13 = Sb, Ep} W == NIL %if R_Flags&Nasty Proc # 0 %start {case 4 - a dangerous internal} Frame = Frame-4 W == Literal(Local Display); W_Base = Local Load(W, R14) Mask = 2_0110 0100 0000 0000 {R10, R13, R14 = Sb, Ep, Env} %finish Frame = Frame&(\3)-8 R == Local Integer(Frame); Loadup Address(R) Plant4(STM ! IA, R_Base, Mask) Release(R13) Release and Drop(W) %if W ## NIL %finish L_Type = Integers Simple(R, L) Release and Drop(R) %end %routine Assign Arrayname(%record(Stackfm)%name Array, To) %record(Stackfm)%name DopeVector Array_Type = Integers {the header contains integer addresses} To _Type = Integers %if Array_Flags&(Arrayname!Static) = 0 %start {in a record} %if Array_Adata == Nil %start DopeVector == Literal(0) %else DopeVector == Literal(Array_Adata_DV) DopeVector_Area = Constant Area %finish Amap(Array) %else DopeVector == Copy(Array) Advance(DopeVector, Integers, Word Length) %finish Simplify(To) Advance(To, Integers, Word Length) Simple(DopeVector, To); Release and Drop(DopeVector) {dope-vector} Advance(To, Integers,-Word Length) Simple(Array, To) {array0} %end %integerfn Select Best(%record(Stackfm)%name From, To, %integer Default) %record(Stackfm)%name W %integer Reg %result = Default %if InReg(From) W == Copy(To); Optimise(W, 1) %if InReg(W) %and Activity(W_Base) = 1 %then Reg = W_Base - %else Reg = Default Release and Drop(W) %result = Reg %end %routine Move(%record(Stackfm)%name From, To) %record(Stackfm)%name Bf1, Bf2, Bt1, Bt2, W %integer R, Pa, N, Best, Op %if From_Oper = ADDx %and Pending Auto # 0 %start W == From_Link %if Iconst(W) %and -4095 <= W_Disp <= 4095 %start From_Oper = 0; From_Link == NIL Pa = Pending Auto {the optimise will destroy it} Optimise(From, 1) %if Inreg(From) %and From_Base = Pa - %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) %else From_Oper = ADDx; From_Link == W %finish %finish %finish %if From_Type = Shorts %and (From_Oper = ANDx %or From_Oper = BICx) - %and To_Type = Integers - %and Iconst(From_Link) %start N = From_Link_Disp N = \N %if From_Oper = BICx %if N&16_FFFF0000 = 0 %start Release and Drop(From_Link) From_Oper = 0; From_Link == NIL %if N <= 255 %start Advance(From, Bytes, 0) {low byte} Operate(ANDx, From, Literal(N)) %if N # 255 %else %if N&255 = 0 Release and Drop(From_Link) From_Oper = 0; From_Link = 0 Advance(From, Bytes, 1) {high byte} Operate(ANDx, From, Literal(N>>8)) %if N>>8 # 255 Operate(LSHx, From, Literal(8)) %else Best = Select Best(From, To, Any) Bf2 == Copy(From); Advance(Bf2, Bytes, 1) {high byte} Operate(ANDx, Bf2, Literal(N>>8)) %if N>>8 # 255 Advance(From, Bytes, 0) {low byte} Operate(ANDx, From, Literal(N&255)) %if N&255 # 255 Loadup(Bf2); Load Safely(From, Best) Loadup(Bf2); Load Safely(From, Best) {in case of hazard} Plant1(ORR, From_Base, From_Base, Ishift(Bf2_Base, 8, Logical Left)) Release and Drop(Bf2) %finish %finish %finish %if To_Type = Shorts %start %if Iconst(From) %start Bf1 == Literal(From_Disp&255) {low byte} Bf2 == Literal(From_Disp>>8&255) {high byte} %else %if From_Type = Shorts %and From_Oper = 0 %if From_Index ## NIL %or From_Record ## NIL %start Loadup Address(From); From_Type = Shorts; From_Form = Direct %finish Bf1 == Copy(From); Advance(Bf1, Bytes, 0) {low byte} Bf2 == Copy(From); Advance(Bf2, Bytes, 1) {high byte} %else %if From_Type = Bytes %and From_Oper = 0 Bf1 == Copy(From); Advance(Bf1, Bytes, 0) {low byte} Bf2 == Literal(0) {high byte} %else Loadup(From) Bf1 == Copy(From) Bf2 == Copy(From); Operate(RSHx, Bf2, Literal(8)) %finish Bt1 == Copy(To); Advance(Bt1, Bytes, 0) {low byte} Bt2 == Copy(To); Advance(Bt2, Bytes, 1) {high byte} Move(Bf2, Bt2) {do the [b+1] side first} Move(Bf1, Bt1) {and the [b+0] side last} Release and Drop Pair(Bf1, Bt1) Release and Drop Pair(Bf2, Bt2) %else %if To_Type = Bytes From_Type = Bytes %if From_Oper = 0 %and From_Type = Shorts Simplify(To) Loadup(From) Plant2(STR ! Byte Op, From_Base, To) %else %if To_Type = Lreals Best = Select Best(From, To, AnyF) Simplify(To) Load(From, Best) Plant6(STFD, From_Base, To) %else %if To_Type = Reals %if Iconst(From) %and (-5 <= From_Disp <= 5 %or From_Disp = 10 - %or From_Disp = -10) %start Op = MVF N = From_Disp Op = MNF %and N = -N %if N < 0 N = 7 %if N = 10 R = FPR Plant9(Op ! Small Constant, 0, R, N) Plant6(STFS, R, To) %else %if From_Form = Direct %and From_Oper = 0 %and From_Type = Reals To == Copy(To); To_Type = Integers From == Copy(From); From_Type = Integers Move(From, To) Forget(From_Base) Release and Drop Pair(From, To) %else Simplify(To) Load(From, AnyF) Plant6(STFS, From_Base, To) {corrected for R0002.IMP} %finish %else Best = Select Best(From, To, Any) Simplify(To) Load(From, Best) Plant2(STR, From_Base, To) %finish %end %routine Move Literal(%integer Value, %record(Stackfm)%name To) %record(Stackfm)%name W == Literal(Value) Simple(W, To) Release and Drop(W) %end %routine Move Biased(%record(Stackfm)%name From, To, %integer Bias) From == Copy(From) To == Copy(To) Advance(From, Integers, Bias) %if From_Form = Direct Advance(To, Integers, Bias) Move(From, To) Release and Drop Pair(From, To) %end %routine Store Address(%record(Stackfm)%name R, L, %integername Extra) %record(Stackfm)%name W %integer Rt, Format %if L_Type = Generals %start L_Type = Integers {really three of them} Amap(L) %unless L_Form = AutoD Format = R_Format Rt = R_Type Amap(R) %if Rt = Generals %start Move Biased(R, L, WordLength*2) Move Biased(R, L, WordLength*1) Move (R, L) %else W == Literal(Type Code(Rt)) Move Biased(W, L, Wordlength*2) Release and Drop(W) %if Rt = Strings %and R_Form = Direct %and Format = 1 %start {(*)} Move Biased(R, L, Wordlength) Move (R, L) %else W == Literal(Item Size(Format)) Move Biased(W, L, Wordlength); Release and Drop(W) Move (R, L) %finish %finish Extra = Extra+12 %else %if L_Form = Proc Assign Procedure(R, L) Extra = Extra+4 %else %if L_Flags&Arrayname # 0 Assign Arrayname(R, L) Extra = Extra+8 %else %if L_Type = Strings %and L_Format = 1 N = R_Format Amap(L) Amap(R) %if N = 1 %and R_Form # Address %start {string(*)name} Move Biased(R, L, Wordlength) Move (R, L) %else W == Literal(N) Move Biased(W, L, Wordlength); Release and Drop(W) Move (R, L) %finish Extra = Extra+8 %else %if L_Form = AutoD %then L_Type = Integers - %else Amap(L) Amap(R) Store(R, L) Extra = Extra+4 %finish %end %routine Jam Transfer(%record(Stackfm)%name L, R) %integer N, Type %record(Stackfm)%name M Type = L_Type %if Type # Strings %start {just omit the remember} Jamit = 1; Store(R, L); Jamit = 0 Forget Destination(L) %else N = L_Format-1 {maximum length} Evaluate String Expression(R) %if R_Oper # 0 Amap(L); Amap(R) %if N <= 0 %start {string(*)%name} M == Copy(L) M_Disp = M_Disp+Word Length; M_Type = Integers %else M == Literal(N+1) %finish Load Trio(L, R2, R, R1, M, R0) Prim(Sjam) Release and Drop(M) %finish %end %routine Assign(%integer How) %integer X = 0 %record(Varfm)%name V %record(Stackfm)%name L, R R == Stack L == R_Stack; Stack == L_Stack %if Diag&MonMove # 0 %start Monitor(L, "A-L") Monitor(R, "A-R") %finish %if How = Equals %start Store(R, L) %else %if How = EqualsEquals Store Address(R, L, X) %else Jam Transfer(L, R) %finish %if Assign Lock # 0 %and L_Varno # 0 %start V == Var(L_Varno) V_Flags = V_Flags!Known Ass %finish Release and Drop Pair(R, L) %end %routine Assign Parameter %record(Stackfm)%name Par Par == Stack {the parameter} Stack == Par_Stack {the procedure} Par_Params == Stack_Params Stack_Params == Par Stack_Extra = Stack_Extra-1 %unless Stack_Extra = 0 {beware of C} Par_Varno = Stack_Extra %end %record(Stackfm)%map To Temp(%record(Stackfm)%name V, %integer Size) %record(Stackfm)%name W W == Claim Work Area(Size, Strings) String Assign(V, W) Release and Drop(V) %result == W %end %include "inc.Pparam"