4 @Define(Ins,Break,Continue,Above 1,Below 1,Fill,LeftMargin +1.3 inches,
5 Spaces Compact,Indent 0,Spacing 1)
7 @string(ptgdno="SYS.18.01")
9 @document(A Machine-Independent MDL
11 @author(Marc S. Blank and Chris Reeve)
15 @pageheading<Left="PTDD",Center="@value<page>",Right="SYS.18.01">
17 @chapter<Global Design>
18 @section<The MIM Virtual Machine>
19 There are a number of possible approaches to re-implementing MDL on
20 various processors; the one chosen for this design is to create a
21 virtual machine running a language called MIM (Machine-Independent MDL).
22 The approach is analogous to that taken with Pascal in that MIM is either an
23 interpreted or compiled language, and interpreters or compilers must be
24 written for each target
25 machine. MIM code will be generated from MDL code by a process called
26 MIMC (the MIM compiler, pronounced mimsy), which will be written in MDL.
28 At the point that an Apollo-MIM (for example) and MIMC are operational, a
29 MDL interpreter written in MDL (called MUM) can be compiled into MIM.
30 MIMC, which will also be written in MDL, can also be compiled into MIM,
31 thereby providing both an MDL interpreter and compiler running on the
32 Apollo. It is also proposed that an order-code compiler for the various
33 target machines be written, to 'open-code' MIM into target machine
34 languages, with an increase in speed traded off for an increase in code
35 length. While MIMOC (MIM Order Compiler) may well become a necessity
36 for runtime systems, it need not become operational for writing,
37 running, and debugging MDL code.
39 A major difference between Pascal P-CODEs and MIM M-CODES is that the
40 latter are in themselves a high-level language, with machine
41 instructions which handle such things as RESTing structures, creating
42 structures, etc. Therefore, very little information of a
43 machine-dependent nature is stored in MIM machine code. By keeping MIM
44 relatively independent of target machine design, better target machine
45 code can eventually be produced by the MIMOC process.
47 @section<MIM Design Goals>
48 MIM (Machine-Independent MDL) is designed to enable the MDL language to
49 be rapidly implemented on a variety of machines. Although the language
50 specification is 'machine-independent', it is nonetheless designed with
51 8/16/32/36 bit processors in mind.
53 In the design of MIM, the goal has been to extract those features of
54 MDL which are 'primitive' and to make those 'primitives' machine instructions.
55 Thus, the MIM machine must understand the concept of an MDL object, MDL
56 structured primtypes, etc. However, it is clear that most of the MDL
57 SUBR/FSUBR's are composites of 'primitives' and that in fact few of
58 the MDL SUBR/FSUBR's need be implemented as machine instructions.
59 For example, MEMQ need not exist given NTH, REST, and ==?. More difficult
60 questions have involved such issues as whether READ can be written
61 efficiently in MDL given only READSTRING, and how much of the ATOM/OBLIST
62 system can be written in MDL.
64 @chapter<MIM Machine Structure>
66 @tabset<1.3 inches,2.5 inches>
67 @section<MIM Instruction Format>
68 Each MIM instructions takes a number of arguments and a destination designator
69 for the result if any.
71 The arguments to a MIM instruction can be either local variable names or
72 quoted MDL objects. The result of a MIM instruction can either be a local
73 variable or the atom STACK which directs the instruction to leave the
76 In describing the instruction set the following convention will
77 be used in denoting operands:
80 @i<operand-type:MDL-type-or-primtype>
82 where @i<operand-type> is one of local or any (meaning either a local or
84 @i<MDL-type-or-primtype> indicates the legal value(s) for that operand.
86 @section<MIM Predicates>
88 Some MIM instructions are predicates. These all have mnemonics which
89 end in a question mark (e.g. EQUAL?). These instructions are all
90 followed by a + or - to indicate whether the branch should be taken
91 if the predicate is true or false. After the + or -, the branch label
94 @section<MIM Internal Variables>
95 MIM has a few internal variables, which may be read and set. These variables
96 should not be confused with global or local variables in MDL. They are more
97 like MIM state variables.
100 MINF - a UVECTOR of information about the machine on which MIM is running
102 PAGETB - a UVECTOR of information about the address space available to MIM
104 BIND - the most recent binding on the STACK
106 FRAME - the current FRAME
108 ARGS - the number of arguments to the current FRAME
110 OBLIST- the global atom-table
112 ICALL - the @b(MSUBR) to CALL when an interrupt occurs
114 ECALL - the @b(MSUBR) to CALL when an error in order-code occurs
116 NCALL - the @b(MSUBR) to CALL when a non-globally-assigned @b(ATOM) or
117 an @b(ATOM) whose global value is not an @b(MSUBR) is CALLed
120 The last three internal variables are intended to be set once during
121 initialization of the MDL interpreter. Extreme caution should be used
122 when setting the BIND, ARGS, FRAME, and OBLIST variables, as these
123 are used internally for @b(MSUBR) CALLing, etc.
125 @section<MIM Objects>
126 A MIM object is a 64-bit or 72-bit structure which is roughly equivalent to
127 the PDP-10 MDL type/value pair. A MIM object contains the following
130 Type Word - 16 or 18 bits specifying the type and primtype of the object. See
131 @i<TYPE-WORD Format>.
133 Length Word - 16 or 18 bits. See @i<LENGTH-WORD Description>
135 Value - 32 or 36 bits, a pointer for structures or a value for non-structures.
138 @section<MIM Subroutines>
140 The unit of executable MIM code is the @b(MSUBR) (@b(M)dl
141 @b(SUBR)outine). This has a format as diagrammed in @i<MSUBR Format>.
142 Briefly, an @b(MSUBR) is a primtype @b(VECTOR) which contains a pointer to
143 an @b(IMSUBR) which is a primtype @b(VECTOR) and contains a pointer to
144 runnable MIM instructions (a primtype @b(UVECTOR) of type @t(MCODE)), as
145 well as other MDL objects used by the @b(MSUBR). By convention, the second
146 element of the MSUBR is its name (an @b(ATOM)), the third is the
147 type declaration for the MSUBR (a @b(LIST)) and the fourth is the offset
148 into the MCODE where the code for this MSUBR starts. When an MSUBR wants to
149 reference an MIM object, it refers to an offset in the IMSUBR. The CALL
150 instruction makes the MIM program counter point to the appropriate element of
151 the @b(MCODE) for the called @b(MSUBR).
155 MIM has a stack (referred to as the STACK) which is used for MSUBR
156 calling, bindings, local variables, temporaries, etc. All items on the
157 STACK are either legal MIM objects (i.e. 64-bit structures) or
158 structures placed there by MIM instructions (e.g. FRAME, BIND).
160 @chapter<MIM Instruction Overview>
162 @section<Stack & Variable Operations>
164 MIM has instructions for placing objects on the STACK (PUSH) and for
165 removing objects from the top of the STACK (POP). In addition, the
166 instruction ADJ adjusts the STACK pointer either forward or backward by
167 a given number of MIM objects.
169 MIM local variables (located on the STACK) can be set with the various
170 SET instructions to either the value of another local variable, a slot
171 in the @b(IMSUBR) or a constant.
173 @section<MSUBR Calling>
175 In order to transfer control from one @b(MSUBR) to another, a STACK @b(FRAME)
176 must be created. This is done using the FRAME instruction. Such a
177 @b(FRAME) will contain enough inforiadio, to$anlow Dr
\bMCUBTh
\0Bet5xls,
\ 5\bmulpip|d`6etur.1, !nd`MDL)style AGAIN." NL
\ 3e the
\0@v F
\12AOE is btHnT, the
\r\bargumenlc un dhe @b(M
\13FBR)(HiF@aFy avE
\10USId$ Knto thE QTACJ. `TIenL
178 tam
\ 3A
\rL ivsTruwty
\7fn is!ayEcetem.
\0\r\ e
179 Hgse
\0kc an`a{`)
\12mT(mf`tie0usg (iF`II
\f awSmlbmq Da~gqege novatinli
\0on 5(D
\r\bcAM
\f instbugtinn:
\r\ 6@bggin<vewBc4km>
180 \v\r\ e <FRAMA> ('` `( 0 $` ; cre`tm
\0` ctack Dramm
181 ` ` <P
\15SH NOO> "
\0 \0 \0 \0 \00 !
\1f(push!th
\ 4 hocil v`riablM DO
\a\r\b @` H<PQ B
\r\18pQQ
\11\a\ 1l gF'o|OOOO
\ f\ eWOMKOGOM@_
\ 6\ 2\ 5\ 3_
\ 3\ 1\18\ f\ 1\10\1c\16\ 1O
\0*
\ 4\ 2\ 6\ e\ 1(
\ f\1c^
\ 4p0O
\ fOGOOOKA
\a\b\ 4\17_O_F
\a@OOOOoOOOI_O_OoaO
\ fNI=G
\ 5\18\ 3P9:ysezE
\ 6\17\ 6\ 4BB
\ 4F
\0\0cgw{x'/sg'ea_r
\1e\ 2\18Sfd
\ fd
\ 3\1c v
\1842@`>
\0)
\0\0\10\ 2&
\0\0(
\ 26
\0\0 \ 25
\0\0\18\ 24
\0\0\10\ 23
\0\0\10\ 38
\0\0(
\ 4{
\0\0 \ 4z
\0\0\10\ 5)
\0\00
\bD
\0\0(
\bC
\0\0 \bB
\0\0\18 \ 2\0\0\10 \ 1\0\0\b\f\ 1\0\0\10\f\1c\0\0\18\fx
\0\0\b\10:
\0\0(
\11t
\0\0 \11s
\0\0\18\11r
\f%
\14A
\ 4\0\0\b\0\ 1\f(
\1c?
\e\0\0\b\ 1f
\fA
\13G
\0\0\0\b\ 2$
\fD
\f[@
\0\0 \ 2-
\r5
\1a\0\e\0\0\b\ 36
\r5
\19\7fd
\0\0\10\ 4u
\f\C`X
\0\0\b\ 5'
\v\ 3.LG
\0\0\10\a\f\f\CO4
\0\0\18\b=
\f\D
\1aw
\0\0\b\bu
\r\ e\13(X
\0\0\10\b|
182 \|Pd
\0\0\b\vU
\r4zc
\0\0\b\f\0\r\ e\13m:
\0\0\b\f\1a\rOi<
\14\0\0\b\fl
185 8
\18 ^
\0\0\b\r\
\v\12KyP
\0\0\18\ eM
189 \7f\ 2+
\ 6\0\0\10\ fM
\f\fQ7P
\0\0\b\ f_
\v\14D^
\ e\0\0\b\10\b\v\14D^
\b\0\0\b\10+
\v\14D^
\ e\0\0\b\109
190 \7f\12`;
\0\0\b\11\b\rY]c"
\0\0\10\11\17\f\D%:
\0\0\b\11$
\v>/g0
\0\0\b\11.
\v\12KyP
\0\0\b\114
\rT
\ e\190
\0\0\b\11C
\f(I
\17\1f\0\0\b\11Q
191 |T
\15\ 2\0\0\18\11m
\f"QO
\ 1\0\0\b\12\19\0\ 18
\0$
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0rnal representation of the various structure classes.
193 @section<MIM Support for ATOMs and Bindings>
195 MIM supports the concepts of @b(ATOM)s and bindings. This is necessary
196 in that a completely external simulation of atomic bindings would be
197 unreasonably expensive without some knowledge in the interpreter of
200 A STACK binding (type LBIND) is created with the BIND instruction.
201 BIND does the following:
203 Creates an LBIND and places it on the STACK
205 Points this new LBIND to the previous LBIND on the STACK
207 Updates the internal pointer to the most recent LBIND to be the one just
211 Code inside MUM does the remainder of the binding process, including
212 pointing the LBIND at the ATOM which is being bound and placing values
213 and declarations in the LBIND. Additionally, an LBIND for a given ATOM
214 is pointed to the previous LBIND for that ATOM. A number of MIM
215 instructions perform 'unbinding' of @b(ATOM)s (e.g. RETURN, RTUPLE, and
216 AGAIN) back to a given FRAME.
217 The steps in 'unbinding' are:
219 Remove the LBIND from the STACK
221 Update the internal pointer to the most recent LBIND to be the previous
222 LBIND (as saved by the BIND instruction)
224 Update the LBIND slot of the ATOM pointed to by the LBIND to be the
225 previous LBIND (if any) for that ATOM.
228 @section<MIM Garbage Collector>
230 It is intended that MDL have two garbage collectors, a mark-sweep
231 garbage collector, and a full-copy garbage collector. MIM instructions
232 for both are included in this document.
234 @section<MIM Bootstrap Routine>
236 In order for any @b(MSUBR) to run, it is necessary for MIM to have
237 'read' that @b(MSUBR). Therefore, MIM must include a primitive MDL
238 reader, which must be capable of parsing the following MDL data types:
239 @b(IMSUBR), @b(MSUBR), @b(MCODE), @b(ATOM), @b(FIX), @b(FLOAT), @b(STRING),
240 @b(VECTOR), @b(LIST), and @b(CHARACTER). By convention, the file
241 BOOT.MSUBR contains the bootstrap routines for loading a MDL. The BOOT
242 file is a sequence of @b(MSUBR)s. MIM must read these @b(MSUBR)s and
243 SETG the names of the @b(MSUBR)s accordingly (by convention, the name
244 of an @b(MSUBR) is the second element of the @b(MSUBR)). Execution
245 commences with MIM CALLing the @b(MSUBR) named BOOT.
247 @chapter<The MDL Interpreter Written in MDL - MUM>
250 @b(MUM) (@b(M)DL @b(U)nder @b(M)DL) is the name given to the MDL
251 interpreter which is written in MDL. In most respects, MUM/MDL will be
252 identical to the current PDP-10 and TOPS-20 MDLs. @b(MUM) will,
253 however, include some capabilities not found in the older MDLs.
255 @section<Modularity of the MDL Interpreter>
257 The new MDL interpreter (@b(MUM)) is composed of individual speCialty
258 modules (e.g. PRINT, READ, ASOC, ARITH). Each od these modules consists
259 of`@b(MSUBB)s, as wnulD any other piece of
\ fuser-code'. The result is
260 that the`distinction`between interpreter And 'user-code' `as become
261 blurrmd. To tie casual MDL user, thE interpreter will probably appear
\1d
262 lareer than $ib-YB
\16\r10 version, because some parts of the MDL
263 environment will be included. However, to the production-systems
264 prWS^itSK` wsY^ eaS`t I_BexG
\19ldeQC
\18y
\0_lFalh
\ 1Zf QJ MY
\18\1a
265 imiHrpEKlerA]bomAEHinNAXoaYKJ, YK@vimNBa G[@llKdFanHABlec]Nr Wsbte:\
\1e\1a\re
\ 1fec S^n>
\13)
\18M S[dlekK^ta
\19SZn>J
\14\1a
266 @
\14Q
\ 6TOjS` aeJFstekFtuEKd w\AbriKitpe
\ 1\ 1\ 6\bRZ
\a\1eRDRAlit`AJouDALlmsKZdsTAF
267 I
\1fFalQAVnd
\ 3]H (
\11DPLBS
\1c
268 ))
\18AD gI
\7fBalQEVnd
\ 3]H (
\11DPGBS
\1d
269 ))PAB p
\1dCXe
\r$Q
\ 4b
\b\a)"INNRP,!S]H a
\1cA
\0b(/
\ 5\1cISXVX ECi
\14erQ_H taJ@fiegh!t
\ f^Belc[Nnt
\16ABanZ
\15DlsN
\ 1@e
\ 2A
\0b(]
\ 3\18\13EBXFinYSGctS]H tQCh!tQK`e!CfFnoQY\ca
\bA^r
\1fY\baX
\1a\12bi]IPNg\
\0D@b!
\1f\ 2LIW Ts aCje IQR scSJ siejctkeH a
\ 6C
\ 6b(c)
\18M)V\B L_iH t
\ 1Ch
270 \11DRATO
\1aQs G]N @
\14Q
\18BLC',)sQCde ]_bmAHA
\18IMAgjruginreFAhhiWPDca
\1cABE
\re[PniAkXatKHDasQC`e OiPerAgjrugihreV\F TQSf
\0aIYXws
\11CXl
\e \1f!"
\0oo
\7f@
\7f\7f\7f\7f\7f support for
271 @b(AT_M)s and @b(OBLIST)c to Be wsitteN in MDL itself whth calls to NTH,
274 The BIND instruction creates and returns an @b(LBIND) ol the STACK.
275 There is no need for a GBIND instruction, as a @b(GBIND) can be created
276 with the RECORD instruction. As with @b(ATOM)s, @b(LBIND)s and
277 @b(
\aBIND)s are primtype @b(RECORD)s which can be manipulated; thus, the
278 SUBR's SET and SETG turn into PUTs, as
\0doH
\0\15@
\rDECL, and GDECL.
280 @section<Arithmetic and Bktwise Operations>
282 @b(FIX) is the only non-structured MIM primtype,!replacing the primtype WORD
283 in the current MDL. All bitwise operations take any primtype @b(FIX) and
284 return a type @b(FIX). The aritHmetic iNstructions take either pairs of
285 @b(FIX)es or @b(FLOAT)s and return objects of the same type.
289 MIM provides a very primitive I/O interface, which consists of OPEN,
290 CLOSE, and ctring read/print. The MDL conversion I/O SUBRs (READ,
291 READCHR, PRILT, PRIN1, PRINC, PARSE, and UNPAR
\13E) have all been written
292 uskng only these operapions. Block-iode I/O SUBRs (PRINTB( READB,
293 PRINTSTRING, READSTRING) can also be!easily incorporated hnto this scheme.
295 While these SUBRs cover mcNy MDL I/O applIcations, snme others will nEed
296 tn be
\0levised. Akong these is some form of core-image I/O, which
297 would provide fast, non-parsed I/O, and some machine-independent MDL I/O
298 scheme, which is being devised by an undergraduate at the present time.
300 The SAVE and RESTORE instructions provide the means for saving and
301 restoring a core-image, and is used mostly in the creation of large
304 @section<Associations>
306 There is no support in MIM for associative storage as implemented
307 in the existing MDL. However, such a scheme has been implemented
312 There is no coroutine/multiprocess facility in MIM. The major issue
313 that coroutines encounter is that of the STACK, whether there should
314 be one for each coroutine, etc. The possible inclusion of this
315 concept into the design of MIM will be considered at a later date.
317 @section<Interrupt Handling>
319 MIM has a very primitive interrupt system which interacts with a rather
320 sophisticated software interrupt system written in MDL, and based on the
321 old MDL's interrupt system. When a non-emergent interrupt is received by
322 MIM, MIM CALLs the @b(MSUBR) specified by the SETS ICALL instruction
323 with one argument, a @b(FIX) between 0 and 35, which is the unique
324 identifier of that class of interrupt.
326 To allow for terminal interrupts, the MIM instruction ATIC (Activate
327 Terminal Interrupt Character) takes a @b(CHARACTER) and returns a
328 @b(FIX) which is the unique identifier for a terminal interrupt on that
331 Emergency interrupts (stack overflow, illegal memory read/write) may
332 require MIM to take some emergency action prior to CALLing the software
333 interrupt system. Naturally, these interrupts are somewhat
334 machine-dependent, and will have to be dealt with for each target machine.
336 @chapter<MIM Instruction Set>
337 @section<Stack Operations & Flow of Control>
339 @b<PUSH>@\@i<any:any>
341 The PUSH instruction @i<pushs> its operand onto STACK. The special destination
342 STACK for other instructions is another of placing objects on the stack.
347 The POP instruction @i<pop>s the top element from the STACK
348 and moves it into a local variable. Calling an MSUBR also removes the
349 arguments from the stack.
353 @b<SET>@\@i<local:any>,@i<any:any>
355 The various SET instructions set a local variable to the value of
356 another local variable or a constant.
357 The use of local variable as destination also causes a SET of that variable
361 @b<SETLR>@\@i<local:any1>,@i<local:frame>,@i<local:any2>
363 Sets local variable @i(any1) in the current frame to the value of
364 local variable @i(any2) in @i(frame).
367 @b<SETRL>@\@i<local:frame>,@i<local:any1>,@i<local:any2>
369 Sets local variable @i(any1) in @i(frame) to the value of local variable
370 @i(any2) in the current frame.
375 Adjusts the STACK by @i<fix> objects, positive indicating @i<push>ing
376 and negative indicating @i<pop>ping.
379 @b<FRAME>@\@i<no operands>
381 Creates a CALL @i<frame> on the STACK.
384 @b<CFRAME>@\@i<no operands>
386 Returns the running @i<frame>.
389 @b<ARGS>@\@i<any:frame>
391 Returns a TUPLE with the arguments to the @i<frame>.
394 @b<TUPLE>@\@i<any:fix>
396 Returns a TUPLE containing @i<fix> elements from the top of the STACK.
399 @b<RFRAME>@\@i<any:frame>
401 The return instruction which follows will cause values to be
402 returned to @i<frame>. Unbinding will occur back to @i<frame>.
405 @b<CALL>@\@i<any:atom>,@i<local:fix>
407 Starts execution of an MSUBR. This instruction must follow the
408 creation of a FRAME and the PUSHing of arguments. If the global
409 value of @i(atom) is an MSUBR, execution starts immediately. Otherwise,
410 the NCALL routine is executed.
413 @b<INCALL>@\@i<local:any>
415 Builds a FRAME and performs a 'CALL' within the current MSUBR. This is
416 useful for PROGs and REPEATs that have external ACTIVATIONS that maybe
417 RETURNed from or AGAINed.
420 @b<MAKTUP>@\@i<local:any1>,@i<local:any2>...@i<local:anyn>
422 Builds and returns a TUPLE out of the arguments passed to an MSUBR. The
423 arguments are the temporaries used in the MSUBR.
426 @b<ACTIVATION>@\@i<no operands>
428 Saves the current offset into the MSUBR as the 'activation' for the
432 @b<AGAIN>@\@i<local:frame>
434 AGAIN restarts execution of the MSUBR running in @i<frame> from
435 the offset specified within that MSUBR by a call to ACTIVATION.
436 Unbinding will occur back to @i<frame>.
439 @b<RETURN>@\@i<local:any>,@<local:frame>
441 Performs a CALL return with value as specified by the operand .
442 The second argument is optional and defaults to the current frame.
443 Unbinding for will occur.
446 @b<RTUPLE>@\@i<local:fix>
448 Performs a CALL return with any number of values, which have been
449 PUSHed onto the STACK, and whose number is specified by @i<fix>,
450 returning as the top of STACK a @i<tuple> pointing to the return values.
455 Unconditional branch to label. JUMPs may only be used
456 locally (i.e. within an @i<msubr>).
461 @section<GC Interface>
463 @b<MARKL>@\@i<local:list>,@i<local:fix>
464 @b<MARKU(U/V/S)>@\@i<local:ublock>,@i<local:fix>
465 @b<MARKR>@\@i<local:record>,@i<local:fix>
467 Marks a structure, setting to mark bit to @i(fix), which should be
468 either zero, one, or a "new address" for copy GC. MARKL marks just one
469 element of the @i(list).
472 @b<MARKL?>@\@i<local:list>,@i<constant:fix>
473 @b<MARKU(U/V/S)?>@\@i<local:ublock>,@i<constant:fix>
474 @b<MARKR?>@\@i<local:record>,@i<constant:fix>
476 Predicate, testing the marked state of a structure. Unlike normal predicates,
477 these return either a fix or false. The second argument is optional, its
478 existance indicates a relocation should be returned for marked objects.
481 @b<SWNEXT>@\@i<local:any>
483 Performs the sweep phase of the garbage collector.
485 @b<NEXTS>@\@i<local:fix>
487 Gets and returns a fix that can be used with CONTENTS to get the next item
488 on the stack. For marking the stack.
490 @b<CONTENTS>@\@i<local:fix>
492 Returns the next stack item. The argument should be one received from NEXTS.
494 @b<PUTS>@\@i<local:fix>,@i<local:any>
496 The opposite of CONTENTS, PUTS stores back into the stack.
498 @b<ALLOCL>@\@i<local:fix>,@i<local:any>
499 @b<ALLOCU(U/V/S)>@\@i<local:fix>,@i<local:any>
500 @b<ALLOCR>@\@i<local:fix>,@i<local:any>
502 Allocates room for the object specified by the second argument at the address
503 specified by the first.
505 @b<BLT>@\@i<local:fix>,@i<local:fix>,@i<local:fix>
507 Moves an object from the location specified by the first argument to the
508 location specified by the second argument. The third argument is the length
509 in words (32 or 36 bit words). This length should include the dopewords.
511 @b<RELL>@\@i<local:list>
512 @b<RELU(U/V/S)>@\@i<local:ublock>
513 @b<RELR>@\@i<local:record>
515 These instructions recycle the appropriate objects.
523 @b<HALT>@\@i<no operands>
528 @b<OBJECT>@\@i<local:fix>,@i<local:fix>,@i<local:fix>
530 Returns a MIM object, whose type, length, and value words are the three
531 operands, respectively.
534 @b<GETS>@\@i<byte:fix>
536 Returns the value for the internal variable indicated by @i(fix).
539 @b<SETS>@\@i<byte:fix>,@i<local:any>
541 Sets the value of the internal variable indicated by @i(fix) to @i(any).
549 @section<Type Manipulation>
551 @b<TYPE>@\@i<local:any>
553 Returns the TYPE of @i<any>, as a @i<fix>.
556 @b<TYPE?>@\@i<local:any>,@i<local:fix>
557 @b<TYPEW?>@\@i<local:any>,<word>
559 Predicate on TYPE of @i<any> being @i<fix>
562 @b<CHTYPE>@\@i<local:any>,@i<local:fix>
564 Returns @i<any>, with its TYPE changed to @i<fix>.
567 @b<NEWTYPE>@\@i<local:fix>
569 Returns a @i<fix>, a new TYPE whose primtype is the primtype of @i<fix>.
572 @b<VALUE>@\@i<local:any>
574 Returns the 'value' 32 bits of @i<any>, as a @i<fix>. This is
575 a utility instruction.
580 @section<Structure Creation>
582 @b<LIST>@\@i<local:fix>
585 LIST creates and returns a LIST containing @i<fix> elements which
586 are on the top of the STACK.
589 @b<UBLOCK>@\@i<local:fix,local:fix,local:fix>
590 @b<UBLOCKB>@\@i<local:fix,local:fix,byte>
592 UBLOCK creates and returns a UBLOCK of the specified type (@i<fix1>),
593 with @i<fix2> elements from the top of the STACK.
596 @b<RECORD>@\@i<local:fix,local:fix>
597 @b<RECORDB>@\@i<local:fix,byte>
599 RECORD creates and returns a RECORD of the specified type (@i<fix1>),
600 with @i<fix2> elements from the top of the STACK.
605 @section<Structure Manipulation>
607 @b<NTHL>@\@i<local:list>,@i<local:fix>
608 @b<NTHLB>@\@i<local:list>,@i<byte>
610 @b<NTHR>@\@i<local:record>,@i<local:fix>
611 @b<NTHRB>@\@i<local:record>,@i<byte>
613 @b<NTHU>@\@i<local:ublock>,@i<local:fix>,@i<local:any>
614 @b<NTHUB>@\@i<local:ublock>,@i<byte>,@i<local:any>
616 Returns the @i<fix>th element of @i<structure>.
619 @b<LENL>@\@i<local:list>
620 @b<LENR>@\@i<local:record>
621 @b<LENU>@\@i<local:ublock>
623 Returns the length of @i<structure>, as a @i<fix>.
626 @b<EMPL?>@\@i<local:list>
627 @b<EMPR?>@\@i<local:record>
628 @b<EMPV?>@\@i<local:ublock>
630 Predicate on emptiness of @i<structure>.
633 @b<PUTL>@\@i<local:list>,@i<local:fix>,@i<local:any>
634 @b<PUTLB>@\@i<local:list>,@i<byte>,@i<local:any>
636 @b<PUTR>@\@i<local:record>,@i<local:fix>,@i<local:any>
637 @b<PUTRB>@\@i<local:record>,@i<byte>,@i<local:any>
639 @b<PUTU>@\@i<local:ublock>,@i<local:fix>,@i<local:any>
640 @b<PUTUB>@\@i<local:ublock>,@i<byte>,@i<local:any>
642 Makes @i<any> the @i<fix>th element of @i<structure>.
646 @b<RESTL>@\@i<local:list>,@i<local:fix>
647 @b<RESTLB>@\@i<local:list>,@i<byte>
649 @b<RESTU>@\@i<local:ublock>,@i<local:fix>,@i<local:any>
650 @b<RESTUB>@\@i<local:ublock>,@i<byte>,@i<local:any>
652 Rests @i<structure> by @i<fix> elements.
656 @b<BACKU>@\@i<local:ublock>,@i<local:fix>
657 @b<BACKUB>@\@i<local:ublock>,@i<byte>
659 Returns @i<ublock> with @i<fix> previously RESTUed elements
663 @b<TOPU>@\@i<local:ublock>
665 Returns @i<ublock> with all previously RESTUed elements restored.
668 @b<CONS>@\@i<local:any>,@i<local:list>
670 Returns a @i<list>, with @i<any> consed onto @i<primtype list>.
673 @b<PUTREST>@\@i<local:list1>,@i<local:list2>
675 Returns @i<list1>, after making REST of it be @i<list2>.
680 @section<ATOM-Related Operations>
682 @b<BIND>@\@i<no operand>
684 Creates and returns a BINDING on the STACK.
687 @b<UNBIND>@\@i<local:lbind>
689 Unbinds STACK bindings until the top binding is @i(lbind).
692 @b<FIXBIND>@\@i<no operands>
694 Ensures that each @t(ATOM) pointed to by a STACK binding points
695 back at that binding.
698 @b<SETG>@\@i<local:atom>,@i<local:any>
700 Assumes that a global binding exists for @i(atom): stuffs @i(any) into
701 that global binding's value slot.
704 @b<GVAL>@\@i<local:atom>
706 Assumes that a global binding exists for @i(atom): returns that global
707 binding's value slot.
713 @section<Input/Output>
716 @b<OPEN>@\@i<local:fix1>,@i<local:fix2>,@i<local:string>
718 Opens a 'channel' to a file specified by @i(string). Note
719 that the format of @i<string> is completely machine-dependent.
720 The direction of the 'channel' is specified by @i(fix1): 1 is 'print',
721 0 is 'read'. The byte-size of the 'channel' is specified by @i(fix2):
722 usually this will be for character I/O (7 or 8) or word I/O (32 or 36).
723 The byte-size will be used by the READ and PRINT instructions in
724 determining the unit of I/O.
726 Returns a @i<fix>, a unique 'channel' designator, or a @i<false>
727 containing an error code (a @i(fix)).
730 @b<CLOSE>@\@i<local:fix>
732 Closes the 'channel' associated with @i<fix>, a 'channel' designator.
735 @b<READ>@\@i<local:fix1>,@i<local:string>,@i<local:fix2>
737 Reads @i(fix2) items from 'channel' with identifier @i(fix1) into
741 @b<PRINT>@\@i<local:fix1>,@i<local:string>,@i<local:fix2>
743 Prints @i(fix2) items to 'channel' with identifier @i(fix1) from
747 @b<SAVE>@\@i<local:fix>
749 Saves the state of MDL on 'channel' @i<fix>.
752 @b<RESTORE>@\@i<local:fix>
754 Restores the state of MDL from 'channel' @i<fix>.
760 The following arithmetic instructions return the result of the
761 appropriate operation.
764 @b<ADD>@\@i<local:fix>,@i<local:fix>
765 @b<ADDB>@\@i<local:fix>,@i<byte>
766 @b<ADDF>@\@i<local:float>,@i<local:float>
768 @b<SUB>@\@i<local:fix>,@i<local:fix>
769 @b<SUBB>@\@i<local:fix>,@i<byte>
770 @b<SUBF>@\@i<local:float>,@i<local:float>
772 @b<MUL>@\@i<local:fix>,@i<local:fix>
773 @b<MULB>@\@i<local:fix>,@i<byte>
774 @b<MULF>@\@i<local:float>,@i<local:float>
776 @b<DIV>@\@i<local:fix>,@i<local:fix>
777 @b<DIVB>@\@i<local:fix>,@i<byte>
778 @b<DIVF>@\@i<local:float>,@i<local:float>
781 @b<RANDOM>@\@i<local:fix>
783 Selects a RANDOM number between one and @i<fix>, inclusive.
787 @b<FIX>@\@i<local:float>
789 Turns @i<float> into a @i<fix>.
792 @b<FLOAT>@\@i<local:fix>
794 Turns @i<fix> into a @i<float>.
798 The following are arithmetic conditional branch instructions.
801 @b<GRTR?>@\@i<local:fix>,@i<local:fix>
802 @b<GRTRB?>@\@i<local:fix>,@i<byte>
804 @b<LESS?>@\@i<local:fix>,@i<local:fix>
805 @b<LESSB?>@\@i<local:fix>,<byte>
809 @section<Bitwise Operations>
810 All of the following instructions take two operands of primtype @i<fix>
811 and return a type @i<fix>.
814 @b<AND>@\@i<local:fix>,@i<local:fix>
816 @b<IOR>@\@i<local:fix>,@i<local:fix>
818 @b<XOR>@\@i<local:fix>,@i<local:fix>
820 @b<EQV>@\@i<local:fix>,@i<local:fix>
822 @b<LSH>@\@i<local:fix>,@i<local:fix>
824 @b<ROT>@\@i<local:fix>,@i<local:fix>
828 @section<General Predicates>
830 @b<EQUAL?>@\@i<local:any>,@i<local:any>
832 Conditional branch on equality of operands (i.e. ==? in the MDL sense).
835 @b<VEQUAL?>@\@i<local:any>,@i<local:any>
836 @b<VEQB?>@\@i<local:any>,@i<byte>
838 Conditional branch on equality of 'value' words of operands only.
842 @appendix<Sample MIM Assembly Code>
844 The following examples give representitive MDL code with the
845 corresponding MIM code, in assembly format. Those familiar with the
846 PDP-10 MDL assembler format will be comfortable reading it. Basically,
847 each instruction is a @b(FORM), whose first element is an operation code
848 mnemonic, and whose remaining elements up to but not including the
849 special characters -, +, and = are operand descriptors. Local operands
850 are denoted by 'names' (i.e. @b(ATOM)s). @b(MSUBR) operands can be any legal
851 MDL object (including @b(ATOMs), and are specified as the MDL object itself
852 (except for @b(ATOM)s, which are specified as '<name>). Predicate
853 instructions are followed by a word which describes a pc-relative jump
854 if the instruction succeeds or fails. A + precedes a label to jump to
855 if a predicate condition succeeds; a - precedes a label to jump to if
856 the condition fails. Instructions which return a value are followed by
857 a byte which describes the local variable in which to store the return
858 value. This is described by the syntax = 'name' where 'name', as
859 before, is an @b(ATOM). If an operation which returns a value does not have
860 an = 'name' or is the @b(ATOM) STACK, the value will be pushed on the
863 The pseudo-op FCN defines an @b(MSUBR), and is followed by the name of
864 the @b(MSUBR), its argument declaration (a @b(LIST)) and names of it's
865 arguments. The pseudo-op TEMP allocates temporary variables on the STACK.
867 Please note that the distinction between such operations as CALL and
868 CALLB is not made in assembly syntax. The assember will generate the
869 correct instruction. Similarly, all STACK-type operations will be
870 listed in their generic form (e.g. PUSH, SET). This is for clarity
875 @appendixsection<Simple MAPF>
881 <MAPF ,LIST ,BAR .L>>
885 <FCN FOO ("VALUE" LIST LIST) L>
897 If the argument to the function FOO were not DECLed, i.e. could
898 be either a primtype LIST, RECORD, or UBLOCK, the following
901 <FCN FOO ("VALUE" LIST STRUCTURED) X>
902 <TEMP TMP0 TMP1 TMP2>
905 <CALL 'EMPTY? 1 = TMP2>
906 <TYPE? TMP2 <TYPE-WORD FALSE> + END>
920 <CALL 'EMPTY? 1 = TMP2>
921 <TYPE? TMP2 <TYPE-WORD FALSE> - LOOP>
925 @appendixsection<Recursive Factorial Function>
932 <* .N <FACT <- .N 1>>>)>>
936 <FCN FACT ("VALUE" FIX FIX) N>
941 <CALL 'FACT 1 = TMP1>