1122 lines
		
	
	
	
		
			37 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			1122 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.
 | ||
| This instruction is obsolete. Its use is strongly discouraged.
 | ||
| .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
 |