TWOSEG; #FILE: RMOD -- REGISTER ALLOCATING MODULE FOR NEW IMP. THIS MODULE REFERENCES TWO VECTORS, RST AND RSV (LENGTHS ARE NRST), WHICH KEEP TRACK OF REGISTER STATES AND VALUES. RST[I] REPRESENTS THE STATE OF REGISTER I: !-- ! ---- ! - ! - ! - ! - ! - ! - ! ---! !TT ! RX ! S ! R ! D ! T ! M ! U ! CNT! !-- ! ---- ! - ! - ! - ! - ! - ! - ! ---! NO. OF BITS: 6 12 1 1 1 1 1 1 12 TT: NUMBER OF THE TEMPORARY IN WHICH THIS REGISTER HAS BEEN SAVED (MEANINGFUL ONLY IF "M" BIT IS ON). RX: POINTS TO THE ELEMENT OF THE REGISTER VECTOR "RG" WHICH RESULTED IN THE ALLOCATION OF THIS REGISTER. THIS INFORMATION NEEDED IF THE REGISTER IS TO BE REASSIGNED. S: 1 IF THIS REGISTER HAS BEEN DECLARED "SCRATCH". R: 1 IF THIS IS A REGISTER WHICH CONTAINS THE RETURNED VALUE OF A FCN. D: 1 IF THIS REFERS TO THE FIRST REGISTER OF A PAIR OF REGISTERS. T: 1 IF THIS IS NOT A TEMPORARY REGISTER - SHOULD BE AVOIDED. M: 1 IF THIS REGISTER HAS BEEN SAVED IN A TEMPORARY (SEE ALSO "TT"). U: 1 IF THIS REGISTER CONTAINS A USEFUL VALUE. CNT: NUMBER OF TIMES THIS REGISTER IS REFERRED TO IN THE REMAINING OBJECT CODE. RSV[I] CONTAINS THE VALUE OF REGISTER I IF "USE BIT" IS SET: LEFT HALF = CONSTANT OFFSET, RIGHT HALF = DIRECTORY INDEX. FUNCTIONS IN THIS MODULE: (THIS DOCUMENATION IS SOMEWHAT OBSOLETE. THE GENERAL FLOW IS CORRECT, BUT THE DETAILS ARE NO LONGER ACCURATE.) REGVAL(R,OPC,W) R: REGISTER INDEX (I.E., INDEX INTO VECTOR RG) OPC: OPCODE OF CURRENT INSTRUCTION W: DATA WORD OF THIS INSTR. (I.E., WORD WHICH CONTAINS DIR INDEX & CONST PART) VALUE: RETURNS 1 IF THE CURRENT INSTR SHOULD BE SUPPRESSED, ELSE 0. THIS FUNCTION HANDLES THE REGISTER ALLOCATION, ACCORDING TO THE FOLLOWING ALGORITHM: 1. IF RG[R]<0 THEN A REGISTER HAS ALREADY BEEN ASSIGNED; THE REGISTER IS -RG[R]. DECREMENT THE REF COUNT IF IT IS NOT ALREADY 0. IF THIS OPCODE CHANGES THE CONTENTS OF THE REGISTER, THEN CLEAR THE "USE BIT". RETURN. 2. EXAMINE RG[R] TO DETERMINE THE LOWER & UPPER BOUNDS FOR THIS REGISTER. 2.1. IF LOWER BND=UPPER BND, THEN A SPECIFIC REGISTER IS BEING REQUESTED. ALLOCATE THE REGISTER AS IN (4) BUT FIRST EMIT AN ERROR MESSAGE IF THE REGISTER IS CURRENTLY IN USE. 3. IF W IS NOT -1 (W=-1 MEANS THAT THE MEMORY FIELD OF THIS INSTR REFERS TO A REGISTER) SEARCH RST TO SEE IF THE NEEDED VALUE IS ALREADY IN A REGISTER (USE BIT ON, W=RSV[I], & REF CNT=0). IF SO, PLACE REF COUNT IN RST[I]. IF THIS OPCODE DOES NOT CHANGE CONTENTS OF REGISTER, TURN ON USE BIT. IF THIS INSTR IS A REGISTER LOAD, AND INSTRUCTION DELETION IS PERMITTED, RETURN 1 TO INDICATE THAT IT SHOULD BE SUPPRESSED. 4. SEARCH RST TO FIND A REGISTER WHICH IS NOT IN USE AND WHICH DOES NOT CONTAIN A DORMANT VALUE (USE BIT OFF & REF COUNT=0). IF FOUND, SET USE BIT OF RST[I] ON AND FILL IN REF COUNT FROM RG[R]. SET RSV[I] TO W. SET RG[R] TO -I TO SHOW THAT A REGISTER HAS BEEN ASSIGNED. RETURN. 5. FIND ANY AVAILABLE REGISTER (REF COUNT=0). IF NONE EXISTS, ISSUE ERROR MESSAGE AND QUIT, ELSE SET RST, RSV, RG[R] AS IN CASE (4). RETURN. RCHK(I,L,W) I: REGISTER NUMBER L: FUNCTION INDICATOR (SEE BELOW) W: SYMBOL VALUE (SEE BELOW) SEE IF REGISTER I SATISFIES THE CONDITIONS SPECIFIED BY L: L=0 AN REGISTER WHICH CONTAINS THE VALUE W L=1 A REGISTER WHICH DOES NOT CONTAIN A DORMANT VALUE L=2 A REGISTER NOT CURRENTLY IN USE--EVEN IF IT HAS AN OLD VALUE RETURN 1 IF CONDITION SATISFIED, ELSE 0. SVREG(SNO,NCO,NARR,OIW,IW,L) SAVES REGISTERS IN TEMPORARIES. RSREG(NC,OIW,IW) RESTORES REGISTERS FROM TEMPORARIES. # SUBR INIREG() IS ( RST,RSV ARE 16 LONG; NRST_15; CONFLSW_0; RG,CO,NCO,ARR,NARR,FINAM ARE COMMON; PSNO_-1; SVD_0; REGCLR(0)); SUBR RGG(I) IS FREE(RG+I); SUBR RGS(I,V) IS FREES(RG+I,V); SUBR GETREG(R) IS (37B AND RGG(R) RS 13); SUBR REGREF(R) IS (I_RGG(R); (I RS 18) GE 7777B=>ERROR(0,'TOO MANY REFERENCES TO ONE REGISTER'); RGS(R,I+1000000B)); SUBR REGSET(ACI,IXI,VAL,VIF,OPC,IND) IS ( #RETURNS RFL=1 TO SUPPRESS CODE# AC_ACI; IX_IXI; RFL_VI_OB_0; OPC=>OB_OCHK(OPC); IX => (VI_1; REGVAL(IX,0,VI)); VIF=> (W_VAL AND 777777B; VI_1; REGVAL(W,0,VI); OB AND 2=>REGZAP(W,0)) ELSE (W_VAL; OB AND 2 => IND=0 => REGZAP(-1,W)); OB NE 5 => VI_1; IND => VI_1; AC => (RFL_REGVAL(AC,W,VI); OB=0=>GO TO EXITRS; OB AND 1=>REGZAP(AC,0); IXI=0 => OB AND 4 => (VIF=0 => (IND=0 => (RSV[AC]_W; RST[AC]_RST[AC] OR 10000B)) ELSE (AC=W => OB=5 => RFL_1; #SUPPRESS MOVE 0# OB AND 1 => RST[W] AND 10000B => (RSV[AC]_RSV[W]; RST[AC]_RST[AC] OR 10000B); OB AND 2 => RST[AC] AND 10000B => (RSV[W]_RSV[AC]; RST[W]_RST[W] OR 10000B)))); EXITRS: RFL); SUBR REGZAP(JJ,W) IS ( JJ GE 0 => (RST[JJ]_RST[JJ] AND NOT 10000B; RSV[JJ]_0; GO TO EXITZ); (W=RSV[I] => (RST[I]_RST[I] AND NOT 10000B; RSV[I]_0)) FOR I FROM NRST; EXITZ: 0); SUBR REGVAL(R,W,F) IS ( II_1; J_RGG(R); JJ_37B AND J RS 13; JC_7777B AND J RS 18; J<0 => JC=0 => (RST[JJ] AND 7777B => RST[JJ]_RST[JJ]-1; RST[JJ] AND 100000B => RST[JJ+1] AND 7777B => RST[JJ+1]_RST[JJ+1]-1; GO TO EXITR); JC_JC-1; (JC AND NOT 7777B) => JC_0; SFL_((J AND 4000B) LS 5) OR ((J AND 40B) LS 10); J<0 => GO TO RV1; LWL_(J RS 6) AND 37B; UPL_J AND 37B; LWL=UPL => (JJ_LWL; RV1: IER_RCHK(JJ,2,0); IER=0=>(CONFLSW=0=>ERROR(2,'REGISTER CONFLICT(S)'); # TURN ON LISTING # FINAM IS COMMON; FINAM[5]_FINAM[5] OR 4000B; CONFLSW_1; PRINT STG 0,'** ATTEMPT TO REFERENCE ',IGR 0,JJ, STG 0,'R WHICH WAS ALREADY IN USE. AT ',/; ALIST(0,-1); FINAM[5] AND 2=>(PRINT STG 0,'ATTEMPT TO ASSIGN R',OCT 0, R,STG 0,' TO ',OCT 0,JJ,STG 0,'R',/; RSTATUS()); RGS(R,(RGG(R) AND 17777B)+(JJ LS 13)+(JC LS 18)+1 LS 35); R_JJ; RETURN 0); F=0=>II_RCHK(JJ,0,W)-1) ELSE II_FRREG(F,2,W,JJ,LWL,UPL); J AND 40B => JJ_FRREG2(JJ,II,R,LWL,UPL); RST[JJ]_SFL OR (R LS 18) OR JC; RGS(R,(RGG(R) AND 17777B) OR (JJ LS 13) OR 1 LS 35); J AND 40B => RST[JJ+1]_RST[JJ+1]+(RST[JJ] AND 7777B); EXITR: R_JJ; II=0 => RFL_1; RFL); SUBR FRREG(L1,L2,W,IX,LWL,UPL) IS ( L_L1; S_W; FRR1: (RCHK(II,L,S) => GO TO EXITF) FOR II IN LWL,1,UPL; (L_L+1) LE L2 => GO TO FRR1; ERROR(0,'OUT OF REGISTERS'); EXITF: IX_II; L); SUBR FRREG2(JJ,II,R,LWL,UPL) IS ( M_UPL-1; FR20: JJ (RCHK(JJ+1,2,0) => ( RST[JJ+1]_((RGG(R+1) RS 18) AND 7777B) OR ((R+1) LS 18); RGS(R+1,(RGG(R+1) AND 17777B) OR ((JJ+1) LS 13) OR 1 LS 35); RTV_JJ; GO TO EXITF2)); JJ (II_FRREG(2,2,0,JJ,JJ+1,M); GO TO FR20); ERROR(0,'CANNOT GET TWO CONSECUTIVE REGISTERS'); EXITF2: RTV); SUBR RSCR(R) IS (I_GETREG(R); RST[I]_RST[I] OR 400000B); SUBR RPRT(R) IS (I_GETREG(R); RST[I]_RST[I] AND NOT 400000B); SUBR RELREG(R) IS (I_GETREG(R); RGS(R,RGG(R) OR (7777B AND RST[I]) LS 18); RST[I]_RST[I] AND NOT 7777B); SUBR REGCLR() IS ( SVD=0 => (RST[I]_RST[I] AND NOT 10000B FOR I TO NRST)); SUBR REGCON(W) IS (#RETURN A REGISTER WITH CONTENTS W# (W=RSV[I] => RST[I] AND 10000B => (RTV_(RST[I] RS 18) AND 7777B; GO TO EXITRC)) FOR I TO NRST; RTV_0; EXITRC: RTV); SUBR RCHK(I,L,W) IS ( RTV_0; GO TO (RCK0,RCK1,RCK2) L; RCK0: W=RSV[I]=>(RST[I] AND 10000B=>GO TO RCK2); GO TO RTNR; RCK1: RST[I] AND 10000B=>GO TO RTNR; RCK2: (RST[I] AND 7777B)=0=>RTV_1; RTNR: RTV); SUBR OCHK(OPC) IS ( RTV_0; GO TO (OP0,OP1,OP2,OP3,OP4,OP5,OP6,OP0) OPC RS 6; OP0: RTV_1; GO TO EXITO; OP1: OPC<140B => (S_OP1V; I_OPC AND 7; GO TO TESTO) ELSE (OP01: S_OP1V[1]; OP02: I_OPC AND 3; TESTO: RTV_RTV OR (7 AND (S RS (3*I))); GO TO EXITO); OP2: OPC<204B => (S_OP2V[2]; GO TO OP02); OPC<240B => GO TO OP01; OPC GE 270B => GO TO OP01; OPC<254B => (S_OP2V; I_OPC-240B) ELSE (S_OP2V[1]; I_OPC-254B); GO TO TESTO; OP3: S_OP3V; I_7 AND (OPC RS 3); (OPC AND 770B)=330B=>RTV_10B; GO TO TESTO; OP4: OPC AND 4 => ((OPC AND 70B)=10B => (S_OP4V; GO TO OP02); (OPC AND 70B)=20B => (S_OP4V[1]; GO TO OP02)); GO TO OP01; OP5: OPC<510B => (S_OP5V; GO TO OP02); OPC<540B => GO TO OP01; OPC<550B => (S_OP5V; GO TO OP02); GO TO OP01; OP6: OPC<620B => RTV_0 ELSE RTV_1; EXITO: RTV); #OCHK RETURNS A 3-BIT VALUE WHICH CHARACTERIZES THE OPERATION CODE: BIT 1 - ALTERS ACCUMULATOR BIT 2 - ALTERS MEMORY LOCATION BIT 4 - AFTER OPERATION, [ACCUMULATOR]=[MEMORY] # OP1V: DATA (02132130B, 7211B); OP2V: DATA (111301110111B, 131213110000B, 5615B); OP3V: DATA (71715000B); OP4V: DATA (5015B, 6600B); OP5V: DATA (3211B); SUBR RSTATUS() IS ( (RSTI_RST[I]; RSTR_7777B AND RSTI RS 18; RSTR=0 => (RSTI AND 10000B)=0 => GO TO FORX; PRINT OCT 0,I,STG 0,'R: R',OCT 0,RSTR,STG 0,' ',IGR 2, 7777B AND RSTI,OCT 14,RSTI,STG 0,' '; RSTI AND 10000B => (DI_RSV[I] AND 777777B; CI_RSV[I] RS 18; DI => PNAME(DI); DI=>CI>0=>PRINT '+'; CI => PRINT IGR 0,CI); PRINT /; FORX:0) FOR I TO NRST; PRINT /); SUBR SVREG(SNO,OIW,IW,L) IS ( FINAM[5] AND 2 => (PRINT STG 0,'STATUS AT REGISTER SAVE',/; RSTATUS()); SNO NE PSNO => (TNI_NEWNAME('TMP'); TNV_TNI OR 600000000000B; TNL_-1; PSNO_SNO); SVD_1; LWL_0; LNCO_NCO; RFL_IW; LS1_(L RS 6) AND 77B; LS2_L AND 77B; (RST[I] AND 7777B => (RST[I] AND 400000B)=0 => (RST[I]_RST[I] OR 20000B OR (LWL LS 30); FADD(CO,NCO,TNV); FADD(CO,NCO,202000000000B+LWL+(I LS 23)); LWL_LWL+1; GO TO SV1); RST[I]_RST[I] AND 7777747777B; SV1:0) FOR I IN LS1,1,LS2; NCO NE LNCO => (RFL_LNCO; FREES(CO+OIW,400000000000B+LNCO); FADD(CO,NCO,400000000000B+IW); TNL=-1 => (TNL_NARR; FADD(ARR,NARR,TNI+(LWL LS 18))) ELSE ((FREE(ARR+TNL) RS 18)FREES(ARR+TNL,TNI+(LWL LS 18)))); RFL); SUBR RSREG(OIW,IW) IS ( LNCO_NCO; RFL_IW; SVD_0; (RST[I] AND 20000B => ( RST[I] AND 200000B => #SUBRTN RTN REGISTER - AREG1(40B,0)# (FRREG(1,2,0,J,LS1,LS2); K_7777B AND RST[I] RS 18; RGS(K,(RGG(K) AND NOT 760000B) OR J LS 13); M_(J LS 23)+(RST[I] RS 30); RST[J]_RST[I] AND 7777157777B; RSV[J]_RSV[I]; RST[I]_RSV[I]_0) ELSE (M_(I LS 23)+(RST[I] RS 30); RST[I]_RST[I] AND 7777157777B); FADD(CO,NCO,TNV); FADD(CO,NCO,200000000000B+M)) ) FOR I IN LS1,1,LS2; NCO NE LNCO => ( RFL_LNCO; FREES(CO+OIW,400000000000B+LNCO); FADD(CO,NCO,400000000000B+IW)); RFL) %%% #IT IS ASSUMED THAT A SUBRTN RTN REGISTER IS REFERRED TO ONLY ONCE IN THE COURSE OF THE CODE. BEFORE DUPLICATION, SUCH CODE MUST HAVE ITS REGISTERS REPLICATED, AS BY COPYCO.#