@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            MTL283
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                           ISSUE 11~
~V9 -1
~P
~V9 1
~YMTL283
~S1~M~OMUTL IMPLEMENTATION DESCRIPTION~
~S1~M~OSection 28  Version 3~
~S1~OSection 28.3 Control Code Generation~
~S1~O1. General Description~
~BThis module implements procedures concerned with code
generation for instructions concerned with control flow. Thus its main function
is to process
labels and control transfers to them, and control transfers
to and from procedures.~
~S1~O2. Interfaces~
~
Exported Procedures:~
   GO.TO~
   COND.GO.TO~
   STK.LINK~
   STK.LINK.LB~
   ENTER~
   ENTER.LB~
   RETURN~
   PROC.BEGIN~
   PROC.CODE~
   PROC.END~
   LABL~
   ASS.LABEL~
   ASS.PROC~
   INIT.28~
   PLANT.REF~
   ADD.REF~
   FILL.IN.REF~
~
Exported Types:~
   LAB.ADDR.TY~
   PROC.ADDR.TY~
   FREF.E~
~
Imported Procedures:~
   Section 27   PROC.ENTRY~
   Section 27   PROC.EXIT~
~
Imported Types:~
   Section 2    STORE.E~
   Section 5    PROC.E~
   Section 6    LAB.E~
~
Imported Data Structures:~
   Section  2    CODE.SEG.P~
   Section  5    TX.I~
   Section 27    BR.FNS~
~S1~O2.1 Hardware Interface~
~
   VAX11~
~S1~O2.2 Software Interface~
~S11) GO.TO(PTR.TO.LAB.E)~
~S12) COND.GO.TO(FUNCTION,PTR.TO.LAB.E)~
~S13) STK.LINK(PTR.TO.PROC.E)~
~S14) STK.LINK.LB(FIND.N.INDEX)~
~S15) ENTER(PTR.TO.PROC.E)~
~S16) ENTER.LB(FIND.N.INDEX)~
~S17) RETURN(PTR.TO.PROC.E)~
~S18) PROC.BEGIN(PTR.TO.PROC.PROPERTIES)~
~S19) PROC.CODE(KIND,PTR.TO.PROC.E)~
~S110) PROC.END(PTR.TO.PROC.E)~
~S111) LABL(PTR.TO.LAB.E)~
~S112) ASS.LABEL(PTR.TO.LAB.E,PTR.TO.STORE.E,POSN)~
~S113) ASS.PROC(PTR.TO.PROC.E,PTR.TO.STORE.E,POSN)~
~S114) INIT.28~
~BThe above procedures are described in Section 28 Version 1.~
~S1~O3. Implementation~
~S1~O3.1 Outline of Operation~
~S1~O3.2 Data Structures~
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H               MTL283
~V9 -1
~F
@TITLE MTL28(3,12)
@COL 8S-1R-2R-3R-4R-6R-7F
@FLOW 8-1-2-3-4-6-7
@BOX 1.0
SECTION 28
CONTROL CODE
GENERATION
[IMPORTS MTL28/1]
@BOX 2.0
TYPE DECLARATIONS
@BOX 3.0
VARIABLE AND LITERAL
DECLARATIONS
@BOX 4.0
PROCEDURES IN INTERFACE
GOT.TO        MTL28.1
COND.GO.TO    MTL28.2
STK.LINK      MTL28.3
ENTER         MTL28.4
RETURN        MTL28.5
PROC.BEGIN    MTL28.6
PROC.CODE     MTL28.7
PROC.END      MTL28.8
LABL          MTL28.9
ASS.LABEL     MTL28.10
ASS.PROC      MTL.28.11
PLANT.REF     MTL.28.12
ADD.REF       MTL.28.13
FILL.IN.REFS  MTL28.14
M.ENTRY       MTL28.15
PLANT.ENTRY   MTL28.16
@BOX 6.0
INITIALISATION
@BOX 7.0
END
@BOX 8.0
MODULE WHICH EXPORTS TYPES:
FREF.E,LAB.ADDR.TY,PROC.ADDR.TY,PROC.ADDR.TY2
LL.CALL.E
@BOX 1.1
#MTL28/1
MODULE(GO.TO,COND.GO.TO,STK.LINK,ENTER,RETURN,
       PROC.BEGIN,PROC.CODE,PROC.END,LABL,
       PLANT.REF,ADD.REF,FILL.IN.REFS,
       ASS.LABEL,ASS.PROC,INIT.28,M.ENTRY);
@BOX 2.1
@BOX 3.1
*GLOBAL 9;
$LI MAX.REFS = 1200;
$IN PQMON;
FREF.E[MAX.REFS] FREFS;
$IN REF.MAX;
$LI LAB.DEFD = %20, LAB.REFD = %10;
$LI  PROC.DEFD = %80,PROC.REFD = %40,LIB.PROC = %8;
$LI GOTO.REF = 6,SUBR.REF = 7,LAB.ADDR.REF = 16,PROC.ADDR.REF = 48,
    VAR.ADDR.REF = %50,VAR.DIM.REF = %51,LIT.REF = %70;
$LI/ADDR FREF.E  F.REF.NIL =;
ADDR FREF.E  REF.CHAIN;
::REGISTER NO LITERALS
$LI/$LO8  XNB1 = 11,AP = 12,FP = 13,SP = 14;
::INSTRUCTION LITERALS
$LI/$LO8 ADDL2 = %C0,BRB = %11,BRW = %31,CALLSI = %FB,CHME = %BD,
         CLRL = %D4,MOVL = %D0,POPR = %BA,PUSHL = %DD,PUSHR = %BB,SUBL2 = %C2;
::ADDRESSING MODE LITERALS
$LI/$LO8 ABSOLUTE = %9F,DISP.B = %A0,IMMED = %8F,SP.MINUS = %7E,
REGM = %50;
*GLOBAL 0;
@BOX 4.1
PSPEC GO.TO(ADDR LAB.E);
PSPEC COND.GO.TO($IN,ADDR LAB.E);
PSPEC STK.LINK();
PSPEC ENTER();
PSPEC RETURN(ADDR PROC.E);
PSPEC PROC.BEGIN(ADDR PROC.E);
PSPEC PROC.CODE($IN,ADDR PROC.E);
PSPEC PROC.END(ADDR PROC.E);
PSPEC LABL(ADDR LAB.E);
PSPEC ASS.LABEL(ADDR LAB.E,ADDR STORE.E,$IN32);
PSPEC ASS.PROC(ADDR PROC.E,ADDR STORE.E,$IN32);
PSPEC PLANT.REF($IN,$LO32);
PSPEC ADD.REF($IN,ADDR FREF.E,ADDR STORE.E,$LO32,$IN)/ADDR FREF.E;
PSPEC FILL.IN.REFS(ADDR FREF.E,$LO32);
PSPEC M.ENTRY(ADDR PROC.E);
PSPEC PLANT.ENTRY(ADDR PROC.E,$IN);
*CODE 3;
#MTL28.1
#MTL28.2
#MTL28.3
#MTL28.4
#MTL28.5
#MTL28.6
#MTL28.7
#MTL28.8
#MTL28.9
#MTL28.10
#MTL28.11
#MTL28.12
#MTL28.13
#MTL28.14
#MTL28.15
#MTL28.16
@BOX 6.1
PSPEC INIT.28();
PROC INIT.28;
FREF.NIL => REF.CHAIN;
0 => REF.MAX=>PQMON;
END
@BOX 7.1
*END
@BOX 8.1
IMPORT TYPE  STORE.E;
MODULE(LAB.ADDR.TY,PROC.ADDR.TY,PROC.ADDR.TY2,
        FREF.E,LL.CALL.E);
TYPE FREF.E         IS  $LO8 REF.KIND
                        ADDR FREF.E  NEXT.REF
                        ADDR STORE.E  REF.SEG
                        $LO32 REF.POS
                     $IN32 OFFSET;
TYPE LAB.ADDR.TY  IS $LO32 ADDRESS
                  OR ADDR FREF.E  LAB.REFS;
TYPE PROC.ADDR.TY2  IS  $LO32 ADDRESS
                    OR  ADDR FREF.E   PROC.REFS;
TYPE PROC.ADDR.TY IS
        $LO32 RET.ADDR
        ADDR FREF.E SP.INSTS
        PROC.ADDRTY2  PADDR;
TYPE LL.CALL.E IS $IN SP.DISP
                   $IN STK.CNT;
*END
@END
@TITLE MTL28/1(3,11)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
EXTERNAL
ENVIRONMENT
@BOX 2.0
TYPES
@BOX 3.0
VARIABLES &
LITERALS
@BOX 4.0
PROCEDURES
@BOX 5.0
END
@BOX 1.1
::EXTERNAL
::ENVIRONMENT
@BOX 2.1
IMPORT TYPE PAR.E,TYPE.E;
TYPE STORE.ADDR.TY IS
          ADDR[$LO8]  SEG.PTR;
TYPE STORE.E IS
   ADDR STORE.I,STORE.Z,STORE.EQ.Z
   $LO8 STORE.KIND,SEG.NO
   STORE.ADDR.TY  STORE.ADDR
   $LO8 STORE.TX
   ADDR STORE.C.ADDR
   $LO32 STORE.R.ADDR
   $LO8 STORE.BASE,STORE.ACCESS;
IMPORT LITERAL FRAME.AREAS,TX.Z;
TYPE TX.E IS $LO16 TX.PROC.N
             $LO8  TX.STATUS,TX.BASE
             STORE.E[FRAME.AREAS] TX.FRAME;
TYPE FREF.E         IS  $LO8 REF.KIND
                        ADDR FREF.E  NEXT.REF
                        ADDR STORE.E  REF.SEG
                        $LO32 REF.POS
                     $IN32 OFFSET;
TYPE LAB.ADDR.TY  IS $LO32  ADDRESS
                  OR ADDR FREF.E  LAB.REFS;
TYPE PROC.ADDR.TY2  IS  $LO32 ADDRESS
                    OR  ADDR FREF.E   PROC.REFS;
TYPE PROC.ADDR.TY IS
        $LO32 RET.ADDR
        ADDR FREF.E SP.INSTS
        PROC.ADDRTY2  PADDR;
TYPE PROC.ENTRY.TY IS
   PROC.ADDR.TY PROC.ADDR
   OR $LO32 PROC.FIND.N;
TYPE PROC.E IS $LO8 PROC.NAT
              $LO8 PROC.RES.TYP
              $LO8 PROC.INFO
               ADDR PAR.E   PROC.PAR.P
               ADDR TYPE.E  PROC.RES.TYP.P
                PROC.ENTRY.TY ENTRY;
TYPE LAB.E  IS $LO8 LAB.USE
                  $LO8 LAB.TX
                  LAB.ADDR.TY  LAB.ADDR;
TYPE OP.TYPE.E IS $LO SIZ $LO8 MOD, AL $IN32 DIM;
TYPE LL.CALL.E IS $IN SP.DISP
                  $IN STK.CNT;
TYPE CALL.PROC.E IS ADDR PAR.E PAR.P
                    ADDR PROC.E PROC.P
                 OR $LO32 FIND.N.I
                    $IN RESULT;
TYPE CALL.E IS $LO8 CALL.K
               OP.TYPE.E RES
               CALL.PROC.E CALL.PROC
               LL.CALL.E LL.CALL;
@BOX 3.1
$IN REGS.IU,TEMP.REGS;
$IN32 UNDEF.VAR.OFF,UNDEF.VAR.DIM;
$IN SP.DISP,CMP.TYPE;
$IN TX.I,TL.PR.M;
ADDR PROC.E CUR.TX.PROC.P;
TX.E[TX.Z] TX.S;
ADDR STORE.E  CODE.SEG.P;
IMPORT LITERAL CALL.Z;
CALL.E[CALL.Z] CALL.S;
$IN CALL.I;
$LO8[8]BR.FNS;
@BOX 4.1
LSPEC OUTI($IN,$IN);
LSPEC OUTHEX($LO32,$IN);
LSPEC NEWLINES($IN);
PSPEC FAULT($IN,ADDR[$LO8]);
PSPEC PROC.ENTRY($IN,ADDR PROC.E);
PSPEC PROC.EXIT(ADDR PROC.E);
PSPEC PLANTBY($LO);
PSPEC REPLANT($IN,$LO64,ADDR STORE.E,$LO32);
PSPEC PLANT.LIT.OPD($IN,$LO64);
PSPEC SET.RESULT.REG($IN,$IN);
PSPEC REL.TEMP.REGS($IN);
@BOX 5.1
::END 28/1
@END
@TITLE MTL28.1(3,6)
@COL 1S-2T-3R-5F
@COL 6R
@ROW 3-6
@FLOW 1-2Y-3-5
@FLOW 2N-6-5
@BOX 1.0
GO.TO(LAB.P);
@BOX 2.0
IS LABEL
DEFINED?
@BOX 3.0
PLANT 'GOTO'
REFERENCE FOR LABEL
@BOX 5.0
END
@BOX 6.0
ADD 'GOTO'
REFERENCE FOR LABEL
(LEAVING SPACE
IN CODE)
MARK LABEL AS
REFERENCED
@BOX 1.1
PROC GO.TO(LAB.P);
$IN I;
@BOX 2.1
IF LAB.USE OF LAB.P^ => I & LAB.DEFD = 0
@BOX 3.1
PLANT.REF(GOTO.REF,ADDRESS OF LAB.ADDR OF LAB.P^);
@BOX 5.1
END
@BOX 6.1
ADD.REF(GOTO.REF,LAB.REFS OF LAB.ADDR OF LAB.P^,
CODE.SEG.P,-3,I & LAB.REFD)
=> LAB.REFS OF LAB.ADDR OF LAB.P^;
I ! LAB.REFD => LAB.USE OF LAB.P^;
@END
@TITLE MTL28.2(3,6)
@COL 1S-2T-3R-5F
@COL 6R
@ROW 3-6
@FLOW 1-2Y-3-5
@FLOW 2N-6-5
@BOX 1.0
COND.GO.TO(FUNCTION,LAB.P)
@BOX 2.0
IS LABEL
DEFINED?
@BOX 3.0
PLANT REFERENCE
TO LABEL
USING FUNCTION
@BOX 5.0
END
@BOX 6.0
ADD.REFERENCE
FOR LABEL
USING FUNCTION
(LEAVING SPACE
IN CODE)
MARK LABEL AS
REFERENCED
@BOX 1.1
PROC COND.GO.TO(FN,LAB.P);
$IN I;
@BOX 2.1
IF LAB.USE OF LAB.P^ => I & LAB.DEFD = 0
@BOX 3.1
PLANT.REF(FN,ADDRESS OF LAB.ADDR OF LAB.P^);
@BOX 5.1
END
@BOX 6.1
ADD.REF(FN,LAB.REFS OF LAB.ADDR OF LAB.P^,
CODE.SEG.P,-5,I & LAB.REFD)
=> LAB.REFS OF LAB.ADDR OF LAB.P^;
I ! LAB.REFD => LAB.USE OF LAB.P^;
@END
@TITLE MTL28.3(3,9)
@COL 1S-6T-2R-3R-4R-8R-5F
@COL 7R
@ROW 2-7
@FLOW 1-6N-2-3-4-8-5
@FLOW 6Y-7-5
@BOX 1.0
STK.LINK
@BOX 6.0
STKLINK FOR
INTERPETIVE CALL?
@BOX 2.0
FILL IN CALL STACK
ENTRY WITH CLEARED
PARAM COUNT AND
SAVED SP.DISP
@BOX 3.0
PLANT CODE TO
ROUND SP
(IF REQUIRED)
@BOX 4.0
IF VSTORE PRE/POST
PROC SAVE ANY REGISTERS
IN USE IF NECESSARY
@BOX8.0
IF CALL BY PROC VARIABLE
WITH ENVIRONMENT PLANT
CODE TO SAVE XNB1
@BOX 5.0
END
@BOX 7.0
PLANT CODE TO
INITIALISE
LONGWORD COUNT
@BOX 1.1
PROC STK.LINK;
$IN I;
@BOX 6.1
IF CALL.I < 0
@BOX 2.1
SELECT CALL.S[CALL.I];
0 => STK.CNT OF LL.CALL;
SP.DISP => SP.DISP OF LL.CALL;
@BOX 3.1
IF SP.DISP & %3 => I /= 0 THEN
0 => SP.DISP;
PLANT.BY(SUBL2);
PLANT.BY(4 - I);
PLANT.BY(REGM ! SP) FI
@BOX 4.1
IF CALL.K & %4 /= 0
AND REGS.IU /= 0 THEN
PLANT.BY(PUSHR);
PLANT.LIT.OPD(2,REGS.IU) FI
@BOX8.1
IF CALL.K & %18 = %10 THEN
PLANT.BY(PUSHL);
PLANT.BY(REGM ! XNB1) FI
@BOX 5.1
END
@BOX 7.1
PLANT.BY(CLRL);
PLANT.BY(SP.MINUS);
@END
@TITLE MTL28.4(3,10)
@COL 14R-15R
@COL 1S-11T-16R-9R-12T-2T-13R-3R-4R-5R-10R-6F
@COL 7R-8R
@ROW 14-16
@ROW 15-12
@ROW 3-7
@FLOW 1-11N-16-9-12N-2Y-13-3-4-5-10-6
@FLOW 11Y-14-4
@FLOW 12Y-15-3
@FLOW 2N-7-8-4
@BOX 1.0
ENTER
@BOX 11.0
ORGANISATIONAL
COMMAND?
@BOX 16.0
SET UP STATIC
LINK IF REQUIRED
@BOX 9.0
PLANT START
OF CALLS
INSTRUCTION
@BOX 12.0
LIBRARY
PROCEDURE?
@BOX 2.0
IS PROC
DEFINED?
@BOX 13.0
GET ADDRESS
OF PROC
@BOX 3.0
PLANT REFERENCE
TO ADDRESS OF PROC
@BOX 4.0
PROCESS RESULT
(IF ANY)
@BOX 5.0
IF VSTORE PRE/POST PROC
RESTORE REGISTERS IF NECESSARY
@BOX 10.0
PLANT CODE TO
ADJUST SP
(IF REQUIRED)
USING SAVED VALUE OF
SP.DISP IN CALL STACK
@BOX 6.0
END
@BOX 14.0
PLANT ENTRY
SEQUENCE FOR
ORGANISATIONAL
COMMAND
@BOX 15.0
GET ADDRESS OF
LIBRARY PROC
@BOX 7.0
ADD REFERENCE FOR
ADDRESS OF PROC
(LEAVING SPACE
IN CODE)
@BOX 8.0
MARK PROC AS
REFERENCED
@BOX 1.1
PROC ENTER;
$IN32 I,F;
ADDR PROC.E PROC.P;
SELECT CALL.S[CALL.I];
@BOX 11.1
IF CALL.K  & %1 /= 0
AND FIND.N.I OF CALL.PROC => F < 0
@BOX 16.1
IF CALL.K & %5 = 0
AND TX.I >= 2 THEN
IF PROC.INFO OF PROC.P^ OF CALL.PROC + 1 => I > 2 THEN
PLANT.BY(MOVL);
IF TX.I - I => I < 0 THEN
PLANT.BY(REGM ! FP);
PLANT.BY(REGM ! AP);
ELSE
FP => F;
LOOP: PLANT.BY(DISP.B ! F);
PLANT.BY(8);
PLANT.BY(REGM ! AP);
IF 1 -> I >= 0 THEN
AP => F;
PLANT.BY(MOVL);
->LOOP; FI
FI FI FI
@BOX 9.1
PLANT.BY(CALLSI);
PLANT.LIT.OPD(4,STK.CNT OF LL.CALL);
PLANT.BY(ABSOLUTE);
@BOX 12.1
IF CALL.K & %1 /= 0
@BOX 2.1
PROC.P OF CALL.PROC  => PROC.P;
IF PROC.NAT OF PROC.P^ => I & PROC.DEFD = 0
@BOX 13.1
ADDRESS OF PADDR OF PROC.ADDR
OF ENTRY OF PROC.P^ => I;
@BOX 3.1
PLANT.REF(PROC.ADDR.REF,I );
@BOX 4.1
IF CALL.K & %2 /= 0 THEN
SET.RESULT.REG(SIZ OF RES,MOD OF RES) FI
@BOX 5.1
IF CALL.K & %4 /= 0
AND REGS.IU /= 0 THEN
PLANT.BY(POPR);
PLANT.LIT.OPD(2,REGS.IU) FI
@BOX 10.1
SP.DISP OF LL.CALL  => SP.DISP;
 IF SP.DISP & %3 => I /= 0 THEN
::DEBUG FAULT(0,%"SP.DISP???");
PLANT.BY(ADDL2);
PLANT.BY(4 - I);
PLANT.BY(REGM ! SP) FI
@BOX 6.1
END;
@BOX 14.1
PLANT.BY(PUSHL);
PLANT.BY(STK.CNT OF LL.CALL);
PLANT.BY(CHME);
PLANT.LIT.OPD(2,F & %FF);
@BOX 15.1
F & %FF * 8 - 4
+ (F & %7FFF0(4)) => I;
@BOX 7.1
ADD.REF(PROC.ADDR.REF,PROC.REFS OF PADDR
OF PROC.ADDR OF ENTRY OF PROC.P^,
CODE.SEG.P,-3,I & PROC.REFD)
=> PROC.REFS OF PADDR
OF PROC.ADDR OF ENTRY OF PROC.P^;
@BOX 8.1
I ! PROC.REFD => PROC.NAT OF PROC.P^;
@END
@TITLE MTL28.5(3,8)
@COL 1S-4R-5F
@FLOW 1-4-5
@BOX 1.0
RETURN(PROC.P)
@BOX 4.0
PLANT PROC EXIT CODE
@BOX 5.0
END
@BOX 6.0
@BOX 1.1
PROC RETURN(PROC.P);
@BOX 4.1
PROC.EXIT(PROC.P);
@BOX 5.1
END;
@END


@TITLE MTL28.6(3,7)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROC.BEGIN(PROC.P)
@BOX 2.0
CALL PLANT.ENTRY WITH
APPROPRIATE MODE TO FILL
IN REFERENCES AND PLANT
ENTRY SEQUENCE ETC
[MTL28.16]
END
@BOX 1.1
PROC PROC.BEGIN(PROC.P);
@BOX 2.1
PLANT.ENTRY(PROC.P,0);
@BOX3.1
END
@END
@TITLE MTL28.7(3,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROC.CODE(KIND,PROC.P);
@BOX 2.0
PLANT PROC ENTRY CODE
@BOX 3.0
END
@BOX 1.1
PROC PROC.CODE(KIND,PROC.P);
@BOX 2.1
PROC.ENTRY(KIND,PROC.P);
@BOX 3.1
END;
@END


@TITLE MTL28.8(3,7)
@COL 1S-3R-4F
@FLOW 1-3-4
@BOX 1.0
PROC.END(PROC.P)
@BOX 3.0
FILL IN FRAME
ALLOCATION INSTRUCTION(S)
@BOX 4.0
END
@BOX 1.1
PROC PROC.END(PROC.P);
$LO32 STKZ;
@BOX 3.1
STORE.I OF TX.FRAME[1]
OF TX.S[TX.I] + 3 & %F(7)C
=> STKZ;
FILL.IN.REFS(SP.INSTS OF PROC.ADDR
OF ENTRY OF PROC.P^,STKZ);
@BOX 4.1
END;
@END


@TITLE MTL28.9(3,10)
@COL 1S-2R-3R-5T-6R-7F
@FLOW 1-2-3-5Y-6-7
@FLOW 5N-7
@BOX 1.0
LABL(LAB.P);
@BOX 2.0
GET FORWARD
REFERENCE CHAIN
@BOX 3.0
CALCULATE LABEL
ADDRESS AND STORE
IN LABEL PROPERTIES
@BOX 5.0
ANY REFERENCES
@BOX 6.0
FILL IN REFERENCES
@BOX 7.0
END
@BOX 1.1
PROC LABL(LAB.P);
$LO32 L;
ADDR FREF.E R;
::DEBUG IF REGS.IU & %3F /= 0 THEN
::DEBUG IF 1 +> PQMON < 20 THEN
::DEBUG OUTHEX(REGS.IU,4);OUTHEX(TEMP.REGS,4);
::DEBUG FAULT(0,%"REGS IN USE AT LABEL"); FI
::DEBUG REL.TEMP.REGS(REGS.IU & %3F) FI
@BOX 2.1
LAB.REFS OF LAB.ADDR OF LAB.P^ => R;
@BOX 3.1
STORE.I OF CODE.SEG.P^ +
 STORE.R.ADDR OF CODE.SEG.P^
=> ADDRESS OF LAB.ADDR OF LAB.P^ => L;
@BOX 5.1
IF LAB.USE OF LAB.P^
& LAB.REFD = 0
@BOX 6.1
FILL.IN.REFS(R,L);
@BOX 7.1
END;
@END
@TITLE MTL28.10(3,6)
@COL 1S-2T-3R-4F
@COL 5R-6R
@ROW 3-5
@FLOW 1-2Y-3-4
@FLOW 2N-5-6-4
@BOX 1.0
ASS.LABEL(LAB.P,STORE.P,POS)
@BOX 2.0
IS LABEL
DEFINED?
@BOX 3.0
PLANT ADDRESS
OF LABEL
AT SPECIFIED
POSITION
@BOX 4.0
END
@BOX 5.0
ADD REFERENCE FOR
ADDRESS OF LABEL
AT SPECIFIED POSITION
@BOX 6.0
MARK LABEL AS
REFERENCED
@BOX 1.1
PROC ASS.LABEL(LAB.P,STORE.P,POS);
$IN I;
@BOX 2.1
IF LAB.USE OF LAB.P^ => I & LAB.DEFD = 0
@BOX 3.1
REPLANT(4,ADDRESS OF LAB.ADDR OF LAB.P^,STORE.P,POS);
@BOX 4.1
END
@BOX 5.1
ADD.REF(LAB.ADDR.REF,LAB.REFS OF LAB.ADDR OF LAB.P^,
STORE.P,POS,I & LAB.REFD)
=> LAB.REFS OF LAB.ADDR OF LAB.P^;
@BOX 6.1
I ! LAB.REFD => LAB.USE OF LAB.P^;
@END


@TITLE MTL28.11(3,7)
@COL 1S-2T-3R-4F
@COL 5R-6R
@ROW 3-5
@FLOW 1-2Y-3-4
@FLOW 2N-5-6-4
@BOX 1.0
ASS.PROC(PROC.P,STORE.P,POS)
@BOX 2.0
IS PROC
DEFINED
@BOX 3.0
PLANT ADDRESS
OF PROC AT
SPECIFIED POSITION
@BOX 4.0
END
@BOX 5.0
ADD REFERENCE FOR
ADDRESS OF PROC
AT SPECIFIED POSITION
@BOX 6.0
MARK PROC AS
REFERENCED
@BOX 1.1
PROC ASS.PROC(PROC.P,STORE.P,POS);
$IN32 VAL;
$IN I;
@BOX 2.1
IF PROC.NAT OF PROC.P^ => I & PROC.DEFD = 0
@BOX 3.1
IF I & LIB.PROC = 0 THEN
ADDRESS OF PADDR OF PROC.ADDR
OF ENTRY OF PROC.P^ => VAL
ELSE
PROC.FIND.N OF ENTRY OF PROC.P^ => VAL & %FF
* 8 - 4 + (VAL & %7FFF0(4)) => VAL
FI
REPLANT(4,VAL,STORE.P,POS);
@BOX 4.1
END
@BOX 5.1
ADD.REF(PROC.ADDR.REF,PROC.REFS OF PADDR
OF PROC.ADDR OF ENTRY OF PROC.P^,STORE.P,POS,I & PROC.REFD)
=> PROC.REFS OF PADDR OF PROC.ADDR OF ENTRY OF PROC.P^;
@BOX 6.1
I ! PROC.REFD
=> PROC.NAT OF PROC.P^;
@END


@TITLE MTL28.12(3,11)
@COL 13R
@COL 1S-2T-3T-4R-5T-6T-7R-8R-9R-10F
@COL 11R-12R
@ROW 3-11
@ROW 13-7
@ROW 8-12
@FLOW 1-2N-3N-4-5N-6N-7-8-9-10
@FLOW 2Y-11-10
@FLOW 3Y-6Y-13-9
@FLOW 5Y-12-10
@BOX 1.0
PLANT.REF(KIND,ADDR)
@BOX 2.0
DOES KIND INDICATE
ADDRESS REQUIRED?
@BOX 3.0
ADDR = 0
@BOX 4.0
CALCULATE
DISPLACEMENT
@BOX 5.0
WILL IT FIT
IN BYTE
@BOX 6.0
IS IT A SUBROUTINE OR
GOTO REFERENCE?
@BOX 7.0
PLANT INVERTED
TEST BRANCH WITH
DISPLACEMENT
@BOX 8.0
ADJUST DISPLACEMENT
@BOX 9.0
PLANT BRANCH WITH
WORD DISPLACEMENT
@BOX 10.0
END
@BOX 11.0
PLANT ADDRESS
IN NEXT 4 BYTES
@BOX 12.0
PLANT REQUIRED
FUNCTION WITH
BYTE DISPLACEMENT
@BOX 13.0
ADJUST BRANCH FUNCTION
FOR WORD DISPLACEMENT
@BOX 1.1
PROC PLANT.REF(KIND,ADDRESS);
$IN32 DISP,I;
$IN B;
@BOX 2.1
IF KIND & %10 /= 0
@BOX 3.1
BR.FNS[KIND] => B;
IF ADDRESS = 0
@BOX 4.1
STORE.I OF CODE.SEG.P^ +2
+STORE.R.ADDR OF CODE.SEG.P^
-: ADDRESS => DISP;
IF DISP & %F(4)8000 => I /= %F(4)8000
AND I /= 0 THEN
FAULT(0,%"BACKWARDS JUMP TOO FAR") FI
@BOX 5.1
IF DISP & %F(6)80 => I = 0
OR I = %F(6)80
@BOX 6.1
IF KIND >= 6
@BOX 7.1
PLANTBY(B -= 1);
BRW => B;
PLANTBY(3);
@BOX 8.1
2 -> DISP;
@BOX 9.1
PLANT.BY(B);
PLANT.BY(1 -> DISP & %FF);
PLANT.BY(DISP ->> 8 & %FF);
@BOX 10.1
END
@BOX 11.1
FOR 4 DO
PLANT.BY(ADDRESS & %FF);
ADDRESS ->> 8 => ADDRESS OD
@BOX 12.1
PLANT.BY(B);
PLANT.BY(DISP & %FF);
@BOX 13.1
%20 +> B;
@END


@TITLE MTL28.13(3,8)
@COL 1S-12R-2T-3R-4R-5R-6T-7R-8R-9R-13R-10F
@COL 11R
@ROW 3-11
@FLOW 1-12-2N-3-4-5-6Y-7-8-9-13-10
@FLOW 2Y-11-4
@FLOW 6N-9
@BOX 1.0
ADD.REF(KIND,REFS.P,SEG.P,POSITION)
@BOX 12.0
IF REFD = 0
SET REFS.P TO
EMPTY CHAIN
@BOX 2.0
IS FREE CHAIN
EMPTY
@BOX 3.0
USE ENTRY ON
TOP OF FREE CHAIN
UPDATE FREE CHAIN
POINTER
@BOX 4.0
LINK INTO FORWARD
REFERENCES CHAIN
@BOX 5.0
SET REFERENCE KIND
AND SEGMENT POINTER
IN ENTRY
@BOX 6.0
POSITION < 0
@BOX 7.0
NOTE POSITION
FROM CURRENT
CODE SEGMENT
@BOX 8.0
PLANT REFERENCE
WITH ZERO ADDRESS
@BOX 9.0
SET POSITION OFFSET
IN ENTRY
@BOX 13.0
SET RESULT TO
UPDATED FORWARD
REFERENCE CHAIN
@BOX 10.0
END
@BOX 11.0
USE NEXT ENTRY
IN FORWARD REFERENCE
TABLE
@BOX 1.1
PROC ADD.REF(KIND,REFS.P,SEG.P,POS,REFD);
ADDR FREF.E REF.ENT;
$IN32 I;
@BOX 12.1
IF REFD = 0 THEN
FREF.NIL => REFS.P FI
@BOX 2.1
IF REF.CHAIN = FREF.NIL
@BOX 3.1
REF.CHAIN => REF.ENT;
NEXT.REF OF REF.CHAIN^ => REF.CHAIN;
@BOX 4.1
REFS.P => NEXT.REF OF REF.ENT^;
@BOX 5.1
IF KIND => REF.KIND OF REF.ENT^ = VAR.ADDR.REF THEN
UNDEF.VAR.OFF => I
ELSE
0 => I
FI
I => OFFSET OF REF.ENT^;
SEG.P => REF.SEG OF REF.ENT^;
@BOX 6.1
IF POS >= 0
@BOX 7.1
STORE.I OF SEG.P^ => POS;
@BOX 8.1
PLANT.REF(KIND,0);
@BOX 9.1
POS => REF.POS OF REF.ENT^;
@BOX 13.1
REF.ENT => ADD.REF;
@BOX 10.1
END;
@BOX 11.1
IF 1 +> REF.MAX >= MAX.REFS THEN
FAULT(0,%"28.13");OUTI(REF.MAX,4) FI
^FREFS[REF.MAX] => REF.ENT;
@END
@TITLE MTL28.14(3,8)
@COL 1S-2T-3R-4R-5T-6R-7R-8T-9R-10F
@COL 11R-12R
@ROW 3-11
@ROW 6-12
@FLOW 1-2N-3-4-5N-6-7-8Y-9-10
@FLOW 2Y-11-7
@FLOW 5Y-12-10
@FLOW 8N-2
@BOX 1.0
FILL.IN.REFS(REF.CH,ADDR)
@BOX 2.0
DOES KIND IN ENTRY
INDICATE ADDRESS REQUIRED
(DISPLACEMENT)
@BOX 3.0
CALCULATE REPLANT
POSITION
@BOX 4.0
CALCULATE
DISPLACEMENT
@BOX 5.0
OUT OF RANGE?
@BOX 6.0
REPLANT DISPLACEMENT
AT REQUIRED POSITION
@BOX 7.0
GET NEXT
ENTRY DOWN CHAIN
@BOX 8.0
NONE?
@BOX 9.0
RETURN REF CHAIN
TO FREE CHAIN
@BOX 10.0
END
@BOX 11.0
REPLANT ADDRESS
AT REQUIRED POSITION
@BOX 12.0
FAULT
@BOX 1.1
PROC FILL.IN.REFS(REF.CH,ADDRESS);
ADDR FREF.E REF.ENT,LAST.REF;
ADDR STORE.E REF.SEG;
$IN32 DISP,I;
$IN K;
$LO32 OFF;
REF.CH => REF.ENT;
@BOX 2.1
REF.SEG OF REF.ENT^ => REF.SEG;
IF REF.KIND OF REF.ENT^ => K & %10 /= 0
@BOX 3.1
(IF K < 6 THEN 3 ELSE 1)
+REF.POS OF REF.ENT^ => OFF;
@BOX 4.1
STORE.R.ADDR OF REF.SEG^
+OFF +2 -: ADDRESS => DISP;
@BOX 5.1
IF DISP > %7FFF
@BOX 6.1
REPLANT(2,DISP,REF.SEG,OFF);
@BOX 7.1
REF.ENT => LAST.REF;
NEXT.REF OF REF.ENT^ => REF.ENT;
@BOX 8.1
IF REF.ENT /= FREF.NIL
@BOX 9.1
REF.CHAIN => NEXT.REF OF LAST.REF^;
REF.CH => REF.CHAIN;
@BOX 10.1
END;
@BOX 11.1
IF K = VAR.DIM.REF THEN
UNDEF.VAR.DIM => I;
ELSE
OFFSET OF REF.ENT^ => I;
ADDRESS +> I;
FI
REPLANT(4,I,REF.SEG,REF.POS OF REF.ENT^);
@BOX 12.1
FAULT(0,%"LABEL OUT OF RANGE");
@END


@TITLE MTL28.15(3,7)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX1.0
M.ENTRY(PROC.P)
@BOX2.0
CALL PLANT.ENTRY WITH
APPROPRIATE MODE
TO FILL IN REFERENCES
AND PLANT ENTRY SEQUENCE ETC
[MTL28.16]
@BOX3.0
END
@BOX1.1
PROC M.ENTRY(PROC.P);
@BOX2.1
PLANT.ENTRY(PROC.P,1);
@BOX3.1
END
@END
@TITLE MTL28.16(3,10)
@COL 1S-2R-4R-5T-6R-7R-8R-9R-10R-11F
@FLOW 1-2-4-5Y-6-7-8-9-10-11
@FLOW 5N-7
@BOX 1.0
PLANT.ENTRY(PROC.P,MODE)
@BOX 2.0
GET FORWARD
REFERENCE CHAIN
@BOX 4.0
CALCULATE PROC ADDRESS
AND STORE IN
PROC PROPERTIES
@BOX 5.0
MARK PROC
AS DEFINED
ANY REFERENCES?
@BOX 6.0
FILL IN REFERENCES
@BOX 7.0
PLANT PROC ENTRY MASK
@BOX 8.0
PLANT FRAME ALLOCATION
INSTRUCTION
(SP - UNFILLED LITERAL)
@BOX 9.0
CLEAR RETURN ADDRESS
IN PROC PROPERTIES
@BOX 10.0
PLANT CODE TO
SET UP XNB1
(IF REQUIRED)
@BOX 11.0
END
@BOX 1.1
PROC PLANT.ENTRY(PROC.P,MODE);
$LO32 L;
ADDR FREF.E R;
::DEBUG IF REGS.IU & %3F /= 0 THEN
::DEBUG IF 1 +> PQMON < 20 THEN
::DEBUG OUTHEX(REGS.IU,4);FAULT(0,%"REGS IN USE AT PROC") FI
::DEBUG 0 => REGS.IU FI
@BOX 2.1
PROC.REFS OF PADDR OF PROC.ADDR OF ENTRY OF PROC.P^ => R;
@BOX 4.1
STORE.R.ADDR OF CODE.SEG.P^
+ STORE.I OF CODE.SEG.P^ => L
=> ADDRESS OF PADDR OF PROC.ADDR OF ENTRY OF PROC.P^;
@BOX 5.1
IF PROC.DEFD !> PROC.NAT OF PROC.P^
& PROC.REFD = 0
@BOX 6.1
FILL.IN.REFS(R,L);
@BOX 7.1
PLANT.BY(%00);
PLANT.BY(%08);
@BOX 8.1
PLANTBY(SUBL2);
PLANTBY(IMMED);
ADD.REF(LIT.REF,SP.INSTS OF PROC.ADDR OF ENTRY
OF CUR.TX.PROC.P^,CODE.SEG.P,-4,MODE)
=> SP.INSTS OF PROC.ADDR OF ENTRY OF CUR.TX.PROC.P^;
PLANTBY(REGM!SP);
@BOX 9.1
0 => RET.ADDR OF PROC.ADDR OF ENTRY OF PROC.P^;
@BOX 10.1
IF TX.I = 1 THEN
PLANT.BY(MOVL);
PLANT.BY(REGM ! FP);
PLANT.BY(REGM ! XNB1) FI
@BOX 11.1
END
@END

