@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             MTL071
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YMTL071
~S1~M~OMUTL IMPLEMENTATION DESCRIPTION
~S1~M~OSection 7 Version 1
~S1~OSection 7.1 Code Planting~
~S1~O1. General Description~
~BThis module implements procedures which cater for the code
planting requirements of both compilers
(via the TL procedures) and other machine dependent
MUTL modules (via interface procedures).~
~S1~O2. Interfaces~
~
Other modules used:~
   Section  1 :   (Type Definitions)~
   Section  3 :   (Storage Declarations)~
   Section  4 :   (Literal Declarations)~
   Section  5 :   (Program Structure Declarations)~
   Section  6 :   (Label Declarations)~
   Section 18 :   (Symbol Management)~
   Section 19 :   (Fault Monitoring)~
   Section 23 :   (Storage Allocation)~
   Section 27 :   (Computational Code Generation)~
   Section 28 :   (Control Code Generation)~
~
MUTL Procedures:~
   TL.PL~
   TL.D.TYPE~
   TL.CHECK~
   TL.INSERT~
   TL.CYCLE~
   TL.REPEAT~
   TL.CV.CYCLE~
   TL.CV.LIMIT~
   TL.REG~
~
Interface Procedures:~
   CODE()~
   JUMP.RND()~
   CHECK.JUMP.RND()~
   LOAD.B()~
   INIT.7()~
   REGS()REGISTER.INFORMATION~
~
Interface Data Structures:~
   CALL.S~
   CALL.I~
~
Interface Types:~
   CALL.E~
~
Configuration Parameters:~
   STK.Z~
   CALL.Z~
   B.Z.T~
   INST.SEQ.Z~
   A.SIZ~
   A.SIZ.Z~
   D.SIZ~
   D.SIZ.Z~
   E.SIZ~
   G.SIZ.Z~
   INIT.B.TYPE~
   B.MODE~
   EXT.OPD.TYPES~
   EXT.OPD.TYPES.Z~
   REGISTERS~
   REGISTERS.Z~
   EXT.REGISTERS~
   EXT.REGISTERS.Z~
   BIT.MODE.T~
   MODE.T~
   MASK.T~
   FN.T~
   BASE.Z~
   AL.T~
~S1~O2.1 Hardware Interface~
~BAny machine.
~S1~O2.2 Software Interface~
~S11) CODE()
~BTL.PL does not generate code immediately, it collects together
an instruction sequence in the vector INST (see 3.2).
Calling CODE causes these instructions
to be passed, as one or more instruction sequences, to PLANT
of section 27 which then generates code.
~BCODE is called at the following points:~
~
   a) before a label definition,~
   b) before a control transfer instruction,~
   c) whenever INST is full.~
~S12) JUMP.RND()
~BMUTL ensures that procedures or vectors embedded in the
code are not entered inadvertently. This procedure is
called to plant a jump around
a procedure or an incode vector. When several procedures and
vectors occur at the same textual level with no intervening
code between them, a single jump is planted around them.
~S13) CHECK.JUMP.RND()
~BThis procedure is called by other MUTL procedures to
determine if the next instruction is the first after an
embedded procedure or incode vector. If it is a label is generated
and the jump instruction for the embedded procedure or
vector completed.
~S14) LOAD.B()~
~BThis procedure is called to load the B register.~
~S15) INIT.7()~
~BThis procedure is called to initialise code generation.~
~S16) REGS()REGISTER.INFORMATION
~BThis procedure yields status information about the MUTL registers.
The result is encoded as follows:~
~T# 13
~
Bit  0 - 1~IB register in use~
     1 - 1~IA register in use~
     2 - 1~ID register in use~
Bits 4 - 6~
Bit  7 - 9~IIf the A register is in use then these
fields are set to the T and Z part of the
OP.CODE field in the type INST.SEQ.E (see Section 27) to the values they
would have for an A register instruction at this point.~
~S17) CALL.S~
~BThis is stack for maintaining information pertinent to code generation
of procedure calls. It is a stack of entries of type
CALL.E (see 9 below).
Entries are normally added on processing the call of TL.PL for
STK.L or STK.LB and removed on processing their corresponding
call of TL.PL for ENTER,
however for the STK.L and ENTER of an interpretive
call sequence CALL.S is not updated.
~S18) CALL.I~
~BThis variable indexes the entry on top of the CALL.S stack.
A value of -1 indicates an empty stack. Note that for an interpretive
call sequence CALL.I has a -1 value.
~S19) CALL.E~
~BThis is the type of the entries on the CALL.S stack. The type
contains the following fields.~
~
   :CALL.K  This is bit coded.~
        Bit 0 = 0  Normal procedure call, i.e.~
                   STKL used in call sequence.~
        Bit 0 = 1  Library procedure call with STKLB~
                   used in call sequence. Note that~
                   library procedure are also called with~
                   this bit 0 = 0 when a MUTL name represents~
                   the library procedure specification.~
        Bit 1 = 0  Procedure has no result.~
        Bit 1 = 1  Procedure has a result.~
        Bit 2 = 1  Call of a V-store procedure.~
        Bits 3,4 = 1 Procedure variable call where variable~
                     has no context. Procedure variable call~
                     where variable has context.~
   :RES  This field is of type OP.TYPE.E (imported from Section 27)~
         containing operand information about the result.~
   :CALL.PROC  This is a union of the fields~
        :PR.PTR  Pointer to the procedure property entry associated~
                 with the call.~
        :PAR.PTR Pointer to properties of next parameter to be~
                 stacked.~
        or~
        :FIND.N.I   FIND.N index of library procedure.~
        :RESULT     Result type encoded as a MUTL type.~
   :LL.CALL This field is for maintaining machine dependent~
            information concerned with procedure calls. Its~
            type LL.CALL.E is imported from section 27.~
~S110) STK.Z~
~BThis literal specifies the maximum number of entries permitted
on the STK.S stack (see 3.2 of this section).~
~S111) CALL.Z
~BThis literal specifies the maximum number of entries permitted
on the CALL.S (see 7 above) stack.~
~S112) B.Z.T
~BThis vector contains three elements, one for 8 bit,
16 bit and 32 bit B register precisions.  An element specifies
the Z component of the OP.CODE of the type INST.SEQ.E
(Section 27) for B instructions.
~S113) INST.SEQ.Z~
~BThis literal specifies the number of elements in the
instruction vector INST (see 3.2).
~S114) A.SIZ~
15) A.SIZ.Z~
~BA.SIZ is a data vector which when indexed by Z of the OP.CODE
(see Section 27) field of type INST.SEQ.E for an A opcode,
where the A is in an arithmetic mode, yields the
size of the A register. A.SIZ.Z is
a literal that specifies the number of elements in A.SIZ.
~S116) D.SIZ~
17) D.SIZ.Z~
~BThis is a data vector which when indexed by Z of the OP.CODE
field of type INST.SEQ.E for an A opcode, where the A is in a
pointer mode, yields the size
of the A register.
D.SIZ.Z is a literal that specifies the number of elements in D.DIZ.
~S118) E.SIZ~
19) E.SIZ.Z~
~BThis is a data vector which when indexed by Z of the OP.CODE field
of type INST.SEQ.E for an A opcode, where the A is in an extended mode, yields t
he
size of the mode. E.SIZ.Z is a literal that specifies the
number of elements in E.SIZ.
~S120) B.TYPE~
~BThis is a literal that specifies the MUTL type encoding of
B arithmetic, e.g. for 16 bit subscript arithmetic use
~X %+
%44, and for 32 bit arithmetic use %4C.
~X %%
~S121) INIT.B.MODE~
~BThis is a literal that specifies the Z, T, R, F
components of the OP.CODE field of type INST.SEQ.E
(Section 27), with F set to zero,
for the initial precision selection of the B register.
~S122) EXT.OPD.TYPES~
23) EXT.OPD.TYPES.Z~
~BThis is a vector containing an entry of a pair of elements
for the non-basic MUTL types of the extended A modes. An entry consists of
the non-basic MUTL type encoding and the value 6.
The vector ends with an entry [0,4]. EXT.OPD.TYPES.Z is a literal
that specifies the number of elements in EXT.OPD.TYPES.
~BTypical encoding would be~
~
~X%| {` }\
~M%83  %6 {Complex}~
~N%108 %6 {Character String}~
~N%0  %4 {End of Table}~
~X%% {{ }}
~S124) REGISTERS~
25) REGISTERS.Z~
~BThis is a vector that enables an appropriate machine register
mode to be selected (i.e. values for Z and T in OP.CODE field of type INST.SEQ.E
)
for the MUTL A register,
it also selects 32 elements of the vector FN.T (see 30) containing
information which relates to the 32 possible opcodes for the A
register in a particular mode. An entry
specifies the set of MUTL A register modes which apply to a
machine register mode, e.g. a 16 bit machine register may support
8 and 16 bit logical and integer arithmetic. An entry
consists of three elements.
The first element specifies
a MUTL type encoding for the MUTL A register mode (e.g.
~X %+
%4C 32 bit integer), thus it specifies the mode as REAL, INTEGER,
LOGICAL and DECIMAL and the maximum size in bytes for the precision of
this mode. In selecting a machine register this vector is searched until
an entry is found that has the correct MUTL A mode and the precision
of the machine register is not less than the precision of the MUTL A
mode. Thus the ordering within the vector is important, e.g. an entry
for an integer 16 bit mode occurs before an entry for an integer 32 bit mode.
~X %%
The second element gives the Z,T,R components of the OP.CODE field
of type INST.SEQ.E for A opcodes in INST (Section 27) when this mode is
selected, while the third selects opcode information,
i.e. the set of function entries (counting from zero) in
FN.T (see 30) are applicable to the mode.
As the first four sets of entries in FN.T relate to other opcode groups
the third element will have a value greater than 3. Note that one
set of opcode information in FN.T may apply to several machine register
modes, e.g. opcode information for integer and logical 8, 16 and
32 bit modes may be identical.
The vector terminates with a [FF,FF,FF] entry.
~BConsider a machine which has hardware support for 16 and
32 integer arithmetic, and 32 and 64 bit real arithmetic, entries
in the table would be as follows:~
~X%| {` }\
~
%84{LOGICAL 16} %9{Z=0,T=LOGICAL,R=A} %4{OPCODE INFORMATION IN FN.T~
                                         ELEMENTS 128 TO 159}~
%44{INTEGER 16} %5{Z=0,T=INTEGER,R=A} %4~
%8C{LOGICAL 16} %29{Z=1,T=LOGICAL,R=A} %4~
%4C{INTEGER 16} %25{Z=1,T=INTEGER,R=A} %4~
%9C{LOGICAL 64} %47{Z=2,T=LOGICAL,R=A} %5{OPCODE INFORMATION IN FN.T~
                                          ELEMENTS 160 TO 191}~
%9C{INTEGER 64} %45{Z=2,T=INTEGER,R=A} %5~
%0C{REAL 32} %21{Z=1,T=REAL,R=A} %6{OPCODE INFORMATION IN FN.T~
                                    ELEMENTS 192 TO 223}~
%1C{REAL 64} %41{Z=2,T=REAL,R=A} %6~
~BThis would normally then be followed by entries for the 6
pointer modes of A and any other arithmetic modes of greater
precision needed.
~BREGISTERS.Z is a literal that specifies the number of elements
in REGISTERS.
~S126) EXT.REGISTERS~
27) EXT.REGISTERS.Z~
~BThis is a vector of entries for selecting machine registers
for the extended modes of the MUTL A register. Each entry consists of three
elements, the first gives the MUTL type encoding of the mode for
the A register, the second gives the Z, T, R and F fields with F set to zero of
the OP.CODE
for A instructions in INST
(Section 27) when this A mode is currently selected,
and the third gives opcode information, i.e. the set of function
entries in FN.T (see 30) which are applicable to the mode.
The vector terminates with a [0,0,0] entry.
~BTypical encodings would be:~
~
~M%108 %320 7 {Complex}~
~N%83  %720 9 {Character String}~
~N%0   %0   0 {End of Table}~
~X%% {{ }}
~BEXT.REGISTERS.Z is a literal that specifies the number of
elements in EXT.REGISTERS.
~S128) MODE.T~
~BThis is a datavector which when indexed by a basic MUTL type
encoding -->2 yields information about the type.
Bits 0 - 2 of the datavector elements specify the T
for the A register, and bit 3 specify the size of the type.
~S129) BIT.MODE.T
~BThis is a datavector which when indexed by the bit size
specifier yield (i.e. bits 8 - 11) of a bit sized MUTL basic
type yields the size of the type in bits 3 - 5.
~S130) MASK.T~
~BThis vector is indexed by a basic MUTL type encoding ->> 2 to
yield information used to generate an
accumulator mask. When the size
of the machine register implementing
the MUTL A register is of greater precision than necessary,
on certain opcodes it is necessary to mask
the contents of the machine A register. This vector contains
~X%|
shift factors S such that %F(16) ->> S yields the appropriate mask
~X%%
which when 'anded' with the A register sets unwanted high order
bits to zero.
~S131) FN.T~
~BThis vector gives information, some of which is machine dependent, about
every possible MUTL opcode. Entries are grouped
into sets of 32. The ordering of these groups is important.
The first 4 groups are:~
~X{* }+
~
~MB opcodes {0 - 31}                ~
~NA in generic mode opcodes {32 - 63}~
~NOrganisational opcodes {64 - 95}~
~ND opcodes {96 - 127}~
~X {{ }}
~BThe remaining groups specify information for the supported A register
modes. The number of modes supported varies between MUTL implementations.
The vector REGISTER refers to FN.T, thus the order of the remaining group
must be done in conjunction with defining REGISTERS.~
~
The encoding rules for an element are:~
~T# 12
~
Bit 0, 1~IThese bits specify register use information~
    0~IRegister information not applicable~
    3~IIllegal function~
~X {* }?
    1~ISet opcode {A and B only} register in use after this opcode~
~X {{ }}
    2~INote opcode register (A and B, for A and B opcodes,~
            T registers for organisational opcodes)~
           not in use after this opcode~
Bit 2 = 1~IOperand has normal decoding rules~
Bit 3 = 1~ISet T in use after this opcode~
Bit 4 = 1~IFor B opcodes it means add into B any
held back constants~
Bits 5, 6~IOn some machines where the actual register is
of greater precision
than the MUTL A register, it is necessary to apply a mask to remove
high order bits from the register for some opcodes. This module generates
appropriate mask instructions by setting bits 5 and 6 accordingly.~
Bit 5 = 1~IThis means plant a mask instruction for A opcodes with
non literal operands.~
Bit 6 = 1~IThis means plant a mask instruction for A opcodes with literal
operands.~
~
Note that for most MUTL implementations the encodings for the first
four groups is as specified in MTL201.~
~S132) BASE.Z
~BThis literal specifies the maximum number of MUTL base registers.
~S133) AL.T
~BThis vector indexed by the size in bytes of a basic
type yields the allignment requirement for scalars and
vectors of this type.
~S1~O3. Implementation.
~S1~O3.1 Outline of Operation~
~BIn TL.PL processing of operands and opcodes is separated.
The procedure OP handles the operand and the procedures B.FN,
A.FNS, C.FNS and O.FNS handle the opcodes. The above utilise a
set of subprocedures, their specifications are as follows:~
~S11) ADD.INST(OP.CODE,REG.SPEC,OPD.KIND,PTR TO OPERAND ENTRY)~
~BThis procedure adds an entry to the instruction sequence vector.
A nil pointer to an operand means that the operand part has already
been set or there is no operand part.
~S12) LOAD.D(OP.CODE)~
~BThis procedure loads the D register. OP.CODE is set as follows.~
~
   2 = Load pointer into D at location currently addressed by D.~
   3 = Load address information of location currently addressed~
       into D.~
~S13) LOAD.D.OP(PTR.TO.OPERAND.ENTRY)~
~BThis loads held back D[] information into the operand entry
specified by P1 of an instruction sequence entry.
~S14) LOAD.OP.TYPE(TYPE,PTR.TO.TYPE.E,DIMENSION,ELEMENT.SELECTED,~
   PTR.TO.OP.TYPE.E)~
~BThis procedure loads operand type information
for the data item described by P1, P2, P3 and P4
into an operand entry specified by P5.
~BThe algorithm for passing the instruction sequence to PLANT
is worthy of discussion. The procedure CODE inspects the code sequence
in a sequential manner to determine if there is any interference between
operands, if there is, then the portions of the sequence are passed to
PLANT so that in each such portion there is no interference between
the operands contained. The algorithm employed splits operand accesses
into the following four groups:~
~T# 6
~
  1.~IDirect Reference (i.e. all accesses but assignments) to a
datastructure component.~
  2.~IDirect Assignments to a datastructure component.~
  3.~IAs 1, but indirect (i.e. datastructure is accessed via
dereferencing a pointer).~
  4.~IAs 2, but indirect.~
~
The algorithm then applies the following four rules on portions of the code
sequence passed to PLANT:~
~
  a.~IIt will not contain any operand accesses after an indirect
assignment to a datastructure component.~
  b.~IAfter a direct assignment to a datastructure component it will
neither contain an indirect access of a datastructure component nor
a direct reference to the same datastructure component.~
  c.~IAfter a direct reference to a datastructure component it will
neither contain an indirect assignment to a datastructure component
nor a direct assignment to the same datastructure component.~
  d.~IAfter an indirect reference to a datastructure component it will
not contain an assignment to any operand.~
~
~IThe algorithm is implemented by a decision table approach.~
~BThe decision whether to include an instruction in a portion is based
on the kinds of operand accesses already in the portion and the operand access o
f
the instruction under consideration for including in the portion, thus
there are 64 decisions catered for. These are encoded in the table
ACTION.T. Table STORE.T is accessed to determine whether the instruction
involves an operand assignment or reference. The vector STAT.OPD contains
a list of operands directly accessed by the portion.
~S1~O3.2 Data Structures~
~BINST is a vector of type INST.SEQ.E (imported from Section 27)
and it holds a sequence of instructions held back awaiting code
generation. The variable INST.I is an index into INST of the next
available element.~
~
B.ST.B gives the current status of the contents of B. It is
encoded as follows:~
~
   Bit 0 - A value of one means the B register has been loaded.~
   Bit 1 - A value of one means that the constant in B.CONST~
           has been held back.~
   Bit 2 - Select element is still operative on contents of~
           B register.~
~
The following variables specify the status of the current
operand address.~
~
D.BASE.ST, D.BASE.N, D.OFFSET, D.FLD.P, D.TYPE, D.MODE, D.TYPE.P, D.DIM and~
D.ELEM.FL.~
~
D.BASE.ST specifies where the origin of the address calculation is~
~T% 6
~
 0 -
~ID.BASE.N is the MUTL name of a data structure. The operand
is contained within this item.~
~
 1 -
~ID.BASE.N is the MUTL name of a pointer variable which
references a data structure containing the operand.~
~
 2 -
~IThe D register references a data item containing the operand.~
~
 3 -
~ID.BASE.N is the MUTL name of a select variable which references
a data structure containing the operand.~
~
 4 -
~ID.BASE.N is the MUTL name of a V-store variable.~
~
-1
~INo active address calculation.~
~
D.BASE.P This is of ORIG.E type (imported from Section 27)
and it contains property entry pointer for variable (data,
V-store or select) D.BASE.N.~
~
D.OFFSET specifies a byte offset to a scalar or vector
field within the data structure. The operand addressed is
the scalar field, the vector or an element of the vector.~
~
D.MODE is set whenever the D register is loaded and it contains
the Z, T and R fields for subsequent D instructions.~
~
D.TYPE, D.TYPE.P, D.DIM and D.ELEM.F specify type and
'access' information of the addressed operand. For
an operand which is a scalar field within a data structure
then D.DIM and D.ELEM.F are zero. Whereas for operands which
are vectors or elements of vectors D.DIM gives the dimension
of the vector, note that a D.DIM of -1 means the dimension is
in the pointer referencing the data structures. A value of one
in D.ELEM.F means the operand is a vector element. D.TYPE and
D.TYPE.P give operand type information. For basic type operands
then D.TYPE contains the basic type and D.TYPE.P is a nil pointer.
For non-basic types then D.TYPE is 0, 1 or 3 and this indicates
whether the operand is of a type as specified D.TYPE.P or a
pointer to data item of type D.TYPE.P. D.TYPE.P contains a
pointer to the associated type property entry.~
~
REG.USE specifies the registers that have been requested to
be retained (by calling TL.REG) after the next TL.PL call.
Encoded as in TL.REG.~
~
REG.ST gives the status of the MUTL registers as follows~
~
~MBit 0 - 1  B in use~
~NBit 1 - 1  A in use
~NBit 2 - 1  D in use
~NBit 3 - 1  T in use~
~
Wherever a typeless pointer is loaded into the D register it is
assigned a type as specified by the last call to TL.D.TYPE.
UND.D.TYPE, UND.D.TYPE.P and UND.D.DIM hold the parameters of the last call to
TL.D.TYPE.~
~
MC.A.MODE gives machine dependent register mode of the MUTL
A register. It contains the Z, T, R and F components, with F set to zero, of the
 OP.CODE field of
the INST.SEQ.E type.
MC.FN.CLASS to a number indicating what class of
functions are alowed for this register.
ARRAY.TYPE.DIM holds the dimension associated with the
accumulator when its mode is array type.~
~
CUR.A.MODE contains the current mode of the MUTL A register
as a MUTL type encoding.~
~
STK.S is a stack of the types of operands stacked by TL.PL(%43,register)
calls. STK.I indexes the next available entry on the stack. An
entry contains the following fields.~
~
   :STK.K  Zero if A, B register stacked, one if D stacked~
   :STK.OP Union field, alternatives are~
       :AB Field of type OP.TYPE.E used when A,B stacked~
     or~
       :SD.TYPE, SD.TYPE.P, SD.DIM, SD.ELEMF, SD.MODE holds values~
        of D.TYPE, D.TYPE.P, D.DIM, D.ELEMF, D.MODE for stacked items.~
       :RESULT  Result type.~
~
BASE.T is a tale which when indexed by a MUTL Base
register number yields an entry which is encoded as
follows~
~
   Bit 8-0(1)  Base register loaded with address of~
               MUTL segment (stack frame).~
   Bits 0-7    MUTL segment number or textual level~
               number.~
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H                MTL071
~V9 -1
~F
@TITLE MTL07(1,10)
@COL 1S-2R-3R-4R
@COL 5R-7F
@ROW 3-5
@FLOW 1-2-3-4-5-7
@BOX 1.0
SECTION 7
CODE PLANTING
@BOX 2.0
EXTERNAL ENVIRONMENT
AND MODULE HEADING
@BOX 3.0
TYPE DECLARATIONS
@BOX 4.0
VARIABLE AND LITERAL
DECLARATIONS
@BOX 5.0
PROCEDURE DECLARATIONS
TL PROCEDURES
TL.PL[MTL07.1]
TL.REG[MTL07.2]
TL.D.TYPE[MTL07.3]
TL.CHECK[MTL07.4]
TL.CYCLE[MTL07.5]
TL.REPEAT[MTL07.6]
TL.CV.CYCLE[MTL07.7]
TL.CV.LIMIT[MTL07.8]
TL.INSERT[MTL07.9]
TL.RANGE[MTL07.10]
OTHER INTERFACE PROCEDURES
CODE[MTL07.20]
JUMP.RND[MTL07.21]
CHECK.JUMP.RND[MTL07.22]
CODE.CHECKS[MTL07.23]
INIT.7[MTL07.24]
ADD.B.CONST[MTL07.25]
REGS[MTL07.26]
INTERNAL PROCEDURES
ADD.INST[MTL07.30]
LOAD.OP.TYPE[MTL07.33]
B.L.OPD[MTL07.34]
PR.OP[MTL07.35]
LOAD.D[MTL07.36]
LOAD.D.OP[MTL07.37]
ENTER.V.PROC[MTL07.38]
@BOX 7.0
END
@BOX 1.1
@BOX 2.1
#MTL07/1
;MODULE(INIT.7,TL.PL,TL.REG,TL.D.TYPE,TL.CHECK,TL.INSERT,TL.CYCLE,
 TL.REPEAT,TL.RANGE,TL.CV.CYCLE,TL.CV.LIMIT,CODE,JUMP.RND,CHECK.JUMP.RND,
 CALL.E,CALL.S,CALL.I,CALL.PROC.E,CODE.CHECKS,REGS);
@BOX 3.1
;TYPE CALL.PROC.E IS
    ADDR PAR.E  PAR.PTR
    ADDR PROC.E  PR.PTR 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
;TYPE STK.OP.E IS
    OP.TYPE.E A.B OR
    $LO S.D.TYPE,S.D.ELEM.F
    ADDR TYPE.E S.D.TYPE.P
    ADDR S.D.DIM
   $LO16 SD.MODE
;TYPE STK.E IS
    $LO8 STK.K
    STK.OP.E STK.OP
@BOX 4.1
;*GLOBAL 9
;ADDR D.DIM,UND.D.DIM,D.OFFSET,B.CONST,ARRAY.TYPE.DIM
;$IN INST.I,D.MODE,B.ST.B,D.BASE.ST,D.BASE.N,D.TYPE,D.ELEM.F
;ADDR FIELD.E D.FLD.P
;ADDR TYPE.E D.TYPE.P,CUR.A.TYPE.P,UND.D.TYPE.P
;INST.SEQ.E[INST.SEQ.Z]INST
;$IN REG.USE,REG.ST,UND.D.TYPE,STK.I,CUR.A.MODE,MC.A.MODE,MC.FN.CLASS
;$IN FORCE.MASK,CALLI,B.MODE
;ORIG.E D.BASE.P
;OPD.E CUR.OPD
;$LO64 ACC.MASK.LS, ACC.MASK.MS
;CALL.E[CALL.Z] CALLS
;STK.E[STK.Z] STK.S
;$LO16[BASE.Z] BASE.T
;$IN REG.OPD, OLD.REG.ST, FN.INFO
;ADDR PROC.E V.W
;*GLOBAL 0
;LITERAL TYPELESS.REG = %220
;LITERAL/ADDR PROC.E NIL.PROC =
;LITERAL/ADDR OPD.E NIL.OPD =
;LITERAL/ADDR FIELD.E NIL.FLD =
;LITERAL/ADDR TYPE.E NIL.TYPE =
;LSPEC TL.PL($IN,$IN)
;LSPEC TL.D.TYPE($IN,ADDR)
;LSPEC TL.CHECK($IN)
;LSPEC TL.INSERT($IN)
;LSPEC TL.CYCLE($IN)
;LSPEC TL.REPEAT()
;LSPEC TL.CV.CYCLE($IN,$IN,$IN)
;LSPEC TL.CV.LIMIT($IN)
;LSPEC TL.REG($IN)
;LSPEC TL.RANGE($IN,$IN,$IN,$IN)
;PSPEC CODE()
;PSPEC JUMP.RND()
;PSPEC CHECK.JUMP.RND()
;PSPEC CODE.CHECKS()
;PSPEC INIT.7()
;PSPEC ADD.B.CONST()
;PSPEC ADD.INST($IN,$IN,$IN,ADDR OPD.E)
;PSPEC LOAD.OP.TYPE($IN,ADDR TYPE.E,ADDR,$IN,ADDR OP.TYPE.E)
;PSPEC B.L.OPD($IN,ADDR TYPE.E)
;PSPEC PR.OP($IN)/$IN
;PSPEC LOAD.D($IN)
;PSPEC LOAD.D.OP(ADDR OPD.E)
;PSPEC ENTER.V.PROC(ADDR PROC.E)
;PSPEC REGS()/$IN
@BOX 5.1
::PDP;*CODE 4;
#MTL07.1
#MTL07.2
#MTL07.3
#MTL07.4
#MTL07.9
#MTL07.10
::PDP;*CODE 1;
#MTL07.20
#MTL07.21
#MTL07.22
#MTL07.23
::PDP;*CODE 4;
#MTL07.30
#MTL07.33
#MTL07.34
#MTL07.35
#MTL07.36
#MTL07.37
#MTL07.38
::PDP;*CODE 5;
#MTL07.5
#MTL07.6
#MTL07.7
#MTL07.8
::PDP;*CODE 3;
#MTL07.24
#MTL07.25
#MTL07.26
@BOX 7.1
*END
@END
@TITLE MTL07/1(1,12)
@COL 1S-2R
@COL 6R-3R-4R-5F
@FLOW 1-2-6-3-4-5
@BOX 1.0
EXTERNAL
ENVIRONMENT
@BOX 2.0
TYPES
@BOX 3.0
VARIABLES &
LITERALS
@BOX 4.0
PROCEDURES
@BOX 5.0
END
@BOX 6.0
MORE TYPES
@BOX 1.1
::EXTERNAL
::ENVIRONMENT
@BOX 2.1
;IMPORT LITERAL FRAME.AREAS
;IMPORT TYPE SEL.ADDR.TY,L.128.E,LL.CALL.E,STORE.ADDR.TY
;IMPORT TYPE LAB.ADDR.TY,VAR.UNDEF.TY,PROC.ADDR.TY
;TYPE FIELD.E;
;TYPE TYPE.E IS
   ADDR FIELD.E TYPE.FIELD.P
   $LO8 TYPE.AL, TYPE.FL
   $LO16 TYPE.Z, TYPE.LIB, TYPE.NAME
;TYPE STORE.E;
;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 PAR.E IS
   ADDR PAR.E N.PAR.P
   $LO8 PAR.TYP
   ADDR  PAR.DIM
   ADDR  TYPE.E  PAR.TYP.P
   ADDR VAR.E PAR.REF.V.P, PAR.VAL.V.P
;TYPE PROC.ENTRY.TY IS
   PROC.ADDR.TY PROC.ADDR OR
   $LO32 PROC.FIND.N
;TYPE PROC.E IS
   $LO8 PROC.NAT
   $LO8 PROC.RES.TYP
   $LO8 PROC.INFO
   ADDR PAR.E PROC.PAR.P
   ADDR TYPE.E PROC.RES.TYP.P
   PROC.ENTRY.TY ENTRY
;TYPE 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 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
   ADDR V.STORE.DIM $LO16 V.STORE.TYPE
   $LO8 V.KIND
   V.E V
;TYPE SEL.B.E IS
   $LO16 SEL.BASE,SEL.ALT,SEL.FIELD
;TYPE LAB.E IS
   $LO8 LAB.USE,LAB.TX
   LAB.ADDR.TY LAB.ADDR
;TYPE ORIG.E IS
   ADDR VAR.E VAR OR
   ADDR VAR.E PTR OR
   ADDR SEL.E SEL OR
ADDR V.STORE.E V.ST
;TYPE OP.TYPE.E IS
   $LO SIZ
   $LO8 MOD, AL
   ADDR DIM
;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
;TYPE TX.E IS
   $LO16 TX.PROC.N
   $LO8 TX.STATUS,TX.BASE
   STORE.E[FRAME.AREAS] TX.FRAME
;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
   ADDR INDEX.C
   $LO8 INDEX.B
   OP.TYPE.E TYP
   OR ADDR V.STORE.E V.STOR
   OR ADDR SEL.E SEL.VAR
   OR OP.TYPE.E LIT.TYP
   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
      ADDR B.L.C
   OP.TYPE.E B.L.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
@BOX 6.1
;TYPE INST.SEQ.E IS
   $LO16 OP.CODE
   $LO8 REG.SPEC
    $LO8 OPD.KIND
   OPD.E OPD
;TYPE FIELD.E IS
   ADDR FIELD.E NEXT.FIELD.P
   $LO16 FIELD.POS, FIELD.TYPE
   ADDR TYPE.E FIELD.TYPE.P
   $IN FIELD.TAG
   ADDR  FIELD.DIM
@BOX 3.1
;IMPORT LITERAL CALL.Z,AL.T.Z,C.ABS.A.MODE,STK.Z,INIT.B.MODE,ESIZ.Z
;IMPORT LITERAL INST.SEQ.Z,SEG.Z,TX.Z,BASE.Z
;IMPORT LITERAL REGISTERS.Z,EXT.REGISTERS.Z
;IMPORT LITERAL DSIZ.Z,EXT.OPD.TYPES.Z,ASIZ.Z,FNT.Z
;$LO8[REGISTERS.Z] REGISTERS
;$LO8[64] MASK.T
;$LO8[64] MODE.T
;$LO8[32] BIT.MODE.T
;$LO16[EXT.REGISTERS.Z] EXT.REGISTERS
;$LO16[EXT.OPD.TYPES.Z] EXT.OPD.TYPES
;$LO8[3] B.Z.T
;$LO8[DSIZ.Z] D.SIZ
;$LO8[ASIZ.Z] A.SIZ
;$LO8[ESIZ.Z] E.SIZ
;$LO8[ALT.Z] AL.T
;$LO8[FNT.Z]FN.T
;STORE.E[SEG.Z] SEG.T
;TX.E [TX.Z] TX.S
;$LO64[2] CUR.LIT
;ADDR [$LO64] USE.LIT.P
;ADDR VAR.E CUR.VAR.P
;ADDR C.TYPE.Z
;$IN PROC.STATUS,TL.M,BLK.I,CMP.MODE, CHK.IN
;ADDR TYPE.E CUR.TYPE.P
;ADDR LAB.E CUR.LAB.P,CUR.BLK.LAB
;ADDR V.STORE.E CUR.V.STORE.P
;ADDR PROC.E CUR.PROC.P,CUR.TX.PROC.P
;ADDR SEL.E CUR.SEL.P
;ADDR SEL.B.E CUR.SEL.B.P
@BOX 4.1
::SYS MUTL ;PSPEC B.TL.PL($IN,$IN)
::SYS MUTL ;PSPEC B.TL.D.TYPE($IN,ADDR)
::SYS MUTL ;PSPEC B.TL.CHECK($IN)
::SYS MUTL ;PSPEC B.TL.INSERT($IN)
::SYS MUTL ;PSPEC B.TL.CYCLE($IN)
::SYS MUTL ;PSPEC B.TL.REPEAT()
::SYS MUTL ;PSPEC B.TL.CV.CYCLE($IN,$IN,$IN)
::SYS MUTL ;PSPEC B.TL.CV.LIMIT($IN)
::SYS MUTL ;PSPEC B.TL.REG($IN)
::SYS MUTL ;PSPEC B.TL.RANGE($IN,$IN,$IN,$IN)
::SYS MUTL ;PSPEC C.TL.PL($IN,$IN)
::SYS MUTL ;PSPEC C.TL.D.TYPE($IN,ADDR)
::SYS MUTL ;PSPEC C.TL.CHECK($IN)
::SYS MUTL ;PSPEC C.TL.INSERT($IN)
::SYS MUTL ;PSPEC C.TL.CYCLE($IN)
::SYS MUTL ;PSPEC C.TL.REPEAT()
::SYS MUTL ;PSPEC C.TL.CV.CYCLE($IN,$IN,$IN)
::SYS MUTL ;PSPEC C.TL.CV.LIMIT($IN)
::SYS MUTL ;PSPEC C.TL.REG($IN)
::SYS MUTL ;PSPEC C.TL.RANGE($IN,$IN,$IN,$IN)
;LSPEC CAPTION(ADDR [$LO8])
;LSPEC NEWLINES($IN)
;LSPEC OUTI($IN32,$IN)
;PSPEC B.INENTER($IN)
;PSPEC TYPE.SIZE($IN,ADDR TYPE.E,ADDR,$IN)
;PSPEC GET.KIND($IN)/$IN
;PSPEC PROP.PTR($IN,$IN)
;PSPEC GET.LIT($IN)/$IN
;PSPEC FAULT($IN,ADDR[$LO8])
;PSPEC FAULT.I($IN,$IN)
::VAX;PSPEC TL.C.LIT.32($IN,	$IN32)
;PSPEC TL.PROC.KIND($IN)
;PSPEC PLANT(ADDR[INST.SEQ.E])
;PSPEC REL.REGS($IN)
;PSPEC TYPE.PTR(ADDR  $IN)/ADDR TYPE.E
;PSPEC LABL(ADDR LAB.E)
;PSPEC GOTO(ADDR LAB.E)
;PSPEC STK.LINK()
;PSPEC ENTER()
;PSPEC RETURN(ADDR PROC.E)
;PSPEC INSERT($IN)
;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 RANGE($IN, $IN, ADDR OPD.E, $IN, ADDR OPD.E)
@BOX 5.1
::END
@END
@TITLE MTL07.1(1,9)
@COL 15R
@COL 1S-2R-3R-4T-5R-6T-7R-8T-9R-10R-11R-16T-12R-14F
@COL 17R
@ROW 12-17
@ROW 15-10
@FLOW 1-2-3-4N-5-6N-7-8N-9-10-11-16N-12-14
@FLOW 16Y-17-12
@FLOW 4Y-6Y-15-14
@FLOW 8Y-10
@BOX 1.0
TL.PL(FN,OP)
@BOX 2.0
SUB PROCEDURES
B.FNS[MTL07.1.1]
A.FNS[MTL07.1.2]
ORG.FNS[MTL07.1.3]
CONTRL.FNS[MTL07.1.4]
LOAD.B[MTL07.1.11]
@BOX 3.0
CHECK IF LABEL NEEDED
AFTER EMBEDDED PROCS OR
VECTORS[MTL07.22]
@BOX 4.0
NOT(FIRST INSTRUCTION OF
PROC BODY AND PROC KIND
NOT DEFINED)?
@BOX 5.0
SET PROC KIND[MTL05]
@BOX 6.0
OBTAIN FN INFO
ILLEGAL FUNCTION?
@BOX 7.0
UPDATE REGISTER USE INFO
FOR FUNCTION
@BOX 8.0
FN HAS NON-NORMAL OR
NO OPERAND
@BOX 9.0
PROCESS OPERAND[MTL07.35]
@BOX 11.0
PROCESS ACCORDING TO FN
B FNS[MTL07.1.1]
A FNS[MTL07.1.2]
ORG FNS[MTL07.1.3]
CONT FNS[MTL07.1.4]
@BOX 10.0
UPDATE REGISTER USE INFO
FROM TL.REG SAVED PARAMETERS
@BOX 12.0
RESET TL.REG INFO
@BOX 14.0
END
@BOX 15.0
FAULT "ILLEGAL TL.PL CALL"
PRINT FN AND OP
@BOX 16.0
VSTORE WRITE PROC TO BE CALLED?
@BOX 17.0
CALL V PROC[MTL07.383]
@BOX 1.1
;PROC TL.PL(FN,OP.N)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.PL(FN,OP.N)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.PL(FN,OP.N)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;$IN J
;$IN CUR.OPD.K,CUR.OPD.REG
;$IN REG,T,I
;$IN OP.K
;DATAVEC SET($LO8)
1  2  8  4
END
;DATAVEC RESET($LO8)
%FE  %FD  %F7  %FB
END
@BOX 2.1
;PSPEC BFNS($IN)
;PSPEC AFNS($IN)
;PSPEC CFNS($IN)
;PSPEC OFNS($IN)
;PSPEC LOAD.B()
#MTL07.1.1
#MTL07.1.2
#MTL07.1.3
#MTL07.1.4
#MTL07.1.11
@BOX 3.1
;CHECK.JUMP.RND()
@BOX 4.1
;IF PROC.STATUS & 1 /= 0
@BOX 5.1
;TL.PROC.KIND(0)
@BOX 6.1
;IF FN  ->> 5 & %3 => REG * 32 => J  = 32 THEN
   ;MC.FN.CLASS *32 => J
;FI
;IF FN.T[FN & %1F + J] => FN.INFO & 3 => T = 3
@BOX 7.1
;REG.ST => OLD.REG.ST
;IF T = 1 THEN
   ;SET[REG] !> REG.ST
;ELSE IF T = 2 THEN
   ;RESET[REG] &> REG.ST
;FI FI
;IF FN.INFO & %8 /= 0 THEN
   ;8!> REG.ST
;FI
@BOX 8.1
;NIL.PROC => V.W
;IF FN.INFO & 4 = 0
@BOX 9.1
;PR.OP(OP.N) => CUR.OPD.K
@BOX 11.1
;%FF9F &> FN
;ALTERNATIVE REG FROM
;BFNS(FN)
;AFNS(FN)
;CFNS(FN)
;OFNS(FN)
;END
@BOX 10.1
;REG.USE & %F !> REG.ST
@BOX 12.1
;0 => REG.USE
@BOX 14.1
;END
@BOX 15.1
;FAULT.I(14,FN)
;OUTI(OP.N,10)
@BOX 16.1
;IF V.W /= NIL.PROC
@BOX 17.1
;ENTER.V.PROC(V.W)
@END
@TITLE MTL07.1.1(1,7)
@COL 13C-14T-16T-17R-15R
@COL 1C-2T-3R-4R-5C-6T-7T-8R-9T-10C-11R-12F
@COL 20R
@ROW 9-20
@ROW 13-5
@FLOW 13-14N-16N-17-11
@FLOW 16Y-11
@FLOW 1-2N-3-4
@FLOW 2Y-4
@FLOW 5-6N-7N-8-9N-10-11-12
@FLOW 6Y-20-11
@FLOW 7Y-9Y-15
@FLOW 14Y-15-12
@BOX 1.0
B FNS
@BOX 2.0
NO CONSTANT TO BE ADDED TO B?
@BOX 3.0
LOAD B[MTL07.1.11]
@BOX 4.0
SWITCH ON FN
@BOX 5.0
B =
@BOX 6.0
OP IS D[]
@BOX 7.0
CURRENT D[] INFO
DOES NOT USE B?
@BOX 8.0
ADD D = REF[MTL07.35]
TO INSTR SEQ
@BOX 9.0
RESET B STATUS
OP A CONSTANT?
@BOX 10.0
OTHER FNS
@BOX 11.0
ADD B FN TO
INSTR SEQ[MTL07.30]
@BOX 12.0
END
@BOX 13.0
B +
B -
@BOX 14.0
OP A CONSTANT?
@BOX 15.0
UPDATE HELD BACK
CONSTANT INFO
@BOX 16.0
B LOADED
@BOX 17.0
CHANGE FN TO LOAD
@BOX 20.0
RESET B STATUS
@BOX 1.1
;PROC BFNS(FN)
@BOX 2.1
;IF FN.INFO & %10 = 0
@BOX 3.1
;LOAD.B()
@BOX 4.1
;IF FN = 2,->F7.1.1B5
;IF FN = 8 OR FN = 9,->F7.1.1B13
;->F7.1.1.B10
@BOX 5.1
;F7.1.1B5:
@BOX 6.1
;IF OP.N = %1004
@BOX 7.1
;IF B.ST.B & 5 /= 5
@BOX 8.1
;LOAD.D(3)
@BOX 9.1
;0 => B.ST.B=>B.CONST
;IF CUR.OPD.K = 3
@BOX 10.1
;F7.1.1B10:
@BOX 11.1
;ADD.INST(FN,REG.ST,CUR.OPD.K,^CUR.OPD)
;1 !> B.ST.B
@BOX 12.1
;END
@BOX 13.1
;F7.1.1B13:
@BOX 14.1
;IF CUR.OPD.K = 3
@BOX 15.1
;IF FN /= 9 THEN
   ;USE.LIT.P^[0] +> B.CONST
;ELSE
   ;USE.LIT.P^[0] -> B.CONST
;FI
;2 !> B.ST.B
@BOX 16.1
;IF B.ST.B & 1 /= 0
@BOX 17.1
;IF FN = 8 THEN
   ;2=>FN
;ELSE
   ;1=>FN
;FI
@BOX 20.1
;0=>B.ST.B=>B.CONST
@END
@TITLE MTL07.1.2(1,10)
@COL 14T-15R-16R
@COL 1S-6T-13T-4T-5R-2R-17T-18R-19T-20R-3F
@COL 7R-8C-9C-10R-11C-12R
@ROW 14-4
@ROW 4-7
@FLOW 1-6N-13N-4N-5-2-17N-18-19N-20-3
@FLOW 17Y-19Y-3
@FLOW 6Y-7
@FLOW 13Y-14N-15-16-2
@FLOW 14Y-16
@FLOW 8-2
@FLOW 9-10-2
@FLOW 11-12-2
@FLOW 4Y-2
@BOX 1.0
A FNS
@BOX 2.0
ADD TO INSTR SEQ
[MTL07.30]
@BOX 3.0
END
@BOX 4.0
NOT MFN?
@BOX 5.0
SET UP MFN OPERAND?
@BOX 6.0
A IN PTR MODE
@BOX 7.0
SWITCH ON FN
@BOX 8.0
=,=>
COMP
@BOX 9.0
=REF
@BOX 10.0
SET REF OF OPERAND
REQUIRED
SET FN TO =
@BOX 11.0
BASE,
LIMIT
@BOX 12.0
SET BASE LIMIT OPERAND
[MTL07.34]
@BOX 13.0
A IN ARRAY TYPE
@BOX 16.0
ADJUST OP TYPE
@BOX 14.0
NOT D[] OPERAND
@BOX 15.0
LOAD D[MTL07.35]
LOAD D OP[MTL07.36]
@BOX 17.0
FORCE ACC MASK NOT REQUIRED
@BOX 18.0
ADD INST TO SEQ TO
MASK ACCUMULATOR TO REQUIRED SIZE
@BOX 19.0
NOT COMPLEX ABS
@BOX 20.0
SET AMODE TO REAL
@BOX 1.1
;PROC AFNS(FN)
;ADDR TYPE.E TP
;$IN T
::VAX;BEGIN
::VAX ;1 +> CHK.IN
::VAX;IF MC.FN.CLASS = 9 THEN
::VAX;DATAVEC SFN($LO32)
::VAX?LHS ?RHS ?STR.FN ?MOV
::VAX?STR.FN ?COMP ?STR.FN ?SRCH
::VAX?STR.FN ?LEN ?STR.FN ?COMP
::VAXEND
::VAX;DATAVEC S.RES($LO8)
::VAX0 0 0 0
::VAX0 %4C 0 %4C
::VAX0 %4C 0 %4C
::VAXEND
::VAX;TL.C.LIT.32(%8C,SFN[FN])
::VAX;TL.PL(%48,S.RES[FN])
::VAX;IF FN < 2 THEN
::VAX   ;TL.PL(%46,%83)
::VAX   ;TL.PL(%21,OP.N)
::VAX   ;TL.PL(%41,%3000)
::VAX;FI
::VAX;TL.PL(%42,0)
::VAX;IF FN = 7 OR FN = 9 THEN
::VAX   ;TL.PL(%2,%3000)
::VAX;ELSE IF FN = 5 OR FN = 11 THEN
::VAX   ;TL.C.LIT.32(%4C,0)
::VAX   ;TL.PL(%2F,0)
::VAX;ELSE
::VAX   ;TL.PL(%52,%83)
::VAX;FI FI
::VAX;1 -> CHK.IN
::VAX;EXIT
::VAX;FI
::VAX;END
::VAX#MTL07.1.2.1
::VAX;1 -> CHK.IN
@BOX 2.1
;ADD.INST(MC.A.MODE ! FN ! %20,REG.ST,CUR.OPD.K,^CUR.OPD)
@BOX 3.1
;END
@BOX 4.1
;IF FN /= %12
@BOX 5.1
;15 => CUR.OPD.K
;OP.N => MFN OF CUR.OPD
@BOX 6.1
;IF MC.FN.CLASS=7
@BOX 7.1
;DATAVEC V.FN($LO8)
0 1 0 0 0 0 2 2
0 0 0 0 0 0 0 0
END
;SWITCH V.FN[FN]\
F7.1.2B8,F7.1.2B9,F7.1.2B11
@BOX 8.1
;F7.1.2B8:
@BOX 9.1
;F7.1.2B9:
@BOX 10.1
;IF CUR.OPD.K=0 THEN
   ;%8=>T
   ;IF MC.A.MODE & %400 /= 0 THEN
      ;%10=>T
   ;FI
   ;T !> ORIG.KIND OF CUR.OPD
;FI
;2=>FN
@BOX 11.1
;F7.1.2B11:
@BOX 12.1
;IF CUR.A.MODE & %3FFC => T < 256 THEN
   ;NIL.TYPE => TP
;ELSE
   ;TYPE.PTR(^T)=>TP
   ;0=>T
;FI
;B.L.OPD(T,TP)
;13=>CUR.OPD.K
@BOX 13.1
;IF MC.FN.CLASS = 1 AND ARRAY.TYPE.DIM > 0
@BOX 14.1
;IF OP.N /= %1004
@BOX 15.1
;LOAD.D(3)
;LOAD.D.OP(^CUR.OPD)
@BOX 16.1
;ARRAY.TYPE.DIM *> SIZ OF TYP OF CUR.OPD
;0 => DIM OF TYP OF CUR.OPD
@BOX 17.1
;IF FN.INFO & %60 = 0 OR FORCE.MASK = 0
      OR [FN.INFO & %40 = 0 AND CUR.OPD.K = 3]
@BOX 18.1
;LOAD.OP.TYPE(CUR.A.MODE,NIL.TYPE,0,0,^LIT.TYP OF CUR.OPD)
;ACC.MASK.LS => VAL.LS OF LIT OF CUR.OPD
;ACC.MASK.MS => VAL.MS OF LIT OF CUR.OPD
;ADD.INST(MC.A.MODE ! %24,REG.ST,3,^CUR.OPD)
@BOX 19.1
;IF FN /= %12 OR OP.N /= 0 OR MC.FN.CLASS /= 8
@BOX 20.1
;TL.PL(%46, C.ABS.A.MODE)
@END
@TITLE MTL07.1.2.1(1,7)
@COL 19N-20R-21R-22N
@COL 1S-3T-4R-5T-6T-7R-8T-9R-10R-11T-12R-13R-14T-15T-16R-17R-18F
@COL 2R-23R-24T-25N
@ROW 2-4
@ROW 19-3
@ROW 20-9-23
@ROW 16-24
@ROW 21-16
@FLOW 1-2-3N-4-5N-6N-7-8N-9-10-11N-12-13-14N-15N-16-17-18
@FLOW 3Y-19-22-18
@FLOW 5Y-10
@FLOW 6Y-20-10
@FLOW 8Y-23-10
@FLOW 11Y-13
@FLOW 14Y-21-17
@FLOW 15Y-24N-25-18
@FLOW 24Y-17
@BOX 1.0
COMPLEX FNS FOR VAX
THIS CHARTS IMPLEMENTS COMPLEX BY CALLING FUNCTIONS
FOR ALL COMPLEX OPERATIONS, THUS AVOIDING CHANGES TO THE LOW LEVEL MUTL.
@BOX 3.0
A NOT IN COMPLEX MODE?
@BOX 2.0
DECLARATIONS
@BOX 4.0
SET TYPE AND SIZE OF OPERAND
@BOX 5.0
STORE
@BOX 6.0
MFN
@BOX 7.0
DETERMINE OPERAND CONVERSION NEEDED
@BOX 8.0
NO CONVERSION REQUIRD
@BOX 9.0
LOAD OPERAND AND CONVERT TO COMPLEX
@BOX 10.0
PLANT STKLINK
@BOX 11.0
STORE OR MFN?
@BOX 12.0
PLANT STACK A
@BOX 13.0
PLANT ENTER
@BOX 14.0
STORE
@BOX 15.0
NOT COMPARE
@BOX 16.0
PLANT A COMP 0
@BOX 17.0
RESET MODE TO COMPLEX
@BOX 18.0
END
@BOX 20.0
SET UP INDEX FOR MFN
@BOX 21.0
PLANT A => OPEREANSD
@BOX 23.0
LOAD COMPLEX AS USER DEFINED ITEM
@BOX 24.0
NOT CABS?
@BOX 1.1
;BEGIN
@BOX 2.1
;$IN CX.FN, OP.TY, T
;$LO32 L
;ADDR OP.TYPE.E TY
;DATAVEC CX.FNS($LO32)
?CX.STORE ?CX.NEG.LOAD ?CX.LOAD ?CX.LOAD.R
?CX.LOAD.I 0 0 0
?CX.ADD ?CX.MIN ?CX.R.MIN ?CX.MULT
?CX.DIV ?CX.R.DIV 0 ?CX.COMP
?CX.ABS ?CX.CONJG 0 ?CX.SQRT
?CX.SIN ?CX.COS ?CX.LOG ?CX.EXP
0 0 0 0
0 0 0 ?CXPOWER
END
@BOX 3.1
;IF MC.FN.CLASS /= 8
@BOX 4.1
;IF CUR.OPD.K = 0 THEN
   ;^TYP OF CUR.OPD => TY
;ELSE IF CUR.OPD.K = 3 THEN
   ;^LIT.TYP OF CUR.OPD => TY
;ELSE IF CUR.OPD.K = 8 THEN
   ;1 +> STK.I ::OP PROCESSING CALLED TWICE
   ;^UNSTK OF CUR.OPD => TY
;FI FI FI
@BOX 5.1
;IF FN => CX.FN = 0
@BOX 6.1
;IF FN = %12
@BOX 7.1
;0 => T
;SIZ OF TY^ <<- 4 ! MOD OF TY^ => OP.TY
;IF OP.TY = %41 THEN
   ;%4C => T ;?I.CX => L
;ELSE IF OP.TY = %40 THEN
   ;%0C => T ;?R.CX => L
;ELSE IF OP.TY = %80 THEN
   ;%1C => T ;?DP.CX => L
;FI FI FI
@BOX 8.1
;IF T = 0
@BOX 9.1
;TL.PL(%46, T)
;TL.PL(%22, OP.N)
;TL.C.LIT32(%8C, L)
;TL.PL(%48, %9C)
;TL.PL(%41, %3000)
;TL.PL(%42,0)
@BOX 10.1
;TL.C.LIT32(%8C, CX.FNS[CX.FN])
;IF FN = 0 THEN
  ;%9C => T
;ELSE IF FN = 15 THEN
   ;%4C => T
;ELSE IF CX.FN = 16 THEN
   ;%0C => T
;ELSE
   ;0 => T
;FI FI FI
;TL.PL(%48, T)
@BOX 11.1
;IF FN = 0 OR FN = %12
@BOX 12.1
;TL.PL(%41, %3000)
@BOX 13.1
;TL.PL(%42, 0)
@BOX 14.1
;IF FN = 0
@BOX 15.1
IF FN /= %F
@BOX 16.1
;TL.C.LIT32(%4C, 0)
;TL.PL(%2F, 0)
@BOX 17.1
;8 => MC.FN.CLASS
;%108 => CUR.A.MODE
;%320 => MC.A.MODE
;1 -> CHK.IN
;EXIT
@BOX 18.1
;END
@BOX 20.1
;IF OP.N < 2 THEN
   ;%10 + OP.N => CX.FN
;ELSE
   ;6 + OPN => CX.FN
;FI
@BOX 21.1
;TL.PL(%46, %108)
;TL.PL(%20, OP.N)
@BOX 23.1
;TL.PL(%46, %108)
;TL.PL(%22, OP.N)
;TL.PL(%46, %9C)
@BOX 24.1
;IF CX.FN /= 16
@END
@TITLE MTL07.1.3(1,11)
@COL 1S-3R-4F
@FLOW 1-3-4
@BOX 1.0
CONTROL FNS
@BOX 3.0
PROCESS FN
STK.L,STK.PAR,ENTER,STK.NIL,RETURN[MTL07.1.3.1]
ACONV,AMODE,STACK[MTL07.1.3.2]
CONTROL TRANSFERS[MTL07.1.3.3]
ADDR= [MTL07.1.3.4]
BCONV, BMODE [MTL07.1.3.5]
@BOX 4.0
END
@BOX 1.1
;PROC CFNS(FN)
;$IN OLD,R,T,K,N,NN,B.IN
;ADDR FIELD.E FP
;ADDR PAR.E PAR
;ADDR TYPE.E R.P
@BOX 3.1
;FN ->> 7 => NN <<- 13 => N
;SWITCH FN  & %1F \
F7.1.3.1B2, F7.1.3.1B1, F7.1.3.1B3, F7.1.3.1B4,
F7.1.3.1B36, F7.1.3.2B1, F7.1.3.2B1, F7.1.3.2B2,
F7.1.3.1B2, F7.1.33B1, F7.1.3.3B1, F7.1.3.3B1,
F7.1.3.3B1, F7.1.3.3B1, F7.1.3.3B1, F7.1.3.3B2,
F7.1.3.3B9,F7.1.3.2B14,F7.1.3.2B14,F7.1.3.4B1,
F7.1.3B3, F7.1.3.5B1, F7.1.3.5B1;
#MTL07.1.3.1
#MTL07.1.3.2
#MTL07.1.3.3
#MTL07.1.3.4
#MTL07.1.3.5
;F7.1.3B3:
@BOX 4.1
;END
@END
@TITLE MTL07.1.3.1(1,11)
@COL 2S-15R-5R-16R-17C-36C-37R-38C-3C-34R-18T-19R-20R
@COL 1C-35T-31T-32R-33R-7R-8C-4C-10T-13R-11R-14C-22R-25R-23C
@ROW 2-1
@ROW 3-4
@FLOW 1-35N-31N-32-7-8
@FLOW 31Y-33-7
@FLOW 2-15-5-16-17
@FLOW 3-34-18N-19-20-23
@FLOW 18Y-22-25-23
@FLOW 4-10N-13-11-14
@FLOW 36-37-38
@FLOW 10Y-11
@FLOW 35Y-33
@BOX 1.0
STACK PARAM
@BOX 31.0
STK LB CALL
@BOX 32.0
SET UP OPERAND[MTL07.33]
@BOX 33.0
SET UP OPERAND[MTL07.33]
@BOX 7.0
ADD A/B => STACK PARAM
TO INST SEQ[MTL07.30]
@BOX 8.0
END
@BOX 4.0
RETURN
@BOX 10.0
NO RESULT?
@BOX 11.0
CODE OUTSTANDING INSTR[MTL07.20]
PLANT RETURN[MTL28]
@BOX 13.0
ADD A => RESULT
TO INST SEQ[MTL07.30]
@BOX 14.0
END
@BOX 2.0
STK.L
@BOX 15.0
CODE INST SEQ[MTL07.20]
@BOX 16.0
PLANT STKLINK[MTL28]
@BOX 5.0
ADD ENTRY TO CALL STACK
@BOX 17.0
END
@BOX 3.0
ENTER
@BOX 18.0
OPERAND A VARIABLE
@BOX 19.0
CODE INST SEG
[MTL07.20]
@BOX 20.0
PLANT ENTER[MTL28]
REMOVE CALL STACK ENTRY
@BOX 22.0
PROCESS OPERAND [MTL07.36]
ADD ENTER TO
INST SEQ[MTL07.30]
@BOX 23.0
END
@BOX 25.0
CODE INSTR SEQ[MTL07.20]
REMOVE CALL STACK ENTRY
@BOX 34.0
SET AMODE = FOR RESULT
@BOX 35.0
PARAM OF INTERPRETIVELY
CALLED PROC
@BOX 36.0
STK NIL
@BOX 37.0
ADD STK.NIL TO
INST SEQ
@BOX 38.0
END
@BOX 2.1
;F7.1.3.1B2:
@BOX 15.1
;CODE()
@BOX 16.1
;STK.LINK()
@BOX 5.1
;IF OP.N /= 0 OR FN & %F /= 0 THEN
;BEGIN
;SELECT CALL.S[1+>CALL.I]
;IF FN & %1F = 0 THEN
      ;OP.N ->> 9 & %18 =>CALL.K
      ;PROP.PTR(OP.N & %FFF,6)
      ;PROC.RES.TYP OF CUR.PROC.P^ => R
      ;PROC.RES.TYP.P OF CUR.PROC.P^ => RP
      ;CUR.PROC.P => PR.PTR OF CALL.PROC
      ;PROC.PAR.P OF CUR.PROC.P^ => PAR.PTR OF CALL.PROC
;ELSE
   ;1=>CALL.K
   ;GET.LIT(0)
   ;USE.LIT.P^[0] => FIND.N.I OF CALL.PROC
   ;OP.N => R => RESULT OF CALL.PROC
   ;NIL.TYPE => R.P
;FI
;IF R /= 0 THEN
   ;2 !> CALL.K
   ;LOAD.OP.TYPE(R,R.P,0,0,^RES)
;FI
;END
;FI
@BOX 17.1
;EXIT
@BOX 1.1
;F7.1.3.1B1:
@BOX 7.1
;ADD.INST(REG.OPD,REG.ST ,7,^CUR.OPD)
@BOX 8.1
;EXIT
@BOX 3.1
;F7.1.3.1B3:
@BOX 18.1
;IF OP.N /= 0 AND FN = 2
@BOX 19.1
;CODE()
@BOX 20.1
;IF B.IN < 0 THEN
   ;ENTER()
;ELSE
   ;B.INENTER(B.IN)
;FI
;1->CALL.I
@BOX 34.1
;OP.N=>T
;-1 => B.IN
;IF CALL.I >= 0 THEN
;BEGIN
   ;SELECT CALL.S[CALL.I]
   ;IF CALL.K & 1 = 0 THEN
      ;SELECT PR.PTR^ OF CALL.PROC
      ;IF PROC.RES.TYP => OP.N > 0 OR PROC.RES.TYP.P /= NIL.TYPE THEN
         ;IF PROC.RES.TYP.P /= NIL.TYPE THEN
             ;256+>OP.N
         ;FI
      ;IF OPN = %100 THEN
        ;%108 => OPN
         ;CFNS(%12)
      ;ELSE
         ;CFNS(6)
      ;FI
      ;FI
      ;IF PROC.NAT & 8 /= 0 THEN
         ;1 !> CALL.K
         ;PROC.FIND.N OF ENTRY => FIND.N.I OF CALL.PROC
      ;FI
   ;IF PROC.NAT & %4 /= 0 THEN
      ;PROC.FIND.N OF ENTRY => B.IN
;FI
   ;ELSE
      ;IF RESULT OF CALL.PROC => OP.N /= 0 THEN
         ;CFNS(6)
;     FI
   ;FI
;END
;FI
::VAX;OP.N=>R
;T=>OP.N
@BOX 22.1
;PR.OP(OP.N) => CUR.OPD.K
;ADD.INST(%68,%F,CUR.OPD.K,^CUR.OPD)
@BOX 23.1
::VAX ;IF R= %108 THEN
::VAX   ;1 +> CHK.IN
::VAX   ;TL.CLIT32(%8C, ?CX.LOAD)
::VAX   ;TL.PL(%48, 0)
::VAX   ;TL.PL(%46, %9C)
::VAX   ;TL.PL(%41, %3000)
::VAX   ;TL.PL(%42, 0)
::VAX   ;8 => MCFNCLASS
::VAX   ;%108 => CUR.A.MODE
::VAX   ;%320 => MC.A.MODE
::VAX   ;1->CHK.IN
::VAX;FI
;EXIT
@BOX 25.1
;CODE()
;IF CALL.I >= 0 THEN
   ;1->CALL.I
;FI
@BOX 4.1
;F7.1.3.1B4:
@BOX 10.1
;IF OP.N = 0
@BOX 11.1
;CODE()
;RETURN(CUR.TX.PROC.P)
@BOX 13.1
::VAX;IF MC.FN.CLASS = 8 THEN
::VAX   ;1 +> CHK.IN
::VAX  ;TLCLIT.32(%8C,?CX.STORE)
::VAX  ;TL.PL(%48, %9C)
::VAX  ;TL.PL(%42, %0)
::VAX  ;8 => MC.FN.CLASS
::VAX  ;%320 => MC.A.MODE
::VAX  ;%108 => CUR.A.MODE
::VAX   ;1 -> CHK.IN
::VAX;FI
;ADD.INST(MC.A.MODE,%D &> REG.ST,12,NIL.OPD)
@BOX 14.1
;EXIT
@BOX 31.1
;IF CALL.K OF CALL.S[CALL.I]  & 1 /= 0
@BOX 32.1
;PAR.PTR OF CALL.PROC OF  CALL.S[CALL.I] => PAR
;LOAD.OP.TYPE(PAR.TYP OF PAR^,PAR.TYP.P OF PAR^,
               0,0,^PAR.STK OF CUR.OPD)
;IF PAR.DIM OF PAR^ > 0 THEN
   ;PAR.DIM OF PAR^ *> SIZ OF PAR.STK OF CUR.OPD
;FI
;N.PAR.P OF PAR^ => PAR.PTR OF CALL.PROC OF CALL.S[CALL.I]
@BOX 33.1
;LOAD.OP.TYPE(CUR.A.MODE, NIL.TYPE,0,0,^PAR.STK OF CUR.OPD)
;IF MC.FN.CLASS = 1 AND ARRAY.TYPE.DIM > 0 THEN
   ;ARRAY.TYPE.DIM *> SIZ OF PAR.STK OF CUR.OPD
;FI
@BOX 35.1
;IF CALL.I < 0
@BOX 36.1
;F7.1.3.1B36:
@BOX 37.1
;OP.N => MFN OF CUR.OPD
;ADD.INST(%6B, %F, 15, ^CUR.OPD)
@BOX 38.1
;EXIT
@END
@TITLE MTL07.1.3.2(1,10)
@COL 1S-18R-19T-3R-4T-5R-6C-16R
@COL 20R-21T-22R-14C-15R-2C-8R-9T-12R-13C
@ROW 19-20
@ROW 12-16
@FLOW 1-18-19N-3-4N-5-6
@FLOW 19Y-20-21N-22-21Y-3
@FLOW 14-15-4Y-6
@FLOW 2-8-9N-12-13
@FLOW 9Y-16-12
@BOX 1.0
ACONV
AMODE=
@BOX 3.0
DETERMINE ACTUAL REGISTER
TO USE
@BOX 4.0
MODE ORDER OR SAME REGISTER?
@BOX 5.0
ADD ACONV INSTR[MTL07.30]
@BOX 6.0
END
@BOX 2.0
STACK
@BOX 8.0
NOTE TYPE OF STACKED ITEM
@BOX 9.0
OPERAND B
@BOX 12.0
ADD => STACK INSTR
[MTL07.30]
@BOX 13.0
END
@BOX 14.0
AECONV
AEMODE=
@BOX 15.0
DETERMINE ACTUAL REGISTER
@BOX 16.0
LOAD B[MTL07.1.11]
@BOX 18.0
SAVE OPERAND INFO
@BOX 19.0
USER SCALAR TYPE
@BOX 20.0
OBTAIN TYPE PTR
@BOX 21.0
NOT A REDUCIBLE TYPE
@BOX 22.0
REDUCE TYPE
@BOX 1.1
;F7.1.3.2B1:
@BOX 3.1
;MC.A.MODE => OLD
;IF OP.N & 1 /= 0 THEN
   ;7=>MC.FN.CLASS
   ;IF OP.N & 2 = 0 THEN
      ;%2A0=>MC.A.MODE
   ;ELSE
      ;%6A0=>MC.A.MODE
   ;FI
;ELSE IF OP.N > 255 OR OP.N & 2 /= 0 THEN
   ;TYPE.LESS.REG => MC.A.MODE
   ;1=>MC.FN.CLASS
    ;0 => ARRAY.TYPE.DIM
    ;IF OP.N & 2 /= 0 THEN
        ;CUR.LIT[0] => ARRAY.TYPE.DIM
   ;FI
;ELSE
   ;-3 => I => R
   ;WHILE R /= %FF DO
      ;IF REGISTERS[3+>I] => R /= %FF AND
         R & %C0 = OP.N & %C0 AND
         OP.N & %3C =< R & %3C THEN
         ;REGISTERS[1+I] <<- 5  => MC.A.MODE
            ;REGISTERS[2+I]=>MC.FN.CLASS
            ;%FF => R
      ;FI
   ;OD
  ;IF MASK.T[OP.N ->> 2] => FORCE.MASK => T /= 0 THEN
      ;IF T > 64 THEN
         ;0 => ACC.MASK.MS
         ;64 -> T
         ;%F(16) ->> T => ACC.MASK.LS
      ;ELSE
         ;%F(16) => ACC.MASK.LS ->> T => ACC.MASK.MS
      ;FI
   ;FI
;FI FI
@BOX4.1
;OP.N => CUR.A.MODE
;IF FN & %1 = 0 OR MC.A.MODE = OLD
@BOX 5.1
::VAX#MTL07.1.3.2.1
;MC.A.MODE ->> 7 ! K => A.TYPE OF CUR.OPD
;OLD ->> 7 => OLD.A.TYPE OF CUR.OPD
;ADD.INST(%67,%F,14,^CUR.OPD)
@BOX 6.1
;EXIT
@BOX 14.1
;F7.1.3.2B14:
@BOX 15.1
;OP.N & %C000 ->> 8 => K
;%3FFF &> OP.N
;0 => FORCE.MASK
;MC.A.MODE => OLD
;-3 => I
;WHILE EXT.REGISTERS[3+>I] /= OP.N /= 0 DO OD
;EXT.REGISTERS[1+I] => MC.A.MODE
;EXT.REGISTERS[2+I] => MC.FN.CLASS
@BOX 2.1
;F7.1.3.2.B2:
@BOX 8.1
;BEGIN
;SELECT STK.S[STK.I]
;IF OP.N = %2000 THEN
   ;ASIZ[B.MODE->>10] => SIZ OF A.B OF STK.OP
   ;1 => MOD OF A.B OF STK.OP
   ;0 => DIM OF A.B OF STK.OP
   ;B.MODE => T
   ;REG.ST & %E ! REG.USE => REG.ST
;ELSE IF OP.N = %3000 THEN
   ;MC.A.MODE->>10 =>  R
   ;MC.A.MODE->>7 & 7 => MOD OF A.B OF STK.OP => T
   ;IF T < 5 THEN
      ;ASIZ[R] => SIZ OF A.B OF STK.OP
   ;ELSE IF T = 4 THEN
      ;LOAD.OP.TYPE(CUR.A.MODE,CUR.A.TYPE.P,0,0,^A.B OF STK.OP)
      ;IF ARRAY.TYPE.DIM > 0 THEN
         ;ARRAY.TYPE.DIM *> SIZ OF A.B OF STK.OP
      ;FI
   ;ELSE IF T = 5 THEN
      ;DSIZ[R] => SIZ OF A.B OF STK.OP
   ;ELSE
      ;ESIZ[R] => SIZ OF A.B OF STK.OP
   ;FI FI FI
   ;0 => DIM OF A.B OF STK.OP
   ;MC.A.MODE => T
   ;REG.ST & %D ! REG.USE => REG.ST
::VAX   ;IF MC.FN.CLASS = 8 THEN
::VAX   ;1 +> CHK.IN
::VAX   ;%C20 => T
::VAX   ;TL.CLIT32(%8C,?CX.STORE)
::VAX   ;TLPL(%48,%9C)
::VAX   ;TLPL(%42,0)
::VAX   ;8=>MC.FN.CLASS
::VAX   ;%108=>CURA.MODE
::VAX   ;%320=>MC.A.MODE
::VAX   ;1 -> CHK.IN
::VAX   ;FI
;ELSE
   ;D.TYPE => S.D.TYPE OF STK.OP
   ;D.TYPE.P => S.D.TYPE.P OF STK.OP
   ;D.DIM => S.D.DIM OF STK.OP
   ;D.ELEM.F => S.D.ELEM.F OF STK.OP
   ;D.MODE=>T => S.D.MODE OF STK.OP
   ;LOAD.D(3)
;FI FI
;END
;1+>STK.I
@BOX 9.1
;IF OP.N = %2000
@BOX 12.1
;ADD.INST(T,REG.ST,6,^CUR.OPD)
@BOX 13.1
;EXIT
@BOX 16.1
;LOAD.B()
@BOX 18.1
;NIL.TYPE => CUR.A.TYPE.P
;OP.N & %C000 ->> 8 => K
@BOX 19.1
;IF %3FFF &> OP.N >  255 AND OP.N & 3 = 0
@BOX 20.1
;PROP.PTR(OP.N ->> 2 - 64, 9)
;CUR.TYPE.P => CUR.A.TYPE.P
@BOX 21.1
;IF CUR.A.TYPE.P = NIL.TYPE OR TYPE.FL OF CUR.A.TYPE.P^ & 1 = 0
@BOX 22.1
;TYPE.FIELD.P OF CUR.A.TYPE.P^ => FP
;FIELD.TYPE OF FP^ => OP.N
;FIELD.TYPE.P OF FP^ => CUR.A.TYPE.P
@END
@TITLE MTL07.1.3.2.1(1,7)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
CONVERSIONS INVOLVING COMPLEX ARITHMETIC
THESE CONVERSIONS ARE IMPLEMENTED BY CALLING FUNCTIONS TO
PERFORM THE CONVERSION, THUS AVAOIDING CHANGES TO THE LOW LEVEL MUTL
@BOX 2.0
CODE
@BOX 3.0
END
@BOX 1.1
;BEGIN
;$IN LT
@BOX 2.1
;DATAVEC CX.CONV($LO32)
?CX.I ?CX.R ?CX.DP 0
?I.CX ?R.CX ?DP.CX
END
;DATAVEC CX.CONV.RES($LO8)
 %4C   %C    %1C    0
 %9C   %9C   %9C
END
;IF OLD = %320 OR MC.A.MODE = %320 THEN
   ;1 +> CHK.IN
   ;IF OLD = %320 THEN
      ;0 => T  ;MC.A.MODE => R
   ;ELSE
      ;4 => T  ;OLD => R
   ;FI
   ;IF R = %820 THEN   ::REAL
         ;1 +> T  ;%0C => LT
   ;ELSE IF R = %C20 THEN    ::DP
         ;2 +> T  ;%1C => LT
   ;ELSE
      ;%4C => LT
   ;FI FI
   ;IF T & 4 = 0 AND K /= 0 THEN
         ;TL.C.LIT.32(%8C,?CX.I.TO.R)
         ;TL.PL(%48,%0)
         ;TL.PL(%42,0)
   ;FI
   ;IF T & 4 /= 0 THEN
      ;TL.PL(%46, LT)
   ;FI
   ;TL.C.LIT.32(%8C,CX.CONV[T])
   ;TL.PL(%48,CX.CONV.RES[T])
   ;IF T >= 4 THEN
      ;TL.PL(%41,%3000)
   ;FI
   ;TL.PL(%42,0)
   ;IF T & 4 /= 0 THEN
      ;TL.C.LIT.32(%8C,?CX.LOAD)
      ;TL.PL(%48,0)
      ;TL.PL(%41,%3000)
      ;TL.PL(%42,0)
      ;%8 => MC.FN.CLASS
      ;%320 => MC.A.MODE
      ;OP.N => CUR.A.MODE
   ;FI
  ;1 -> CHK.IN
   ;EXIT
;FI

@BOX 3.1
;END
@END
@TITLE MTL07.1.3.3(1,6)
@COL 1S-3R-4C-9C-10R-2C-5T-8R-6R-7C
@FLOW 1-3-4
@FLOW 2-5N-8-6-7
@FLOW 9-10-5Y-3
@BOX 1.0
CONDITIONAL CONTROL
TRANSFERS
@BOX 3.0
ADD CONTROL INSTR
[MTL07.30]
@BOX 4.0
END
@BOX 2.0
SEG ->
@BOX 5.0
NOT A LABEL OPERAND?
@BOX 6.0
PLANT GO TO LABEL[MTL28]
@BOX 7.0
END
@BOX 8.0
CODE INST SEQ[MTL07.20]
@BOX 9.0
ISEG->
@BOX 10.0
RESET FN
@BOX 1.1
;F7.1.3.3B1:
@BOX 3.1
;ADD.INST(FN-%9 ! %60,REG.ST,CUR.OPD.K,^CUR.OPD)
@BOX 4.1
;EXIT
@BOX 2.1
;F7.1.3.3B2:
@BOX 5.1
;IF CUR.OPD.K /= 4
@BOX 6.1
;GO.TO(LAB OF CUR.OPD)
@BOX 7.1
;EXIT
@BOX 8.1
;CODE()
@BOX 9.1
;F7.1.3.3B9:
@BOX 10.1
;15=>FN
@END
@TITLE MTL07.1.3.4(1,9)
@COL 1S-2R-3T-4R-5F
@FLOW 1-2-3N-4-5
@FLOW 3Y-5
@BOX 1.0
ADDR =
@BOX 2.0
SET UP INSTR OPERAND
AND NOTE BASE RGISTER LOADED
@BOX 3.0
NO LOAD NEEDED
@BOX 4.0
ADD ADDR = INSTR
[MTL07.30]
@BOX 5.0
END
@BOX 1.1
;F7.1.3.4B1:
@BOX 2.1
;OP.N & %FF => T
;IF OP.N & %100 = 0 THEN
   ;^SEG.T[T] => AD.STORE OF CUR.OPD
   ;NN + 1 =>  STORE.BASE OF SEG.T[T]
;ELSE
   ;^TX.S[T] => AD.TX OF CUR.OPD
   ;NN + 1 => TX.BASE OF TX.S[T]
;FI
;OP.N ->> 8 & 1 => AD.KIND OF CUR.OPD
;OP.N => BASE.T[NN]
@BOX 3.1
;IF OP.N & %200 /= 0
@BOX 4.1
;ADD.INST(N ! %69, 0, 18, ^CUR.OPD)
@BOX 5.1
;EXIT
@END
@TITLE MTL07.1.3.5(1,10)
@COL 1S-2R-3T-4R-5F
@FLOW 1-2-3N-4-5
@FLOW 3Y-5
@BOX 1.0
BMODE
BCONV
@BOX 2.0
NOTE OLD BMODE
SELCT NEW BMODE
@BOX 3.0
BMODE THE SAME OR
BMODE OPCODE
@BOX 4.0
PLANT B CONV
@BOX 5.0
END
@BOX 1.1
;F7.1.3.5B1:
@BOX 2.1
;IF OP.N & %3C ->> 2 => T = 3 THEN
   ;2 => T
;FI
;BMODE => OLD
;B.Z.T[T] <<- 10 ! (OP.N & %C0 <<- 1) => B.MODE
@BOX 3.1
;IF OLD = B.MODE OR FN & %1F = %16
@BOX 4.1
;B.MODE ->> 7 ! (OP.N & %C000 ->> 8) => A.TYPE OF CUR.OPD
;OLD ->> 7 => OLD.A.TYPE OF CUR.OPD
;ADD.INST(%6A, %F, 14, ^CUR.OPD)
@BOX 5.1
;EXIT
@END
@TITLE MTL07.1.4(1,6)
@COL 1S-3R-4F
@FLOW 1-3-4
@BOX 1.0
D OP CODES
@BOX 3.0
SWITCH ON FN
SEL.FLD,SEL.ALT,SEL.EL[MTL07.1.4.1]
D=, D=REF [MTL07.1.4.2]
BASE,LIMIT [MTL07.1.4.2]
D=A, A=D [MTL07.1.4.2]
@BOX 4.0
END
@BOX 1.1
;PROC O.FNS(FN)
;ADDR FIELD.E FP
;$IN T
@BOX 3.1
;SWITCH FN \
F7.1.4.2B23,F7.1.4.2B5,F7.1.4.2B1,F7.1.4.1B1,
F7.1.4.1B11,F7.1.4.1B8,F7.1.4.2B16,F7.1.4.2B16
#MTL07.1.4.1
#MTL07.1.4.2
@BOX 4.1
;F7.1.4B3:
;END
@END
@TITLE MTL07.1.4.1(1,7)
@COL 1S-2T-3R-5R-6R-7C
@COL 8C-9R-10C-11C-12T-13R-14C
@COL 15R
@ROW 13-15
@FLOW 1-2N-3-5-6-7
@FLOW 2Y-5
@FLOW 8-9-10
@FLOW 11-12N-13-14
@FLOW 12Y-15-14
@BOX 1.0
SEL FLD
@BOX 2.0
CURRENT D[] DOES NOT
USE B
@BOX 3.0
LOAD D=REF[MTL07.35]
@BOX 5.0
LOCATE REQUIRED FIELD
OF TYPE
@BOX 6.0
UPDATE D[] INFO
@BOX 7.0
END
@BOX 8.0
SEL ALT
@BOX 9.0
LOCATE REQUIRED
ALTERNATIVE
@BOX 10.0
END
@BOX 11.0
SEL EL
@BOX 12.0
B CONTAINS JUST A
CONSTANT AND
BASE IS NOT V.STORE?
@BOX 13.0
UPDATE D[] INFO
@BOX 14.0
END
@BOX 15.0
RELEASE B
GET SIZE OF EL[MTL23]
UPDATE D[] INFO
@BOX 1.1
;F7.1.4.1B1:
@BOX 2.1
;IF B.ST.B & %4 = 0
@BOX 3.1
;LOAD.D(3)
@BOX 5.1
;IF D.FLD.P = NIL.FLD THEN
   ;TYPE.FIELD.P OF D.TYPE.P^=>D.FLD.P
;FI
;WHILE 1 -> OP.N >= 0 DO
   ;NEXT.FIELD.P OF D.FLD.P^ => D.FLD.P
;OD
@BOX 6.1
;FIELD.TYPE OF D.FLD.P^ => D.TYPE
;FIELD.TYPE.P OF D.FLD.P^ => D.TYPE.P
;FIELD.DIM OF D.FLD.P^ => D.DIM
;FIELD.POS OF D.FLD.P^ +> D.OFFSET
;NIL.FLD=>D.FLD.P
;0 => D.ELEM.F
@BOX 7.1
;EXIT
@BOX 8.1
;F7.1.4.1B8:
@BOX 9.1
;TYPE.FIELD.P OF D.TYPE.P^=>D.FLD.P
;WHILE 1->OP.N >= 0 DO
   ;WHILE FIELD.TAG OF D.FLD.P^ /= 1 DO
      ;NEXT.FIELD.P OF D.FLD.P^ => D.FLD.P
   ;OD
   ;NEXT.FIELD.P OF D.FLD.P^ => D.FLD.P
;OD
@BOX 10.1
;EXIT
@BOX 11.1
;F7.1.4.1B11:
@BOX 12.1
;1 => D.ELEM.F
;IF B.ST.B & 1 = 0 AND D.BASE.ST /= 4
@BOX 13.1
;4 !> B.ST.B
@BOX 14.1
;EXIT
@BOX 15.1
;0 => B.ST.B
;TYPE.SIZE(D.TYPE,D.TYPE.P,1,0)
;B.CONST * C.TYPE.Z +> D.OFFSET
;0=>B.CONST
;%E &> REG.ST
@END
@TITLE MTL07.1.4.2(1,12)
@COL 21R-22R-23C-24T-25R-43T-8T-30R-26R-27C-44R-45C
@COL 1S-19T-20T-2R-28T-35R-36C-4R-40T-41R-42C
@COL 5C-31R-32T-6R-33R-34C-16C-17R-18C
@FLOW 1-19N-20N-2-40N-41-40Y-42
@FLOW 28N-35-36
@FLOW 19Y-28Y-4-40
@FLOW 5-31-32N-6-40
@FLOW 32Y-33-34
@FLOW 16-17-18
@FLOW 20Y-21-22-40
@FLOW 23-24N-25-43N-8NO-30-26-27
@FLOW 24Y-26
@FLOW 43Y-30
@FLOW 8Y-44-45
@BOX 1.0
D=
@BOX 8.0
BASE NOT OFFSTACK PTR
@BOX 28.0
OPERAND NOT A SELECT BASE
@BOX 19.0
OPERAND A SCALAR PTR
@BOX 2.0
LOAD D=[MTL07.36]
@BOX 4.0
UPDATE D[] INFO
@BOX 5.0
D = REF
@BOX 31.0
RESET D[] INFO
@BOX 32.0
V STORE OPERAND
@BOX 33.0
UPDATE D[] INFO
@BOX 34.0
END
@BOX 35.0
EXPAND TO D=SEL BASE
  SEL ALT
  SEL FIELD
[MTL07.1.4]
@BOX 36.0
EXIT
@BOX 6.0
UPDATE D[] INFO
@BOX 16.0
BASE, LIMIT
@BOX 17.0
LOAD D[MTL07.36]
SET UP BASE LIMIT OPERAND
[MTL07.34]
ADD BASE LIMIT TO
INSTR SEQ WITH TWO
PART OPERAND[MTL07.30]
@BOX 18.0
END
@BOX 20.0
OPERAND ON STACK?
@BOX 22.0
ADD D = UNSTACK INST
   [MTL07.30]
@BOX 21.0
UPDATE INFO
@BOX 23.0
D=>
@BOX 30.0
LOAD D[MTL07.36]
@BOX 24.0
NOT SELECT VARIABLE
@BOX 25.0
SAVE TYPE INFO IN SELECT
VARIABLE ENTRY
@BOX 26.0
ADD D=> INST TO INST SEQ
@BOX 27.0
END
@BOX 40.0
NOT A REDUCIBLE SCALAR TYPE
@BOX 41.0
REDUCE TYPE
@BOX 42.0
END
@BOX 43.0
IS SELECT INFO DYNAMIC
@BOX 44.0
SAVE STATIC SELECT INFO
@BOX 45.0
END
@BOX 1.1
;F7.1.4.2B1:
@BOX 19.1
;IF OP.N < 4096
@BOX 20.1
;IF OP.N = %1005
@BOX 2.1
;D.TYPE & %2 <<- 9 ! %40 => T
;LOAD.D(2)
;T => D.MODE
;IF D.TYPE = 0 AND D.TYPE.P = NIL.TYPE THEN
   ;UND.D.TYPE => D.TYPE
   ;UND.D.TYPE.P => D.TYPE.P
;FI
@BOX 4.1
;OP.N => D.BASE.N
;0 => D.OFFSET
;IF T /= 4 THEN
   ;IF SEL.V.BASE.ST OF CUR.SEL.P^
           => D.BASE.ST > 1 THEN
      ;%40 => D.MODE
      ;CUR.SEL.P => SEL OF D.BASE.P
   ;ELSE
      ;SEL.V.MODE OF CUR.SEL.P^ => D.MODE
      ;SEL.V.BASE.P OF CUR.SEL.P^ => VAR OF D.BASE.P
      ;SEL.V.OFFSET OF CUR.SEL.P^ => D.OFFSET
      ;SEL.V.BASE.N OF CUR.SEL.P^ => D.BASE.N
   FI
   ;SEL.V.TYP OF CUR.SEL.P^ => D.TYPE
   ;;SEL.V.TYP.P OF CUR.SEL.P^ => D.TYPE.P
   ;SEL.V.DIM OF CUR.SEL.P^ => D.DIM
   ;SEL.V.F OF CUR.SEL.P^ & 1 => D.ELEM.F
;ELSE
   ;VAR.TYP OF CUR.VAR.P^ & 2 <<- 9 ! %40 => D.MODE
   ;1 => D.BASE.ST
   ;VAR.TYP OF CUR.VAR.P^ & %FC => D.TYPE
   ;CUR.VAR.P=>PTR OF D.BASE.P
   ;VAR.TYP.P OF CUR.VAR.P^ => D.TYPE.P
;IF VAR.TYP OF CUR.VAR.P^ & 3 = 3 THEN
   ;-1 => D.DIM
;ELSE
   ;0=>D.DIM
;FI
;0=>D.ELEM.F
;IF D.TYPE = 0 AND D.TYPE.P = NIL.TYPE THEN
   ;UND.D.TYPE  => D.TYPE
   ;UND.D.TYPE.P => D.TYPE.P
;FI
;FI
;NILFLD => D.FLD.P
@BOX 22.1
;LOAD.OP.TYPE(D.MODE ->> 9 ! 1,
    NIL.TYPE,0,0,^UNSTK OF CUR.OPD)
;ADD.INST(D.MODE ! 2,REG.ST,8,^CUR.OPD)
@BOX 21.1
;BEGIN
;SELECT STK.OP OF STK.S[1->STK.I]
   ;SDDIM => D.DIM
   ;SDTYPE => D.TYPE
   ;SDTYPEP => D.TYPEP
   ;SDELEM.F => D.ELEM.F
   ;S.D.MODE => D.MODE
   ;0 => D.OFFSET
;END
;NIL.FLD => D.FLD.P
;2 => D.BASE.ST
@BOX 5.1
;F7.1.4.2B5:
@BOX 31.1
;%40 => D.MODE
;0 => D.OFFSET => D.ELEM.F
;NIL.FLD => D.FLD.P
;OP.N => D.BASE.N
@BOX 32.1
;PROP.PTR(OPN,GET.KIND(OPN) & %F => T)
;IF T /= 4
@BOX 33.1
;4=>D.BASE.ST
;V.STORE.TYPE OF CUR.V.STOREP^ => D.TYPE
;NIL.TYPE=>D.TYPE.P
;V.STORE.DIM OF CUR.V.STORE.P^ => D.DIM
;CUR.V.STOREP => V.ST OF D.BASE.P
@BOX 34.1
;EXIT
@BOX 6.1
;0=>D.BASE.ST
;VAR.TYP OF CUR.VAR.P^ => D.TYPE
;VAR.TYP.P OF CUR.VAR.P^ => D.TYPE.P
;VAR.DIM OF CUR.VAR.P^ => D.DIM
;CUR.VAR.P => VAR OF D.BASE.P
@BOX 16.1
;F7.1.4.2B16:
@BOX 17.1
;LOAD.D(3)
;B.L.OPD(D.TYPE,D.TYPE.P)
;ADD.INST(FN & %F ! %40,REG.ST,13,^CUR.OPD)
@BOX 18.1
;EXIT
@BOX 23.1
;F7.1.4.2B23:
@BOX 30.1
;3 => SEL.V.BASE.ST OF CUR.SEL.P^
;LOAD.D(3)
@BOX 24.1
;IF CUR.OPD.K /= 2
@BOX 25.1
;D.TYPE => SEL.V.TYP OF CUR.SEL.P^
;D.TYPE.P => SEL.V.TYP.P OF CUR.SEL.P^
;D.DIM => SEL.V.DIM OF CUR.SEL.P^
;%FE & SEL.V.F OF CUR.SEL.P^ ! D.ELEM.F
   => SEL.V.F OF CUR.SEL.P^
@BOX 26.1
;ADD.INST(%40,%FB &> REG.ST,CUR.OPD.K,^CUR.OPD)
@BOX 27.1
;EXIT
@BOX 28.1
;PROP.PTR(OPN,GET.KIND(OPN) & %F => T)
;IF T /= 12
@BOX 35.1
;SEL.BASE OF CUR.SEL.BP^ => OPN
;O.FNS(2)
;IF SEL.ALT OF CUR.SEL.BP^ => OP.N > 0 THEN
   ;OFNS(5)
;FI
;SEL.FIELD OF CUR.SEL.BP^ => OPN
;OFNS(3)
@BOX 36.1
;EXIT
@BOX 40.1
;IF D.TYPE.P = NIL.TYPE OR D.TYPE & 3 /= 0
    OR TYPE.FL OF D.TYPE.P^ & 1 = 0
@BOX 41.1
;TYPE.FIELD.P OF D.TYPE.P^ => FP
;FIELD.TYPE OF FP^ => D.TYPE
;FIELD.TYPE.P OF FP^ => D.TYPE.P
@BOX 42.1
;EXIT
@BOX 43.1
;IF D.BASE.ST > 1 OR B.ST.B & 4 /= 0
@BOX 8.1
;PROP.PTR(D.BASE.N, 4)
;IF  D.BASE.ST = 0 OR
   [VAR.F OF CUR.VAR.P^ & 1 /= 0 AND
   STORE.KIND OF VAR.STORE.P^
   OF VAR.ADDR OF CUR.VAR.P^ & 1 = 0]
@BOX 44.1
;D.MODE => SEL.V.MODE OF CUR.SEL.P^
;VAR OF D.BASE.P => SEL.V.BASE.P OF CUR.SEL.P^
;D.OFFSET => SEL.V.OFFSET OF CUR.SEL.P^
;D.BASE.N => SEL.V.BASE.N OF CUR.SEL.P^
;D.BASE.ST => SEL.V.BASE.ST OF CUR.SEL.P^
@BOX 45.1
;EXIT
@END
@TITLE MTL07.1.11(1,7)
@COL 1S-2T-3R-4T-5R-6R-7F
@FLOW 1-2N-3-4N-5-6-7
@FLOW 2Y-4Y-6
@BOX 1.0
LOAD.B
@BOX 2.0
SELECT ELEMENT NOT OPERATIVE
ON B REGISTER
@BOX 3.0
LOAD D[MTL07.36]
@BOX 4.0
NO HELD BACK CONSTANT
@BOX 5.0
ADD CONSTANT INTO B[MTL07.25]
@BOX 6.0
RESET B INFO
@BOX 7.0
END
@BOX 1.1
;PROC LOAD.B
@BOX 2.1
;IF B.ST.B & 4 = 0
@BOX 3.1
;LOAD.D(3)
@BOX 4.1
;IF B.ST.B & 2 = 0
@BOX 5.1
;ADD.B.CONST()
@BOX 6.1
;1 => B.ST.B
@BOX 7.1
;END
@END
@TITLE MTL07.2(1,9)
@COL 1S-4T-2R-3F
@COL 7T-5R-6R-8R
@FLOW 1-4N-2-3
@FLOW 4Y-7N-5-6-3
@FLOW 7Y-8-3
@ROW 2-7
@BOX 1.0
TL.REG(SAVE REG INFO)
@BOX 2.0
SAVE PARAMETER
@BOX 3.0
END
@BOX 4.0
ANY REGISTERS RELEASED?
@BOX 5.0
CODE ANY OUTSTANDING INSTRUCTIONS
[MTL07.20]
@BOX 6.0
UPDATE REGISTER STATUS
RELEASE REGISTERS[MTL27]
@BOX 7.0
BASE REGISTER TO BE RELEASED
@BOX 8.0
RELEASE BASE REGISTER
@BOX 1.1
;PROC TL.REG(P)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.REG(P)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.REG(P)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;$IN T
@BOX 2.1
;P => REG.USE
@BOX 3.1
;END
@BOX 4.1
;IF P & %F0 /= 0
@BOX 5.1
;CODE()
@BOX 6.1
;P ->> 4 => P -= %F &> REG.ST
;REL.REGS(P)
@BOX 7.1
;IF P & %80 /= 0
@BOX 8.1
;IF BASE.T[P ->> 8] => T & %100 = 0 THEN
   ;0 => STORE.BASE OF SEG.T[T & %FF]
;ELSE
   ;0 => TX.BASE OF TX.S[T & %FF]
;FI
@END
@TITLE MTL07.3(1,11)
@COL 1S-2R-4T-5R-3F
@FLOW 1-2-4N-5-3
@FLOW 4Y-3
@BOX 1.0
TL.D.TYPE(TYPE,DIMENSION)
@BOX 2.0
SAVE TYPE AND DIMENSION
@BOX 3.0
END
@BOX 4.0
CHANGE DTYPE ON LOADING TYPELESS POINTERS
@BOX 5.0
SET DTYPE
@BOX 1.1
;PROC TL.D.TYPE(TYP,DIM)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.D.TYPE(TYP,DIM)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.D.TYPE(TYP,DIM)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
@BOX 2.1
;TYP & %3FFF => UND.D.TYPE
;DIM => UND.D.DIM
;TYPE.PTR(^UND.D.TYPE) => UND.D.TYPE.P
@BOX 3.1
;END
@BOX 4.1
;IF TYP & %4000 = 0
@BOX 5.1
;UND.D.TYPE => D.TYPE
;UND.D.DIM => D.DIM
;UND.D.TYPE.P => D.TYPE.P
@END


@TITLE MTL07.4(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TL.CHECK(INFO)
@BOX 2.0
NOT IMPLEMENTED
@BOX 3.0
END
@BOX 1.1
;PROC TL.CHECK(INFO)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.CHECK(INFO)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.CHECK(INFO)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
@BOX 2.1
:: ;FAULT(9,%"CHECK")
@BOX 3.1
;END
@END

@TITLE MTL07.5(1,7)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
TL.CYCLE(LIMIT)
@BOX 2.0
DO CODE CHECKS[MTL07.23]
@BOX 3.0
PLANT CYCLE[MTL27]
RELEASE A REGISTER IF LIMIT IS A
@BOX 4.0
END
@BOX 1.1
;PROC TL.CYCLE(L)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.CYCLE(L)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.CYCLE(L)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
@BOX 2.1
;CODE.CHECKS()
@BOX 3.1
;REG.ST => OLD.REG.ST
;0 => FN.INFO
;CYCLE(PR.OP(L),^CUR.OPD)
;IF L = %3000 THEN
    ;%FD &> REG.ST
   ;REL.REGS(2)
;FI
@BOX 4.1
;END
@END
@TITLE MTL07.6(1,7)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
TL.REPEAT()
@BOX 2.0
DO CODE CHECKS[MTL07.23]
@BOX 3.0
PLANT REPEAT[MTL27]
END
@BOX 1.1
;PROC TL.REPEAT
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.REPEAT()
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.REPEAT()
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
@BOX 2.1
;CODE.CHECKS()
@BOX 3.1
;REPEAT()
@BOX 4.1
;END
@END
@TITLE MTL07.7(1,7)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
TL.CV.CYCLE(CV,INIT,MODE)
@BOX 2.0
DO.CODE.CHECKS[MTL07.23]
@BOX 3.0
PLANT CV.CYCLE[MTL27]
RELEASE A REGISTER IF INIT IS A REGISTER
@BOX 4.0
END
@BOX 1.1
;PROC TL.CV.CYCLE(CV,INIT,M)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.CV.CYCLE(CV,INIT,M)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.CV.CYCLE(CV,INIT,M)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
@BOX 2.1
;CODE.CHECKS()
@BOX 3.1
;PROP.PTR(CV,4)
;REG.ST =>  OLD.REG.ST
;0 => FN.INFO
;CV.CYCLE(CUR.VAR.P,PR.OP(INIT),^CUR.OPD,M)
;IF INIT = %3000 THEN
   ;%FD &> REG.ST
   ;REL.REGS(2)
;FI
@BOX 4.1
;END
@END
@TITLE MTL07.8(1,7)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
TL.CV.LIMIT(LIMIT)
@BOX 2.0
DO CODE CHECKS[MTL07.23]
@BOX 3.0
PLANT CV.LIMIT[MTL27]
RELEASE REGISTER IF LIMIT IS A REGISTER
@BOX 4.0
END
@BOX 1.1
;PROC TL.CV.LIMIT(L)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.CV.LIMIT(L)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.CV.LIMIT(L)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
@BOX 2.1
;CODE.CHECKS()
@BOX 3.1
;REG.ST => OLD.REG.ST
;0 => FN.INFO
;CV.LIMIT(PR.OP(L),^CUR.OPD)
;IF L = %3000 THEN
   ;%FD &> REG.ST
   ;REL.REGS(2)
;FI
@BOX 4.1
;END
@END
@TITLE MTL07.9(1,7)
@COL 1S-4R-2R-3F
@FLOW 1-4-2-3
@BOX 1.0
TL.INSERT(BINARY)
@BOX 2.0
TL.INSERT[MTL27]
@BOX 3.0
END
@BOX 4.0
DO CODE CHECKS
[MTL07.23]
@BOX 5.0
CHECK JUMP ROUND
EMBEDDED PROCS ETC
[MTL07.22]
@BOX 1.1
;PROC TL.INSERT(BIN)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.INSERT(BIN)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.INSERT(BIN)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
@BOX 2.1
;INSERT(BIN)
@BOX 3.1
;END
@BOX 4.1
;CODE.CHECKS()
@END
@TITLE MTL07.10(1,10)
@COL 1S-12R-11R-2T-3R-4T-5T-6R-7R-8F
@COL 9R-10R
@ROW 3-9
@ROW 6-10
@FLOW 1-12-11-2N-3N-4-5N-6-7-8
@FLOW 2Y-9-4N-7
@FLOW 5Y-10-7
@BOX 1.0
TL.RANGE(REGISTER,KIND,LL.OPD,UL.OPD)
@BOX 2.0
LOWER LIMIT IS AN
EXPLICIT LITERAL?
@BOX 3.0
SET UP MUTL NAME OPERAND
[MTL07.35]
@BOX 4.0
UPPER LIMIT NOT DEFINED?
@BOX 5.0
UPPER LIMIT IS AN
EXPLICIT LITERAL?
@BOX 6.0
SET UP OPERAND FOR
MUTL NAME [MTL07.35]
@BOX 7.0
PLANT RANGE CHECK
[MTL27]
@BOX 8.0
END
@BOX 9.0
SET UP LITERAL OPERAND
@BOX 10.0
SET UP LITERAL OPERAND
@BOX 11.0
CODE OUSTANDING INSTUCTIONS
@BOX 12.0
SET UP REGISTER INFO
@BOX 1.1
;PROC TL.RANGE(REG,K,LL,UL)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.RANGE(REG,K,LL,UL)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.RANGE(REG,K,LL,UL)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;OPD.E LL.OPD
;$IN LL.K,UL.K,F,Z
@BOX 2.1
;IF K & 0 = 0
@BOX 3.1
;PR.OP(LL) => LL.K
;CUR.OPD => LL.OPD
@BOX 4.1
;IF K & 2 /= 0
@BOX 5.1
;IF K & 4 = 0
@BOX 6.1
;PR.OP(UL) => UL.K
@BOX 7.1
;REG & %FF <<- 13 !> F
;RANGE(F,LL.K,^LL.OPD,UL.K,^CUR.OPD)
@BOX 8.1
;END
@BOX 9.1
;3 => LL.K
;0 => DIM OF LIT.TYP OF LL.OPD
;1 => MOD OF LIT.TYP OF LL.OPD
;Z => SIZ OF LIT.TYP OF LL.OPD
;LL => VAL OF LIT OF LL.OPD
@BOX 10.1
;3 => UL.K
;0 => DIM OF LIT.TYP OF CUR.OPD
;1 => MOD OF LIT.TYP OF CUR.OPD
;Z => SIZ OF LIT.TYP OF CUR.OPD
;UL => VAL OF LIT OF CUR.OPD
@BOX 11.1
;CODE()
@BOX 12.1
IF REG & %1000 /= 0 THEN
   ;MC.A.MODE => F
;ELSE
   ;B.MODE => F
;FI
;ASIZ[F ->> 10 & 7] => Z
@END
@TITLE MTL07.20(1,11)
@COL 1S-11R-21T-22R-2T-3R-5T-6R-8T-9T-10T-12R-14R-15T-16R-17T-18R-19F
@COL 20C
@ROW 3-20
@FLOW 1-11-21N-22-2N-3-5N-6-8N-9N-10N-12-14-15Y-16-17N-18-19
@FLOW 21-2
@FLOW 2Y-20
@FLOW 5Y-17Y-5
@FLOW 8Y-12
@FLOW 9Y-14
@FLOW 10Y-14
@FLOW 15Y-17
@BOX 1.0
CODE ()
@BOX 11.0
DECISION TABLES[MTL07.20.1]
@BOX 2.0
INSTR SEQ EMPTY?
@BOX 3.0
RESET OPD FLAGS
RESET STACK OPD LIST
@BOX 5.0
ENTRY DOES NOT HAVE A VARIABLE OPERAND?
@BOX 6.0
DETERMINE KIND OF OPERAND
PTR REFN/STORE, STATIC REFN/STORE
SELECT ACTION FROM DECISION TABLE
@BOX 8.0
UNCONDITIONAL PLANTING AT THIS POINT?
@BOX 9.0
NO PLANTING NECESSARY AT THIS POINT?
@BOX 10.0
SEARCH FOR MATCHING OPERAND OF CORRECT ACCESS IN STATIC LIST
NOT FOUND?
@BOX 12.0
CALL PLANT[MTL27] TO CODE INSTR SEQ
RESET OPD FLAGS
RESET STATIC OPD LIST
@BOX 14.0
UPDATE OPD FLAGS
@BOX 15.0
OPERAND NOT STATIC?
@BOX 16.0
ADD TO LIST
@BOX 17.0
GET NEXT INST. END OF SEQUENCE?
@BOX 18.0
CALL PLANT TO CODE INST SEQ[MTL27]
RESET INST SEQ INDEX
@BOX 19.0
END
@BOX 20.0
EXIT
@BOX 21.0
NO B CONSTANT HELD BACK
@BOX 22.0
LOAD OR ADD CONSTANT TO B [MTL07.25]
@BOX 1.1
;PROC CODE
;TYPE  STAT.OPD.E  IS
   ADDR  VAR.E  ST.VAR
   ADDR         ST.OFF
   $LO8         ST.RW
;STAT.OPD.E[256]  STAT.OPD
;$IN OPD.FL,SH,ST.I,I,OPD.BIT,OPD.K,T,ACTION,J,F
;$IN OLD.I,A.OPD.FL,B.OPD.FL,O.OPD.FL,OP.C
@BOX 11.1
#MTL07.20.1
@BOX 2.1
;IF INST.I = 0
@BOX 3.1
;0=>I=>ST.I=>B.OPD.FL=>A.OPD.FL=>O.OPD.FL=>OLD.I
@BOX 5.1
;SELECT INST[I]
;IF OPD.KIND /= 0
@BOX 6.1
;IF ORIG.KIND OF OPD = 0 THEN 2=>OPD.K
;ELSE 0=>OPD.K FI
;OP.CODE & 3 => SH
;STORE.T[OP.CODE=>T ->>3 & %F] ->> SH & 1 + 2 => OPD.K
;1 <<- OPD.K => OPD.BIT
;IF OP.CODE & %60 => OP.C = %20 THEN B.OPD.FL ! O.OPD.FL => OPD.FL
;ELSE IF OP.C = 0 THEN A.OPD.FL ! O.OPD.FL => OPD.FL
;ELSE A.OPD.FL ! B.OPD.FL => OPD.FL FI FI
;ACTION.T[OPD.FL+OPD.K] => ACTION
@BOX 8.1
;IF ACTION & 1 /= 0
@BOX 9.1
;IF ACTION & 6 = 0
@BOX 10.1
;-1 => J => F
;WHILE 1+>J < ST.I DO
   ;BEGIN
   ;SELECT STAT.OPD[J]
   ;IF ST.VAR = VAR OF ORIG OF OPD
      AND ST.OFF = OFFSET OF OPD
      AND ST.RW & ACTION /=0 THEN
         ;J => ST.I => F
   ;FI
   ;END
;OD
;IF F < 0
@BOX 12.1
;PLANT(PART(^INST,OLD.I,I-1))
;I => OLD.I
;0 => B.OPD.FL => A.OPD.FL => O.OPD.FL => ST.I
@BOX 14.1
IF OP.C = %20 THEN OPD.BIT !> A.OPD.FL
;ELSE IF OP.C = 0 THEN OPD.BIT !> B.OPD.FL
;ELSE OPD.BIT !> O.OPD.FL FI FI
@BOX 15.1
;IF ACTION & 8 = 0
@BOX 16.1
;BEGIN
;SELECT STAT.OPD[ST.I]
   ;VAR OF ORIG OF OPD => ST.VAR
   ;OFFSET OF OPD => ST.OFF
   ;OPD.K & 1*2 -: 4 => ST.RW
;END
;1+>ST.I
@BOX 17.1
;IF 1+>I < INST.I
@BOX 18.1
;PLANT(PART(^INST,OLD.I,INST.I-1))
;0 => INST.I
@BOX 19.1
;END
@BOX 20.1
;EXIT
@BOX 21.1
;IF B.ST.B & 2 = 0
@BOX 22.1
:: ;ADD.B.CONST()
:: ;2 -=> B.ST.B
@END
@TITLE MTL07.20.1(1,6)
@COL 1S-2R-3R
@FLOW 1-2-3
@BOX 1.0
DATAVECS FOR CODE
@BOX 2.0
DECISION TABLE
ENTRY DECODE IS
BIT 0=1 CODE SEQUENCE
BIT 1=1 CODE SEQUENCE IF PREVIOUS ASSIGNMENT
        TO STATIC OPERAND
BIT 2=1 CODE SEQUENCE IF PREVIOUS REFN
        TO STATIC OPERAND
BIT 3=1 SAVE STATIC OPERAND IN LIST
@BOX 3.0
STORE TABLE
INDICATES WHICH OP CODES ARE ASSIGNMENTS
@BOX 1.1
@BOX 2.1
;DATAVEC ACTION.T($LO8)
0   0   8   8
0   1   8   9
1   1   9   9
1   1   9   9
0   1   8  12
0   1   8   9
1   1   9   9
1   1   9   9
1   1  10  10
1   1  10   9
1   1   9   9
1   1   9   9
1   1  10  14
1   1  10   9
1   1   9   9
1   1   9   9
END
@BOX 3.1
;DATAVEC STORE.T($LO8)
%01   %00   %38   %EF
%01   %00   %38   %EF
%01   %00   %00   %00
%00   %00   %00   %00
END
@END
@TITLE MTL07.21(1,6)
@COL 1S-2T-3R-4R-5R-6F
@FLOW 1-2N-3-4-5-6
@FLOW 2Y-6
@BOX 1.0
JUMP.RND()
@BOX 2.0
IS THERE ALREADY AN OUTSTANDING
JUMP AROUND PROCS ETC AT THIS TEXTUAL
LEVEL
@BOX 3.0
CODE INST SEQ[MTL07.20]
@BOX 4.0
PLANT GO TO LABEL[MTL28]
@BOX 5.0
NOTE OUTSTANDING JUMP AROUND PROC ETC
@BOX 6.0
END
@BOX 1.1
;PROC JUMP.RND
@BOX 2.1
;IF LAB.USE OF CUR.BLK.LAB^ & %10 /= 0
@BOX 3.1
;CODE()
@BOX 4.1
;GO.TO(CUR.BLK.LAB)
@BOX 5.1
;%10 => LAB.USE OF CUR.BLK.LAB^
@BOX 6.1
;END
@END
@TITLE MTL07.22(1,6)
@COL 1S-2T-3R-4R-5R-6F
@FLOW 1-2N-3-4-5-6
@FLOW 2Y-6
@BOX 1.0
CHECK JUMP ROUND()
@BOX 2.0
NO OUTSTANDING JUMP AROUND
PROCS AND DATAVECS?
@BOX 3.0
CODE INST SEQ[MTL07.20]
@BOX 4.0
DEFINE LABEL[MTL28]
@BOX 5.0
NOTE NO OUTSTANDING JUMP
AROUND PROCS ETC
@BOX 6.0
END
@BOX 1.1
;PROC CHECK.JUMP.RND
@BOX 2.1
;IF BLK.I =< 0 OR LAB.USE OF CUR.BLK.LAB^ & %10 = 0
@BOX 3.1
;CODE()
@BOX 4.1
;LABL(CUR.BLK.LAB)
@BOX 5.1
;0 => LAB.USE OF CUR.BLK.LAB^
@BOX 6.1
;END
@END
@TITLE MTL07.23(1,7)
@COL 1S-2R-3R-4T-5R-6F
@FLOW 1-2-3-4N-5-6
@FLOW 4Y-6
@BOX 1.0
CODE.CHECKS()
@BOX 2.0
CODE ANY OUTSTANDING INSTRUCTIONS[MTL07.20]
@BOX 3.0
CHECK IF LABEL NEEDED AROUND EMBEDDED
PROCS OR DATAVECS[MTL07.22]
@BOX 4.0
TL PROC KIND NOT REQUIRED
@BOX 5.0
SET TL.PROC.KIND
@BOX 6.0
END
@BOX 1.1
;PROC CODE.CHECKS
@BOX 2.1
;CODE()
@BOX 3.1
;CHECK.JUMP.RND()
@BOX 4.1
;IF PROC.STATUS & 1 /=0
@BOX 5.1
;TL.PROC.KIND(0)
@BOX 6.1
;END
@END
@TITLE MTL07.24(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
INIT.7()
@BOX 2.0
INITIALISE
@BOX 3.0
END
@BOX 1.1
;PROC INIT.7
@BOX 2.1
;-1 => CALL.I => D.BASE.ST
;0 => STK.I  => INST.I => B.ST.B => REG.ST
;INIT.B.MODE => B.MODE
@BOX 3.1
;END
@END
@TITLE MTL07.25(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ADD.B.CONST()
@BOX 2.0
PLANT INSTR TO ADD BCONST
TO B [MTL07.30]
@BOX 3.0
END
@BOX 1.1
;PROC ADD.B.CONST
;OPD.E B.OPD
@BOX 2.1
;B.CONST => VAL OF LIT OF B.OPD
;0 => B.CONST => DIM OF LIT.TYP OF B.OPD
;1 => MOD OF LIT.TYP OF B.OPD
;ASIZ[BMODE ->> 10] => SIZ OF LIT.TYP OF B.OPD
;ADD.INST(B.ST.B & 1 * 6 + 2, REG.ST, 3, ^B.OPD)
@BOX 3.1
;END
@END

@TITLE MTL07.26(1,7)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
REGS()REG.INFO
@BOX 2.0
GET REG INFO
@BOX 3.0
END
@BOX 1.1
;PROC REGS
@BOX 2.1
;MC.A.MODE ! REG.ST => REGS
@BOX 3.1
;END
@END
@TITLE MTL07.30(1,6)
@COL 1S-6T-7R-2R-8T-9R-3T-4R-5F
@FLOW 1-6N-7-2-8N-9-3N-4-5
@FLOW 3Y-5
@FLOW 6Y-2
@FLOW 8Y-3
@BOX 1.0
ADD.INST(OP.CODE,REG.SPEC,OPD.KIND,PTR.TO.DPD)
@BOX 2.0
ADD ENTRY TO INST.SEQ
@BOX 3.0
SEQUENCE FULL
@BOX 4.0
CODE INST.SEQ[MTL07.20]
@BOX 5.0
END
@BOX 6.0
NOT B INSTR?
@BOX 7.0
SET B MODE
@BOX 8.0
NOT LITERAL OPERAND OF TYPE INT
OR LOGICAL WITH A/B OP CODE
@BOX 9.0
SET LIT MODE AND SIZE
TO THAT OF A/B
@BOX 1.1
;PROC ADD.INST(OP.C,R.S,OPD.K,OPD.P)
@BOX 2.1
;SELECT INST[INST.I]
   ;OP.C => OP.CODE
   ;R.S -= %F => REG.SPEC
   ;OPD.K => OPD.KIND
   ;IF OPD.P /= NIL.OPD THEN
      ;OPD.P^ => OPD
;   FI
@BOX 3.1
;IF 1 +> INST.I < INST.SEQ.Z
@BOX 4.1
;CODE()
@BOX 5.1
;END
@BOX 6.1
;IF OP.C & %60 /= 0
@BOX 7.1
;B.MODE !> OP.C
@BOX 8.1
;IF OPD.K /= 3 OR OP.C & %60 > %20 OR
   [MOD OF LIT.TYP OF OPD /= 1 /= 2] OR
   [OP.C & %380 /= %80 /= %100]
@BOX 9.1
;ASIZ[OP.C->>10] => SIZ OF LIT.TYP OF OPD
@END
 @TITLE MTL07.33(1,10)
@COL 1S-2T-4R-3R-5T-6T-7R-12R-14R-9F
@COL 10R-11R
@ROW 6-10
@ROW 7-11
@FLOW 1-2N-4-2Y-3-5N-6N-7-12-14-9
@FLOW 5Y-10-12
@FLOW 6Y-11-14
@BOX 1.0
LOAD.OP.TYPE(TYPE,TYPE.PTR,DIM,ELEM.FLAG,
PTR.TO.OPD.TYPE)
@BOX 2.0
NOT A REDUCIBLE USER SCALAR TYPE
@BOX 3.0
SET DIM
@BOX 4.0
REDUCE TYPE
@BOX 5.0
POINTER TYPE?
@BOX 6.0
NON BASIC TYPE?
@BOX 7.0
SET MODE AND SIZE
@BOX 14.0
SET DIM
@BOX 9.0
END
@BOX 10.0
SET MODE TO TYPELESS
SET SIZE
@BOX 11.0
SET MODE AND SIZE
AND ALLIGNMENT
@BOX 12.0
SET ALLIGNMENT
@BOX 1.1
;PROC LOAD.OP.TYPE(T,TP,D,EL.F,OP.TP)
;ADDR FIELD.E FP
;$IN M,I,E
;ADDR Z
@BOX 2.1
;IF TP = NIL.TYPE OR T & 3 /= 0
    OR TYPE.FL OF TP^ & 1 = 0
@BOX 3.1
;IF D = -1 THEN
   ;0=>D
;FI
@BOX 4.1
;TYPE.FIELD.P  OF TP^ => FP
;FIELD.TYPE OF FP^ => T
;FIELD.TYPE.P OF FP^ => TP
@BOX 5.1
;IF T & %1 /= 0
@BOX 6.1
;IF TP /= NIL.TYPE
@BOX 7.1
;IF T & %2000 = 0 THEN
    ;MODE.T[T->>2 & %3F] => I & %7 => M
;ELSE
     ;T ->> 6 & 3 => M
     ;BIT.MODE.T[T ->> 8 & %1F] => I
;FI
;I ->> 3 => Z
@BOX 14.1
;M => MOD OF OP.TP^
;Z => SIZ OF OP.TP^
;D => DIM OF OP.TP^
@BOX 9.1
;END
@BOX 10.1
;D.SIZ[T ->> 1 & 1] => Z
;5 => M
@BOX 11.1
;TYPE.Z OF T.P^ => Z
;-2 => I
;WHILE EXT.OPD.TYPES[2+>I] => E /= T
      AND E /= 0 DO OD
;EXT.OPD.TYPES[I+1] => M
;TYPE.AL OF T.P^ => AL OF OP.TP^
@BOX 12.1
;Z => I
;AL.T[I] => AL OF OP.TP^
@END
@TITLE MTL07.34(1,6)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
B.L.OPD(TYPE, TYPE.PTR)
@BOX 2.0
SET UP ELEMENT INFO[MTL07.33]
@BOX 3.0
SET UP B INFO
@BOX 4.0
END
@BOX 1.1
;PROC BL.OPD(T,TP)
@BOX 2.1
;LOAD.OP.TYPE(T,TP,1,1,^B.L.EL OF CUR.OPD)
@BOX 3.1
;IF B.ST.B & 2 = 0 THEN
   ;0=>B.CONST
;FI
;B.CONST=> BL.C OF CUR.OPD
;B.ST.B & 1 => BL.B OF CUR.OPD
;0 => B.ST.B
@BOX 4.1
;END
@END


@TITLE MTL07.35(1,7)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PR.OP(OP.NAME)
@BOX 2.0
SWITCH ON OPERAND KIND
AND NAME
CURRENT OR NAMED LITERAL[MTL07.35.1]
MUTL NAMES < 4096 [MTL07.35.2]
MUTL NAMES > 4095[MTL07.35.3]
@BOX 3.0
END
@BOX 1.1
;PROC PR.OP(N)
;$IN OP.K
@BOX 2.1
;IF N > 4095 THEN
#MTL07.35.3
;ELSE IF N=0 OR GET.KIND(N) & %F => OP.K < 4 THEN
#MTL07.35.1
;ELSE
#MTL07.35.2
;FI FI
@BOX 3.1
;END
@END
@TITLE MTL07.35.1(1,7)
@COL 1S-2R-3R-4T-5R-6R-7F
@COL 8R
@ROW 5-8
@FLOW 1-2-3-4N-5-6-7
@FLOW 4Y-8-6
@BOX 1.0
CURRENT LITERAL
LITERAL NAME
@BOX 2.0
OBTAIN LITERAL VALUE
[MTL04]
@BOX 3.0
LOAD CUROPD TYPE[MTL07.33]
@BOX 4.0
SIZE > 64 BITS
@BOX 5.0
LOAD CUR OPD VALUE
@BOX 6.0
SET CUR OPD KIND
@BOX 7.0
END
@BOX 8.0
LOAD CUR OPD VALUE
@BOX 1.1
;BEGIN
;$IN T
@BOX 2.1
;GET.LIT(N) => T
@BOX 3.1
;LOAD.OP.TYPE(T,NIL.TYPE,0,0,^LIT.TYP OF CUR.OPD)
@BOX 4.1
;IF SIZ OF LIT.TYP OF CUR.OPD > 8
@BOX 5.1
;USE.LIT.P^[0] => VAL OF LIT OF CUR.OPD
@BOX 6.1
;3 =>  PR.OP
@BOX 7.1
;END
@BOX 8.1
;USE.LIT.P^[0] => VAL.LS OF LIT OF CUR.OPD
;USE.LIT.P^[1] => VAL.MS OF LIT OF CUR.OPD
@END
@TITLE MTL07.35.2(1,7)
@COL 1S-2R-3R-4R-5R-6R-7R-8R-9F
@FLOW 1-2-3-4-5-6-7-8-9
@BOX 1.0
MUTL NAMES 2-4095
@BOX 2.0
GET PROP PTR[MTL18]
PROCESS ACCORDING TO OPERAND
KIND
@BOX 3.0
VARIABLE
SET UP CUR OPERAND
SET TYPE[MTL07.33]
@BOX 4.0
LABEL
SET UP CUR OPERAND
@BOX 5.0
PROC
SET UP CUR OPERAND
@BOX 6.0
SELECT VARIABLE
SET UP CUR OPERAND
@BOX 7.0
V STORE
IF VECTOR VSTORE
 ADD INST B=>VSUB[MTL07.30]
IF READ ACCESS CALL VPROC IF PRESENT[MTL07.38]
IF WRITE ACCESS SAVE INFO OF PROC
SET UP CUR OPERAND
@BOX 8.0
SELECT BASE VARIABLE
NO ACTION
@BOX 9.0
END
@BOX 1.1
;BEGIN
@BOX 2.1
;PROP.PTR(N,GET.KIND(N) & %F=>OP.K)
;ALTERNATIVE OP.K -4 FROM
@BOX 3.1
;BEGIN
;0 =>  PR.OP
;0 => ORIG.KIND OF CUR.OPD
;CUR.VAR.P => VAR OF ORIG OF CUR.OPD
;0 => OFFSET OF CUR.OPD => INDEX.C OF CUR.OPD
=> INDEX.B OF CUR.OPD
;LOAD.OP.TYPE(VAR.TYP OF CUR.VAR.P^, VAR.TYP.P OF CUR.VAR.P^,
              VAR.DIM OF CUR.VAR.P^,0,^TYP OF CUR.OPD)
;END
@BOX 4.1
;BEGIN
;4 =>  PR.OP
;CUR.LAB.P => LAB OF CUR.OPD
;IF CUR.A.MODE = %30 THEN
   ;1 => LAB.K OF CUR.OPD
;ELSE
   ;0 => LAB.K OF CUR.OPD
;FI
;END
@BOX 5.1
;BEGIN
;5 =>  PR.OP
;CUR.PROC.P => PROCED OF CUR.OPD
;IF CUR.A.MODE = %28 THEN
   ;1 => PROC.K OF CUR.OPD
;ELSE
   ;0 => PROC.K OF CUR.OPD
;FI
;END
@BOX 6.1
;BEGIN
;2 =>  PR.OP
;CUR.SEL.P => SEL.VAR OF CUR.OPD
;END
@BOX 7.1
;BEGIN
;IF FN.INFO & %B /= 2 THEN
   ;IF V.READ.P OF CUR.V.STORE.P^ => CUR.PROC.P /= NIL.PROC THEN
      ;ENTER.V.PROC(CUR.PROC.P)
   ;FI
;ELSE
   ;V.WRITE.P OF CUR.V.STORE.P^ => V.W
;FI
;0 => PR.OP
;IF V.KIND OF CUR.V.STORE.P^ = 0 THEN
   ;4=>ORIG.KIND OF CUR.OPD
   ;CUR.V.STOREP => V.ST OF ORIG OF CUR.OPD
;ELSE
   ;0=>ORIG.KIND OF CUR.OPD
   ;VAR.P OF V OF CUR.V.STORE.P^ => VAR OF ORIG OF CUR.OPD
;FI
;0=>OFFSET OF CUR.OPD=>INDEX.C OF CUR.OPD
  =>INDEX.B OF CUR.OPD
;LOAD.OP.TYPE(V.STORE.TYPE OF CUR.V.STORE.P^,NIL.TYPE
     ,0,0,^TYP OF CUR.OPD)
;END
@BOX 8.1
;BEGIN END
;BEGIN END
;BEGIN END
;BEGIN END
@BOX 9.1
;END
;END
@END
@TITLE MTL07.35.3(1,10)
@COL 21S-1C-2R-3C-4C-5R-6R-7C-8C-9R-10F
@COL 11C-12R-13C-14C-15R-17C-18C-19R-20C
@ROW 1-11
@FLOW 1-2-3
@FLOW 4-5-6-7
@FLOW 8-9-10
@FLOW 11-12-13
@FLOW 14-15-17
@FLOW 18-19-20
@BOX 21.0
MUTL NAMES>4095
SWITCH ON NAME
@BOX 1.0
A,B
@BOX 2.0
SET UP OP INFO
UPDATE REG USE INFO
@BOX 3.0
END
@BOX 4.0
ONSTACK
@BOX 5.0
OBTAIN TYPE OF STACKED ITEM
REMOVE ENTRY FROM STACK
@BOX 6.0
SET UP OP INFO
@BOX 7.0
END
@BOX 8.0
V SUB
@BOX 9.0
SET UP OP INFO
@BOX 10.0
END
@BOX 11.0
D[]
@BOX 12.0
RELEASE D REGISTER
SET UP OP INFO
[MTL07.37]
@BOX 13.0
END
@BOX 14.0
D
@BOX 15.0
LOAD D[MTL07.36]
@BOX 17.0
END
@BOX 18.0
T
@BOX 19.0
SET UP CUR OP INFO
@BOX 20.0
END
@BOX 21.1
;BEGIN
;DATAVEC T.OPD($LO8)
0 1 2 5 4 3
END
;$IN T,MD
;IF N = %1004, -> B11
;IF N >= %4000 OR N =%1003, -> B4
;IF N >= %2000, -> B1
;IF N >= %1008, -> B18
;IF N = %1002, -> B8
;-> B14
@BOX 1.1
;B1:
@BOX 2.1
;N ->> 12-2 => T => REG OF CUR.OPD
;9 =>  PR.OP
;IF T = 1 THEN
   ;MC.A.MODE => MD => REG.OPD
   ;%D &> REG.ST
;ELSE
   ;B.MODE => MD
   ;0=>REG.OPD
   ;%E &> REG.ST
;FI
;ASIZ[MD ->> 10] => SIZ OF REG.TYP OF CUR.OPD
;MD ->> 7 & 7 => MOD OF REG.TYP OF CUR.OPD
@BOX 3.1
;EXIT
@BOX 4.1
;B4:
@BOX 5.1
;A.B OF STK.OP OF STK.S[1->STK.I] => UNSTK OF CUR.OPD
@BOX 6.1
;8 =>  PR.OP
@BOX 7.1
;EXIT
@BOX 8.1
;B8:
@BOX 9.1
;11 =>  PR.OP
@BOX 10.1
;END
@BOX 11.1
;B11:
@BOX 12.1
;%B &> REG.ST
;LOAD.D.OP(^CUR.OPD)
;0 =>  PR.OP
@BOX 13.1
;EXIT
@BOX 14.1
;B14:
@BOX 15.1
;LOAD.D(1)
@BOX 17.1
;EXIT
@BOX 18.1
;B18:
@BOX 19.1
;10 =>  PR.OP
;T.OPD[N - %1008] => T.REG OF CUR.OPD
;%7 &> REG.ST
@BOX 20.1
;EXIT
@END
@TITLE MTL07.36(1,7)
@COL 1S-2T-6T-3R-4R-5F
@FLOW 1-2N-6N-3-4-5
@FLOW 6Y-5
@FLOW 2Y-5
@BOX 1.0
LOAD.D(OP.CODE)
@BOX 2.0
NO CURRENT ADDRESS
CALCULATION?
@BOX 6.0
D ALREADY LOADED
@BOX 3.0
LOAD D[]OPERAND[MTL07.37]
ADD LOAD D INST
TO INST SEQ[MTL07.30]
UPDATE REG STATUS
@BOX 4.0
SET D INFO
@BOX 5.0
END
@BOX 1.1
;PROC LOAD.D(FN)
;OPD.E D.OPD
@BOX 2.1
;IF D.BASE.ST = -1
@BOX 3.1
;LOAD.D.OP(^D.OPD)
;IF FN = 3 THEN
   ;%8 !> ORIG.KIND OF D.OPD
;FI
;ADD.INST(D.MODE ! 2, 4 !> REG.ST,0,^D.OPD)
@BOX 4.1
;2 => D.BASE.ST
;%FC &> D.TYPE
;0 => D.OFFSET => D.DIM => D.ELEM.F
@BOX 5.1
;END
@BOX 6.1
;IF FN = 3 AND D.BASE.ST=2 AND D.OFFSET=0 AND B.ST.B & 6 = 0
@END
@TITLE MTL07.37(1,10)
@COL 1S-2R-3T-8T-9T-10R-11R-12R-13T-14R-4R-5R-6F
@COL 7R
@ROW 4-7
@FLOW 1-2-3N-8N-9N-10-11-12-13N-14-4-5-6
@FLOW 3Y-7-5
@FLOW 8Y-4
@FLOW 9Y-11
@FLOW 13Y-4
@BOX 1.0
LOAD D.OP(PTR TO OPD ENTRY)
@BOX 2.0
SET UP ORIGIN AND OFFSET FIELD
@BOX 3.0
B NOT IN SELECT USE
@BOX 4.0
UPDATE B STATUS
SET INDEX FIELD
RELEASE B REGISTER
@BOX 5.0
LOAD OP TYPE[MTL07.33]
@BOX 6.0
END
@BOX 7.0
CLEAR INDEX FIELDS
@BOX 8.0
NOT VSTORE
@BOX 9.0
NO CONSTANT INDEX AND B LOADED
@BOX 10.0
ADD CONSTANT TO B[MTL07.25]
@BOX 11.0
ADD INSTR B => VSUB [MTL07.30]
@BOX 12.0
CALL PRE-PROC IF NECESSARY
NOTE IF POST-PROC NEEDS CALLING
@BOX 13.0
VSTORE MAPPED TO STORE ADDRESS?
@BOX 14.0
CHANGE ORIGIN TO DATA VARIABLE
@BOX 1.1
;PROC LOAD.D.OP(P)
@BOX 2.1
;D.BASE.ST=>ORIG.KIND OF P^
;D.BASE.P => ORIG OF P^
;D.OFFSET => OFFSET OF P^
@BOX 3.1
;IF B.ST.B & %4 = 0
@BOX 4.1
;B.CONST => INDEX.C OF P^
;%B &> B.ST.B & 3 => INDEX.B OF P^
;%E &> REG.ST
@BOX 5.1
;LOAD.OP.TYPE(D.TYPE,D.TYPE.P,D.DIM,D.ELEM.F,^TYP OF P^)
@BOX 6.1
;END
@BOX 7.1
;0 => INDEX.C OF P^ => INDEX.B OF P^
@BOX 8.1
;IF D.BASE.ST /= 4
@BOX 9.1
;IF B.CONST = 0 AND B.ST.B & 1 /= 0
@BOX 10.1
;ADD.B.CONST()
;1 !> B.ST.B
@BOX 11.1
;ADD.INST(0, OLD.REG.ST, 11, NIL.OPD)
@BOX 12.1
;IF FN.INFO & %B /= 2 THEN
;IF V.READ.P OF V.ST^ OF D.BASE.P => CUR.PROC.P /= NIL.PROC THEN
      ;ENTER.V.PROC(CUR.PROC.P)
   ;FI
;ELSE
   ;V.WRITE.P OF V.ST^ OF D.BASE.P => V.W
;FI
@BOX 13.1
;IF V.KIND OF V.ST^ OF D.BASE.P = 0
@BOX 14.1
;0=>ORIG.KIND OF P^
;VAR.P OF V OF V.ST^ OF D.BASE.P => VAR OF ORIG OF P^
@END
@TITLE MTL07.38(1,7)
@COL 1S-9R-2R-3R-4R-5R-6R-7R-8F
@FLOW 1-9-2-3-4-5-6-7-8
@BOX 1.0
ENTER.V.PROC(PROC PTR)
@BOX 2.0
ALLOCATE CALL ENTRY
@BOX 3.0
INITIALISE CALL ENTRY
@BOX 4.0
PLANT STACKLINK[MTL28]
@BOX 5.0
SET AMODE IF V.PROC FUNCTIONAL
@BOX 6.0
PLANT ENTER[MTL28]
@BOX 7.0
   DE-ALLOCATE CALL ENTRY
@BOX 8.0
   END
@BOX 9.0
   CODE ANY OUTSTANDING INSTRUCTIONS
@BOX 1.1
;PROC ENTER.V.PROC(PR)
;$IN T
@BOX 2.1
;SELECT CALLS[1+>CALL.I]
@BOX 3.1
;IF PROC.RES.TYP OF PR^ => T = 0 THEN
   ;4 => CALL.K
;ELSE
   ;6 => CALL.K
   ;LOAD.OP.TYPE(T,PROC.RES.TYP.P OF PR^,0,0, ^RES)
;FI
;PR => PR.PTR OF CALL.PROC
;PROC.PAR.P OF PR^ => PAR.PTR OF CALL.PROC
@BOX 4.1
;STKLINK()
@BOX 5.1
;IF T /= 0 THEN
   ;1 +> CHK.IN
   ;TL.PL(%46,T)
   ;1 -> CHK.IN
;FI
@BOX 6.1
;ENTER()
@BOX 7.1
;1 -> CALL.I
@BOX 8.1
;END
@BOX 9.1
;CODE()
@END

