@L3 COUK1247
80
@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H          MTL273
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YMTL273
~S1~M~OMUTL IMPLEMENTATION DESCRIPTION~
~S1~M~OSection 27  Version 3~
~S1~OSection 27.3 Computational Code Generation (VAX11)~
~S1~O1. General Description~
~BThis module implements the procedures which cater for
code generation of computations for a particular computer. Its interface
procedures, in conjunction with those from Section 28, present an 'ideal target
machine' for the
code generation actions of the machine independent
components of MUTL.~
~S1~O2. Interfaces~
~
Export procedures~
   PLANT([INSTRUCTION.SEQUENCE])~
   PROC.ENTRY(KIND,PTR.TO.PROC.E)~
   PROC.EXIT(PTR.TO.PROC.E)~
   INSERT(BINARY)~
   PROG.ENTRY(MODE,DIRECTORY.SIZE)~
   PROG.EXIT(MODE)~
   PR.VAR.REFS(PTR.TO.VAR.E,PTR.TO.STORE.E,OFFSET)~
   ASS.LIT.64(VALUE,SIZE,PTR.TO.STORE.E,POSN)~
   ASS.LIT.128(VALUE,VALUE,SIZE,PTR.TO.STORE.E,POSN)~
   ASS.BIT(VALUE,PTR.TO.STORE.E,POSN,BIT)~
   ASS.REF.VAR(PTR.TO.VAR.E,PTR.TO.STORE.E,POSN)~
   INSERT(BINARY)~
   INIT.27~
~
Export types~
   INST.SEQ.E~
   VAR.UNDEF.TY~
   SEL.ADDR.TY~
   ORIG.E~
   OP.TYPE.E~
   LIT.OPD.E~
   OPD.E~
~
Imported Procedures~
   Section 28   COND.GO.TO~
   Section 28   PLANT.REF~
   Section 28   ADD.REF~
   Section 28   FILL.IN.REFS~
~
Imported Types~
   Section 2    STORE.E~
   Section 3    VAR.E~
                V.STORE.E~
                SEL.E~
   Section 5    PROC.E~
   Section 6    LAB.E~
~
Imported Data Structures~
   Section 2    CODE.SEG.P~
   Section 5    TX.I~
   Section 9    TL.PR.M~
~S1~O2.1 Hardware Interface~
~
   VAX11~
~S1~O2.2 Software Interface~
~S11) PLANT([INSTRUCTION.SEQUENCE])~
~S12) TYPE INST.SEQ.E~
~BFor the VAX the values of Z are:~
~3
~
         0 -   8~
         1 -  16~
         2 -  32~
         3 -  64~
         4 - 128~
~0
~S13) PROC.ENTRY(KIND,PTR.TO.PROC.E)~
~S14) PROC.EXIT(PTR.TO.PROC.E)~
~S15) PROG.ENTRY(MODE,DIRECTORY.SIZE)~
~S16) PROG.EXIT(MODE)
~S17) PR.VAR.REFS(PTR.TO.VAR.E,PTR.TO.STORAGE.ENTRY,OFFSET)~
~S18) ASS.LIT64(VALUE,SIZE,PTR.TO.STORE.E,POSN)~
~S19) ASS.LIT128(VALUE1,VALUE2,PTR.TO.STORE.E,POSN)~
~S110) ASS.BIT(VALUE,PTR.TO.STORE,POSN,BIT)~
~S111) ASS.REF.VAR(PTR.TO.VAR.E,PTR.TO.STORE.E,POSN)~
~S112) INSERT(BINARY)~
~S113) OP.TYPE~
~S114) VAR.UNDEF.TY~
~S115) INIT.27~
~BThe above are described in Section 27 Version 1.~
~S1~O3. Implementation~
~S1~O3.1 Outline of Operation~
~S1~M~OMUTL IMPLEMENTATION FOR VAX.
~S1~ORegisters.~
~T% 5
~
A:
~Ito operate in integer, logical and real modes (is decimal required?)
integer will be implemented in 32 bit mode for operand sizes ~C< 32
or 64 bit mode (restricted) similarly for logical. Real is only
implemented for 32 or 64 bit modes (is 128 required?)~
~
B:
~Iis equivalent to integer mode of size 32.~
~
D:
~Ioperates in 32 or 64 bit mode 32 bits address and 32 bits for
bounds or environment information.~
~S1~OStorage.
~S1i) ~OOn stack.
~BThe stack moves towards lower addresses as items are added. A
typical stack frame appears as~
~Q 15
~3
~
            |                 |~
            |~O                 ~O|~
            |                 |~
            | PARAMETERS      |~
R12 (AP) -> |~O                 ~O|~
            |                 |   INCLUDES OLD SP~
            | LINK INFO       |                FP~
R13 (FP) -> |~O                 ~O|            LINK~
            |                 |            ETC.~
            | VARIABLES       |~
            |~O                 ~O|~
            |                 |~
            | PARTIAL RESULTS |~
R14 (SP) -> |~O                 ~O|~
~0
~S1Note.
~BA display or linking mechanism for non local accessing/stack
unwinding has yet to be resolved.
~S1ii) ~OOff stack.
~BOff stack storage is at static addresses as expected.
~S1~OOperand statorage.
~BAs any address in the VAX is interpreted as a byte address, there
is no (logical) reason to round addresses to any particular boundary.
Any register can be advanced by 1 or more bytes. Note that FP and
SP are rounded to a 32 bit boundary on procedure entry. Note also
that 4 bytes stored to a 32 bit word in order will appear as 3 2 1 0
when accessed as a word.
~S1~ORegister Usage.
~BThe VAX has 16 32 bit registers 4 of these R12, R13, R14 and R15
are dedicated as AP, FP, SP and PC (although it may be possible to
use R12 it is altered on procedure entry). The other registers are
all available for use by the program although some instructions, in
particular the character string move and compare orders will destroy
R0 - R5 inclusive. MUTL therefore endeavours to keep~
~
~MA in R6 & R7 if necessary
~ND in R8(DB) and R9(D0)
~NB in R10
~NXNB in R11 for non local accesses
~
and uses the other registers for copying or duplicating
use of the above.~
~BIt is possible to preserve and restore register contents across
procedure calls but it is not envisaged that this feature will be
used.~
~BWhen a register is loaded or operated on in a size smaller than 32
bits (i.e. 16 or 8) its other bits remain uneffected. Thus an 8 bit
load to a register must be followed by a CONVERT order to clear higher
order bits before the register can be assigned to a larger operand.~
~
~
Operand forms and operand addressing.~
~
0 Variables~
  (i) On stack (including parameters).~
~
~
Displacement addressing of the minimal form is used for the initial
access, relative to FP or XNB (which may require setting up).~
~
  (ii) Off stack~
         Absolute addressing.~
~BFor structural variables the address may need to be evaluated in a
register and then the operand accessed using deferred or displacement
deferred addressing.~
~BFor vectors accessed by a 'dynamic' subscript the address may need
to be evaluated in a register (possibly using the INDEX instruction).
When the subscript is known the displacement may be
added to the initial operand address, if possible. Otherwise, if
no bound checking is required the indexed form of addressing is
applied. This however can only be used for 8, 16, 32 or 64 bit
operands.~
~
   1  V store Variables~
   2  Select Variables~
   3  Literals~
~BThe short form of literal operand is used if possible, otherwise
note that the literal planted in the code must be of the same
size as the function being performed.~
~
   4  Label~
~BNote that the Branch on Test Conditions Instructions only allow
an 8 bit displacement for the branch operand.~
~
   5  Procedure~
   6  Stack~
      This is simply - (SP)~
   7  Parameter stack~
      Generally - (SP)~
   8  Unstack~
      This is simply (SP)+~
   9  Register~
      Again straightforward~
  10  T Operand~
~S1~OInstructions to Note.
~BArithmetic shift orders (ASHL,ASHQ) are only available for
32 and 64 bit operands. There is a circular logical shift
ROTL that applies to 32 bit operands only.
~S1~OUse of 2 & 3 address codes.~
~S1CLR,INC,DEC.
~BThese are used in 8, 16, or 32 bit sequences (0=>...;
1+>...; 1->...) if the register is not required at the
end of the sequence and the sequence contains no other operations.
~S1PUSHL.
~BThis is used to stack 32 bit parameters or partial results if the
register is no longer required at the end of the sequence and it
contains no other operands.
~S1MOV,ADD2,ADD3,SUB2,SUB3 etc.
~BThese functions are used~
~
     i) when sequence only contains 2/3 operands~
    ii) and operands are all same type (and size=8,16,62,64)~
   iii) and register is not required at end of sequence.~
~
~
TST  INC,DEC  PUCHL  PUSHA~
~
OPD  &  (MASK => SMALLER.OPD~
                 (SIZE=MASK)~
~S1~O3.2 Data Structures~
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H                MTL273
~V9 -1
~F
@TITLE MTL27(3,11)
@COL 8S-1R-2R-4R-6R-7F
@COL 3R
@FLOW 8-1-2-3-4-6-7
@BOX 1.0
SECTION 27
COMPUTATIONAL
CODE GENERATION
[IMPORTS MTL27/1]
@BOX 2.0
TYPE DECLARATIONS
@BOX 3.0
VARIABLE AND LITERAL
DECLARATIONS
@BOX 4.0
PROCEDURES IN INTERFACE
[MTL27/2]
@BOX 6.0
INITIALISATION
@BOX 7.0
END
@BOX 8.0
MODULE WHICH EXPORTS
TYPES
[MTL27/0]
@BOX 1.1
#MTL27/1
MODULE (PLANT,PROC.ENTRY,PROC.EXIT,
        PR.VAR.REFS,PROG.ENTRY,PROG.EXIT,
        LIB.ENTRY,ASS.LIT.64,ASS.LIT.128,
        ASS.REF.VAR,CYCLE,CV.CYCLE,
        CV.LIMIT,REPEAT,RANGE,ASS,ASS.END,
        PLANT.BY,PLANT.LIT.OPD,REPLANT,
        INSERT,END.CODE.AREA,SP.DISP,INIT.27,
        CMP.TYPE,UNDEF.VAR.OFF,REGS.IU,
        TEMP.REGS,SET.RESULT.REG,REL.REGS,
        BR.FNS,UNDEF.VAR.DIM,REL.TEMP.REGS);
@BOX 2.1
TYPE REG.E IS $LO8 STATUS;
TYPE VAR.OR.LIT IS ADDR VAR.E VAR.P
                 OR $IN32 LIT;
TYPE CYCLE.ENT IS VAR.OR.LIT LIMITV
                  ADDR VAR.E CYCLE.V
                  $LO8 CV.Z
                  $IN KIND
                  ADDR STORE.E LOOP.SEG
                  $LO LOOP.POS;
@BOX 3.1
*GLOBAL 9;
$IN REGS.IU,SP.DISP,CMP.TYPE;
$IN32 UNDEF.VAR.OFF,UNDEF.VAR.DIM,DBOUND;
$IN A.REG,B.REG,D.REG,A.TYPE,DKIND;
$IN TEMP.REGS,OPD.SIZE,OPD.MODE,OPDK,REF.REQD;
$LO32 OPD.DIM;
ADDR VAR.E  UNDEF.VAR.P;
ADDR PROC.E UNDEF.PROC.P;
ADDR LAB.E UNDEF.LAB.P;
$IN32 PDC.VAR.ADDR;
REG.E[12] REGS;
$IN CY.PTR;
$LI CY.Z = 18;
CYCLE.ENT[CY.Z] CYCLES;
OPD.E CY.OPD;
$IN GENA.KIND,GENA.SIZE,GEN.LAST.FN,GEN.TEMP.REGS;
$IN LAST.TEST,OVP;
$LO8[10] OPD.VEC;
$LO8[10] GEN.OV;
ADDR[$LO8] GENA.OPD;
$LO64 LIT;
ADDR STORE.E SP.SEG.P;
$LO32  SP.MIN.INST;
$IN LIB.PNO,INT.AP.CNT.REG;
::REGISTER NO LITERALS
$LI  A = 2,D = 6,B = 8,VSUB.REG = 9,XNB0 = 10,XNB1 = 11,
     AP = 12,FP = 13,SP = 14,PC = 15;
::INST LITERALS
$LI/$LO8  ADDL2 = %C0,ADDB3 = %81,ADDL3 = %C1,ADDW3 = %A1,ASHL = %78,
         BEQL = %13,BICL2 = %CA,BICW2 = %AA,
BISL2 = %C8,BLSS = %19,BNEQ = %12,BRB = %11,BRW = %31,
CALLSI = %FB,CHME = %BD,CLRB = %94,CLRL = %D4,CLRW = %B4,
CLRQ = %7C,CMPL = %D1,CMPC3 = %29,DECB = %97,DECL = %D7,
INCB = %96,INCL = %D6,JMP = %17,MNEGB = %8E,MNEGL = %CE,MNEGW = %AE,MOVAB = %9E,
MOVAL = %DE,MOVAQ = %7E,MOVAW = %3E,MOVC3 = %28,
MOVB = %90,MOVL = %D0,MOVQ = %7D,MOVW = %B0,
MOVZWL = %3C,MULL2 = %C4,MULW2 = %A4,PUSHL = %DD,
RET = %04,SUBB3 = %83,SUBL2 = %C2,SUBL3 = %C3,SUBW3 = %A3,TSTL = %D5;
*GLOBAL 0;
*GLOBAL 2;
$DA MOVES($LO8)
MOVB MOVW MOVL MOVL
END
$DA ADD3S($LO8)
ADDB3 ADDW3 ADDL3 ADDL3
END
$DA SUB3S($LO8)
SUBB3 SUBW3 SUBL3 SUBL3
END
$DA MNEGS($LO8)
MNEGB MNEGW MNEGL MNEGL
END
$DA CLRS($LO8)
CLRB CLRW CLRL CLRL
END
$DA MOVE.CODES($LO8)
0 MOVB MOVW 0 MOVL 0 0 0 MOVQ
END
$DA MOVA.CODES($LO8)
0 MOVAB MOVAW 0 MOVAL 0 0 0 MOVAQ
END
$DA BR.FNS($LO8)
%13  %12  %18  %19  %15  %14  :: = /= >= < =< >
%11  %10  ::BRB  BSBB
END
*GLOBAL 0;
::ADDRESSING MODE LITERALS
$LI/$LO8  ABSOLUTE = %9F,INDXD = %40,DISP.B = %A0,
          DISP.DEFD.B = %B0,DISP.DEFD.L = %F0,
          IMMED = %8F,REGM = %50,REG.DEFD = %60,
          REL.DEFD.L = %FF,
         SP.MINUS = %7E,SP.PLUS = %8E,TOS = %6E;
::EVALUATED OPERAND KIND LITERALS
$LI/$LO8 LITK=0,NLITK=1,RESK=12;
::OPERAND EVALUATION MODE LITERALS
$LI/$LO8  COMPLIT = %1,NLITPOSS = %2,NEGLIT = %10,
          DONTINDX = %20,GEN.MODE = %40,UNSTACK = %80,NOTSHORT = %100;
::REGISTER STATUS CONSTANTS
$LI/$LO8  IN.USE = 1,NOT.IN.USE = 0;
::PLANT.REF MODES
$LI/$LO8 GOTO.REF = %6,LAB.ADDR.REF = %10,PROC.ADDR.REF = %30,
         VAR.ADDR.REF = %50,VAR.DIM.REF = %51;
::MISCELLANEOUS
$LI/$LO8  VAR.REFD = %2,VAR.DEFD = %1,SEL.DEFD = %2;
$LI/$LO8 LAB.DEFD = %20,LAB.REFD = %10;
$LI/$LO8 PROC.DEFD = %80,PROC.REFD = %40,LIB.PROC = %8;
*GLOBAL 2;
$DA MODE.FROM.SIZE($LO8)
%FF %00 %08 %FF %10 %FF %FF %FF %18
END
$DA COL($IN)
-2 2 6 -256 -256 10
END
*GLOBAL 0;
@BOX 4.1
#MTL27/2
@BOX 6.1
PSPEC INIT.27();
PROC INIT.27;
$IN I;
FOR I < 12 DO
NOT.IN.USE => STATUS OF REGS[I] OD
0 => REGS.IU => TEMP.REGS;
A => A.REG;D => D.REG;B => B.REG;
0 => SP.DISP => LIB.PNO;
-1 => CY.PTR;
SELECT CY.OPD;
0 => ORIG.KIND;0 => OFFSET;
0 => INDEX.C;0 => INDEX.B;
4 => SIZ OF OP.TYPE;
1 => MOD OF OP.TYPE;
0 => DIM OF OP.TYPE;
END
@BOX 7.1
*END
@BOX 8.1
#MTL27/0
@END
@TITLE MTL27/0(3,11)
@COL 1S
@BOX1.0
MODULE TO EXPORT TYPES
@BOX1.1
IMPORT TYPE FREF.E,VAR.E,SEL.E,STORE.E,TX.E;
IMPORT TYPE VSTORE.E,LAB.E,PROC.E;
MODULE(SEL.ADDR.TY,VAR.UNDEF.TY,ORIG.E,
       OP.TYPE.E,LIT.OPD.E,OPD.E,INST.SEQ.E);
TYPE SEL.ADDR.TY IS ADDR VAR.E SEL.VAR;
TYPE VAR.UNDEF.TY IS
      ADDR FREF.E  VAR.REFS;
TYPE ORIG.E IS ADDR VAR.E VAR
            OR ADDR VAR.E PTR
            OR ADDR SEL.E SEL
            OR ADDR VSTORE.E V.ST;
TYPE OP.TYPE.E IS $LO SIZ $LO8 MOD, AL $IN32 DIM;
TYPE LIT.OPD.E IS $LO64 VAL
               OR $LO64 VAL.LS,VAL.MS;
TYPE OPD.E     IS $LO8 ORIG.KIND
                  ORIG.E  ORIG
                  $LO32     OFFSET
                  $IN32   INDEX.C
                  $LO8    INDEX.B
                OP.TYPE.E OP.TYPE
               OR ADDR VSTORE.E  V.STOR
               OR ADDR SEL.E  SEL.VAR
               OR OP.TYPE.E   LIT.TYPE
                  LIT.OPD.E   LIT
               OR ADDR LAB.E  LAB
                  $LO8 LAB.K
               OR ADDR PROC.E PROCED
                  $LO8 PROC.K
               OR OP.TYPE.E PAR.STK
                  OR OP.TYPE.E UNSTK
               OR $LO16  REG
     OP.TYPE.E  REG.TYP
               OR $LO16  TREG
               OR $LO8   B.L.B
                  $IN32  B.L.C
                  OP.TYPE.E BL.EL
               OR $LO16  A.TYPE, OLD.A.TYPE
               OR $LO8   MFN
     OR $LO8 AD.KIND
        ADDR STORE.E AD.STORE
        ADDR TX.E    AD.TX;
TYPE INST.SEQ.E IS $LO16 OP.CODE
                   $LO8  REG.SPEC
                   $LO8  OPD.KIND
                   OPD.E OPD;
*END
@END
@TITLE MTL27/1(3,11)
@COL 1S-2R
@COL 6R-3R-4R-5F
@FLOW 1-2-6-3-4-5
@BOX 1.0
EXTERNAL
ENVIRONMENT
@BOX 2.0
TYPES
@BOX6.0
TYPES CONTINUED
@BOX 3.0
VARIABLES &
LITERALS
@BOX 4.0
PROCEDURES
@BOX 5.0
END
@BOX 1.1
::EXTERNAL ENVIRONMENT
@BOX 2.1
IMPORT TYPE TYPE.E,PAR.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 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.ADDR.TY2 PADDR;
TYPE PROC.ENTRY.TY IS PROC.ADDR.TY PROC.ADDR
                   OR $LO32 PROC.FIND.N;
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
               PROC.ENTRY.TY ENTRY;
TYPE VAR.UNDEF.TY IS ADDR FREF.E  VAR.REFS;
TYPE VAR.ADDR.TY IS ADDR STORE.E VAR.STORE.P
                    ADDR VAR.OFF
                 OR VAR.UNDEF.TY VAR.UNDEF;
TYPE VAR.E IS $LO16 VAR.TYP
              ADDR VAR.DIM
              $LO16 VAR.F
              ADDR TYPE.E  VAR.TYP.P
              VAR.ADDR.TY VAR.ADDR;
TYPE V.E IS $LO32 STORE.ADDR
         OR ADDR VAR.E VAR.P;
TYPE V.STORE.E IS ADDR PROC.E V.READ.P,V.WRITE.P
                  $IN32 V.STORE.DIM
                  $LO16 V.STORE.TYPE
                  $LO8 VKIND
                  V.E V;
TYPE LAB.ADDR.TY IS $LO32 ADDRESS
                 OR ADDR FREF.E LAB.REFS;
TYPE LAB.E IS $LO8 LAB.USE,LAB.TX
              LAB.ADDR.TY LAB.ADDR;
TYPE SEL.ADDR.TY IS ADDR VAR.E SEL.VAR;
TYPE SEL.E IS $LO8 SEL.V.MODE, SEL.V.BASE.ST
             $LO16 SEL.V.BASE.N
             ADDR SEL.V.OFFSET
             ADDR VAR.E SEL.V.BASE.P
             $LO16 SEL.V.TYP
             ADDR TYPE.E SEL.V.TYP.P
             ADDR SEL.V.DIM
             $LO8 SEL.V.F
             SEL.ADDR.TY SEL.ADDR;
TYPE ORIG.E IS ADDR VAR.E VAR
            OR ADDR VAR.E PTR
            OR ADDR SEL.E SEL
            OR ADDR VSTORE.E V.ST;
TYPE OP.TYPE.E IS $LO SIZ $LO8 MOD, AL $IN32 DIM;
TYPE LIT.OPD.E IS $LO64 VAL
               OR $LO64 VAL.LS,VAL.MS;
@BOX6.1
TYPE OPD.E IS $LO8 ORIG.KIND
               ORIG.E  ORIG
               $LO32   OFFSET
               $IN32   INDEX.C
               $LO8    INDEX.B
               OP.TYPE.E OP.TYPE
OR ADDR VSTORE.E  V.STOR
OR ADDR SEL.E  SEL.VAR
OR OP.TYPE.E   LIT.TYPE
   LIT.OPD.E   LIT
OR ADDR LAB.E  LAB
   $LO8 LAB.K
OR ADDR PROC.E PROCED
   $LO8 PROC.K
OR OP.TYPE.E PAR.STK
OR OP.TYPE.E UNSTK
OR $LO16  REG
  OP.TYPE.E REG.TYPE
OR $LO16  TREG
OR $LO8   B.L.B
   $IN32  B.L.C
   OP.TYPE.E BL.EL
OR $LO16  A.TYPE, OLD.A.TYPE
OR $LO8   MFN
OR $LO8 AD.KIND
   ADDR STORE.E AD.STORE
   ADDR    TX.E AD.TX;
TYPE INST.SEQ.E IS $LO16 OP.CODE
                   $LO8  REG.SPEC,OPD.KIND
                   OPD.E OPD;
TYPE LL.CALL.E IS $IN SP.DISP,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
IMPORT LITERAL INDICES.Z, CODES.Z;
$LO16[INDICES.Z] INDICES;
$LO8[CODES.Z] CODES;
$IN TX.I,TL.PR.M;
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;
@BOX 4.1
PSPEC S.DECL($IN,ADDR)/ADDR VAR.E;
PSPEC OUTPLANT(ADDR[INST.SEQ.E]);
PSPEC FAULT($IN,ADDR[$LO8]);
PSPEC GO.TO(ADDR LAB.E);
PSPEC STK.LINK();
PSPEC ENTER();
PSPEC COND.GO.TO($IN,ADDR LAB.E);
LSPEC CUR.PROG($LO32);
LSPEC CAPTION(ADDR[$LO8]);
LSPEC NEWLINES($IN);
LSPEC OUTI($IN,$IN);
LSPEC OUTHEX($LO32,$IN);
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);
@BOX 5.1
::END 27/1
@END
@TITLE MTL27/2(3,11)
@COL 1S
@BOX 1.0
PROCEDURES IN INTERFACE
PLANT          MTL27.1
PROC.ENTRY     MTL27.2
PROC.EXIT      MTL27.3
PROG.ENTRY     MTL27.4
PROG.EXIT      MTL27.5
PR.VAR.REFS    MTL27.6
ASS.LIT.64     MTL27.7
ASS.LIT.128    MTL27.8
RANGE          MTL27.9
ASS.REF.VAR    MTL27.10
PLANT.BY       MTL27.16
PLANT.LIT.OPD  MTL27.17
REPLANT        MTL27.21
INSERT         MTL27.22
REL.REGS       MTL27.26
LIB ENTRY      MTL27.27
CYCLE          MTL27.28
CV.CYCLE       MTL27.29
CV.LIMIT       MTL27.30
REPEAT         MTL27.31
ASS            MTL27.34
ASS.END        MTL27.35
INTERNAL PROCEDURES
REL.TEMP.REGS  MTL27.11
DISP.ADDR      MTL27.12
ABS.ADDR       MTL27.13
CONVERT        MTL27.14
PLANT.OPD      MTL27.15
GET.TEMP.REG   MTL27.18
GET.OPD        MTL27.19
RESERVE.REGS   MTL27.23
RELEASE.REGS   MTL27.24
SET.RESULT.REG MTL27.25
CHECK.OPD      MTL27.32
CHECK.OPD.MODE MTL27.33
@BOX 1.1
PSPEC PLANT(ADDR[INST.SEQ.E]);
PSPEC PROC.ENTRY($IN,ADDR PROC.E);
PSPEC PROC.EXIT(ADDR PROC.E);
PSPEC PROG.ENTRY($IN,$IN);
PSPEC PROG.EXIT($IN);
PSPEC PR.VAR.REFS(ADDR VAR.E,ADDR STORE.E,$IN32);
PSPEC ASS.LIT.64($LO64,$IN,ADDR STORE.E,$IN32);
PSPEC ASS.LIT.128($LO64,$LO64,$IN,ADDR STORE.E,$IN32);
PSPEC RANGE($IN, $IN, ADDR OPD.E, $IN, ADDR OPD.E);
PSPEC ASS.REF.VAR(ADDR VAR.E,ADDR STORE.E,$IN32);
PSPEC REPLANT($IN,$LO64,ADDR STORE.E,$LO32);
PSPEC INSERT($IN);
PSPEC PLANT.BY($LO);
PSPEC PLANT.LIT.OPD($IN,$LO64);
PSPEC REL.TEMP.REGS($IN);
PSPEC DISP.ADDR($IN,$IN,$IN32);
PSPEC ABS.ADDR($IN32);
PSPEC CONVERT($IN,$IN,$IN,$IN)/$IN;
PSPEC PLANT.OPD(ADDR[$LO8],$IN);
PSPEC GET.TEMP.REG($IN)/$IN;
PSPEC GET.OPD($IN,$IN,$IN,ADDR OPD.E);
PSPEC RESERVE.REGS($IN,$IN);
PSPEC RELEASE.REGS($IN,$IN);
PSPEC SET.RESULT.REG($IN,$IN);
PSPEC REL.REGS($IN);
PSPEC LIB.ENTRY(ADDR PROC.E);
PSPEC CYCLE($IN,ADDR OPD.E);
PSPEC CV.CYCLE(ADDR VAR.E,$IN,ADDR OPD.E,$IN);
PSPEC CV.LIMIT($IN,ADDR OPD.E);
PSPEC REPEAT();
PSPEC CHECK.OPD($IN,ADDR OPD.E,$IN)/$IN;
PSPEC CHECK.OPD.MODE($IN,$IN,ADDR[INST.SEQ.E],$IN)/$IN;
PSPEC ASS();
PSPEC ASS.END();
PSPEC END.CODE.AREA();
PROC END.CODE.AREA; END;
#MTL27.1
#MTL27.2
#MTL27.3
#MTL27.4
#MTL27.5
#MTL27.6
#MTL27.7
#MTL27.8
#MTL27.9
#MTL27.10
#MTL27.16
#MTL27.17
#MTL27.21
#MTL27.22
#MTL27.11
#MTL27.12
#MTL27.13
#MTL27.14
#MTL27.15
#MTL27.18
#MTL27.19
#MTL27.23
#MTL27.24
#MTL27.25
#MTL27.26
#MTL27.27
#MTL27.28
#MTL27.29
#MTL27.30
#MTL27.31
#MTL27.32
#MTL27.33
#MTL27.34
#MTL27.35
@END
@TITLE MTL27.1(3,11)
@COL 9N-10R-11N
@COL 1S-2R-14R-4R-5R-6R-7R-16T-8F
@COL 12R
@COL 13R
@ROW 9-4
@ROW 10-6-12-13
@FLOW 1-2-14-4-5
@FLOW 6-7-16Y-8
@FLOW 16N-11-9-4
@FLOW 10-7
@FLOW 12-7
@FLOW 13-7
@BOX 1.0
PLANT(INST.SEQ)
@BOX 2.0
DECLARATIONS &
INITIALISATION
@BOX 14.0
DATA VECTORS
FOR DRIVING
CODE GENERATION
[MTL27.1.7]
@BOX 4.0
SET UP FOR
NEXT FUNCTION
IN INST SEQ
@BOX 5.0
SWITCH ON
REGISTER
@BOX 6.0
A
[MTL27.1.2]
[MTL27.1.4]
@BOX 7.0
RELEASE REGISTERS
NOT REQUIRED
@BOX 16.0
ALL SEQUENCE
PROCESSED
@BOX 8.0
END
@BOX 10.0
B
[MTL27.1.1]
@BOX 12.0
D
[MTL27.1.3]
@BOX 13.0
ORG
[MTL27.1.5]
@BOX 1.1
PROC PLANT(INST.SEQ);
::DEBUG IF TL.PR.M & %80 /= 0 THEN
::DEBUG OUTPLANT(INST.SEQ) FI
@BOX 2.1
ADDR PROC.E  PROC.P;
ADDR STORE.E ST.P;
$IN CPTR,T,Z,OPC;
$IN32 J;
$IN I,K,L,M;
$IN FN,IOFF,INST,REG,TEMP.REG,
   REG.SPEC,B.TYPE,
    OPD.GOT,NO.OPDS,OPD.CONV,
    OPDKIND,ISPTR,NIS;
$LO32 FN.BIT,OFFSET,ADDRESS;
$LO64 MASK,VAL;
ADDR LAB.E LAB.P;
ADDR OPD.E  OPD.DESC.P;
$IN OPD1.MODE,OPD2.MODE,OPD3.MODE,
    OVP1,OVP2,FN.CODE,OPD.ORDER,TREGS23,
    FN2,FN3,FN2.PTR,FN3.PTR,COLN,AOBP;
$LO8[16] OPD1.VEC,OPD2.VEC;
$LI/$IN32 LOAD.FN = %6,SHIFT.FN = %C0,
    STORE.FN = %7F380001;
$LO8[4] IOPDK,IOPDL;
0 => ISPTR;
SIZE(INST.SEQ) => NIS;
@BOX 14.1
#MTL27.1.7
@BOX 4.1
0 => TEMP.REGS;
OP.CODE OF INST.SEQ^[ISPTR] => OPC
& %1F => FN;
1 <<- FN => FN.BIT;
REG.SPEC OF INST.SEQ^[IS.PTR] => REG.SPEC;
OPD.KIND OF INST.SEQ^[IS.PTR] => OPD.KIND;
^OPD OF INST.SEQ^[IS.PTR] => OPD.DESC.P;
@BOX 5.1
SWITCH OPC ->> 5 & %3
\ IN.B,IN.A,IN.DREG,IN.ORG;
@BOX 6.1
IN.A:
#MTL27.1.2
@BOX 7.1
IF TEMP.REGS /= 0 THEN
REL.TEMP.REGS(TEMP.REGS) FI
IF REG.SPEC /= 0 THEN
REL.REGS(REG.SPEC) FI
@BOX 16.1
IF 1 +> ISPTR < NIS
@BOX 8.1
END;
@BOX 10.1
IN.B:
#MTL27.1.1
@BOX 12.1
IN.DREG:
#MTL27.1.3
@BOX 13.1
IN.ORG:
#MTL27.1.5
@END
@TITLE MTL27.1.1(3,6)
@COL 1S-2R-3R-4R-5C-6C-7T-9R-11F
@COL 12T-13R
@ROW 9-12
@FLOW 1-2-3-4-5
@FLOW 6-7Y-9-11
@FLOW 7N-12N-13-11
@FLOW 12Y-11
@BOX 1.0
PROCESS B
FUNCTIONS
@BOX 2.0
SET UP TO
PROCESS B
FUNCTION
@BOX 3.0
SET INDEX IN
CODES VECTOR FOR
FUNCTION FOR
INTEGER32 ARITHMETIC
@BOX 4.0
IF LOAD FUNCTION
SET UP REGISTER
FOR B
@BOX 5.0
AFN
LOOP
@BOX 6.0
BFN
END
@BOX 7.0
LOAD FUNCTION?
@BOX 9.0
RELEASE TEMPORARY
REGISTER IF ANY
SET B REGISTER
IN USE
@BOX 11.0
END
@BOX 12.0
IN CORRECT
MODE?
@BOX 13.0
CONVERT B REGISTER
@BOX 1.1
::PROCESS B
::FUNCTIONS
@BOX 2.1
BREG => REG;
%11 => B.TYPE;
0 => IOFF;
@BOX 3.1
INDICES[BFN.START + FN] - 1 => CPTR;
@BOX 4.1
IF FN.BIT & LOAD.FN /= 0 THEN
B => BREG => REG FI
@BOX 5.1
->AFN.LOOP;
@BOX 6.1
BFN.END:
@BOX 7.1
IF FN.BIT & LOAD.FN = 0
@BOX 9.1
IF TEMP.REGS /= 0 THEN
REL.TEMP.REGS(TEMP.REGS) FI
RESERVE.REGS(BREG,1);
@BOX 11.1
::END 27.1.1
@BOX 12.1
IF B.TYPE = %11
@BOX 13.1
CONVERT(3,B.TYPE,%11,B.REG);
@END
@TITLE MTL27.1.2(3,8)
@COL 1S-3T-4R-5R-6C-2R-21T-22R-23T-7R-8R-9R-10R-11R
@COL 12R-13C-14T-15T-17R-19F-24R
@COL 20C
@ROW 4-12
@ROW 15-20
@FLOW 1-3N-4-5-6-2-21N-22-23N-7-8-9-10-11-7
@FLOW 3Y-12-19
@FLOW 21Y-24-13
@FLOW 23Y-24
@FLOW 13-14N-15Y-17-19
@FLOW 14Y-20
@FLOW 15N-19
@BOX 1.0
PROCESS
A FUNCTIONS
@BOX 2.0
SET UP FOR
THIS FUNCTION
@BOX 3.0
GENERIC OR
POINTER ETC?
@BOX 4.0
CALCULATE INDEX IN
INDICES FROM FUNCTION
AND ARITHMETIC TYPE
SET INDEX INTO
CODES VECTOR
SET INSTRUCTION OFFSET
@BOX 5.0
IF LOAD FUNCTION
SET UP REGISTER
FOR A
@BOX 6.0
AFN
LOOP
@BOX21.0
2/3 ADDRESS ETC
OPERAND REQUIRED?
@BOX22.0
ATTEMPT TO PLANT
2/3 ADDRESS INSTRUCTION
[MTL27.1.6]
@BOX23.0
2/3 ADDRESS ETC
OPERAND REQUIRED?
@BOX 7.0
PROCESS DRIVER
WORDS
[MTL27.1.2.1]
[MTL27.1.2.2]
@BOX 8.0
SET INST CODE
FROM CODES VECTOR
ADD OFFSET IF
REQUIRED
@BOX 9.0
PROCESS
OPERANDS
[MTL27.1.2.3]
@BOX 10.0
PLANT INST CODE
@BOX 11.0
PLANT INST
OPERANDS
[MTL27.1.2.4]
@BOX 12.0
PROCESS GENERIC,
POINTER ETC FUNCTIONS
[MTL27.1.4]
@BOX 13.0
AFN
END
@BOX 14.0
IN B REGISTER?
@BOX 15.0
LOAD FUNCTION?
@BOX 17.0
RELEASE TEMPORARY
REGISTERS IF ANY
SET A REGISTER
IN USE
@BOX 19.0
END
@BOX24.0
EVALUATE 2/3 ADDRESS
ETC OPERANDS
[MTL27.1.2.5]
@BOX 20.0
BFN
END
@BOX 1.1
::PROCESS
::A FUNCTIONS
@BOX 2.1
-1 => TEMP.REG => OPD.CONV;
0 => OPD.GOT;
@BOX 3.1
IF OPC ->> 7 & %7 => T >= 4
@BOX 4.1
INDICES[IND.STARTS[OPC ->> 10 & %7 => Z
+ COL[T] =>  COLN] + FN] - 1 => CPTR;
FN.OFFS[COLN] => IOFF;
@BOX 5.1
AREG => REG;
IF FN.BIT & LOAD.FN /= 0 THEN
A => AREG => REG;
OPC ->> 7 => A.TYPE FI
@BOX 6.1
AFN.LOOP:
@BOX21.1
IF OPC & %8000 /= 0
@BOX22.1
#MTL27.1.6
@BOX23.1
IF OPC & %8000 /= 0
@BOX 7.1
2 => NO.OPDS;
#MTL27.1.2.1
->AROUND;
#MTL27.1.2.2
AROUND:
@BOX 8.1
CODES[1+>CPTR] - IOFF => INST;
@BOX 9.1
#MTL27.1.2.3
@BOX 10.1
PLANT.BY(INST);
@BOX 11.1
#MTL27.1.2.4
@BOX 12.1
#MTL27.1.4
@BOX 13.1
AFN.END:
@BOX 14.1
IF REG = B.REG
@BOX 15.1
IF FN.BIT & LOAD.FN = 0
@BOX 17.1
IF TEMP.REGS /= 0 THEN
REL.TEMP.REGS(TEMP.REGS) FI
RESERVE.REGS(AREG,
(IF Z >= 3 THEN 2 ELSE 1));
@BOX 19.1
::END 27.1.2
@BOX24.1
#MTL27.1.2.5
@BOX 20.1
->BFN.END;
@END
@TITLE MTL27.1.2.1(3,10)
@COL 9C-10T-11R-12C-13R-14R-16C
@COL 1S-2T-3F-4R-5R-30C-6R-7R-8C
@COL 17C-18R-19R-20R-31C-21R-22R-23C
@COL 24R-25R-26C-27R-28R-29C
@ROW 3-18
@ROW 11-4-19-24
@ROW 13-6-21-27
@FLOW 1-2Y-3
@FLOW 2N-18
@FLOW 4-5-30
@FLOW 6-7-8
@FLOW 9-10N-3
@FLOW 10Y-2
@FLOW 11-12
@FLOW 13-14-16
@FLOW 17-2
@FLOW 19-20-31
@FLOW 21-22-23
@FLOW 24-25-26
@FLOW 27-28-29
@BOX 1.0
PROCESS
DRIVER WORDS
@BOX 2.0
SET DRIVER WORD
FROM CODES VECTOR
IS IT = 0?
@BOX 3.0
END
@BOX 4.0
2,FAULT
@BOX 5.0
FAULT,
ILLEGAL
FUNCTION
@BOX 30.0
AFN
END
@BOX 6.0
6,SETFNOFF
@BOX 7.0
SET INST CODE
OFFSET FROM
BITS 6-4 OF
DRIVER WORD
@BOX 8.0
GET
NEXT
@BOX 9.0
GET
NEXT
@BOX 10.0
TOP BIT SET
IN LAST
DRIVER WORD?
@BOX 11.0
1,EOS
@BOX 12.0
AFN
END
@BOX 13.0
5,GETOPD
@BOX 14.0
EVALUATE OPERAND
SETTING EVALUATION
MODE FROM
NEXT BYTE IN
CODES VECTOR
NOTE OPERAND
PROCESSED
@BOX 16.0
GET
NEXT
@BOX 17.0
NEXT
@BOX 18.0
SWITCH ON
DRIVER WORD
@BOX 19.0
3,OPDCONV
@BOX 20.0
SET UP TO
CHECK OPERAND
@BOX 31.0
CHECK.OPD
[MTL27.1.2.3]
@BOX 21.0
7,SUBR
@BOX 22.0
SPECIAL
SUBROUTINES
[MTL27.1.2.1.1]
@BOX 23.0
GET
NEXT
@BOX 24.0
4,OPNDS
@BOX 25.0
SET NUMBER OF
OPERANDS IN NEXT
INSTRUCTION FROM
BITS 6-4 OF
DRIVER WORD
@BOX 26.0
GET
NEXT
@BOX 27.0
8,JUMP
@BOX 28.0
SET NEW POSITION
IN CODES VECTOR
FROM BITS 7-4 OF
DRIVER WORD AND
NEXT BYTE IN
CODES VECTOR
@BOX 29.0
NEXT
@BOX 1.1
::PROCESS
::DRIVER WORDS
@BOX 2.1
IF CODES[1+>CPTR] => I /= 0
@BOX 3.1
::END 27.1.2.1
@BOX 4.1
DW2:
@BOX 5.1
FAULT(0,%"ILLEGAL FUNCTION$LOPC=");
OUTHEX(OPC,4);
@BOX 30.1
->AFN.END;
@BOX 6.1
DW6:
@BOX 7.1
I & %70 <<- 1 => IOFF;
@BOX 8.1
->GET.NEXT;
@BOX 9.1
GET.NEXT:
@BOX 10.1
IF I & %80 /= 0
@BOX 11.1
DW1:
@BOX 12.1
->AFN.END;
@BOX 13.1
DW5:
@BOX 14.1
GET.OPD(CODES[1+>CPTR],
OPC,OPD.KIND,OPD.DESC.P);
1 => OPD.GOT;
@BOX 16.1
-> GET.NEXT;
@BOX 17.1
NEXT:
@BOX 18.1
SWITCH I & %F -1 \
DW1,DW2,DW3,DW4,DW5,DW6,
DW7,DW8,DW9,DW10,DW11,
DW12,DW13,DW14,DW15;
@BOX 19.1
DW3:
@BOX 20.1
-1 => J;
@BOX 31.1
->CHECK.OPD;
@BOX 21.1
DW7:
@BOX 22.1
#MTL27.1.2.1.1
@BOX 23.1
->GET.NEXT;
@BOX 24.1
DW4:
@BOX 25.1
I ->> 4 & %7 => NO.OPDS;
@BOX 26.1
->GET.NEXT;
@BOX 27.1
DW8:
@BOX 28.1
I & %F0 <<- 4
! CODES[1+>CPTR]
-1 => CPTR;
@BOX 29.1
->NEXT;
@END
@TITLE MTL27.1.2.1.1(3,8)
@COL 1S-2R-3R-4R-5F-10R-11R-19R-20R-26R-27R
@COL 6R-7R-14N-12R-13R-15N-21R-22T-23R-28R
@COL 8R-9R-16R-18R-24R-25C-29R-30R
@ROW 3-6-8
@ROW 10-12-16
@FLOW 1-2
@FLOW 3-4-5
@FLOW 6-7-14-5
@FLOW 8-9-14
@FLOW 10-11-5
@FLOW 12-13-15-5
@FLOW 16-18-15
@FLOW 19-20-5
@FLOW 21-22Y-23-28-5
@FLOW 22N-24-25
@FLOW 26-27-5
@FLOW 29-30-28
@BOX 1.0
SPECIAL
SUBROUTINES
@BOX 2.0
SWITCH ON
SUBROUTINE
NUMBER
@BOX 3.0
SUBR 0
@BOX 4.0
PLANT CODE ETC
FOR MATHS FUNCTION
ODD (INTEGER)
@BOX 5.0
END
@BOX 10.0
SUBR 3
@BOX 11.0
SET UP MASK FOR
L64 ->> LITERAL
@BOX 19.0
SUBR 6
@BOX 20.0
IF INTERPRETIVE
PROC CALL INCREMENT
AND STACK LONGWORD
COUNT
@BOX 26.0
SUBR 8
@BOX 27.0
PLANT CODE FOR
FLOATING ABS
@BOX 6.0
SUBR 1
@BOX 7.0
SET UP MASK FOR
I32 ->> LITERAL
@BOX 12.0
SUBR 4
@BOX 13.0
SET UP MASK FOR
I32/L32/L64 ->> VARIABLE
@BOX 16.0
SUBR 5
@BOX 18.0
CHECK IF ACCL
IS IN USE
@BOX 8.0
SUBR 2
@BOX 9.0
SET UP CMP.TYPE
WITH ARITHMETIC
TYPE USED IN
COMPARE
@BOX 21.0
SUBR 7
@BOX 22.0
IS MATH FN
A PROC CALL?
@BOX 23.0
PLANT CODE TO
STACK A REGISTER
SET UP FOR
APPROPRIATE LIB PROC
@BOX 28.0
PLANT CODE TO
CALL LIB PROC
@BOX 24.0
SET INDEX IN INDICES
FOR MATH FN
@BOX 25.0
NEXT
[MTL27.1.2.1]
@BOX 29.0
SUBR 9
@BOX 30.0
(EXPONENTIATION)
PLANT CODE TO
STACK A REGISTER
PLANT CODE TO
STACK OPERAND
SET UP FOR
APPROPRIATE
LIB PROC
@BOX 1.1
::SPECIAL
::SUBROUTINES
@BOX 2.1
SWITCH CODES[1 +> CPTR]\
S0,S1,S2,S3,S4,S5,S6,S7,S8,S9;
@BOX 3.1
S0:
@BOX 4.1
PLANT.BY(BICL2);
PLANT.LIT.OPD(4,%F(7)E);
PLANT.BY(REGM ! AREG);
%02 => A.TYPE;
@BOX 5.1
::END 27.1.2.1.1
@BOX 10.1
S3:
@BOX 11.1
LIT => J;
0 - J => J;
%F(16) ->> J -= %F(16) => MASK;
@BOX 19.1
S6:
@BOX 20.1
IF CALL.I < 0 THEN
PLANT.BY(ADDL3);
PLANT.BY(REGM ! INT.AP.CNT.REG);
PLANT.BY((IF OPD.SIZE =< 4 THEN
1 ELSE 2));
PLANT.BY(SP.MINUS);
FI
@BOX 26.1
S8:
@BOX 27.1
PLANT.BY(BICW2);
PLANT.LIT.OPD(2,%8000);
PLANT.BY(REGM ! AREG);
@BOX 6.1
S1:
@BOX 7.1
LIT => J;
0 -J => J;
1 <<- J - 1 => J;
J => MASK;
@BOX 12.1
S4:
@BOX 13.1
%80(15) => MASK;
@BOX 16.1
S5:
@BOX 18.1
IF 2 <<- AREG & REGS.IU /= 0 THEN
::DEBUG FAULT(0,%"ACCL IN USE AT SHIFT");
FI
@BOX 21.1
S7:
@BOX 22.1
IF MFN.INDS[MFN OF OPD.DESC.P^
=> K + (T * 58) + (Z - 2 * 29)] => J >= 0
@BOX 23.1
IF SP.DISP & %3 => M /= 0 THEN
PLANT.BY(SUBL2);
PLANT.BY(4 - M);
PLANT.BY(REGM ! SP) FI
-1 - J => J;
PLANT.BY((IF Z = 3 THEN
MOVQ ELSE MOVL));
PLANT.BY(REGM ! AREG);
PLANT.BY(SP.MINUS);
(IF K = 24 THEN
2 ELSE 1) => K;
IF Z = 3 THEN
2 *> K FI
@BOX 28.1
PLANT.BY(CALLSI);
PLANT.BY(K);
MFN.PROCS[J] => J & %FF
* 8 - 4 + (J & %7FFF0000) => J;
PLANT.BY(ABSOLUTE);
PLANT.REF(PROC.ADDR.REF,J);
IF M /= 0 THEN
PLANT.BY(ADDL2);
PLANT.BY(4 - M);
PLANT.BY(REGM ! SP) FI
@BOX 24.1
INDICES[MFN.START + J]
- 1 => CPTR;
@BOX 25.1
->NEXT;
@BOX 8.1
S2:
@BOX 9.1
A.TYPE => CMP.TYPE;
@BOX 29.1
S9:
@BOX 30.1
IF SP.DISP & %3 => M /= 0 THEN
PLANT.BY(SUBL2);
PLANT.BY(4 - M);
PLANT.BY(REGM ! SP) FI
IF OPD.KIND = 8 THEN
IF OPD.SIZE = 8 THEN
MOVQ => J;2 => K;
ELSE
MOVL => J;1 => K;
FI
PLANT.BY(J);
PLANT.BY(SP.PLUS);
PLANT.BY(GET.TEMP.REG(K)
! REGM => OPD.VEC[0 => OVP]);
FI
PLANT.BY(MOVL - IOFF);
PLANT.BY(REGM ! AREG);
PLANT.BY(SP.MINUS);
(IF Z = 3 THEN
3 ELSE 2) => K - 2 * 3 + 28 => J;
IF T /= 0 THEN
6 +> J FI
IF OPD.SIZE = 8 THEN
1 +> J; 1 +> K; MOVQ => L;
ELSE
MOVL => L;
IF OPD.MODE /= 0 THEN
2 +> J FI FI
PLANT.BY(L);
PLANT.OPD(^OPD.VEC,OVP);
PLANT.BY(SP.MINUS);
@END
@TITLE MTL27.1.2.2(3,6)
@COL 1R-2R-3C-4R-5T-6C
@COL 7R-8R-9N-10R-11C
@COL 12R-13R-14N-17R-18R-22R-23R-30R
@COL 21C-16R-24R-25R-31R-32R
@ROW 6-10
@ROW 22-31
@FLOW 1-2-3-4-5N-6
@FLOW 5Y-10-11
@FLOW 7-8-9-3
@FLOW 12-13-14-9
@FLOW 21-16-14
@FLOW 17-18-9
@FLOW 22-23-30-9
@FLOW 24-25-14
@FLOW 31-32-30
@BOX 1.0
9,OPDLIT
@BOX 2.0
SET CONDITION
TRUE IF OPERAND
IS A LITERAL
ELSE FALSE
@BOX 3.0
BRANCH
@BOX 4.0
SET BRANCH
DISPLACEMENT
FROM NEXT BYTE
IN CODES VECTOR
@BOX 5.0
IS CONDITION STATE
AS INDICATED BY BIT 4
OF DRIVER WORD?
@BOX 6.0
GET
NEXT
@BOX 7.0
10,OPDNLIT
@BOX 8.0
SET CONDITION
TRUE IF OPERAND
IS A NEGATED
LITERAL ELSE FALSE
@BOX 10.0
SET NEW POSITION
IN CODES VECTOR
@BOX 11.0
NEXT
@BOX 12.0
11,REG.REQD
@BOX 13.0
SET CONDITION
TRUE IF REGISTER
IS REQUIRED
AFTER FUNCTION
ELSE FALSE
@BOX 17.0
13,OPDRES
@BOX 18.0
SET CONDITION
TRUE IF OPERAND
IS RESULT
ELSE FALSE
@BOX 22.0
14,TESTMASK
@BOX 23.0
SET UP TO TEST
VALUE OF MASK
@BOX 30.0
SET UP TO TEST
LEFT OR RIGHT
HALF OF VALUE
SET CONDITION TRUE
IF VALUE IS THAT
INDICATED BY ENCODING
IN NEXT WORD IN
CODES VECTOR
@BOX 21.0
OPD.CHECKED
@BOX 16.0
SET CONDITION
TRUE IF OPERAND
HAS BEEN CONVERTED
ELSE FALSE
@BOX 24.0
12,OPDAP
@BOX 25.0
SET CONDITION TRUE
IF OPERAND IS
PARAMETER STACK
ELSE FALSE
@BOX 31.0
15,TESTLIT
@BOX 32.0
SET UP TO TEST
VALUE OF LITERAL
@BOX 1.1
DW9:
@BOX 2.1
(IF OPDK = LITK THEN
%10 ELSE 0) => J;
@BOX 3.1
BRANCH:
@BOX 4.1
CODES[1+>CPTR] - 2 => K;
@BOX 5.1
IF I & %10 /= J
@BOX 6.1
-> GET.NEXT;
@BOX 7.1
DW10:
@BOX 8.1
(IF OPDK = NLITK THEN
%10 ELSE 0) => J;
@BOX 10.1
K +> CPTR;
@BOX 11.1
->NEXT;
@BOX 12.1
DW11:
@BOX 13.1
(IF REG = AREG THEN
2 ELSE 1) => J;
(IF REG.SPEC & J = 0 THEN 1 ELSE 0) => J;
@BOX 17.1
DW13:
@BOX 18.1
(IF OPDK = RESK THEN
%10 ELSE 0) => J;
@BOX 22.1
DW14:
@BOX 23.1
MASK => VAL;
@BOX 30.1
IF I & %40 /= 0 THEN
VAL ->> 32 => J
ELSE
VAL & %F(8) => J;
FI
(IF CODES[1 +> CPTR] - 1 = J THEN
%10 ELSE 0) => J;
@BOX 21.1
OPD.CHECKED:
@BOX 16.1
(IF OPD.CONV >= 0 THEN
%10 ELSE 0 ) => J;
@BOX 24.1
DW12:
@BOX 25.1
(IF OPD.KIND = 7 THEN
%10 ELSE 0) => J;
@BOX 31.1
DW15:
@BOX 32.1
LIT => VAL;
@END
@TITLE MTL27.1.2.3(3,11)
@COL 19R-20T-21R-12R-13R-17R-18R-22T-23N
@COL 1S-2R-3T-4R-5R-6T-7R-8R-24C-9T-27T-10R-11R-25T-26C
@COL 14F-15R-16R-28R
@ROW 4-14
@ROW 19-5-15
@ROW 10-28
@FLOW 1-2-3N-4
@FLOW 3Y-14
@FLOW 5-6N-7-8-24-9N-27N-10-11-25Y-26
@FLOW 6Y-22N-23-9
@FLOW 9Y-25
@FLOW 27Y-28-25
@FLOW 25N-13
@FLOW 19-20N-21-13
@FLOW 20Y-13
@FLOW 12-13-3
@FLOW 17-18-13
@FLOW 22Y-13
@FLOW 15-16-8
@BOX 1.0
PROCESS INST OPERANDS
@BOX 2.0
INITIALISE
@BOX 3.0
ALL OPERANDS
PROCESSED?
@BOX 4.0
GET NEXT INST
OPERAND KIND FROM
CODES VECTOR AND
SWITCH USING IT
@BOX 5.0
1,OPD
@BOX 6.0
OPERAND ALREADY
EVALUATED?
@BOX 7.0
CLEAR OPERAND
EVALUATION MODE
@BOX 8.0
EVALUATE OPERAND
NOTE OPERAND
EVALUATED
@BOX 24.0
CHECK.OPD
@BOX 9.0
OPERAND CORRECT
TYPE?
@BOX 27.0
STORE OPERATOR AND IN
B REGISTER?
@BOX 10.0
SET DESTINATION
FOR CONVERSION
USE A/B IF LOAD
OTHERWISE USE
TEMPORARY REGISTER
@BOX 11.0
PLANT CONVERSION
SET OPERAND TO
DESTINATION REGISTER
@BOX 25.0
FROM OPDCONV
TEST?
@BOX 26.0
OPD.CHECKED
[MTL27.1.2.2]
@BOX 19.0
3,TEMP
6,TEMPL
7,TEMPR
@BOX 20.0
TEMP REGISTER
OBTAINED?
@BOX 21.0
OBTAIN TEMP
REGISTER
@BOX 12.0
0,ACC
4,ACCL
5,ACCR
8,VAL8
9,MASKL
10,MASKR
11,STK
12,UNSTK
13,TOS
@BOX 13.0
NOTE INST
OPERAND KIND
@BOX 17.0
14,LIT
@BOX 18.0
NOTE BYTE LITERAL
VALUE FROM NEXT
BYTE IN CODES
VECTOR
@BOX 22.0
HAS IT BEEN
TYPE CHECKED?
@BOX 14.0
END
@BOX 15.0
2,OPD(MODE)
@BOX 16.0
SET OPERAND
EVALUATION MODE
FROM NEXT BYTE
IN CODES VECTOR
@BOX 28.0
CONVERT B REGISTER
SET INST CODE OFFSET
NOTE B REGISTER TYPE
@BOX 1.1
::PROCESS INST
::OPERANDS
@BOX 2.1
-1 => I;
@BOX 3.1
IF 1 +> I = NO.OPDS
@BOX 4.1
SWITCH CODES[1+>CPTR] => J \
IOK0,IOK1,IOK2,IOK3,
IOK4,IOK5,IOK6,IOK7,
IOK8,IOK9,IOK10,IOK11,
IOK12,IOK13,IOK14;
@BOX 5.1
IOK1:
@BOX 6.1
IF OPD.GOT /=0
@BOX 7.1
0 => K;
@BOX 8.1
GET.OPD(K,OPC,OPD.KIND,OPD.DESC.P);
@BOX 24.1
CHECK.OPD:
@BOX 9.1
3 => OPD.GOT;
IF OPD.MODE /= 5 THEN
MODE.FROM.SIZE[OPD.SIZE] ! OPD.MODE => L;
ELSE
OPD.SIZE ->> 3 ! OPD.MODE =>  L FI
IF L = OPC ->> 7 => K
OR FN.BIT & SHIFT.FN /= 0
@BOX 27.1
IF REG = B.REG
AND FN.BIT & STORE.FN /= 0
@BOX 10.1
(IF FN.BIT & LOAD.FN /= 0 THEN
REG ELSE TEMP.REG) => M;
@BOX 11.1
IF CONVERT(0,L,K,M) => OPD.CONV >= 0 THEN
OPD.CONV => TEMP.REG
! REGM => OPD.VEC[0 => OVP];
6 => OPDK FI
@BOX 25.1
IF J >= 0
@BOX 26.1
->OPD.CHECKED;
@BOX 19.1
IOK3:
IOK6:
IOK7:
@BOX 20.1
IF TEMP.REG >= 0
@BOX 21.1
GET.TEMP.REG((IF Z >= 3
THEN 2 ELSE 1)) => TEMP.REG;
@BOX 12.1
IOK0:
IOK4:
IOK5:
IOK8:
IOK9:
IOK10:
IOK11:
IOK12:
IOK13:
@BOX 13.1
J => IOPDK[I];
@BOX 17.1
IOK14:
@BOX 18.1
CODES[1+>CPTR]
=> IOPDL[I];
@BOX 22.1
IF OPD.GOT = 3
@BOX 14.1
::END 27.1.2.3
@BOX 15.1
IOK2:
@BOX 16.1
CODES[1+>CPTR] => K;
@BOX 28.1
IF L /= %12 THEN
CONVERT(3,%11,L=>B.TYPE,B.REG);
(IF OPD.SIZE = 2 THEN
%20 ELSE %40) => IOFF ->INST; FI
@END
@TITLE MTL27.1.2.4(3,7)
@COL 10R-11R-12R-13R-25R-26R-20R-21R
@COL 1S-2R-3T-4R-5R-6R-7R-8R-9R-22R-27R-23R-24N
@COL 14F-15R-16R-28R-29R-30R-31R-32R-33R-34R-17R-18R
@ROW 4-14
@ROW 10-5-15
@ROW 12-7
@FLOW 1-2-3N-4
@FLOW 5-6-9-3
@FLOW 7-8-9
@FLOW 10-11-9
@FLOW 12-13-9
@FLOW 25-26-23
@FLOW 15-16-3
@FLOW 28-29-34
@FLOW 30-31-34
@FLOW 32-33-34-3
@FLOW 17-18-3
@FLOW 3Y-14
@FLOW 20-21-24
@FLOW 22-27-23-24-3
@BOX 1.0
PLANT INST
OPERANDS
@BOX 2.0
INITIALISE
@BOX 3.0
ALL INST OPERANDS
PROCESSED?
@BOX 4.0
SWITCH ON NEXT
INST OPERAND KIND
@BOX 5.0
4,ACCL
@BOX 6.0
SET REGISTER
AS ACC/B + 1
@BOX 7.0
6,TEMPL
@BOX 8.0
SET REGISTER AS
TEMP REGISTER + 1
@BOX 9.0
PLANT REGISTER
OPERAND
@BOX 22.0
9,MASKL
@BOX 27.0
SET MASK OPERAND
AS MOST SIGNIFICANT
32 BITS OF MASK
@BOX 23.0
PLANT MASK
OPERAND
@BOX 10.0
0,ACC
5,ACCR
@BOX 11.0
SET REGISTER
AS ACC/B
@BOX 12.0
3,TEMP
7,TEMPR
@BOX 13.0
SET REGISTER AS
TEMP REGISTER
@BOX 25.0
10,MASKR
@BOX 26.0
SET MASK OPERAND AS
LEAST SIGNIFICANT
32 BITS OF MASK
@BOX 20.0
8,VAL8
@BOX 21.0
PLANT BYTE
LITERAL
OPERAND
@BOX 14.0
END
@BOX 15.0
1,OPD
2,OPD(MODE)
@BOX 16.0
PLANT OPERAND
@BOX 28.0
11,STK
@BOX 29.0
SET UP FOR
STACK OPERAND
-(SP)
@BOX 30.0
12,UNSTK
@BOX 31.0
SET UP FOR
UNSTACK OPERAND
(SP)+
@BOX 32.0
13,TOS
@BOX 33.0
SET UP FOR
TOS OPERAND
(SP)
@BOX 34.0
PLANT OPERAND
@BOX 17.0
14,LIT
@BOX 18.0
PLANT NOTED
BYTE LITERAL
@BOX 1.1
::PLANT INST
::OPERANDS
@BOX 2.1
-1 => I;
@BOX 3.1
IF 1 +> I = NO.OPDS
@BOX 4.1
SWITCH IOPDK[I] \
IK0,IK1,IK2,IK3,
IK4,IK5,IK6,IK7,
IK8,IK9,IK10,IK11,
IK12,IK13,IK14;
@BOX 5.1
IK4:
@BOX 6.1
REG + 1 => J;
@BOX 7.1
IK6:
@BOX 8.1
TEMP.REG + 1 => J;
@BOX 9.1
PLANT.BY(REGM ! J);
@BOX 22.1
IK9:
@BOX 27.1
MASK ->> 32 => J;
@BOX 23.1
PLANT.LIT.OPD(4,J);
@BOX 10.1
IK0: IK5:
@BOX 11.1
REG => J;
@BOX 12.1
IK3: IK7:
@BOX 13.1
TEMP.REG => J;
@BOX 25.1
IK10:
@BOX 26.1
MASK & %F(8) => J;
@BOX 20.1
IK8:
@BOX 21.1
PLANT.LIT.OPD(1,LIT & %FF);
@BOX 14.1
::END 27.1.2.4
@BOX 15.1
IK1: IK2:
@BOX 16.1
PLANT.OPD(^OPD.VEC,OVP);
@BOX 28.1
IK11:
@BOX 29.1
SP.MINUS => J;
@BOX 30.1
IK12:
@BOX 31.1
SP.PLUS =>  J;
@BOX 32.1
IK13:
@BOX 33.1
TOS =>  J;
@BOX 34.1
PLANT.BY(J);
@BOX 17.1
IK14:
@BOX 18.1
PLANT.LIT.OPD(1,IOPDL[I]);
@END
@TITLE MTL27.1.2.5(3,8)
@COL 1S-2R-3R-4R-5R-6R-7R-8F
@COL 9R-10R-11R-12R
@ROW 3-9
@ROW 5-11
@FLOW 1-2
@FLOW 3-4-8
@FLOW 5-6-7-8
@FLOW 9-10-8
@FLOW 11-12-8
@BOX1.0
EVALUATE 2/3 ADDRESS
ETC OPERANDS
@BOX2.0
SWITCH ON TYPE
@BOX3.0
0
@BOX4.0
EVALUATE AND SAVE
OPERAND 1
@BOX5.0
2
@BOX6.0
EVALUATE OPERAND 3
@BOX7.0
PLANT FN CODE
AND OPERANDS IN
APPROPRIATE ORDER
@BOX8.0
END
@BOX9.0
1
@BOX10.0
EVALUATE AND SAVE
OPERAND 2
@BOX11.0
3
@BOX12.0
IGNORE
@BOX1.1
::EVALUATE 2/3 ADDRESS
::ETC OPERANDS
@BOX2.1
SWITCH OPC ->> 13 & %3
\T0,T1,T2,T3;
@BOX3.1
T0:
@BOX4.1
GET.OPD(OPD1.MODE,OPC,OPD.KIND,OPD.DESC.P);
TEMP.REGS !> TREGS23;
0 => TEMP.REGS;
OVP => OVP1;
FOR I < OVP1 + 1 DO
OPD.VEC[I] => OPD1.VEC[I] OD
@BOX5.1
T2:
@BOX6.1
GET.OPD(OPD3.MODE,OPC,OPD.KIND,OPD.DESC.P);
@BOX7.1
PLANT.BY(FN.CODE);
OPDK => I;
WHILE OPD.ORDER /= 0 DO
ALTERNATIVE OPD.ORDER & %F - 1 FROM
BEGIN
2 => OPDK;
PLANT.OPD(^OPD1.VEC,OVP1);
END
BEGIN
2 => OPDK;
PLANT.OPD(^OPD2.VEC,OVP2);
END
BEGIN
I => OPDK;
PLANT.OPD(^OPD.VEC,OVP);
END
PLANT.BY(REGM ! REG);
BEGIN
STORE.I OF CODE.SEG.P^ =>AOBP;
PLANT.BY(0);
%8066 => OP.CODE OF INST.SEQ^[IS.PTR+1];
END
END
OPD.ORDER ->> 4 => OPD.ORDER;
OD
TREGS23 !> TEMP.REGS;
@BOX8.1
::END 27.1.2.5
@BOX9.1
T1:
@BOX10.1
GET.OPD(OPD2.MODE,OPC,OPD.KIND,OPD.DESC.P);
TEMP.REGS !> TREGS23;
0 => TEMP.REGS;
OVP => OVP2;
FOR I < OVP2 + 1 DO
OPD.VEC[I] => OPD2.VEC[I] OD
@BOX11.1
T3:
@BOX12.1
::IGNORE
@END
@TITLE MTL27.1.3(3,7)
@COL 20T
@COL 1S-2T-3R-4R-5T-6R-7T-8T-9R-10R-11R-18R-12F
@COL 13R-19R-14T-15T-16R-17R
@ROW 3-13
@ROW 6-14
@ROW 20-8
@ROW 11-17
@FLOW 1-2N-3-4-5Y-6-7Y-8Y-9-10-11-18-12
@FLOW 2Y-13-19-12
@FLOW 5N(=>)-14Y-15N-16-17-12
@FLOW 7N-20Y-18
@FLOW 20N-11
@FLOW 8N-10
@FLOW 14N-17
@FLOW 15Y-17
@BOX 1.0
PROCESS
D FUNCTIONS
@BOX 2.0
BASE OR LIMIT?
@BOX 3.0
PROCESS
OPERAND
@BOX 4.0
SET INST CODE
FROM OPERAND SIZE
AS MOVE QUADWORD
OR MOVE LONGWORD
@BOX 5.0
LOAD?
@BOX 6.0
SET UP
REGISTER FOR D
@BOX 7.0
REFERENCE TO
OPERAND REQUIRED?
@BOX 8.0
BOUNDED REFERENCE
REQUIRED?
@BOX 9.0
NOTE WHAT
BOUND SHOULD BE
@BOX 10.0
SET INST CODE
TO APPROPRIATE
MOVE ADDRESS CODE
@BOX 11.0
PLANT INST CODE
WITH OPERAND
AND D REGISTER
@BOX 18.0
RELEASE TEMPORARY
REGISTERS IF ANY
SET D REGISTER
IN USE
@BOX 12.0
END
@BOX 20.0
IS OPERAND
D REGISTER?
@BOX 13.0
SET UP FOR
BASE/LIMIT
@BOX 19.0
PROCESS
BASE OR LIMIT
[MTL27.1.3.1]
@BOX 14.0
BOUNDED POINTER
REQUIRED?
@BOX 15.0
BOUND LOADED
IN D REGISTER?
@BOX 16.0
PLANT CODE TO
LOAD BOUND INTO
D REGISTER
@BOX 17.0
PLANT INST CODE
WITH D REGISTER
AND OPERAND
@BOX 1.1
::PROCESS
::D FUNCTIONS
@BOX 2.1
IF FN >= 6
@BOX 3.1
GET.OPD(0,OPC,OPD.KIND,OPD.DESC.P);
@BOX 4.1
(IF OPD.SIZE = 8 THEN
MOVQ ELSE MOVL) => I;
@BOX 5.1
IF FN /= 2
@BOX 6.1
D => DREG;
(IF OPD.SIZE = 8 THEN
1 ELSE 0) => DKIND;
@BOX 7.1
IF REF.REQD = 0
@BOX 8.1
IF(IF REF.REQD & %8 /= 0 THEN
0 ELSE 3) => DKIND = 0
@BOX 9.1
OPD.DIM => DBOUND;
@BOX 10.1
IF OPD.VEC[0] & %F0 /= INDXD THEN
MOVAB => I ELSE
MOVA.CODES[OPD.SIZE] => I FI
@BOX 11.1
PLANT.BY(I);
PLANT.OPD(^OPD.VEC,OVP);
PLANT.BY(REGM!DREG);
@BOX 18.1
IF TEMP.REGS /= 0 THEN
REL.TEMP.REGS(TEMP.REGS) FI
RESERVE.REGS(DREG,
(IF DKIND & 1 = 1 THEN 2 ELSE 1));
@BOX 12.1
::END 27.1.3
@BOX 20.1
IF OPDK /= 9
@BOX 13.1
DREG => REG;
@BOX 19.1
#MTL27.1.3.1
@BOX 14.1
IF I = MOVL
@BOX 15.1
IF DKIND & 2 = 0
@BOX 16.1
PLANT.BY(MOVL);
PLANT.LIT.OPD(4,DBOUND);
PLANT.BY(REGM!DREG+1);
1 => DKIND;
@BOX 17.1
PLANT.BY(I);
PLANT.BY(REGM!DREG);
PLANT.OPD(^OPD.VEC,OVP);
@END
@TITLE MTL27.1.3.1(3,6)
@COL 11T
@COL 1S-2C-3R-4T-5R-17R-6T-8R-9R-10T-15F
@COL 12R-13T-14R-16C
@ROW 5-12
@ROW 11-8
@ROW 15-16
@FLOW 1-2-3-4N-5-17-6Y-8-9-10N-15
@FLOW 4Y-12-13-14-10
@FLOW 6N-11Y-10
@FLOW 11N-9
@FLOW 10Y-16
@FLOW 13N-10
@BOX 1.0
PROCESS BASE
OR LIMIT
@BOX 2.0
BASE
LIMIT
@BOX 3.0
EVALUATE OPERAND
@BOX 4.0
IS IT LIMIT?
@BOX 5.0
GET ELEMENT SIZE
@BOX 17.0
IF BOUNDED POINTER THEN
IF OPERAND IS B REGISTER
PLANT CODE TO ADD OFFSET
INTO B REGISTER (IF ANY)
THEN PLANT CODE TO SUBTRACT
OPERAND FROM BOUND FIELD
OF POINTER REGISTER
@BOX 6.0
OPERAND IN B?
@BOX 8.0
PLANT CODE TO SCALE
B REGISTER
@BOX 9.0
PLANT CODE TO
ADD OPERAND (B OR OFFSET)
TO POINTER REGISTER
(INTO ADDRESS FIELD)
@BOX 10.0
IN A REGISTER?
@BOX 15.0
END
@BOX 11.0
SCALE OFFSET
IS IT = 0?
@BOX 12.0
PLANT CODE TO LOAD
BOUND FIELD OF
POINTER REGISTER
FROM OPERAND (B OR OFFSET)
NOTE BOUND LOADED
@BOX 13.0
WAS OPERAND IN B?
@BOX 14.0
PLANT CODE TO ADD
OFFSET INTO BOUND FIELD
OF POINTER REGISTER
(IF SET)
@BOX 16.0
A.BL
DONE
[MTL27.1.4]
@BOX 1.1
::PROCESS BASE
::OR LIMIT
@BOX 2.1
BASE.LIM:
@BOX 3.1
B.L.B OF OPD.DESC.P^ => I;
B.L.C OF OPD.DESC.P^ => OFFSET;
@BOX 4.1
IF FN = 7
@BOX 5.1
SIZ OF BL.EL OF OPD.DESC.P^ => J;
@BOX 17.1
IF I /= 0 AND OFFSET /= 0 THEN
PLANT.BY(ADDL2);
PLANT.LIT.OPD(4,OFFSET);
PLANT.BY(REGM ! BREG)
FI
IF I /= 0 OR OFFSET /= 0 THEN
PLANT.BY(SUBL2);
IF I = 0 THEN
PLANT.LIT.OPD(4,OFFSET)
ELSE
PLANT.BY(REGM ! BREG)
FI
PLANT.BY(REGM ! REG + 1)
FI
@BOX 6.1
IF I = 0
@BOX 8.1
IF J /= 1 THEN
PLANT.BY(MULL2);
PLANT.LIT.OPD(4,J);
PLANT.BY(REGM ! BREG) FI
@BOX 9.1
PLANT.BY(ADDL2);
IF I = 0 THEN
PLANT.LIT.OPD(4,OFFSET)
ELSE
PLANT.BY(REGM ! BREG) FI
PLANT.BY(REGM ! REG);
@BOX 10.1
IF REG = AREG
@BOX 15.1
::END 27.1.3.1
@BOX 11.1
IF J *> OFFSET /= 0
@BOX 12.1
1 +> OFFSET;
PLANT.BY(MOVL);
IF I = 0 THEN
PLANT.LIT.OPD(4,OFFSET)
ELSE
PLANT.BY(REGM ! BREG) FI
PLANT.BY(REGM ! REG + 1);
IF REG = DREG THEN
%1 &> DKIND FI
@BOX 13.1
IF I = 0
@BOX 14.1
IF OFFSET /= 0 THEN
IF OFFSET = 1 THEN
PLANT.BY(INCL)
ELSE
PLANT.BY(ADDL2);
PLANT.LIT.OPD(4,OFFSET) FI
PLANT.BY(REGM ! REG + 1) FI
@BOX 16.1
->A.BL.DONE;
@END
@TITLE MTL27.1.4(3,10)
@COL 13R-14R-30T-32T-33R-15T-16R-17R
@COL 1S-2R-3T-4R-5R-6T-7T-8R-29T-9R-10R-11R-12F
@COL 25T-18R-26R-27C-28C-19T-31R-20R-21R-22R-23N
@COL 24R
@ROW 4-25
@ROW 13-7
@ROW 31-24
@FLOW 1-2-3Y-4-5-6N-7Y-8-29N-9-10-11-12
@FLOW 3N-25N-18-12
@FLOW 6Y-13-14-30N-32Y-33-15Y-16-17-10
@FLOW 7N-19N-31-20-21-22-23-12
@FLOW 29Y-11
@FLOW 30Y-9
@FLOW 32N-15N-17
@FLOW 25Y-26-27
@FLOW 28-12
@FLOW 19Y-24-31
@BOX 1.0
PROCESS GENERIC
POINTER ETC FUNCTIONS
@BOX 2.0
SET UP FOR
FUNCTION
@BOX 3.0
IS IT LOAD?
@BOX 4.0
EVALUATE OPERAND
@BOX 5.0
SET GENERIC
A SIZE
SET A.TYPE
@BOX 6.0
REFERENCE TO
OPERAND REQUIRED?
@BOX 7.0
IS OPERAND 1,2,4
OR 8 BYTES LONG?
@BOX 8.0
SET UP REGISTER
FOR GENERIC A
@BOX 29.0
IS OPERAND
A REGISTER?
@BOX 9.0
SET INST CODE TO
APPROPRIATE MOVE CODE
@BOX 10.0
PLANT INST CODE
WITH OPERAND AND
GENERIC A REGISTER
@BOX 11.0
SET GENERIC A
REGISTER IN USE
SET GENERIC
A KIND
@BOX 12.0
END
@BOX 13.0
SET GENERIC
A SIZE AS
APPROPRIATE
@BOX 14.0
SET UP REGISTER
FOR GENERIC A
@BOX 30.0
IS OPERAND LITERAL,
UNDEFINED LABEL
OR UNDEFINED PROC?
@BOX32.0
IS NEXT ITEM IN
INST SEQ STORE TO
ACTUAL PARAMETER?
@BOX33.0
SET UP TO USE
PUSHA INSTS
@BOX 15.0
BOUNDED REFERENCE
REQUIRED?
@BOX 16.0
PLANT CODE TO
LOAD BOUND INTO
GENERIC A
@BOX 17.0
SET INST CODE
TO APPROPRIATE
MOVE ADDRESS CODE
@BOX 25.0
BASE/LIMIT?
@BOX 18.0
GENERIC STORE
OR COMPARE
[MTL27.1.4.1]
@BOX 26.0
SET UP FOR
BASE/LIMIT
@BOX 27.0
BASE
LIMIT
[MTL27.1.3.1]
@BOX 28.0
A.BL
DONE
@BOX 19.0
WERE REGISTERS
R0-R5 IN USE?
@BOX 31.0
IF OPERAND USES
B OR D REGISTER COPY IT
TO TEMPORARY REGISTER
@BOX 20.0
SAVE OPERAND
@BOX 21.0
SAVE TEMP.REGS
AND CLEAR IT
@BOX 22.0
SET GENERIC
A KIND
@BOX 24.0
FAULT
@BOX 1.1
::PROCESS GENERIC
::FUNCTIONS
@BOX 2.1
0 => K;
REGS.IU => I;
@BOX 3.1
IF FN /= 2
@BOX 4.1
GET.OPD(GEN.MODE,OPC,
OPD.KIND,OPD.DESC.P);
@BOX 5.1
OPD.SIZE => GENA.SIZE => J;
OPC ->> 7 => A.TYPE;
@BOX 6.1
IF REF.REQD /= 0
@BOX 7.1
IF J > 8
OR 1 <<- J & %116 = 0
@BOX 8.1
A => AREG;
@BOX 29.1
IF OPDK = 8
@BOX 9.1
MOVE.CODES[OPD.SIZE] => I;
@BOX 10.1
PLANT.BY(I);
PLANT.OPD(^OPD.VEC,OVP);
IF K = 0 THEN
PLANT.BY(REGM!AREG) FI
@BOX 11.1
IF TEMP.REGS /= 0 THEN
REL.TEMP.REGS(TEMP.REGS) FI
RESERVE.REGS(AREG,
(IF J > 4 THEN 2 ELSE 1));
0 => GENA.KIND;
@BOX 12.1
::END 27.1.4
@BOX 13.1
REF.REQD ->> 1 => GENA.SIZE => J;
@BOX 14.1
A => AREG;
@BOX 30.1
IF 1 <<- OPDK & %30001 /= 0
@BOX32.1
IF IS.PTR + 1 >= NIS
OR OPC - 2 /= OP.CODE
OF INST.SEQ^[ISPTR+1]
OR OPD.KIND OF INST.SEQ^[IS.PTR+1] /= 7
OR CALL.I < 0
@BOX33.1
1 => K;
1 +> IS.PTR;
REG.SPEC OF INST.SEQ^[IS.PTR]
!> REG.SPEC;
IF J => L = 4 AND SIZ OF PAR.STK
OF OPD OF INST.SEQ^[IS.PTR] = 8 THEN
8 => L;
PLANT.BY(PUSHL);
PLANT.BY(0) FI
(IF L > 4 THEN 2 ELSE 1)
+> STK.CNT OF LL.CALL OF CALL.S[CALL.I];
@BOX 15.1
IF J = 4
@BOX 16.1
PLANT.BY(%D * K +MOVL);
IF OPDK /= 18 THEN
PLANT.LIT.OPD(4,OPD.DIM);
ELSE
PLANT.BY(IMMED);
ADD.REF(VAR.DIM.REF,VAR.REFS OF VAR.UNDEF
OF VAR.ADDR OF UNDEF.VAR.P^,CODE.SEG.P,
-3,VAR.F OF UNDEF.VAR.P^
=> I & VAR.REFD) => VAR.REFS OF VAR.UNDEF
OF VAR.ADDR OF UNDEF.VAR.P^;
I ! VAR.REFD => VAR.F OF UNDEF.VAR.P^; FI
IF K = 0 THEN
PLANT.BY(REGM!AREG+1) FI
@BOX 17.1
IF OPD.VEC[0] & %F0 /= INDXD THEN
MOVAB + K => I ELSE
MOVA.CODES[OPD.SIZE] + K => I FI
@BOX 25.1
IF FN = 6
OR FN = 7
@BOX 18.1
#MTL27.1.4.1
@BOX 26.1
AREG => REG;
@BOX 27.1
->BASE.LIM;
@BOX 28.1
A.BL.DONE:
@BOX 19.1
IF I & %3F /= 0
@BOX 31.1
IF OPD.VEC[0] & %F => J = BREG
OR J = DREG THEN
GET.TEMP.REG(1) => I;
OPD.VEC[0] & %F0 ! I
=> OPD.VEC[0];
PLANT.BY(MOVL);
PLANT.BY(REGM ! J);
PLANT.BY(REGM ! I) FI
@BOX 20.1
FOR I < OVP + 1 DO
OPD.VEC[I] => GEN.OV[I] OD
PART(^GEN.OV,0,OVP) => GENA.OPD;
@BOX 21.1
TEMP.REGS => GEN.TEMP.REGS;
0 => TEMP.REGS;
@BOX 22.1
(IF OPD.KIND = 8 THEN
5 ELSE 1) => GENA.KIND;
@BOX 24.1
FAULT(0,
%"REGCLASH27.1.4");
OUTHEX(I,4);
@END
@TITLE MTL27.1.4.1(3,9)
@COL 8R
@COL 1S-2R-3T-4R-5T-16T-6R-17R-7F
@COL 9T-10R-11T-12R-13R-14R
@COL 15R
@ROW 4-9
@ROW 10-15
@ROW 8-6
@FLOW 1-2-3N-4-5N(=>)-16N-6-17-7
@FLOW 3Y-9Y-10-11-12-13-14-7
@FLOW 5Y-8-7
@FLOW 16Y-7
@FLOW 9N-15-11
@BOX 1.0
GENERIC STORE
OR COMPARE
@BOX 2.0
EVALUATE
OPERAND
@BOX 3.0
USING STORE
TO STORE ORDERS?
@BOX 4.0
SET INST CODE
@BOX 5.0
64 BIT
COMPARE?
@BOX 16.0
IS OPERAND
RESULT?
@BOX 6.0
PLANT INST CODE
WITH GENERIC A
REGISTER AND OPERAND
@BOX 17.0
IF => PARAMETER
STACK FOR INTERPRETIVE
PROC CALL INCREMENT
LONGWORD COUNT
@BOX 7.0
END
@BOX 8.0
PLANT CODE
FOR 64 BIT
COMPARE
@BOX 9.0
PREVIOUS STORE
OR COMPARE?
@BOX 10.0
PLANT CODE TO
SET UP/ADJUST
ADDRESS IN R1
SET SAVED
OPERAND AS (R1)
@BOX 11.0
SET INST CODE
@BOX 12.0
PLANT INST CODE
WITH SIZE
OPERAND AND
SAVED OPERAND
@BOX 13.0
RELEASE TEMPORARY
REGISTERS IF ANY
SET R0 AND
R1 IN USE
@BOX 14.0
SET GENERIC
A KIND AND
NOTE FUNCTION
@BOX 15.0
RELEASE
SAVED
TEMP.REGS
@BOX 1.1
::GENERIC STORE
::OR COMPARE
@BOX 2.1
IF GENA.KIND = 0 THEN
0 => I ELSE
DONTINDX => I FI
GET.OPD(I,OPC,OPD.KIND,OPD.DESC.P);
@BOX 3.1
IF GENA.KIND /= 0
@BOX 4.1
MOVE.CODES[OPD.SIZE] => I;
IF FN = 15 THEN
1 +> I
ELSE IF OPD.KIND = 7
AND OPD.SIZE < 4 THEN
MOVL => I FI FI
@BOX 5.1
IF I = %7E
@BOX 16.1
IF OPDK = RESK
@BOX 6.1
PLANT.BY (I);
PLANT.BY(REGM!AREG);
PLANT.OPD(^OPD.VEC,OVP);
@BOX 17.1
IF OPD.KIND = 7
AND CALL.I < 0 THEN
PLANT.BY(ADDL3);
PLANT.BY(REGM ! INT.AP.CNT.REG);
PLANT.BY((IF OPD.SIZE =< 4 THEN
1 ELSE 2));
PLANT.BY(SP.MINUS);
FI
@BOX 7.1
::END 27.1.4.1
@BOX 8.1
GET.TEMP.REG(2) => J;
PLANT.BY(MOVQ);
PLANT.OPD(^OPD.VEC,OVP);
PLANT.BY(REGM!J);
PLANT.BY(CMPL);
PLANT.BY(REGM!AREG);
PLANT.BY(REGM!J);
PLANT.BY(BNEQ);
PLANT.BY(3);
PLANT.BY(CMPL);
PLANT.BY(REGM!AREG+1);
PLANT.BY(REGM!J+1);
@BOX 9.1
IF GENA.KIND & %2 = 0
@BOX 10.1
IF GEN.LAST.FN = 15
AND LAST.TEST = 0 THEN
PLANT.BY(MOVZWL);
PLANT.BY(REGM);
PLANT.BY(REGM);
PLANT.BY(ADDL2);
PLANT.BY(REGM);
PLANT.BY(REGM!1) FI
PLANT.BY(SUBL2);
PLANT.LIT.OPD(4,GENA.SIZE);
PLANT.BY(REGM!1);
REG.DEFD ! 1 => GEN.OV[0];
PART(^GEN.OV,0,0) => GENA.OPD;
@BOX 11.1
(IF FN = 15 THEN
CMPC3 ELSE MOVC3) => I;
@BOX 12.1
PLANT.BY(I);
PLANT.LIT.OPD(2,GENA.SIZE);
PLANT.OPD(GENA.OPD,SIZE(GENA.OPD)-1);
PLANT.OPD(^OPD.VEC,OVP);
@BOX 13.1
IF TEMP.REGS /= 0 THEN
REL.TEMP.REGS(TEMP.REGS) FI
RESERVE.REGS(0,2);
@BOX 14.1
3 => GENA.KIND;
FN => GEN.LAST.FN;
@BOX 15.1
TEMP.REGS => I;
REL.TEMP.REGS(GEN.TEMP.REGS);
I => TEMP.REGS;
@END
@TITLE MTL27.1.5(3,10)
@COL 1S-3T-2T-5T-15T-7R-8R-9R-10T-11R-12F
@COL 14R-16R-17R
@ROW 5-14
@ROW 7-16
@ROW 11-17
@FLOW 1-3N-2N-5N-15N-7-8-9-10N-11-12
@FLOW 3Y-12
@FLOW 2Y-14-12
@FLOW 5Y-9
@FLOW 15Y-16-12
@FLOW 10Y-17-12
@BOX 1.0
PROCESS ORG
FUNCTIONS
@BOX 2.0
IS IT ACONV
OR ENTER?
@BOX 3.0
B CONV?
@BOX 5.0
IS IT SEG-> ?
@BOX15.0
LABEL OPERAND?
@BOX 7.0
NOTE ADDRESS IN
CODE SEGMENT
@BOX 8.0
PLANT (INVERSE)
TEST JUMP ENSURING
BYTE DISPLACEMENT
@BOX 9.0
PROCESS JUMP
TO VARIABLE
@BOX 10.0
IS IT SEG-> ?
@BOX 11.0
FILL IN CORRECT
DISPLACEMENT IN
INVERSE TEST JUMP
I.E. TO THIS ADDRESS
@BOX 12.0
END
@BOX 14.0
PROCESS
ACONV OR ENTER
[MTL27.1.5.1]
@BOX16.0
PLANT CONDITIONAL
JUMP TO LABEL
@BOX17.0
FILL IN AOB
INSTRUCION
IF PLANTED
@BOX 1.1
::PROCESS
::ORG FUNCTIONS
@BOX 2.1
IF FN >= 7
@BOX 3.1
IF FN = 10
@BOX 5.1
IF FN = 6
@BOX15.1
IF OPD.KIND = 4
@BOX 7.1
STORE.I OF CODE.SEG.P^ => OFFSET
+ STORE.R.ADDR OF CODE.SEG.P^
=> ADDRESS;
@BOX 8.1
PLANT.REF(FN-=%1,ADDRESS);
@BOX 9.1
GET.OPD(DONT.INDX,OPC,OPD.KIND,OPD.DESC.P);
IF OPD.SIZE /= 4 THEN
PLANT.BY(MOVQ);
PLANT.OPD(^OPD.VEC,OVP);
PLANT.BY(REGM);
PLANT.BY(CMPL);
PLANT.BY(REGM ! 1);
PLANT.BY(REGM ! FP);
PLANT.BY(BEQL);
PLANT.BY(9);
STORE.I OF CODE.SEG.P^
+ STORE.R.ADDR
OF CODE.SEG.P^ - 5 => ADDRESS;
PLANT.BY(MOVL);
PLANT.LIT.OPD(4,ADDRESS);
PLANT.BY(DISP.B ! FP);
PLANT.BY(16);
PLANT.BY(RET);
PLANT.BY(JMP);
PLANT.BY(REG.DEFD);
ELSE
IF OPD.KIND = 4 THEN
GO.TO(LAB OF OPD.DESC.P^);
ELSE
IF OPD.VEC[0] = ABSOLUTE THEN
PLANT.BY(CLRL);
GET.TEMP.REG(1) => I ! DISP.DEFD.L => OPD.VEC[0];
PLANT.BY(REGM ! I)
ELSE
::MAKE IT ADDRESS DEFERRED
%10 !> OPD.VEC[0] FI
PLANT.BY(JMP);
PLANT.OPD(^OPD.VEC,OVP) FI FI
@BOX 10.1
IF FN = 6
@BOX 11.1
STORE.I OF CODE.SEG.P^
- OFFSET -2 => ADDRESS;
REPLANT(1,ADDRESS,CODE.SEG.P,OFFSET+1);
@BOX 12.1
::END 27.1.5
@BOX 14.1
#MTL27.1.5.1
@BOX16.1
COND.GOTO(FN,LAB OF OPD.DESC.P^);
@BOX17.1
IF OPC & %8000 /= 0 THEN
STORE.I OF CODE.SEG.P^ - AOBP - 1 => I;
REPLANT(1,I,CODE.SEG.P,AOBP) FI
@END
@TITLE MTL27.1.5.1(3,11)
@COL 1S-2T-3R
@COL 9T-4R-5T-6R-7F
@COL 11T-10R-12R-8R
@ROW 3-9
@ROW 4-11
@ROW 6-8
@FLOW 1-2N-3-7
@FLOW 2Y-9N-4-5N-6-7
@FLOW 9Y-11N(ADDR=)-10-7
@FLOW 5Y-8-7
@FLOW 11Y-12-7
@BOX 1.0
PROCESS
ACONV OR ENTER
@BOX 2.0
IS IT ENTER
ADDR= OR STK NIL
@BOX 3.0
CONVERT A REGISTER
TO GIVEN MODE
@BOX 4.0
PROCESS OPERAND
@BOX 5.0
INTERPRETIVE
LIB CALL?
@BOX 6.0
PROCESS ENTER
VIA VARIABLE
@BOX 7.0
END
@BOX 8.0
PROCESS INTERPRETIVE
LIB PROC CALL
@BOX 9.0
IS IT ADDR =
OR STK NIL
@BOX11.0
IS IT STK NIL ?
@BOX 10.0
LOAD BASE REGISTER
@BOX12.0
PLANT CODE TO
SUBTRACT FROM SP
FOR OMITTED PARAMETERS
ADJUSTING LONGWORD
COUNT IN CALL STACK
@BOX 1.1
::PROCESS
::ACONV OR ENTER
@BOX 2.1
IF FN >= 8
@BOX 3.1
CONVERT(1,A.TYPE,
A.TYPE OF OPD.DESC.P^ => I,
A.REG);
I & %3F => A.TYPE;
0 => GEN.A.KIND;
@BOX 4.1
GET.OPD(DONT.INDX,OPC,OPD.KIND,OPD.DESC.P);
@BOX 5.1
IF CALL.I < 0
@BOX 6.1
IF  1 <<- OPDK & %24 = 0 THEN
FAULT(0,%"MTL27.1.5.1");
ELSE
SELECT CALL.S[CALL.I];
IF CALL.K & %18 = %10 THEN
PLANT.BY(MOVQ);
PLANT.OPD(^OPD.VEC,OVP);
PLANT.BY(REGM ! AREG);
PLANT.BY(ASHL);
PLANT.LIT.OPD(1,%F1);
PLANT.BY(REGM ! AREG + 1);
PLANT.BY(REGM ! XNB1);
PLANT.BY(MOVZWL);
PLANT.BY(REGM ! AREG + 1);
PLANT.BY(REGM ! AP);
PLANT.BY(CALLSI);
PLANT.LIT.OPD(4,STK.CNT OF LLCALL);
PLANT.BY(%80 ! AREG);
PLANT.BY(MOVL);
PLANT.BY(SP.PLUS);
PLANT.BY(REGM ! XNB1);
ELSE
IF OPD.VEC[0] = ABSOLUTE THEN
PLANT.BY(CLRL);
GET.TEMP.REG(1) => I ! DISP.DEFD.L => OPD.VEC[0];
PLANT.BY(REGM ! I);
ELSE
::MAKE IT ADDRESS DEFERRED
IF OPD.VEC[0] & %F0 = %60 THEN
%E0 -=> OPD.VEC[0]
ELSE
%10 !> OPD.VEC[0] FI FI
PLANT.BY(CALLSI);
PLANT.LIT.OPD(4,STK.CNT OF LLCALL);
PLANT.OPD(^OPD.VEC,OVP);
FI
IF CALL.K & %2 /= 0 THEN
SET.RESULT.REG(SIZ OF RES,MOD OF RES) FI
IF SP.DISP OF LLCALL => SP.DISP & %3 => I /= 0 THEN
PLANT.BY(ADDL2);
PLANT.BY(4-I);
PLANT.BY(REGM ! SP) FI
FI
@BOX 7.1
::END
@BOX 8.1
PLANT.BY(MOVL);
PLANT.BY(SP.PLUS);
PLANT.BY(REGM); ::R0
PLANT.BY(BICL2);
PLANT.LIT.OPD(4,%FF00);
PLANT.BY(REGM ! AREG => I);
PLANT.BY(BLSS);
PLANT.BY(11);
PLANT.BY(MULW2);
PLANT.BY(8);
PLANT.BY(I);
PLANT.BY(SUBL2);
PLANT.BY(4);
PLANT.BY(I);
PLANT.BY(CALLSI);
PLANT.BY(REGM); ::R0
PLANT.BY(REG.DEFD ! AREG);
PLANT.BY(BRB);
PLANT.BY(4);
PLANT.BY(PUSHL);
PLANT.BY(REGM); ::R0
PLANT.BY(CHME);
PLANT.BY(I);
@BOX 9.1
;IF FN /= 8
@BOX11.1
IF FN >= 11
@BOX 10.1
PLANT.BY(MOVL);
AD.STORE OF OPD.DESC.P^ => ST.P;
PLANT.LIT.OPD(4,STORE.R.ADDR OF ST.P^);
PLANT.BY(OP.C ->> 13 + 9 ! REG.M);
@BOX12.1
MFN OF OPD.DESC.P^ <<- 1 => I;
I +> STK.CNT OF LL.CALL OF CALL.S[CALL.I];
PLANT.BY(SUBL2);
PLANT.LIT.OPD(4,I <<- 2);
PLANT.BY(REGM ! SP);
@END
@TITLE MTL27.1.6(3,8)
@COL 9C
@COL 1S-2T-3T-4T-5T-6T-7R-8F
@COL 10C-11R
@ROW 5-10
@ROW 9-7-11
@FLOW 1-2N-3Y-4Y-5Y-6N-7-8
@FLOW 2Y-9-8
@FLOW 3N-9
@FLOW 4N-10
@FLOW 5N-11-8
@FLOW 6Y-11
@BOX1.0
ATTEMPT TO PLANT
2/3 ADDRESS INSTRUCTION
@BOX2.0
FIND NEXT FUNCTION
IN VECTOR.
NONE OR INTERVENING
ORG FUNCTION?
@BOX3.0
BOTH OPERANDS SIZE OF
ACC AND SAME MODE?
@BOX4.0
IS FIRST FUNCTION
A LOAD FUNCTION?
@BOX5.0
CAN SECOND FUNCTION
BE COMBINED WITH LOAD?
@BOX6.0
IS REGISTER REQUIRED
AFTER SECOND FUNCTION?
@BOX7.0
REDUCE TO SPECIAL CASE
OR 2 ADDRESS INSTRUCTION
[MTL27.1.6.1]
@BOX8.0
END
@BOX9.0
CANT.DO
@BOX10.0
NON.LOAD
[MTL27.1.6.2]
@BOX11.0
ATTEMPT SPECIAL CASE
OR 3 ADDRESS INSTRUCTION
[MTL27.1.6.2]
@BOX1.1
::ATTEMPT TO PLANT
::2/3 ADDRESS INST
@BOX2.1
IF REG = BREG@>>
IS.PTR => FN2.PTR;
OPC & %3FE0 => J & %60 => K;
WHILE 1 +> FN2.PTR < NIS DO
IF OP.CODE OF INST.SEQ^[FN2.PTR]
=> I & %60 => L /= K THEN
IF L = %60@>>
ELSE
IF I & %3FE0 /= J@>>
->FN2.GOT;
FI OD
FN2.GOT:
IF FN2.PTR >= NIS@>>
@BOX3.1
IF CHECK.OPD.MODE(Z,T,INST.SEQ,IS.PTR) /= 0
OR CHECK.OPD.MODE(Z,T,INST.SEQ,FN2.PTR) /= 0
@BOX4.1
I & %1F => FN2;
IF FN.BIT & LOAD.FN = 0
@BOX5.1
IF 1 <<- FN2 & OPT2FNBITS[COLN] = 0
@BOX6.1
IF REG.SPEC OF INST.SEQ^[FN2.PTR] & %2 = 0
@BOX7.1
#MTL27.1.6.1
@BOX8.1
::END 27.1.6
@BOX9.1
CANT.DO:
@BOX10.1
->NON.LOAD;
@BOX11.1
#MTL27.1.6.2
@END
@TITLE MTL27.1.6.1(3,9)
@COL 11C-12T-13T-14R-15R-16F-17N-18T-19T-20R-21R
@COL 1S-2T-3T-4T-5T-6R-7R-8N-9N-10C
@COL 22T-23T-24T-25R-26R-27T-29T-30T-31N-28R-32R
@ROW 3-22
@ROW 11-4
@ROW 17-9
@ROW 21-10
@FLOW 1-2N-3N-4Y-5Y-6-7-16
@FLOW 2Y-22N-23Y-24Y-25-8-15
@FLOW 3Y-11
@FLOW 4N-12Y-13Y-14-15-16
@FLOW 5N-17-18Y-19Y-20-21-16
@FLOW 12N-17
@FLOW 13N-17
@FLOW 18N-10
@FLOW 19N-10
@FLOW 22Y-27Y-29Y-30N-31-9
@FLOW 23N-9-17
@FLOW 24N-26-9
@FLOW 27N-9
@FLOW 29N-28-32-7
@FLOW 30Y-10
@BOX1.0
REDUCE TO SPECIAL CASE
OR 2 ADDRESS INSTRUCTION
@BOX2.0
SECOND FUNCTION '=>' ?
@BOX3.0
FIRST FUNCTION
LOAD NEGATIVE?
@BOX4.0
SECOND FUNCTION COMPARE?
@BOX5.0
SECOND OPERAND LITERAL
0 AND NO INTERVENING
FUNCTIONS?
@BOX6.0
SET INST CODE
FOR TST
@BOX7.0
SET UP FOR
TST/PUSHL
@BOX10.0
CANT.DO
@BOX11.0
CANT.DO
@BOX12.0
'+>' OR '-:>' ?
@BOX13.0
INTEGER/LOGICAL
=< 32 BITS AND
FIRST OPERAND
LITERAL 1 ?
@BOX14.0
SET INST CODE
FOR INC/DEC
@BOX15.0
SET UP FOR
INC/DEC/CLR
@BOX16.0
END
@BOX18.0
CHECK FIRST OPERAND.
IS IT OK?
@BOX19.0
CHECK SECOND OPERAND.
IS IT OK?
@BOX20.0
SET INST CODE
FOR FUNCTION
@BOX21.0
SET UP FOR
FUNCTION
@BOX22.0
SECOND OPERAND
PARAMETER STACK?
@BOX23.0
FIRST OPERAND
A LITERAL?
@BOX24.0
= 0 ?
@BOX25.0
SET INST CODE
FOR CLR
@BOX26.0
ADJUST FUNCTION
AND LITERAL FOR
SHORTEST CODE
(TRY TO USE SHORT
LITERAL FORM)
@BOX27.0
NOT INTERPRETIVE
AND SIZE =< 32 BITS?
@BOX28.0
SET INST CODE
FOR PUSHL
IF SIZE < 32 BITS
NOTE NOT TO USE
INDEXED FORM OR IF
LITERAL TO ENSURE
32 BIT OPERAND
ELSE NOTE NOT TO
USE SHORT FLOATING
LITERAL FORM
@BOX29.0
LOAD NEGATIVE?
@BOX30.0
SIZE < 32 BITS?
@BOX31.0
ADJUST LITERAL
@BOX32.0
INCREMENT LONGWORD
COUNT IN CALL STACK
@BOX1.1
::REDUCE TO SPECIAL
::CASE OR 2 ADDRESS
::INSTRUCTION
0 => OPD1.MODE
  => OPD3.MODE
  => TREGS23;
@BOX2.1
IF FN2 = 0
@BOX3.1
IF FN = 1
@BOX4.1
IF FN2 /= 15
@BOX5.1
IF OPD.KIND OF INST.SEQ^[FN2.PTR] /= 3
OR VAL OF LIT OF OPD
OF INST.SEQ^[FN2.PTR] /= %0
OR IS.PTR + 1 /= FN2.PTR
@BOX6.1
TSTL - IOFF => FN.CODE;
IF T =  0 THEN
2 -> FN.CODE FI
@BOX7.1
%C000 !> OPC;
%E000 !> OP.CODE
OF INST.SEQ^[FN2.PTR];
3 => OPD.ORDER;
@BOX10.1
->CANT.DO;
@BOX11.1
->CANT.DO;
@BOX12.1
IF FN2 /= 24 /= 26
@BOX13.1
IF Z > 2 OR T = 0
OR OPD.KIND /= 3
OR VAL OF LIT OF OPD.DESC.P^ /= %1
@BOX14.1
(IF FN2 = 24 THEN
INCL ELSE DECL)
 - IOFF => FN.CODE;
@BOX15.1
%E000 !> OPC;
%C000 !> OP.CODE OF INST.SEQ^[FN2.PTR];
3 => OPD.ORDER;
@BOX16.1
::END 27.1.6.1
@BOX18.1
IF CHECK.OPD(OPD.KIND,OPD.DESC.P,%20)
=> I < 0
OR I & %19 /= 0 AND IS.PTR + 1 /= FN2.PTR
@BOX19.1
IF CHECK.OPD(OPD.KIND OF INST.SEQ^[FN2.PTR],
^OPD OF INST.SEQ^[FN2.PTR],I & %119) < 0
@BOX20.1
IF FN2 >= 15 THEN
FN.CODES2[FN2 - 15] - IOFF => FN.CODE;
OPD.ORDERS2[FN2 - 15] => OPD.ORDER;
ELSE
IF FN = 2 THEN
MOVL - IOFF => FN.CODE;
IF T /= 0 AND Z = 3 THEN
MOVQ => FN.CODE FI
ELSE
MNEGL - IOFF => FN.CODE;
IF T = 0 THEN
4 +> FN.CODE FI
FI
%31 => OPD.ORDER;
FI
@BOX21.1
%8000 !> OPC;
%C000 !> OP.CODE OF INST.SEQ^[FN2.PTR];
@BOX22.1
IF OPD.KIND OF INST.SEQ^[FN2.PTR] = 7
@BOX23.1
IF OPD.KIND /= 3
@BOX24.1
IF VAL OF LIT OF OPD.DESC.P^ /= 0
@BOX25.1
CLRL - IOFF => FN.CODE;
IF Z = 3 THEN
CLRQ => FN.CODE
ELSE
IF T = 0 THEN
CLRL => FN.CODE
FI FI
@BOX26.1
IF T /= 0 AND Z < 3 THEN
VAL OF LIT OF OPD.DESC.P^ => I;
IF I < 0 AND I >= -63 THEN
0 - I => I;I => VAL OF LIT
OF OPD.DESC.P^;
3 - FN => FN;
FI FI
@BOX27.1
IF Z >= 3 OR CALL.I < 0
@BOX28.1
PUSHL => FN.CODE;
IF Z < 2 THEN
IF OPD.KIND = 3 THEN
4 => SIZ OF LIT.TYPE OF OPD.DESC.P^
ELSE DONTINDX => OPD3.MODE FI
ELSE NOTSHORT => OPD3.MODE FI
@BOX29.1
IF FN /= 1
@BOX30.1
IF Z < 2
@BOX32.1
(IF Z = 3 THEN 2 ELSE 1)
+> STK.CNT OF LL.CALL OF CALL.S[CALL.I];
@END
@TITLE MTL27.1.6.2(3,8)
@COL 16C
@COL 1S-2T-3T-4T-6T-7T-8T-9T-10T-11T-17T-13R-15F
@COL 19C-20T-21R-31T-22R-23T-32T-24T-25T-26R-27R-33T-34R-28T-29R-30C
@ROW 16-13
@ROW 6-31
@FLOW 1-2Y-3N-4Y-6Y-7N-8Y-9Y-10Y-11Y-17Y-13-15
@FLOW 2N-16
@FLOW 3Y-31N-22-8
@FLOW 4N-31
@FLOW 6N-23Y-32Y-24N-25Y-26-27-8
@FLOW 7Y-31
@FLOW 8N-16
@FLOW 9N-16
@FLOW 10N-28N-29-11
@FLOW 11N-13
@FLOW 17N-16
@FLOW 19-20Y-21-4
@FLOW 20N-30
@FLOW 31Y-30
@FLOW 23N-30
@FLOW 32N-33Y-34-8
@FLOW 33N-30
@FLOW 24Y-27
@FLOW 25N-30
@FLOW 28Y-30
@BOX1.0
ATTEMPT SPECIAL
CASE OR THREE
ADDRESS INSTRUCTION
@BOX2.0
NOT LOAD NEGATIVE AND
SECOND FUNCTION
SUITABLE?
@BOX3.0
FIND NEXT FUNCTION
IN VECTOR.
NONE OR INTERVENING
ORG FUNCTION?
@BOX4.0
OPERAND SIZE OF
ACC AND SAME MODE
AND REGISTER NOT REQUIRED
AFTER THIRD FUNCTION?
@BOX6.0
THIRD FUNCTION '=>' AND
SECOND FUNCTION NOT '+>'?
@BOX7.0
THIRD OPERAND ACTUAL
PARAMETER AND WRONG
MODE OR SIZE?
@BOX8.0
CHECK FIRST OPERAND.
IS IT OK?
@BOX9.0
CHECK SECOND OPERAND.
IS IT OK?
@BOX10.0
CHECK THIRD OPERAND.
IS IT OK?
@BOX11.0
IS SECOND FUNCTION '&' OR
EQUIVALENCE AND NOT 'BIT' CASE?
@BOX13.0
SET INST CODE
FOR FUNCTION
SET UP FOR FUNCTION
@BOX15.0
END
@BOX16.0
CANT.DO
@BOX17.0
ADJUST OPERAND MODES
TO GIVE COMPLEMENTED
LITERAL.
POSSIBLE?
@BOX19.0
NON.LOAD
@BOX20.0
FUNCTION SUITABLE?
@BOX21.0
SET UP FOR 3 ADDRESS
WITH ACC AS FIRST OPERAND
@BOX31.0
FIRST OPERAND ACC
OR SECOND FUNCTION '+>'?
@BOX22.0
SET UP FOR 3 ADDRESS
WITH ACC AS THIRD OPERAND
@BOX23.0
THIRD FUNCTION COMPARE?
@BOX32.0
SECOND FUNCTION '&'?
@BOX24.0
THIRD OPERAND
LITERAL ZERO?
@BOX25.0
CAN 'BIT' BE USED?
@BOX26.0
ADJUST VECTOR ETC
@BOX27.0
SET UP TO USE 'BIT'
@BOX33.0
SECOND FUNCTION '+>' AND
POSSIBLE TO USE 'AOB'?
@BOX34.0
SET UP FOR 'AOB'
@BOX28.0
FIRST OPERAND ACC
OR SECOND FUNCTION '+>'?
@BOX29.0
SET UP FOR 3 ADDRESS
WITH ACC AS THIRD OPERAND
@BOX30.0
CANT.DO
@BOX1.1
::ATTEMPT SPECIAL CASE
::OR 3 ADDRESS
::INSTRUCTION
0 => M;
@BOX2.1
IF FN = 1 OR 1 <<- FN2 & OPT3FNBITS[COLN] = 0
@BOX3.1
FN2.PTR => FN3.PTR;
WHILE 1 +> FN3.PTR < NIS DO
IF OP.CODE OF INST.SEQ^[FN3.PTR]
=> I & %60 => L /= K THEN
IF L = %60@>>
ELSE IF I & %1FE0 /= J@>>
->FN3.GOT FI OD
FN3.GOT: IF FN3.PTR >= NIS@>>
@BOX4.1
IF CHECK.OPD.MODE(Z,T,INST.SEQ,FN3.PTR) /= 0
OR REG.SPEC OF INST.SEQ^[FN3.PTR] & %2 = 0
@BOX6.1
IF I & %1F => FN3 /= 0 OR FN2 = 24
@BOX7.1
IF OPD.KIND OF INST.SEQ^[FN3.PTR] = 7
AND T /= 0 AND Z < 2
@BOX8.1
0 => I => OPD1.MODE => OPD2.MODE
  => OPD3.MODE => TREGS23;
IF M /= 1 AND
[CHECK.OPD(OPD.KIND,OPD.DESC.P,%20) => I < 0
OR I & %19 /= 0 AND [IS.PTR + 1 /= FN2.PTR
OR M /= 2 AND FN2.PTR + 1 /= FN3.PTR]]
@BOX9.1
I & %119 => J;
IF M /= 2 THEN %20 !> J FI
IF CHECK.OPD(OPD.KIND OF INST.SEQ^[FN2.PTR],
^OPD OF INST.SEQ^[FN2.PTR],J) => J < 0
OR J & %19 /= 0 AND M /= 2
AND FN2.PTR + 1 /= FN3.PTR
@BOX10.1
I ! J & %119 => K;
IF M /= 2 AND
CHECK.OPD(OPD.KIND OF INST.SEQ^[FN3.PTR],
^OPD OF INST.SEQ^[FN3.PTR],K) => K < 0
@BOX11.1
IF FN2 /= 4 AND FN2 /= 14
@BOX13.1
FN.CODES3[FN2] - IOFF => FN.CODE;
OPD.ORDERS3[M * 17 + FN2] => OPD.ORDER;
IF M /= 2 THEN
%C000 !> OP.CODE OF INST.SEQ^[FN3.PTR];
ELSE
%C000 !> OP.CODE OF INST.SEQ^[FN2.PTR];
FI
IF M = 0 THEN
%8000 !> OPC;
%A000 !> OP.CODE OF INST.SEQ^[FN2.PTR];
ELSE
%A000 !> OPC;
FI
@BOX15.1
::END 27.1.6.2
@BOX16.1
->CANT.DO;
@BOX17.1
IF M /= 1 THEN
IF OPD.KIND = 3 THEN
IF M = 0 THEN COMP.LIT !> OPD1.MODE;
ELSE COMPLIT !> OPD2.MODE FI
->AND.OK FI FI
IF OPD.KIND OF INST.SEQ^[FN2.PTR] = 3 THEN
IF M /= 2 THEN COMPLIT !> OPD2.MODE;
ELSE COMPLIT !> OPD3.MODE FI
IF FN2 = 4 THEN
2 => FN2 FI FI
AND.OK:
IF OPD1.MODE ! OPD2.MODE ! OPD3.MODE
& COMPLIT = 0
@BOX19.1
NON.LOAD:
@BOX20.1
IF FN.BIT & OPT3FNBITS[COLN] = 0
OR FN = 24
@BOX21.1
1 => M;
FN2.PTR => FN3.PTR;
IS.PTR => FN2.PTR;
FN2 => I;
FN => FN2;
@BOX31.1
IF M = 1 OR FN2 = 24
@BOX22.1
2 => M;
@BOX23.1
IF FN3 /= 15
@BOX32.1
IF FN2 /= 4
@BOX24.1
IF OPD.KIND OF INST.SEQ^[FN3.PTR] = 3
AND VAL OF LIT OF OPD
OF INST.SEQ^[FN3.PTR] = 0
@BOX25.1
::NOT YET
IF 1=1
@BOX26.1
::NOT YET
@BOX27.1
0 => FN2;
@BOX 33.1
IF FN2 /= 24 OR OPD.KIND /= 3
OR VAL OF LIT OF OPD.DESC.P^ /= %1
OR FN3.PTR + 1 >= NIS
OR OP.CODE OF INST.SEQ^[FN3.PTR + 1]
=> I /= %62 AND I /= %65
@BOX34.1
I & %1 +15 => FN2;
@BOX28.1
IF M = 1 OR FN2 >= 15
@BOX29.1
2 => M;
IF FN2 = 0 THEN
4 => FN2 FI
@BOX30.1
->CANT.DO;
@END
@TITLE MTL27.1.7(3,8)
@COL 1S
@BOX 1.0
DATAVECS FOR
DRIVING CODE
GENERATION
@BOX 1.1
$DA OPT2FNBITS($LO32)
%3F008001 %3F800001
%3F288001 %3F288001 %3F288001 %1
%3F288001 %3F228001 %3F288001 %1
END
$DA FN.CODES2($LO8)
%D1 0 0 0 %CC %CA %C8 0 0
%C0 %C3 %C2 %C4 %C7 %C6 %CC
END
$DA OPD.ORDERS2($LO16)
%31 0 0 0 %31 %31 %31 0 0
%31 %313 %31 %31 %313 %31 %31
END
$DA OPT3FNBITS($LO32)
%3F00 %3F00
%7F38 %7F38 %1007F38 %0
%7F38 %7F38 %1007F38 %0
END
$DA FN.CODES3($LO8)
%D3 0 %CB %CD %CB %C9 0 0 ::0 IS BIT, 2 IS & WITH OPD2 LIT
%C1 %C3 %C3 %C5 %C7 %C7 %CD %F2 %F3 ::15 IS AOBLSS 16 IS AOBLEQ
END
$DA OPD.ORDERS3($LO16)
%21 0 %312 %321 %321 %321 0 0
%321 %312 %321 %321 %312 %321 %321 %523 %523
%24 0 %342 %324 0 %324 0 0
%324 %342 %324 %324 %342 %324 %324 0 0
0 0 %423 %432 %432 %432 0 0
%432 %423 %432 %432 %423 %432 %432 0 0
END
$DA MFN.PROCS($LO32)
?SQRT   ?SIN    ?COS    ?LN    ?EXP
?LOG    ?TAN    ?ASIN   ?ACOS   ?ATAN   ?ATAN2
?SINH   ?COSH   ?TANH   ?DSQRT  ?DSIN
?DCOS   ?DLN   ?DEXP   ?DLOG  ?DTAN    ?DASIN
?DACOS  ?DATAN  ?DATAN2 ?DSINH  ?DCOSH
?DTANH
?RPOWER   ?RDPOWER  ?IPOWER
?DRPOWER  ?DDPOWER  ?DIPOWER
0 0 ?POWER
END
$DA MFN.INDS($IN8)
  0   1   2   3   4   5   6   7   8   9  ::R32
 10  11  12  -1  -2  -3  -4  -5  -6  -7
 -8  -9 -10  13 -11 -12 -13 -14  14
 15  16  17  18  19  20  21  22  23  24  ::R64
 25  26  27 -15 -16 -17 -18 -19 -20 -21
-22 -23 -24  28 -25 -26 -27 -28  29
 30  31  32  33  34  35  36  37  38  39  ::I32
 40  41  42  43
END
$LI MFN.START = 192;
$LI BFN.START = 128;
DATAVEC IND.STARTS($LO8)
0 32
64 96 128 160
64 96 128 160
END
DATAVEC FN.OFFS($LO8)
%80 %60
%40 %20 0 0
%40 %20 0 0
END
@END
@TITLE MTL27.2(3,6)
@COL 1S-2F
@FLOW 1-2
@BOX 1.0
PROC.ENTRY(KIND,PROC.P)
@BOX 2.0
END
@BOX 1.1
PROC PROC.ENTRY(KIND,PROC.P);
@BOX 2.1
END;
@END
@TITLE MTL27.3(3,8)
@COL 1S-12R-13F
@FLOW 1-12-13
@BOX 1.0
PROC.EXIT(PROC.P)
@BOX 12.0
PLANT RETURN INSTRICTION
@BOX 13.0
END
@BOX 1.1
PROC PROC.EXIT(PROC.P);
@BOX 12.1
PLANT.BY(RET);
@BOX 13.1
END;
@END
@TITLE MTL27.4(3,6)
@COL 1S-3R-2T-5R-6F
@FLOW 1-3-2N-5-6
@FLOW 2Y-6
@BOX 1.0
PROG.ENTRY(MODE,DIRSIZE)
@BOX 2.0
MUSS COMPILE?
@BOX 3.0
CALCULATE AND PLANT
ADDRESS OF FIRST
INSTRUCTION
IF LIBRARY ALLOCATE SPACE
FOR DIRECTORY
@BOX 5.0
PLANT
XNB0 = FP
PLANT (INCOMPLETE)
SP - INSTRUCTION FOR
FRAME ALLOCATION AND
NOTE ADDRESS
@BOX 6.0
END
@BOX 1.1
PROC PROG.ENTRY(MODE,DIRSIZE);
   $LO32 L;
@BOX 2.1
IF MODE & %2 /= 0
@BOX 3.1
IF MODE & 4 /= 0 THEN
PLANT.BY(BRW);
DIR.SIZE * 8 + 1 => L;
PLANT.BY(L & %FF);
PLANT.BY(L ->> 8);
PLANT.BY(0);
DIR.SIZE * 8 +> STORE.I OF CODE.SEG.P^ FI
@BOX 5.1
PLANT.BY(MOVL);
PLANT.BY(REGM!FP);
PLANT.BY(REGM!XNB0);
PLANTBY(SUBL2);
CODE.SEG.P => SP.SEG.P;
STORE.I OF CODE.SEG.P^ + 1 => SP.MIN.INST;
PLANT.LIT.OPD(4,%F0(7));
PLANT.BY(REGM!SP);
@BOX 6.1
END;
@END
@TITLE MTL27.5(3,9)
@COL 1S-2T-3R-4R-6R-5F
@FLOW 1-2N-3-4-6-5
@FLOW 2Y-5
@BOX 1.0
PROG.EXIT(MODE)
@BOX 2.0
MUSS COMPILE?
@BOX 3.0
FILL IN FRAME
ALLOCATION INSTRUCTION
@BOX 4.0
PLANT RETURN
INSTRUCTION
@BOX 5.0
END
@BOX 6.0
SET CURRENT PROGRAM ENTRY ADDRESS
@BOX 1.1
PROC PROG.EXIT(MODE);
$LO32 STKZ;
@BOX 2.1
IF MODE & 2 /= 0
@BOX 3.1
STORE.I OF TX.FRAME[1]
OF TX.S[0] + 3 & %F(7)C => STKZ;
REPLANT(4,STKZ,SP.SEG.P,SP.MIN.INST);
@BOX 4.1
PLANT.BY(RET);
PLANT.BY(RET); ::REDUNDANT INSTR
::BECAUSE VAX PREFETCHES NEXT OPCODE
@BOX 5.1
END;
@BOX 6.1
CUR.PROG(STORE.R.ADDR OF SP.SEG.P^ ->> 16);
@END
@TITLE MTL27.6(3,8)
@COL 1S-2T-3R-4F
@FLOW 1-2Y-3-4
@FLOW 2N-4
@BOX 1.0
PR.VAR.REFS(VAR.P,SEG.P,POSN)
@BOX 2.0
VARIABLE REFERENCES?
@BOX 3.0
FILL IN REFERENCES TO
VARIABLE
@BOX 4.0
END
@BOX 1.1
PROC PR.VAR.REFS(VAR.P,SEG.P,POS);
$LO32 L;
@BOX 2.1
IF VAR.F OF VAR.P^ & VAR.REFD = 0
@BOX 3.1
STORE.R.ADDR OF SEG.P^
+ POS => L;
VAR.DIM OF VAR.P^ => UNDEF.VAR.DIM;
FILL.IN.REFS(VAR.REFS OF VAR.UNDEF OF VAR.ADDR
OF VAR.P^,L);
@BOX 4.1
END;
@END
@TITLE MTL27.7(3,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ASS.LIT.64(VAL,SIZE,SEG.P,POS)
@BOX 2.0
PLANT LITERAL IN
STORE AT
SPECIFIED POSITION
@BOX 3.0
END
@BOX 1.1
PROC ASS.LIT.64(VAL,SIZ,SEG.P,POS);
@BOX 2.1
REPLANT(SIZ,VAL,SEG.P,POS);
@BOX 3.1
END;
@END
@TITLE MTL27.8(3,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ASS.LIT.128(VAL1,VAL2,SIZE,SEG.P,POS)
@BOX 2.0
PLANT TWO HALFS
OF LITERAL IN STORE
AT REQUIRED POSITION
@BOX 3.0
END
@BOX 1.1
PROC ASS.LIT.128(VAL1,VAL2,SIZ,SEG.P,POS);
@BOX 2.1
REPLANT(8,VAL2,SEG.P,POS);
REPLANT(8,VAL1,SEG.P,POS+8);
@BOX 3.1
END;
@END
@TITLE MTL27.9(3,9)
@COL 1S-2F
@FLOW 1-2
@BOX 1.0
RANGE
@BOX 2.0
END
@BOX 1.1
PROC RANGE(P1,P2,P3,P4,P5);
@BOX 2.1
END;
@END
@TITLE MTL27.10(3,8)
@COL 1S-2R-3T-4R-5R-6F
@COL 7R
@ROW 4-7
@FLOW 1-2-3Y-4-5-6
@FLOW 3N-7-6
@BOX 1.0
ASS.REF.VAR(VAR.P,SEG.P,POSN)
@BOX 2.0
NOTE IF
VECTOR
@BOX 3.0
VARIABLE
DEFINED?
@BOX 4.0
PLANT ADDRESS
OF VARIABLE
@BOX 5.0
PLANT DIMENSION
OF VARIABLE
IF A VECTOR
@BOX 6.0
END
@BOX 7.0
PLANT UNFILLED REFERENCE
ADDRESS OF VARIABLE
@BOX 7.0
FAULT
@BOX 1.1
PROC ASS.REF.VAR(VAR.P,SEG.P,POS);
$IN VEC,I;
$LO32 L,DIM;
@BOX 2.1
(IF VAR.DIM OF VAR.P^ => DIM = 0
THEN 0 ELSE 1) => VEC;
@BOX 3.1
IF VAR.F OF VAR.P^ => I & VAR.DEFD = 0
@BOX 4.1
STORE.R.ADDR
OF VAR.STORE.P^ OF VAR.ADDR OF VAR.P^
+ VAR.OFF OF VAR.ADDR OF VAR.P^ => L;
REPLANT(4,L,SEG.P,POS);
@BOX 5.1
IF VEC /= 0 THEN
REPLANT(4,DIM,SEG.P,POS+4) FI
@BOX 6.1
END;
@BOX 7.1
ADD.REF(VAR.ADDR.REF.VEC,^VAR.REFS
OF VAR.UNDEF OF VAR.ADDR OF VAR.P^,
SEG.P,POS,I & VAR.REFD);
@BOX 7.1
FAULT(0,%"FREF VAR 27.10");
@END
@TITLE MTL27.11(3,6)
@COL 1S-2R-3R
@FLOW 1-2-3
@BOX 1.0
REL.TEMP.REGS(TEMP.REGS);
@BOX 2.0
RELEASE REGISTERS
INDICATED BY BITS
SET IN TEMP REGS
@BOX 3.0
END
@BOX 1.1
PROC REL.TEMP.REGS(REGS);
$IN I,J
@BOX 2.1
FOR I < 12 DO
IF REGS = 0, -> OUT
IF 1 <<- I & REGS => J /= 0 THEN
RELEASE.REGS(I,1);
J -> REGS FI OD
@BOX 3.1
OUT:
0 => TEMP.REGS;
END
@END
@TITLE MTL27.12(3,6)
@COL 11T-12R-13R-14F
@COL 1S-2R-3T-4R-5T-6R-7T-8R-9R-10R
@ROW 11-4
@FLOW 1-2-3N-4-5N-6-7Y-8-13
@FLOW 3Y-11Y-12-13-14
@FLOW 5Y-13
@FLOW 7N-9-10-13
@FLOW 11N-4
@BOX 1.0
DISP.ADDR(KIND,REG,DISP)
@BOX 2.0
NOTE OPERAND
VEC POINTER
AND INCREMENT IT
@BOX 3.0
DISPLACEMENT = 0?
@BOX 4.0
PUT BOTTOM BYTE OF
DISPLACEMENT IN NEXT
BYTE OF OPERAND VEC
INCREMENT OPERAND
VEC POINTER
@BOX 5.0
WILL DISPLACEMENT
FIT IN A BYTE?
@BOX 6.0
PUT NEXT BYTE OF
DISPLACEMENT IN NEXT
BYTE OF OPERAND VEC
INCREMENT OPERAND
VEC POINTER
@BOX 7.0
WILL DISPLACEMENT
FIT IN 16 BITS
@BOX 8.0
ALTER KIND FOR
WORD DISPLACEMENT
@BOX 9.0
MOVE TOP 2 BYTES OF
DISPLACEMENT TO NEXT
2 BYTES OF OPERAND VEC
ADD 2 TO OPERAND
VEC POINTER
@BOX 10.0
ALTER KIND FOR
LONGWORD DISPLACEMENT
@BOX 11.0
DISPLACEMENT ADDRESSING
AND REG /= PC?
@BOX 12.0
CHANGE KIND TO
REGISTER DEFERRED
@BOX 13.0
PUT KIND/REG (ADDRESSING MODE)
IN OPERAND VEC AT NOTED POINT
@BOX 14.0
END
@BOX 1.1
PROC DISP.ADDR(KIND,REG,DISP);
$IN OP;
$IN32 I;
@BOX 2.1
1 +> OVP => OP;
@BOX 3.1
IF DISP = 0
@BOX 4.1
DISP & %FF => OPD.VEC[1+>OVP];
@BOX 5.1
IF DISP & %F(6)80 => I = 0
OR I = %F(6)80
@BOX 6.1
DISP ->> 8 & %FF => OPD.VEC[1+>OVP];
@BOX 7.1
IF DISP & %F(4)8000 => I /= 0
AND I /= %F(4)8000
@BOX 8.1
IF KIND /= REL.DEFD.L THEN
%20 +> KIND FI
@BOX 9.1
DISP ->> 16 & %FF => OPD.VEC[1+>OVP];
DISP ->> 24 => OPD.VEC[1+>OVP];
@BOX 10.1
IF KIND /= REL.DEFD.L THEN
%40 +> KIND FI
@BOX 11.1
IF REG = PC
OR KIND /= DISP.B
@BOX 12.1
REG.DEFD => KIND;
@BOX 13.1
KIND ! REG => OPD.VEC[OP];
@BOX 14.1
END
@END
@TITLE MTL27.13(3,6)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
ABS.ADDR(ADDR)
@BOX 2.0
SET ABSOLUTE
ADDRESSING MODE
IN OPERAND VEC
INCREMENT OPERAND
VEC POINTER
@BOX 3.0
PUT ADDR IN NEXT
4 BYTES OF OPERAND
VEC IN APPROPRIATE ORDER
INCREMENTING OPERAND
VEC POINTER
@BOX 4.0
END
@BOX 1.1
PROC ABS.ADDR(ADDRESS);
$IN I;
@BOX 2.1
ABSOLUTE => OPD.VEC[1 +> OVP];
@BOX 3.1
-8 => I
WHILE 8 +> I /= 32 DO
ADDRESS ->> I & %FF => OPD.VEC[1+>OVP]
OD
@BOX 4.1
END
@END
@TITLE MTL27.14(3,7)
@COL 13R-16C-17R
@COL 1S-2R-3R-4T-15C-5T-6R-7R-8T-9R-10R-11R-12T-18F
@COL 14R
@ROW 15-14
@ROW 13-9
@FLOW 1-2-3-4N-15-5N-6-7-8N-9-10-11-12N-18
@FLOW 4Y-14-12
@FLOW 5Y-7
@FLOW 8Y-13-10
@FLOW 16-17-18
@FLOW 12Y-17
@BOX 1.0
CONVERT
(KIND,OLD.MODE,NEW.MODE,DEST.REG)
@BOX 2.0
INCLUDE DATAVECS
FOR CONVERSIONS
[MTL27.14.1]
@BOX 3.0
CALCULATE INDEX IN
CONVERSIONS TABLE
GET CONVERSION CODE
@BOX 4.0
SPECIAL CASE?
@BOX 15.0
TRUN
CONV
@BOX 5.0
DEST.REG SET?
@BOX 6.0
GET TEMPORARY
REGISTER(S)
FOR DEST.REG
@BOX 7.0
PLANT CONVERSION
INSTRUCTION
@BOX 8.0
A REGISTER
CONVERSION?
@BOX 9.0
PLANT OPERAND
@BOX 10.0
PLANT OPERAND
FOR DEST.REG
@BOX 11.0
SET RESULT
TO DEST.REG
@BOX 12.0
A REGISTER
CONVERSION?
@BOX 18.0
END
@BOX 13.0
PLANT OPERAND
FOR A/B REGISTER
@BOX 16.0
ADJUST
A REG
@BOX 17.0
IF INCREASING OR
DECREASING SIZE
OF A REGISTER
ADJUST REGISTERS
IN USE INFORMATION
@BOX 14.0
PROCESS
SPECIAL CASES
[MTL27.14.2
@BOX 1.1
PROC CONVERT(KIND,OLD.MODE,NEW.MODE,DEST.REG);
$IN I,CC,NEW.SIZ,OLD.SIZ;
@BOX 2.1
#MTL27.14.1
@BOX 3.1
NEW.MODE ->> 3 & %7 => NEW.SIZ + COL[NEW.MODE & %7] * 12
+ (OLD.MODE ->> 3 => OLD.SIZ + COL[OLD.MODE & %7]) => I;
IF NEW.MODE < %40 THEN
CONVS[I] => CC;
ELSE
0 => I;
OLD.MODE <<- 8 ! NEW.MODE => CC;
LOOP:
IF SPEC.MODES[I] = CC THEN
SPEC.CONVS[I] => CC;
->FOUND FI
IF 1 +> I < NO.SPEC.CONVS,->LOOP;
0 => CC;
FOUND:
FI
@BOX 4.1
IF CC < %30
@BOX 15.1
TRUN.CONV:
@BOX 5.1
IF DEST.REG >= 0
@BOX 6.1
GET.TEMP.REG((IF NEW.SIZ >= 3 THEN 2 ELSE 1))
=> DEST.REG;
@BOX 7.1
PLANT.BY(CC);
@BOX 8.1
IF KIND & %1 /= 0
@BOX 9.1
PLANT.OPD(^OPD.VEC,OVP);
@BOX 10.1
PLANT.BY(REGM ! DEST.REG);
@BOX 11.1
DEST.REG => CONVERT;
@BOX 12.1
IF KIND = 1
@BOX 18.1
END
@BOX 13.1
PLANT.BY((IF KIND = 3 THEN B.REG
   ELSE A.REG) ! REG.M);
@BOX 16.1
ADJUST.AREG:
@BOX 17.1
IF NEW.SIZ >= 3 THEN
IF OLD.SIZ < 3 THEN
RESERVE.REGS(AREG + 1,1) FI
ELSE
IF OLD.SIZ >= 3 THEN
RELEASE.REGS(AREG + 1,1) FI
FI
@BOX 14.1
#MTL27.14.2
@END
@TITLE MTL27.14.1(3,11)
@COL 1S
@BOX 1.0
DATAVECS FOR
CONVERSIONS
@BOX 1.1
DATAVEC CONVS($LO8)
::COL FOR FROM
::ROW FOR TO
::R32 R64  I8  I16  I32 I64  L8  L16  L32  L64  PTR32 PTR64
  1  %76  %4C  %4D  %4E  0  %9A  %3C    1  %23    0   0  ::R32
%56    1  %6C  %6D  %6E  0    4    4    4    1    0   0  ::R64
%48  %68    1  %22  %21  0    1  %22  %21  %23    0   0  ::I8
%49  %69  %99    1  %20  0  %9B    1  %20  %23    0   0  ::I16
%4A  %6A  %98  %32    1  0  %9A  %3C    1  %23    1   2  ::I32
  0    0    0    0    0  0    0    0    0    1    0   0  ::I64
  0    0    1  %22  %21  0    1  %22  %21  %23    0   0  ::L8
  0    0  %99    1  %20  0  %9B    1  %20  %23    0   0  ::L16
  1    0  %98  %32    1  0  %9A  %3C    1  %23    0   0  ::L32
  4    1    4    4    4  1    4    4    4    1    4   1  ::L64
  0    0    0    0    1  0    0    0    0  %23    1   1  ::PTR32
  0    0    0    0    3  0    0    0    0    1    1   1  ::PTR64
END
DATAVEC TRUN.CONVS($LO8)
%F7 ::32 ->16
%F6 ::32 -> 8
%33 ::16 -> 8
%7D ::64 -> 832 MOVQ ASSUMES 64 BIT DEST REG
END
LITERAL NO.SPEC.CONVS = 7;
DATAVEC SPEC.MODES($LO16)
%0D51  :: PTR64 -> I32 (BOUND REQUIRED)
%1051  :: R32 -> I32 (ROUNDED)
%1851  :: R64 -> I32 (ROUNDED)
%1049  :: R32 -> I16 (ROUNDED) USES CVTRFL - NO CHECK
%1041  :: R32 -> I8 (ROUNDED) USES CVTRL - NO CHECK
%1849  :: R64 -> I16 (ROUNDED) USES CVTRL - NO CHECK
%1841  :: R64 -> I8 (ROUNDED) USES CVTRL - NO CHECK
END
DATAVEC SPEC.CONVS($LO8)
2
%4B
%6B
%4B
%4B
%6B
%6B
END
@END
@TITLE MTL27.14.2(3,10)
@COL 1S-8T-2R-3R-4R-5F-19R-20T-21R-22R-23R-24R
@COL 9T-6R-7R-12R-13R-14T-15R-16R
@COL 10R-11C-17R-18R
@ROW 2-9
@ROW 3-6-10
@FLOW 1-8N-2
@FLOW 8Y-9Y-6
@FLOW 3-4-7
@FLOW 19-20N-21-22-23-24-5
@FLOW 20Y-22
@FLOW 9N-10-11
@FLOW 6-7-5
@FLOW 12-13-14Y-15-16-5
@FLOW 14N-7
@FLOW 17-18-7
@BOX 1.0
PROCESS
SPECIAL CASES
@BOX 8.0
TRUNCATED
CONVERSION?
@BOX 2.0
SWITCH ON
CASE NUMBER
@BOX 3.0
CASE 0
@BOX 4.0
FAULT
NOT YET
IMPLEMENTED
@BOX 5.0
END
@BOX 19.0
CASE 4
L8/16/32 -> L64
I8/16/32 -> L64
R32 -> L64
@BOX 20.0
DEST.REG SET?
@BOX 21.0
GET TEMPORARY
REGISTERS FOR
DEST.REG
@BOX 22.0
IF L8/16 OR I8/16
PLANT CONVERSION
TO L32 OR I32
ELSE LOAD OPERAND
IF OPERAND CONVERSION
@BOX 23.0
IF FROM INTEGER
SIGN EXTEND INTO
ELSE CLEAR
TOP HALF OF DEST.REG
@BOX 24.0
SET RESULT
TO DEST.REG
@BOX 9.0
IS IT CONVERSION
OF A/B REGISTER?
@BOX 6.0
CASE 1
@BOX 7.0
SET RESULT AS
NO CONVERSION
REQUIRED
@BOX 12.0
CASE 2
PTR64 -> I32
@BOX 13.0
SET UP TO
RELEASE BOUND
REGISTER
@BOX 14.0
BOUND REQUIRED?
@BOX 15.0
PLANT CODE TO
COPY BOUND TO
A REGISTER
@BOX 16.0
SET RESULT TO
A REGISTER
@BOX 10.0
GET TEMPORARY REGISTER(S)
FOR DEST.REG IF NEEDED
GET TRUNCATED
CONVERSION CODE
@BOX 11.0
TRUN
CONV
@BOX 17.0
CASE 3
I32 -> PTR64
@BOX 18.0
SET UP TO
RESERVE REGISTER
FOR BOUND
@BOX 1.1
::PROCESS
::SPECIAL CASES
@BOX 8.1
IF CC >= %20
@BOX 2.1
SWITCH CC\
C0,C1,C2,C3,C4;
@BOX 3.1
C0:
@BOX 4.1
FAULT(0,%"CONV NOT IMPL$LO/N=");
OUTHEX(OLD.MODE,4);OUTHEX(NEW.MODE,4);NEWLINES(1);
@BOX 5.1
::END 27.14.2
@BOX 19.1
C4:
@BOX 20.1
IF DEST.REG >= 0
@BOX 21.1
GET.TEMP.REG(2)
=> DEST.REG;
@BOX 22.1
IF OLD.SIZ =< 1 THEN
CONVERT(KIND,OLD.MODE,OLD.MODE& %7 ! %10,DEST.REG)
ELSE
IF KIND = 0 THEN
PLANT.BY(MOVL);
PLANT.OPD(^OPD.VEC,OVP);
PLANT.BY(REGM ! DEST.REG) FI
FI
@BOX 23.1
IF OLD.MODE & %1 = 1 THEN
PLANT.BY(ASHL);
PLANT.LIT.OPD(1,%E1);
PLANT.BY(REGM ! DEST.REG)
ELSE
PLANT.BY(CLRL)
FI
PLANT.BY(REGM ! DEST.REG + 1);
@BOX 24.1
DEST.REG => CONVERT;
@BOX 9.1
IF KIND & %1 = 0
@BOX 6.1
C1:
@BOX 7.1
-1 => CONVERT;
@BOX 12.1
C2:
@BOX 13.1
3 => OLD.SIZ;
@BOX 14.1
IF NEW.MODE < %40
@BOX 15.1
PLANT.BY(MOVL);
PLANT.BY(REGM ! AREG + 1);
PLANT.BY(REGM ! AREG);
@BOX 16.1
AREG => CONVERT;
@BOX 10.1
IF DEST.REG < 0 THEN
GET.TEMP.REG((IF OLD.SIZ >= 3 THEN
2 ELSE 1)) => DEST.REG
FI
TRUN.CONVS[CC - %20]
=> CC;
@BOX 11.1
->TRUN.CONV;
@BOX 17.1
C3:
@BOX 18.1
3 => NEW.SIZ;
@END
@TITLE MTL27.15(3,11)
@COL 1S-3T-4R-5R-6F
@FLOW 1-3Y-4-5-6
@FLOW 3N-5
@BOX 1.0
PLANT.OPD(OPDV,N)
@BOX 3.0
SPECIAL CASE?
@BOX 4.0
PROCESS SPECIAL CASES
[MTL27.15.1]
@BOX 5.0
PLANT BYTES
IN OPERAND VECTOR
@BOX 6.0
END
@BOX 1.1
PROC PLANT.OPD(OPD.V,N);
$IN I;
$IN32 J,ADDRESS;
ADDR STORE.E SEG.P;
@BOX 3.1
IF OPDK < 16
@BOX 4.1
#MTL27.15.1
@BOX 5.1
FOR I < N + 1 DO
PLANT.BY(OPD.V^[I]) OD
@BOX 6.1
END;
@END
@TITLE MTL27.15.1(3,7)
@COL 1S-2R-3R-4R-5R-6R-7F-12R-13R-14R
@COL 8R-9R-10R-16R-17R
@ROW 4-8
@ROW 12-16
@FLOW 1-2-3
@FLOW 4-5-6-7
@FLOW 8-9-10-7
@FLOW 12-13-14-7
@FLOW 16-17-7
@BOX 1.0
PROCESS
SPECIAL
CASES
@BOX 2.0
INITIALISE
@BOX 3.0
SWITCH ON
OPERAND KIND
@BOX 4.0
UNDEFINED
PROCEDURE
@BOX 5.0
ADD REFERENCE FOR
ADDRESS OF PROC
@BOX 6.0
MARK PROC AS
REFERENCED
@BOX 7.0
END
@BOX 8.0
UNDEFINED
LABEL
@BOX 9.0
ADD REFERENCE FOR
ADDRESS OF LABEL
@BOX 10.0
MARK LABEL AS
REFERENCED
@BOX 12.0
UNDEFINED
VARIABLE
@BOX 13.0
ADD REFERENCE FOR
ADDRESS OF VARIABLE
@BOX 14.0
MARK VARIABLE AS
REFERENCED
@BOX 16.0
POSITION
DEPENDENT CODE
@BOX 17.0
CALCULATE REQUIRED
ADDRESS AND INSERT
IN OPERAND VECTOR
@BOX 1.1
::PROCESS
::SPECIAL
::CASES
@BOX 2.1
(IF OPD.V^[0] & %F0 = %40 THEN
2 ELSE 1 ) => I;
CODE.SEG.P => SEG.P;
STORE.I OF SEG.P^ => J;
@BOX 3.1
SWITCH OPDK - 16\
OK16,OK17,OK18,OK19;
@BOX 4.1
OK16:
@BOX 5.1
ADD.REF(PROC.ADDR.REF,PROC.REFS OF PADDR
OF PROC.ADDR OF ENTRY OF UNDEF.PROC.P^,SEG.P,I+J,
PROC.NAT OF UNDEF.PROC.P^ => I & PROC.REFD)
=> PROC.REFS OF PADDR OF PROC.ADDR OF ENTRY OF UNDEF.PROC.P^;
@BOX 6.1
I ! PROC.REFD => PROC.NAT OF UNDEF.PROC.P^;
@BOX 7.1
::END 27.15.1
@BOX 8.1
OK17:
@BOX 9.1
ADD.REF(LAB.ADDR.REF,LAB.REFS OF LAB.ADDR OF
UNDEF.LAB.P^,SEG.P,I+J,LAB.USE OF UNDEF.LAB.P^ =>  I & LAB.REFD)
=> LAB.REFS OF LAB.ADDR OF UNDEF.LAB.P^;
@BOX 10.1
I ! LAB.REFD => LAB.USE OF UNDEF.LAB.P^;
@BOX 12.1
OK18:
@BOX 13.1
ADD.REF(VAR.ADDR.REF,VAR.REFS OF VAR.UNDEF
OF VAR.ADDR OF UNDEF.VAR.P^,SEG.P,I+J,VAR.F OF UNDEF.VAR.P^
=> I & VAR.REFD) => VAR.REFS OF VAR.UNDEF
OF VAR.ADDR OF UNDEF.VAR.P^;
@BOX 14.1
I ! VAR.REFD => VAR.F OF UNDEF.VAR.P^;
@BOX 16.1
OK19:
@BOX 17.1
::THIS CODE MAY NEED TO RUN
::WITH OVERFLOW INHIBITED
STORE.R.ADDR OF SEG.P^
+ J + I + 4 => ADDRESS;
PDC.VAR.ADDR - ADDRESS => ADDRESS;
I - 1 => OVP;
FOR 4 DO
ADDRESS & %FF => OPD.VEC[1 +> OVP];
ADDRESS ->> 8 => ADDRESS OD
@END
@TITLE MTL27.16(3,8)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PLANT.BY(VAL)
@BOX 2.0
PLANT BYTE IN
CURRENT CODE AREA
AND INCREMENT
DISPLACEMENT
@BOX 3.0
END
@BOX 1.1
PROC PLANT.BY(VAL);
@BOX 2.1
VAL => SEG.PTR^[STORE.I OF CODE.SEG.P^]
OF STORE.ADDR OF CODE.SEG.P^;
   1 +> STORE.I OF CODE.SEG.P^;
@BOX 3.1
END;
@END
@TITLE MTL27.17(3,6)
@COL 1S-5T-2R-3R-4F
@COL 6R
@ROW 2-6
@FLOW 1-5N-2-3-4
@FLOW 5Y-6-4
@BOX 1.0
PLANT.LIT.OPD(SIZE,VAL)
@BOX 5.0
SHORT LITERAL
FORM POSSIBLE?
@BOX 2.0
PLANT IMMEDIATE
MODE OPERAND
SPECIFIER
@BOX 3.0
PLANT BYTES OF
LITERAL
@BOX 4.0
END
@BOX 6.0
PLANT SHORT
LITERAL OPERAND
@BOX 1.1
PROC PLANT.LIT.OPD(SIZ,VAL);
@BOX 5.1
IF VAL >= 0 AND VAL =< 63
@BOX 2.1
PLANT.BY(IMMED);
@BOX 3.1
FOR SIZ DO
PLANT.BY(VAL);
VAL ->> 8 => VAL;
OD
@BOX 4.1
END
@BOX 6.1
PLANT.BY(VAL);
@END
@TITLE MTL27.18(3,6)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
GET.TEMP.REG(NO);
@BOX 2.0
FIND REGISTER(S)
NOT IN USE
MARK AS IN USE
FAULT IF NONE
AVAILABLE
SET APPROPRIATE
BITS IN TEMP.REGS
@BOX 3.0
SET RESULT TO
REGISTER NUMBER
(OF FIRST IF MULTIPLE)
@BOX 4.0
END
@BOX 1.1
PROC GET.TEMP.REG(NO);
$IN I
@BOX 2.1
FOR I < 12 DO
IF STATUS OF REGS[I] = IN.USE, -> RPT;
IF NO = 1, -> FOUND
IF I = 11, -> FLT
IF STATUS OF REGS[I+1] = NOT.IN.USE, -> FOUND;
RPT: OD
FLT: CAPTION(%"NO TEMPORARY REGS");NEWLINES(1);->OUT;
FOUND:
1 <<- I !> TEMP.REGS;
IF NO > 1 THEN
2 <<- I !> TEMP.REGS FI
RESERVE.REGS(I,NO);
@BOX 3.1
I => GET.TEMP.REG;
@BOX 4.1
OUT:
END;
@END
@TITLE MTL27.19(3,6)
@COL 1S-2R-3R-4R-5R-6R-7F
@COL 10N-11N-12R-13N
@COL 14R-15N-16R-17N
@COL 18R-19R
@ROW 4-10-14-18
@ROW 5-12-16-19
@FLOW 1-2-3
@FLOW 4-7
@FLOW 5-7
@FLOW 6-7
@FLOW 12-13-7
@FLOW 14-15-11-7
@FLOW 16-17-13
@FLOW 18-15
@FLOW 19-17
@BOX 1.0
GET.OPD
(MODE,OPC,OPD.KIND,OPD.DESC.P)
@BOX 2.0
DECLARATIONS &
INITIALISATION
@BOX 3.0
SWITCH ON
OPERAND KIND
@BOX 4.0
VARIABLE
[MTL27.19.1]
@BOX 5.0
LABEL
PROC
[MTL27.19.5]
@BOX 6.0
TYPE
MFN
NONE
[MTL27.19.9]
@BOX 7.0
END
@BOX 12.0
STACK
PARAMETER STACK
UNSTACK
[MTL27.19.6]
@BOX 14.0
SELECT VARIABLE
[MTL27.19.3]
@BOX 16.0
REGISTER
T OPERAND
VSUB
[MTL27.19.7]
@BOX 18.0
LITERAL
[MTL27.19.4]
@BOX 19.0
RESULT
BASE/LIMIT
[MTL27.19.8]
@BOX 1.1
PROC GET.OPD(MODE,OPC,OPD.KIND,OPD.DESC.P);
@BOX 2.1
$LO64 L64;
$LO32 ADDRESS,OFFSET,INDEXC;
$IN32 VAL;
$IN I,J,K,N,BASER,STORE.KIND,INDEXB,
    IND.POSS,SC.DIS.B,ORIG.KIND;
ADDR VAR.E VAR.P;
ADDR SEL.E SEL.P;
ADDR LAB.E LAB.P;
ADDR PROC.E PROC.P;
-1 => OVP;
@BOX 3.1
SWITCH OPD.KIND\
K0,K1,K2,K3,K4,K5,
K6,K7,K8,K9,K10,K11,
K12,K13,K14,K15,K16;
@BOX 4.1
K0: K1:
#MTL27.19.1
@BOX 5.1
#MTL27.19.5
@BOX 6.1
K14: K15: K16:
::#MTL27.19.9
@BOX 7.1
END;
@BOX 12.1
#MTL27.19.6
@BOX 14.1
K2:
#MTL27.19.3
@BOX 16.1
#MTL27.19.7
@BOX 18.1
K3:
#MTL27.19.4
@BOX 19.1
#MTL27.19.8
@END
@TITLE MTL27.19.1(3,6)
@COL 17T-18R
@COL 1S-20R-2T-3R-4T-6R-8T-21R-9T-10T-11R-12R-13R-14F
@COL 19R
@ROW 21-19
@ROW 17-12
@FLOW 1-20-2Y-3-4N-6-8N-21-9Y-10Y-11-12-13-14
@FLOW 2N-4Y-19-14
@FLOW 8Y-19
@FLOW 9N-17N-18-14
@FLOW 10N-12
@FLOW 17Y-13
@BOX 1.0
VARIABLE
@BOX 20.0
SET UP FOR
VARIABLE ETC
@BOX 2.0
SUBSCRIPTED?
@BOX 3.0
PROCESS SUBSCRIPT
[MTL27.19.1.1]
@BOX 4.0
BASE OPERAND
D REGISTER?
@BOX 6.0
SET ADDRESS
OR BASE AND
DISPLACEMENT
[MTL27.19.1.2]
@BOX 8.0
POINTER OR
SELECT?
@BOX 21.0
ADD OFFSET
TO ADDRESS
@BOX 9.0
SCALED DISPLACEMENT
IN B REGISTER?
@BOX 10.0
BASE REGISTER SET?
@BOX 11.0
PLANT CODE TO
ADD BASE REGISTER
INTO B REGISTER
(NOTE B ALTERED)
@BOX 12.0
SET BASE REGISTER
AS B REGISTER
@BOX 13.0
FORM OPERAND USING
DISPLACEMENT ADDRESSING
@BOX 14.0
END
@BOX 17.0
BASE REGISTER
SET?
@BOX 18.0
FORM ADDRESS
USING ABSOLUTE
ADDRESSING
@BOX 19.0
PROCESS
POINTERS
[MTL27.19.1.3]
@BOX 1.1
::VARIABLE
@BOX 20.1
SIZ OF OP.TYPE OF OPD.DESC.P^ => OPD.SIZE;
MOD OF OP.TYPE OF OPD.DESC.P^ => OPD.MODE;
DIM OF OP.TYPE OF OPD.DESC.P^ => OPD.DIM;
ORIG.KIND OF OPD.DESC.P^ => ORIG.KIND
      & %18 => REF.REQD;
%7 &> ORIG.KIND;
OFFSET OF OPD.DESC.P^ => OFFSET;
INDEX.C OF OPD.DESC.P^ => INDEX.C;
INDEX.B OF OPD.DESC.P^ => INDEX.B;
2 => OPDK;
0 => SC.DIS.B;
@BOX 2.1
IF INDEX.B = 0
@BOX 3.1
#MTL27.19.1.1
@BOX 4.1
IF ORIG.KIND = 2
@BOX 6.1
#MTL27.19.1.2
@BOX 8.1
IF ORIG.KIND & %3 /= 0
@BOX 21.1
OFFSET +> ADDRESS;
@BOX 9.1
IF SC.DIS.B = 0
@BOX 10.1
IF BASE.R < 0
@BOX 11.1
PLANT.BY(ADDL2);
PLANT.BY(REGM!BASE.R);
PLANT.BY(REGM!B.REG);
::NOTE B ALTERED
@BOX 12.1
B.REG => BASE.R;
@BOX 13.1
DISP.ADDR(DISP.B,BASE.R,ADDRESS);
@BOX 14.1
::END 27.19.1
@BOX 17.1
IF BASE.R >= 0
@BOX 18.1
ABS.ADDR(ADDRESS);
@BOX 19.1
#MTL27.19.1.3
@END
@TITLE MTL27.19.1.1(3,6)
@COL 15R-11R
@COL 1S-2R-4T-14T-5T-6T-7R-8T-9R-10F
@COL 12R-13R
@ROW 15-6
@ROW 9-12
@FLOW 1-2-4Y-14N-5Y-6Y-7-8Y-9-10
@FLOW 8N-12-13-10
@FLOW 4N-11-8
@FLOW 5N-11
@FLOW 6N-11
@FLOW 14Y-15-11
@BOX 1.0
PROCESS
SUBSCRIPT
@BOX 2.0
NOTE IF ELEMENT
SIZE IS 8,16,32 OR 64 BITS
CALCULATE SCALING FACTOR
@BOX 4.0
IS BASE OPERAND
POINTER, D OR SELECT?
@BOX 5.0
ELEMENT SIZE
8,16,32 OR 64 BITS
@BOX 6.0
FIELD OFFSET = 0?
@BOX 14.0
REFERENCE
REQUIRED?
@BOX 7.0
IF REQUIRED
PLANT CODE
TO ADD B
OFFSET TO B
(NOTE B ALTERED)
@BOX 8.0
ELEMENT SIZE
8,16,32 OR 64 BITS
AND INDEX MODE
PERMITTED?
@BOX 9.0
FORM OPERAND
INDEXED BY
B REGISTER
@BOX 10.0
END
@BOX 15.0
SET INDEX MODE
NOT PERMITTED
@BOX 11.0
ADD SCALED
B OFFSET TO
FIELD OFFSET
@BOX 12.0
PLANT CODE
TO SCALE B
(NOTE B ALTERED)
@BOX 13.0
SET SCALED
DISPLACEMENT
IN B REGISTER
@BOX 1.1
::PROCESS
::SUBSCRIPT
@BOX 2.1
IF OPD.SIZE < 9 AND 1<<-OPD.SIZE & %116 /= 0 THEN 1 => IND.POSS
ELSE 0 => IND.POSS;
FI
@BOX 4.1
IF ORIG.KIND = 0
@BOX 5.1
IF IND.POSS = 0
@BOX 6.1
IF OFFSET /= 0
@BOX 14.1
IF REF.REQD /= 0
@BOX 7.1
IF INDEX.C /= 0 THEN
PLANTBY(ADDL2);
PLANT.LIT.OPD(4,INDEX.C);
PLANTBY(REGM!B.REG);
::NOTE B ALTERED
FI
@BOX 8.1
IF IND.POSS = 0
OR MODE & DONTINDX /= 0
@BOX 9.1
INDXD!B.REG => OPD.VEC[1+>OVP];
@BOX 10.1
::END 27.19.1.1
@BOX 15.1
DONTINDX !> MODE;
@BOX 11.1
INDEX.C * OPD.SIZE +> OFFSET;
@BOX 12.1
IF OPD.SIZE /= 1 THEN
PLANTBY(MULL2);
PLANT.LIT.OPD(4,OPD.SIZE);
PLANTBY(REGM!B.REG);
::NOTE B ALTERED
FI
@BOX 13.1
1 => SC.DIS.B;
@END
@TITLE MTL27.19.1.2(3,9)
@COL 15R
@COL 1S-2T-3T-4R-5T-22C-6R-7T-8R-9F-10N
@COL 18R-19R-23T-24R-20R-21R
@ROW 3-18
@ROW 15-8
@ROW 6-19
@ROW 8-23
@FLOW 1-2N-3N-4-5N-22-6-7Y-8-9
@FLOW 2Y-18-5Y-19-21-9
@FLOW 3Y-15-10-21
@FLOW 7N-23Y-20-21
@FLOW 23N-24-9
@BOX 1.0
SET ADDRESS
OR BASE AND
DISPLACEMENT
@BOX 2.0
VARIABLE
OR POINTER?
@BOX 3.0
VSTORE?
@BOX 4.0
(SELECT VARIABLE)
SET POINTER TO
ASSOCIATED
VARIABLE PROPERTIES
@BOX 5.0
VARIABLE
UNDEFINED?
@BOX 22.0
SEL.ENT
@BOX 22.1
SEL.ENT:
@BOX 6.0
GET VARIABLE
OFFSET
@BOX 7.0
VARIABLE
ON STACK?
@BOX 8.0
SET UP BASE
REGISTER AND
DISPLACEMENT
[MTL27.19.1.2.1]
@BOX 9.0
END
@BOX 15.0
SET VSTORE ADDRESS
@BOX 18.0
SET POINTER TO
VARIABLE PROPERTIES
@BOX 19.0
SET UP FOR
UNDEFINED VARIABLE
@BOX 20.0
CALCULATE VARIABLE
ADDRESS
@BOX 21.0
NOTE NO BASE
REGISTER
@BOX 23.0
BASE REGISTER LOADED
AND DISP < %8000
@BOX 24.0
SET UP BASE REGISTER OPERAND
@BOX 1.1
::SET ADDRESS
::OR BASE AND
::DISPLACEMENT
@BOX 2.1
IF ORIG.KIND < 2
@BOX 3.1
IF ORIG.KIND = 4
@BOX 4.1
SEL.VAR OF SEL.ADDR OF SEL^
OF ORIG OF OPD.DESC.P^
=> VAR.P;
@BOX 5.1
IF VAR.F OF VAR.P^ & VAR.DEFD = 0
@BOX 6.1
VAR.OFF OF VAR.ADDR OF VAR.P^
=> ADDRESS;
@BOX 7.1
IF STORE.KIND OF VAR.STORE.P^
OF VAR.ADDR OF VAR.P^
& %F => STORE.KIND = 1
@BOX 8.1
#MTL27.19.1.2.1
@BOX 9.1
::END 27.19.1.2
@BOX 15.1
STORE.ADDR OF V OF V.ST^
OF ORIG OF OPD.DESC.P^
 => ADDRESS;
@BOX 18.1
VAR OF ORIG OF OPD.DESC.P^
=> VAR.P;
@BOX 19.1
OFFSET => UNDEF.VAR.OFF;
1 => STORE.KIND;
18 => OPDK;
VAR.P => UNDEF.VAR.P;
%F0F0F0F0 => ADDRESS;
@BOX 20.1
STORE.R.ADDR OF VAR.STORE.P^
OF VAR.ADDR OF VAR.P^ +> ADDRESS;
@BOX 21.1
-1 => BASE.R;
@BOX 23.1
IF STORE.BASE OF VAR.STORE.P^
  OF VAR.ADDR OF VAR.P^ = 0
  OR ADDRESS > %7FFF
@BOX 24.1
STORE.BASE OF VAR.STORE.P^
  OF VAR.ADDR OF VAR.P^ + 8 => BASE.R;
@END
@TITLE MTL27.19.1.2.1(3,6)
@COL 11R
@COL 1S-2T-3T-12R-4R-7T-13R-14F
@COL 8T-9R-15R
@ROW 3-9
@ROW 11-12
@ROW 13-15
@FLOW 1-2N-3N-12-4-7N-13-14
@FLOW 2Y-9-7
@FLOW 3Y-11-7
@FLOW 7Y-15-14
@BOX 1.0
SET UP
BASE REGISTER
AND DISPLACEMENT
@BOX 2.0
LOCAL?
@BOX 3.0
TEXTUAL LEVEL 0 OR 1?
@BOX 12.0
OBTAIN TEMPORARY
REGISTER FOR XNB
SET BASE REGISTER
TO THIS REGISTER
@BOX 4.0
PLANT CODE TO
SET XNB FROM
STATIC LINKS
@BOX 7.0
PARAMETER?
@BOX 13.0
ADJUST DIPLACEMENT
FOR ON STACK
VARIABLES
@BOX 14.0
END
@BOX 11.0
SET BASE REGISTER
AS XNB0 OR XNB1
@BOX 9.0
SET BASE
REGISTER
AS FP (R13)
@BOX 15.0
SET DISPLACEMENT
FOR PARAMETER
@BOX 1.1
::SET UP
::BASE REGISTER
::AND DISPLACEMENT
@BOX 2.1
IF STORE.TX OF VAR.STORE.P^ OF VAR.ADDR OF VAR.P^ => I = TX.I
@BOX 3.1
IF I < 2
@BOX 12.1
AP => BASE.R;
@BOX 4.1
TX.I - I =>  K;
FP =>J;
LOOP: PLANT.BY(MOVL);
PLANT.BY(DISP.B ! J);
PLANT.BY(8);
PLANT.BY(REGM ! AP);
IF 1 -> K > 0 THEN
AP =>  J;
->LOOP; FI
@BOX 7.1
IF STORE.KIND = 2
@BOX 13.1
0 -:> ADDRESS;
@BOX 14.1
::END 17.19.1.2
@BOX 11.1
(IF I = 0 THEN
XNB0 ELSE XNB1)
=> BASE.R;
@BOX 9.1
FP => BASE.R;
@BOX 15.1
28 + STORE.I OF TX.FRAME[0]
OF TX.S[I] -:> ADDRESS;
@END
@TITLE MTL27.19.1.3(3,9)
@COL 14T-15R-16R-17R-8R
@COL 1S-2T-3T-4T-26T-5T-6R-7R-10R-24R-11R-12F
@COL 25R-27R-18T-19R-20T-21R-22R
@COL 23R
@ROW 3-25
@ROW 14-4
@ROW 26-27
@ROW 5-18
@ROW 19-23
@ROW 17-7
@ROW 8-11
@FLOW 1-2N-3N-4N-26N-5N-6-7-8-12
@FLOW 2Y-25-12
@FLOW 3Y-14Y-15-10
@FLOW 14N-16-11
@FLOW 4Y-27-18
@FLOW 4Y-27-18
@FLOW 26Y-18N-19-20N-21-22-11
@FLOW 18Y-23-20Y-10-24-11-12
@FLOW 5Y-17-8
@BOX 1.0
PROCESS
POINTERS
@BOX 2.0
REFERENCE
REQUIRED?
@BOX 3.0
IN D REGISTER?
@BOX 4.0
FORWARD REFERENCE
TO VARIABLE?
@BOX 26.0
FIELD OFFSET /= 0 OR
SCALED DISPLACEMENT
IN B REGISTER
@BOX 5.0
BASE OPERAND
ON STACK?
@BOX 6.0
SET UP FOR POSITION
DEPENDENT CODE
@BOX 7.0
SET BASE
REGISTER AS PC
SET RELATIVE
DEFERRED ADDRESSING
@BOX 8.0
FORM OPERAND
@BOX 10.0
PLANT CODE TO
ADD OPERAND TO
B REGISTER
(NOTE B ALTERED)
@BOX 24.0
SET BASE
REGISTER AS B
@BOX 11.0
FORM OPERAND USING
DISPLACEMENT ADDRESSING
FROM BASE REGISTER
WITH FIELD OFFSET
@BOX 12.0
END
@BOX 14.0
SCALED DISPLACEMENT
IN B REGISTER?
@BOX 15.0
FORM OPERAND
FOR D REGISTER
@BOX 16.0
SET BASE
REGISTER AS D
@BOX 17.0
SET DISPLACEMENT
DEFERRED ADDRESSING
@BOX 25.0
PROCESS REFERENCE
VIA POINTER VARIABLE
OR D REGISTER
[MTL27.19.1.3.1]
@BOX 27.0
CLEAR OFFSET FOR
UNDEFINED POINTER
VARIABLE
@BOX 18.0
BASE OPERAND
ON STACK?
@BOX 19.0
FORM OPERAND
FOR BASE OPERAND
USING ABSOLUTE
ADDRESSING
@BOX 20.0
SCALED DISPLACEMENT
IN B REGISTER
@BOX 21.0
GET TEMPORARY
REGISTER
SET AS BASE
REGISTER
@BOX 22.0
PLANT CODE TO
LOAD OPERAND
INTO REGISTER
@BOX 23.0
FORM OPERAND
FOR BASE OPERAND
USING DISPLACEMENT
ADDRESSING
@BOX 1.1
::PROCESS
::POINTERS
@BOX 2.1
IF REF.REQD /= 0
@BOX 3.1
IF ORIG.KIND = 2
@BOX 4.1
IF OPDK = 18
@BOX 26.1
IF OFFSET /= 0
OR SC.DIS.B /= 0
@BOX 5.1
IF BASE.R >= 0
@BOX 6.1
19 => OPDK;
ADDRESS => PDC.VAR.ADDR;
%F0F0F0F0 => ADDRESS;
@BOX 7.1
PC => BASE.R;
REL.DEFD.L => I;
@BOX 8.1
DISP.ADDR(I,BASE.R,ADDRESS);
@BOX 10.1
PLANT.BY(ADDL2);
PLANT.OPD(^OPD.VEC,OVP);
-1 => OVP;
PLANT.BY(REG.M!B.REG);
::NOTE B ALTERED
5 => OPDK;
@BOX 24.1
B.REG => BASE.R;
@BOX 11.1
DISP.ADDR(DISP.B,BASE.R,OFFSET);
@BOX 12.1
::END 27.19.1.3
@BOX 14.1
IF SC.DIS.B = 0
@BOX 15.1
REG.M!DREG => OPD.VEC[1+>OVP];
@BOX 16.1
D.REG => BASE.R;
@BOX 17.1
DISP.DEFD.B => I;
@BOX 25.1
#MTL27.19.1.3.1
@BOX 27.1
0 => UNDEF.VAR.OFF;
@BOX 18.1
OVP => I;
IF BASE.R >= 0
@BOX 19.1
ABS.ADDR(ADDRESS);
@BOX 20.1
IF SC.DIS.B /= 0
@BOX 21.1
GET.TEMP.REG(1) => BASE.R;
@BOX 22.1
PLANTBY(MOVL);
PLANT.OPD(PART(^OPD.VEC,I+1,OVP),
OVP - I - 1);
I => OVP;
PLANT.BY(REG.M!BASE.R);
5 => OPDK;
@BOX 23.1
DISP.ADDR(DISP.B,BASE.R,ADDRESS);
@END
@TITLE MTL27.19.1.3.1(3,7)
@COL 1S-2R-3R-4T-5R-6T-7R-8T-9R-10R-11F
@FLOW 1-2-3-4Y-5-6Y-7-8Y-9-10-11
@FLOW 4N-6N-8N-10
@BOX 1.0
PROCESS REFERENCE
VIA POINTER VARIABLE
OR D REGISTER
@BOX 2.0
SET UP OPERAND
KIND ETC AND
DESTINATION REGISTER
USING FUNCTION AND REGISTER
AND TYPE OF REFERENCE
REQUIRED
IF FORWARD REFERENCE TO
VARIABLE THEN CLEAR OFFSET FOR
UNDEFINED POINTER VARIABLE
@BOX 3.0
PLANT CODE TO LOAD
POINTER INTO
DESTINATION REGISTER
@BOX 4.0
SCALED DISPLACEMENT
IN B REGISTER?
@BOX 5.0
PLANT CODE TO
ADD B TO ADDRESS FIELD
OF DESTINATION REGISTER
@BOX 6.0
ANY FIELD OFFSET?
@BOX 7.0
PLANT CODE TO ADD
OFFSET TO ADDRESS FIELD
OF DESTINATION REGISTER
@BOX 8.0
BOUNDED REFERENCE REQUIRED
AND BOUND KNOWN?
@BOX 9.0
PLANT CODE TO LOAD
BOUND INTO BOUND FIELD
OF DESTINATION REGISTER
@BOX 10.0
CLEAR REFERENCE REQUIRED
AND FORM OPERAND
@BOX 11.0
END
@BOX 1.1
::PROCESS REFERENCE
::VIA POINTER VARIABLE
::OR D REGISTER
@BOX 2.1
(IF REF.REQD ->> 1 => OPD.SIZE = 8
THEN MOVQ ELSE MOVL) => I;
IF OPC & %3F => J /= %2F THEN
IF J = %22 THEN
AREG => N;
8 => K;
ELSE
DREG => N;
9 => K;
FI
ELSE
GET.TEMP.REG(REF.REQD ->> 3) => N;
6 => K;
FI
IF OPDK = 18 THEN
0 => UNDEF.VAR.OFF FI
@BOX 3.1
IF ORIG.KIND /= 2
OR J /= %42 THEN
PLANT.BY(I);
IF ORIG.KIND = 2 THEN
PLANT.BY(REGM ! DREG)
ELSE
IF BASE.R >= 0 THEN
DISP.ADDR(DISP.B,BASE.R,ADDRESS)
ELSE
ABS.ADDR(ADDRESS)
FI
PLANT.OPD(^OPD.VEC,OVP);
-1 => OVP;
FI
PLANT.BY(REGM ! N)
FI
@BOX 4.1
IF SC.DIS.B = 0
@BOX 5.1
PLANT.BY(ADDL2);
PLANT.BY(REGM ! BREG);
PLANT.BY(REGM ! N);
@BOX 6.1
IF OFFSET = 0
@BOX 7.1
PLANT.BY(ADDL2);
PLANT.LIT.OPD(4,OFFSET);
PLANT.BY(REGM ! N);
@BOX 8.1
IF REF.REQD = 8
OR OPD.DIM = 0
@BOX 9.1
PLANT.BY(MOVL);
PLANT.LIT.OPD(4,OPD.DIM);
PLANT.BY(REGM ! N + 1);
@BOX 10.1
REGM ! N => OPD.VEC[1 +> OVP];
K => OPDK;
0 => REF.REQD;
@BOX 11.1
::END 27.19.1.3.1
@END
@TITLE MTL27.19.3(3,6)
@COL 1S-2R-3R-4C
@FLOW 1-2-3-4
@BOX 1.0
SELECT VARIABLE
@BOX 2.0
SET UP FOR
D => SELECT
@BOX 3.0
ALLOCATE VARIABLE
FOR POINTER
MARK AS DEFINED
AND SET POINTER TO
VARIABLE PROPERTIES
@BOX 4.0
SEL.ENT
(27.19.1.2)
@BOX 1.1
::SELECT VARIABLE
@BOX 2.1
2 => OPDK;
0 => ORIG.KIND => OFFSET
  => REF.REQD => SC.DIS.B;
SEL.VAR OF OPD.DESC.P^ => SEL.P;
4 => OPD.SIZE;
@BOX 3.1
S.DECL(1,0) => SEL.VAR OF SEL.ADDR OF SEL.P^ => VAR.P;
SEL.DEFD !> SEL.V.F OF SEL.P^;
@BOX 4.1
->SEL.ENT;
@END
@TITLE MTL27.19.4(3,11)
@COL 12R
@COL 1S-2R-3T-4R-5R-6T-7T-8T-9R-10R-11F
@COL 13T-15R-16R-17T-18T-19T-20R
@ROW 4-13
@ROW 12-10
@FLOW 1-2-3Y-4-5-6N-7N-8Y-9-12
@FLOW 3N-13Y-15-16-6Y-17N-18Y-19Y-20-11
@FLOW 7Y-12-11
@FLOW 8N-10-11
@FLOW 13N-5
@FLOW 17Y-10
@FLOW 18N-10
@FLOW 19N-10
@BOX 1.0
LITERAL
@BOX 2.0
SET OPERAND
SIZE MODE & DIM
SET LITERAL VALUE
@BOX 3.0
COMPLEMENTED
LITERAL REQUIRED?
@BOX 4.0
COMPLEMENT
LITERAL VALUE
@BOX 5.0
SET OPERAND
KIND AS LITERAL
@BOX 6.0
REAL LITERAL?
@BOX 7.0
IS VALUE >= 0
AND =< 63?
@BOX 8.0
NEGATED LITERAL
POSSIBLE AND
VALUE < 0
AND > -64?
@BOX 9.0
NEGATE LITERAL
VALUE
SET OPERAND KIND
AS NEGATED LITERAL
@BOX 10.0
FORM OPERAND USING
IMMEDIATE MODE AND
BYTES OF VALUE IN
APPROPRIATE ORDER
@BOX 11.0
END
@BOX 12.0
FORM OPERAND
USING LITERAL MODE
AND 'SHORT' VALUE
@BOX 13.0
NEGATED LITERAL
REQUIRED?
@BOX 15.0
NEGATE LITERAL
VALUE
@BOX 16.0
SET OPERAND KIND
AS NEGATED LITERAL
@BOX 17.0
64 BIT LITERAL AND
TOP 32 BITS NONZERO
OR SHORT FORM DISALLOWED?
@BOX 18.0
WILL SIGN AND
EXPONENT FIT
IN 3 BITS?
@BOX 19.0
WILL MANTISSA
FIT IN 3 BITS?
@BOX 20.0
FORM OPERAND USING
LITERAL MODE AND
3 BITS OF EXPONENT &
3 BITS OF MANTISSA
@BOX 1.1
::LITERAL
@BOX 2.1
SIZ OF LIT.TYPE OF OPD.DESC.P^ => OPD.SIZE;
MOD OF LIT.TYPE OF OPD.DESC.P^ => OPD.MODE;
DIM OF LIT.TYPE OF OPD.DESC.P^ => OPD.DIM;
VAL OF LIT OF OPD.DESC.P^ => LIT;
@BOX 3.1
IF MODE & COMP.LIT = 0
@BOX 4.1
%F(16) -=> LIT;
@BOX 5.1
0 => OPDK;
@BOX 6.1
LIT => VAL;
IF OPD.MODE = 0
@BOX 7.1
IF LIT & %F(8)0(8) = 0
AND VAL >= 0 AND VAL =< 63
@BOX 8.1
IF MODE & NLITPOSS = 0
OR LIT & %F(8)0(8) /= %F(8)0(8)
OR VAL >= 0
OR VAL < -63
@BOX 9.1
0 -:> VAL;
VAL => LIT;
1 => OPDK;
@BOX 10.1
IMMED => OPD.VEC[1+>OVP];
LIT => L64;
FOR OPD.SIZE DO
L64 & %FF => OPD.VEC[1+>OVP];
L64 ->> 8 => L64 OD
@BOX 11.1
::END 27.19.4
@BOX 12.1
LIT & %FF => OPD.VEC[1+>OVP];
@BOX 13.1
IF MODE & NEG.LIT = 0
@BOX 15.1
LIT => VAL;
0 -:> VAL;
VAL => LIT;
@BOX 16.1
1 => OPDK;
@BOX 17.1
IF MODE & NOTSHORT /= 0
OR OPD.SIZE = 8
AND LIT & %F(8)0(8) /= 0
@BOX 18.1
IF VAL & %FC00 /= %4000
@BOX 19.1
IF VAL & %F(4)000F /= 0
@BOX 20.1
VAL ->> 4 & %3F => OPD.VEC[1+>OVP];
@END
@TITLE MTL27.19.5(3,9)
@COL 8R-9R
@COL 1S-2T-3T-4R-5R-6R-7F
@COL 10S-11T-12T-13R-14N
@COL 15R-16R
@ROW 8-3-12-15
@FLOW 1-2N-3Y-4-5-6-7
@FLOW 2Y-8-3N-9-6
@FLOW 10-11N-12Y-13-5
@FLOW 11Y-15-12N-16-14-6
@BOX 1.0
LABEL
@BOX 2.0
ENVIRONMENT
REQUIRED?
@BOX 3.0
IS LABEL
DEFINED?
@BOX 4.0
GET ADDRESS
OF LABEL
@BOX 5.0
SET OPERAND
KIND AS LITERAL
@BOX 6.0
SET REF.REQD
FORM OPERAND
FOR LITERAL
@BOX 7.0
END
@BOX 8.0
PLANT CODE TO
LOAD ENVIRINMENT
INTO BOUND FIELD
OF A REGISTER
@BOX 9.0
SET OPERAND
KIND TO
UNDEFINED
LABEL
@BOX 10.0
PROC
@BOX 11.0
ENVIRONMENT
REQUIRED?
@BOX 12.0
IS PROC
DEFINED?
@BOX 13.0
GET ADDRESS
OF PROC
@BOX 15.0
PLANT CODE TO LOAD
ENVIRONMENT INFORMATION
INTO BOUND FIELD OF
A REGISTER
(NOTE THAT THIS IMPLEMENTATION
IS DEPENDENT ON POSITION AND
SIZE OF STACK SEGMENT)
@BOX 16.0
SET OPERAND
KIND TO
UNDEFINED
PROC
@BOX 1.1
K4:
@BOX 2.1
LAB OF OPD.DESC.P^
=> LAB.P;
IF LAB.K OF OPD.DESC.P^ => I /= 0
@BOX 3.1
IF LAB.USE OF LAB.P^
& LAB.DEFD = 0
@BOX 4.1
ADDRESS OF LAB.ADDR
OF LAB.P^ => VAL;
@BOX 5.1
0 => OPDK;
4 => OPD.SIZE;
@BOX 6.1
%8 <<- I => REF.REQD;
4 => OPD.SIZE;
IMMED => OPD.VEC[1+>OVP];
FOR 4 DO
VAL & %FF => OPD.VEC[1+>OVP];
VAL ->> 8 => VAL OD
@BOX 7.1
::END 27.19.5
@BOX 8.1
IF LAB.TX OF LAB.P^ => J = TX.I THEN
FP => J
ELSE
IF J < 2 THEN
(IF J = 0 THEN
XNB0 ELSE XNB1) => J
ELSE
FAULT(0,%"LAB ENVIRON TX > 1")
FI FI
PLANT.BY(MOVL);
PLANT.BY(REGM ! J);
PLANT.BY(REGM ! AREG + 1);
@BOX 9.1
0 => VAL;
17 => OPDK;
LAB.P => UNDEF.LAB.P;
@BOX 10.1
K5:
@BOX 11.1
PROCED OF OPD.DESC.P^
=> PROC.P;
IF PROC.K OF OPD.DESC.P^ => I /= 0
@BOX 12.1
IF PROC.NAT OF PROC.P^
& PROC.DEFD = 0
@BOX 13.1
IF PROC.NAT OF PROC.P^
& 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
@BOX 15.1
PLANT.BY(ASHL);
PLANT.BY(15);
PLANT.BY(REGM ! XNB1);
PLANT.BY(REGM ! AREG + 1);
IF TX.I >= 2 THEN
IF PROC.INFO OF PROC.P^ + 1 => J > 2 THEN
IF TX.I - J => J < 0 THEN
FP => N;
ELSE
DISP.B ! FP => N;
FOR J DO
PLANT.BY(MOVL);
PLANT.BY(N);
PLANT.BY(8);
PLANT.BY(REGM ! AP);
DISP.B ! AP => N;
OD
FI
PLANT.BY(BISL2);
PLANT.BY(N);
IF N /= FP THEN
PLANT.BY(8) FI
PLANT.BY(REGM ! AREG + 1);
FI FI
@BOX 16.1
0 => VAL;
16 => OPDK;
PROC.P => UNDEF.PROC.P;
@END
@TITLE MTL27.19.6(3,9)
@COL 1S-2R-3T-4R-5R-6R-7R
@COL 8S-9R-10T-11T-12R-13R-14F
@COL 15R-16R-17N
@COL 18S-19R-20T-21R-22T-23R-24R
@ROW 11-15
@FLOW 1-2-3N-4-13
@FLOW 3Y-6-7-14
@FLOW 8-9-10N-11N-12-13-14
@FLOW 10Y-15-13
@FLOW 11Y-5-7
@FLOW 18-19-20N-21-22N-23-17-14
@FLOW 20Y-24-17
@FLOW 22Y-16-14
@BOX1.0
STACK
@BOX2.0
SET UP FOR
STACK OPERAND
@BOX3.0
GENERIC?
@BOX4.0
ADJUST SP.DISP
@BOX5.0
ADJUST LONGWORD
COUNT IN CALL STACK
@BOX6.0
SET OPERAND SIZE
FROM GENERIC A SIZE
@BOX7.0
PLANT CODE TO
SUBTRACT OPERAND
SIZE FROM SP
SET OPERAND AS (SP)
@BOX8.0
PARAMETER
STACK
@BOX9.0
SET UP FOR PARAMETER
STACK OPERAND
@BOX10.0
INTERPRETIVE
PROC CALL?
@BOX11.0
GENERIC?
@BOX12.0
ADJUST LONGWORD
COUNT IN CALL STACK
@BOX13.0
SET OPERAND AS -(SP)
@BOX14.0
END
@BOX15.0
PLANT CODE TO
LOAD INTERPRETIVE
LONGWORD COUNT INTO
TEMPORARY REGISTER
FROM ON STACK
@BOX16.0
PLANT CODE TO
UNSTACK OPERAND
TO TEMPORARY REGISTER
FORM OPERAND FOR SAME
@BOX18.0
UNSTACK
@BOX19.0
SET UP FOR
UNSTACK OPERAND
@BOX20.0
GENERIC?
@BOX21.0
ADJUST SP.DISP
@BOX22.0
MUST OPERAND
BE UNSTACKED?
@BOX23.0
SET OPERAND AS (SP)+
@BOX24.0
PLANT CODE TO ADD
OPERAND SIZE TO SP
SET OPERAND AS (-DISP)(SP)
@BOX1.1
K6:
@BOX2.1
OPC ->> 10 & %7 => I;
(IF OPC ->> 7 & %7 => OPD.MODE < 4
AND OPC & %60 /= %40 THEN
1 ELSE 4) <<- I => OPD.SIZE;
0 =>OPD.DIM;
@BOX3.1
IF OPC & %60 = %20
AND OPD.MODE = 4
AND GENA.KIND & %1 = 1
@BOX4.1
OPD.SIZE +> SP.DISP;
@BOX5.1
GENA.SIZE => OPD.SIZE => I + 3 / 4
+> STK.CNT OF LL.CALL OF CALL.S[CALL.I];
0 => OPD.DIM;
@BOX6.1
GENA.SIZE => OPD.SIZE => I;
@BOX7.1
I + 3 & %F(7)C => I;
PLANT.BY(SUBL2);
PLANT.LIT.OPD(4,I);
PLANT.BY(REGM ! SP);
REG.DEFD ! SP => OPD.VEC[1+>OVP];
5 => OPDK;
@BOX8.1
K7:
@BOX9.1
SIZ OF PAR.STK OF OPD.DESC.P^ => OPD.SIZE;
MOD OF PAR.STK OF OPD.DESC.P^ => OPD.MODE;
DIM OF PAR.STK OF OPD.DESC.P^ => OPD.DIM;
@BOX10.1
IF CALL.I < 0
@BOX11.1
IF OPC ->> 7 & %7 = 4
AND GENA.KIND & %1 = 1
@BOX12.1
(IF OPD.SIZE > 4 THEN 2 ELSE 1)
+> STK.CNT OF LL.CALL OF CALL.S[CALL.I];
@BOX13.1
SP.MINUS => OPD.VEC[1+>OVP];
4 => OPDK;
@BOX14.1
::END 27.19.6
@BOX15.1
PLANT.BY(MOVL);
PLANT.BY(SP.PLUS);
PLANT.BY(GET.TEMP.REG(1)
=> INT.AP.CNT.REG ! REGM);
@BOX16.1
PLANT.BY(MOVE.CODES[OPD.SIZE]);
PLANT.BY(SP.PLUS);
PLANT.BY(GET.TEMP.REG((IF OPD.SIZE > 4 THEN
2 ELSE 1)) ! REGM => OPD.VEC[1+>OVP]);
5 =>OPDK;
@BOX18.1
K8:
@BOX19.1
SIZ OF UNSTK OF OPD.DESC.P^ => OPD.SIZE;
MOD OF UNSTK OF OPD.DESC.P^ => OPD.MODE;
DIM OF UNSTK OF OPD.DESC.P^ => OPD.DIM;
@BOX20.1
IF OPC & %60 /= %40
AND OPD.MODE = 4
AND GENA.KIND & %1 = 1
@BOX21.1
OPD.SIZE -> SP.DISP;
@BOX22.1
IF MODE & UNSTACK /= 0
@BOX23.1
SP.PLUS =>OPD.VEC[1+>OVP];
4 => OPDK;
@BOX24.1
PLANT.BY(ADDL2);
OPD.SIZE + 3 & %F(7)C => I;
PLANT.LIT.OPD(4,I);
PLANT.BY(REGM ! SP);
DISP.ADDR(DISP.B,SP,0 - I);
5 => OPDK;
@END
@TITLE MTL27.19.7(3,8)
@COL 1S-3T-4R-5R
@COL 10S-11R-12R-13F
@COL 14S-15R
@FLOW 1-3N-4-12
@FLOW 3Y-5-12
@FLOW 10-11-12-13
@FLOW 14-15-12
@BOX 1.0
REGISTER
@BOX 3.0
GET REGISTER NUMBER
IS IT B REGISTER?
@BOX 4.0
SET UP FOR A
REGISTER
@BOX 5.0
SET UP FOR B
REGISTER
@BOX 10.0
VSUB
@BOX 11.0
SET UP FOR VSUB
REGISTER
@BOX 12.0
FORM OPERAND FOR
RELEVANT REGISTER
@BOX 13.0
END
@BOX 14.0
T OPERAND
@BOX 15.0
GET TEMPORARY REGISTER
FOR T OPERAND
PLANT CODE TO LOAD
IT WITH APPROPRIATE
VALUE (0 OR 1)
@BOX 1.1
K9:
@BOX 3.1
IF REG OF OPD.DESC.P^
+ 7 => OPDK = 7
@BOX 4.1
A.TYPE & %7 => OPD.MODE;
A.TYPE ->> 3 => I;
1 <<- I => OPD.SIZE;
A.REG => J;
@BOX 5.1
1 => OPD.MODE;
4 => OPD.SIZE;
B.REG => J;
@BOX 10.1
K11:
@BOX 11.1
6 => OPDK;
1 => OPD.MODE;
4 => OPD.SIZE;
VSUB.REG => J;
@BOX 12.1
REGM ! J => OPD.VEC[1+>OVP];
@BOX 13.1
::END 27.19.7
@BOX 14.1
K10:
@BOX 15.1
GET.TEMP.REG(1) => J;
PLANT.BY(BR.FNS[TREG OF OPD.DESC.P^] -= 1);
PLANT.BY(5);
PLANT.BY(MOVL);
PLANT.BY(1);
PLANT.BY(REGM ! J);
PLANT.BY(BRB);
PLANT.BY(2);
PLANT.BY(CLRL);
PLANT.BY(REGM ! J);
A.TYPE & %7 => OPD.MODE;
A.TYPE ->> 3  => I;
1 <<- I => OPD.SIZE;
5 => OPDK;
@END
@TITLE MTL27.19.8(3,6)
@COL 1S-2R-3F
@COL 4S-5R
@FLOW 1-2-3
@FLOW 4-5
@BOX 1.0
RESULT
@BOX 2.0
SET OPERAND KIND
AS RESULT
@BOX 3.0
END
@BOX 4.0
BASE/LIMIT
@BOX 5.0
FAULT
@BOX 1.1
K12:
@BOX 2.1
RESK => OPDK;
0 => OPD.VEC[1+>OVP];::TEMP
@BOX 3.1
::END 27.19.8
@BOX 4.1
K13:
@BOX 5.1
FAULT(0,%"27.19.8");
@END
@TITLE MTL27.21(3,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
REPLANT(SIZE,VAL,SEG.P,POS)
@BOX 2.0
PLANT VAL IN
SEGMENT AT
GIVEN POSITION
@BOX 3.0
END
@BOX 1.1
PROC REPLANT(SIZ,VAL,SEG.P,POS);
ADDR[$LO8] SEG;
$IN I;
@BOX 2.1
SEG.PTR OF STORE.ADDR OF SEG.P^ => SEG;
FOR I < SIZ DO
VAL & %FF => SEG^[POS+I];
VAL ->> 8 => VAL OD
@BOX 3.1
END;
@END
@TITLE MTL27.22(3,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
INSERT(BYTE)
@BOX 2.0
PLANT BYTE
IN CODE
@BOX 3.0
END
@BOX 1.1
PROC INSERT(BY);
@BOX 2.1
PLANT.BY(BY);
@BOX 3.1
END
@END
@TITLE MTL27.23(3,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
RESERVE.REGS(REG,NO)
@BOX 2.0
SET REGISTER(S)
IN USE
SET APPROPRIATE
BIT(S) IN REGS.IU
@BOX 3.0
END
@BOX 1.1
PROC RESERVE.REGS(REG,NO);
$IN I,J;
@BOX 2.1
FOR I < NO DO
IN.USE => STATUS OF REGS[REG+I=>J];
1 <<- J !> REGS.IU OD
@BOX 3.1
END
@END
@TITLE MTL27.24(3,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
RELEASE.REGS(REG,NO)
@BOX 2.0
SET REGISTER(S)
NOT IN USE
CLEAR APPROPRIATE
BIT IN REGS.IU
@BOX 3.0
END
@BOX 1.1
PROC RELEASE.REGS(REG,NO);
$IN I,J;
@BOX 2.1
FOR I < NO DO
NOT.IN.USE => STATUS OF REGS[REG+I=>J];
1 <<- J -=> REGS.IU OD
@BOX 3.1
END
@END
@TITLE MTL27.25(3,8)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
SET.RESULT.REG(SIZE,MODE)
@BOX 2.0
SET RESULT
REGISTER IN USE
@BOX 3.0
SET A.TYPE
@BOX 4.0
END
@BOX 1.1
PROC SET.RESULT.REG(SIZ,MODE);
@BOX 2.1
RESERVE.REGS(AREG,
(IF SIZ > 4 THEN 2 ELSE 1));
@BOX 3.1
IF MODE = 5 THEN
0 => GENA.KIND;
SIZ ! MODE => A.TYPE
ELSE
MODE.FROM.SIZE[SIZ] ! MODE => A.TYPE
FI
@BOX 4.1
END
@END
@TITLE MTL27.26(3,6)
@COL 1S-3T-4R-5T-6T-20R-7R-8T-9R-10T-11R-12F
@COL 15T-13R-16R-17N
@COL 18T-19R
@ROW 20-15
@ROW 13-18
@FLOW 1-3Y-4-5Y-6N-20-7-8Y-9-10Y-11-12
@FLOW 3N-5N-8N-10N-12
@FLOW 6Y-15Y-13-7
@FLOW 15N-18N-19-17-8
@FLOW 18Y-16-7
@BOX 1.0
REL.REGS(REG.SPEC)
@BOX 3.0
B REGISTER?
@BOX 4.0
RELEASE B
@BOX 5.0
A REGISTER?
@BOX 6.0
WAS A GENERIC
OR POINTER?
@BOX 20.0
GET SIZE OF
A REGISTER
@BOX 7.0
RELEASE A
@BOX 8.0
D REGISTER?
@BOX 9.0
RELEASE D
@BOX 10.0
T REGISTER?
@BOX 11.0
RELEASE T
@BOX 12.0
END
@BOX 15.0
POINTER TYPE?
@BOX 13.0
GET SIZE OF
A REGISTER
@BOX 16.0
GET SIZE OF
A REGISTER
@BOX 18.0
GENERIC IN
A REGISTER?
@BOX 19.0
RELEASE R0 & R1
@BOX 1.1
PROC REL.REGS(REG.SPEC);
$IN I;
@BOX 3.1
IF REG.SPEC & %1 = 0
OR STATUS OF REGS[BREG] = NOT.IN.USE
@BOX 4.1
RELEASE.REGS(BREG,1);
@BOX 5.1
IF REG.SPEC & %2 = 0
@BOX 6.1
IF A.TYPE & %7 >= 4
@BOX 20.1
(IF ATYPE >= %18 THEN
2 ELSE 1) => I;
@BOX 7.1
IF STATUS OF REGS[AREG] = IN.USE THEN
RELEASE.REGS(AREG,I) FI
@BOX 8.1
IF REG.SPEC & %4 = 0
OR STATUS OF REGS[DREG] = NOT.IN.USE
@BOX 9.1
RELEASE.REGS(DREG,(IF DKIND = 3 THEN 2 ELSE 1));
@BOX 10.1
IF REG.SPEC & %8 = 0
@BOX 11.1
::NOT YET
@BOX 12.1
END
@BOX 15.1
IF A.TYPE & %7 /= 5
@BOX 13.1
(IF ATYPE = %D THEN
2 ELSE 1) => I;
@BOX 16.1
(IF GENA.SIZE > 4 THEN
2 ELSE 1) => I;
@BOX 18.1
IF GENA.KIND = 0
@BOX 19.1
IF STATUS OF REGS[0] = IN.USE THEN
RELEASE.REGS(0,2) FI
@END
@TITLE MTL27.27(3,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
LIB.ENTRY(PROC.P)
@BOX 2.0
REPLANT PROC ENTRY
MASK AND BRANCH
TO PROCEDURE IN NEXT
DIRECTORY ENTRY
@BOX 3.0
END
@BOX 1.1
PROC LIB.ENTRY(PROC.P);
$LO64 L;
$IN32 I,J;
@BOX 2.1
8 * LIB.PNO + 4 => I;
1 +> LIB.PNO;
ABSOLUTE <<- 8 ! JMP <<- 16 ! %0800 => L;::0800 SHOULD BE C800
REPLANT(4,L,CODE.SEG.P,I);
ADDRESS OF PADDR OF PROC.ADDR OF ENTRY OF PROC.P^ + 2 => J;
REPLANT(4,J,CODE.SEG.P,I+4);
@BOX 3.1
;
END
@END
@TITLE MTL27.28(3,7)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX1.0
CYCLE(LIMITK,LIMIT)
@BOX2.0
FORM MODE FOR CV.CYCLE
LOOP TEST FROM LIMIT
@BOX3.0
GENERATE INTEGER VARIABLE
FOR CYCLE VARIABLE (CV)
AND CALL CV.CYCLE TO LOAD
LIMIT VALUE INTO CV AND
MAKE ENTRY ON CYCLE STACK
@BOX4.0
CALL CV.LIMIT TO
SET LIMIT TO LITERAL 0
@BOX5.0
END
@BOX1.1
PROC CYCLE(LIMITK,LIMIT);
$IN MODE;
@BOX2.1
(IF LIMITK = 3 THEN
%83 ELSE %82) => MODE;
@BOX3.1
CV.CYCLE(S.DECL(%4C,0),LIMITK,LIMIT,MODE);
@BOX4.1
0 => VAL OF LIT OF LIMIT^;
CV.LIMIT(3,LIMIT);
@BOX5.1
END
@END
@TITLE MTL27.29(3,10)
@COL 1S-2R-3T-4R-5F
@COL 6R
@ROW 4-6
@FLOW 1-2-3N-4-5
@FLOW 3N-6-5
@BOX1.0
CV.CYCLE(CV,INITK,INIT,MODE)
@BOX2.0
MAKE ENTRY ON
CYCLE STACK
@BOX3.0
INITIAL VALUE LITERAL?
@BOX4.0
PLANT CODE TO LOAD
INITIAL VALUE
(POSSIBLY +/- 1)
INTO CYCLE VARIABLE
NOTE CYCLE VARIABLE
ON CYCLE STACK
@BOX5.0
END
@BOX6.0
NOTE LITERAL INITIAL
VALUE IN CYCLE STACK
@BOX1.1
PROC CV.CYCLE(CV,INITK,INIT,MODE);
$IN I,Z;
@BOX2.1
IF 1 +> CY.PTR >= CY.Z THEN
FAULT(0,%"CYCLE STACK OFLO") FI
SELECT CYCLES[CY.PTR];
MODE => KIND;
CV => CYCLE.V;
VAR.TYP OF CV^ ->> 2 & 7 =>CV.Z => Z;
@BOX3.1
IF INITK = 3
@BOX4.1
IF MODE & %80 /= 0 THEN
MOVES[Z] => I
ELSE
(IF MODE & %2 /= 0 THEN
ADD3S[Z] ELSE SUB3S[Z]) => I
FI
PLANT.BY(I);
IF I & %F /= 0 THEN
PLANT.BY(1) FI
GET.OPD(0,%8A0,INITK,INIT);
PLANT.OPD(^OPD.VEC,OVP);
CV => VAR OF ORIG OF CY.OPD;
GET.OPD(0,%8A0,0,^CY.OPD);
PLANT.OPD(^OPD.VEC,OVP);
@BOX5.1
END
@BOX6.1
%10 !> KIND;
VAL OF LIT OF INIT^
=> LIT OF LIMITV;
@END
@TITLE MTL27.30(3,11)
@COL 1S-2T-3T-4R-5R-6T-7R-8R-9T-10R-11R-12F
@COL 13T-14R-15T-16R
@ROW 4-13
@ROW 7-15
@FLOW 1-2N-3N-4-5-6Y-7-8-9Y-10-11-12
@FLOW 2Y-6
@FLOW 3Y-13Y-14-5
@FLOW 6N-15Y-16-9N-11
@FLOW 13N-4
@FLOW 15N-8
@BOX1.0
CV.LIMIT(LIMITK,LIMIT)
@BOX2.0
CV INITIALISED?
@BOX3.0
LIMIT A LITERAL?
@BOX4.0
ADJUST INITIAL VALUE
@BOX5.0
PLANT CODE TO LOAD
CV WITH INITIAL VALUE
@BOX6.0
IS LIMIT ACC OR
D[]?
@BOX7.0
GENERATE LOCAL INTEGER
FOR LIMIT VALUE
PLANT CODE TO LOAD
IT FROM ACC
@BOX8.0
NOTE LIMIT VARIABLE
ON CYCLE STACK
@BOX9.0
IS BRANCH TO TEST
AT END LOOP REQUIRED?
@BOX10.0
PLANT BRANCH
@BOX11.0
NOTE LOOP ADDRESS
IN CYCLE STACK
@BOX12.0
END
@BOX13.0
WILL CYCLE BE OBEYED
AT LEAST ONCE?
@BOX14.0
NOTE BRANCH TO TEST AT
END LOOP NOT REQUIRED
@BOX15.0
IS LIMIT A LITERAL?
@BOX16.0
NOTE IN CYCLE STACK
@BOX1.1
PROC CV.LIMIT(LIMITK,LIMIT);
$IN32 I,J;
$IN K,Z;
ADDR VAR.E VAR.P;
SELECT CYCLES[CY.PTR];
CV.Z => Z;
(IF KIND & %2 /= 0 THEN
-1 ELSE 1) => K;
@BOX2.1
IF KIND & %10 = 0
@BOX3.1
LIT OF LIMITV => I;
IF LIMITK = 3
@BOX4.1
I - K => I;
@BOX5.1
IF I < 0 THEN
MNEGS[Z] => J;
0 -:> I;
ELSE
(IF I = 0 THEN
CLRS[Z] ELSE MOVES[Z]) => J;
FI
PLANT.BY(J);
IF I /= 0 THEN
PLANT.LIT.OPD(Z+1,I) FI
CYCLE.V => VAR OF ORIG OF CY.OPD;
GET.OPD(0,%8A0,0,^CY.OPD);
PLANT.OPD(^OPD.VEC,OVP);
@BOX6.1
IF LIMITK /= 9 AND
    [LIMITK /= 0 OR
       [ORIGKIND OF LIMIT^ = 0 AND OFFSET OF LIMIT^ = 0 AND INDEX.B OF LIMIT^ =
0]]
@BOX7.1
S.DECL(Z <<- 2 ! %40,0) => VAR.P
=> VAR OF ORIG OF CY.OPD;
IF LIMITK = 0 THEN
  GET.OPD(0,%8A0,0,LIMIT);
  PLANT.BY(MOVES[Z]);
  PLANT.OPD(^OPD.VEC,OVP);
  9 => LIMITK;
ELSE
  PLANT.BY(MOVES[Z]);
  PLANT.BY(REGM ! AREG);
FI
GET.OPD(0,%8A0,0,^CY.OPD);
PLANT.OPD(^OPD.VEC,OVP);
@BOX8.1
IF LIMITK = 9 THEN
VAR.P => VAR.P OF LIMITV
ELSE
VAR OF ORIG OF LIMIT^
=> VAR.P OF LIMITV
FI
@BOX9.1
IF KIND & %20 /= 0
@BOX10.1
PLANT.REF(GOTO.REF,0);
@BOX11.1
CODE.SEG.P => LOOP.SEG;
STORE.I OF CODE.SEG.P^ => LOOP.POS;
@BOX12.1
END
@BOX13.1
VAL OF LIT OF LIMIT^ => J;
IF J - I * K =< 0
@BOX14.1
%20 !> KIND;
@BOX15.1
IF LIMITK /= 3
@BOX16.1
%40 !> KIND;
VAL OF LIT OF LIMIT^
=> LIT OF LIMITV;
@END
@TITLE MTL27.31(3,11)
@COL 1S-2T-3R-7T-4R-5R-6F
@COL 10R
@ROW 4-10
@FLOW 1-2Y-3-7N-4-5-6
@FLOW 2N-7
@FLOW 7Y-10-5
@BOX1.0
REPEAT
@BOX2.0
WAS BRANCH TO TEST
FROM START LOOP PLANTED
@BOX3.0
FILL IN BRANCH
@BOX4.0
PLANT APPROPRIATE TEST
INSTRUCTION WITH LIMIT
FROM CYCLE STACK
@BOX5.0
DELETE ENTRY FROM
CYCLE STACK
@BOX6.0
END
@BOX 7.0
WORD OR BYTE CONTROL VAR
@BOX 10.0
PLANT CODE
@BOX1.1
PROC REPEAT;
$IN32 I,J,K,D;
$IN M,Z;
$DA BRS($LO8)
%18 %18 %15 %15
END
SELECT CYCLES[CY.PTR];
CV.Z => Z;
STORE.R.ADDR OF LOOP.SEG^
+ LOOP.POS => K
-: STORE.R.ADDR OF CODE.SEG.P^ => I;
@BOX2.1
IF KIND & %20 /= 0
@BOX3.1
I + STORE.I OF CODE.SEG.P^ => J;
REPLANT(2,J,LOOP.SEG,LOOP.POS - 2);
@BOX4.1
IF Z = 0 THEN
   %9D => J ::ACBB
ELSE IF Z = 1 THEN
   %3D => J ::ACBW
ELSE
KIND & %3 + %F2 => J;
IF J >= %F4
AND [KIND & %40 = 0
OR LIT OF LIMITV /= 0] THEN
%F1 => J FI FI FI
PLANT.BY(J);
IF J < %F4 THEN
  IF KIND & %40 /= 0 THEN
    PLANT.LIT.OPD(Z+1,LIT OF LIMITV)
  ELSE
    VAR.P OF LIMITV => VAR OF ORIG OF CY.OPD;
    GET.OPD(0,%8A0,0,^CY.OPD);
    PLANT.OPD(^OPD.VEC,OVP);
  FI
  IF J =< %F1 THEN
  IF KIND & %B /=2 /= 3 THEN
      PLANT.BY(1)
   ELSE
      PLANT.LIT.OPD(Z+1,%FFFFFFFF)
FI FI
FI
CYCLE.V => VAR OF ORIG OF CY.OPD;
GET.OPD(0,%8A0,0,^CY.OPD);
PLANT.OPD(^OPD.VEC,OVP);
STORE.I OF CODE.SEG.P^ + 1 +> I;
IF J =< %F1 THEN
  PLANT.BY(-1 -I => I);
  PLANT.BY(I ->> 8)
ELSE
  IF I =< %80 THEN
    PLANT.BY(0 - I)
  ELSE
    PLANT.BY(2);
    PLANT.BY(BRB);
    PLANT.BY(3);
    PLANT.REF(GOTO.REF,K);
  FI
FI
@BOX5.1
1 -> CY.PTR;
@BOX6.1
END
@BOX 7.1
IF Z < 2
@BOX 10.1
IF KIND & %B => M /= 2 /= 3 THEN
   INCB => J
ELSE
   DECB => J
FI
Z * %20 +> J;
IF M = 0 OR M = 3 THEN
  PLANT.BY(J);
  CYCLE.V => VAR OF ORIG OF CY.OPD;
  GET.OPD(0,%8A0,0,^CY.OPD);
  PLANT.OPD(^OPD.VEC,OVP);
FI
PLANT.BY(Z * %20 + %91);
CYCLE.V => VAR OF ORIG OF CY.OPD;
GET.OPD(0,%8A0,0,^CY.OPD);
PLANT.OPD(^OPD.VEC,OVP);
IF KIND & %40 /= 0 THEN
  PLANT.LIT.OPD(Z+1,LIT OF LIMITV)
ELSE
   VAR.P OF LIMITV => VAR OF ORIG OF CY.OPD;
   GET.OPD(0,%8A0,0,^CY.OPD);
   PLANT.OPD(^OPD.VEC,OVP);
FI
PLANT.BY(BRS[KIND & 3]);
PLANT.BY(0);
STORE.I OF CODE.SEG.P^ => D;
IF M = 1 OR M = 2 THEN
  PLANT.BY(J);
  CYCLE.V => VAR OF ORIG OF CY.OPD;
  GET.OPD(0,%8A0,0,^CY.OPD);
  PLANT.OPD(^OPD.VEC,OVP);
FI
STORE.I OF CODE.SEG.P^ + 2 +> I;
IF I =< %80 THEN
   PLANT.BY(BRB);
   PLANT.BY(0-I);
ELSE
   PLANT.BY(BRW);
   PLANT.BY(-1 -I => I);
   PLANT.BY(I ->> 8);
FI
REPLANT(1,(STORE.I OF CODE.SEG.P^ - D),CODE.SEG.P,D-1);
@END
@TITLE MTL27.32(3,8)
@COL 1S-2R-3T-4T-5T-6T-7T-8R-9F
@COL 10T-11T-12N-13C-14R
@COL 15T-16T-17N
@ROW 5-10
@ROW 11-15
@ROW 12-17
@FLOW 1-2-3N-4Y-5N-6Y-7Y-8-9
@FLOW 3Y-9
@FLOW 4N-10Y-11Y-12-9
@FLOW 5Y-13-14-9
@FLOW 6N-8
@FLOW 7N-13
@FLOW 10N-15Y-16Y-17-12
@FLOW 11N-13
@FLOW 15N-13
@FLOW 16N-13
@BOX1.0
CHECK.OPD
(OPD.KIND,OPD.DESC.P,PERMIT)
@BOX2.0
INITIALISE ETC
CLEAR RESULT
@BOX3.0
GET OPERAND KIND.
IS IT A LITERAL?
@BOX4.0
VARIABLE ETC?
@BOX5.0
REFERENCE
REQUIRED?
@BOX6.0
INDEXED?
@BOX7.0
NOTE IN RESULT.
PERMITTED?
@BOX8.0
CHECK VARIABLE
[MTL27.32.1]
@BOX9.0
END
@BOX10.0
ACTUAL
PARAMETER?
@BOX11.0
NOTE IN RESULT.
PERMITTED?
@BOX13.0
NOT.OK
@BOX14.0
SET RESULT
NEGATIVE
@BOX15.0
STACK/UNSTACK?
@BOX16.0
NOTE IN RESULT.
PERMITTED?
@BOX1.1
PROC CHECK.OPD(OPD.KIND,OPD.DESC.P,PERMIT);
$IN I;
@BOX2.1
ADDR VAR.E VAR.P;
$IN STORE.KIND;
0 => CHECK.OPD;
SELECT OPD.DESC.P^;
@BOX3.1
IF OPD.KIND = 3
@BOX4.1
IF OPD.KIND /= 0
@BOX5.1
IF ORIG.KIND & %18 /= 0
@BOX6.1
IF INDEX.B = 0
@BOX7.1
%1 !> CHECK.OPD;
IF PERMIT & %1 /= 0
@BOX8.1
#MTL27.32.1
@BOX9.1
END
@BOX10.1
IF OPD.KIND /= 7
@BOX11.1
%80 !> CHECK.OPD;
IF PERMIT & %80 /= 0
OR CALL.I < 0
@BOX13.1
NOT.OK:
@BOX14.1
-1 => CHECK.OPD;
@BOX15.1
IF OPD.KIND /= 6 /= 8
@BOX16.1
%100 !> CHECK.OPD;
IF PERMIT & %100 /= 0
@END
@TITLE MTL27.32.1(3,8)
@COL 1S-2T-3T-4T-5T-6T-7F
@COL 8T-9T-10T-11T-12T-13T-14N
@COL 15C
@ROW 3-8
@ROW 14-15
@FLOW 1-2N-3N-4Y-5Y-6Y-7
@FLOW 2Y-8Y-9Y-10Y-7
@FLOW 3Y-7
@FLOW 4N-11Y-7
@FLOW 5N-12N-7
@FLOW 6N-13Y-7
@FLOW 8N-15
@FLOW 9N-4
@FLOW 10N-15
@FLOW 11N-15
@FLOW 12Y-11
@FLOW 13N-15
@BOX1.0
CHECK VARIABLE
@BOX2.0
POINTER TYPE?
@BOX3.0
VSTORE?
@BOX4.0
GET VARIABLE ENTRY.
IS IT DEFINED?
@BOX5.0
ON STACK?
@BOX6.0
LOCAL
OR LEVEL 0 OR 1?
@BOX7.0
END
@BOX8.0
NOTE IN RESULT.
PERMITTED?
@BOX9.0
D REGISTER?
@BOX10.0
NOTE IN RESULT.
PERMITTED?
@BOX11.0
NOTE IN RESULT.
PERMITTED?
@BOX12.0
WILL IT CAUSE
POSITION DEPENDENT
CODE?
@BOX13.0
NOTE IN RESULT.
PERMITTED?
@BOX15.0
NOT.OK
@BOX1.1
::CHECK VARIABLE
@BOX2.1
IF ORIG.KIND & %3 /= 0
@BOX3.1
IF ORIG.KIND = 4
@BOX4.1
IF ORIG.KIND = 2 THEN
SEL.VAR OF SEL.ADDR OF SEL^
OF ORIG => VAR.P;
ELSE
VAR OF ORIG => VAR.P;
FI
IF VAR.F OF VAR.P^ & VAR.DEFD = 0
@BOX5.1
IF STORE.KIND OF VAR.STORE.P^
OF VAR.ADDR OF VAR.P^
& %F => STORE.KIND = 1
@BOX6.1
IF STORE.TX OF VAR.STORE.P^
OF VAR.ADDR OF VAR.P^ => I >= 2 /= TX.I
@BOX7.1
::END 27.32.1
@BOX8.1
%4 !> CHECK.OPD;
IF PERMIT & %4 /= 0
@BOX9.1
IF ORIG.KIND /= 2
@BOX10.1
%8 !> CHECK.OPD;
IF PERMIT & %8 /= 0
@BOX11.1
%20 !> CHECK.OPD;
IF PERMIT & %20 /= 0
@BOX12.1
IF ORIG.KIND & %3 /= 0
AND OFFSET = 0
@BOX13.1
%10 !> CHECK.OPD;
IF PERMIT & %10 /= 0
@BOX15.1
->NOT.OK;
@END
@TITLE MTL27.33(3,8)
@COL 1S-2T-3R-4T-5T-6R-7F
@COL 8R
@ROW 6-8
@FLOW 1-2N-3-4Y-5Y-6-7
@FLOW 2Y-8-7
@FLOW 4N-8
@FLOW 5N-8
@BOX1.0
CHECK.OPD.MODE(Z,T,INST.SEQ,PTR)
@BOX2.0
OPERAND KIND
SUITABLE?
@BOX3.0
GET SIZE AND MODE
OF OPERAND
@BOX4.0
OPERAND SIZES
THE SAME?
@BOX5.0
OPERAND MODES
COMPATIBLE?
@BOX6.0
SET RESULT
TO ZERO
@BOX7.0
END
@BOX8.0
SET RESULT
NONZERO
@BOX1.1
PROC CHECK.OPD.MODE(Z,T,INST.SEQ,PTR);
$IN I;
ADDR OP.TYPE.E OP.TYP;
SELECT INST.SEQ^[PTR];
-1 => CHECK.OPD.MODE;
@BOX2.1
IF OPD.KIND > 8
@BOX3.1
ALTERNATIVE OPD.KIND FROM
^OP.TYPE OF OPD => OP.TYP;
1 => CHECK.OPD.MODE;
1 => CHECK.OPD.MODE;
^LIT.TYPE OF OPD => OP.TYP;
1 => CHECK.OPD.MODE;
1 => CHECK.OPD.MODE;
0 => CHECK.OPD.MODE;
^PAR.STK OF OPD => OP.TYP;
^UNSTK OF OPD => OP.TYP;
END
IF CHECK.OPD.MODE >= 0,->OUT;
@BOX4.1
IF 1 <<- Z /= SIZ OF OP.TYP^
@BOX5.1
IF MOD OF OP.TYP^ => I = T,->OK;
IF T = 1 AND I = 2,->OK;
IF T /= 2 OR I /= 1
@BOX6.1
OK:
0 => CHECK.OPD.MODE;
@BOX7.1
OUT:
END
@BOX8.1
1 => CHECK.OPD.MODE;
@END
@TITLE MTL27.34(3,8)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX1.0
ASS
@BOX2.0
NO ACTION
@BOX3.0
END
@BOX1.1
PROC ASS;
@BOX2.1
::NO ACTION
@BOX3.1
END
@END
@TITLE MTL27.35(3,8)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX1.0
ASS.END
@BOX2.0
NO ACTION
@BOX3.0
END
@BOX1.1
PROC ASS.END;
@BOX2.1
::NO ACTION
@BOX3.1
END
@END
