Trailing-Edge
-
PDP-10 Archives
-
decuslib20-02
-
decus/20-0068/rmod.imc
There are 2 other files named rmod.imc in the archive. Click here to see a list.
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<UPL => (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<M => (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)<LWL=>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.#