1121 lines
		
	
	
	
		
			37 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			1121 lines
		
	
	
	
		
			37 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
.lg 0
 | 
						||
.ta 8 16 24 32 40 48 56 64 72 80
 | 
						||
.hw iden-ti-fi-er
 | 
						||
.nr a 0 1
 | 
						||
.nr f 1 1
 | 
						||
.de x1
 | 
						||
'sp 2
 | 
						||
'tl '''%'
 | 
						||
'sp 2
 | 
						||
.ns
 | 
						||
..
 | 
						||
.wh 0 x1
 | 
						||
.de fo
 | 
						||
'bp
 | 
						||
..
 | 
						||
.wh 60 fo
 | 
						||
.ll 79
 | 
						||
.lt 79
 | 
						||
.de HT
 | 
						||
.ti -4
 | 
						||
..
 | 
						||
.de PP
 | 
						||
.sp
 | 
						||
.ne 2
 | 
						||
.ti +5
 | 
						||
..
 | 
						||
.de SE
 | 
						||
.bp
 | 
						||
\fB\\n+a. \\$1\fR
 | 
						||
.nr b 0 1
 | 
						||
..
 | 
						||
.de SB
 | 
						||
.br
 | 
						||
.ne 10
 | 
						||
.sp 5
 | 
						||
\fB\\na.\\n+b. \\$1\fR
 | 
						||
..
 | 
						||
.de DC
 | 
						||
.ti -14
 | 
						||
DECISION~\\$1:
 | 
						||
..
 | 
						||
.de IN
 | 
						||
.in +6
 | 
						||
..
 | 
						||
.de OU
 | 
						||
.in -6
 | 
						||
..
 | 
						||
.tr ~
 | 
						||
.sp 5
 | 
						||
.rs
 | 
						||
.sp 10
 | 
						||
.ce 3
 | 
						||
Changes in EM-1
 | 
						||
 | 
						||
Addendum to Informatica Rapport IR-54
 | 
						||
.sp 5
 | 
						||
.PP
 | 
						||
This document describes a revision of EM-1.
 | 
						||
A list of differences is presented roughly in the order IR-54
 | 
						||
describes the original architecture.
 | 
						||
A complete list of EM-1 pseudo's and instructions is also included.
 | 
						||
.SE Introduction
 | 
						||
.PP
 | 
						||
EM is a family of intermediate languages, resembling assembly
 | 
						||
language for a stack machine.
 | 
						||
EM defines the layout of data memory and a partitioning
 | 
						||
of instruction memory.
 | 
						||
EM has can do operations on five basic types:
 | 
						||
pointers, signed integers, unsigned integers, floating point numbers
 | 
						||
and sets of bits.
 | 
						||
The size of pointers is fixed in each member,
 | 
						||
in contrast to the sizes of the other types.
 | 
						||
Each member has one more fixed size: the word size.
 | 
						||
This is the mimimum size of any object on the stack.
 | 
						||
The sizes of all objects on the stack are assumed to
 | 
						||
multiples of the word size.
 | 
						||
We assume that pointer and word-sizes are both powers of two.
 | 
						||
.PP
 | 
						||
It is possible to load objects smaller then the word size from memory.
 | 
						||
These objects are converted to objects of the word size by
 | 
						||
clearing the most significant bytes.
 | 
						||
(A separate conversion instruction can do sign extension).
 | 
						||
While storing objects smaller then the word size are stored in memory,
 | 
						||
the most significant bytes are ignored.
 | 
						||
The size of such objects has to be a divisor of the word size.
 | 
						||
.PP
 | 
						||
Put in other terms, instructions such as LOC, LOL, LOE, STF, etc.
 | 
						||
manipulate WORDS.  Up until now, a word was defined as 16 bits.
 | 
						||
It is now possible to define a word size other than 16 bits.  For
 | 
						||
example, MES 2,1,2 defines a word to be 8 bits and a pointer to be
 | 
						||
16 bits.  As another example, MES 2,4,4 defines a word to be 32 bits
 | 
						||
and a pointer to be 32 bits.
 | 
						||
.PP
 | 
						||
If a compiler receives flags telling it to use 32 bit integers, it now
 | 
						||
has a choice of setting the word length to 16 bits and using LDL etc
 | 
						||
for dealing with integers, or setting the word length to 32 bits and using
 | 
						||
LOL etc for integers.
 | 
						||
For example, x:=a+b for 32-bit integers would become:
 | 
						||
 | 
						||
  MES 2,2,4                          MES 2,4,4
 | 
						||
  LDL a                              LOL a
 | 
						||
  LDL b                              LOL b
 | 
						||
  ADI 4                              ADI 4
 | 
						||
  SDL x                              STL x
 | 
						||
 | 
						||
In many cases, the target machine code that is finally produced from either
 | 
						||
of the above sequences will not show any traces of the stack machine, however
 | 
						||
for some instructions actual pushes and pops at run time will be necessary.
 | 
						||
Choosing a wider EM word will usually produce fewer stack operations than
 | 
						||
a narrower word, but it eliminates the possibility of doing arithmetic on
 | 
						||
quantities smaller than a word.  If, for example, a compiler chooses a 32-bit
 | 
						||
EM word, it will be difficult to add two 16 bit integers with ADI, since
 | 
						||
the argument must be multiple of the word size.
 | 
						||
(The operation can be done by converting the operands to 32 bits using CII,
 | 
						||
adding the 32-bit numbers, and reconverting the result.)
 | 
						||
On the other hand, choosing a 16-bit EM word makes it possible to do both
 | 
						||
16-bit adds (ADI 2) and 32-bit adds (ADI 4), 
 | 
						||
but the price paid is that 32-bit operations will be viewed as double
 | 
						||
precision, and may be slightly less efficient on target machines with a
 | 
						||
32-bit word, i.e. the EM to target translator may not take full advantage
 | 
						||
of the 32 bit facilities.
 | 
						||
.PP
 | 
						||
Note that since LOC pushes a WORD on the stack, the argument of LOC
 | 
						||
must fit ina word.  LOC 256 on an EM machine with a 1-byte word length
 | 
						||
is not allowed.  LDC 256 is allowed, however.
 | 
						||
.PP
 | 
						||
A general rule of thumb is that the compiler should choose an EM word
 | 
						||
length equal to the width of a single precision integer.
 | 
						||
Obviously, compilers should be well parameterized to allow the integer
 | 
						||
size(s) and word size(s) to be changed by just changing a few constants.
 | 
						||
.PP
 | 
						||
The size of a instruction space pointer in is the same
 | 
						||
as the size of a data space pointer.
 | 
						||
.PP
 | 
						||
EM assumes two's complement arithmetic on signed integers,
 | 
						||
but does not define an ordering of the bytes in a integer.
 | 
						||
The lowest numbered byte of a two-byte object can contain
 | 
						||
either the most or the least significant part.
 | 
						||
.SE Memory
 | 
						||
.PP
 | 
						||
EM has two separate addressing spaces, instruction and data.
 | 
						||
The sizes of these spaces are not specified.
 | 
						||
The layout of instruction space in not defined.
 | 
						||
Any interpreter or translator may assume a layout fitting his/her needs.
 | 
						||
The layout of data memory is specified by EM.
 | 
						||
EM data memory consists of a sequence of 8-bit bytes each separately
 | 
						||
addressable.
 | 
						||
Certain alignment restrictions exist for object consisting of multiple bytes.
 | 
						||
Objects smaller then the word size can only be addressed
 | 
						||
at multiples of the object size.
 | 
						||
For example: in a member with a four-byte word size, two-byte integers
 | 
						||
can only be accessed from even addresses.
 | 
						||
Objects larger then the word size can only be placed at multiples
 | 
						||
of the word size.
 | 
						||
For example: in a member with a four-byte word size,
 | 
						||
eight-byte floating point numbers can be fetched at addresses
 | 
						||
0, 4, 8, 12, etc.
 | 
						||
.SB "Procedure identifiers"
 | 
						||
.PP
 | 
						||
Procedure identifiers in EM have the same size
 | 
						||
as pointers.
 | 
						||
Any implementation of EM is free to use any method of identifying procedures.
 | 
						||
Common methods are indices into tables containing further information
 | 
						||
and addresses of the first instructions of procedures.
 | 
						||
.SB "Heap and Stack in global data"
 | 
						||
.PP
 | 
						||
The stack grows downward, the heap grows upward.
 | 
						||
The stack pointer points to the lowest occupied word on the stack.
 | 
						||
The heap pointer marks the first free word in the heap area.
 | 
						||
.br
 | 
						||
.ne 39
 | 
						||
.sp 1
 | 
						||
.nf
 | 
						||
       65534 -> |-------------------------------|
 | 
						||
                |///////////////////////////////|
 | 
						||
		|//// unimplemented memory /////|
 | 
						||
                |///////////////////////////////|
 | 
						||
          SB -> |-------------------------------|
 | 
						||
		|				|
 | 
						||
		|     stack and local area      | <- LB
 | 
						||
                |                               |
 | 
						||
		|				|
 | 
						||
                |-------------------------------| <- SP
 | 
						||
		|///////////////////////////////|
 | 
						||
		|// implementation dependent  //|
 | 
						||
		|///////////////////////////////|
 | 
						||
                |-------------------------------| <- HP
 | 
						||
		|				|
 | 
						||
		|           heap area           |
 | 
						||
		|				|
 | 
						||
		|                               |
 | 
						||
                |-------------------------------|
 | 
						||
		|				|
 | 
						||
		|          global area          |
 | 
						||
		|				|
 | 
						||
          EB -> |-------------------------------|
 | 
						||
		|				|
 | 
						||
		|				|
 | 
						||
                |         program text          | <- PC
 | 
						||
		|				|
 | 
						||
		|				|
 | 
						||
          PB -> |-------------------------------|
 | 
						||
		|///////////////////////////////|
 | 
						||
		|////////// undefined //////////|
 | 
						||
		|///////////////////////////////|
 | 
						||
           0 -> |-------------------------------|
 | 
						||
 | 
						||
	   Fig. \nf.  Example of memory layout showing typical register
 | 
						||
           positions during execution of an EM program.
 | 
						||
.fi
 | 
						||
.SB "Data addresses as arguments"
 | 
						||
.PP
 | 
						||
Anywhere previous versions of the EM assembly language
 | 
						||
allowed identifiers of objects in
 | 
						||
data space,
 | 
						||
it is also possible to use 'identifier+constant' or 'identifier-constant'.
 | 
						||
For example, both "CON LABEL+4" and "LAE SAVED+3" are allowed.
 | 
						||
More complicated expressions are illegal.
 | 
						||
.SB "Local data area"
 | 
						||
.PP
 | 
						||
The mark block has been banished.
 | 
						||
When calling a procedure,
 | 
						||
the calling routine first has to push the actual parameters.
 | 
						||
All language implementations currently push their arguments
 | 
						||
in reverse order, to be compatible with C.
 | 
						||
Then the procedure is called using a CAL or CAI instruction.
 | 
						||
Either the call or the procedure prolog somehow has to save
 | 
						||
the return address and dynamic link.
 | 
						||
The prolog allocates the space needed for locals and is free to
 | 
						||
surround this space with saved registers and other information it
 | 
						||
deems necessary.
 | 
						||
.PP
 | 
						||
The locals are now accessed using negative offsets in LOL, LDL, SDL, LAL,
 | 
						||
LIL, SIL and STL instructions.
 | 
						||
The parameters are accessed using positive offsets in LOL, LDL, SDL, LAL,
 | 
						||
LIL, STL and
 | 
						||
STL instructions.
 | 
						||
The prolog might have stored information in the area between parameters and
 | 
						||
locals.
 | 
						||
As a consequence there are two bases, AB(virtual) and LB.
 | 
						||
AB stands for Argument Base and LB stands for Local Base.
 | 
						||
Positive arguments to LOL etc ... are interpreted as offsets from AB,
 | 
						||
negative arguments as offsets from LB.
 | 
						||
.PP
 | 
						||
The BEG instruction is not needed to allocate the locals because
 | 
						||
storage for locals is set aside in the prolog.
 | 
						||
The instruction still exists under the name ASP (Adjust Stack Pointer).
 | 
						||
.PP
 | 
						||
Procedures return using the RET instruction.
 | 
						||
The RET pops the function result from the stack and
 | 
						||
brings the stack pointer and other relevant registers to the state
 | 
						||
they had just before the procedure was called.
 | 
						||
The RET instruction expects that - aside from possible function results -
 | 
						||
the stack pointer has the value it had after execution of the prolog.
 | 
						||
RET finally returns control to the calling routine.
 | 
						||
The actual parameters have to be removed from the stack by the calling routine,
 | 
						||
and not by the called procedure.
 | 
						||
.sp 1
 | 
						||
.ne 38
 | 
						||
.nf
 | 
						||
 | 
						||
 | 
						||
 | 
						||
		|===============================|
 | 
						||
                |     actual argument  n        |
 | 
						||
		|-------------------------------|
 | 
						||
                |              .                |
 | 
						||
                |              .                |
 | 
						||
                |              .                |
 | 
						||
		|-------------------------------|
 | 
						||
                |     actual argument  1        | ( <- AB )
 | 
						||
		|===============================|
 | 
						||
		|///////////////////////////////|
 | 
						||
		|// implementation dependent  //|
 | 
						||
		|///////////////////////////////|   <- LB
 | 
						||
                |===============================|
 | 
						||
                |                               |
 | 
						||
                |       local variables         |
 | 
						||
                |                               |
 | 
						||
		|-------------------------------|
 | 
						||
                |                               |
 | 
						||
                |      compiler temporaries     |
 | 
						||
                |                               |
 | 
						||
		|===============================|
 | 
						||
		|///////////////////////////////|
 | 
						||
		|// implementation dependent  //|
 | 
						||
		|///////////////////////////////|
 | 
						||
                |===============================|
 | 
						||
                |                               |
 | 
						||
                |   dynamic local generators    |
 | 
						||
                |                               |
 | 
						||
		|===============================|
 | 
						||
                |           operand             |
 | 
						||
		|-------------------------------|
 | 
						||
                |           operand             | <- SP
 | 
						||
		|===============================|
 | 
						||
 | 
						||
                A sample procedure frame.
 | 
						||
 | 
						||
.fi
 | 
						||
.sp 1
 | 
						||
This scheme allows procedures to be called with a variable number
 | 
						||
of parameters.
 | 
						||
The parameters have to be pushed in reverse order,
 | 
						||
because the called procedure has to be able to locate the first one.
 | 
						||
.PP
 | 
						||
.PP
 | 
						||
Since the mark block has disappeared, a new mechanism for static
 | 
						||
links had to be created.
 | 
						||
All compilers use the convention that EM procedures needing
 | 
						||
a static link will find a link in their zero'th parameter,
 | 
						||
i.e. the last one pushed on the stack.
 | 
						||
This parameter should be invisible to users of the compiler.
 | 
						||
The link needs to be in a fixed place because the lexical instructions
 | 
						||
have to locate it.
 | 
						||
The LEX instruction is replaced by two instructions: LXL and LXA.
 | 
						||
\&"LXL~n" finds the LB of a procedure n static levels removed.
 | 
						||
\&"LXA~n" finds the (virtual) AB.
 | 
						||
The value used for static link is LB.
 | 
						||
.PP
 | 
						||
When a procedure needing a static link is called, first the actual
 | 
						||
parameters are pushed, then the static link is pushed using LXL
 | 
						||
and finally the procedure is called with a CAL with the procedure's
 | 
						||
name as argument.
 | 
						||
.br
 | 
						||
.ne 40
 | 
						||
.nf
 | 
						||
 | 
						||
 | 
						||
 | 
						||
		|===============================|
 | 
						||
                |     actual argument  n        |
 | 
						||
		|-------------------------------|
 | 
						||
                |              .                |
 | 
						||
                |              .                |
 | 
						||
                |              .                |
 | 
						||
		|-------------------------------|
 | 
						||
                |     actual argument  1        |
 | 
						||
		|-------------------------------|
 | 
						||
                |        static link            | ( <- AB )
 | 
						||
		|===============================|
 | 
						||
		|///////////////////////////////|
 | 
						||
		|// implementation dependent  //|
 | 
						||
		|///////////////////////////////|   <- LB
 | 
						||
                |===============================|
 | 
						||
                |                               |
 | 
						||
                |       local variables         |
 | 
						||
                |                               |
 | 
						||
		|-------------------------------|
 | 
						||
                |                               |
 | 
						||
                |      compiler temporaries     |
 | 
						||
                |                               |
 | 
						||
		|===============================|
 | 
						||
		|///////////////////////////////|
 | 
						||
		|// implementation dependent  //|
 | 
						||
		|///////////////////////////////|
 | 
						||
                |===============================|
 | 
						||
                |                               |
 | 
						||
                |   dynamic local generators    |
 | 
						||
                |                               |
 | 
						||
		|===============================|
 | 
						||
                |           operand             |
 | 
						||
		|-------------------------------|
 | 
						||
                |           operand             | <- SP
 | 
						||
		|===============================|
 | 
						||
 | 
						||
                A procedure frame with static link.
 | 
						||
 | 
						||
.fi
 | 
						||
.sp 1
 | 
						||
.sp 1
 | 
						||
.PP
 | 
						||
Pascal and other languages have to use procedure
 | 
						||
instance identifiers containing
 | 
						||
the procedure identifier
 | 
						||
'ul
 | 
						||
and
 | 
						||
the static link the procedure has to be called with.
 | 
						||
A static link having a value of zero signals
 | 
						||
that the called procedure does not need a static link.
 | 
						||
C uses the same convention for pointers to C-routines.
 | 
						||
In pointers to C-routines the static link is set to zero.
 | 
						||
.PP
 | 
						||
Note: The distance from LB to AB must be known for each procedure, otherwise
 | 
						||
LXA can not be implemented.
 | 
						||
Most implementations will have a fixed size area between
 | 
						||
the parameter and local storage.
 | 
						||
The zone between the compiler temporaries and the dynamic
 | 
						||
local generators can be used
 | 
						||
to save a variable number of registers.
 | 
						||
.PP
 | 
						||
.ne 11
 | 
						||
Prolog examples:
 | 
						||
.sp 2
 | 
						||
.nf
 | 
						||
 | 
						||
	       proc1                       proc2
 | 
						||
	   
 | 
						||
	   mov lb,-(sp)                mov lb,-(sp)
 | 
						||
	   mov sp,lb                   mov sp,lb
 | 
						||
	   sub $loc_size,sp            sub $loc_size,sp
 | 
						||
	   mov r2,-(sp) ; save r2      mov r2,-(sp)
 | 
						||
	   mov r4,-(sp) ; save r4
 | 
						||
 | 
						||
.fi
 | 
						||
.SB "Return values"
 | 
						||
.PP
 | 
						||
The return value popped by RET is stored in an unnamed 'function return area'.
 | 
						||
This area can be different for different sized objects returned,
 | 
						||
e.g. one register for two byte objects,
 | 
						||
two registers for four byte objects,
 | 
						||
memory for larger objects.
 | 
						||
The area is available for 'READ-ONCE' access using the LFR instruction.
 | 
						||
The result of a LFR is only defined if the sizes used to store and
 | 
						||
fetch are identical.
 | 
						||
The only instructions guaranteed not to destroy the contents of
 | 
						||
any 'function return area' are ASP and BRA.
 | 
						||
Thus parameters can be popped before fetching the function result.
 | 
						||
The maximum size of all function return areas is
 | 
						||
implementation dependant,
 | 
						||
but allows procedure instance identifiers and all
 | 
						||
implemented objects of type integer, unsigned, float
 | 
						||
and pointer to be returned.
 | 
						||
 | 
						||
.SE "EM Assembly Language"
 | 
						||
.nr b 0 1
 | 
						||
.SB "Object types and instructions"
 | 
						||
.PP
 | 
						||
EM knows five basic object types:
 | 
						||
pointers,
 | 
						||
signed integers,
 | 
						||
unsigned integers,
 | 
						||
floating point numbers and
 | 
						||
sets of bits.
 | 
						||
Operations on objects of the last four types do not assume
 | 
						||
a specific size.
 | 
						||
Pointers (including procedure identifiers) have a fixed size in each
 | 
						||
implementation.
 | 
						||
Instructions acting on one or more objects of the last four types need
 | 
						||
explicit size information.
 | 
						||
This information can be given either as the argument of the
 | 
						||
instruction or on top of the stack.
 | 
						||
.sp 1
 | 
						||
For example:
 | 
						||
.nf
 | 
						||
addition of integers         LOL a, LOL b, ADI 2
 | 
						||
subtraction of two floats    LDL a, LDL b, SBF 4
 | 
						||
integer to float             LOL a, LOC 2, LOC 4, CIF, SDL b
 | 
						||
.fi
 | 
						||
.sp
 | 
						||
Note that conversion instructions always expect size
 | 
						||
before and size after conversion on the stack.
 | 
						||
.sp
 | 
						||
No obligation exists to implement all operations on all possible sizes.
 | 
						||
.PP
 | 
						||
The EM assembly language
 | 
						||
allows constants as instruction arguments up to a size of four bytes.
 | 
						||
In all EM's it is possible to initialize any type and size object.
 | 
						||
BSS, HOL, CON and ROM allow type and size indication in initializers.
 | 
						||
.SB "Conversion instructions"
 | 
						||
.PP
 | 
						||
The conversion operators can convert from any type and size to any
 | 
						||
type and size.
 | 
						||
The types are specified by the instruction,
 | 
						||
the sizes should be in words on top of the stack.
 | 
						||
Normally the sizes are multiples of the word size,
 | 
						||
There is one exception: the CII instructions sign-extends if the
 | 
						||
size of the source is a divisor of the word size.
 | 
						||
.SB "CSA and CSB"
 | 
						||
.PP
 | 
						||
The tables used by these instructions do not contain the procedure
 | 
						||
identifier any more.
 | 
						||
See also "Descriptors".
 | 
						||
.SB EXG
 | 
						||
.PP
 | 
						||
The EXG instruction is deleted from the EM instruction set.
 | 
						||
If future applications show any need for this instruction,
 | 
						||
it will be added again.
 | 
						||
.SB "FIL"
 | 
						||
.PP
 | 
						||
A FIL instruction has been introduced.
 | 
						||
When using separate compilation,
 | 
						||
the LIN feature of EM was insufficient.
 | 
						||
FIL expects as argument an address in global data.
 | 
						||
This address is stored in a fixed place in memory,
 | 
						||
where it can be used by any implementation for diagnostics etc.
 | 
						||
Like LIN, it provides access to the ABS fragment at the start
 | 
						||
of external data.
 | 
						||
.SB "LAI and SAI"
 | 
						||
.PP
 | 
						||
LAI and SAI have been dropped, they thwarted register optimization.
 | 
						||
.SB LNC
 | 
						||
.PP
 | 
						||
The LNC instruction is deleted from the instruction set.
 | 
						||
LOC -n wil do what it is supposed to.
 | 
						||
.SB "Branch instructions"
 | 
						||
.PP
 | 
						||
The branch instructions are allowed to branch both forward and backward.
 | 
						||
Consequently BRF and BRB are deleted and a BRA instruction is added.
 | 
						||
BRA branches unconditionally in any direction.
 | 
						||
.SB LDC
 | 
						||
.PP
 | 
						||
Loads a double word constant on the stack.
 | 
						||
.SB LEX
 | 
						||
.PP
 | 
						||
LXA and LXL replace LEX.
 | 
						||
.SB LFR
 | 
						||
.PP
 | 
						||
LFR loads the function result stored by RET.
 | 
						||
.SB "LIL and SIL"
 | 
						||
.PP
 | 
						||
They replace LOP and STP. (Name change only)
 | 
						||
.SB "Traps and Interrupts"
 | 
						||
.PP
 | 
						||
The numbers used for distinguishing the various types
 | 
						||
of traps and interrupts have been reassigned.
 | 
						||
The new instructions LIM and SIM
 | 
						||
allow setting and clearing of bits in a mask.
 | 
						||
The bits in the mask control the action taken upon encountering certain
 | 
						||
errors at runtime.
 | 
						||
A 1 bit causes the corresponding error to be ignored,
 | 
						||
a 0 bit causes the run-time system to trap.
 | 
						||
.SB LPI
 | 
						||
.PP
 | 
						||
Loads a procedure identifier on the stack.
 | 
						||
LOC cannot be used to do this anymore.
 | 
						||
.SB "ZER and ZRF"
 | 
						||
.PP
 | 
						||
ZER loads S zero bytes on the stack.
 | 
						||
ZRF loads a floating point zero of size S.
 | 
						||
.SB "Descriptors"
 | 
						||
.PP
 | 
						||
All instructions using descriptors have the size of the integer used
 | 
						||
in the descriptor as argument.
 | 
						||
The descriptors are: case descriptors (CSA and CSB),
 | 
						||
range check descriptors (RCK) and
 | 
						||
array descriptors ( LAR, SAR, AAR).
 | 
						||
.SB "Case descriptors"
 | 
						||
.PP
 | 
						||
The value used in a case descriptor to indicate the absence of a label
 | 
						||
is zero instead of -1.
 | 
						||
.SE "EM assembly language"
 | 
						||
.SB "Instruction arguments"
 | 
						||
.PP
 | 
						||
The previous EM had different instructions for distinguishing
 | 
						||
between operand on the stack and explicit argument in the instruction.
 | 
						||
For example, LOI and LOS.
 | 
						||
This distinction has been removed.
 | 
						||
Several instructions have two possible forms:
 | 
						||
with explicit argument and with implicit argument on top of the stack.
 | 
						||
The size of the implicit argument is the word size.
 | 
						||
The implicit argument is always popped before all other operands.
 | 
						||
Appendix 1 shows what is allowed for each instruction.
 | 
						||
.SB Notation
 | 
						||
.PP
 | 
						||
First the notation used for the arguments of
 | 
						||
instructions and pseudo instructions.
 | 
						||
.in +12
 | 
						||
.ti -11
 | 
						||
<num>~~=~~an integer number in the range -32768..32767
 | 
						||
.ti -11
 | 
						||
<off>~~=~~an offset -2**31..2**31~-~1
 | 
						||
.ti -11
 | 
						||
<sym>~~=~~an identifier
 | 
						||
.ti -11
 | 
						||
<arg>~~=~~<off> or <sym> or <sym>+<off> or <sym>-<off>
 | 
						||
.ti -11
 | 
						||
<con>~~=~~integer constant,
 | 
						||
unsigned constant,
 | 
						||
floating point constant
 | 
						||
.ti -11
 | 
						||
<str>~~=~~string constant (surrounded by double quotes),
 | 
						||
.ti -11
 | 
						||
<lab>~~=~~instruction label ('*' followed by an integer in the range
 | 
						||
0..32767).
 | 
						||
.ti -11
 | 
						||
<pro>~~=~~procedure number ('$' followed by a procedure name)
 | 
						||
.ti -11
 | 
						||
<val>~~=~~<arg>,
 | 
						||
<con>,
 | 
						||
<pro> or
 | 
						||
<lab>.
 | 
						||
.ti -11
 | 
						||
<...>*~=~~zero or more of <...>
 | 
						||
.ti -11
 | 
						||
<...>+~=~~one or more of <...>
 | 
						||
.ti -11
 | 
						||
[...]~~=~~optional ...
 | 
						||
.in -12
 | 
						||
.SB Labels
 | 
						||
.PP
 | 
						||
No label, instruction or data, can have a (pseudo) instruction
 | 
						||
on the same line.
 | 
						||
.SB Constants
 | 
						||
.PP
 | 
						||
All constants in EM are interpreted in the decimal base.
 | 
						||
.PP
 | 
						||
In BSS, HOL, CON and ROM pseudo-instructions
 | 
						||
numbers must be followed by I, U or F
 | 
						||
indicating Integer, Unsigned or Float.
 | 
						||
If no character is present I is assumed.
 | 
						||
This character can be followed by an even positive number or a 1.
 | 
						||
The number indicates the size in bytes of the object to be initialized,
 | 
						||
up to 32766.
 | 
						||
Double precision integers can no longer be indicated by a trailing L.
 | 
						||
As said before CON and ROM also allow expressions of the form:
 | 
						||
\&"LABEL+offset" and "LABEL-offset".
 | 
						||
The offset must be an unsigned decimal number.
 | 
						||
The 'IUF' indicators cannot be used with the offsets.
 | 
						||
.PP
 | 
						||
Areas reserved in the global data area by HOL or BSS can be
 | 
						||
initialized.
 | 
						||
BSS and HOL have a third parameter indicating whether the initialization
 | 
						||
is mandatory or optional.
 | 
						||
.PP
 | 
						||
Since EM needs aligment of objects, this alignment is enforced by the
 | 
						||
pseudo instructions.
 | 
						||
All objects are aligned on a multiple of their size or the word size
 | 
						||
whichever is smaller.
 | 
						||
Switching to another type of fragment or placing a label forces word-alignment.
 | 
						||
There are three types of fragments in global data space: CON, ROM and BSS-HOL.
 | 
						||
.sp
 | 
						||
.SB "Pseudo instructions"
 | 
						||
.PP
 | 
						||
The LET, IMC and FWC pseudo's have disappeared.
 | 
						||
The only application of these pseudo's was in postponing the
 | 
						||
specification of the size of the local storage to just before
 | 
						||
the END of the procedure.
 | 
						||
A new mechanism has been introduced to handle this problem.
 | 
						||
.ti +5
 | 
						||
The pseudos involved in separate compilation and linking have
 | 
						||
been reorganized.
 | 
						||
.ti +5
 | 
						||
PRO and END are altered and reflect the new calling sequence.
 | 
						||
EOF has disappeared.
 | 
						||
.ti +5
 | 
						||
BSS and HOL allow initialization of the requested data areas.
 | 
						||
.sp 2
 | 
						||
Four pseudo instructions request global data:
 | 
						||
.sp 2
 | 
						||
  BSS <off>,<val>,<num>
 | 
						||
.IN
 | 
						||
Reserve <off> bytes.
 | 
						||
<val> is the value used to initialize the area.
 | 
						||
<off> must be a multiple of the size of <val>.
 | 
						||
<num> is 0 if the initialization is not strictly necessary,
 | 
						||
1 otherwise.
 | 
						||
.OU
 | 
						||
.sp
 | 
						||
  HOL <off>,<val>,<num> 
 | 
						||
.IN
 | 
						||
Idem, but all following absolute global data references will
 | 
						||
refer to this block.
 | 
						||
Only one HOL is allowed per procedure,
 | 
						||
it has to be placed before the first instruction.
 | 
						||
.OU
 | 
						||
.sp
 | 
						||
  CON <val>+ 
 | 
						||
.IN
 | 
						||
Assemble global data words initialized with the <val> constants.
 | 
						||
.OU
 | 
						||
.sp
 | 
						||
  ROM <val>+ 
 | 
						||
.IN
 | 
						||
Idem, but the initialized data will never be changed by the program.
 | 
						||
.OU
 | 
						||
.sp 2
 | 
						||
Two pseudo instructions partition the input into procedures:
 | 
						||
.sp 2
 | 
						||
  PRO <sym>[,<off>] 
 | 
						||
.IN
 | 
						||
Start of procedure.
 | 
						||
<sym> is the procedure name.
 | 
						||
<off> is the number of bytes for locals.
 | 
						||
The number of bytes for locals must be specified in the PRO or
 | 
						||
END pseudo-instruction.
 | 
						||
When specified in both, they must be identical.
 | 
						||
.OU
 | 
						||
.sp
 | 
						||
  END  [<off>]
 | 
						||
.IN
 | 
						||
End of Procedure.
 | 
						||
<off> is the number of bytes for locals.
 | 
						||
The number of bytes for locals must be specified in either the PRO or
 | 
						||
END pseudo-instruction or both.
 | 
						||
.OU
 | 
						||
.PP
 | 
						||
Names of data and procedures in a EM module can either be
 | 
						||
internal or external.
 | 
						||
External names are known outside the module and are used to link
 | 
						||
several pieces of a program.
 | 
						||
Internal names are not known outside the modules they are used in.
 | 
						||
Other modules will not 'see' an internal name.
 | 
						||
.ti +5
 | 
						||
In order to reduce the number of passes needed,
 | 
						||
it must be known at the first occurrence whether
 | 
						||
a name is internal or external.
 | 
						||
If the first occurrence of a name is in a definition,
 | 
						||
the name is considered to be internal.
 | 
						||
If the first occurrence of a name is a reference,
 | 
						||
the name is considered to be external.
 | 
						||
If the first occurrence is in one of the following pseudo instructions,
 | 
						||
the effect of the pseudo has precedence.
 | 
						||
.sp 2
 | 
						||
  EXA <sym> 
 | 
						||
.IN
 | 
						||
External name.
 | 
						||
<sym> is external to this module.
 | 
						||
Note that <sym> may be defined in the same module.
 | 
						||
.OU
 | 
						||
.sp
 | 
						||
  EXP <pro>
 | 
						||
.IN
 | 
						||
External procedure identifier.
 | 
						||
Note that <sym> may be defined in the same module.
 | 
						||
.OU
 | 
						||
.sp
 | 
						||
  INA <sym>
 | 
						||
.IN
 | 
						||
Internal name.
 | 
						||
<sym> is internal to this module and must be defined in this module.
 | 
						||
.OU
 | 
						||
.sp
 | 
						||
  INP <pro> 
 | 
						||
.IN
 | 
						||
Internal procedure.
 | 
						||
<sym> is internal to this module and must be defined in this module.
 | 
						||
.OU
 | 
						||
.sp 2
 | 
						||
Two other pseudo instructions provide miscellaneous features:
 | 
						||
.sp 2
 | 
						||
  EXC <num1>,<num2> 
 | 
						||
.IN
 | 
						||
Two blocks of instructions preceding this one are
 | 
						||
interchanged before being processed.
 | 
						||
<num1> gives the number of lines of the first block.
 | 
						||
<num2> gives the number of lines of the second one.
 | 
						||
Blank and pure comment lines do not count.
 | 
						||
.OU
 | 
						||
.sp
 | 
						||
  MES <num>,<val>* 
 | 
						||
.IN
 | 
						||
A special type of comment.  Used by compilers to communicate with the
 | 
						||
optimizer, assembler, etc. as follows:
 | 
						||
.br
 | 
						||
  MES 0 -
 | 
						||
.IN
 | 
						||
An error has occurred, stop further processing.
 | 
						||
.OU
 | 
						||
.br
 | 
						||
  MES 1 -
 | 
						||
.IN
 | 
						||
Suppress optimization
 | 
						||
.OU
 | 
						||
.br
 | 
						||
  MES 2,<num1>,<num2>
 | 
						||
.IN
 | 
						||
Use word-size <num1> and pointer size <num2>.
 | 
						||
.OU
 | 
						||
.br
 | 
						||
  MES 3,<off>,<num1>,<num2> -
 | 
						||
.IN
 | 
						||
Indicates that a local variable is never referenced indirectly.
 | 
						||
<off> is offset in bytes from LB if positive
 | 
						||
and offset from AB if negative.
 | 
						||
<num1> gives the size of the variable.
 | 
						||
<num2> indicates the class of the variable.
 | 
						||
.OU
 | 
						||
.br
 | 
						||
  MES 4,<num>,<str>
 | 
						||
.IN
 | 
						||
Number of source lines in file <str> (for profiler).
 | 
						||
.OU
 | 
						||
.br
 | 
						||
  MES 5 -
 | 
						||
.IN
 | 
						||
Floating point used.
 | 
						||
.OU
 | 
						||
.br
 | 
						||
  MES 6,<val>* -
 | 
						||
.IN
 | 
						||
Comment.  Used to provide comments in compact assembly language (see below).
 | 
						||
.OU
 | 
						||
.sp 1
 | 
						||
Each back end is free to skip irrelevant MES pseudos.
 | 
						||
.OU
 | 
						||
.SB "The Compact Assembly Language"
 | 
						||
.PP
 | 
						||
The assembler accepts input in a highly encoded form.  This
 | 
						||
form is intended to reduce the amount of file transport between the compiler
 | 
						||
and assembler, and also reduce the amount of storage required for storing
 | 
						||
libraries.
 | 
						||
Libraries are stored as archived compact assembly language, not machine language.
 | 
						||
.PP
 | 
						||
When beginning to read the input, the assembler is in neutral state, and
 | 
						||
expects either a label or an instruction (including the pseudoinstructions).
 | 
						||
The meaning of the next byte(s) when in neutral state is as follows, where b1, b2 
 | 
						||
etc. represent the succeeding bytes.
 | 
						||
.sp
 | 
						||
       0   Reserved for future use
 | 
						||
   1-129   Machine instructions, see Appendix 2, alphabetical list
 | 
						||
 130-149   Reserved for future use
 | 
						||
 150-161   BSS,CON,END,EXC,EXA,EXP,HOL,INA,INP,MES,PRO,ROM
 | 
						||
 162-179   Reserved for future pseudoinstructions
 | 
						||
 180-239   Instruction labels 0 - 59  (180 is local label 0 etc.)
 | 
						||
 240-244   See the Common Table below
 | 
						||
 245-255   Not used
 | 
						||
 | 
						||
After a label, the assembler is back in neutral state; it can immediately
 | 
						||
accept another label or an instruction in the very next byte.  There are
 | 
						||
no linefeeds used to separate lines.
 | 
						||
.PP
 | 
						||
If an opcode expects no arguments,
 | 
						||
the assembler is back in neutral state after
 | 
						||
reading the one byte containing the instruction number.  If it has one or
 | 
						||
more arguments (only pseudos have more than 1), the arguments follow directly,
 | 
						||
encoded as follows:
 | 
						||
.sp
 | 
						||
   0-239     Offsets from -120 to 119
 | 
						||
.br
 | 
						||
 240-255     See the Common Table below
 | 
						||
.sp 2
 | 
						||
If an opcode has one optional argument,
 | 
						||
a special byte is used to announce that the argument is not present.
 | 
						||
.ce 1
 | 
						||
Common Table for Neutral State and Arguments
 | 
						||
.sp
 | 
						||
.nf
 | 
						||
<lab>   240 b1                Instruction label b1  (Not used for branches)
 | 
						||
<lab>   241 b1 b2             16 bit instruction label  (256*b2 + b1)
 | 
						||
<sym>   242 b1                Global label .0-.255, with b1 being the label
 | 
						||
<sym>   243 b1 b2             Global label .0-.32767
 | 
						||
			      with 256*b2+b1 being the label
 | 
						||
<sym>   244 <string>          Global symbol not of the form .nnn
 | 
						||
. \" Only the previous can occur in neutral state.
 | 
						||
<num>   245 b1 b2             (16 bit constant) 256*b2+b1
 | 
						||
<off>   246 b1 b2 b3 b4       (32 bit constant) (256*(256*(256*b4)+b3)+b2)+b1
 | 
						||
<arg>   247 <sym><off>        Global label + (possibly negative) constant
 | 
						||
<pro>   248 <string>          Procedure name  (not including $)
 | 
						||
<str>   249 <string>          String used in CON or ROM (no quotes)
 | 
						||
<con>   250 <num><string>     Integer constant, size <num> bytes
 | 
						||
<con>   251 <num><string>     Unsigned constant, size <num> bytes
 | 
						||
<con>   252 <num><string>     Floating constant, size <num> bytes
 | 
						||
<end>   255                   Delimiter for argument lists or
 | 
						||
			      indicates absence of optional argument
 | 
						||
 | 
						||
.fi
 | 
						||
.PP
 | 
						||
The notation <string> consists first of a length field, and then an
 | 
						||
arbitrary string of bytes.
 | 
						||
The length is specified by a <num>.
 | 
						||
.PP
 | 
						||
.ne 8
 | 
						||
The pseudoinstructions fall into several categories, depending on their
 | 
						||
arguments:
 | 
						||
.sp
 | 
						||
 Group 1 -- EXC, BSS, HOL have a known number of arguments
 | 
						||
 Group 2 -- EXA, EXP, INA, INP start with a string
 | 
						||
 Group 3 -- CON, MES, ROM have a variable number of various things
 | 
						||
 Group 4 -- END, PRO have a trailing optional argument.
 | 
						||
 | 
						||
Groups 1 and 2
 | 
						||
use the encoding described above.
 | 
						||
Group 3 also uses the encoding listed above, with a <end> byte after the
 | 
						||
last argument to indicate the end of the list.  
 | 
						||
Group 4 uses
 | 
						||
a <end> byte if the trailing argument is not present.
 | 
						||
 | 
						||
.ad
 | 
						||
.fi
 | 
						||
.sp 2
 | 
						||
.ne 12
 | 
						||
.nf
 | 
						||
Example  ASCII			Example compact
 | 
						||
(LOC = 66, BRA = 18 here):
 | 
						||
 | 
						||
  2				182
 | 
						||
  1				181
 | 
						||
   LOC 10			66 130
 | 
						||
   LOC -10			66 110
 | 
						||
   LOC 300			66 245 44 1
 | 
						||
   BRA 19			18 139
 | 
						||
  300				241 44 1
 | 
						||
  .3				242 3 
 | 
						||
   CON 4,9,*2,$foo		151 124 130 240 2 248 3 102 111 111 255
 | 
						||
   LOC .35			66 242 35
 | 
						||
.fi
 | 
						||
.nr a 0 1
 | 
						||
.SE "ASSEMBLY LANGUAGE INSTRUCTION LIST"
 | 
						||
.PP
 | 
						||
For each instruction in the list the range of operand values
 | 
						||
in the assembly language is given.
 | 
						||
All constants, offsets and sizes are in the range -2**31~..~2**31-1.
 | 
						||
The column headed \fIassem\fP contains the mnemonics defined
 | 
						||
in 4.1.
 | 
						||
The following column indicates restrictions in the range of the operand.
 | 
						||
Addresses have to obey the restrictions mentioned in chapter 2 - Memory -.
 | 
						||
The size parameter of most instructions has to be a multiple
 | 
						||
of the word size.
 | 
						||
The classes of operands
 | 
						||
are indicated by letters:
 | 
						||
.ds b \fBb\fP
 | 
						||
.ds c \fBc\fP
 | 
						||
.ds d \fBd\fP
 | 
						||
.ds g \fBg\fP
 | 
						||
.ds f \fBf\fP
 | 
						||
.ds l \fBl\fP
 | 
						||
.ds n \fBn\fP
 | 
						||
.ds i \fBi\fP
 | 
						||
.ds p \fBp\fP
 | 
						||
.ds r \fBr\fP
 | 
						||
.ds s \fBs\fP
 | 
						||
.ds z \fBz\fP
 | 
						||
.ds - \fB-\fP
 | 
						||
.nf
 | 
						||
 | 
						||
  \fIassem\fP       constraints            rationale
 | 
						||
 | 
						||
\&\*c  off                                 1-word constant
 | 
						||
\&\*d  off                                 2-word constant
 | 
						||
\&\*l  off                                 local offset
 | 
						||
\&\*g  arg          >= 0                   global offset
 | 
						||
\&\*f  off                                 fragment offset
 | 
						||
\&\*n  num          >= 0                   counter
 | 
						||
\&\*s  off          > 0                    object size
 | 
						||
\&\*z  off          >= 0                   object size
 | 
						||
\&\*i  off          > 0                    object size *
 | 
						||
\&\*p  pro                                 pro identifier
 | 
						||
\&\*b  lab          >= 0                   label number
 | 
						||
\&\*r  num          0,1,2                  register number
 | 
						||
\&\*-                                      no operand
 | 
						||
 | 
						||
.fi
 | 
						||
.PP
 | 
						||
The * at the rationale for \*i indicates that the operand
 | 
						||
can either be given as argument or on top of the stack.
 | 
						||
If the operand has to be fetched from the stack,
 | 
						||
it is assumed to be a word-sized unsigned integer.
 | 
						||
.PP
 | 
						||
Instructions that check for undefined operands and underflow or overflow
 | 
						||
are indicated by (*).
 | 
						||
.nf
 | 
						||
 | 
						||
GROUP 1 - LOAD
 | 
						||
 | 
						||
  LOC \*c : Load constant (i.e. push one word onto the stack)
 | 
						||
  LDC \*d : Load double constant ( push two words )
 | 
						||
  LOL \*l : Load word at \*l-th local (l<0) or parameter (l>=0)
 | 
						||
  LOE \*g : Load external word \*g
 | 
						||
  LIL \*l : Load word pointed to by \*l-th local or parameter
 | 
						||
  LOF \*f : Load offsetted. (top of stack + \*f yield address)
 | 
						||
  LAL \*l : Load address of local or parameter
 | 
						||
  LAE \*g : Load address of external
 | 
						||
  LXL \*n : Load lexical. (address of LB \*n static levels back)
 | 
						||
  LXA \*n : Load lexical. (address of AB \*n static levels back)
 | 
						||
  LOI \*s : Load indirect \*s bytes (address is popped from the stack)
 | 
						||
  LOS \*i : Load indirect. \*i-byte integer on top of stack gives object size
 | 
						||
  LDL \*l : Load double local or parameter (two consecutive words are stacked)
 | 
						||
  LDE \*g : Load double external (two consecutive externals are stacked)
 | 
						||
  LDF \*f : Load double offsetted (top of stack + \*f yield address)
 | 
						||
  LPI \*p : Load procedure identifier
 | 
						||
 | 
						||
GROUP 2 - STORE
 | 
						||
 | 
						||
  STL \*l : Store local or parameter
 | 
						||
  STE \*g : Store external
 | 
						||
  SIL \*l : Store into word pointed to by \*l-th local or parameter
 | 
						||
  STF \*f : Store offsetted
 | 
						||
  STI \*s : Store indirect \*s bytes (pop address, then data)
 | 
						||
  STS \*i : Store indirect. \*i-byte integer on top of stack gives object size
 | 
						||
  SDL \*l : Store double local or parameter
 | 
						||
  SDE \*g : Store double external
 | 
						||
  SDF \*f : Store double offsetted
 | 
						||
 | 
						||
GROUP 3 - INTEGER ARITHMETIC
 | 
						||
 | 
						||
  ADI \*i : Addition (*)
 | 
						||
  SBI \*i : Subtraction (*)
 | 
						||
  MLI \*i : Multiplication (*)
 | 
						||
  DVI \*i : Division (*)
 | 
						||
  RMI \*i : Remainder (*)
 | 
						||
  NGI \*i : Negate (two's complement) (*)
 | 
						||
  SLI \*i : Shift left (*)
 | 
						||
  SRI \*i : Shift right (*)
 | 
						||
 | 
						||
GROUP 4 - UNSIGNED ARITHMETIC
 | 
						||
 | 
						||
  ADU \*i : Addition
 | 
						||
  SBU \*i : Subtraction
 | 
						||
  MLU \*i : Multiplication
 | 
						||
  DVU \*i : Division
 | 
						||
  RMU \*i : Remainder
 | 
						||
  SLU \*i : Shift left
 | 
						||
  SRU \*i : Shift right
 | 
						||
 | 
						||
GROUP 5 - FLOATING POINT ARITHMETIC   (Format not defined)
 | 
						||
 | 
						||
  ADF \*i : Floating add (*)
 | 
						||
  SBF \*i : Floating subtract (*)
 | 
						||
  MLF \*i : Floating multiply (*)
 | 
						||
  DVF \*i : Floating divide (*)
 | 
						||
  NGF \*i : Floating negate (*)
 | 
						||
  FIF \*i : Floating multiply and split integer and fraction part (*)
 | 
						||
  FEF \*i : Split floating number in exponent and fraction part (*)
 | 
						||
 | 
						||
GROUP 6 - POINTER ARITHMETIC
 | 
						||
 | 
						||
  ADP \*f : Add \*c to pointer on top of stack
 | 
						||
  ADS \*i : Add \*i-byte value and pointer
 | 
						||
  SBS \*i : Subtract pointers in same fragment and push diff as size \*i integer
 | 
						||
 | 
						||
GROUP 7 - INCREMENT/DECREMENT/ZERO
 | 
						||
 | 
						||
  INC \*- : Increment top of stack by 1 (*)
 | 
						||
  INL \*l : Increment local or parameter (*)
 | 
						||
  INE \*g : Increment external (*)
 | 
						||
  DEC \*- : Decrement top of stack by 1 (*)
 | 
						||
  DEL \*l : Decrement local or parameter (*)
 | 
						||
  DEE \*g : Decrement external (*)
 | 
						||
  ZRL \*l : Zero local or parameter
 | 
						||
  ZRE \*g : Zero external
 | 
						||
  ZRF \*i : Load a floating zero of size \*i
 | 
						||
  ZER \*i : Load \*i zero bytes
 | 
						||
 | 
						||
GROUP 8 - CONVERT    ( stack: source, source size, dest. size (top) )
 | 
						||
 | 
						||
  CII \*- : Convert integer to integer (*)
 | 
						||
  CUI \*- : Convert unsigned to integer (*)
 | 
						||
  CFI \*- : Convert floating to integer (*)
 | 
						||
  CIF \*- : Convert integer to floating (*)
 | 
						||
  CUF \*- : Convert unsigned to floating (*)
 | 
						||
  CFF \*- : Convert floating to floating (*)
 | 
						||
  CIU \*- : Convert integer to unsigned
 | 
						||
  CUU \*- : Convert unsigned to unsigned
 | 
						||
  CFU \*- : Convert floating to unsigned
 | 
						||
 | 
						||
GROUP 9 - LOGICAL
 | 
						||
 | 
						||
  AND \*i : Boolean and on two groups of \*i bytes
 | 
						||
  IOR \*i : Boolean inclusive or on two groups of \*i bytes
 | 
						||
  XOR \*i : Boolean exclusive or on two groups of \*i bytes
 | 
						||
  COM \*i : Complement (one's complement of top \*i bytes)
 | 
						||
  ROL \*i : Rotate left a group of \*i bytes
 | 
						||
  ROR \*i : Rotate right a group of \*i bytes
 | 
						||
 | 
						||
GROUP 10 - SETS
 | 
						||
 | 
						||
  INN \*i : Bit test on \*i byte set (bit number on top of stack)
 | 
						||
  SET \*i : Create singleton \*i byte set with bit n on (n is top of stack)
 | 
						||
 | 
						||
GROUP 11 - ARRAY
 | 
						||
 
 | 
						||
  LAR \*i : Load array element, descriptor contains integers of size \*i
 | 
						||
  SAR \*i : Store array element
 | 
						||
  AAR \*i : Load address of array element
 | 
						||
 | 
						||
GROUP 12 - COMPARE
 | 
						||
 | 
						||
  CMI \*i : Compare \*i byte integers. Push negative, zero, positive for <, = or >
 | 
						||
  CMF \*i : Compare \*i byte reals
 | 
						||
  CMU \*i : Compare \*i byte unsigneds
 | 
						||
  CMS \*i : Compare \*i byte sets. can only be used for equality test.
 | 
						||
  CMP \*- : Compare pointers
 | 
						||
 | 
						||
  TLT \*- : True if less, i.e. iff top of stack < 0
 | 
						||
  TLE \*- : True if less or equal, i.e. iff top of stack <= 0
 | 
						||
  TEQ \*- : True if equal, i.e. iff top of stack = 0
 | 
						||
  TNE \*- : True if not equal, i.e. iff top of stack non zero
 | 
						||
  TGE \*- : True if greater or equal, i.e. iff top of stack >= 0
 | 
						||
  TGT \*- : True if greater, i.e. iff top of stack > 0
 | 
						||
 | 
						||
GROUP 13 - BRANCH
 | 
						||
 | 
						||
  BRA \*b : Branch unconditionally to label \*b
 | 
						||
 | 
						||
  BLT \*b : Branch less (pop 2 words, branch if top > second)
 | 
						||
  BLE \*b : Branch less or equal
 | 
						||
  BEQ \*b : Branch equal
 | 
						||
  BNE \*b : Branch not equal
 | 
						||
  BGE \*b : Branch greater or equal
 | 
						||
  BGT \*b : Branch greater
 | 
						||
 | 
						||
  ZLT \*b : Branch less than zero (pop 1 word, branch negative)
 | 
						||
  ZLE \*b : Branch less or equal to zero
 | 
						||
  ZEQ \*b : Branch equal zero
 | 
						||
  ZNE \*b : Branch not zero
 | 
						||
  ZGE \*b : Branch greater or equal zero
 | 
						||
  ZGT \*b : Branch greater than zero
 | 
						||
 | 
						||
GROUP 14 - PROCEDURE CALL
 | 
						||
 | 
						||
  CAI \*- : Call procedure (procedure instance identifier on stack)
 | 
						||
  CAL \*p : Call procedure (with name \*p)
 | 
						||
  LFR \*s : Load function result
 | 
						||
  RET \*z : Return (function result consists of top \*z bytes)
 | 
						||
 | 
						||
GROUP 15 - MISCELLANEOUS
 | 
						||
 | 
						||
  ASP \*f : Adjust the stack pointer by \*f
 | 
						||
  ASS \*i : Adjust the stack pointer by \*i-byte integer
 | 
						||
  BLM \*z : Block move \*z bytes; first pop destination addr, then source addr
 | 
						||
  BLS \*i : Block move, size is in \*i-byte integer on top of stack
 | 
						||
  CSA \*i : Case jump; address of jump table at top of stack
 | 
						||
  CSB \*i : Table lookup jump; address of jump table at top of stack
 | 
						||
  DUP \*s : Duplicate top \*s bytes
 | 
						||
  DUS \*i : Duplicate top \*i bytes
 | 
						||
  FIL \*g : File name (external 4 := \*g)
 | 
						||
  LIM \*- : Load 16 bit ignore mask
 | 
						||
  LIN \*n : Line number (external 0 := \*n)
 | 
						||
  LNI \*- : Line number increment
 | 
						||
  LOR \*r : Load register (0=LB, 1=SP, 2=HP)
 | 
						||
  MON \*- : Monitor call
 | 
						||
  NOP \*- : No operation
 | 
						||
  RCK \*i : Range check; trap on error
 | 
						||
  RTT \*- : Return from trap
 | 
						||
  SIG \*- : Trap errors to proc nr on top of stack (-2 resets default).  Static
 | 
						||
          link of procedure is below procedure number. Old values returned
 | 
						||
  SIM \*- : Store 16 bit ignore mask
 | 
						||
  STR \*r : Store register (0=LB, 1=SP, 2=HP)
 | 
						||
  TRP \*- : Cause trap to occur (Error number on stack)
 | 
						||
.fi
 |