@V7 54 2 -5
@L5 HIUK1047
0
85  85  85  85  85  85  85  85
85  85  85  85  85  85  85  85
85  85  85  85  85  85  85  85
85  85  85  85  85  85  85  85
85  58  78  85  85  127 90  60
85  85  90  85  85  85  85  85
85  85  85  85  85  85  85  85
85  85  85  85  85  85  85  85
100 91  99  107 109 93  90  109
111 50  82  93  78  127 112 109
90  109 100 89  90  115 95  127
86  83  87  55  72  55  80  91
60  84  87  82  87  84  50  87
83  46  46  74  46  125 83  85
87  87  61  76  45  83  65  100
63  65  65  55  50  55  85  127
@L3 COUK1247
80
@V9 0
@YCHAPTER 23 - MUSS USER MANUAL
@G@RCHAPTER 23 - THE COMPILER TARGET LANGUAGE (MUTL)@G
@V10 1 9 277
@S223.1 INTRODUCTION
@T% 10
@BThe tasks performed by a compiler in translating a high level
language program to some object form may be divided into two parts.
Some tasks, such as lexical and syntax processing, are largely independent
of the machine on which the compiler is running; while other tasks, such as
code generation, are very much more dependent on the type of machine that the
program is being compiled for. The concept of a compiler target language
is to present an abstract machine model to which the compiler targets
its code, thereby increasing the proportion of the
compiler which is almost machine independent.
Thus a compiler may be considered in the two parts shown below.@
@3
@U 15
@
                               |
      ---------------------    |    ---------------------
     |                     |   |   |                     |
     | High level language |   |   |   Target language   |
     | to                  |   |   |   to                |
     | target language     |---|-->|   machine code      |--->
     | translator          |Target |   translator        | Machine
     |                     | code  |                     |  code
      ---------------------    |    ---------------------
                               |
     <- low level of machine ->|<- high level of machine ->
            dependency         |        dependency
@0
@
@
The compilers which run under the MUSS system are organised in
this way and the target language is the @GM@Ganchester @GU@Gniversity @GT@Garget
@GL@Ganguage (MUTL).
@BThe justification for this separation of a compiler is mainly threefold.
@
@
1.@IThe abstract machine model can be the target machine for several high level
language compilers, thus all code generation tasks of these compilers
is centralised, and they are thereby simplified.@
@
2.@IA single compiler can produce code for several different machine types,
by having several abstract machine code translators available to
the compiler.@
@
3.@IOn transferring the compilers to another type of computer,
only the abstract machine code translator need
be rewritten for the new environment.@
@BThe diagram below illustrates points 1 and 2.
@Q 23
@D23
@
@BAlthough the main function of a target language is code generation,
it may to advantage perform other subsidiary functions. For example,
the task of compilation mode control and the provision of
high level language run time diagnostics may be functions of the target
language.
@BExperience of the design of several abstract machine models for multi-language
multi-machine usage has led to the following conclusions.
@
@
1)@IThe design of the target model is strongly influenced by the efficiency of
the code required. If the best object code efficiency possible
for a multiple register machine is to be achieved the compiler must be
aware of the number and type of registers available on a particular
machine in order to make optimum use of registers. For single
accumulator and stack based machines, abstract models
based on a single accumulator or stack architecture are equally effective,
and such models are capable of reasonably good object code efficiency
for multiple register machines.@
@
2)@IOptimisations such as removing multiple evaluations of sub-expressions
and moving invariant expressions outside loops should be in the machine
independent part of the compiler and not in the target language translator.
As a consequence of this the unit of code generation of the target language
can be in terms of single instructions in the abstract model.@
@
3)@ICompiler target languages which are easily portable normally achieve
this by restricting their data types and data structures, consequently
these languages often have considerable inefficiency in data storage
mapping and inefficient data access code. In order to obtain efficient
data access code on different machines, and allow heterogeneous data
structures, the target language must be sympathetic to the type
and structure of data.@
@
4)@IThe MUTL abstract model
caters primarily for Fortran, Pascal, Algol and Cobol as well
as the system implementation language MUSL.
An actual implementation
of the model may omit some of the capabilities of the model when they
are not required for the set of high language compilers required at a particular
 installation.
For instance if only Fortran and Algol are required, the target language need
not have decimal arithmetic.
As further compilers based on MUTL are developed, then where necessary
the MUTL model definition will be revised to encorporate new requirements.@
@
5)@IThe communication between the compiler and the target language should be
essentially one way. Restricting the target language in this way means
that the high level language to target code translation and target
code to machine code translation may, where necessary, be completely
separated. There are several advantages of this approach:@
@
@
a)@Ian encoded form of the target language (MUBL) can be utilised in self bootst
rapping
the high level language compilers,@
@
b)@Iin a computer network, compilation for several different machine types
may be done on a central machine, and if the output of the compiler is in the en
coded
target language code, it can be assembled into machine code on the
appropriate execute job machine in the network, and@
@
c)@Ifor small machines, which have a small address space it provides a
natural division of the compiler into two passes.
@BIn the abstract model data is allocated in terms of scalar or vector
quantities, and from these basic data components more complex data
structures are built. The model provides addressing functions to access
such data structures, but the target language provides the
declarative functions for the allocation of data in the abstract model. As
the target language deals with data at this high level, data
accessing on the actual machine can be handled efficiently.
@BThe diagram below illustrates a simplified view of the MUTL model, it basicall
y
consists of registers, stores and a CPU.
@
@3
@U 34
@
           Offstack                                Onstack
           Storage                                 Storage
   @O                           @O                   @O             @O
   |            |            |                   |           |
   |            |            |      @O       @O      |           |
   |            |            |<- - -@O|  D  |@O- - ->|           |@
 ->|Instructions|    Data    |         D         |   Data    |
|  |            |            |         D         |           |
|  |            |            |         D         |           |
|  |            |            |<- -     D     - ->|           |
|  @O|            |            |@O    |    D    |    @O|           |@O
|        I             D          |    D    |         D
|        I             D          |    D    |         D
|        I             D          |    D    |         D
|  @O      I             D          |    D    |         D       @O
|  |                                                         |
 --|                                  CPU                    |
   @O|                                                         |@O
                               D          D
                               D          D
                            @O   D  @O      @O  D   @O
                            | Bo |      | Ao |
                            |    |      |    |
                            |    |      |    |
                            @O|    |@O      @O|    |@O
                            @O| Bm |@O      @O| An |@O
                               B          A
                         Registers      Registers
@
@
DDDDDDD data paths
- - - - store requests
IIIIIII instruction path
@0
@S323.1.1 Registers
@BAs mentioned briefly in the introduction, optimum register
usage on a multiple register machine is best achieved if the
compiler can adapt to the number of different registers available.
Thus the MUTL model has multiple B registers and multiple A registers,
but only a single D register.
At present all issued versions of MUTL implementations only cater
for one B register and one A register.
@BThe A registers operate in one of several modes:@
@Q 7
@
@Minteger
@Nunsigned integer
@Nfloating point
@Nfixed point decimal
@Npointer
@Ngeneric
@BThe B registers are primarily for subscription of data structures.
They operate in integer and unsigned integer modes.
@BThe D is a data selection register that references
into a data structure
in order to access a component from it.
@S323.1.2 Arithmetic precision.
@BTo allow MUTL to be implemented on micro, mini and mainframe computers
the precision of an A register is selected from the following:@
@
@M1, 8 and 16 bits (with integer mode only)
@N32, 64 and 128 bits (all modes of A except decimal)
@Nany byte sized multiple up to 80 bits (decimal).
@
@
An implementation of MUTL need only implement
sufficient arithmetic capability for the
high level languages concerned.
The permitted precisions for B register
are 8, 16 and 32 bits.
@S323.1.3 Instruction and Data Stores.
@BThe model incorporates off-stack storage and on-stack
storage. Instructions are fetched in sequence from the off-stack store and execu
ted
in the CPU, until a control transfer order is executed at which point instructio
n
fetches continue from some other 'labelled' place in the store.
@BData is contained in both stores. The off-stack store generally contains data
that
does not belong to any particular procedure e.g. Fortran Common, and
permanent data of a procedure e.g. OWN in Algol, SAVE in Fortran. The on-stack s
tore
holds the data of all the currently active procedures. Within the stack frame of
 a procedure,
its data is split into three groups:@
@Q 5
@
@Ma) parameters of the procedure
@Nb) variables (scalars, vectors and aggregates)
@N   local to the procedure
@Nc) partial results stored in a LIFO basis.
@S323.1.4 Operand types and lengths.
@BData in store may be considered as a sequence of simple typed
operands, where each operand is either arithmetic or
a pointer.
@BAn arithmetic operand is either:@
@Q 4
@
@Ma) 1 bit long
@Nb) or between 1 and 16 bytes long
@Nc) a string of up to 32 bits.
@BAt operand declaration time type is specified. Arithmetic
operands may be of real, signed or unsigned integer and decimal type.
A 1 bit operand is always of unsigned integer type, real operands
are restricted to precisions of 2, 4, 8 and 16 bytes,
and decimal operands is limited to 10 bytes.
In addition bit string operands are restricted to signed
and unsigned integer types.
@BPointer operands refer to:
data items, labels and procedures. However, the information content
required for such entities differs between high level languages,
consequently six types of pointers are distinguished.
@3
@U 8
@
@
     a) pointer to a data item
     b) bounded pointer to a data item
     c) pointer to a label
     d) pointer plus environment information of a label
     e) pointer to a procedure
     f) pointer plus environment information of a procedure
@0
@S323.1.5 The CPU.
@BThe instruction set is mainly one address and most instructions consist of a
function part and an operand part.
It is fully described in Section 23.9.
Implementors of MUTL code generates should beware that whilst
many MUTL instructions translate into one machine
instruction, and some may translate into several machine
instructions, others such as those concerned with operand
selection and arithmetic mode selection are not expected
to generate any code.
@S223.2 OVERVIEW OF MUTL CONCEPTS
@BIn addition to providing the imperative functions of code generation for
compilers, MUTL provides declarative functions for data
items, procedures, labels etc. Before a specification of the procedural interfac
e
is given, it is necessary to introduce briefly;
compilation units, storage control, the MUTL concept of types, names, machine co
de
efficiency, diagnostic information and MUTL code output.
@S323.2.1 Compilation Units (Modules)
@BThe basic unit of compilation is a module which normally
contains one or more procedures, and a program or library may involve
several such modules.
A module contains the specifications for the entities which are
considered local to the module. Some of these may be indicated as
'exports' in which case they are available for import into
other modules. In order that modules may be compiled independently they
must contain specifications of their imports, which at compile time
are taken on trust. However, these import specifications are passed
to MUTL, so that at load time it can check their consistency with the
corresponding export specifications. The entities referenced in
import or export specifications are called interface entities.
Only areas of store, data items, data types, literals, procedures and
subroutines, and labels may be
interface entities.
In fact areas of store are slightly different from other interface entities in t
hat
they do not belong to any particular module, but are shared between
all modules using them.
@BIt is the symbolic name of the interface entity, specified in characters,
that enables inter-module references to be resolved. Therefore,
each interface entity of one kind must be uniquely
identifiable by its symbolic name.
@S323.2.2 Storage control
@BAs discussed earlier storage is split into off-stack and
on-stack storage.
On activation of a dynamic procedure, a new stack frame is
created to contain its parameters and local variables.
Further space on the stack is obtained as required at
run time by the TL.MAKE function.
The off-stack store is considered by MUTL as a number
of areas into which code is planted and data is statically
allocated.
There are 255 such areas numbered from 1 upwards, from which
current code and data areas are selected as appropriate.
The amount of store allocated in an area while selected as
a current area is known as a partition. The selection of an area as
current defines the start of a partition, and the selection of another area
terminates the partition. An area thus consists of one or more partitions.
@BThe procedure TL.S.DECL is used to statically allocate off-stack and on-stack
data. A portion
of an area (off-stack or on-stack) may be statically allocated as a SPACE so tha
t
at run time variables may be dynamically allocated within it, this is achieved b
y the TL.MAKE function.
@BThe organisation of the stack is the MUTL translators
responsibility. However, non-local accesses will generally involve
static-links, or a display approach, or even a mixture of both methods.
@S323.2.3 Data types
@BIn MUTL there are a set of predefined data types known
as the basic types. Additional types known as aggregate
types may be specified. These consist of a concatenation of several
basic types or previously defined aggregate types.
A variable of aggregate type may, when required, be considered
as a single entity. In general aggregate types may be considered as a
hierarchic structure of types. For variables of aggregate types,
individual fields are identified by their
relative position, counting from zero (at each level in the hierarchy).
Within an aggregate type, fields may have several alternative type
definitions, thus allowing variables to contain variant fields.
@BBasic types are classified into arithmetic and pointer
types. An arithmetic basic type specifies size and mode information (e.g.
16 bit integer) for the data item. Pointer types specify
whether the type of the
data item referenced is a
data, label or procedure item.
There is also a typeless data pointer, but whenever a pointer of
this kind is loaded into the D register, type information must first be given by
 calling
TL.D.TYPE.
@S323.2.4 Allocation of names
@BMUTL names are used to identify and reference many different kinds of
entities, for example data variables, literals, procedures, type
specifications, etc..
There are two sorts of MUTL entities local and global.  Local entities
declared within a procedure or block lose their identity at the end
of the procedure or block in which they are declared.  Global entities
lose their identity at the end of the module in which they are declared.
In order to maintain the one way communication of MUTL, for
reasons specified earlier, MUTL and the compilers use the following
simple algorithm for allocating names within a module.
Names exist as numbers in the range 2 to 1983.
Names for local entities are allocated
consecutively from 2 upwards as local entities are declared. At the end
of procedures and blocks all names allocated for local entities within the proce
dure
or block become undefined, and they are re-assigned consecutively as
new local entities declarations occur.
Names for global entities are allocated consecutively from
1983 downwards.
@BSubject to the non-local accessing restrictions of variables
and labels of procedures (discussed later in section 23.7)
all names currently defined can be referenced regardless of
the level of procedure nesting at which they are defined.
@S323.2.5 Code efficiency and optimisation
@BThe optimisation task is shared between compilers and the
MUTL translator. It is the compilers job to perform global optimisation
techniques, and to produce optimum MUTL code
sequences. The MUTL translator then applies peephole type
optimisation when generating code from those sequences.
@BAs mentioned earlier, the strategy in utilising
multiple registers is to have optimising compilers tune their output
code to the number and type of register available. Thus the
procedure TL.ENQ.REG(23.12) supplies this kind of information about the
compiling environment. Normally a MUTL translator reserves some
actual machine registers for such tasks as stack management,
operand conversion and data accessing, the remaining machine
registers being nominated as MUTL registers. Furthermore to assist
efficient code generation the use of MUTL registers is
deterministic, this is achieved with assistance from the compiler.
@BOn some actual machines the intelligent use of base
registers reduces significantly the size of operand access code
(for example, on the VAX computer when a base register is loaded to a static are
a then
access to an operand relative to the base register costs 2 bytes,
while an absolute operand access cost 5 bytes).
However, when the number of base registers is limited then
global analysis is necessary in determining an optimal
strategy for base registers.
Thus there is a diochotomy in that it is the compiler's role
to perform global analysis but as the operands
in the MUTL interface are at a high level, code
generation details of operand accesses are a
MUTL function. The solution to this is to have a set of
MUTL base registers, and as with A and B registers the number of
base registers is dependent on the actual machine and is
obtained by calling TL.ENQ.REG.
A MUTL base register is loaded either with the
address of a MUTL segment or the address of a frame on the
stack, this is done under the guidance of the compiler.
@BTo use base registers effectively for accessing non-local
operands on the stack the compiler needs to cater for
static-link and display based stack organisations.
A compiler should not load a base register for accesses
within the currently active frame or any frames covered by
the display; the procedure TL.ENQ informs the compilers of
how many procedural textual levels are covered by the display.
In accessing an operand covered by a base register MUTL may then
plant an access relative to a
base register.
@S323.2.6 Program error detection and diagnostics.
@BThe checking for possible program errors is normally done by
a mixture of hardware and software. MUTL normally provides some of
the software checking, and control of this checking by compilers may be required
.
The MUTL procedure TL.CHECK provides this
control.
@BThe run time diagnostic procedures in MUTL
provide primitives to support machine
independent diagnostic software for such tasks as producing compile and data map
s,
debugging (batch and interactive), and profiling.
Therefore source language reference information such as data
item symbolic names, procedure symbolic names
and source line numbers are passed into MUTL during compilation,
this and the relevant declarative information is retained
at the end of compilation if run time diagnostic support is required.
@S323.2.7 MUTL Code Output.
@BThe forms of code output produced by MUTL depends largely
on the requirements of a particular installation.
@BA compilation produces either all or part of a program
or a library.
When compiling a library,
a directory is automatically generated for the
libraries interface. Apart from the directory structure,
programs and libraries are similar. The code at the outer textual
level of a compiled library (i.e. not embedded in a procedure) is
executed, as initialisation code for the library,
whenever it is loaded.
The definition of library and program files in achieved
by MUTL calling procedures in the Library Organisation section of the
MUSS Library.
@BMUTL views a program or library as a collection of MUTL
segments, these segments are numbered 0, 1, 2 etc.
The model of a program is of MUTL segment 0 containing code
while other segments normally contain data, but may contain code. Entry to
a program is always via MUTL segment 0, therefore any entry
and exit sequence code concerned with running a program is
added to segment 0 by MUTL.
The model of a library is of MUTL segment zero containing a
library entry table, followed by
code for the library procedures. There is a directory structure
created for the library, but its placement and organisation
is dependent on the library organisation for a particular machine.
Entry to the library initialisation code is always via
MUTL segment 0, therefore, any entry and exit sequence
code necessary is added to segment 0 by MUTL.
@BMany situations arise where it is necessary for the user to
exercise control over the mapping of the module areas into actual
storage. Examples of this need are in overlaying for
machines with limited address space, and the creation of operating
systems where strict control of the placement of areas is required. In
some high level languages such control is a language feature, while in
others, where it is necessary, control is provided either by compiler
directives or by job commands. The procedures in 23.4
enable the compiler to control the placement of compilation
output.
@S223.3 TYPE DEFINITIONS
@BThe procedures in this section enable aggregate types
to be defined and a MUTL name allocated.
In other contexts where the type of an entity has to be given,
a MUTL TYPE SPECIFIER is used. This is an encoded 14 bit integer
whose least significant two bits indicate whether the specifier
relates to@
@Q 6
@
@M0  an entity of the given type
@N1  a pointer to an entity of the given type
@N3  a bounded pointer to a vector of entities of
@N   given type.
@
@
The other part of TYPE SPECIFIER either defines a basic
type or the MUTL name of a user defined type. Basic
types have values which are either less than 64 or greater than 2047 (shifted le
ft two places to
accommodate the two bits defined above). Thus in order that
they may be distinguished user types are actually
represented by their MUTL name + 64 (again shifted left
two places).
Thus a TYPE.SPECIFIER for basic types whose size is specified
as one or more bytes is encoded as:@
@Q 9
@
Bits 2-5@Ispecify the size of the type as the number of bytes
less one (e.g, 1 means a 2 byte type)@
@
Bits 6-7@Ispecify the type mode.@
@I0 - real@
@I1 - signed integer@
@I2 - unsigned integer@
@I3 - signed fixed point decimal with a
representation of a decimal digit per nibble
with one nibble for the sign, thus a 7 byte
decimal represents a signed 13 decimal digit number.@
@
Bits 8-13@I0@
@
As real types are restricted to 2, 4, 8 and
16 bytes, the above leaves 48 spare encodings. Some of these
are utilised as follows:@
@3
@U 11
@
@X%`
          %20 - denotes a 1 bit scalar
@
          %01 - Typeless data pointer.
          %03 - Typeless unbounded data pointer.
@
          %24 - Pointer to a procedure.
          %28 - Pointer to a procedure and its environment.
          %2C - Pointer to a label.
          %30 - Pointer to a label and its environment.
@X%%
@0
@BA TYPE.SPECIFIER for basic types whose size is specified as a bit
string is encoded as@
@
Bits 2-5@I0@
@
Bits 6-7@Ispecify the type mode@
@I1 - signed integer@
@I2 - unsigned integer@
@
Bits 8-12@Ispecify the size of the type as the
number of bits less one (e.g. 2 means a 3 bit type).@
@
Bit 13@I1
@
@
1) @JTL.TYPE([SYMB.NAME],NATURE)
@BThis starts the specification of an aggregate type
and allocates a MUTL name for the type, unless one had previously
been allocated for it. Type
specifications themselves may not be nested, but an aggregate type may include
previously defined types and pointers to types which are
not yet fully specified.
The constituent types of the aggregate are
added by calling TL.TYPE.COMP repeatedly.
During the specification of a type only calls to the MUTL
procedures TL.TYPE.COMP and TL.END.TYPE are permitted.
@BThe second parameter specifies whether the type is
internal to the module, an export from
the module, or an assumed type from another
module.
A type may be imported
without its type detail being re-specified in this module
in which case there are no further calls to TL.TYPE.COMP
or TL.END.TYPE; this situation arises when the language
compiler need not be aware of the type details in compiling
a module.
@BAn @5incremented@0 type is an aggregate type where the type
specification is given incrementally over several modules.  For an
incremental type a skeleton specification is first given for the
type so that MUTL knows it's overall size for code generation
purposes.  The actual specification is built up incrementally by
modules adding fields to the type.  If a module adds fields to an
incremental type it cannot access directly any of the other fields
added by other modules.
@BNote that a type specification containing no fields is permitted.
@BThe position of a component, counting from zero, within
the type definition
is used in accessing it.
@
@T% 30
@SParameters:-
@
[SYMB.NAME]@IBounded pointer to a byte vector containing
the symbolic name in characters of the type.
When the type is an interface entity the
symbolic name identifies the type, it is also
retained in the symbol table for run time
diagnostic purposes.@
@
NATURE@IBit 14 = 1 type exported from module.
Bit 15 = 1 type of an assumed
entity to be imported.@
@
Bits 0-13@
@X%`
@I%0000 means a MUTL name is to be allocated
and its type specification follows immediately.@
@I%0001 is as %0000 except that the type has no alternatives
and contains only one field. In referencing this type selection
of the contained field is automatic, i.e. no SEL FLD is necessary,
such a type is known as an automatic type.
This feature enables compilers to create extra
types to assist in type checking and for defining
enumeration types.@
@X%`
@I%1000 means a MUTL name is to be
allocated and its type specification is
not specified in this module; MUTL obtains
the specification from the export of the
type from another module.@
@I%2000 means a MUTL name is to be allocated
but its type specification is given
later in the module.@
@I%3000 indicates fields are to be added to an incremental
type.  A MUTL name is allocated and further fields are added
to the type's specification by calling TL.TYPE.COMP to add each
new field, and then finally calling TL.END.TYPE.  Within the
module the newly added fields are referenced by ascending
field numbers 0, 1, 2 etc, regardless of how many fields there
are already in the type.@
@I%0002 to %07FF means the type specification
now follows for the MUTL name specified
in bits 0-10, which had previously been
allocated with %2000 specified for this
field.@
@I%3002 to %37FF is as %0002 to %7FF except that fields
are to be added to an incremental type as in %3000 above.
@SExample:
@BTo create a type T consisting of a vector of two integers (4
bytes each) TVI, and a vector of three reals (8 bytes each) TVR.@
@U 5
@
          TL.TYPE(["T"],0)
          TL.TYPE.COMP(%4C,2,["TVI"])
          TL.TYPE.COMP(%1C,3,["TVR"])
          TL.END.TYPE(0)
@BA type S consisting of an integer (4 bytes) SI, and a ten element
vector SVT where each element is of type T can then be created by:@
@U 6
@
          TL.TYPE(["S"],0)
          TL.TYPE.COMP(%4C,0,["SI"])
          TL.TYPE.COMP(MUTL NAME of T*4+256,10,["SVT"])
          TL.END.TYPE(0)
@
The ten element vector is referenced as the second component of S
(i.e. SEL FLD 1).
@X%%
@
@
2) @JTL.TYPE.COMP(TYPE,DIMENSION,[SYMB.NAME])
@BAdds the next component to the current aggregate type
specification. The first two parameters specify the type of the component.
@SParameters:-
@
TYPE -@IBits 0-13 give a TYPE SPECIFIER as
described above at the start of 23.3.@
@IBit 14 a value of one means that P3 specifies
a list of names for an enumeration type.@
@
DIMENSION -@I0 :scalar@
@I>0:vector, parameter specifies number
of elements.@
@I-2048:vector, current literal specifies number of elements.@
@IOther negative values: vector, the parameter is the negated MUTL
name of a literal whose value gives the
vectors dimension.@
@
[SYMB.NAME] -@IBounded pointer to a byte vector containing
the symbolic name in characters of the
component, or a list of symbolic names
for the names of an enumeration type (each name in the
list is terminated by a zero valued byte). This parameter is
for run time diagnostic purposes only.
@
@
3) @JTL.END.TYPE(STATUS)
@BTerminates the addition of fields to the aggregate type
currently being defined.
STATUS indicates the end of a type specification, the end of an
alternative within the type, or that the type specification is the
skeleton of an incremental type.
@SParameters:-
@3
@U 6
@
STATUS 0 - end of type specification, or end of fields
           being added by this module to an incremental type.
STATUS 1 - another alternative type specifications follows
       2 - indicates a skeleton specification for an
           incremental type.
@0
@S223.4 STORAGE MAPPING
@BAs previously explained in 23.2 MUTL plants code and literals
within the current code area and allocates
statically mapped storage within the current data area.
All areas are placed in MUTL segments. The procedure TL.SEG
introduces a MUTL segment into the compilation, while the
procedure TL.LOAD specifies into which MUTL segment a
particular area is placed.
Thus
a modules areas may
be mapped to several MUTL segments and a MUTL segment may contain areas from
several modules. The characteristics of a MUTL segment are that it occupies,
when in store at run time, a contiguous address space and all parts
of it have the same level of protection (e.g. same level of protection
and overlay type) and similar items throughout the space are accessed
in an identical manner.
Note that if there is more than one area mapped to a MUTL segment the partitions
 of an area may not be allocated
contiguously within the MUTL segment, and generally the
currently selected data and code areas should not be mapped to the
same segment
as interleaving may occur of code and data.
Normally each data declaration can be considered as unrelated
from other data declarations, but for off-stack data involved in a
Fortran type EQUIVALENCE it implies a specific ordering of the data.
Therefore the TL.EQUIV.POS is provided to permit the declaration
point of a variable to be specified explicitly within an off-stack
data area.
@
@
1) @JTL.SEG(SEG.NUMBER,SIZE,RUN.TIME.ADDR,COMP.TIME.ADDR,KIND)
@BIntroduces a segment into the compilation.
These are known as MUTL segments and have numbers in
the range 0 to 31. On introducing MUTL segment 0
initialisation code concerned with compiling a
program or library is planted automatically by MUTL.
@SParameters:-
@
SEG.NUMBER@INumber of MUTL segment.@
SIZE@ISize of MUTL segment in bytes.
On machines where control transfers between
virtual store segments is severely restricted (e.g.
procedure calls only) the maximum size of a
MUTL segment is normally limited to
that of a virtual store segment, whereas for
other machines a MUTL segment may span
several consecutive virtual store segments.
A size of zero means a segment of default size is created.@
RUN.TIME.ADDR@Iof MUTL segment specified in bytes.
A value of -1 means that the segment's
address will be allocated automatically.@
COMP.TIME.ADDR@Iof MUTL segment specified in bytes.
A non negative value specifies the
compile time address for the MUTL segment.
A value of -1 means the compile time
address will be automatically allocated;
a value of -2 means that the MUTL segment
need not be allocated at compile
time as no code production or
static data initialisation occur for
this MUTL segment;
and a value of -3 is similar to -2
except that on loading a program or library
for execution the MUTL segment is not
introduced automatically by the loading
mechanism into the execution environment.@
KIND@IThis parameter specifies the properties
of the MUTL segment.@
@IBit 1=1 means that the MUTL segment at
run time requires execute access.@
@IBit 2=1 as Bit 1 but for read access.@
@IBit 3=1 as Bit 1 but for write access.
@
@
2) @JTL.LOAD(SEG.NUMBER,AREA.NUMBER).
@BThis procedure specifies into which MUTL segment the partitions
of an area will be mapped.
If the MUTL segment has not been defined a MUTL segment
is created with default parameters i.e. TL.SEG(SEG.NUMBER,0,-1,-1,0).
The mapping of an area must be given before
the area is used.
@BWhen modules are bound together then once an area
segment mapping is established it applies to all modules
following until a new mapping is given.
@SParameters:-
@
@T% 10
SEG.NO@ISegment number.@
AREA.NO@IArea number of current module, if between
modules then of next module compiled.
@
@
3) @JTL.CODE.AREA(AREA.NUMBER)
@BNominates the current code area and sets the current position to the
next available location within it.
@SParameters:-
@
AREA.NUMBER
@
@
4) @JTL.DATA.AREA(AREA.NUMBER)
@BThis procedure nominates the area specified as the current data
area and sets the current position within the area.
Statically allocated variables are mapped to the current position
in the currently selected data area.
@SParameters:-
@
@T% 30
AREA.NUMBER@I- > 0 Area number@
@I- 0 stack frame of the current procedure@
@I- < 0 stack frame of procedure whose textual level is
[current procedural textual level - AREA.NUMBER]@
@
@
5) @JTL.COMMON([SYMB.NAME],SIZE,NATURE)
@BThis procedure associates a symbolic name with
a data area, such an area is termed a 'common area'.
To declare variables in a common area, TL.COMMON is first called, then
calls on TL.S.DECL declare variables, finally a call on
TL.END.COMMON indicates the end of a declaration set
within the common area.  In a compilation sets of
declarations can be given several times for the
same common area.
Storage is allocated from the start of the named data
area each time.
@BThe first call of TL.COMMON for a particular common area
defines its mapping this is either explicit or performed
by MUTL.
@BThe total storage requirement for a common area is normally
defined by the first declaration set for that common.
All other declaration sets for the common must not exceed
this storage limit.  To override this restriction the common
area may be nominated as a flexible common area.
@
@
Parameters:-
@
@
@T% 30
@
[SYMB.NAME]@IBounded pointer to a byte vector containing the
symbolic name in characters of the common area.  An unnamed
common area is allowed; this is specified by a nil pointer.@
@
SIZE@ISize of common area for inflexible common areas.@
@
NATURE@IBit 15 = 0 Common area is flexible.@
@IBit 14 = 1 TL.COMMON specifies mapping information only, i.e.
there are no immediately following calls to TL.S.DECL or TL.END.COMMON.@
@IBit 0 - 13 On the first call of TL.COMMON for a particular
common area a non-zero value gives the number of the data area to
which the common is mapped; if the value is zero, MUTL maps the
common area itself.  For subsequent TL.COMMON calls for a common
area this value must be zero.
@BFor some MUTL implementations flexible common areas involve
significant overheads, in which case flexible usage is normally
restricted to the unnamed common area.
@
@
@
6) @JTL.END.COMMON()
@BThis procedure ends a declaration set for a common area.
@
@
@
7) @JTL.EQUIV.POS(POSITION)
@BThis procedure resets the current position of the current
area to the position specified.
The data area to which it applies must be off-stack.
@SParameter:-
@
POSITION:@IPosition from start of area specified
in bytes.
@S223.5 STATIC DATA STORAGE DECLARATION
@BVariables declared at the outer level of a module are
available to all procedures within the module. For variables declared within
a procedure, the kind of procedure determines whether its
variables may be accessed non-locally.
@
@
1) @JTL.SPACE(SIZE)
@BSpace is statically allocated in the current
data area, which could be either on-stack or off-stack, and
an integer variable is declared to keep track
of the run time usage of the allocated space.
A MUTL name is allocated for the SPACE and this name can be used in
imperative functions (e.g. TL.PL) to control usage of the space. Structures are
created dynamically in the space by the TL.MAKE procedure.
@SParameters:-
@
SIZE@IWhen positive it specifies the size in bytes
of the SPACE@
@IWhen negative it is the negated MUTL name of a
literal whose value gives the size of the SPACE
in bytes.
@
@
2) @JTL.S.DECL([SYMB.NAME],TYPE,DIMENSION)
@BThis procedure declares a variable which
may be a scalar or a vector of basic or
aggregate type. A MUTL name is allocated for the variable.
For variables of a known dimension then,
unless the declaration is for an assumed interface entity
of another module, storage is allocated for it within the
currently selected data area.
For variables of an unknown dimension then it is the
set of values that statically initialise the variable
that determines its size.
@SParameters:-
@
[SYMB.NAME]@IBounded pointer to a byte vector
containing the variables symbolic name
in characters. It is used to identify
the interface entity and for run time
diagnostic identification.@
@
TYPE@IBits 0 - 13 is a TYPE SPECIFIER,
see 23.3 for its encoding unless Bits 14, 15 = 3.@
@
@IBit 14, 15 = 1 Data item to be exported
as an interface entity@
@IBit 14, 15 = 2 Declaration of an assumed
interface entity imported from
another module.@
@IBit 14, 15 = 3 Data item to be exported as an
interface but it is already declared as an import in
this module.@
@IBits 0 - 11 gives its MUTL name.@
@
DIMENSION@I= 0: Scalar@
@I> 0: Vector, dimension
defined explicitly@
@I-1: Dimension of initialised vector unknown. Value initialisation
determines actual dimension.
Storage is allocated at initialisation time.@
@I-2048: Vector, dimension defined by current literal.@
@I-4096: Initialised scalar with storage allocated
at initialisation time.@
@IOther negative values: vector, parameter is the negated
MUTL name of a literal whose value
gives the vectors dimension.
@
@
3) @JTL.V.DECL([SYMB.NAME],POSN,PRE.PROC,POST.PROC,TYPE,DIMENSION).
@BThis procedure enables MUSL V-store variables to be defined and
MUTL names allocated to them. After declaration they may then be treated
by MUSL as ordinary variables in imperative statements. A V-store
variable is a special control/status register of the MUSS
ideal machine (refn. MUSS VOL.1)
that can in general be read or written. If the real machine has an
actual control/status that is exactly equivalent, the V-store variable
may be mapped directly to the actual register. If the correspondence is not
exact then the V-store is mapped onto an ordinary store line. In this
case it may be necessary to update the store line before a read access
and to propagate the implied actions after a write access. Therefore,
associated with each V-store of the ideal machine there is, a store line
address, and optionally a procedure (PRE.PROC) to be called before a read access
,
and optionally a procedure (POST.PROC) to be called after a write access.
@BThe read and write subroutines associated with V-store
variables which are vectors generally need to know the index
number of the element to be acted upon. Therefore, on entry to such
procedures MUTL makes the index number available. Within the
subroutine the index number is obtained by specifying an operand
@X%`
of %1002, known as V.SUB, in the operand description of TL.PL.
@X%%
@BIn the implementation of index number passing, whenever the
actual machine architecture permits it, the index should be
passed in the register that corresponds to the B register
in the MUTL model, and an implementor of MUTL may assume that
any B register use within a PRE.PROC or POST.PROC destroys the passed
index value.
@BLike other data variables V-store variables may be interface entities.
@SParameters:-
@
[SYMB.NAME]@IBounded pointer to a byte vector containing
the variables symbolic name in characters.
It is used solely to identify the interface
entity.@
@
POSN@IActual store line associated with V-store
variable. This may either be a previously
declared variable or the address of a
store line. Thus the parameter may
either be the MUTL name of a variable
or a literal, or a zero which means the
current literal gives the store line address.@
@
PRE.PROC@IMUTL name of the subroutine to be called before a
read access. A value of zero means no subroutine
call on a read access.@
@
POST.PROC@IMUTL name of the subroutine to be called after a write
access. A value of zero means no subroutine call
on a write access.@
@
TYPE@IBits 0-13 is a TYPE SPECIFIER, see
23.3 for details.@
@IBit 14=1 V-store variable to be exported
as an interface entity.@
@IBit 15=1 V-store variable to be imported
as an interface entity.@
@
DIMENSION@I= 0: V-store is a scalar variable.@
@I> 0: V-store is a vector variable,
the parameter specifies the dimension.@
@I-1: V-store is a vector variable but its
dimension is unknown, this is only permitted
on imports.@
@I= -2048: V-store is a vector variable, its
dimension is given by the current literal.@
@IOther negative values: V-store is a vector variable, the
parameter is the negated MUTL name
of a literal whose value is the vector's
dimension.
@
@
4) @JTL.MAKE(SPACE,TYPE,DIMENSION)
@BThis procedure plants code to create at run time
a mapping for a variable either at the top of the current stack frame or
in a previously declared space. For the latter
the integer control variable of the SPACE
is updated to the next available storage
location. Yielded in the D register is a
pointer to the variable.
@SParameters:-
@
SPACE@IThe MUTL name of a SPACE (i.e. SPACE > 1) or
zero means allocate at the top
of the stack frame.@
@
TYPE@ITYPE SPECIFIER, see 23.3 for
its encoding.@
@
DIMENSION@IA value of zero means make a scalar
variable and yield in the A register
an unbounded pointer to it. A non zero
value means make a vector variable and
yield in the A register a bounded pointer
to it. A positive DIMENSION specifies the
number of elements that the vector is to
contain, whereas a value of -1 means that
the value of the B register on 'making'
the vector determines the number of elements
in the vector.
@
@
5) @JTL.SELECT.VAR().
@T% 10
@BThis procedure notionally declares a SELECT variable
and allocates a name for it. A SELECT variable is used to save
data structure selection information held in the D register for
later use. This variable may only be used in D= and D=> instructions.
In a selection instruction sequence involving SEL EL, SEL FLD and
SEL ALT, a 'D=> SELECT variable' saves the current selection information
of D. A 'D= SELECT variable' reloads into the D register the previously
saved selection information.
@BBefore a 'D= SELECT variable' instruction is planted in the code a
corresponding D=> to the same SELECT variable must have already been
planted. During run time of the code on executing a 'D= SELECT variable'
instruction, the SELECT variable must have previously been assigned by
the immediately preceding D=> to the same SELECT variable in the code;
in other words, information in a SELECT variable has a static scope.
@
@
6) @JTL.SELECT.FIELD(BASE,ALTERNATIVE,FIELD)
@BThis procedure allocates a MUTL name for a field
within a data structure pointed to by the
BASE parameter.
@SParameters:
@T% 30
@
BASE@IMUTL name of a Select variable which specifies
the containing data structure of the required
field.@
@
ALTERNATIVE@IIf the containing data structure
is of union type, this specifies the
alternative, counting from zero, required.@
@
FIELD@INumber, counting from zero, of field required.
@
@
7) @JTL.SET.TYPE(MUTL.NAME,TYPE)
@BThis procedure is called to supply information about an entity
(variable or parameter) which was not available at entity declaration time.
The procedure is used as follows:@
@
@T% 10
1)@IA variable or parameter may be declared to be a pointer to
an unknown data type, this procedure is called to set the data type.@
@
2)@ITo reset the data type of a 64 bit logical variable or parameter.
@SParameters:-
@3
@U 22
@
NAME      MUTL name of variable or parameter.
@
TYPE      If bits 0-13 are non-zero then
          for typeless pointers TYPE is as follows
@
          Bits 0, 1      1 Scalar instance of a type
                         3 Vector instance of a type
          Bits 2-13      encoded as in paragraph 23.3.
@
          and for 64 bit logical variables and parameters, this
          is restricted to basic types of a size not greater
          than 8 bytes and pointer types.  Bits 0-13 contain a
          TYPE SPECIFIER, see paragraph 23.3 for its encoding.
@
          If bits 0-13 are zero then bits 14-15
          respecify the interface attributes of the
          variable.

          Bit 14,15 = 0 Variable not an interface item
          Bit 14 = 1    Variable is an export
          Bit 15 = 1    Variable is an import.
@0
@BRespecification of interface attributes is restricted to promotion
of an import to an export and removing the import attribute.
@
@
8) @JTL.ASS(MUTL.NAME.OR.TYPE,AREA.NUMBER).
@BThis procedure is used to nominate a variable or a
user defined type for the current user defined type literal to
which value assignment procedures refer. During value assignments
there is the concept of a current assignment position. Normally
value assignments start at the first component of the item, but
any point can be selected as the current assignment
position by calling TL.ASS.ADV appropriately.
@BIf the variable was declared in TL.S.DECL as an
vector of unknown dimension, then storage is
allocated for the vector when initialisation commences,
and the size of the vector is then determined by the
set of values assigned. For such variables MUTL assumes that
complete value assignment occurs at the same time.
@SParameter:-
@T% 30
@
MUTL.NAME.OR.TYPE@IIf bit 14 is zero then bits 0-11 is a
MUTL name of an off-stack data variable.
If bit 14 is one then bits 0-13 is a TYPE
SPECIFIER, see 23.3 for its encoding, of the
current user defined type literal.@
@
AREA.NUMBER@IThis specifies the area number in which to
allocate storage for vectors of unknown size.
A value of -1 means allocate in current code
area, and -2 means allocate in current data area.
@
@
9) @JTL.ASS.VALUE(NAME,REPEAT.COUNT)
@BAssigns the values as specified by the NAME parameter to
the components starting at the current assignment position within the
literal or variable being assigned to, and advances the current
assignment position accordingly. The second parameter
allows this to be repeated.
@BNormally the NAME represents a single value, the exception
to this is when the components being assigned to have a size
of one byte, in which case the NAME can specify the current
basic type literal which had previously been defined to
represent multiple
byte size values (see Section 23.6).
@SParameters:-
@
NAME@IThe type of name permitted is dictated by the type of the current
component having its value assigned.@
@IFor components of arithmetic basic type, the name is that of
a previously defined literal, and
a NAME of zero or one means the current basic type literal.
It is the type of the literal that dictates how the
component is assigned a value. This means that logical literals
are right justified within the component, with zero padding
and truncated where necessary; similarly for integer literals,
but with sign extension instead of zero padding; and for real
literals, generally, these are left justified with zero padding
and truncated where necessary.@
@IFor components of label type, the name is that of
a label,
or the current literal with a null label pointer value.@
@IFor components of procedure type, the
name is that of an actual procedure or the current literal
with a null procedure pointer value.@
@IFor components of pointer type, the name is that of an
statically allocated data item, in which case the assigned value is a
pointer to the data item, or the current literal
with a null data pointer.@
@
REPEAT.COUNT@INumber of times the values associated
with the first parameter are assigned.
If this parameter is positive
the parameter itself is the repeat count, else a
negative parameter indicates that the
repeat count is that of a named literal in
which case the parameter is the negated MUTL name.
@
@
10) @JTL.ASS.END().
@BThis procedure is called to indicate the end of assignments.
@
@
11) @JTL.ASS.ADV(NO).
@BThis procedure advances the current assignment position over the
specified number of basic type components of the literal or variable
being initialised.
@SParameter:-
@
NO@INumber of basic type components to be advanced over.@
@S223.6 LITERAL DECLARATIONS
@BThe procedures in this section provide for the declaration
of literals and the compile time evaluation of literal expressions of integer ty
pe.  First a value must be assigned to the current
literal, then a MUTL name is assigned to the
current literal. This two stage approach is necessary
because the current literal is used in other contexts.
Literals of basic type and user defined type are
defined in this way. There are two current literals,
one of basic type and one of user defined type.
@
@
1) @JTL.C.LIT.16(BASIC.TYPE,VALUE.16)
@
@
2) @JTL.C.LIT.32(BASIC.TYPE,VALUE.32)
@
@
3) @JTL.C.LIT.64(BASIC.TYPE,VALUE.64)
@
@
4) @JTL.C.LIT.128(BASIC.TYPE,VALUE.128)
@BThese procedures are used to define the value of the current
basic type literal. The first parameter specifies the type of the current
literal. The size of the basic type value can be smaller
than the size of the value parameter, in which case the value
is right justified within the parameter.
@SParameters:-
@
BASIC TYPE -@IBits 2-7 specify a Basic arithmetic scalar
type for the value. These are encoded as
bits 2-7 of basic type specifications.
In a cross compiling situation conversion of character
values will be necessary when the compiling and
target machines have a different character set.
Compilers indicate character values by setting Bit 0.@
@IBit 0 = 1 means value specified as a
character string.@
@IBit 0 = 0 means value in binary.@
@
VALUE.16 -@IValue of current literal@
VALUE.32@
VALUE.64@
VALUE.128
@
@
5) @JTL.C.LIT.S(BASIC.TYPE,[VALUE]).
@BThis procedure provides an alternative way of defining the
current basic type literal value.
To expedite the initialisation of byte vectors, this
procedure also permits the 'current literal' to be a sequence
of byte sized values.
@SParameters:-
@
BASIC.TYPE@ISee BASIC.TYPE of above procedures
TL.C.LIT.16, etc...  In addition if bit 1
is set then the bytes from the value are taken in sequence
and arranged so that a stored value would have these bytes in an
ascending address sequence.@
[VALUE]@IA bounded pointer to a byte vector.
If the literal type does not have a
size of one byte the current literal
consists of a single VALUE, the size
in bytes of the literal type and
VALUE must be the same. Otherwise the
length in bytes of the [VALUE]
parameter determines the number of byte
sized values associated with the
current literal.
@
@
6) @JTL.C.NULL(TYPE)
@BThis procedure assigns a 'null' pointer value to the
current basic type literal.
@SParameters
@
TYPE@ISpecification of a pointer type, see
23.3 for its encoding.
@
@
7) @JTL.C.TYPE(BASIC.TYPE,KIND,TYPE)
@BThis procedure defines the current literal whose type is specified
by the first parameter with information about a data type. Zero in
KIND sets the current literal to the size in bytes and a one in KIND
sets it to the boundary alignment in bytes of a data type, whose
TYPE SPECIFIER is given by TYPE.
@SParameters:-
@
BASIC.TYPE@ISee 23.3 for its encoding.@
KIND@ISpecifies information required.@
TYPE@ISee 23.3 for its encoding.@
@
@
8) @JTL.C.DATA(BASIC.TYPE,MUTL.NAME,ELEMENT.NO)
@BThis procedure defines the current literal whose value type is
given by the first parameter with a value which is the address of a
static data structure.  If the data structure is a vector then the
address of a particular element may be obtained.
@
@T% 30
@
Parameters:-@
@
BASIC.TYPE@ISee 23.3 for its encoding.@
MUTL.NAME@IMUTL name of a static data structure.@
ELEMENT.NO@I> 0: Element number of vector@
@I-2048: Element number specified by current literal.
@
@
@
9) @JTL.LIT([SYMB.NAME],KIND).
@BThis procedure allocates a MUTL name for a literal which
has the value and type
of the current literal.
For literals of basic type then the above procedures 1) to
6) specify the literal value. For literals of user defined
type then the TL.ASS procedures 9) to 11) specify the
literal value.
@BFor imported literals the value is optional. When the value
is present it is checked against the exported literal value.
@SParameters:-
@
[SYMB.NAME]@IBounded pointer to a byte vector containing
the literal symbolic name in characters.
This is also used if the literal is an
interface entity.@
@
KIND@IBit 14=1 Literal to be exported as an interface
entity.@
@IBit 15=1 Literal to be imported as an interface
entity.@
@IBits 0-13 A value of zero means it is a basic
type literal and a value of 2 means it is a user
defined type literal, in both these cases the
literal value is that of the appropriate current
literal. For imported literals any other value is
interpreted as a TYPE SPECIFIER, see 23.3 for its
encoding, of the literal and no value is given.
@
@
@
10) @JTL.CALC(OP.CODE,OPERAND)
@BThis procedure provides compile time evaluation of literal
expression within MUTL.  Expressions are evaluated in 32 bit
integer precision in a literal accumulator.  Operands in the
expression must be of integer or logical type.  A stack of
literal values is available for holding intermediate values
of an expression.
@
@T% 30
@
Parameters:-@
@
OPCODE@IOperation codes are a subset of the integer operation
codes allowed in the procedure TL.PL and are as follows:@
@
@Q 19
@3
@I@O               @O@
%@O|   0  |  =>  |@O@
%@O|   1  |  =-  |@O@
%@O|   2  |   =  |@O@
%@O|   3  |  -=  |@O@
%@O|   4  |   &  |@O@
%@O|   5  |   V  |@O@
%@O|   6  |  <<  |@O@
%@O|   7  |  >>  |@O@
%@O|   8  |   +  |@O@
%@O|   9  |   -  |@O@
%@O|  10  |  -:  |@O@
%@O|  11  |   *  |@O@
%@O|  12  |   /  |@O@
%@O|  13  |  /:  |@O@
%@O|  14  |  ==  |@O@
%@O|  15  | COMP |@O@
%@O|  71  | STACK|@O@
@0
@
@ISee description of TL.PL procedure for meaning of operation
code symbols.@
@
@IThe STACK operation code pushes the value of the literal
accumulator onto the literal stack.@
@
OPERAND@IOperands are a subset of the operand parameter of the
TL.PL procedure.  Permitted operands are:@
@I0 Current literal@
@I>1<2048 MUTL name of literal@
@X%|
@T| 30
@I%1003 Pop the literal value from the top of the literal stack.@
@X%%
@
@T% 30
@IFor the next six operands a pair of literal operands are
popped from the literal stack and one of them, depending on T, is
loaded into the literal accumulator and the other is discarded.  Let
TRUE and FALSE represent these two values, TRUE is pushed onto
stack before FALSE.@
@
@X%|
@T| 30
@I%1008 ACC = TRUE if T implies =, otherwise ACC = FALSE@
@I%1009 ACC = TRUE if T implies /=, otherwise ACC = FALSE@
@I%100A ACC = TRUE if T implies >=, otherwise ACC = FALSE@
@I%100B ACC = TRUE if T implies >, otherwise ACC = FALSE@
@I%100C ACC = TRUE if T implies =<, otherwise ACC = FALSE@
@I%100D ACC = TRUE if T implies <, otherwise ACC = FALSE@
@X%%
@
@IOperand restrictions:@
@
@I1) The => opcode has the current literal as it's operand.
@S223.7 PROGRAM STRUCTURE DECLARATIONS
@BThere are basically three types of program structures; namely
procedures, subroutines and blocks.
@BA @5procedure@0 may have parameters and a result.
Procedures
are further classified with regards to the permitted non-local availability
of their variables,
and also whether a procedure is static or potentially recursive.
The local namespace is created dynamically on entry to a
potentially recursive procedure.
The non-local accessibility of a procedures variables is
at one of the following levels.@
@T% 10
@
I)@INo non-local variable access.@
@
II)@INon-Local variable access permitted.@
@
If the procedure kind is not specified explicitly, then by default its
variables may not be referenced non-locally.
@BA @5subroutine@0 has no parameters and no stack frame of its own,
but it may have a result and be called recursively.
For subroutines that are only invoked from the code of the
immediately enclosing procedure the code of the subroutine
may access (as local variables) the variables of the enclosing procedure,
for all other subroutines such access is prohibited.
@BThe same set of procedures are used to define procedures
and subroutines.
@BA @5block@0 is a delimited sequence of code.
The block has no name and is not referenced from control
instructions. Any labels or variables declared within the block
are only accessible within the block, but the variables of the
enclosing procedure, if there is one, are still accessible as locals from
within the block.
@
@
1) @JTL.PROC.SPEC([SYMB.NAME],NATURE)
@BA specification must be given before a procedure
(or subroutine) is either defined
or referenced. A procedure (or subroutine) specification
consists of one call
to TL.PROC.SPEC,
followed immediately by the
appropriate number of calls to TL.PROC.PARAM
to specify its parameters,
and terminates with a call to TL.PROC.RESULT which indicates
the end of the parameters and also specifies the result type.
Of course for a subroutine specification there are no calls to
TL.PROC.PARAM.
@BA procedure (or subroutine) definition starts with a call to TL.PROC.
For procedures its kind is specified, unless the default kind of procedure is
required, by calling TL.PROC.KIND before the first imperative instruction
of the procedure is planted. Finally, TL.PROC.END is called at the
end of the procedure (or subroutine).
@BThe symbolic names of parameters, these are used for diagnostic
purposes only, are supplied to MUTL by calling TL.PARAM.NAME during
the procedure definition, i.e. in between calls of TL.PROC and
TL.END.PROC.
@BThis procedure normally allocates a name for the declared procedure (or subrou
tine).
@T% 30
@SParameters:-
@
[SYMB.NAME]@IBounded pointer to a byte vector containing
the characters of the procedures (or subroutines)
symbolic name.
It is used to identify the procedure (or subroutine)
if it is an interface entity,
for runtime diagnostic identification,
and for constructing a directory
of a library if this procedure is
part of its interface. To permit
abbreviated names to be used to
identify library procedures, then the
name supplied to MUTL contains both
lower and upper case characters. The
abbreviated name consists of these
upper case characters. The only use
of this abbreviated name is in constructing
the directory of the library, and for
interface and diagnostic purposes the name
is handled as if it were all upper case
characters.@
@
NATURE@IBit 0 A value of zero means the procedure is
dynamic i.e. a potentially recursive, and a
one means it is static.@
@IBit 1 A value of zero means this is a procedure
specification, and a one means it is a subroutine
specification.@
@IBit 2 A value of one means this is a procedure
specification of a built-in procedure.  These procedures are
predefined to MUTL and may vary between installations.  They are
provided to improve performance.  MUTL normally generates an
inline code sequence for built-in procedure calls.@
@IBit 3 A value of one means this is a library
procedure specification.@
@IBits 6-11 for non-interface procedures this specifies the
textual level number for the procedure.  The outermost procedure
textual level in a module is numbered one for each nested level of
procedure the textual level is increased by one.  A value of
zero means the procedure textual level is set from the
currently active textual level.@
@IBits 12, 13 Specifies whether a MUTL name
is allocated, and if a specification of the parameters
and result for the procedure is supplied.@
@I0 - A MUTL name is allocated and a specification is given.@
@I1 - A MUTL name already exists for the procedure, but it
does not have a specification, in this case bits 0-11 give the
MUTL name, and calls to TL.PROC.PARAM and TL.PROC.RESULT will follow
to give its specification.@
@I2 - A MUTL name is required but the procedures symbolic name, and it's
parameter and result specification is to be supplied
later or the name is a multiple entry point to a procedure.@
@I3 - A MUTL name, given by bits 0-11, already exists for
the procedure.  The symbolic name is given but the rest of the
specification of the procedure is supplied later.@
@IBit 14 A value of one means the procedure (or
subroutine) is an interface entity that is
to be exported from the current module.@
@IBit 15 A value of one means this is a specification
of an assumed interface procedure (or subroutine)
of another module.@
@
@ITo reference a procedure from a library then its
specification must be given. Bits 3 and 15 of
NATURE are set to one to indicate this.@
@
When compiling a library bits 3 and 14 are set
to one to indicate that this procedure is in
the libraries interface.
@
@
2) @JTL.PROC.PARAM(TYPE,DIMENSION)
@BThis procedure defines the type of the next parameter in the current procedure
declaration.
A MUTL name is not allocated for the parameter by this procedure.
Names for a procedures parameters are allocated by TL.PROC when it
is called to commence the definition of the procedure.
@SParameters:-
@
TYPE@ITYPE SPECIFIER of parameter, see
paragraph 23.3 for its encoding.@
@
DIMENSION@I= 0: scalar parameter@
@I>0: parameter is a vector containing
the DIMENSION elements@
@I-2048: Parameter is a vector, its dimension is
specified by the current literal.@
@IOther negative values: parameter is a vector
its dimension is the value of
literal whose MUTL name is
DIMENSION negated.
@
@
3) @JTL.PROC.RESULT(TYPE)
@BThis procedure defines the result type for the procedure
(or subroutine).@
@
Parameters:-@
@
TYPE@IBits 0-13 contain a TYPE SPECIFIER
of the result, see paragraph
23.3 for its encoding, in addition a zero
value means the procedure has no result.
@
@
4) @JTL.PROC(MUTL.NAME)
@BDefines that a procedure (or subroutine) starts at the current
position in the
code segment. For procedures a name for each of its parameters
as specified in the associated procedure specification
is automatically
allocated at this point.
@SParameter:-
@
MUTL.NAME@IMUTL name of procedure.
@
@
5) @JTL.PARAM.NAME(MUTL.NAME,[SYMB.NAME])
@BThis procedure is called during the definition of a procedure
to supply symbolic names to its parameters.
@SParameters:-
@
MUTL.NAME@IMUTL name of parameter.@
@
[SYMB.NAME]@IBounded pointer to a byte vector containing
the symbolic name of the parameter. It is
used only for diagnostic purposes.
@
@
6) @JTL.PROC.KIND(KIND)
@BThis procedure is called to specify the non-local accessibility
of the current procedures labels and variables.
@SParameters:-
@
KIND@
@
bit 2@ISpecify non-local accessibility of the procedures
variables.@
1 -@IProhibited.@
0 -@IAllowed.
@
@
7) @JTL.END.PROC()
@BDefines the end of the code for the procedure
(or subroutine) most recently started.
@
@
8) @JTL.ENTER(MUTL.NAME)
@BOn calling this procedure the current position in the code is designated to be
 a
multiple entry point
for the enclosing procedure.
Multiple entry is only allowed on static procedures,
all entry points have an identical specification.
@SParameters:-
@
NAME@IMUTL name previously allocated by calling
@X%`
TL.PROC.SPEC with a NATURE of %2000, and this
@X%%
name is specified to call the procedure via the
multiple entry point.
@
@
9) @JTL.I.PARAM(MUTL.NAME, PARAM.NO, BASIC.TYPE)
@BMUSS Fortran allows integer data types to be 1, 2 or 4 bytes.
In Fortran procedure specifications are implicit, therefore the
data type precision of integer formal parameters
(dummy arguments) can not be inferred from the actual parameter
(argument) when the actual parameter is either a constant or an
expression.  The procedure TL.I.PARAM allows procedure calls
to be made without the precision of the formal parameter being
known.  Note this procedure is only used for parameters passed
by reference and that recursion of such procedures is prohibited.
@BThe procedures allocates MUTL names for two variables.  MUTL
initialises the first variable to reference the second variable.
To generate code to pass parameter P2 of procedure P1 where the
precision of the formal parameter is not known, the value is
first placed in the second variable, then a reference to it is
passed by stacking as a parameter the first variable.
@
@
@T% 30
Parameters:-@
@
@
MUTL.NAME@IMUTL name of procedure.@
@
PARAM.NO@INumber of parameter (counting from zero).@
@
BASIC.TYPE@IBit 15. A value of one means that the variables
are required for a procedure call.@
@IBit 14. A value of one means that the variables may
be allocated storage in the current data area, which must be static, and the
reference between the two variable established.@
@IBits 0-13 is a TYPE SPECIFIER, see paragraph 23.3
for its encoding.  For a procedure call (bit 15 = 1) then
the type should be an unbounded pointer where the size
specifies the maximum possible precision of the formal
parameter.  For a procedure definition (bit 14 = 1) then
the type specifies the data type of the formal parameter.@
@
@
10) @JTL.BLOCK()
@BThis procedure is called to indicate the start of a block.
No name is allocated for the block.
@
@
11) @JTL.END.BLOCK()
@BThis procedure is called to indicate the end of the block
most recently started.
@S223.8 LABEL DECLARATION
@BLabels in code may be classified by their use and their origin,
i.e. whether the label is source language or compiler generated. As most
compiler generated labels are referenced in a very restricted manner,
some MUTL implementations may be able to preserve actual machine
registers across such labels. Labels are classified as follows.@
@
@T% 10
@
i)@ISource language labels. Non-local (i.e. from textually embedded procedures)
to these labels is not permitted.
For local jumps to labels of this kind use the -> orders.@
@
ii)@ISource language restart labels. These labels are always accessible non-loca
lly
from textually embedded procedure.@
@
iii)@ICompiler generated labels.
@BAs some labels need to be forward referenced, a specification
of a label is always given before the definition of the value
of the label. The specification and declaration of the label
must appear in the same procedure.
@
@
1) @JTL.LABEL.SPEC([SYMB.NAME],LABEL.USE)
@BThis procedure gives a specification for a label and
allocates a MUTL name for the label.
@SParameters:-
@
@T% 30
@
[SYMB.NAME]@IBounded pointer to a byte vector containing
the characters of the labels symbolic name.
It is used to identify the interface
entity and for run time diagnostic
purposes.@
@
LABEL.USE@IBits 0 to 3. Values interpreted as@
@
@I0 - Source language label.@
@I>1 - Compiler generated labels.@
@
@IBit 14 = 1 Label to be exported
as an interface entity.
Bit 15 = 1 Specification of an assumed
interface entity which is to be imported
from another module.
@
@
2) @JTL.LABEL(MUTL.NAME)
@BThis procedure declares a label value by assigning the
current code address value to the label.
@SParameters:-
@
@
MUTL.NAME@IMUTL name of a label.
@S223.9 PICTURE DECLARATIONS
@BCode planting in MUTL caters for Cobol like editing
operations.  The editing is controlled by a picture specification.
@
@
1) @JTL.PIC(PICTURE)
@BThis procedure allocates a MUTL name for a picture specification.
@T% 10
@
@
Parameter:@
@
PICTURE@IThis is a bounded pointer to a byte vector containing
a picture specification in a canonical form.  Exact details
of this encoding have not yet been resolved.
@S223.10 CODE PLANTING
@BMost instructions consist of a function and an operand
as
specified in the TL.PL procedure.
Optimisation of loop control, when possible, is desirable
for reasonable object code efficiency, therefore, MUTL also provides special cod
e
planting procedures for the most frequently used types of loops.
MUTL distinguishes two special kind of loop.@
@
@T% 10
@
a)@ILoops that are executed a number of times, where this number
can be determined at the start of the loop, and no explicit
control variable is required.@
@
b)@ILoops that require a control variable, but the increment
for the control variable is either +1 or -1.@
@
For (a) the procedures TL.CYCLE and TL.REPEAT are called,
for (b) the procedures TL.CV.CYCLE, TL.CV.LIMIT and TL.REPEAT
are called. For other loops the appropriate sequence of TL.PL,
TL.LABELS, etc. calls must be used.
@
@
1) @JTL.PL(FN,OP)
@BThis procedure specifies one MUTL instruction.
It may translate into several actual machine
instructions or it may sometimes be optimised out.
The latter is very often the case with the D instructions
concerned with stepping through data structures. The general
form of MUTL instructions is one-address, and they are
in the main orthogonal in the sense that any
function can be used with any operand. The exceptions
to this rule are given in 23.10.3.
A function (FN) specifies an operation and an
operation type (or MUTL register) as shown in 23.10.1.
@BThe operand part a MUTL instruction (OP) is
in principle a MUTL name, but there are special encodings
of this name to provide for literals, registers, stacked
quantities etc, as described in 23.10.2.
@
@
@S323.10.1 Operation Codes
@BThe FN parameter is encoded thus@
@3
@U 9
@
bits 0 - 4 specify the operation
bits 5 - 6 specify the operation set
         0 indicates B operation
         1 indicates A operation
         2 indicates Organisational operation
         3 indicates D operation
bits 8 -15 for A and B operations, and ACONV, AMODE and ADDR= opcodes
            this field specifies the register number.
@0
@BThere is in effect a greater range of operation types than is
apparent in the above since the A-register may be defined to be in any
of the following basic modes@
@Q 7
@
@MREAL(SIZE 32 or 64 or 128 BITS)
@NINTEGER(SIZE 8 or 16 or 32 or 64 or 128)
@NLOGICAL(SIZE 1 or 8 or 16 or 32 or 64 or 128)
@NDECIMAL(any size up to and including 80)
@NPTR(SIZE UNBOUNDED or BOUNDED)
@NTYPELESS(ANY SIZE or TYPE)
@BThere are other modes for the A-register which cater for
specific high level languages. These are known as extended A modes
and at present these operations are only available on the A0 register.
The extended modes are:@
@Q 4
@3
@U 3
@
          COMPLEX    -    FORTRAN
          CHARACTER STRING OPERATIONS - FORTRAN and COBOL
@0
@
@
Thus in the operation table given below, the A operations are given
for each basic mode which is selectable.@
@3
@U 37
@
@
  @O                                                                   @O
  |       |      @O|              A FUNCTIONS                 |@O       |
  @O|   D   |  B   | REAL | DEC  | INT  | LOG  |       | PTR  | ORG.FN|@O
 0@O|   =>  |  =>  |  =>  |  =>  |  =>  |  =>  |   =>  | =>   | STK L |@O
 1@O| =REF  |  =-  |  =-  |      |  =-  |      |       | =REF |STK PAR|@O
 2@O|   =   |  =   |  =   |   =  |  =   |  =   |   =   |  =   | ENTER |@O
 3@O|SEL FLD|  -=  |      |      |  -=  |  -=  |       |      | RETURN|@O
 4@O| SEL EL|  &   |      |      |  &   |  &   |       |      |STK NIL|@O
 5@O|SEL ALT|  V   |      |      |  V   |  V   |       |      | ACONV |@O
 6@O|  BASE |  <<  |      | SCALE|      |  <<  |       |BASE  | AMODE=|@O
 7@O| LIMIT |  >>  |      |      |      |  >>  |       |LIMIT | STACK |@O
 8@O|       |  +   |  +   |   +  |  +   |      |       |      | STK LB|@O
 9@O|       |  -   |  -   |   -  |  -   |      |       |      | -> IF=|@O
10@O|       |  -:  |  -:  |  -:  |  -:  |      |       |      |-> IF/=|@O
11@O|       |  *   |  *   |   *  |  *   |      |       |      |-> IF>=|@O
12@O|       |  /   |  /   |   /  |  /   |      |       |      | -> IF<|@O
13@O|       |  /:  |  /:  |  /:  |  /:  |      |       |      |-> IF=<|@O
14@O|       |  ==  |      |      |  ==  |  ==  |       |      | -> IF>|@O
15@O|       | COMP | COMP | COMP | COMP | COMP | COMP  | COMP | SEG ->|@O
16@O|       |      |      |      |      |      |       |      |ISEG ->|@O
17@O|       |      |      |      |      |      |       |      | AECONV|@O
18@O|       |      | MFN  |  MFN | MFN  |      |       |      |AEMODE=|@O
19@O|       | -=>  |      |      | -=>  | -=>  |       |      |  ADDR=|@O
20@O|       |  &>  |      |      |  &>  |  &>  |       |      |       |@O
21@O|       |  V>  |      |      |  V>  |  V>  |       |      | BCONV |@O
22@O|       |      |      |      |      |      |       |      | BMODE=|@O
23@O|       |      |      |      |      |      |       |      |       |@O
24@O|       |  +>  |  +>  |  +>  |  +>  |      |       |      |       |@O
25@O|       |  ->  |  ->  |  ->  |  ->  |      |       |      |       |@O
26@O|       | -:>  | -:>  |  -:> | -:>  |      |       |      |       |@O
27@O|       |  *>  |  *>  |  *>  |  *>  |      |       |      |       |@O
28@O|       |  />  |  />  |  />  |  />  |      |       |      |       |@O
29@O|       | /:>  | /:>  |  /:> | /:>  |      |       |      |       |@O
30@O|       | ==>  |      |      |  ==> |  ==> |       |      |       |@O
31@O|       |  **  |  **  |      |  **  |      |       |      |       |@O
@0
@BThe operators used in the above table have the
following meanings.@
@
@
=>@IStore@
=-@ILoad negative.@
=@ILoad.@
-=@ILogical 'non-equivalence'.@
&@ILogical 'and'.@
V@ILogical 'or'.@
==@ILogical 'equivalence'.@
<<@ILogical left shift. The operand must be a positive integer.@
>>@ILogical right shift. The operand must be a positive integer.@
+@IAdd.@
-@IMinus.@
-:@IReverse minus.@
*@IMultiply.@
**@IExponentiate.@
/@IDivide. For integer division this yields the nearest integer in the range zer
o
to the mathematical result.@
/:@IReverse divide.@
COMP@IThe operand is compared with the register concerned and the T register set
accordingly. The T register indicates one or more of the following
six states namely,
=, /=, >=, >, =< and <.@
-=>@ILogical 'non-equivalence' into store.@
&>@ILogical 'and' into store.@
V>@ILogical 'or' into store.@
==>@ILogical 'equivalence' into store.@
+>@IAdd into store.@
->@ISubtract into store.@
-:>@IReverse subtract into store.@
*>@IMultiply into store.@
/>@IDivide into store.@
/:>@IReverse divide into store.@
SCALE@IScales the decimal A register by a power of 10
specified by bits 0-7 of the operand which are interpreted as
a signed integer.  For a negative scale factor the digit in
bits 8-11 of the operand is added to the last discarded digit
in forming the result.  Thus a digit of 5 in bits 8-11 rounds
and a 0 truncates the result.@
STK L@IStack link. Bits 0-11 of the operand contain the name of a procedure spec
ification
or zero. The latter value is for implementing interpretive
procedure calls.
Bits 12 and 13 given information about the procedure,
a zero means that there is a definition associated with the
specification, a one means entry is via a procedure variable without
environment information, and a two means entry via a procedure
variable with environment information.
This opcode is required at the start of a procedure call sequence.@
STK LB@ISimilar to STK L except the procedure being called is specified by it's
FIND.N value which is contained in the current literal,
the operand is a literal that specifies the type of the result
and is encoded as described in paragraph 23.3.@
STK PAR@IStacks a parameter in a procedure call sequence. The operand must be
a register whose mode is compatible with the parameter specification.
For interpretive procedure calls and procedure called with STK LB the mode of th
e A register
is taken as the parameter specification.@
STK NIL@IIn a call of a procedure trailing parameters may be
omitted.  The operand is a literal that specifies the number of
missing parameters.@
ENTER@IInstruction used at the end of the procedure
call sequence to enter the procedure as specified by the associated
STK L.
A zero operand enters the procedure associated with the specification
given by STK L or STK LB, or it specifies the name of a procedure variable,
or it specifies the A register in which case the A register
contains the entry address of the procedure.@
RETURN@IReturns control from a called procedure to the instruction immediately
following the ENTER used to call the procedure. The operand specifies
the result for functional procedures.
The result is passed back via the A register. An operand
@X%`
of %30dd means the A register contains the result and a
@X%%
zero operand either means there is no result.@
ACONV@ISets a new basic mode and precision for the specified A register, and the
 contents
of A are converted into the new mode as described in 23.10.4.
The operand specifies the mode.@
AMODE=@ISets the basic mode and precision of the specified A register at the sta
rt of an evaluation.
The operand is an encoded mode as described in 23.10.4.@
BCONV@ISets a new mode and precision for the B register, and
the contents of the B are converted into the new mode as
described in 23.10.4.  The operand specifies the mode.@
BMODE=@ISets the mode and precision of the B register.@
AECONV@IOperates as ACONV but selects an extended
mode for the A register.@
AEMODE=@IOperates as AMODE= but selects an extended
mode for the A register.@
STACK@IStacks the register specified by the operand. A stacked operand is remove
d by specifying an
UNSTACK operand in the instruction.@
->IF=  ->IF<  ->IF>  ->IF/=  ->IF=<  ->IF>=@
@ITransfers control to a label in the same MUTL segment if the status of
T implies the condition of the instruction. Operand is a name of
label type.@
SEG ->@ITransfers control to a label in the same MUTL segment. Operand is
of label type.@
I.SEG ->@ITransfers control to a label in another MUTL segment. Operand is
of label type.@
=REF@ILoad a reference to the entity specified by the operand.
The operand must be the MUTL name of a data item or D[].@
SEL FLD@ISelects a sub-field of the current field. The operand is a non-negative
literal integer.@
SEL EL@ISelects the Bdd'th element of the current sub-field.
The operand is a literal of the form
@X%`
%20dd where dd specifies a particular B register. A zero
operand means select the B0'th element.@
@X%%
SEL ALT@IIf a field has multiple type definitions this selects the required
type definition. A SEL ALT is not required if the first of the
multiple type definitions is required. The operand is always a
non-negative literal integer.@
BASE@IThe B0 register specifies an element of a vector addressed
by a pointer in the A or D register.
This pointer is modified by this instruction so that the base of the vector
now starts at the element specified.
The operand specifies whether to maintain an
unbounded or a bounded pointer (i.e. = 0 or 1).@
LIMIT@IThe B0 register specifies an element of a vector addressed by
a pointer in the D or A
register. The pointer is modified so that the last element of the vector
becomes the element specified. No operand is required.@
MFN@IMathematical and built-in functions that operate
on A registers.
The operand is taken to be a function number and the
available functions are given in 23.10.5.@
ADDR=@ILoad a MUTL base register. The operand is a literal
and it is encoded as follows:@
@3
@U 7
@
          Bits 0 - 7 MUTL Segment Number or Procedural textual level.
          Bit 8      1 Load with MUTL segment address
                     0 Load with stack frame address
          Bit 9      0 Plant code to load base register
                     1 Note that base register is loaded but do
                     not plant code.
@0
@BThe operation codes for the extended modes are given in the
table below@
@3
@U 36
@
@
                    @O                           @O
                    @O|    |COMPLEX|   STRING   |@O
                    @O|  0 |  =>   |   L.STR    |@O
                    @O|  1 |  =-   |   R.STR    |@O
                    @O|  2 |  =    |     MOV    |@O
                    @O|  3 |  R=   |   E.MOV    |@O
                    @O|  4 |  I=   |    COMP    |@O
                    @O|  5 |       |  E.COMP    |@O
                    @O|  6 |       |    SRCH    |@O
                    @O|  7 |       |  E.SRCH    |@O
                    @O|  8 |  +    |     LEN    |@O
                    @O|  9 |  -    |   E.LEN    |@O
                    @O| 10 |  -:   |  ASC.COMP  |@O
                    @O| 11 |  *    | E.ASC.COMP |@O
                    @O| 12 |  /    |    LOAD    |@O
                    @O| 13 |  /:   |    EDIT    |@O
                    @O| 14 |       |   C.EDIT   |@O
                    @O| 15 | COMP  |   N.EDIT   |@O
                    @O| 16 |       |  E.N.EDIT  |@O
                    @O| 17 |       |    MOV.B   |@O
                    @O| 18 |  MFN  |            |@O
                    @O| 19 |       |            |@O
                    @O| 20 |       |            |@O
                    @O| 21 |       |            |@O
                    @O| 22 |       |            |@O
                    @O| 23 |       |            |@O
                    @O| 24 |  +>   |            |@O
                    @O| 25 |  ->   |            |@O
                    @O| 26 | -:>   |            |@O
                    @O| 27 |  *>   |            |@O
                    @O| 28 |  />   |            |@O
                    @O| 29 | /:>   |            |@O
                    @O| 30 |       |            |@O
                    @O| 31 |  **   |            |@O
@0
@T% 30
@BWhere the operation codes mean@
@
R=@ILoad real part only of complex accumulator.@
I=@ILoad imaginary part only of complex accumulator.@
@
The other operators are as for the basic modes except
they operate on the complex accumulator.
@BNine character string operations are provided:@
@
MOVE@IThis involves concatenation of one or more
strings (called right strings) to form a result
string and storing this in a destination string
(called a left string). If the result string is
longer than the left string, then the string
starting at the lefthand end of the result
string of the same length as the left string is
stored. If the result string is shorter, then
the result string is transferred to the lefthand
end of the left string and blanks inserted in
the remaining part of the left string.@
COMPARE@IThis compares two strings and sets the T status
bits accordingly. The strings involved are a
left and a right string, and each string consists of a
concatenation of one or more strings.  The left string is
compared with the right string.  If one of the strings is
shorter than the other then it is extended to the right
with blanks so that both strings are of the same length.
Comparison proceeds by comparing the strings from left
to right using the collating sequence of the character set.@
SEARCH@IThis searches one string for the leftmost
occurrence of another string. The left string is
searched for the leftmost occurrence of the right
string. If found its position, counting from one
is put in the B register, otherwise B is set to
zero.@
LENGTH@IThis gives the length of a string in B. The left
string is used to hold the string.@
ASCII COMPARE@ISimilar to COMPARE but the comparison uses
collating sequence described in ANSI, X3.4-1968
(ASCII).@
LOAD@IThis loads a numeric character string, so that an
immdiately following ACONV opcode enables conversion to a decimal
representation in the A register.@
EDIT@IThis performs editing as typified by an alphanumeric
move in Cobol between two character strings.  Editing is
governed by a Picture specifier.@
NUMERIC EDIT@IThis performs editing as typified by a
numeric edited move in Cobol between a decimal value in the
A register and a character string.  Editing is governed by a
Picture specifier.@
MOVE BYTE@IThis moves the same literal value to every byte of a
character string.
@BEach one of these operations is specified as a sequence of
simpler character string instructions.@
@3
@U 14
@
Example
@
          E = F//G//H
@
MUTL instructions
@
          MOV        :: Start of a MOVE operation
          L.STR E    :: Left string
          R.STR F    :: Result string of right strings
                        F, G and H
          R.STR G    :: Concatenated
          R.STR H    :: Together
          E.MOV      :: End of MOVE operation.
@0
@BThe character string opcodes provided are described below. A
string operand is always a vector of byte sized elements.@
@
L.STR@IThis opcode is used to specify the left string. If
the character operation in which this is used permits
concatenation of strings, then a sequence of L.STR
functions specify that the left strings will be
concatenated together and then act as a single string
in the operation.@
@
R.STR@IAs L.STR except it applies to the right string.@
@
MOV@IStart of a MOVE operation, this is followed by
instructions to specify the left string and then the
right string. The left string consists of a single
operand, whereas the right string may consist of
several concatenated operands.@
@
E.MOV@IThis opcode terminates the specification of the
right string and MOVE operation.@
@
COMP@IStart of a COMPARE operation, this is followed by
functions to specify the left string and then the
right string. Both the left and the right strings may
consist of several concatenated operands.@
@
E.COMP@IThis function terminates the specification of the
right string and the COMPARE operation.@
@
SRCH@IStart of a SEARCH operation, this is followed by
functions to specify
the left and then the right string.  Both of
these strings may consist of several concatenated operands.@
@
E.SRCH@IThis opcode terminates the specification of the
right string and the SEARCH operation.@
@
LEN@IStart of a LENGTH operation, this is followed by
instructions to specify the right string, which may
consist of concatenated operands.@
@
E.LEN@IThis opcode terminates the specification of the
right string and the LENGTH operation.
@BThe MOV, E.MOV, COMP, E.COMP, SRCH, E.SRCH, LEN and E.LEN
opcodes do not have an operand. The stack may be used during an
operation for holding temporary data.@
@
ASC.COMP@IAs COMP but for ASCII collating sequence.@
@
E.ASC.COMP@IAs COMP but for ASCII collating sequence.@
@
LOAD@ILoads a numeric character string.@
@
EDIT@IStart of an editing operation.  The operand is a MUTL name of a
Picture specifier.  The destination for the edited move is defined by a
single left string operand (i.e. L.STR) followed by the
source which is defined by a single right string operand
(i.e. R.STR).@
@
E.EDIT@IEnd of an editing operation.@
@
N.EDIT@IStart of a numeric editing operation.
The operand is a MUTL name of a Picture specifier.
The destination of the move is defined by a single
left string (i.e. L.STR) followed by code to
load the decimal A register.@
@
E.N.EDIT@IEnd of numeric editing operation.@
@
MOV.B@IThis moves the current literal value
to every byte of the character string specified
by the operand.@
@S323.10.2 Operands
@BFor most functions the operand is one of the following:@
@
@T% 10
1.@IA zero which means the operand is a basic type literal
having a value and type of the current basic type literal.@
@
@X%`
2.@IA name of a previously declared item (1<OP<%800)@
@
3.@IA special operand (OP>%7FF).@
@
%1002@IV.SUB see TL.V.DECL in 23.5.@
@
%1003@IThe operand is to be popped from the top of the current
stack frame. MUTL requires that the use of the stack for
temporary variables is determinable at translation time.
This means that the corresponding STACK function must
statically precede a %1003 operand, and that associated
pairs of STACK functions and %1003 operands must be
statically nested.
As with most other operands of A and B opcodes this
operand may be of a different type and size to the register,
the operand type information is obtained from the corresponding
STACK opcode.@
@
%1004@ID[] the item addressed by the D register.@
@
%1005@Ispecifies an operand that is normally used with the STACK and the
D= instructions. This operand allows the stack to be used for
temporary select variables (see 23.5). This operand
with a STACK instruction pushes the current selection information
of the D register onto the stack, and on the corresponding paired
D= instruction with this operand, the stacked selection information
is popped into the D register. Obviously several items of this type
may be on the stack simultaneously, but as with select variables
there are static scope implications. The STACK and D= with this
operand may be statically nested, and the D= is paired with the
immediately preceding unpaired STACK in the compiled code.@
@
@IFor the next six special operands the value of the
operand for the instruction depends on the state
of the T register.@
@
%1008@Ia 1 if T implies =, otherwise 0@
%1009@Ia 1 if T implies /=, otherwise 0@
%100A@Ia 1 if T implies >=, otherwise 0@
%100B@Ia 1 if T implies >, otherwise 0@
%100C@Ia 1 if T implies =<, otherwise 0@
%100D@Ia 1 if T implies <, otherwise 0@
@
%20dd@Ia B register, bits 0-7 specify which one.@
%30dd@Ian A register, bits 0-7 specify which one.
@X%%
@S323.10.3 Restrictions on the Use of Operands
@BThere are a number of exceptions to the general rule
that any function can be combined with any operand.@
@3
@U 14
@
          a)  Some functions have no operand as stated in the
              function description
          b)  Some functions have specially encoded operands as
              stated in the function description
          c)  Operands of B orders must be of type integer or
              logical
          d)  Operands of store and into store operation
              codes must match the size and type of the
              storing register.
          e)  For MUTL translators where there is only
              single A and B registers the B and A
              register operands are restricted to
              =, =>, STACK and STK.PAR opcodes.
@0
@S323.10.4 Mode Conversions
@T% 10
@BFor most arithmetic functions on the B and A accumulator. if the
mode of operand differs from the mode of the accumulator then there is
an implicit conversion of the operand to the accumulator mode.
@BThe operand of AMODE=, ACONV, BMODE and BCONV operations is taken as an
encoded integer where the bits 0-13 give a TYPE SPECIFIER
as in 23.3 to specify a scalar type mode; an array type generic
mode is selected by a value of 2 in bits 0, 1 with bits 2-13
specifying the element type and
the number of array elements specified by the current literal.
In the case of ACONV bit 14 is
also relevant and it specifies a KIND of conversion.
Note that basic arithmetic modes have a value less 256
and have bits 0, 1 zero, while PTR modes have a value of 1 or
3 in bits 0, 1.
@BFor the extended modes the operand of AEMODE= and
AECONV operations is encoded as for AMODE= and ACONV, but the
TYPE SPECIFIERs are as follows:@
@3
@U 6
@
          Complex - TYPE SPECIFIER of an aggregate type
                    containing 2 reals. Fortran always
@X%|
                    uses a TYPE SPECIFIER of %108.
@
          Character string - TYPE SPECIFIER of %83.
@X%%
@0
@BWhen the target type of a conversion
is unsigned integer then the conversion is such that
a binary equivalent value is obtained.
Similarly when converting from
an existing mode of unsigned integer
the conversion is such that a binary equivalent value is
obtained.  The notion of a binary equivalent is to imply that
if a value of one mode is converted to an unsigned integer of
greater or equal precision, then a comment back to the original
mode yields the same value.@
@
The conversions available are given below@
@T% 35
@
INTEGER TO REAL@
@
INTEGER TO DECIMAL@
@
REAL TO INTEGER@
KIND = 0@ITruncated conversion yielding the
nearest integer value selected from the
range zero to the floating point value.@
KIND = 1@IRounded conversion yielding the
nearest integer value to the floating
point value.@
@
REAL TO DECIMAL@
KIND = 0@ITruncated conversion.@
KIND = 1@IRounded conversion.@
@
DECIMAL TO INTEGER@
@
DECIMAL TO REAL@
@
INTEGER TO INTEGER@IChange in precision@
@
REAL TO REAL@IChange in precision@
@
DECIMAL TO DECIMAL@IChange in precision@
@
INTEGER TO UNSIGNED INTEGER@ISign extend integer to new precision.@
@
REAL TO UNSIGNED    INTEGER@IBinary equivalent conversion.@
@
DECIMAL TO UNSIGNED INTEGER@IBinary equivalent conversion.@
@
UNSIGNED INTEGER TO UNSIGNED INTEGER@
@IChange in precision.@
@
UNSIGNED INTEGER TO INTEGER@IChange to new precision.@
@
UNSIGNED INTEGER TO REAL@IBinary equivalent conversion.@
@
UNSIGNED INTEGER TO DECIMAL@IBinary equivalent conversion.@
@
INTEGER TO PTR@IThe integer value becomes the address origin
of a pointer.@
@
PTR TO INTEGER@
KIND = 0@IThe address origin of the pointer becomes an
integer value.@
KIND = 1@IThe bound of the pointer becomes an integer value.@
@
PTR TO UNSIGNED INTEGER@IBinary equivalent conversion.@
@
UNSIGNED INTEGER TO PTR@IBinary equivalent conversion.@
@
INTEGER/REAL TO COMPLEX@
KIND = 0@IThe integer/real accumulator value is
converted and becomes the real part, and
the imaginary part is set to zero.@
KIND = 1@IThe integer/real value is converted and
becomes the real part, and the imaginary part is undefined.@
@
COMPLEX TO INTEGER@IA truncated conversion is applied to the
real part of the complex value to yield
an integer value.@
@
COMPLEX TO REAL@
KIND = 0@IThe conversion yields the real part of the
complex value.@
KIND = 1@IThe conversion yields the imaginary part
of the complex value.@
@
DECIMAL TO NUMERIC CHARACTER STRING@
@IConversion from decimal to a numeric character string,
the result defines a right string operand as does the
opcode R.STR.  KIND specifies the sign representation in the string.@
@
KIND = 0@ITrailing sign.@
@
KIND = 1@ILeading sign.@
@
KIND = 2@ITrailing separate sign.@
@
KIND = 3@ILeading separate sign.@
@
NUMERIC CHARACTER STRING TO DECIMAL@
@IConversion from a numeric character string to decimal,
KIND specifies the sign representation as described above.@
@S323.10.5 Mathematical Functions
@3
@U 32
@
@M@O                                                 @O
@N@O| MFN NO |  REAL  | INTEGER | DECIMAL | COMPLEX |@O
@N|    0   |   ABS  |   ABS   |         |   ABS   |
@N|    1   |  MOD.1 |  MOD.1  |         |  CONJG  |
@N|    2   |  MOD.2 |  MOD.2  |         |         |
@N|    3   | SIGN.1 | SIGN.1  |         |         |
@N|    4   | SIGN.2 | SIGN.2  |         |         |
@N|    5   |  DIM.1 |  DIM.1  |         |         |
@N|    6   |  DIM.2 |  DIM.2  |         |         |
@N|    7   |  MAX.S |  MAX.S  |         |         |
@N|    8   |  MAX.M |  MAX.M  |         |         |
@N|    9   |  MAX.F |  MAX.F  |         |         |
@N|   10   |  MIN.S |  MIN.S  |         |         |
@N|   11   |  MIN.M |  MIN.M  |         |         |
@N|   12   |  MIN.F |  MIN.F  |         |         |
@N|   13   |   SQRT |  ODD    |         |   SQRT  |
@N|   14   |   SIN  |         |         |   SIN   |
@N|   15   |   COS  |         |         |    COS  |
@N|   16   |   LOG  |         |         |    LOG  |
@N|   17   |   EXP  |         |         |    EXP  |
@N|   18   | LOG.10 |         |         |         |
@N|   19   |   TAN  |         |         |         |
@N|   20   |   ASIN |         |         |         |
@N|   21   |   ACOS |         |         |         |
@N|   22   |   ATAN |         |         |         |
@N|   23   | ATAN.1 |         |         |         |
@N|   24   | ATAN.2 |         |         |         |
@N|   25   |   SINH |         |         |         |
@N|   26   |   COSH |         |         |         |
@N|   27   |   TANH |         |         |         |
@N@O|   28   | X SIGN | X SIGN  |         |         |@O
@0
@BSome of the functions (e.g. SIN,ABS) operate solely
on the current contents of the accumulator. While others
are used in a sequence (e.g. MOD.1,MOD.2)
to provide a 'function' that operates on several values,
@Kfor these the code generation may use the stack for intermediate
results, therefore the stack should be in the same state for each
function in the sequence.@K@
@
Example@
@
For the Fortran statements@
@Q 4
@
@MREAL X,Y,W,Z,V
@NZ = MAX (X,Y,Z,V)
@
@
The equivalent MUTL instructions are:@
@Q 14
@
@MA.MODE = real
@NA = X
@NMAX.S
@NA.MODE = real
@NA = Y
@NMAX.M
@NA.MODE = real
@NA = Z
@NMAX.M
@NA.MODE = real
@NA = V
@NMAX.F
@NA => Z
@BIn such a sequence the mode of the accumulator must be
the same for each of the functions in the sequence.@
@
The functions provided are as follows:@
@T% 10
@
ABS@IYields absolute value. For complex mode the result
is yielded in the A register whose mode
and precision is that of the real part of
the complex mode.@
@
MOD.1@IYields a1 - int(a1/a2)*a2,@
MOD.2@Iwhere a1 is the value of the A register for
MOD.1, and a2 is the value of A for MOD.2.@
@
SIGN.1@IYields |a1| if a2 >= 0, and@
SIGN.2@I-|a1| if a2 < 0.@
@
DIM.1@IYields a1-a2 if a1 > a2, and@
DIM.2@I0     if a1 =< a2.@
@
MAX.S@IYields the maximum of (as,am ..... am,af),@
MAX.M@Iwhere as is the value of the A register for@
MAX.F@IMAX.S, am is the value for MAX.M, and af for
MAX.F.@
@
MIN.S@IYields the minimum of (as,am ..... am,af)@
MIN.M@
MIN.F@
@
SQRT@IYields square root@
@
SIN@IYields sine@
@
COS@IYields cosine@
@
LOG@IYields natural logarithm@
@
EXP@IYields exponential@
@
LOG10@IYields common logarithm@
@
TAN@IYields tangent@
@
ASIN@IYields arcsine@
@
ACOS@IYields arccosine@
@
ATAN@IYields arctangent@
@
ATAN.1@IYields arctangent of a1/a2@
ATAN.2@
@
SINH@IYields hyperbolic sine@
@
COSH@IYields hyperbolic cosine@
@
TANH@IYields hyperbolic tangent@
@
X SIGN@IExtract sign. Yields -1 in A register if A value
negative, otherwise yields 1 in A register.@
@
ODD@IConverts the A register into 1 bit mode
and loads it with a value of one if a contains
an odd integer, otherwise loads a zero.@
@
CONJG@IYields the conjugate of the complex value.
@
@
The following groups of functions operate on a pair of values,
each function is used once and in order.@
@Q 6
@
@MMOD.1    MOD.2
@NSIGN.1   SIGN.2
@NDIM.1    DIM.2
@NATAN.1   ATAN.2
@
@
The following groups of functions operate on two or more
values. The function suffixed .S is used for the first
value, the one suffixed .F for the last value, and the
.M functions for all values inbetween.@
@Q 4
@
@MMAX.S    MAX.M    MAX.F
@NMIN.S    MIN.M    MIN.F
@
@
Note that intermediate values in the above group functions are held
temporarily on the stack, and that
nested use of functions is permitted.
@
@
2) @JTL.D.TYPE(TYPE,DIMENSION)
@BThe type of an operand referenced by the D register must be
set by the compiler whenever a
typeless data pointer is loaded into the D
register.  This procedure is called immediately before the call to
TL.PL which loads a typeless data pointer into the D register.
Furthermore this procedure allows the current type information
of the D register to be reset from the parameters.
@
@T% 30
@
Parameters:-@
@
TYPE@IBit 0-13 contain a TYPE SPECIFIER of the operand addressed by D
register, see 23.3 for its encoding.@
@IBit 14=0 Resets type information of D when a typeless
data pointer is next loaded into D.@
@IBit 14=1 Reset type information of D.@
@
DIMENSION@I0 - Scalar addressed by D register.@
@I>0 - No. of elements in vector addressed
by D register or length of bit string.@
@I<0 - D addresses a vector but number of
elements unknown.
@
@
3) @JTL.CHECK(STATUS)
@BThis procedure changes the level of program error checking.
Note, a change in hardware error detection is dynamic in that it affects
all subsequent instructions executed.
Whereas the effect of a change in software error
detection is static.
@BAt the start of compilation all hardware checking is
permitted, and all software checking is inhibited.
@Q 19
@SParameters:-
@
STATUS@
Bit 7 = 0(1)@Imeans change level of software
(hardware) checking@
Bit 8 - 14@Ispecify which of bits 0-6 are
acted upon@
@IIf bit (8+i) = 1 then act on
bit i@
Bit 0 = 0(1)@Iinhibit (permit) hardware array bounds
checking@
Bit 1 = 0(1)@Iinhibit (permit) overflow
checking on B@
Bit 2 = 0(1)@Iinhibit (permit) overflow
checking on A in integer mode@
Bit 3 = 0(1)@Iinhibit (permit) overflow
checking on A in floating
point mode@
Bit 4 = 0(1)@Iinhibit (permit) overflow
checking on A in decimal
mode.
@
@
4) @JTL.RANGE(REGISTER,KIND,LOWER.LIMIT,UPPER.LIMIT)
@BThis plants code to ensure that the value in the register specified by
P1 is not outside the value range as specified by P3 and P4.
@SParameters:-
@
@X%`
REGISTER@I%20dd a B register@
@I%30dd an A register@
@Idd specify which register.@
@X%%
@
KIND@Ispecifies how P3 and P4 are encoded.@
@IBit 0 - 0 P3 is an explicit literal@
@I-1 P3 is the MUTL name of a literal or a variable.@
@IBit 1 - 0(1) Upper limit (not) defined.@
@IBit 2 - 0 P4 is an explicit literal@
@I-1 P4 is the MUTL name of a literal or a variable.
@
@
5) @JTL.INSERT(BINARY)
@BThe binary specified by the parameter is planted in the next available
location in the current code area. Thus special operating system
functions of an order code, such as dump and reload register, can be
used from the systems implementation language MUSL.
@SParameter:-
@
BINARY@IValue of binary to be planted. The unit
of binary planted is machine dependent.
@
@
6) @JTL.CYCLE(LIMIT)
@BThis indicates the start of a loop which will be executed
LIMIT times.
@SParameter:
@
LIMIT@IThe MUTL name of an integer variable or an
integer literal,
note that for integer variables MUTL
uses the variable specified in
the limit test for the loop and does not
take a copy of the variable. A value of zero means use
the current literal. In addition the names
@X%`
%30dd and %1004 (see TL.PL) may be used.
@X%%
@
@
7) @JTL.REPEAT()
@BThis defines the end of a loop.
@
@
8) @JTL.CV.CYCLE(CV,INIT,MODE)
@BThis indicates the start of a loop which has an explicit
control variable and a unit increment.
@SParameters:
@
CV@IThe MUTL name of the integer control variable.@
@
INIT@IThe initial value to be assigned to the control
variable at the start of the loop. It can be
the MUTL name of a variable or a literal, or
@X%`
zero meaning use the current literal, or %30dd
or %1004 (see TL.PL).@
@X%%
@
MODE@
Bit 0,1,3  0@IIncrement is +1 and the loop is terminated
when the control variable is greater or equal to the LIMIT
specified in TL.CV.LIMIT.@
1@IAs 0 except loop is terminated on a greater
than condition.@
2@IIncrement is -1 and the loop is terminated
when the control variable is less than the LIMIT
specified in TL.CV.LIMIT.@
3@IAs 2 except loop is terminated on a less than
or equal to condition.@
4@I(i.e. bit 3 = 1) Increment is +1 and loop is
terminated when the control variable is equal to the LIMIT
specified in TL.CV.LIMIT.@
6@IAs 4 but increment is -1.@
Bit 2=0@IControl variable may be left undefined
at the end of the loop.@
Bit 2=1@IControl variable is defined at the end
of the loop.
@
@
9) @JTL.CV.LIMIT(LIMIT)
@BThis is called after TL.CV.CYCLE, but before the start of the
code for the loop body. This procedure specifies the limit value
of the termination test of the loop.
@SParameter:-
@
LIMIT@IThis can be the MUTL name of an integer variable
of the same size as the control variable
or an integer literal, or zero meaning use the
current literal, or
@X%`
%30dd OR %1004 (see TL.PL).
@X%%
@
@
10) @JTL.REG(REG.USE)
@BOnce a register is loaded it is defined to be in current
use. A register is no longer in current use after one of the
following events:@
@3
@U 24
@
@OEVENT@O                      @OREGISTER@O
@
a) => and into store orders  B, A or  D
b) COMP order                B, A or D
c) ST PAR with               B,A or  D
   register operand
d) STACK with                B,A or  D
   register operand
e) B or A used as a          B or A
   register operand when
   function is not =>
f) access of operand via     D
   D[]
g) SEL.EL                    B
h) after a TL.MAKE           B
   function call
h) IF orders                 T
i) BASE and LIMIT orders     B
j) TL.CYCLE, TL.CV.CYCLE,
@X%`
   TL.CV.LIMIT with %30dd
   operand                   A
@X%%
@0
@
@
or events a) to g) inclusive, the A and B registers may
be retained in current use after the event by calling TL.REG
immediately before
the TL.PL call which causes
such an event. The D register is only maintainable
in current use after event a) when the operand is not
a select variable and after f).
@BIn other situations the compiler may need to inform the target
code translator that a register is no longer in use.
@SParameters:-
@3
@U 12
@
REG USE
@X}\
 bit - 0 = 1 B    }
       1 = 1 A    }  retain register in current use
       2 = 1 D    }
       3 = 1 T    }
@
 bit - 4 = 1 B    }
       5 = 1 A    }  register no longer in current use
       7 = 1 ADDR }
@
bits 8 - 15 register number.
@X}}
@0
@S223.11 MUTL INITIALISATION
@
@
1) @JTL(MODE,FILE.NAME,DIRECTORY.SIZE)
@BInitialises MUTL for a compilation.
This initialisation includes creating
MUTL segment 0, this may be overridden where necessary by a call to
TL.SEG to replace this default creation of MUTL segment 0.
At the start of each module, area 1 of the module is automatically
mapped to this code segment, and area 1 selected as the
current code segment while area 0 (i.e., the stack) is
selected as the current data area. The action of MUTL in this
mode can be described more precisely in terms of MUTL
procedure calls.@
@T% 10
@
1)@IAt TL time, MUTL takes the following action:-@
@
@Ia) TL.SEG (0, Default Segment Size, -1, -1, 6).@
@
2)@IAt TL.MODULE time, MUTL takes the following action:-@
@
@Ia) Map area 1 (code area) of the module to
segment 0: TL.LOAD(0,1).@
@Ib) Select area 1 as the current code area: TL.CODE.AREA(1).@
@Ic) Select area 0 as the current data area: TL.DATA.AREA(0).@
@
3)@IAt TL.END time, MUTL plants in code segment 0 any code
required for exiting from a program or library.
@BThere are some restrictions when compiling in a one pass mode.
In order to map data declarations as they occur then generally interface
literals and anonymous types must be exported in the compilation run
before they are imported into any other modules. Furthermore on some
machines there may be some restrictions on the use of
interface data variables.
@BWhen compiling a library the DIRECTORY.SIZE parameter
specifies the maximum number of procedures expected in the
library interface.
@T% 30
@SParameters:-
@
MODE Bit 0 = 0@IProduce necessary data structures to support
run time diagnostics@
Bit 0 = 1@IDo not produce data structures@
Bit 1 = 0@INormal compilation run@
Bit 1 = 1@IMUSS type compilation, note that this means
that all on-stack declarations are within
procedures.@
Bit 2@IOnly used for a normal compilation run.
A value of zero means compilation of all or
part of a program, and a value of one means
compiling all or part of a library.@
Bit 3@IIndicates action if any compilation faults
are present. A zero value means abandon the compilation at the
end of the first module encountered containing faults, a one
means compilation continues even though faults are present,
and in this case bit 4 specifies filing action.@
Bit 4@IA zero means that a faulty compilation yields
no output files, and a one means output files are produced.@
Bit@K 5@IThe use of this bit@K is machine dependent.
For example when compiling MUSS
control of the stack position may
be required. See the MUTL implementation
manual of the appropriate machine for
details.@
@KBits 6-7@IThis specifies the form of the MUTL output as follows.@
@I0 - Generate executable binery.@
@I1 - Generate MUBL.@
@I2 - Generate no code.@K@
@
FILENAME@IThis gives the name of the file into which the
output (i.e. code and data areas etc.) of a
successful translation will be placed at the
end of a translation (i.e. at TL.END).@
@
DIRECTORY SIZE@
Bits 0-11@ISpecify the number of procedures in
library interface.@
Bit 15@IA value of one means that MUTL will
not create a library entry table.@
Bits 12-14@ISpecify library organisation dependent
information. See appropriate Library
Interface Implementation Manual for
details.
@
@
2) @JTL.END()
@BTerminates a compilation.
@
@
3) @JTL.MODULE()
@BInitialises the compilation of a module.
@
@
4) @JTL.END.MODULE(STATUS)
@BTerminates the compilation of a module.
@SParameter:-
@
STATUS@IA zero value means no faults detected by high level
language compiler in this module, a value of one means faults.
@
@
5) @JTL.GLOBAL()
@BTL.GLOBAL is called immediately prior to declaring a global
entity (see 23.2.4) to MUTL.
@
@
6) @JTL.MODE(MODE,INFO)
@BThis procedure allows the translation mode to be altered. The
mode is set first by the MODE parameter of TL.MODE.@
@
MODE@IBits 8-15 specify which bits of the translation mode
to alter. If bit 8 is set then change bit
0, if bit 9 is set then change bit 1, etc.
Bits 0- 7 specify the altered bit values of the
@X%`
translation mode. E.g. a mode of %8480
@X%%
would change bit 3 to a zero and bit 7
to a one.@
@IThe translation mode is interpreted
as follows:@
@IBit 0=1 Inhibit repositioning of fields
in a type@
@IBit 1=1 Inhibit code optimisation.@
@IBit 2=0 Allign fields of a type to minimise store accessing.@
@IBit 2=1 Inhibit above allignment thus reducing the size of some types.@
@
INFO@IThis parameter permits further machine
dependent control over the translation.
See the implementation manual of the
appropriate machine for details.
@S223.12 TARGET MACHINE PARAMETERS
@BIt was mentioned earlier that in the interests of efficiency
and reducing the complexity of a MUTL translator an optimising
compiler is aware of certain parameters
concerning the target machine being compiled for.
@
@
1) @JTL.ENQ(KIND)STATUS
@BThis procedure yields information about the compiler target
machine.
@SParameters:
@
KIND@I0 STATUS returns the MUTL type encoding for default length
integers of the machine.@
@I1 STATUS returns the MUTL type encoding for default length
reals of the machine.@
@I2 STATUS returns the number of procedural textual levels
maintained by a display.
@
@
2) @JTL.ENQ.REG(MODE)[RESULT.VECTOR]
@BThis procedure yields information concerning the number of
MUTL registers available on the target machine.
For a particular high level language MUTL allocates
a fixed number of B registers and a fixed number of Base registers,
but the mapping of A registers is not so straightforward.
On many machines there are separate registers for different
arithmetic modes, also a large register is often comprised
of two or more smaller registers.
@BThe RESULT VECTOR specifies the available registers.
@BThe RESULT.VECTOR is encoded as@
@3
@U 25
@
          Word 0    Number of B registers
          Word 1    Number of Base registers
          Word 2    0
          Word 3    Number of A register entries. Each entry consists
                    of the three following words:
@
          Word 0    Specifies which arithmetic modes that this set of
                    machine registers support
                    Bit 0 - 1 Real
                    Bit 1 - 1 Integer/Logical
@
          Word 1    Machine register size specified in bytes.
                    If a register greater than this size is
                    required then two or more consecutive
                    registers are allocated as a single MUTL
                    register. For example if a machine has
                    four 32 bit registers, then the first
                    two or the last two could be treated as
                    a 64 bit register. Note that when
                    several registers are needed, the number
                    of registers is always a power of two
                    (2{n}).
@
          Word 2    Number of machine registers in this set.
@0
@BThe MUTL register A0 operates in all modes.
@BThus an example RESULT.VECTOR encoding is@
@3
@U 14
@
          2         :: 2 MUTL B registers i.e. B0, B1
          3         :: 3 MUTL Base registers i.e. BASE0, BASE1, BASE2
          2         :: Machine has 2 kinds of arithmetic registers.
          0
          1         :: Set of Floating point registers.
          8         :: 64 bit precision.
          7         :: Seven registers of this kind numbered
                    :: A1 to A7.
          2         :: Set of 4 integer registers.
          4         :: 32 bit precision.
          4         :: Four registers numbered A8 to A11.
@0
@
@
When several machine registers are treated as a single MUTL
register the MUTL register number is that of the first
register allocated, e.g. if A10 and A11 are treated as a
64 bit register, then A10 refers to the register pair, providing
of course AMODE has been set appropriately. Furthermore
compilers must choose consecutive registers such that they
start on a register boundary within the register set
which is an exact multiple of the number of machine registers
needed for a particular A register. Thus A10 is a valid
64 register but A9 is not.
@SParameters:
@
MODE@ISome features of MUTL necessitate registers for their
implementation, thus if such features are not needed in a particular
high level language, such registers will, wherever possible, be made
available as additional MUTL registers.@
@I0 - MUSL@
@I1 - FORTRAN@
@I2 - PASCAL@
@
[RESULT.VECTOR]@IA bounded pointer to a vector of integers
containing the Register Resource and Register Mapping tables.
@S223.13 DIAGNOSTICS
@BRun time diagnostics refer to items in terms of the source language program.
Most of the necessary information to accomplish this is in the
existing declarative procedures within MUTL, e.g. TL.S.DECL,
TL.TYPE etc. Alternatively or in addition to high level
language diagnostics a compile and data map of the
compilation may be produced from the diagnostic information
known at compile time.
The procedures in this section exist solely to
supply information to support diagnostics.
@
@
1) @JTL.LINE(LINE.NO)CODE.ADDRESS
@BMUTL notes the specified source language line number and this
should be called for each line of source program that generates
code.
@BTL.LINE yields the address of the next location in the code
area to enable compilers to incorporate this information in a
compile map.
@SParameters:-
@
LINE.NO 0@Imeans that the line number is obtained
by the basic system IN.LINE procedure.@
/=0@Imeans that the parameter itself specifies
the line number.
@
@
2) @JTL.BOUNDS(MUTL.NAME,[BOUNDS])
@BA vector variable in MUTL consists of a single dimension
with a lower bound of zero.
Languages that support multi-dimensional arrays, non-zero bounds or
adjustable dimensions may elect (for reasons of efficiency) to
map these arrays into a single dimension with a zero bound. TL.BOUNDS
function is therefore to define this mapping, so that array diagnostics are in
terms of the source language declaration of the array.
@BA multi-dimension array M may be mapped to a MUTL vector V in two
ways. Consider an array of N dimensions with lower and upper bounds on
each dimension of Li, Ui for i = 1, 2 .... N, and an array element
(M(S1, S2 .... Sn). A 'Forward Mapping' is such that M(S1, S2 .... Sn) is
mapped to@
@3
@U 5
@
     V((S1-L1)*D2*D3....*Dn + (S2-L2)*D3*D4....Dn
        + (Sn-1 - Ln-1)*Dn + (Sn-Ln)
@0
@
@
A 'Reverse Mapping' is such that M(S1, S2 .... Sn) is mapped to@
@3
@U 5
@
     V(S1-L1+(S2-L2)*D1 + (S3-L3)*D2*D1
       ................ (Sn-Ln)*Dn-1*Dn*...*D1)
@0
@
@
where Di is the size of the ith dimension i.e. (U1-L1+1).
@SParameters:
@
@
MUTL.NAME@IBit 0-11 specify the MUTL name. A value of zero in bit 13
means the array has a Forward Mapping, and value of one means it
has a Reverse Mapping.@
@
[BOUNDS]@IBounded pointer to vector of integer elements.
The bounds of a dimension are specified by a pair of elements.
The first element specifies the lower bound and the second the
upper bound of the dimension. Each element contains a MUTL name
of a literal or a scalar variable. However a value of zero is
permitted for U1 of a Forward mapped array, and for Un of a
Reversed mapped array; this means that the bound is not known.
@
@
3) @JTL.PRINT(MODE)
@BThis procedure controls the monitoring output of MUTL.
@SParameter:-
@
MODE@IThis is bit encoded.@
@
@IBit 0 = 1 means print name of all TL procedure
calls and their parameters.@
@IBit 1 = 1 means generate MUBL of all TL
procedure calls.@
@IBit 2 = 1 means print procedures map.@
@IBit 3 = 1 means print code generated.@
@IBit 5 = 1 means print data map.@
@IBit 6, 7 used by implementors of MUTL
for debug monitoring control. Object code
in MUTL is produced from an intermediate
form held in a vector. Setting bit
7 = 1 prints out this vector prior to
code generation. See Section 27 of the MUTL
Implementation Description for further
details of the encoding of this intermediate form.@
@IBit 8 = 1 means insert tracing instruction at the
beginning of each line.
@F
