@TITLE MTL28(7,8)
@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

.1 GO TO
.2 COND GO TO
.3 STK LINK
.5 ENTER
.7 RETURN
.8 PROC BEGIN
.9 PROC CODE
.10 PROC END
.11 LABL
.12 ASS LABEL
.13 ASS PROC

.20 PLANT ENTER
.21 PLANT JUMP
.22 INIT PROC
.23 INIT LABEL
@BOX 6.0
INITIALISATION
@BOX 7.0
END
@BOX 8.0
MODULE WHICH EXPORTS TYPES:
LL.CALL.E, LAB.ADDR.TY, PROC.ADDR.TY
@BOX 1.1
#MTL28/1
MODULE(GO.TO,COND.GO.TO,STK.LINK,ENTER,RETURN,
       PROC.BEGIN,PROC.CODE,PROC.END,LABL,
    INITPROC,INITLABEL,PLANTENTER,PLANTJUMP,
       ASS.LABEL,ASS.PROC,INIT.28);
@BOX 2.1
@BOX 3.1
@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,ADDR);
PSPEC ASS.PROC(ADDR PROC.E,ADDR STORE.E,ADDR);
PSPEC PLANTENTER(ADDR OPERANDTYPE,$IN,$IN,$IN);
PSPEC PLANTJUMP($IN,ADDR OPERANDTYPE);
PSPEC INITPROC(ADDR PROCE);
PSPEC INITLABEL(ADDR LABE);
#MTL28.1
#MTL28.2
#MTL28.3
#MTL28.5
#MTL28.7
#MTL28.8
#MTL28.9
#MTL28.10
#MTL28.11
#MTL28.12
#MTL28.13
#MTL28.20
#MTL28.21
#MTL28.22
#MTL28.23
@BOX 6.1
PSPEC INIT.28();
PROC INIT.28;
END
@BOX 7.1
*END
@BOX 8.1
IMPORT TYPE STORE.E;
TYPE FWDREFTYPE IS
 $LO32 FWDADDRESS ADDR FWDREFTYPE FRLINK ADDR STOREE FWDSTORE;
MODULE(LAB.ADDR.TY,PROC.ADDR.TY,LL.CALL.E);
TYPE LAB.ADDR.TY IS
 $LO32 LABADDRESS
 ADDR FWDREFTYPE LABFWDREF; ::ONLY USED IF ADDRESS = 0
TYPE PROC.ADDR.TY IS
 $LO32 PROCADDRESS
 ADDR FWDREFTYPE PROCSFLIT,PROCFWDREF; ::ONLY USED IF ADDRESS = 0
TYPE LL.CALL.E IS $IN UNUSED;
*END
@END
@TITLE MTL28/1(7,8)
@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
@BOX 2.1
TYPE STORE.ADDR.TY IS
 $LO32 STORE.RA,STORE.CA,MUSS.SFNS ADDR[$LO8] STORE.DESC;
TYPE STORE.E IS
 $IN 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;
TYPE FWDREFTYPE IS
 $LO32 FWDADDRESS ADDR FWDREFTYPE FRLINK ADDR STOREE FWDSTORE;
::VAX TYPE OPERANDTYPE IS
::VAX  $LO64 OPLIT
::VAX  $IN MU6GOP,OPSIZE,OPTOPDIFF,TOPMU6GOP,REFBIT,OPTYP,V64ASV32S
::VAX  ADDR FWDREFTYPE OPFWDREF,TOPFWDREF
::VAX OR
::VAX  $IN32 OPOFFSET,TOPLIT;
::MU6 TYPE OPERANDTYPE IS
::MU6 $LO64 OPLIT
::MU6 $IN MU6GOP,OPSIZE,OPTOPDIFF,TOPMU6GOP,REFBIT,OPTYP,V64ASV32S
::MU6 ADDR FWDREFTYPE OPFWDREF,TOPFWDREF
::MU6 OR $IN TOPLIT,OPOFFSET;
IMPORT TYPE PAR.E,TYPE.E;
IMPORT LITERAL FRAME.AREAS,TX.Z;
TYPE TX.E IS
 $LO16 TX.PROC.N $LO8 TX.STATUS,TXBASE STORE.E[FRAME.AREAS] TX.FRAME;
TYPE LAB.ADDR.TY IS
 $LO32 LABADDRESS ADDR FWDREFTYPE LABFWDREF;
TYPE PROC.ADDR.TY IS
 $LO32 PROCADDRESS ADDR FWDREFTYPE PROCSFLIT,PROCFWDREF;
TYPE PROC.ENTRYTY IS
 PROCADDRTY PROCADDR OR
 $LO32 PROCFINDN;
TYPE PROC.E IS
 $LO8 PROC.NAT,PROC.RES.TYP,PROC.INFO
 ADDR PAR.E PROC.PAR.P ADDR TYPE.E PROC.RES.TYP.P PROCENTRYTY ENTRY;
TYPE LAB.E IS
 $LO8 LAB.USE,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 UNUSED;
TYPE CALL.PROC.E IS
 ADDR PAR.E PAR.P ADDR PROC.E PROC.P
 OR $LO32 FIND.N.I $IN FIND.N.P.NO;
TYPE CALL.E IS
 $LO8 CALL.K OP.TYPE.E RES CALL.PROC.E CALL.PROC LL.CALL.E LL.CALL;
@BOX 3.1
ADDR FWDREFTYPE PROGSFLIT;
ADDR PROCE CURTXPROCP;
$LI/ADDR FWDREFTYPE NILFWDREF=;
IMPORT LITERAL CALL,EXECENTRY,JUMPS,SUBRENTRY,ENTERVAR,ENTERACC;
$IN TX.I,NOOFPPROCS;
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;
$IN LASTAMODE;
$IN32 REGS;
$IN32 [21] REGMASK;
$IN [9] ACCREGS;
@BOX 4.1
PSPEC GETREG($IN,$IN,$IN)/$IN;
PSPEC PLANTCODE($LO,$LO);
PSPEC PLANTV16CODE($LO);
PSPEC PLANTV32CODE($LO,$LO);
PSPEC ASSADDR($IN,ADDR STOREE,$IN,ADDR FWDREFTYPE);
PSPEC ADDFWDREF(ADDR STOREE,$IN,$IN,ADDR FWDREFTYPE,$IN);
PSPEC PLANTFWDREF($IN,ADDR FWDREFTYPE);
PSPEC CLEAROP(ADDR OPERANDTYPE);
PSPEC PROCENTRY($IN,ADDR PROCE);
PSPEC PROCEXIT(ADDR PROCE);
PSPEC PLANTSLINK($IN,$IN,$IN);
PSPEC PLANTSEQ($IN,$IN,$IN,ADDR OPERANDTYPE,$IN);
PSPEC PLANTLOAD($IN,$IN,ADDR OPERANDTYPE,$IN);
PSPEC PLANTSTACK(ADDR OPERANDTYPE,$IN);
PSPEC ROUNDUP($IN,$IN)/$IN;
PSPEC RUNADDR(ADDR STORE.E,$IN)/$IN;
PSPEC GETFWDREF()/ADDR FWDREFTYPE;
PSPEC UNDOOPTS($IN);
PSPEC FLUSHPOOL();
LSPEC OUTI($IN,$IN);
LSPEC OUTHEX($LO32,$IN);
LSPEC CAPTION(ADDR [$LO8]);
@BOX 5.1
::END 28/1
@END
@TITLE MTL28.1(7,8)
@COL 1S-2R-4F
@FLOW 1-2-4
@BOX 1.0
GO TO (^LABEL)
@BOX 2.0
COND GO TO (UNCOND, LABEL)
@BOX 4.0
END
@BOX 1.1
PROC GOTO(PLABEL);
@BOX 2.1
CONDGOTO(6,PLABEL);
@BOX 4.1
END;
@END
@TITLE MTL28.2(7,8)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
COND GO TO (FUNC,^LABEL)
@BOX 2.0
GENERATE ADDRESS OF LABEL
@BOX 3.0
PLANT JUMP (COND) TO LABEL
@BOX 4.0
END
@BOX 1.1
PROC CONDGOTO(FUNC,PLABEL);
OPERANDTYPE OP;
SELECT PLABEL^;
SELECT LABADDR;
SELECT OP;
INITLABEL(PLABEL);
@BOX 2.1
CLEAROP(^OP);
4 => OPSIZE;
%100 => MU6GOP; ::LITERAL
LABADDRESS<<-3=>OPOFFSET;
LABFWDREF=>OPFWDREF;
@BOX 3.1
PLANTJUMP(FUNC,^OP);
@BOX 4.1
END;
@END
@TITLE MTL28.3(7,8)
@COL 1S-2F
@FLOW 1-2
@BOX 1.0
STK LINK
@BOX 2.0
END
@BOX 1.1
PROC STKLINK;
@BOX 2.1
END;
@END
@TITLE MTL28.5(7,8)
@COL 1S-2T-3T-4R-5R-6F
@COL 7R
@COL 8R
@ROW 4-7-8
@FLOW 1-2N-3N-4-5-6
@FLOW 2Y-8-5
@FLOW 3Y-7-5
@BOX 1.0
ENTER
@BOX 2.0
INTERPRETED
@BOX 3.0
LIBRARY
@BOX 4.0
GENERATE ADDRESS OF PROC
@BOX 5.0
PLANT ENTER PROC
@BOX 6.0
END
@BOX 7.0
GENERATE ADDRESS OF PROC
@BOX 8.0
GENERATE OPERAND = A
@BOX 1.1
PROC ENTER;
OPERANDTYPE OP;
$IN TLEV,EXEC,SUBR;
SELECT OP;
CLEAROP(^OP);
@BOX 2.1
IF CALL.I=-1,
@BOX 3.1
SELECT CALLS[CALLI];
SELECT CALLPROC;
IF CALLK&1/=0,
@BOX 4.1
INITPROC(PROCP);
SELECT PROC.P^;
SELECT PROCADDR OF ENTRY;
%100=>MU6GOP ::LITERAL;
PROCFWDREF=>OPFWDREF;
PROCADDRESS<<-3=>OPOFFSET;
4=>OPSIZE;
PROCINFO+1=>TLEV;
0=>EXEC;
PROCNAT&2=>SUBR;
@BOX 5.1
PLANTENTER(^OP,TLEV,EXEC,SUBR);
@BOX 6.1
END;
@BOX 7.1
%100=>MU6GOP:: LIT
FINDNI&%7FFF00FF<<-5=>OPOFFSET;
4=>OPSIZE;
0=>TLEV=>SUBR;
FINDNI->>31=>EXEC;
@BOX 8.1
%053=>MU6GOP ::BM3 (A)
4=>OPSIZE;
0=>EXEC=>TLEV=>SUBR;
@END
@TITLE MTL28.7(7,8)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
RETURN (^PROC)
@BOX 2.0
PLANT RETURN
(?PLANT JUMP TO PROC EXIT?)
@BOX 3.0
END
@BOX 1.1
PROC RETURN(PPROC);
SELECT PPROC^;
@BOX 2.1
IF PROCNAT&2=0 THEN
 PLANTCODE(%E1D0,-1-ROUNDUP(STOREI OF TXFRAME[0]OF TXS[TXI],3)); ::RTS V64 ?/NB
ELSE
 PLANTV16CODE(%C87F) ::NB=UNSTK
 PLANTV16CODE(%E0FF) ::RTS V64 -1/NB
FI;
FLUSHPOOL();
@BOX 3.1
END;
@END
@TITLE MTL28.8(7,8)
@COL 1S-3R-5F
@FLOW 1-3-5
@BOX 1.0
PROC BEGIN (^PROC)
@BOX 3.0
CALCULATE ADDRESS OF PROC
RESOLVE FWD REFS
@BOX 5.0
END
@BOX 1.1
PROC PROCBEGIN(PPROC);
SELECT PPROC^;
SELECT PROCADDR OF ENTRY;
INITPROC(PPROC);
UNDOOPTS(1);
@BOX 3.1
STOREI OF CODESEGP^&1+>STOREI OF CODESEGP^;
PLANTFWDREF(RUNADDR(CODESEGP,-1)=> PROCADDRESS<<-3,PROCFWDREF);
NILFWDREF => PROCFWDREF;
%80!>PROCNAT;
IF PROCNAT&2/=0 THEN
 1+>NOOFPPROCS;
FI;
@BOX 5.1
END;
@END
@TITLE MTL28.9(7,8)
@COL 1S-3R-4F
@FLOW 1-3-4
@BOX 1.0
PROC CODE (KIND,^PROC)
@BOX 3.0
SAVE KIND
PROC ENTRY (KIND,^PROC)
@BOX 4.0
END
@BOX 1.1
PROC PROCCODE(KIND,PPROC);
SELECT PPROC^; SELECT PROCADDR OF ENTRY;
@BOX 3.1
PROCENTRY(KIND,PPROC);
@BOX 4.1
END;
@END
@TITLE MTL28.10(7,8)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROC END (^PROC)
@BOX 2.0
PROC EXIT()
@BOX 3.0
END
@BOX 1.1
PROC PROCEND(PPROC);
@BOX 2.1
PROCEXIT(PPROC);
UNDOOPTS(1);
IF PROCNAT OF PPROC^&2/=0 THEN
 1->NOOFPPROCS;
FI;
@BOX 3.1
END;
@END
@TITLE MTL28.11(7,8)
@COL 1S-2R-4R-6F
@FLOW 1-2-4-6
@BOX 1.0
LABL(^LABEL)
@BOX 2.0
TERMINATE ANY OPTIMISATIONS
@BOX 4.0
CALCULATE ADDRESS OF LABEL
RESOLVE ANY FWD REFS
@BOX 6.0
END
@BOX 1.1
PROC LABL(PLABEL);
SELECT PLABEL^; SELECT LABADDR;
ADDR FWDREFTYPE TEMP;
INITLABEL(PLABEL);
@BOX 2.1
UNDOOPTS(1);
@BOX 4.1
STOREI OF CODESEGP^&1+>STOREI OF CODESEGP^;
PLANTFWDREF(RUNADDR(CODESEGP,-1)=> LABADDRESS<<-3,LABFWDREF);
NILFWDREF => LABFWDREF;
@BOX 6.1
END;
@END
@TITLE MTL28.12(7,8)
@COL 1S-3R-4F
@FLOW 1-3-4
@BOX 1.0
ASS LABEL (^LABEL,^STORE,POSN)
@BOX 3.0
ASS ADDR (ADDRESS,^STORE,POSN,^FWD REF LIST)
@BOX 4.0
END
@BOX 1.1
PROC ASSLABEL(PLABEL,PSTORE,PPOSN);
SELECT PLABEL^; SELECT LABADDR;
INITLABEL(PLABEL);
@BOX 3.1
ASSADDR(LABADDRESS<<-3,PSTORE,PPOSN,LABFWDREF);
@BOX 4.1
END;
@END
@TITLE MTL28.13(7,8)
@COL 1S-3R-4F
@FLOW 1-3-4
@BOX 1.0
ASS PROC (^PROC,^STORE,POSN)
@BOX 3.0
ASS ADDR (ADDRESS,^STORE,POSN,^FWD REF LIST)
@BOX 4.0
END
@BOX 1.1
PROC ASSPROC(PPROC,PSTORE,PPOSN);
SELECT PPROC^;
SELECT PROCADDR OF ENTRY;
INITPROC(PPROC);
@BOX 3.1
ASSADDR(PROCADDRESS<<-3,PSTORE,PPOSN,PROCFWDREF);
@BOX 4.1
END;
@END
@TITLE MTL28.20(7,8)
@COL 1S-10T-2T-3T-4R-5T-6R-7F
@COL 14T-8R-15R-9R
@COL 11R-12R-13R
@ROW 2-11
@ROW 2-14
@ROW 6-9
@FLOW 1-10N-2N-3N-4-5N-6-7
@FLOW 2Y-14N-8-7
@FLOW 14Y-15-7
@FLOW 3Y-5Y-9-7
@FLOW 10Y-11-12-13-7
@BOX 1.0
PLANT ENTER(^OPERAND,TLEV,EXEC,SUBR)
@BOX 2.0
VARIABLE OPERAND?
@BOX 3.0
STATIC LINK UNNECESSARY?
@BOX 4.0
LOAD STATIC LINK
@BOX 5.0
ENTER EXEC?
@BOX 6.0
PLANT NORMAL CALL SEQUENCE
@BOX 7.0
END
@BOX 8.0
PLANT VARIABLE CALL SEQUENCE
@BOX 9.0
PLANT EXEC CALL SEQUENCE
@BOX 10.0
SUBR
@BOX 11.0
SAVE ALL REGISTERS
@BOX 12.0
PLANT SUBR CALL SEQUENCE
@BOX 13.0
RESTORE ALL REGISTERS
@BOX14.0
PPCSEQ ?
@BOX15.0
PLANT PPCSEQ CALL
@BOX 1.1
PROC PLANTENTER(OP,TLEV,EXEC,SUBR);
SELECT OP^;
$IN I,J;
$IN32 MASK;
@BOX 2.1
IF MU6GOP&%C0/=0 OR MU6GOP&%3F/=0,
@BOX 3.1
IF TLEV=<1,
@BOX 4.1
PLANTSLINK(13,TLEV,TXI-NOOFPPROCS) ::BA13 (SLINKREG)
@BOX 5.1
IF EXEC/=0,
@BOX 6.1
PLANTSEQ(CALL,-1,-1,OP,0);
@BOX 7.1
::FIX BECAUSE RP BUNGLED INTERFACE
SELECT CALLS[CALLI];
$IN T,Z,TEMP;
IF CALLK&2/=0 THEN
 SIZ OF RES=>Z;
 MOD OF RES=>T;
 REGMASK[ACCREGS[T]]=>TEMP!>REGS;
 IF [T=5 AND Z=1] OR Z=8 THEN
  TEMP->>1!>REGS;
 FI;
 IF Z>=5 THEN ::ANTI-ASIZ
  5=>Z;
 FI;
 Z<<-3!T<<-2!1=>LASTAMODE;
FI;
END;
@BOX 8.1
IF OPSIZE=8 THEN
 PLANTLOAD(13,4,OP,1):: SLINKREG=ENVIRONMENT
FI;
PLANTSEQ(ENTERVAR,GETREG(-1,6,11),-1,OP,0);
@BOX 9.1
PLANTSEQ(EXECENTRY,-1,-1,OP,0);
@BOX 10.1
IF SUBR/=0,
@BOX 11.1
IF CALLK OF CALLS[CALLI]&4/=0 THEN
1=>MASK;
FOR I<20 DO
 IF REGS&MASK/=0 AND MASK&%303F=0 THEN
  IF I>=16 THEN
   PLANTV16CODE(I<<-13!%007E);
  ELSE
   PLANTV16CODE(I<<-9!%A07E);
  FI;
 FI;
 MASK<<-1=>MASK;
OD;
FI;
@BOX 12.1
PLANTSEQ(SUBRENTRY,-1,-1,OP,0);
@BOX 13.1
IF CALLK OF CALLS[CALLI]&4/=0 THEN
%80(4)=>MASK;
FOR I<20 DO
 IF REGS&MASK/=0 AND MASK&%303F=0 THEN
  IF 19-I=>J>=16 THEN
   PLANTV16CODE(J<<-13!%047F);
  ELSE
   PLANTV16CODE(J<<-9!%C07F);
  FI;
 FI;
 MASK->>1=>MASK;
OD;
FI;
@BOX14.1
IF CALLI<0,
@BOX15.1
PLANTSEQ(ENTERACC,-1,-1,OP,0);
@END
@TITLE MTL28.21(7,8)
@COL 1S-2T-3R-4R-5F
@FLOW 1-2N-3-4-5
@FLOW 2Y-4
@BOX 1.0
PLANT JUMP(CONDITION,^OPERAND)
@BOX 2.0
NO ENVIRONMENT ?
@BOX 3.0
RESET ENVIRONMENT
@BOX 4.0
PLANT SEQUENCE
@BOX 5.0
END
@BOX 1.1
PROC PLANTJUMP (CONDITION,OP);
$IN TEMP;
SELECT OP^;
UNDOOPTS(1);
@BOX 2.1
IF OPSIZE=<4,
@BOX 3.1
IF MU6GOP->>2&%F=4 THEN ::NB
PLANTSTACK(OP,0);
PLANTLOAD(4,4,OP,1) ::NB
%7F=> MU6GOP ::UNSTACK
ELSE
PLANTLOAD(4,4,OP,1) ::NB
FI;
@BOX 4.1
PLANTSEQ(JUMPS+CONDITION,-1,-1,OP,0);
IF CONDITION=6 THEN
 FLUSHPOOL();
FI;
@BOX 5.1
END;
@END
@TITLE MTL28.22(7,8)
@COL 1S-2T-3R-4F
@FLOW 1-2N-3-4
@FLOW 2Y-4
@BOX 1.0
INIT PROC (^PROC)
@BOX 2.0
IS PROC INITIALISED?
@BOX 3.0
INITIALISE PROC ADDR
@BOX 4.0
END
@BOX 1.1
PROC INITPROC(PPROC);
SELECT PPROC^; SELECT PROCADDR OF ENTRY;
@BOX 2.1
IF PROCNAT & %C0 /= 0,
@BOX 3.1
GETFWDREF()=>PROCFWDREF;
GETFWDREF()=>PROCSFLIT;
0 => PROCADDRESS;
%40 !> PROCNAT;
@BOX 4.1
END;
@END
@TITLE MTL28.23(7,8)
@COL 1S-2T-3R-4F
@FLOW 1-2N-3-4
@FLOW 2Y-4
@BOX 1.0
INIT LABEL (^LABEL)
@BOX 2.0
IS LABEL INITIALISED?
@BOX 3.0
INITIALISE LABEL ADDR
@BOX 4.0
END
@BOX 1.1
PROC INITLABEL(PLABEL);
SELECT PLABEL^; SELECT  LABADDR;
@BOX 2.1
IF LABUSE & %30 /= 0,
@BOX 3.1
GETFWDREF()=>LABFWDREF;
0 => LABADDRESS;
%10 !> LABUSE;
@BOX 4.1
END;
@END

