1123 lines
37 KiB
Plaintext
1123 lines
37 KiB
Plaintext
.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
|