%routine Simplify(%record(Stackfm)%name V) %integer N, D %record(Stackfm)%name R, X Monitor(V, "->Simplify") %if Diag&MonOperate # 0 %if V_Oper # 0 %start {Can do nothing but load it?} Loadup(V); ->OK %finish %if V_Record ## Nil %start %if V_Form = Address %and V_Disp = 0 - %and V_Base = 0 - %and V_Index == Nil %start {it all reduces to just the value of _record} R == V_Record V_Data = R_Data R_Index == Nil; R_Record == Nil; Drop(R) Simplify(V) ->OK %finish Simplify(V_Record) Loadup(V_Record) %if V_Record_Index ## Nil - %or V_Record_Form # Address - %or V_Record_Area # 0 V_Disp = V_Disp+V_Record_Disp; V_Record_Disp = 0 {V_Record is now either the constant 0 or a register} %if V_Record_Base = None %start {it's zero} Drop(V_Record); V_Record == Nil %else %if V_Base = None {replace the base} V_Base = V_Record_Base Drop(V_Record); V_Record == Nil %else %if V_Index == Nil {make it the index} V_Index == V_Record; V_Xsize = 1 V_Record == Nil %else {combine it with the index} Operate(ADDx, V_Index, V_Record) V_Record == Nil %finish %finish %if V_Index ## Nil %start Simplify(V_Index) %if V_Area = Constant Area %start {temp frig} X == Literal(V_Disp); V_Disp = 0 X_Area = Constant Area; V_Area = 0 Loadup(X) %if V_Base = None %start V_Base = X_Base Drop(X) %else Operate(MULx, V_Index, Literal(V_Xsize)); V_Xsize = 1 Operate(ADDx, V_Index, X) %finish %else N = Power(V_Xsize) %if N < 0 %start Operate(MULx, V_Index, Literal(V_Xsize)); V_Xsize = 1 Loadup(V_Index) %finish %finish {There is no disp field on indexed instructions} %if V_Disp # 0 %start %if V_Xsize # 1 %start Operate(MULx, V_Index, Literal(V_Xsize)); V_Xsize = 1 %finish Operate(ADDx, V_Index, Literal(V_Disp)); V_Disp = 0 Loadup(V_Index) %finish %finish %routine Ensure Displacement(%integer D, Type) %record(Stackfm)%name W %if Type = Integers %start %return %if -16_0FFF <= D <= 16_0FFF %else Fail("real address error") %if D&3 # 0 %return %if -255 <= D//4 <= 255 %finish V_Disp = 0 W == Literal(D); Loadup(W) %if V_Index == NIL %start V_Index == W; V_Xsize = 1 %else %if V_Xsize # 1 %start Operate(MULx, V_Index, Literal(V_Xsize)); V_Xsize = 1 %finish Operate(ADDx, V_Index, W) %finish Simplify(V) %end D = V_Disp %if Iconst(V) %start {adjust the type of constants} %if 16_0000 <= D <= 16_00FF %then V_Type = Bytes - %else %if -16_8000 <= D <= 16_7FFF %then V_Type = Shorts %else %if V_Form # Address %if V_Type = Lreals %or V_Type = Reals %start Ensure Displacement(D, Reals) %else %if V_Type <= Addrs Ensure Displacement(D, Integers) %finish %finish OK:Monitor(V, "<-Simplify") %if Diag&MonOperate # 0 %end