Google
 

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.#