3 @use (database "/usr/lisp/scribe/database/")
4 @libraryfile [Mathematics10]
5 @libraryfile [ArpaCredit]
8 @style(FontFamily=TimesRoman)
9 @style(Date="March 1952")
11 @commandstring(pusharrow = "@jsym<L>")
12 @define(f, facecode f)
14 @commandstring(InstrSection = "@tabclear@tabset[.5 in, 3.0 in]")
15 @form(Instr = "@*@\@Parm[name]@\")
16 @form(BInstr ="@*@\@Parm[name]@+[*]@\")
17 @string(DinkyMachine = "IBM RT PC")
21 @heading[Internal Design of CMU Common Lisp
36 CMU Common Lisp is an implementation of Common Lisp that currently runs on
37 the IBM RT PC under Mach, a Berkeley Unix 4.3 binary compatible operating
38 system. This document describes low level
39 details of the implementation. In particular, it describes the data
40 formats used for all Lisp objects, the assembler language routines
41 (miscops) used to support compiled code, the function call and return
42 mechanism, and other design information necessary to understand the
43 underlying structure of the CMU Common Lisp implementation on the IBM RT PC
44 under the Mach operating system.
47 @begin[ResearchCredit]
48 @ArpaCredit[Contract=Strategic87-90]
52 @heading [Acknowledgments]
54 This document is based heavily on the document @i[Revised Internal Design
55 of Spice Lisp] by Skef Wholey, Scott Fahlman, and Joseph Ginder.
57 The FASL file format was designed by Guy L. Steele Jr. and Walter van
58 Roggen, and the appendix on this subject is their document with very few
61 @chapter [Introduction]
63 @section [Scope and Purpose]
65 This document describes a new implementation of CMU Common Lisp (nee Spice
66 Lisp) as it is implemented on the @value(DinkyMachine) running Mach, a
67 Berkeley Unix 4.3 binary compatible operating system. This design is
68 undergoing rapid change, and for the present is not guaranteed to
69 accurately describe any past, present, or future implementation of CMU
70 Common Lisp. All questions and comments on this material should be
71 directed to David B. McDonald (David.McDonald@@CS.CMU.EDU).
73 This document specifies the hand-coded assembler routines (miscops) and
74 virtual memory architecture of the @value(DinkyMachine) CMU Common Lisp system.
75 This is a working document, and it will change frequently as the system is
76 developed and maintained. If some detail of the system does not agree with
77 what is specified here, it is to be considered a bug.
79 @section [Notational Conventions]
80 @index [Bit numbering]
81 @index [Byte numbering]
82 CMU Common Lisp objects are 32 bits long. The high-order bit of each word is
83 numbered 0; the low-order bit is numbered 31. If a word is broken into smaller
84 units, these are packed into the word from left to right. For example, if we
85 break a word into bytes, byte 0 would occupy bits 0-7, byte 1 would occupy
86 8-15, byte 2 would occupy 16-23, and byte 3 would occupy 24-31.
88 All CMU Common Lisp documentation uses decimal as the default radix; other
89 radices will be indicated by a subscript (as in 77@-[8]) or by a clear
90 statement of what radix is in use.
92 @chapter [Data Types and Object Formats]
94 @section [Lisp Objects]
97 Lisp objects are 32 bits long. They come in 32 basic types, divided into three
98 classes: immediate data types, pointer types, and forwarding pointer types.
99 The storage formats are as follows:
101 @index [Immediate object format]
102 @index [Pointer object format]
103 @begin [verbatim, group]
105 @b[Immediate Data Types:]
107 ------------------------------------------------------------------------
108 | Type Code (5) | Immediate Data (27) |
109 ------------------------------------------------------------------------
111 @b[Pointer and Forwarding Types:]
113 ------------------------------------------------------------------------
114 | Type Code (5) | Space Code (2) | Pointer (23) | Unused (2) |
115 ------------------------------------------------------------------------
118 @section [Table of Type Codes]
121 @begin [verbatim, group]
123 Code Type Class Explanation
124 ---- ---- ----- -----------
125 0 + Fixnum Immediate Positive fixnum, miscop code, etc.
126 1 GC-Forward Pointer GC forward pointer, used during GC.
127 4 Bignum Pointer Bignum.
128 5 Ratio Pointer Two words: numerator, denominator.
129 6 + Short Float Immediate Positive short flonum.
130 7 - Short Float Immediate Negative short flonum.
131 8 Single Float Pointer Single precision float.
132 9 Double Float Pointer Double precision float (?).
133 9 Long Float Pointer Long float.
134 10 Complex Pointer Two words: real, imaginary parts.
135 11 String Pointer Character string.
136 12 Bit-Vector Pointer Vector of bits
137 13 Integer-Vector Pointer Vector of integers
138 14 General-Vector Pointer Vector of Lisp objects.
139 15 Array Pointer Array header.
140 16 Function Pointer Compiled function header.
141 17 Symbol Pointer Symbol.
142 18 List Pointer Cons cell.
143 20 C. S. Pointer Pointer Pointer into control stack.
144 21 B. S. Pointer Pointer Pointer into binding stack.
145 26 Interruptible Immediate Marks a miscop as interruptible.
146 27 Character Immediate Character object.
147 28 Values-Marker Immediate Multiple values marker.
148 29 Catch-All Immediate Catch-All object.
149 30 Trap Immediate Illegal object trap.
150 31 - Fixnum Immediate Negative fixnum.
153 @section [Table of Space Codes]
156 @begin [verbatim, group]
158 Code Space Explanation
159 ---- ----- -----------
160 0 Dynamic-0 Storage normally garbage collected, space 0.
161 1 Dynamic-1 Storage normally garbage collected, space 1.
162 2 Static Permanent objects, never moved or reclaimed.
163 3 Read-Only Objects never moved, reclaimed, or altered.
166 @section [Immediate Data Type Descriptions]
170 @index [Fixnum format]
171 Fixnum@\A 28-bit two's complement integer. The sign bit is stored redundantly
172 in the top 5 bits of the word.
174 @index [Short float format]
175 Short-Float@\The sign bit is stored as part of the type code,
176 allowing a 28 bit signed short float format. The format of short floating
180 ---------------------------------------------------------------
181 | Type code (4) | Sign (1) | Exponent (8) | Mantissa (19) |
182 ---------------------------------------------------------------
184 The floating point number is the same format as the @value(DinkyMachine)
185 supports for single precision numbers, except it has been shifted right
186 by four bits for the type code. The result of any operation is therefore
187 truncated. Long floating point numbers are also available if you need
188 more accuracy and better error propagation properties.
190 @index [Character object]
191 Character@\A character object holding a character code, control bits, and font
192 in the following format:
193 @begin [verbatim, group]
194 0 4 6 7 8 15 16 23 24 31
195 ---------------------------------------------------------------
196 | Type code (5) | Unused (3) | Font (8) | Bits (8) | Code (8) |
197 ---------------------------------------------------------------
200 @index [Values-Marker]
201 Values-Marker@\Used to mark the presence of multiple values on the stack. The
202 low 16 bits indicate how many values are being returned. Note that only 65535
203 values can be returned from a multiple-values producing form. These are pushed
204 onto the stack in order, and the Values-Marker is returned in register A0.
206 @index [Catch-All object]
207 Catch-All@\Object used as the catch tag for unwind-protects. Special things
208 happen when a catch frame with this as its tag is encountered during a throw.
209 See section @ref[Catch] for details.
212 @index[Illegal object trap]
213 Trap@\Illegal object trap. This value is used in symbols to signify an
214 undefined value or definition.
216 @index[Interruptible Marker]
217 Interruptible-Marker@\Object used to mark a miscop as interruptible. This
218 object is put in one of the registers and signals to the interrupt handler
219 that the miscop can be interrupted safely. Only miscops that can take a long
220 time (e.g., length when passed a circular list, system call miscops that
221 may wait indefinitely) are marked this way.
224 @section [Pointer-Type Objects and Spaces]
225 @index [Pointer object format]
226 @index [Virtual memory]
228 Each of the pointer-type lisp objects points into a different space in virtual
229 memory. There are separate spaces for Bit-Vectors, Symbols, Lists, and so on.
230 The 5-bit type-code provides the high-order virtual address bits for the
231 object, followed by the 2-bit space code, followed by the 25-bit pointer
232 address. This gives a 30-bit virtual address to a 32-bit word; since the
233 @value(DinkyMachine) is a byte-addressed machine, the two low-order
234 bits are 0. In effect we have carved a 30-bit space into a fixed set
235 of 23-bit subspaces, not all of which are used.
238 The space code divides each of the type spaces into four sub-spaces,
239 as shown in the table above. At any given time, one of the dynamic
240 spaces is considered newspace, while the other is oldspace.
241 During a stop and copy garbage collection, a ``flip'' can be done, turning the
242 old newspace into the new oldspace. All type-spaces are flipped at once.
243 Allocation of new dynamic objects always occurs in newspace.
245 @index [Static space]
246 @index [Read-only space]
247 Optionally, the user (or system functions) may allocate objects in
248 static or read-only space. Such objects are never reclaimed once they
249 are allocated -- they occupy the space in which they were initially
250 allocated for the lifetime of the Lisp process. The advantage of
251 static allocation is that the GC never has to move these objects,
252 thereby saving a significant amount of work, especially if the objects
253 are large. Objects in read-only space are static, in that they are
254 never moved or reclaimed; in addition, they cannot be altered once
255 they are set up. Pointers in read-only space may only point to
256 read-only or static space, never to dynamic space. This saves even
257 more work, since read-only space does not need to be scavenged, and
258 pages of read-only material do not need to be written back onto the
261 Objects in a particular type-space will contain either pointers to
262 garbage-collectible objects or words of raw non-garbage-collectible bits, but
263 not both. Similarly, a space will contain either fixed-length objects or
264 variable-length objects, but not both. A variable-length object always
265 contains a 24-bit length field right-justified in the first word, with
266 the positive fixnum type-code in the high-order five bits. The remaining three
267 bits can be used for sub-type information. The length field gives the
268 size of the object in 32-bit words, including the header word. The
269 garbage collector needs this information when the object is moved, and
270 it is also useful for bounds checking.
272 The format of objects in each space are as follows:
277 @index [Definition cell]
278 @index [Property list cell]
280 @index [Print name cell]
282 @index [Package cell]
283 Symbol@\Each symbol is represented as a
284 fixed-length block of boxed Lisp cells. The number of cells
285 per symbol is 5, in the following order:
286 @begin [verbatim, group]
287 0 Value cell for shallow binding.
288 1 Definition cell: a function or list.
289 2 Property list: a list of attribute-value pairs.
290 3 Print name: a string.
291 4 Package: the obarray holding this symbol.
295 List@\A fixed-length block of two boxed Lisp cells, the CAR and the CDR.
297 @index [General-Vector format]
298 @index [G-Vector format]
299 @index [Vector format]
300 General-Vector@\Vector of lisp objects, any length. The first word is a fixnum
301 giving the number of words allocated for the vector (up to 24 bits). The
302 highest legal index is this number minus 2. The second word is vector entry 0,
303 and additional entries are allocated contiguously in virtual memory. General
304 vectors are sometimes called G-Vectors. (See section @ref[Vectors] for further
307 @index [Integer-Vector format]
308 @index [I-Vector format]
309 @index [Vector format]
310 Integer-Vector@\Vector of integers, any length. The 24 low bits of the first
311 word give the allocated length in 32-bit words. The low-order 28 bits of the
312 second word gives the length of the vector in entries, whatever the length of
313 the individual entries may be. The high-order 4 bits of the second word
314 contain access-type information that yields, among other things, the number of
315 bits per entry. Entry 0 is left-justified in the third word of the vector.
316 Bits per entry will normally be powers of 2, so they will fit neatly into
317 32-bit words, but if necessary some empty space may be left at the low-order
318 end of each word. Integer vectors are sometimes called I-Vectors. (See
319 section @ref[Vectors] for details.)
321 @index [Bit-Vector format]
322 @index [Vector format]
323 Bit-Vector@\Vector of bits, any length. Bit-Vectors are represented in a form
324 identical to I-Vectors, but live in a different space for efficiency reasons.
326 @index [Bignum format]
328 Bignum@\Bignums are infinite-precision integers, represented in a format
329 identical to G-Vectors. Each bignum is stored as a series of 32-bit words,
330 with the low-order word stored first. The representation is two's complement,
331 but the sign of the number is redundantly encoded in the type field of the
332 fixnum in the header word. If this fixnum is non-negative, then so is the
333 bignum, if it is negative, so is the bignum.
335 @index [Flonum format]
336 @index [Flonum formats]
337 @index [Floating point formats]
338 Floats@\Floats are stored as two or more consecutive words of bits, in the
340 @begin [verbatim, group]
341 ---------------------------------------------------------------
342 | Header word, used only for GC forward pointers. |
343 ---------------------------------------------------------------
344 | Appropriate number of 32-bit words in machine format |
345 ---------------------------------------------------------------
347 The number of words used to represent a floating point number is one plus the
348 size of the floating point number being stored. The floating point numbers
349 will be represented in whatever format the @value(DinkyMachine) expects. The
350 extra header word is needed so that a valid floating point number is not
351 mistaken for a gc-forward pointer during a garbage collection.
353 @index [Ratio format]
354 Ratio@\Ratios are stored as two consecutive words of Lisp objects, which should
357 @index [Complex number format]
358 Complex@\Complex numbers are stored as two consecutive words of Lisp objects,
359 which should both be numbers.
361 @index [Array format]
362 Array@\This is actually a header which holds the accessing and
363 other information about the array. The actual array contents are held in a
364 vector (either an I-Vector or G-Vector) pointed to by an entry in
365 the header. The header is identical in format to a G-Vector. For
366 details on what the array header contains, see section @ref[Arrays].
368 @index [String format]
369 String@\A vector of bytes. Identical in form to I-Vectors with the access type
370 always 8-Bit. However, instead of accepting and returning fixnums, string
371 accesses accept and return character objects. Only the 8-bit code field is
372 actually stored, and the returned character object always has bit and font
375 @index [Function object format]
376 Function @\A compiled CMU Common Lisp function consists of both lisp
377 objects and raw bits for the code. The Lisp objects are stored in
378 the Function space in a format identical to that used for general
379 vectors, with a 24-bit length field in the first word. This object
380 contains assorted parameters needed by the calling machinery, a
381 pointer to an 8-bit I-Vector containing the compiled code, a number
382 of pointers to symbols used as special variables within the function,
383 and a number of lisp objects used as constants by the function.
386 @section [Forwarding Pointers]
387 @index [Forwarding pointers]
390 @index [GC-Forward pointer]
391 GC-Forward@\When a data structure is transported into newspace, a GC-Forward
392 pointer is left behind in the first word of the oldspace object. This points
393 to the same type-space in which it is found. For example, a GC-Forward in
394 G-Vector space points to a structure in the G-Vector newspace. GC-Forward
395 pointers are only found in oldspace.
398 @section [System and Stack Spaces]
399 @index [System table space]
400 @index [Stack spaces]
401 @index [Control stack space]
402 @index [Binding stack space]
403 @index [Special binding stack space]
405 The virtual addresses below 08000000@-[16] are not occupied by Lisp objects,
406 since Lisp objects with type code 0 are positive fixnums. Some of this space
407 is used for other purposes by Lisp. A couple of pages (4096 byte pages)
408 at address 00100000@-[16] contain tables that Lisp needs to access
409 frequently. These include the allocation table, the active-catch-frame,
410 information to link to C routines, etc. Memory at location 00200000@-[16]
411 contains code for various miscops. Also, any C code loaded into a running
412 Lisp process is loaded after the miscops. The format of the allocation
413 table is described in chapter @ref[Alloc-Chapter].
415 The control stack grows upward (toward higher addresses) in memory,
416 and is a framed stack. It contains only general Lisp objects (with
417 some random things encoded as fixnums). Every object
418 pointed to by an entry on this stack is kept alive. The frame for a
419 function call contains an area for the function's arguments, an area
420 for local variables, a pointer to the caller's frame, and a pointer
421 into the binding stack. The frame for a Catch form contains similar
422 information. The precise stack format can be found in chapter
425 The special binding stack grows downward. This stack is used to hold
426 previous values of special variables that have been bound. It grows and
427 shrinks with the depth of the binding environment, as reflected in the
428 control stack. This stack contains symbol-value pairs, with only boxed
429 Lisp objects present.
431 All Lisp objects are allocated on word boundaries, since the
432 @value(DinkyMachine) can only access words on word boundaries.
434 @section [Vectors and Arrays]
438 Common Lisp arrays can be represented in a few different ways in CMU Common
439 Lisp -- different representations have different performance advantages.
440 Simple general vectors, simple vectors of integers, and simple strings are
441 basic CMU Common Lisp data types, and access to these structures is quicker
442 than access to non-simple (or ``complex'') arrays. However, all
443 multi-dimensional arrays in CMU Common Lisp are complex arrays, so
444 references to these are always through a header structure.
446 @subsection [General Vectors]
447 @index [General-Vector format]
449 G-Vectors contain Lisp objects. The format is as follows:
451 @begin [verbatim, group]
452 ------------------------------------------------------------------
453 | Fixnum code (5) | Subtype (3) | Allocated length (24) |
454 ------------------------------------------------------------------
455 | Vector entry 0 (Additional entries in subsequent words) |
456 ------------------------------------------------------------------
459 The first word of the vector is
460 a header indicating its length; the remaining words hold the boxed entries of
461 the vector, one entry per 32-bit word. The header word is of type fixnum. It
462 contains a 3-bit subtype field, which is used to indicate several special types
463 of general vectors. At present, the following subtype codes are defined:
467 @begin [itemize, spread 0, spacing 1]
468 0 Normal. Used for assorted things.
470 1 Named structure created by DEFSTRUCT, with type name in entry 0.
472 2 EQ Hash Table, last rehashed in dynamic-0 space.
474 3 EQ Hash Table, last rehashed in dynamic-1 space.
476 4 EQ Hash Table, must be rehashed.
479 Following the subtype is a 24-bit field indicating how many 32-bit words are
480 allocated for this vector, including the header word. Legal indices into the
481 vector range from zero to the number in the allocated length field minus 2,
482 inclusive. Normally, the index is checked on every access to the vector.
483 Entry 0 is stored in the second word of the vector, and subsequent entries
484 follow contiguously in virtual memory.
486 Once a vector has been allocated, it is possible to reduce its length by using
487 the Shrink-Vector miscop, but never to increase its length, even back to
488 the original size, since the space freed by the reduction may have been
489 reclaimed. This reduction simply stores a new smaller value in the length
490 field of the header word.
492 It is not an error to create a vector of length 0, though it will always be an
493 out-of-bounds error to access such an object. The maximum possible length for
494 a general vector is 2@+[24]-2 entries, and that can't fit in the available
495 space. The maximum length is 2@+[23]-2 entries, and that is only possible if
496 no other general vectors are present in the space.
498 @index [Bignum Format]
499 Bignums are identical in format to G-Vectors although each entry is a 32-bit
500 integer, and thus only assembler routines should ever access an entry.
502 @index [Function object format]
503 @index [Array format]
504 Objects of type Function and Array are identical in format to
505 general vectors, though they have their own spaces.
507 @subsection [Integer Vectors]
508 @index [Integer-Vector format]
510 I-Vectors contain unboxed items of data, and their format is more complex. The
511 data items come in a variety of lengths, but are of constant length within a
512 given vector. Data going to and from an I-Vector are passed as Fixnums, right
513 justified. Internally these integers are stored in packed form, filling 32-bit
514 words without any type-codes or other overhead. The format is as follows:
516 @begin [verbatim, group]
517 ----------------------------------------------------------------
518 | Fixnum code (5) | Subtype (3) | Allocated length (24) |
519 ----------------------------------------------------------------
520 | Access type (4) | Number of entries (28) |
521 ----------------------------------------------------------------
522 | Entry 0 left justified |
523 ----------------------------------------------------------------
526 The first word of an I-Vector
527 contains the Fixnum type-code in the top 5 bits, a 3-bit subtype code in the
528 next three bits, and the total allocated length of the vector (in 32-bit words)
529 in the low-order 24 bits. At present, the following subtype codes are defined:
530 @begin [itemize, spread 0, spacing 1]
531 0 Normal. Used for assorted things.
533 1 Code. This is the code-vector for a function object.
536 The second word of the vector is the one that is looked at every
537 time the vector is accessed. The low-order 28 bits of this word
538 contain the number of valid entries in the vector, regardless of how
539 long each entry is. The lowest legal index into the vector is always
540 0; the highest legal index is one less than this number-of-entries
541 field from the second word. These bounds are checked on every access.
542 Once a vector is allocated, it can be reduced in size but not increased.
543 The Shrink-Vector miscop changes both the allocated length field
544 and the number-of-entries field of an integer vector.
546 @index [Access-type codes]
547 The high-order 4 bits of the second word contain an access-type code
548 which indicates how many bits are occupied by each item (and therefore
549 how many items are packed into a 32-bit word). The encoding is as follows:
550 @begin [verbatim, group]
561 In I-Vectors, the data items are packed into the third and subsequent
562 words of the vector. Item 0 is left justified in the third word,
563 item 1 is to its right, and so on until the allocated number of items
564 has been accommodated. All of the currently-defined access types
565 happen to pack neatly into 32-bit words, but if this should not be
566 the case, some unused bits would remain at the right side of each
567 word. No attempt will be made to split items between words to use up
568 these odd bits. When allocated, an I-Vector is initialized to all
571 As with G-Vectors, it is not an error to create an I-Vector of length
572 0, but it will always be an error to access such a vector. The
573 maximum possible length of an I-Vector is 2@+[28]-1 entries or
574 2@+[23]-3 words, whichever is smaller.
576 @index [String format]
577 Objects of type String are identical in format to I-Vectors, though they have
578 their own space. Strings always have subtype 0 and access-type 3 (8-Bit).
579 Strings differ from normal I-Vectors in that the accessing miscops accept
580 and return objects of type Character rather than Fixnum.
586 An array header is identical in form to a G-Vector. Like any G-Vector, its
587 first word contains a fixnum type-code, a 3-bit subtype code, and a 24-bit
588 total length field (this is the length of the array header, not of the vector
589 that holds the data). At present, the subtype code is always 0. The entries
590 in the header-vector are interpreted as follows:
592 @index [Array header format]
594 0 Data Vector @\This is a pointer to the I-Vector, G-Vector, or string that
595 contains the actual data of the array. In a multi-dimensional array, the
596 supplied indices are converted into a single 1-D index which is used to access
597 the data vector in the usual way.
599 1 Number of Elements @\This is a fixnum indicating the number of elements for
600 which there is space in the data vector.
602 2 Fill Pointer @\This is a fixnum indicating how many elements of the data
603 vector are actually considered to be in use. Normally this is initialized to
604 the same value as the Number of Elements field, but in some array applications
605 it will be given a smaller value. Any access beyond the fill pointer is
608 3 Displacement @\This fixnum value is added to the final code-vector index
609 after the index arithmetic is done but before the access occurs. Used for
610 mapping a portion of one array into another. For most arrays, this is 0.
612 4 Range of First Index @\This is the number of index values along the first
613 dimension, or one greater than the largest legal value of this index (since the
614 arrays are always zero-based). A fixnum in the range 0 to 2@+[24]-1. If any
615 of the indices has a range of 0, the array is legal but will contain no data
616 and accesses to it will always be out of range. In a 0-dimension array, this
617 entry will not be present.
619 5 - N Ranges of Subsequent Dimensions
622 The number of dimensions of an array can be determined by looking at the length
623 of the array header. The rank will be this number minus 6. The maximum array
624 rank is 65535 - 6, or 65529.
626 The ranges of all indices are checked on every access, during the conversion to
627 a single data-vector index. In this conversion, each index is added to the
628 accumulating total, then the total is multiplied by the range of the following
629 dimension, the next index is added in, and so on. In other words, if the data
630 vector is scanned linearly, the last array index is the one that varies most
631 rapidly, then the index before it, and so on.
633 @section [Symbols Known to the Assembler Routines]
634 @label [Known-Objects]
636 A large number of symbols will be pre-defined when a CMU Common Lisp system
637 is fired up. A few of these are so fundamental to the operation of the
638 system that their addresses have to be known to the assembler routines.
639 These symbols are listed here. All of these symbols are in static space,
640 so they will not move around.
644 NIL @\94000000@-[16] The value of NIL is always NIL; it is an error
645 to alter it. The plist of NIL is always NIL; it is an error to alter
646 it. NIL is unique among symbols in that it is stored in Cons cell
647 space and thus you can take its CAR and CDR, yielding NIL in either
648 case. NIL has been placed in Cons cell space so that the more common
649 operations on lists will yield the desired results. This slows down
650 some symbol operations but this should be insignificant compared to
651 the savings in list operations. A test for NIL for the
652 @value(DinkyMachine) is:
655 bz IsNIL or bnz IsNotNIL
659 T @\8C000000@-[16] The value of T is always T; it is an error
660 to alter it. A similar sequence of code as for NIL above can test for T,
663 @index [%SP-Internal-Apply]
664 %SP-Internal-Apply @\8C000014@-[16] The function stored in the definition cell
665 of this symbol is called by an assembler routine whenever compiled code calls
666 an interpreted function.
668 @index [%SP-Internal-Error]
669 %SP-Internal-Error @\8C000028@-[16] The function stored in the definition cell
670 of this symbol is called whenever an error is detected during the execution of
671 an assembler routine. See section @ref[Errors] for details.
673 @index [%SP-Software-Interrupt-Handler]
674 %SP-Software-Interrupt-Handler @\8C00003C@-[16] The function stored in the
675 definition cell of this symbol is called whenever a software interrupt occurs.
676 See section @ref[Interrupts] for details.
678 @index [%SP-Internal-Throw-Tag]
679 %SP-Internal-Throw-Tag @\8C000050@-[16] This symbol is bound to the tag being
680 thrown when a Catch-All frame is encountered on the stack. See section
681 @ref[Catch] for details.
683 @index [%Initial-function]
684 %Initial-function@\8c000064@-[16] This symbol's function cell should contain
685 a function that is called when the initial core image is started. This
686 function should initialize all the data structures that Lisp needs to run.
688 @index [%Link-table-header]
689 %Link-table-header@\8c000078@-[16] This symbol's value cell contains a pointer
690 to the link table information.
692 @index [Current-allocation-space]
693 Current-allocation-space@\8c00008c@-[16] This symbol's value cell contains
694 an encoded form of the current space that new lisp objects are to be allocated
697 @index [%SP-bignum/fixnum]
698 %SP-bignum/fixnum@\8c0000a0@-[16] This function is invoked by the miscops
699 when a division of a bignum by a fixnum results in a ratio.
701 @index [%SP-fixnum/bignum]
702 %SP-bignum/bignum@\8c0000b4@-[16] This
703 function is invoked by the miscops when a division of a fixnum by a
704 bignum results in a ratio.
706 @index [%SP-bignum/bignum]
707 %SP-bignum/bignum@\8c0000c8@-[16] This function is invoked by the miscops
708 when a division of a bignum by a bignum results in a ratio.
710 @index [%SP-abs-ratio]
711 %SP-abs-ratio@\8c0000dc@-[16] This function is invoked by the miscops
712 when the absolute value of a ratio is taken.
714 @index [%SP-abs-complex]
715 %SP-abs-complex@\8c0000f0@-[16] This function is invoked by the miscops
716 when the absolute value of a complex is taken.
718 @index [%SP-negate-ratio]
719 %SP-negate-ratio@\8c000104@-[16] This function is invoked by the miscops
720 when a ratio is to be negated.
722 @index [%SP-negate-complex]
723 %SP-negate-ratio@\8c000118@-[16] This function is invoked by the miscops
724 when a complex is to be negated.
726 @index[%SP-integer+ratio]
727 %SP-integer+ratio@\8c00012c@-[16] This function is invoked by the miscops
728 when a fixnum or bignum is added to a ratio.
730 @index[%SP-ratio+ratio]
731 %SP-ratio+ratio@\8c000140@-[16] This function is invoked by the miscops
732 when a ratio is added to a ratio.
734 @index[%SP-complex+number]
735 %SP-complex+number@\8c000154@-[16] This function is invoked by the miscops
736 when a complex is added to a number.
738 @index[%SP-number+complex]
739 %SP-number+complex@\8c000168@-[16] This function is invoked by the miscops
740 when a number is added to a complex.
742 @index[%SP-complex+complex]
743 %SP-complex+complex@\8c00017c@-[16] This function is invoked by the miscops
744 when a number is added to a complex.
747 %SP-1+ratio@\8c000190@-[16] This function is invoked by the miscops when
748 1 is added to a ratio.
750 @index[%SP-1+complex]
751 %SP-1+complex@\8c000190@-[16] This function is invoked by the miscops when
752 1 is added to a complex.
754 @index[%SP-ratio-integer]
755 %SP-ratio-integer@\8c0001b8@-[16] This function is invoked by the miscops
756 when an integer is subtracted from a ratio.
758 @index[%SP-ratio-ratio]
759 %SP-ratio-ratio@\8c0001cc@-[16] This function is invoked by the miscops
760 when an ratio is subtracted from a ratio.
762 @index[%SP-complex-number]
763 %SP-complex-number@\8c0001e0@-[16] This function is invoked by the miscops
764 when a complex is subtracted from a number.
766 @index[%SP-number-complex]
767 %SP-number-complex@\8c0001f4@-[16] This function is invoked by the miscops
768 when a number is subtracted from a complex.
770 @index[%SP-complex-complex]
771 %SP-complex-complex@\8c000208@-[16] This function is invoked by the miscops
772 when a complex is subtracted from a complex.
774 @index[%SP-1-complex]
775 %SP-1-complex@\8c000230@-[16] This function is invoked by the miscops when
776 1 is subtracted from a complex.
778 @index[%SP-ratio*ratio]
779 %SP-ratio*ratio@\8c000244@-[16] This function is invoked by the miscops to
782 @index[%SP-number*complex]
783 %SP-number*complex@\8c000258@-[16] This function is invoked by the miscops to
784 multiply a number by a complex.
786 @index[%SP-complex*number]
787 %SP-complex*number@\8c00026c@-[16] This function is invoked by the miscops to
788 multiply a complex by a number.
790 @index[%SP-complex*complex]
791 %SP-complex*complex@\8c000280@-[16] This function is invoked by the miscops
792 to multiply a complex by a complex.
794 @index[%SP-integer/ratio]
795 %SP-integer/ratio@\8c000294@-[16] This function is invoked by the miscops to
796 divide an integer by a ratio.
798 @index[%SP-ratio/integer]
799 %SP-ratio/integer@\8c0002a8@-[16] This function is invoked by the miscops to
800 divide a ratio by an integer.
802 @index[%SP-ratio/ratio]
803 %SP-ratio/ratio@\8c0002bc@-[16] This function is invoked by the miscops to
804 divide a ratio by a ratio.
806 @index[%SP-number/complex]
807 %SP-number/complex@\8c0002d0@-[16] This function is invoked by the miscops to
808 divide a number by a complex.
810 @index[%SP-complex/number]
811 %SP-complex/number@\8c0002e4@-[16] This function is invoked by the miscops to
812 divide a complex by a number.
814 @index[%SP-complex/complex]
815 %SP-complex/complex@\8c0002f8@-[16] This function is invoked by the miscops
816 to divide a complex by a complex.
818 @index[%SP-integer-truncate-ratio]
819 %SP-integer-truncate-ratio@\8c00030c@-[16] This function is invoked by the
820 miscops to truncate an integer by a ratio.
822 @index[%SP-ratio-truncate-integer]
823 %SP-ratio-truncate-integer@\8c000320@-[16] This function is invoked by the
824 miscops to truncate a ratio by an integer.
826 @index[%SP-ratio-truncate-ratio]
827 %SP-ratio-truncate-ratio@\8c000334@-[16] This function is invoked by the
828 miscops to truncate a ratio by a ratio.
830 @index[%SP-number-truncate-complex]
831 %SP-number-truncate-complex@\8c000348@-[16] This function is invoked by the
832 miscops to truncate a number by a complex.
834 @index[%SP-complex-truncate-number]
835 %SP-complex-truncate-number@\8c00035c@-[16] This function is invoked by the
836 miscops to truncate a complex by a number.
838 @index[%SP-complex-truncate-complex]
839 %SP-complex-truncate-complex@\8c000370@-[16] This function is invoked by
840 the miscops to truncate a complex by a complex.
843 Maybe-GC@\8c000384@-[16] This function may be invoked by any miscop that
844 does allocation. This function determines whether it is time to garbage
845 collect or not. If it is it performs a garbage collection. Whether it
846 invokes a garbage collection or not, it returns the single argument passed
849 @index[Lisp-environment-list]
850 Lisp-environment-list@\8c000398@-[16] The value of this symbol is
851 set to the a list of the Unix environment strings passed into the Lisp
852 process. This list by Lisp to obtain various environment information, such
853 as the user's home directory, etc.
855 @index[Call-lisp-from-c]
856 Call-lisp-from-C@\8c0003ac@-[16] This function is called whenever a
857 C function called by Lisp tries to call a Lisp function.
859 @index[Lisp-command-line-list]
860 Lisp-command-line-list@\8c0003c0@-[16] The value of this symbol is
861 set to the list of strings passed into the Lisp process as the command
864 @index[*Nameserverport*]
865 *Nameserverport*@\8c0003d4@-[16] The value of this symbol is set to
866 the C global variable name_server_port. This allows Lisp to access the
869 @index[*Ignore-Floating-Point-Underflow*]
870 *Ignore-Floating-Point-Underflow*@\8c0003e8@-[16] If the the value of this
871 symbol is NIL then an error is signalled when floating point underflow
872 occurs, otherwise the operation quietly returns zero.
875 @chapter [Runtime Environment]
876 @index [Runtime Environment]
879 @section [Register Allocation]
880 @index [Register allocation]
881 To describe the assembler support routines in chapter @ref[Instr-Chapter] and
883 control conventions in chapter @ref[Control-Conventions] requires that we talk
884 about the allocation of the 16 32-bit general purpose registers provided
885 by the @value(DinkyMachine).
887 @index [Program-Counter register]
888 Program-Counter (PC) [R15]@\This register contains an index into the current
889 code vector when a Lisp function is about to be called. When a miscop is
890 called, it contains the return address. It may be used as a super temporary
891 between miscop and function calls.
893 @index [Active-Function-Pointer register]
894 Active-Function-Pointer (AF) [R14]@\This register contains a pointer to the
895 active function object. It is used to access the symbol and constant area for
896 the currently running function.
898 @index [Active-Frame-Pointer register]
899 Active-Frame-Pointer (FP) [R13]@\This register contains a pointer to the
900 current active frame on the control stack. It is used to access the arguments
901 and local variables stored on the control stack.
903 @index [Binding-Stack-Pointer register]
904 Binding-Stack-Pointer (BS) [R12]@\This register contains the current binding
905 stack pointer. The binding stack is a downward growing stack and follows
906 a decrement-write/increment-read discipline.
908 @index [Local registers]
909 Local registers (L0-L4) [R7-R11]@\These registers contain locals and saved
910 arguments for the currently executing function. Functions may use these
911 registers, so that stack accesses can be reduced, since a stack access is
912 relatively expensive compared to a register access.
914 @index [Argument registers]
915 Argument register (A0, A1, A2) [R1, R3, R5]@\These registers contain arguments
916 to a function or miscop that has just been called. On entry to a function
917 or miscop, they contain the first three arguments. The first thing a function
918 does is to move the contents of these registers into the local registers.
920 @index [Miscop argument register]
921 Miscop argument register (A3) [R4]@\This register is used to pass a fourth
922 argument to miscops requiring four or more arguments. It is also used as a
923 super temporary by the compiler.
925 @index [Control-Stack-Pointer register]
926 Control-Stack-Pointer (CS) [R6]@\The stack pointer for the control stack, an
927 object of type Control-Stack-Pointer. Points to the last used word in
928 Control-Stack space; this upward growing stack uses a
929 increment-write/read-decrement discipline.
931 @index [Non-Lisp temporary registers]
932 Non-Lisp temporary registers (NL0, NL1) [R0, R2]@\These registers are used to
933 contain non-Lisp values. They will normally be used during miscop calls, but
934 may also be used in in-line code to contain temporary data. These are the only
935 two registers never examined by the garbage collector, so no pointers to Lisp
936 objects should be stored here (since they won't get updated during a garbage
940 @section [Function Object Format]
943 Each compiled function is represented in the machine as a Function
944 Object. This is identical in form to a G-Vector of lisp objects, and
945 is treated as such by the garbage collector, but it exists in a
946 special function space. (There is no particular reason for this
947 distinction. We may decide later to store these things in G-Vector
948 space, if we become short on spaces or have some reason to believe
949 that this would improve paging behavior.) Usually, the function
950 objects and code vectors will be kept in read-only space, but nothing
951 should depend on this; some applications may create, compile, and
952 destroy functions often enough to make dynamic allocation of function
956 @index [Constants in code] The function object contains a vector of
957 header information needed by the function-calling mechanism: a
958 pointer to the I-Vector that holds the actual code. Following this
959 is the so-called ``symbols and constants'' area. The first few
960 entries in this area are fixnums that give the offsets into the code
961 vector for various numbers of supplied arguments. Following this
962 begin the true symbols and constants used by the function. Any
963 symbol used by the code as a special variable.
964 Fixnum constants can be generated faster
965 with in-line code than they can be accessed from the function-object,
966 so they are not stored in the constants area.
968 The subtype of the G-Vector header indicates the type of the function:
969 @begin(Itemize, spacing 1, spread 0)
970 0 - A normal function (expr).
972 1 - A special form (fexpr).
974 2 - A defmacro macroexpansion function.
976 3 - An anonymous expr. The name is the name of the parent function.
978 4 - A compiled top-level form.
980 Only the fexpr information has any real meaning to the system. The rest
981 is there for the printer and anyone else who cares.
984 After the one-word G-Vector header, the entries of the function object
987 @begin [verbatim, group]
988 0 Name of the innermost enclosing named function.
989 1 Pointer to the unboxed Code vector holding the instructions.
990 2 A fixnum with bit fields as follows:
991 24 - 31: The minimum legal number of args (0 to 255).
992 16 - 23: The maximum number of args, not counting &rest (0 to 255).
993 The fixnum has a negative type code, if the function accepts a &rest
994 arg and a positive one otherwise.
995 3 A string describing the source file from which the function was defined.
996 See below for a description of the format.
997 4 A string containing a printed representation of the argument list, for
998 documentation purposes. If the function is a defmacro macroexpansion
999 function, the argument list will be the one originally given to defmacro
1000 rather than the actual arglist to the expansion function.
1001 5 The symbols and constants area starts here.
1002 This word is entry 0 of the symbol/constant area.
1003 The first few entries in this area are fixnums representing the
1004 code-vector entry points for various numbers of optional arguments.
1007 @section [Defined-From String Format]
1008 @label [Defined-From-String-Format]
1009 @index [Defined-From String Format]
1011 The defined-from string may have any of three different formats, depending
1012 on which of the three compiling functions compiled it:
1014 compile-file "@i[filename user-time universal-time]"@\ The @i[filename] is
1015 the namestring of the truename of the file the function was defined from.
1016 The time is the file-write-date of the file.
1018 compile "Lisp on @i[user-time], machine @i[machine universal-time]"@\
1019 The time is the time that the function was compiled. @i[Machine] is the
1020 machine-instance of the machine on which the compilation was done.
1022 compile-from-stream "@i[stream] on @i[user-time], machine @i[machine-instance
1023 universal-time]"@\@i[Stream] is the printed representation of the stream
1024 compiled from. The time is the time the compilation started.
1027 An example of the format of @i[user-time] is 6-May-86 1:04:44. The
1028 @i[universal-time] is the same time represented as a decimal integer.
1029 It should be noted that in each case, the universal time is the last
1030 thing in the string.
1032 @section [Control-Stack Format]
1033 @label [Control-Stack-Format]
1034 @index [Control-stack format]
1036 The CMU Common Lisp control stack is a framed stack. Call frames, which hold
1037 information for function calls, are intermixed with catch frames, which hold
1038 information used for non-local exits. In addition, the control stack is used
1039 as a scratchpad for random computations.
1041 @subsection [Call Frames]
1043 @index [Active frame]
1045 At any given time, the machine contains pointers to the current top
1046 of the control stack and the start of the current active frame (in
1047 which the current function is executing). In addition, there is a
1048 pointer to the current top of the special binding stack. CMU Common Lisp
1049 on the Perq also has a pointer to an open frame. An open frame is
1050 one which has been partially built, but which is still having
1051 arguments for it computed. When all the arguments have been computed
1052 and saved on the frame, the function is then started. This means
1053 that the call frame is completed, becomes the current active frame,
1054 and the function is executed. At this time, special variables may be
1055 bound and the old values are saved on the binding stack. Upon
1056 return, the active frame is popped away and the result is either sent
1057 as an argument to some previously opened frame or goes to some other
1058 destination. The binding stack is popped and old values are
1061 On the @value(DinkyMachine), open frames still exist, however, no register is
1062 allocated to point at the most recent one. Instead, a count of the arguments
1063 to the function is kept. In most cases, a known fixed number of arguments are
1064 passed to a function, and this is all that is needed to calculate the correct
1065 place to set the active frame pointer.
1066 In some cases, it is not as simple, and runtime calculations are necessary to
1067 set up the frame pointer. These calculations are simple except in some very
1070 The active frame contains pointers to the previously-active frame and
1071 to the point to which the binding stack will be popped
1072 on exit, among other things. Following this is a vector of storage locations
1073 for the function's arguments and local variables. Space is allocated for the
1074 maximum number of arguments that the function can take, regardless of how many
1075 are actually supplied.
1077 In an open frame, stack space is allocated up to the point where the arguments
1078 are stored. Nothing is stored in the frame
1079 at this time. Thus, as arguments are computed, they can simply be pushed on
1080 the stack. Since the first three arguments are passed in registers, it is
1081 sometimes necessary to save these values when succeeding arguments are
1082 complicated. When the function is finally started, the remainder of the frame
1083 is built (including storing all the
1084 registers that must be saved). A call frame looks like this:
1085 @begin [verbatim, group]
1086 0 Saved local 0 register.
1087 1 Saved local 1 register.
1088 2 Saved local 2 register.
1089 3 Saved local 3 register.
1090 4 Saved local 4 register.
1091 5 Pointer to previous binding stack.
1092 6 Pointer to previous active frame.
1093 7 Pointer to previous active function.
1094 8 Saved PC of caller. A fixnum.
1095 9 Args-and-locals area starts here. This is entry 0.
1097 The first slot is pointed to by the Active-Frame register if this frame is
1100 @subsection [Catch Frames]
1102 @index [Catch frames]
1104 Catch frames contain much of the same information that call frames
1105 do, and have a very similar format. A catch frame holds the function
1106 object for the current function, a stack pointer to the current
1107 active frame, a pointer to the current top of the binding stack, and
1108 a pointer to the previous catch frame. When a Throw occurs, an
1109 operation similar to returning from this catch frame (as if it
1110 were a call frame) is performed, and the stacks are unwound to the
1111 proper place for continued execution in the current function. A
1112 catch frame looks like this:
1113 @begin [verbatim, group]
1114 0 Pointer to current binding stack.
1115 1 Pointer to current active frame.
1116 2 Pointer to current function object.
1117 3 Destination PC for a Throw.
1118 4 Tag caught by this catch frame.
1119 5 Pointer to previous catch frame.
1121 The conventions used to manipulate call and catch frames are described in
1122 chapter @ref[Control-Conventions].
1124 @section [Binding-Stack Format]
1125 @index [Binding stack format]
1127 Each entry of the binding-stack consists of two boxed (32-bit) words. Pushed
1128 first is a pointer to the symbol being bound. Pushed second is the symbol's
1129 old value (any boxed item) that is to be restored when the binding stack is
1132 @chapter [Storage Management]
1133 @index [Storage management]
1134 @index [Garbage Collection]
1135 @label [Alloc-Chapter]
1137 @index [Free-Storage pointer]
1138 @index [Clean-Space pointer]
1139 New objects are allocated from the lowest unused addresses within the specified
1140 space. Each allocation call specifies how many words are wanted, and a
1141 Free-Storage pointer is incremented by that amount. There is one of these
1142 Free-Storage pointers for each space, and it points to the lowest free address
1143 in the space. There is also a Clean-Space pointer associated with each space
1144 that is used during garbage collection. These pointers are stored in a table
1145 which is indexed by the type and space code. The
1146 address of the Free-Storage pointer for a given space is
1148 (+ alloc-table-base (lsh type 5) (lsh space 3)).
1150 The address of the Clean-Space pointer is
1152 (+ alloc-table-base (lsh type 5) (lsh space 3) 4).
1155 Common Lisp on the @value(DinkyMachine) uses a stop-and-copy garbage collector
1156 to reclaim storage. The Collect-Garbage miscop performs a full GC. The
1157 algorithm used is a degenerate form of Baker's incremental garbage collection
1158 scheme. When the Collect-Garbage miscop is executed, the following
1161 The current newspace becomes oldspace, and the current oldspace becomes
1164 The newspace Free-Storage and Clean-Space pointers are initialized to point to
1165 the beginning of their spaces.
1167 The objects pointed at by contents of all the registers containing Lisp objects
1168 are transported if necessary.
1170 The control stack and binding stack are scavenged.
1172 Each static pointer space is scavenged.
1174 Each new dynamic space is scavenged. The scavenging of the dynamic spaces
1175 continues until an entire pass through all of them does not result in anything
1176 being transported. At this point, every live object is in newspace.
1178 A Lisp-level GC function returns the oldspace pages to Mach.
1180 @index [Transporter]
1181 @section [The Transporter]
1182 The transporter moves objects from oldspace to newspace. It is given an
1183 address @i[A], which contains the object to be transported, @i[B]. If @i[B] is
1184 an immediate object, a pointer into static space, a pointer into read-only
1185 space, or a pointer into newspace, the transporter does nothing.
1187 If @i[B] is a pointer into oldspace, the object it points to must be
1188 moved. It may, however, already have been moved. Fetch the first
1189 word of @i[B], and call it @i[C]. If @i[C] is a GC-forwarding
1190 pointer, we form a new pointer with the type code of @i[B] and the
1191 low 27 bits of @i[C]. Write this into @i[A].
1193 If @i[C] is not a GC-forwarding pointer, we must copy the object that
1194 @i[B] points to. Allocate a new object of the same size in newspace,
1195 and copy the contents. Replace @i[C] with a GC-forwarding pointer to
1196 the new structure, and write the address of the new structure back
1199 Hash tables maintained with an EQ relation need special treatment by the
1200 transporter. Whenever a G-Vector with subtype 2 or 3 is transported to
1201 newspace, its subtype code is changed to 4. The Lisp-level hash-table
1202 functions will see that the subtype code has changed, and re-hash the entries
1203 before any access is made.
1206 @section [The Scavenger] The scavenger looks through an area of
1207 pointers for pointers into oldspace, transporting the objects they
1208 point to into newspace. The stacks and static spaces need to be
1209 scavenged once, but the new dynamic spaces need to be scavenged
1210 repeatedly, since new objects will be allocated while garbage
1211 collection is in progress. To keep track of how much a dynamic space
1212 has been scavenged, a Clean-Space pointer is maintained. The
1213 Clean-Space pointer points to the next word to be scavenged. Each
1214 call to the scavenger scavenges the area between the Clean-Space
1215 pointer and the Free-Storage pointer. The Clean-Space pointer is
1216 then set to the Free-Storage pointer. When all Clean-Space pointers
1217 are equal to their Free-Storage pointers, GC is complete.
1219 To maintain (and create) locality of list structures, list space is
1220 treated specially. When a list cell is transported, if the cdr points
1221 to oldspace, it is immediately transported to newspace. This continues until
1222 the end of the list is encountered or a non-oldspace pointer occurs in the cdr
1223 position. This linearizes lists in the cdr direction which should
1224 improve paging performance.
1226 @section [Purification]
1227 @index [Purification]
1230 Garbage is created when the files that make up a CMU Common Lisp system are
1231 loaded. Many functions are needed only for initialization and
1232 bootstrapping (e.g. the ``one-shot'' functions produced by the compiler for
1233 random forms between function definitions), and these can be thrown away
1234 once a full system is built. Most of the functions in the system, however,
1235 will be used after initialization. Rather than bend over backwards to make
1236 the compiler dump some functions in read-only space and others in dynamic
1237 space (which involves dumping their constants in the proper spaces, also),
1238 @i[everything] is dumped into dynamic space. A purify miscop is provided
1239 that does a garbage collection and moves accessible information in dynamic
1240 space into read-only or static space.
1242 @chapter [Assembler Support Routines]
1243 @label [Instr-Chapter]
1244 @index [Assembler Support Routines]
1246 To support compiled Common Lisp code many hand coded assembler
1247 language routines (miscops) are required. These routines accept
1248 arguments in the three argument registers, the special miscop
1249 argument register, and in a very few cases on the stack. The current
1250 register assignments are:
1251 @begin(Itemize, spread 0, spacing 1)
1252 A0 contains the first argument.
1254 A1 contains the second argument.
1256 A2 contains the third argument.
1258 A3 contains the fourth argument.
1260 The rest of the arguments are passed on the stack with the last
1261 argument at the end of the stack. All arguments on the stack must be
1262 popped off the stack by the miscop. All miscops return their
1263 values in register A0. A few miscops return two or three values,
1264 these are all placed in the argument registers. The main return
1265 value is stored in register A0, the others in A1 and A2. The
1266 compiler must generate code to use the multiple values correctly,
1267 i.e., place the return values on the stack and put a values marker in
1268 register A0 if multiple-values are wanted. Otherwise the compiler
1269 can use the value(s) it needs and ignore the rest. NB: Most of the
1270 miscops follow this scheme, however, a few do not. Any
1271 discrepancies are explained in the description of particular
1274 Several of the instructions described in the Perq Internal Design Document do
1275 not have associated miscops, rather they have been code directly in-line.
1276 Examples of these instructions include push, pop, bind, bind-null, many of the
1277 predicates, and a few other instructions. Most of these instructions can be
1278 performed in 4 or fewer @value(DinkyMachine) instructions and the overhead of
1279 calling a miscop seemed overly expensive. Some instructions are encoded
1280 in-line or as a miscop call depending on settings of compiler optimization
1281 switches. If space is more important than speed, then some Perq instructions
1282 are compiled as calls to out of line miscops rather than generating in-line
1285 @section [Miscop Descriptions]
1288 There are 10 classes of miscops: allocation, stack manipulation,
1289 list manipulation, symbol manipulation, array manipulation, type predicate,
1290 arithmetic and logical, function call and return,
1291 miscellaneous, and system hacking.
1293 @subsection [Allocation]
1295 All non-immediate objects are allocated in the ``current allocation space,''
1296 which is dynamic space, static space, or read-only space. The current
1297 allocation space is initially dynamic space, but can be changed by using the
1298 Set-Allocation-Space miscop below. The current allocation space can be
1299 determined by using the Get-Allocation-Space miscop. One usually wants to
1300 change the allocation space around some section of code; an unwind protect
1301 should be used to insure that the allocation space is restored to some safe
1305 @index [Get-Allocation-Space]
1306 Get-Allocation-Space (@i[])@\returns 0, 2, or 3 if the current allocation
1307 space is dynamic, static, or read-only, respectively.
1309 @index [Set-Allocation-Space]
1310 Set-Allocation-Space (@i[X])@\sets the current allocation space to dynamic,
1311 static, or read-only if @i[X] is 0, 2, or 3 respectively. Returns @i[X].
1313 @index [Alloc-Bit-Vector]
1314 Alloc-Bit-Vector (Length)@\returns a new bit-vector @i[Length] bits long,
1315 which is allocated in the current allocation space. @i[Length] must be a
1318 @index [Alloc-I-Vector]
1319 Alloc-I-Vector (@i[Length A])@\returns a new I-Vector @i[Length]
1320 bytes long, with the access code specified by @i[A]. @i[Length] and
1321 @i[A] must be positive fixnums.
1323 @index [Alloc-String]
1324 Alloc-String (@i[Length])@\ returns a new string @i[Length] characters long.
1325 @i[Length] must be a fixnum.
1327 @index [Alloc-Bignum]
1328 Alloc-Bignum (@i[Length])@\returns a new bignum @i[Length] 32-bit words long.
1329 @i[Length] must be a fixnum.
1331 @index [Make-Complex]
1332 Make-Complex (@i[Realpart Imagpart])@\returns a new complex number with the
1333 specified @i[Realpart] and @i[Imagpart]. @i[Realpart] and @i[Imagpart] should
1334 be the same type of non-complex number.
1337 Make-Ratio (@i[Numerator Denominator])@\returns a new ratio with the
1338 specified @i[Numerator] and @i[Denominator]. @i[Numerator] and
1339 @i[Denominator] should be integers.
1341 @index [Alloc-G-Vector]
1342 Alloc-G-Vector (@i[Length Initial-Element])@\returns a new G-Vector
1343 with @i[Length] elements initialized to @i[Initial-Element].
1344 @i[Length] should be a fixnum.
1346 @index [Static-Alloc-G-Vector]
1347 Static-G-Vector (@i[Length Initial-Element])@\returns a new G-Vector in
1348 static allocation space with @i[Length] elements initialized to
1349 @i[Initial-Element].
1352 Vector (@i[Elt@-[0] Elt@-[1] ... Elt@-[Length - 1] Length])@\returns a new
1353 G-Vector containing the specified @i[Length] elements. @i[Length] should be a
1354 fixnum and is passed in register A0. The rest of the arguments are passed on
1357 @index [Alloc-Function]
1358 Alloc-Function (@i[Length])@\returns a new function with @i[Length] elements.
1359 @i[Length] should be a fixnum.
1361 @index [Alloc-Array]
1362 Alloc-Array (@i[Length])@\returns a new array with @i[Length] elements.
1363 @i[Length] should be a fixnum.
1365 @index [Alloc-Symbol]
1366 Alloc-Symbol (@i[Print-Name])@\returns a new symbol with the print-name as
1367 @i[Print-Name]. The value is initially Trap, the definition is Trap,
1368 the property list and the package are initially NIL. The symbol is
1369 not interned by this operation -- that is done in Lisp code.
1370 @i[Print-Name] should be a simple-string.
1373 Cons (@i[Car Cdr])@\returns a new cons with the specified @i[Car] and @i[Cdr].
1376 List (@i[Elt@-[0] Elt@-[1] ... Elt@-[CE - 1] Length])@\returns a new list
1377 containing the @i[Length] elements. @i[Length] should be fixnum and is
1378 passed in register NL0. The first three arguments are passed in A0, A1, and
1379 A2. The rest of the arguments are passed on the stack.
1382 List* (@i[Elt@-[0] Elt@-[1] ... Elt@-[CE - 1] Length])@\returns a list* formed
1383 by the @i[Length-1] elements. The last element is placed in the cdr of the
1384 last element of the new list formed. @i[Length] should be a fixnum and is
1385 passed in register NL0. The first three arguments are passed in A0, A1, and
1386 A2. The rest of the arguments are passed on the stack.
1389 MV-List (@i[Elt@-<0> Elt@-<1> ... Elt@-<CE - 1> Length])@\returns a list
1390 formed from the elements, all of which are on the stack. @i[Length] is
1391 passed in register A0. This miscop is invoked when multiple values from
1392 a function call are formed into a list.
1395 @subsection [Stack Manipulation]
1400 Push (@i[E])@\pushes E on to the control stack.
1403 Pop (@i[E])@\pops the top item on the control stack into @i[E].
1406 NPop (@i[N])@\If @i[N] is positive, @i[N] items are popped off of the stack.
1407 If @i[N] is negative, NIL is pushed onto the stack -@i[N] times. @i[N] must be
1411 Bind-Null (@i[E])@\pushes @i[E] (which must be a symbol) and its current value
1412 onto the binding stack, and sets the value of @i[E] to NIL. Returns NIL.
1415 Bind (Value Symbol)@\pushes @i[Symbol] (which must be a symbol) and its current
1416 value onto the binding stack, and sets the value cell of @i[Symbol] to
1417 @i[Value]. Returns @i[Symbol].
1420 Unbind (@i[N])@\undoes the top @i[N] bindings on the binding stack.
1423 @subsection [List Manipulation]
1433 Car, Cdr, Caar, Cadr, Cdar, Cddr (@i[E])@\returns the car, cdr, caar, cadr,
1434 cdar, or cddr of @i[E] respectively.
1438 Set-Cdr, Set-Cddr (@i[E])@\The cdr or cddr of the contents of @i[E] is stored
1439 in @i[E]. The contents of @i[E] should be either a list or NIL.
1442 Set-Lpop (@i[E])@\The car of the contents of @i[E] is returned;
1443 the cdr of the contents of @i[E] is stored in @i[E]. The contents of @i[E]
1444 should be a list or NIL.
1447 Spread (@i[E])@\pushes the elements of the list @i[E] onto the stack in
1448 left-to-right order.
1450 @index [Replace-Car]
1451 @index [Replace-Cdr]
1452 Replace-Car, Replace-Cdr (@i[List Value])@\sets the car or cdr of the @i[List]
1453 to @i[Value] and returns @i[Value].
1456 Endp (X)@\sets the condition code eq bit to 1 if @i[X] is NIL, or 0 if @i[X] is
1457 a cons cell. Otherwise an error is signalled.
1461 Assoc, Assq (@i[List Item])@\returns the first cons in the association-list
1462 @i[List] whose car is EQL to @i[Item]. If the = part of the EQL comparison
1463 bugs out (and it can if the numbers are too complicated), a Lisp-level Assoc
1464 function is called with the current cdr of the @i[List]. Assq returns the
1465 first cons in the association-list @i[List] whose car is EQ to @i[Item].
1468 @index [Memq] Member, Memq (@i[List Item])@\returns the first cons in
1469 the list @i[List] whose car is EQL to @i[Item]. If the = part of the
1470 EQL comparison bugs out, a Lisp-level Member function is called with
1471 the current cdr of the @i[List]. Memq returns the first cons in
1472 @i[List] whose car is EQ to the @i[Item].
1476 GetF (@i[List Indicator Default])@\searches for the @i[Indicator] in
1477 the list @i[List], cddring down as the Common Lisp form GetF would.
1478 If @i[Indicator] is found, its associated value is returned,
1479 otherwise @i[Default] is returned.
1482 @subsection [Symbol Manipulation]
1485 Most of the symbol manipulation miscops are compiled in-line rather than
1490 Get-Value (@i[Symbol])@\returns the value of @i[Symbol] (which must be a
1491 symbol). An error is signalled if @i[Symbol] is unbound.
1494 Set-Value (@i[Symbol Value])@\sets the value cell of the symbol @i[Symbol] to
1495 @i[Value]. @i[Value] is returned.
1497 @index [Get-Definition]
1498 Get-Definition (@i[Symbol])@\returns the definition of the symbol
1499 @i[Symbol]. If @i[Symbol] is undefined, an error is signalled.
1501 @index [Set-Definition]
1502 Set-Definition (@i[Symbol Definition])@\sets the definition of the symbol
1503 @i[Symbol] to @i[Definition]. @i[Definition] is returned.
1506 Get-Plist (@i[Symbol])@\returns the property list of the symbol @i[Symbol].
1509 Set-Plist (@i[Symbol Plist])@\sets the property
1510 list of the symbol @i[Symbol] to
1511 @i[Plist]. @i[Plist] is returned.
1514 Get-Pname (@i[Symbol])@\returns the print name of the symbol @i[Symbol].
1516 @index [Get-Package]
1517 Get-Package (@i[Symbol])@\returns the package cell of the symbol @i[Symbol].
1519 @index [Set-Package]
1520 Set-Package (@i[Symbol Package])@\sets the package cell of the symbol
1521 @i[Symbol] to @i[Package]. @i[Package] is returned.
1524 Boundp (@i[Symbol])@\sets the eq condition code bit to 1 if the symbol
1525 @i[Symbol] is bound; sets it to 0 otherwise.
1528 FBoundp (@i[Symbol])@\sets the eq condition code bit to 1 if the symbol
1529 @i[Symbol] is defined; sets it to 0 otherwise.
1532 Get (@i[Symbol] @i[Indicator] @i[Default])@\searches the property list of
1533 @i[Symbol] for @i[Indicator] and returns the associated value. If
1534 @i[Indicator] is not found, @i[Default] is returned.
1537 Put (@i[Symbol] @i[Indicator] @i[Value])@\searches the property list of
1538 @i[Symbol] for @i[Indicator] and replaces the associated value with @i[Value].
1539 If @i[Indicator] is not found, the @i[Indicator] @i[Value] pair are consed onto
1540 the front of the property list.
1543 @subsection [Array Manipulation]
1546 Common Lisp arrays have many manifestations in CMU Common Lisp. The CMU
1547 Common Lisp data types Bit-Vector, Integer-Vector, String, General-Vector,
1548 and Array are used to implement the collection of data types the Common
1549 Lisp manual calls ``arrays.''
1551 In the following miscop descriptions, ``simple-array'' means an array
1552 implemented in CMU Common Lisp as a Bit-Vector, I-Vector, String, or
1553 G-Vector. ``Complex-array'' means an array implemented as a CMU Common Lisp
1554 Array object. ``Complex-bit-vector'' means a bit-vector implemented as a
1555 CMU Common Lisp array; similar remarks apply for ``complex-string'' and so
1559 @index [Vector-Length] @index [G-Vector-Length] @index
1560 [Simple-String-Length] @index [Simple-Bit-Vector-Length] Vector-Length
1561 (@i[Vector])@\returns the length of the one-dimensional Common Lisp array
1562 @i[Vector]. G-Vector-Length, Simple-String-Length, and
1563 Simple-Bit-Vector-Length return the lengths of G-Vectors, CMU Common Lisp
1564 strings, and CMU Common Lisp Bit-Vectors respectively. @i[Vector] should
1565 be a vector of the appropriate type.
1567 @index [Get-Vector-Subtype]
1568 Get-Vector-Subtype (@i[Vector])@\returns the subtype field of the vector
1569 @i[Vector] as an integer. @i[Vector] should be a vector of some sort.
1571 @index [Set-Vector-Subtype]
1572 Set-Vector-Subtype (@i[Vector A])@\sets the subtype field of the vector
1573 @i[Vector] to @i[A], which must be a fixnum.
1575 @index [Get-Vector-Access-Code]
1576 Get-Vector-Access-Code (@i[Vector])@\returns the access code of the I-Vector
1577 (or Bit-Vector) @i[Vector] as a fixnum.
1579 @index [Shrink-Vector]
1580 Shrink-Vector (@i[Vector Length])@\sets the length field and the
1581 number-of-entries field of the vector @i[Vector] to @i[Length]. If the vector
1582 contains Lisp objects, entries beyond the new end are set to Trap.
1583 Returns the shortened vector. @i[Length] should be a fixnum. One cannot
1584 shrink array headers or function headers.
1587 Typed-Vref (@i[A Vector I])@\returns the @i[I]'th element of the I-Vector
1588 @i[Vector] by indexing into it as if its access-code were @i[A]. @i[A] and
1589 @i[I] should be fixnums.
1592 Typed-Vset (@i[A Vector I Value])@\sets the @i[I]'th element of the I-Vector
1593 @i[Vector] to @i[Value] indexing into @i[Vector] as if its access-code were
1594 @i[A]. @i[A], @i[I], and @i[Value] should be fixnums. @i[Value] is returned.
1596 @index [Header-Length]
1597 Header-Length (@i[Object])@\returns the number of Lisp objects in the header of
1598 the function or array @i[Object]. This is used to find the number of
1599 dimensions of an array or the number of constants in a function.
1602 Header-Ref (@i[Object I])@\returns the @i[I]'th element of the function or
1603 array header @i[Object]. @i[I] must be a fixnum.
1606 Header-Set (@i[Object I Value])@\sets the @i[I]'th element of the function of
1607 array header @i[Object] to @i[Value], and pushes @i[Value]. @i[I] must be a
1611 The names of the miscops used to reference and set elements of arrays are
1612 based somewhat on the Common Lisp function names. The SVref, SBit, and SChar
1613 miscops perform the same operation as their Common Lisp namesakes --
1614 referencing elements of simple-vectors, simple-bit-vectors, and simple-strings
1615 respectively. Aref1 references any kind of one dimensional array.
1616 The names of setting functions are derived by replacing ``ref'' with ``set'',
1617 ``char'' with ``charset'', and ``bit'' with ``bitset.''
1624 Aref1, SVref, SChar, SBit (@i[Array I])@\returns the @i[I]'th element of the
1626 array @i[Array]. SVref pushes an element of a G-Vector; SChar an element of a
1627 string; Sbit an element of a Bit-Vector. @i[I] should be a fixnum.
1633 Aset1, SVset, SCharset, SBitset (@i[Array I Value])@\sets the @i[I]'th element
1634 of the one-dimensional
1635 array @i[Array] to @i[Value]. SVset sets an element of a G-Vector; SCharset an
1636 element of a string; SBitset an element of a Bit-Vector. @i[I] should be a
1637 fixnum and @i[Value] is returned.
1641 CAref2, CAref3 (@i[Array I1 I2])@\returns the element (@i[I1], @i[I2]) of the
1642 two-dimensional array @i[Array]. @i[I1] and @i[I2] should be
1643 fixnums. CAref3 pushes the element (@i[I1], @i[I2], @i[I3]).
1647 CAset2, CAset3 (@i[Array I1 I2 Value]) @\sets the element (@i[I1], @i[I2]) of
1648 the two-dimensional array @i[Array] to @i[Value] and returns @i[Value].
1649 @i[I1] and @i[I2] should be fixnums. CAset3 sets the element (@i[I1], @i[I2],
1653 Bit-Bash (@i[V1 V2 V3 Op])@\@i[V1], @i[V2], and @i[V3] should be bit-vectors
1654 and @i[Op] should be a fixnum. The elements of the bit vector @i[V3] are
1655 filled with the result of @i[Op]'ing the corresponding elements of @i[V1] and
1656 @i[V2]. @i[Op] should be a Boole-style number (see the Boole miscop in
1657 section @ref[Boole-Section]).
1660 The rest of the miscops in this section implement special cases of sequence or
1661 string operations. Where an operand is referred to as a string, it may
1662 actually be an 8-bit I-Vector or system area pointer.
1666 Byte-BLT (@i[Src-String Src-Start Dst-String Dst-Start Dst-End])@\
1667 moves bytes from @i[Src-String] into @i[Dst-String] between @i[Dst-Start]
1668 (inclusive) and @i[Dst-End] (exclusive). @i[Dst-Start] - @i[Dst-End] bytes are
1669 moved. If the substrings specified overlap, ``the right thing happens,'' i.e.
1670 all the characters are moved to the right place. This miscop corresponds
1671 to the Common Lisp function REPLACE when the sequences are simple-strings.
1673 @index [Find-Character]
1674 Find-Character (@i[String Start End Character])@\
1675 searches @i[String] for the @i[Character] from @i[Start] to @i[End]. If the
1676 character is found, the corresponding index into @i[String] is returned,
1677 otherwise NIL is returned. This miscop corresponds to the Common Lisp
1678 function FIND when the sequence is a simple-string.
1680 @index [Find-Character-With-Attribute]
1681 Find-Character-With-Attribute (@i[String Start End Table Mask])@\
1682 The codes of the characters of @i[String] from @i[Start] to @i[End] are used as
1683 indices into the @i[Table], which is an I-Vector of 8-bit bytes. When the
1684 number picked up from the table bitwise ANDed with @i[Mask] is non-zero, the
1685 current index into the @i[String] is returned.
1687 @index [SXHash-Simple-String]
1688 SXHash-Simple-String (@i[String Length])@\Computes the hash code of the first
1689 @i[Length] characters of @i[String] and pushes it on the stack. This
1690 corresponds to the Common Lisp function SXHASH when the object is a
1691 simple-string. The @i[Length] operand can be Nil, in which case the length of
1692 the string is calculated in assembler.
1695 @subsection [Type Predicates]
1698 Many of the miscops described in this sub-section can be coded in-line rather
1699 than as miscops. In particular, all the predicates on basic types are coded
1700 in-line with default optimization settings in the compiler. Currently, all of
1701 these predicates set the eq condition code bit to return an indication of
1702 whether the predicate is true or false. This is so that the
1703 @value(DinkyMachine) branch instructions can be used directly without having to
1704 test for NIL. However, this only works if the value of the predicate is needed
1705 for a branching decision. In the cases where the value is actually needed, T
1706 or NIL is generated in-line according to whether the predicate is true or
1707 false. At some point it might be worthwhile having two versions of these
1708 predicates, one which sets the eq condition code bit, and one which returns T
1709 or NIL. This is especially true if space becomes an issue.
1712 @index [Bit-Vector-P]
1713 Bit-Vector-P (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is
1714 a Common Lisp bit-vector or 0 if it is not.
1716 @index [Simple-Bit-Vector-P]
1717 Simple-Bit-Vector-P (@i[Object])@\sets the eq condition code bit to 1 if
1718 @i[Object] is a CMU Common Lisp bit-vector or 0 if it is not.
1720 @index [Simple-Integer-Vector-P]
1721 Simple-Integer-Vector-P (@i[Object])@\sets the eq condition code bit to 1
1722 if @i[Object] is a CMU Common Lisp I-Vector or 0 if it is not.
1725 StringP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1726 Common Lisp string or 0 if it is not.
1728 @index [Simple-String-P]
1729 Simple-String-P (@i[Object])@\sets the eq condition code bit to 1 if
1730 @i[Object] is a CMU Common Lisp string or 0 if it is not.
1733 BignumP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1734 bignum or 0 if it is not.
1736 @index [Long-Float-P]
1737 Long-Float-P (@i[Object])@\sets the eq condition code bit to 1 if
1738 @i[Object] is a long-float or 0 if it is not.
1741 ComplexP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1742 complex number or 0 if it is not.
1745 RatioP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1746 ratio or 0 if it is not.
1749 IntegerP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1750 fixnum or bignum or 0 if it is not.
1753 RationalP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1754 fixnum, bignum, or ratio or 0 if it is not.
1757 FloatP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1758 short-float or long-float or 0 if it is not.
1761 NumberP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1762 number or 0 if it is not.
1764 @index [General-Vector-P]
1765 General-Vector-P (@i[Object])@\sets the eq condition code bit to 1 if
1766 @i[Object] is a Common Lisp general vector or 0 if it is not.
1768 @index [Simple-Vector-P]
1769 Simple-Vector-P (@i[Object])@\sets the eq condition code bit to 1 if @i[Object]
1770 is a CMU Common Lisp G-Vector or 0 if it is not.
1772 @index [Compiled-Function-P]
1773 Compiled-Function-P (@i[Object])@\sets the eq condition code bit to 1 if
1774 @i[Object] is a compiled function or 0 if it is not.
1777 ArrayP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1778 Common Lisp array or 0 if it is not.
1781 VectorP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1782 Common Lisp vector of 0 if it is not.
1784 @index [Complex-Array-P]
1785 Complex-Array-P (@i[Object])@\sets the eq condition code bit to 1 if @i[Object]
1786 is a CMU Common Lisp array or 0 if it is not.
1789 SymbolP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1790 symbol or 0 if it is not.
1793 ListP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a cons
1794 or NIL or 0 if it is not.
1797 ConsP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a cons
1801 FixnumP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is a
1802 fixnum or 0 if it is not.
1804 @index [Single-Float-P]
1805 Single-Float-P (@i[Object])@\sets the eq condition code bit to 1 if @i[Object]
1806 is a single-float or 0 if it is not.
1809 CharacterP (@i[Object])@\sets the eq condition code bit to 1 if @i[Object] is
1810 a character or 0 if it is not.
1813 @subsection [Arithmetic]
1817 @index [Integer-Length]
1818 Integer-Length (@i[Object])@\returns the integer-length (as defined in the
1819 Common Lisp manual) of the integer @i[Object].
1822 Logcount (@i[Object])@\returns the number of 1's if @i[object] is a
1823 positive integer, the number of 0's if @i[object] is a negative integer,
1824 and signals an error otherwise.
1826 @index [Float-Short]
1827 Float-Short (@i[Object])@\returns a short-float corresponding to the number
1831 Float-Long (@i[Number])@\returns a long float formed by coercing @i[Number] to
1832 a long float. This corresponds to the Common Lisp function Float when given a
1833 long float as its second argument.
1836 Realpart (@i[Number])@\returns the realpart of the @i[Number].
1839 Imagpart (@i[Number])@\returns the imagpart of the @i[Number].
1842 Numerator (@i[Number])@\returns the numerator of the rational @i[Number].
1844 @index [Denominator]
1845 Denominator (@i[Number])@\returns the denominator of the rational @i[Number].
1847 @index [Decode-Float]
1848 Decode-Float (@i[Number])@\performs the Common Lisp Decode-Float function,
1851 @index [Scale-Float]
1852 Scale-Float (@i[Number X])@\performs the Common Lisp Scale-Float function,
1853 returning the result.
1856 = (@i[X Y])@\sets the condition codes according to whether @i[X] is equal
1857 to @i[Y]. Both @i[X] and @i[Y] must be numbers, otherwise an error is
1858 signalled. If a rational is compared with a flonum, the rational is
1859 converted to a flonum of the same type first. If a short flonum is compared
1860 with a long flonum, the short flonum is converted to a long flonum.
1861 Flonums must be exactly equal (after conversion) for the condition codes to
1862 be set to equality. This miscop also deals with complex numbers.
1865 Compare (@i[X Y])@\sets the condition codes according to
1866 whether @i[X] is less than, equal to, or greater than @i[Y]. @i[X]
1867 and @i[Y] must be numbers. Conversions as described in = above are done
1868 as necessary. This miscop replaces the < and > instructions on the Perq,
1869 so that the branch on condition instructions can be used more
1870 effectively. The value of < and > as defined for the Perq are
1871 only generated if necessary, i.e., the result is saved. If @i[X] or @i[Y]
1872 is a complex number, an error is signalled.
1875 Truncate (@i[N X])@\performs the Common Lisp TRUNCATE operation. There are 3
1876 cases depending on @i[X]:
1878 If @i[X] is fixnum 1, return two items: a fixnum or bignum
1879 representing the integer part of @i[N] (rounded toward 0), then either 0 if
1880 @i[N] was already an integer or the fractional part of @i[N] represented as a
1881 flonum or ratio with the same type as @i[N].
1883 If @i[X] and @i[N] are both fixnums or bignums and @i[X] is not 1, divide
1884 @i[N] by @i[X]. Return two items: the integer quotient (a fixnum or
1885 bignum) and the integer remainder.
1887 If either @i[X] or @i[N] is a flonum or ratio, return a fixnum or bignum
1888 quotient (the true quotient rounded toward 0), then a flonum or ratio
1889 remainder. The type of the remainder is determined by the same type-coercion
1890 rules as for +. The value of the remainder is equal to @i[N] - @i[X] *
1893 On the @value(DinkyMachine), the integer part is returned in register A0, and
1894 the remainder in A1.
1900 +, -, *, / (@i[N X])@\returns @i[N] + @i[X]. -, *, and / are similar.
1902 @index [Fixnum*Fixnum]
1903 @index [Fixnum/Fixnum]
1904 Fixnum*Fixnum, Fixnum/Fixnum (@i[N X])@\returns @i[N] * @i[X], where
1905 both @i[N] and @i[X] are fixnums. Fixnum/ is similar.
1908 1+ (@i[E])@\returns @i[E] + 1.
1911 1- (@i[E])@\returns @i[E] - 1.
1914 Negate (@i[N])@\returns -@i[N].
1917 Abs (@i[N])@\returns |@i[N]|.
1920 GCD (@i[N X])@\returns the greatest common divisor of the integers @i[N] and @i[X].
1925 Logand (@i[N X])@\returns the bitwise and of the integers @i[N] and @i[X].
1926 Logior and Logxor are analogous.
1929 Lognot (@i[N])@\returns the bitwise complement of @i[N].
1932 @label [Boole-Section]
1933 Boole (@i[Op X Y])@\performs the Common Lisp Boole operation @i[Op] on @i[X],
1934 and @i[Y]. The Boole constants for CMU Common Lisp are these:
1935 @begin [verbatim, group]
1955 Ash (@i[N X])@\performs the Common Lisp ASH operation on @i[N] and @i[X].
1958 Ldb (@i[S P N])@\All args are integers; @i[S] and @i[P] are non-negative.
1959 Performs the Common Lisp LDB operation with @i[S] and @i[P] being the size and
1960 position of the byte specifier.
1963 Mask-Field (@i[S P N])@\performs the Common Lisp Mask-Field operation with
1964 @i[S] and @i[P] being the size and position of the byte specifier.
1967 Dpb (@i[V S P N])@\performs the Common Lisp DPB operation with @i[S] and @i[P]
1968 being the size and position of the byte specifier.
1970 @index [Deposit-Field]
1971 Deposit-Field (@i[V S P N])@\performs the Common Lisp Deposit-Field operation
1972 with @i[S] and @i[P] as the size and position of the byte specifier.
1975 Lsh (@i[N X])@\returns a fixnum that is @i[N] shifted left by @i[X] bits, with
1976 0's shifted in on the right. If @i[X] is negative, @i[N] is shifted to the
1977 right with 0's coming in on the left. Both @i[N] and @i[X] should be fixnums.
1980 Logldb (@i[S P N])@\All args are fixnums. @i[S] and @i[P] specify a ``byte''
1981 or bit-field of any length within @i[N]. This is extracted and is returned
1982 right-justified as a fixnum. @i[S] is the length of the field in bits; @i[P]
1983 is the number of bits from the right of @i[N] to the beginning of the
1984 specified field. @i[P] = 0 means that the field starts at bit 0 of @i[N], and
1985 so on. It is an error if the specified field is not entirely within the 26
1989 Logdpb (@i[V S P N])@\All args are fixnums. Returns a number equal to @i[N],
1990 but with the field specified by @i[P] and @i[S] replaced by the @i[S] low-order
1991 bits of @i[V]. It is an error if the field does not fit into the 26 bits of
1994 @index[Sin]@index[Cos]@index[Tan]@index[Atan]
1995 Sin(@i[X]), Cos(@i[X]), Tan(@i[X]), and Atan(@i[X])@\accept a single number
1996 @i[X] as argument and return the sine, cosine, tangent, and arctangent of
1997 the number respectively. These miscops take advantage of the hardware
1998 support provided on the IBM RT PC if it is available, otherwise they escape
1999 to Lisp code to calculate the appropriate result.
2002 Log(@i[X])@\returns the natural log of the number @i[X]. This miscop uses
2003 the hardware operation if it is available, otherwise it escapes to Lisp
2004 code to calculate the result.
2007 Exp(@i[X])@\returns e raised to the power @i[X]. This miscop uses the
2008 hardware operation if it is available, otherwise it escapes to Lisp code to
2009 calculate the result.
2012 Sqrt(@i[X])@\returns the square root of @i[X]. This miscop uses the
2013 hardware operation if it is available, otherwise it escapes to Lisp code to
2014 calculate the result.
2017 @subsection [Branching]
2018 All branching is done with @value(DinkyMachine) branch instructions.
2019 Instructions are generated to set the condition code bits appropriately, and
2020 a branch which tests the appropriate condition code bit is generated.
2022 @subsection [Function Call and Return]
2027 Call()@\A call frame for a function is opened. This is explained in
2028 more detail in the next chapter.
2031 Call-0 (@i[F])@\@i[F] must be an executable function, but is a
2032 function of 0 arguments. Thus, there is no need to collect arguments. The
2033 call frame is opened and activated in a single miscop.
2035 @index [Call-Multiple]
2036 Call-Multiple ()@\Just like a Call miscop, but it marks the frame
2037 to indicate that multiple values will be accepted. See
2038 section @ref[Multi].
2040 @index[Set-Up-Apply-Args]
2041 Set-Up-Apply-Args ()@\is called to handle the last argument of a
2042 function called by apply. All the other arguments will have been
2043 properly set up by this time. Set-up-apply-args places the values of
2044 the list passed as the last argument to apply in their proper
2045 locations, whether they belong in argument registers or on the stack.
2046 It updates the NArgs register with the actual count of the arguments
2047 being passed to the function. When Set-up-apply-args returns, all the
2048 arguments to the function being applied are in their correct
2049 locations, and the function can be invoked normally.
2051 @index[Start-Call-Interpreter]
2052 Start-Call-Interpreter (@i[NArgs])@\is called from the interpreter to
2053 start a function call. It accepts the number of arguments that are
2054 pushed on the stack in register A0. Just below the arguments is the
2055 function to call; just below the function is the area to store the
2056 preserved registers. This miscop sets up the argument registers
2057 correctly, moves any other arguments down on the stack to their
2058 proper place, and invokes the function.
2061 Invoke1 (@i[Function] @i[Argument])@\is similar to Start-Call-Interpreter,
2062 but is simpler, since the @i[Function] is being called with only a
2063 single @i[Argument].
2066 Invoke1* (@i[Function] @i[Argument])@\is similar to Invoke1, but the
2067 @i[Function] being called is called for one value, rather than multiple ones.
2069 @index [Start-call-mc]
2070 Start-call-mc ()@\is called when the compiler generates code for the
2071 form multiple-value-call. Register A0 contains the function to be
2072 called, A1 contains a 0 if the call if for a single value, and 1
2073 otherwise, NArgs contains the number of arguments that are stored on
2074 the stack. The argument registers are set up correctly, and the
2075 excess values moved down on the stack if necessary. Finally, the
2076 function is actually invoked.
2079 Push-Last ()@\closes the currently open call frame, and initiates a function
2083 Return (@i[X])@\Return from the current function call. After the current
2084 frame is popped off the stack, @i[X] is returned in register A0 as the result
2085 Being returned. See section @ref[Return] for more details.
2087 @index [Return-From]
2088 Return-From (@i[X] @i[F])@\is similar to Return, except it accepts the frame
2089 to return from as an additional argument.
2091 @index [Return-1-Value-Any-Bind]
2092 Return-1-Value-Any-Bind (@i[X])@\is similar to return, except only
2093 one value is returned. Any number of bindings are undone during the
2096 @index [Return-Mult-Value-0-Bind]
2097 Return-Mult-Value-0-Bind (@i[X])@\is similar to return, except multiple values
2098 may be returned, but the binding stack does not have to be popped.
2100 @index [Link-Address-Fixup]
2101 Link-Address-Fixup (@i[Symbol NArgs Code-Vector Offset])@\finds the
2102 correct link table entry for @i[Symbol] with @i[NArgs] (@i[NArgs]
2103 specifies the fixed number of arguments and a flag if more may be
2104 passed). It smashes the @i[Code-Vector] at @i[Offset] to generate
2105 code to point at the absolute address of the link table entry.
2107 @index [Miscop-Fixup]
2108 Miscop-Fixup (@i[Code-Vector Offset Index])@\smashes @i[Code-Vector] at
2109 @i[Offset] with the correct value for the miscop specified by @i[Index] in a
2110 transfer vector of all the miscops.
2112 @index [Make-Compiled-Closure]
2113 Make-Compiled-Closure (@i[env fcn offset])@\returns a new function object
2114 that is a copy of the function object @i[fcn] which has the @i[env]
2115 information stored at @i[offset]. Compiled lexical closures are now
2116 represented as real function objects rather than as lists. This miscop is
2117 necessary to support this change.
2119 @index [Reset-link-table]
2120 Reset-link-table (@i[function])@\resets all the link table entries for
2121 @i[function] to the default action. This is necessary because Portable
2122 Commonloops updates generic function objects by copying new information
2123 into the function object. The link table must be updated to reflect this
2124 or the wrong function will be called.
2126 @index[Interrupt-Handler]
2128 Interrupt-Handler (@i[Signal Code Signal-Context])@\gets the first
2129 indication that a Unix signal has occurred. This miscop does not follow
2130 the normal Lisp calling conventions at all. Instead it follows the
2131 standard IBM RT PC calling conventions for C or other algorithmic
2132 languages. On entry the registers are as follows:
2134 R0@\Pointer to C data area for Interrupt-Handler. Currently this data area
2135 only holds a pointer to the entry point for Interrupt-Handler and nothing
2138 R1@\Pointer to a C stack that contains information about the signal.
2140 R2@\Contains the @i[Signal] number that caused the interrupt to happen.
2142 R3@\Contains the @i[Code] that further specifies what caused the interrupt
2145 R4@\Contains a pointer to the @i[signal-context] which contains
2146 information about where the interrupt occurred, the saved registers, etc.
2148 R5-R14@\Contain unknown values.
2150 R15@\is the return PC which will return from the interrupt handler and
2151 restart the computation.
2153 Interrupt-Handler determines whether it is safe to take the interrupt now,
2154 i.e., it is executing in Lisp code, C code, or an interruptible miscop. An
2155 interruptible miscop is one that has been specially written to make sure
2156 that it is safe to interrupt it at any point and is possible that it will
2157 never return of its own accord (e.g., length which could be passed a
2158 circular list, some of the system call miscops, etc.). If it is safe to
2159 take the interrupt, the signal-context is modified so that control will
2160 transfer to the miscop interrupt-routine when the interrupt-handler returns
2161 normally (i.e., after the kernel has done the necessary bookkeeping). If
2162 it is unsafe to take the interrupt (i.e., it is executing in an
2163 non-interruptible miscop), then the return PC of the miscop is modified to
2164 be interrupt-routine and interrupt-handler returns to the kernel. In
2165 either case interrupts are disabled and information is stored in a global
2166 Lisp data area, so that the interrupt-routine miscop can retrieve the
2167 important information about the interrupt.
2170 Interrupt-Routine ()@\gets control when it is safe to take an interrupt.
2171 It saves the current state of the computation on the appropriate stack (on
2172 the C stack if it was executing in C or on the Lisp stack if in Lisp)
2173 including all the registers, some control information specifying whether
2174 the computation was in C code, Lisp code, whether it should form a PC in
2175 register R15. When a PC has to be formed in R15, R14 will contain a pointer
2176 to the active function and R15 will contain an index into the code vector
2177 associated with the active function. Reforming the PC is necessary so
2178 it is possible to restart a computation even after a garbage collection
2179 may have moved the function. Once this information is stored,
2180 interrupt-routine invokes the Lisp function %sp-software-interrupt-routine
2181 which moves the processing of the interrupt to Lisp code.
2183 @index [Break-Return]
2184 Break-Return (@i[])@\returns from a function called by the
2185 interrupt-routine miscop. The only function that should ever do this is
2186 %sp-software-interrupt-routine. This miscop expects the stack to be in a
2187 format that is generated during an interrupt and should not be used for
2191 Catch (@i[Tag PC])@\builds a catch frame. @i[Tag] is the tag caught by this
2192 catch frame, @i[PC] is a saved-format PC (i.e., an index into the current code
2193 vector). See section @ref[Catch] for details.
2195 @index [Catch-Multiple]
2196 Catch-Multiple (@i[Tag PC])@\builds a multiple-value catch frame. @i[Tag] is
2197 the tag caught by this catch frame, and @i[PC] is a saved-format PC. See
2198 section @ref[Catch] for details.
2201 Catch-All (@i[PC])@\builds a catch frame whose tag is the special Catch-All
2202 object. @i[PC] is the saved-format PC, which is the address to branch to if
2203 this frame is thrown through. See section @ref[Catch] for details.
2206 Throw (@i[X Tag])@\@i[Tag] is the throw-tag, normally a symbol. @i[X] is the
2207 value to be returned. See section @ref[Catch] for a description of how this
2210 @index[Rest-Entry-0]@index[Rest-Entry-1]@index[Rest-Entry-2]@index[Rest-Entry]
2211 Rest-Entry-0, Rest-Entry-1, Rest-Entry-2, Rest-Entry@\are miscops
2212 that do the processing for a function at its &rest entry point.
2213 Rest-Entry-@i[i] are miscops that are invoked by functions that have
2214 0, 1, or 2 arguments before the &rest argument. Rest-entry is
2215 invoked for all other cases, and is passed an additional argument in
2216 A3 which is the number of non-&rest arguments. These miscops form
2217 the &rest arg list and set up all the registers to have the
2218 appropriate values. In particular, the non-&rest arguments are copied
2219 into preserved registers, and the &rest arg list is built and stored
2220 in the appropriate preserved register or on the stack as appropriate.
2222 @index[Call-Foreign]
2223 Call-Foreign (@i[C-Function Arguments NArgs])@\establishes the C
2224 environment so that C code can be called correctly. @i[C-Function] is a
2225 pointer to the data area for a C function, the first word of which is a
2226 pointer to the entry point of the C function. @i[Arguments] is a block of
2227 storage that contains the @i[NArgs] arguments to be passed to the C
2228 function. The first four of these arguments are passed in registers R2
2229 through R5 respectively, the rest are moved onto the C stack in the proper
2230 location. When the C function returns, Call-Foreign restores the Lisp
2231 environment and returns as its value the integer in R2.
2234 Call-Lisp (@i[Arg@-<1> ... Arg@-<2>])@\is a Lisp miscop that gets control
2235 when a C function needs to call a Lisp function. Lisp provides a mechanism
2236 for setting up an object that looks like a C procedure pointer. The code
2237 pointer in this object always points at Call-Lisp. Additional data in this
2238 procedure pointer is the Lisp function to call and the number of arguments
2239 that it should be called with. Call-Lisp restores the Lisp environment,
2240 saves the state of the C computation, moves the C arguments into the
2241 correct places for a call to a Lisp function and then invokes the special
2242 Lisp function call-lisp-from-c. This Lisp function actually invokes the
2243 correct Lisp function. Call-Lisp never regains control.
2246 Return-To-C (@i[C-Stack-Pointer Value])@\is used in the
2247 function call-lisp-from-c to return control to C from a Lisp function
2248 called by C. @i[C-Stack-Pointer] is the C stack pointer when the call-lisp
2249 miscop got control. The C stack pointer argument is used to restore the C
2250 environment to what it was at the time the call to Lisp was made.
2251 @i[Value] is the value returned from Lisp and is passed back to C in
2252 register R2. Currently, it is not possible to return other than a single
2255 @index[Reset-C-Stack]
2256 Reset-C-Stack ()@\is invoked when a Lisp function called by C throws out
2257 past where it should return to C. Reset-C-Stack restores the C stack to
2258 what it was before the original call to C happened. This is so that in the
2259 future, the C stack will not contain any garbage that should not be there.
2261 @index[Set-C-Procedure-Pointer]
2262 Set-C-Procedure-Pointer (@i[Sap] @i[I] @I[Proc])@\sets the @i[I/2]'th
2263 element of @i[sap] to be the data part of the statically allocated g-vector
2264 @i[Proc]. This is used to set up a C procedure argument in the argument
2265 block that is passed to call-foreign.
2269 @subsection [Miscellaneous]
2274 Eq (@i[X Y])@\sets the eq condition code bit to 1 if @i[X] and @i[Y] are the
2275 same object, 0 otherwise.
2278 Eql (@i[X Y])@\sets the eq condition code bit to 1 if @i[X] and @i[Y] are the
2280 @i[X] and @i[Y] are numbers of the same type with the same value, 0 otherwise.
2282 @index [Make-Predicate]
2283 Make-Predicate (@i[X])@\returns NIL if @i[X] is NIL or T if it is not.
2285 @index [Not-Predicate]
2286 Not-Predicate (@i[X])@\returns T if @i[X] is NIL or NIL if it is not.
2288 @index [Values-To-N]
2289 Values-To-N (@i[V])@\@i[V] must be a Values-Marker. Returns the number
2290 of values indicated in the low 24 bits of @i[V] as a fixnum.
2292 @index [N-To-Values]
2293 N-To-Values (@i[N])@\@i[N] is a fixnum. Returns a Values-Marker with the
2294 same low-order 24 bits as @i[N].
2296 @index [Force-Values]
2297 Force-Values (@i[VM])@\If the @i[VM] is a Values-Marker, do
2298 nothing; if not, push @i[VM] and return a Values-Marker 1.
2300 @index [Flush-Values]
2301 Flush-Values (@i[])@\is a no-op for the @value(DinkyMachine), since the only
2302 time that a Flush-Values miscop is generated is in some well-defined cases
2303 where all the values are wanted on the stack.
2306 @subsection [System Hacking]
2307 @label [System-Hacking-Instructions]
2312 Get-Type (@i[Object])@\returns the five type bits of the @i[Object] as a
2316 Get-Space (@i[Object])@\returns the two space bits of @i[Object] as a
2319 @index [Make-Immediate-Type]
2320 Make-Immediate-Type (@i[X A])@\returns an object whose type bits are the
2321 integer @i[A] and whose other bits come from the immediate object or pointer
2322 @i[X]. @i[A] should be an immediate type code.
2324 @index [8bit-System-Ref]
2325 8bit-System-Ref (@i[X I])@\@i[X] must be a system area pointer, returns
2326 the @i[I]'th byte of @i[X], indexing into @i[X] directly. @i[I]
2329 @index [8bit-System-Set]
2330 8bit-System-Set (@i[X I V])@\@i[X] must be a system area pointer, sets the
2331 @i[I]'th element of @i[X] to @i[V], indexing into @i[X] directly.
2333 @index [16bit-System-Ref]
2334 16bit-System-Ref (@i[X I])@\@i[X] must be a system area pointer, returns the
2335 @i[I]'th 16-bit word of @i[X], indexing into @i[X] directly.
2337 @index [Signed-16bit-System-Ref]
2338 Signed-16bit-System-Ref (@i[X I])@\@i[X] must be a system area pointer,
2339 returns the @i[I]'th 16-bit word of @i[X] extending the high order bit as
2342 @Index [16bit-System-Set]
2343 16bit-System-Set (@i[X I V])@\@i[X] must be a system area pointer, sets the
2344 @i[I]'th element of @i[X] to @i[V], indexing into @i[X] directly.
2346 @Index [Signed-32bit-System-Ref]
2347 Signed-32bit-System-Ref (@i[X I])@\@i[X] must be a system area pointer and
2348 @i[I] an even fixnum, returns the @i[I]/2'th 32 bit word as a signed
2351 @Index [Unsigned-32bit-System-Ref]
2352 Unsigned-32bit-System-Ref (@i[X I])@\@i[X] must be a system area pointer and
2353 @i[I] an even fixnum, returns the @i[I]/2'th 32 bit word as an unsigned
2356 @Index [Signed-32bit-System-Set]
2357 Signed-32bit-System-Set (@i[X I V])@\@i[X] must be a system area pointer,
2358 @i[I] an even fixnum, and @i[V] an integer, sets the @i[I]/2'th element of
2361 @index[Sap-System-Ref]
2362 Sap-System-Ref (@i[X I])@\@i[X] must be a system area pointer and @i[I] and
2363 even fixnum, returns the @i[I]/2'th element of @i[X] as a system area
2366 @index[Sap-System-Set]
2367 Sap-System-Set (@i[X I V])@\@i[X] and @i[V] must be a system area pointers
2368 and @i[I] an even fixnum, sets the @i[I]/2'th element of @i[X] to @i[V].
2370 @index[Pointer-System-Set]
2371 Pointer-System-Set (@i[X I])@\@i[X] must be a system area pointer, @i[I] an
2372 even fixnum, and @i[V] a pointer (either system area pointer or Lisp
2373 pointer), sets the @i[I]/2'th element of @i[X] to the pointer @i[V]. If
2374 the pointer is a Lisp pointer, the pointer stored is to the first word of
2375 data (i.e., the header word(s) are bypassed).
2378 Sap-Int (@i[X])@\@i[X] should be a system area pointer, returns a Lisp
2379 integer containing the system area pointer. This miscop is useful when it
2380 is necessary to do arithmetic on system area pointers.
2383 Int-Sap (@i[X])@\@i[X] should be an integer (fixnum or bignum), returns a
2384 system area pointer. This miscop performs the inverse operation of sap-int.
2387 Check-<= (@i[X] @i[Y])@\checks to make sure that @i[X] is less than or
2388 equal to @i[Y]. If not, then check-<= signals an error, otherwise it just
2391 @index [Collect-Garbage]
2392 Collect-Garbage (@i[])@\causes a stop-and-copy GC to be performed.
2395 Purify (@i[])@\is similar to collect-garbage, except it copies Lisp objects
2396 into static or read-only space. This miscop needs Lisp level code to get
2397 the process started by putting some root structures into the correct space.
2399 @index [Newspace-Bit]
2400 Newspace-Bit (@i[])@\returns 0 if newspace is currently space 0 or 1 if it is
2404 Save (@i[*current-alien-free-pointer*] @i[Checksum] @I[memory])@\Save takes
2405 a snap short of the current state of the Lisp computation. The value of
2406 the symbol *Current-alien-free-pointer* must be passed to save, so that it
2407 can save the static alien data structures. The parameter @i[checksum]
2408 specifies whether a checksum should be generated for the saved image.
2409 Currently, this parameter is ignored and no checksum is generated. The
2410 parameter @i[memory] should be be a pointer to a block of memory where the
2411 saved core image will be stored. Save returns the size of the core image
2420 Syscall0 Syscall1 Syscall2 Syscall3 Syscall4 Syscall (@i[number]
2421 @i[arg@-<1> ... arg@-<n>])@\is for making syscalls to the Mach kernel. The
2422 argument @i[number] should be the number of the syscall. Syscall0 accepts
2423 no arguments to the syscall; syscall1 accepts one argument to the syscall,
2424 etc. Syscall accepts five or more arguments to the syscall.
2427 Unix-Write (@i[fd buffer offset length])@\performs a Unix write syscall to
2428 the file descriptor @i[fd]. @i[Buffer] should contain the data to be
2429 written; @i[Offset] should be an offset into buffer from which to start
2430 writing; and @i[length] is the number of bytes of data to write.
2433 Unix-Fork ()@\performs a Unix fork operation returning one or two values.
2434 If an error occurred, the value -1 and the error code is returned. If no
2435 error occurred, 0 is returned in the new process and the process id of the
2436 child process is returned in the parent process.
2438 @index [Arg-In-Frame] Arg-In-Frame (@i[N F])@\@i[N] is a fixnum, @i[F] is a
2439 control stack pointer as returned by the Active-Call-Frame miscop. It
2440 returns the item in slot @i[N] of the args-and-locals area of call frame
2443 @index [Active-Call-Frame]
2444 Active-Call-Frame (@i[])@\returns a control-stack pointer to the start of the
2445 currently active call frame. This will be of type Control-Stack-Pointer.
2447 @index [Active-Catch-Frame]
2448 Active-Catch-Frame (@i[])@\returns the control-stack pointer to the start of
2449 the currently active catch frame. This is Nil if there is no active catch.
2451 @index [Set-Call-Frame]
2452 Set-Call-Frame (@i[P])@\@i[P] must be a control stack pointer. This becomes
2453 the current active call frame pointer.
2455 @index [Current-Stack-Pointer]
2456 Current-Stack-Pointer (@i[])@\returns the Control-Stack-Pointer that points
2457 to the current top of the stack (before the result of this operation is
2458 pushed). Note: by definition, this points to the
2459 to the last thing pushed.
2461 @index [Current-Binding-Pointer]
2462 Current-Binding-Pointer (@i[])@\returns a Binding-Stack-Pointer that points
2463 to the first word above the current top of the binding stack.
2465 @index [Read-Control-Stack]
2466 Read-Control-Stack (@i[F])@\@i[F] must be a control stack pointer. Returns
2467 the Lisp object that resides at this location. If the addressed object is
2468 totally outside the current stack, this is an error.
2470 @index [Write-Control-Stack]
2471 Write-Control-Stack (@i[F V])@\@i[F] is a stack pointer, @i[V] is any Lisp
2472 object. Writes @i[V] into the location addressed. If the addressed cell is
2473 totally outside the current stack, this is an error. Obviously, this should
2474 only be used by carefully written and debugged system code, since you can
2475 destroy the world by using this miscop.
2477 @index [Read-Binding-Stack]
2478 Read-Binding-Stack (@i[B])@\@i[B] must be a binding stack pointer. Reads and
2479 returns the Lisp object at this location. An error if the location specified
2480 is outside the current binding stack.
2482 @index [Write-Binding-Stack]
2483 Write-Binding-Stack (@i[B V])@\@i[B] must be a binding stack pointer. Writes
2484 @i[V] into the specified location. An error if the location specified is
2485 outside the current binding stack.
2488 @chapter [Control Conventions]
2489 @label [Control-Conventions]
2490 @index [Hairy stuff]
2492 @section [Function Calls]
2495 @index [Call-Multiple]
2497 On the Perq function calling is done by micro-coded instructions. The
2498 instructions perform a large number of operations, including determining
2499 whether the function being called is compiled or interpreted, determining that
2500 a legal number of arguments are passed, and branching to the correct entry
2501 point in the function. To do all this on the @value(DinkyMachine) would
2502 involve a large amount of computation. In the general case, it is necessary to
2503 do all this, but in some common cases, it is possible to short circuit most of
2506 To perform a function call in the general case, the following steps occur:
2509 Allocate space on the control stack for the fix-sized part of a call
2510 frame. This space will be used to store all the registers that must
2511 be preserved across a function call.
2513 Arguments to the function are now evaluated. The first three
2514 arguments are stored in the argument registers A0, A1, and A2. The
2515 rest of the arguments are stored on the stack as they are evaluated.
2516 Note that during the evaluation of arguments, the argument registers
2517 may be used and may have to be stored in local variables and restored
2518 just before the called function is invoked.
2520 Load R0 with the argument count.
2522 Load the PC register with the offset into the current code vector of
2523 the place to return to when the function call is complete.
2525 If this call is for multiple values, mark the frame as accepting
2526 multiple values, by making the fixnum offset above negative by oring
2527 in the negative fixnum type code.
2529 Store all the registers that must be preserved over the function call in the
2533 At this point, all the arguments are set up and all the registers have been
2534 saved. All the code to this point is done inline. If the object being called
2535 as a function is a symbol, we get the definition from the definition cell of
2536 the symbol. If this definition is the trap object, an undefined symbol error
2537 is generated. The function calling mechanism diverges at this point depending
2538 on the type of function being called, i.e., whether it is a compiled function
2541 If we have a compiled function object, the following steps are performed (this
2542 code is out of line):
2544 Load the active function register with a pointer to the compiled function
2547 The active frame register is set to the start of the current frame.
2549 Note the number of arguments evaluated. Let this be K. The correct
2550 entry point in the called function's code vector must be computed as
2551 a function of K and the number of arguments the called function
2553 @begin(Enumerate, spread 0, spacing 1)
2554 If K < minimum number of arguments, signal an error.
2556 If K > maximum number of arguments and there is no &rest argument,
2559 If K > maximum number of arguments and there is a &rest argument,
2560 start at offset 0 in the code vector. This entry point must collect
2561 the excess arguments into a list and leave the &rest argument in the
2562 appropriate argument register or on the stack as appropriate.
2564 If K is between the minimum and maximum arguments (inclusive), get
2565 the starting offset from the appropriate slot of the called
2566 function's function object. This is stored as a fixnum in slot K -
2567 MIN + 6 of the function object.
2570 Load one of the Non-Lisp temporary registers with the address of the
2571 code vector and add in the offset calculated above. Then do a branch
2572 register instruction with this register as the operand. The called
2573 function is now executing at the appropriate place.
2576 If the function being called is a list, %SP-Internal-Apply must be called to
2577 interpret the function with the given arguments. Proceed as follows:
2579 Note the number of arguments evaluated for the current open frame (call this N)
2580 and the frame pointer for the frame (call it F). Also remember the lambda
2581 expression in this frame (call it L).
2583 Load the active function register with the list L.
2585 Load the PC register with 0.
2587 Allocate a frame on the control stack for the call to %SP-Internal-Apply.
2589 Move the contents of the argument registers into the local registers L0, L1,
2590 and L2 respectively.
2592 Store all the preserved registers in the frame.
2594 Place N, F, and L into argument registers A0, A1, and A2 respectively.
2596 Do the equivalent of a start call on %SP-Internal-Apply.
2597 @end(Enumerate) %SP-Internal-Apply, a function of three arguments,
2598 now evaluates the call to the lambda-expression or interpreted
2599 lexical closure L, obtaining the arguments from the frame pointed to
2600 by F. The first three arguments must be obtained from the frame that
2601 %SP-Internal-Apply runs in, since they are stored in its stack frame
2602 and not on the stack as the rest of the arguments are. Prior to
2603 returning %SP-Internal-Apply sets the Active-Frame register to F, so
2604 that it returns from frame F.
2606 The above is the default calling mechanism. However, much of the
2607 overhead can be reduced. Most of the overhead is incurred by having
2608 to check the legality of the function call everytime the function is
2609 called. In many situations where the function being called is a
2610 symbol, this checking can be done only once per call site by
2611 introducing a data structure called a link table. The one exception
2612 to this rule is when the function apply is used with a symbol. In
2613 this situation, the argument count checks are still necessary, but
2614 checking for whether the function is a list or compiled function
2615 object can be bypassed.
2617 The link table is a hash table whose key is based on the name of the
2618 function, the number of arguments supplied to the call and a flag
2619 specifying whether the call is done through apply or not. Each entry
2620 of the link table consists of two words:
2622 The address of the function object associated with the symbol being
2623 called. This is here, so that double indirection is not needed to
2624 access the function object which must be loaded into the active
2625 function register. Initially, the symbol is stored in this slot.
2627 The address of the instruction in the function being called to start
2628 executing when this table entry is used. Initially, this points to
2629 an out of line routine that checks the legality of the call and
2630 calculates the correct place to jump to in the called function. This
2631 out of line routine replaces the contents of this word with the
2632 correct address it calculated. In the case when the call is caused
2633 by apply, this will often be an out of line routine that checks the
2634 argument count and calculates where to jump. In the case where the
2635 called function accepts &rest arguments and the minimum number of
2636 arguments passed is guaranteed to be greater than the maximum number
2637 of arguments, then a direct branch to the &rest arg entry point is
2641 When a compiled file is loaded into the lisp environment, all the
2642 entries for the newly loaded functions will be set to an out of line
2643 routine mentioned above. Also, during a garbage collection the
2644 entries in this table must be updated when a function object for a
2647 The @value(DinkyMachine) code to perform a function call using the link table
2650 cal CS,CS,%Frame-Size ; Alloc. space on control st.
2652 <Code to evaluate arguments to the function>
2654 cau NL1,0,high-half-word(lte(function nargs flag))
2655 oil NL1,0,low-half-word(lte(function nargs flag))
2656 cal PC,0,return-tag ; Offset into code vector.
2657 <oiu PC,PC,#xF800 ; Mark if call-multiple frame>
2658 stm L0,CS,-(%Frame-Size-4) ; Save preserved regs.
2659 lm AF,NL1,0 ; Link table entry contents.
2660 bnbrx pz,R15 ; Branch to called routine.
2661 cal FP,CS,-(%Frame-Size-4) ; Get pointer to frame.
2664 The first two instructions after the arguments are evaled get the
2665 address of the link table entry into a register. The two 16-bit half
2666 word entries are filled in at load time. The rest of the
2667 instructions should be fairly straight forward.
2669 @section(Returning from a Function Call)
2673 Returning from a function call on the Perq is done by a micro-coded
2674 instruction. On the @value(DinkyMachine), return has to do the following:
2676 Pop the binding stack back to the binding stack pointer stored in the frame
2677 we're returning from. For each symbol/value pair popped of the binding stack,
2678 restore that value for the symbol.
2680 Save the current value of the frame pointer in a temporary registers. This
2681 will be used to restore the control stack pointer at the end.
2683 Restore all the registers that are preserved across a function call.
2685 Get a pointer to the code vector for the function we're returning to. This is
2686 retrieved from the code slot of what is now the active function.
2688 Make sure the relative PC (which is now in a register) is positive and add it
2689 to the code vector pointer above, giving the address of the instruction to
2692 If the function is returning multiple values do a block transfer of all the
2693 return values down over the stack frame just released, i.e., the first return
2694 value should be stored where the temporarily saved frame pointer points to.
2695 In effect the return values can be pushed onto the stack using the saved frame
2696 pointer above as a stack pointer that is incremented everytime a value is
2697 pushed. Register A0 can be examined to determine the number of values that
2698 must be transferred.
2700 Set the control stack register to the saved frame pointer above. NB: it may
2701 have been updated if multiple values are being returned.
2703 Resume execution of the calling function.
2706 Again, it is not always necessary to use the general return code. At compile
2707 time it is often possible to determine that no special symbols have to be
2708 unbound and/or only one value is being returned. For example the code to
2709 perform a return when only one value is returned and it is unnecessary to
2710 unbind any special symbols is:
2712 cas NL1,FP,0 ; Save frame register.
2713 lm L0,FP,0 ; Restore all preserved regs.
2714 ls A3,AF,%function-code ; Get pointer to code vector.
2715 niuo PC,PC,#x07FF ; Make relative PC positive.
2716 cas PC,A3,PC ; Get addr. of instruction
2717 bnbrx pz,PC ; to return to and do so while
2718 cas CS,NL1,0 ; updating control stack reg.
2722 @subsection [Returning Multiple-Values]
2724 @index [Multiple values]
2726 If the current frame can accept multiple values and a values marker is in
2727 register A0 indicating N values on top of the stack, it is necessary to copy
2728 the N return values down to the top of the control stack after the current
2729 frame is popped off. Thus returning multiple values is similar to the
2730 above, but a block transfer is necessary to move the returned values down to
2731 the correct location on the control stack.
2733 In tail recursive situations, such as in the last form of a PROGN, one
2734 function, FOO, may want to call another function, BAR, and return ``whatever
2735 BAR returns.'' Call-Multiple is used in this case. If BAR returns multiple
2736 values, they will all be passed to FOO. If FOO's caller wants multiple values,
2737 the values will be returned. If not, FOO's Return instruction will see that
2738 there are multiple values on the stack, but that multiple values will not be
2739 accepted by FOO's caller. So Return will return only the first value.
2741 @section [Non-Local Exits]
2745 @index [Catch-All object]
2746 @index [Unwind-Protect]
2747 @index [Non-Local Exits]
2749 The Catch and Unwind-Protect special forms are implemented using
2750 catch frames. Unwind-Protect builds a catch frame whose tag is the
2751 Catch-All object. The Catch miscop creates a catch frame for a
2752 given tag and PC to branch to in the current instruction. The Throw
2753 miscop looks up the stack by following the chain of catch frames
2754 until it finds a frame with a matching tag or a frame with the
2755 Catch-All object as its tag. If it finds a frame with a matching
2756 tag, that frame is ``returned from,'' and that function is resumed.
2757 If it finds a frame with the Catch-All object as its tag, that frame
2758 is ``returned from,'' and in addition, %SP-Internal-Throw-Tag is set
2759 to the tag being searched for. So that interrupted cleanup forms
2760 behave correctly, %SP-Internal-Throw-Tag should be bound to the
2761 Catch-All object before the Catch-All frame is built. The protected
2762 forms are then executed, and if %SP-Internal-Throw-Tag is not the
2763 Catch-All object, its value is thrown to. Exactly what we do is
2766 Put the contents of the Active-Catch register into a register, A.
2767 Put NIL into another register, B.
2769 If A is NIL, the tag we seek isn't on the stack. Signal an
2770 Unseen-Throw-Tag error.
2772 Look at the tag for the catch frame in register A. If it's the tag
2773 we're looking for, go to step 4. If it's the Catch-All object and B
2774 is NIL, copy A to B. Set A to the previous catch frame and go back
2777 If B is non-NIL, we need to execute some cleanup forms. Return into
2778 B's frame and bind %SP-Internal-Throw-Tag to the tag we're searching
2779 for. When the cleanup forms are finished executing, they'll throw to
2782 If B is NIL, return into this frame, pushing the return value (or
2783 BLTing the multiple values if this frame accepts multiple values and
2784 there are multiple values).
2787 If no form inside of a Catch results in a Throw, the catch frame
2788 needs to be removed from the stack before execution of the function
2789 containing the throw is resumed. For now, the value produced by the
2790 forms inside the Catch form are thrown to the tag. Some sort of
2791 specialized miscop could be used for this, but right now we'll
2792 just go with the throw. The branch PC specified by a Catch
2793 miscop is part of the constants area of the function object,
2794 much like the function's entry points.
2796 @section [Escaping to Lisp code]
2798 @index [Escape to Lisp code convention]
2800 Escaping to Lisp code is fairly straight forward. If a miscop discovers that
2801 it needs to call a Lisp function, it creates a call frame on the control
2802 stack and sets it up so that the called function returns to the function that
2803 called the miscop. This means it is impossible to return control to a miscop
2804 from a Lisp function.
2810 When an error occurs during the execution of a miscop, a call
2811 to %SP-Internal-Error is performed. This call is a break-type call,
2812 so if the error is proceeded (with a Break-Return instruction), no
2813 value will be returned.
2816 %SP-Internal-Error is passed a fixnum error code as its first
2817 argument. The second argument is a fixnum offset into the current
2818 code vector that points to the location immediately following the
2819 instruction that encountered the trouble. From this offset, the
2820 Lisp-level error handler can reconstruct the PC of the losing
2821 instruction, which is not readily available in the micro-machine.
2822 Following the offset, there may be 0 - 2 additional arguments that
2823 provide information of possible use to the error handler. For
2824 example, an unbound-symbol error will pass the symbol in question as
2827 The following error codes are currently defined. Unless otherwise
2828 specified, only the error code and the code-vector offset are passed
2833 1 Object Not List@\The object is passed as the third argument.
2835 2 Object Not Symbol@\The object is passed as the third argument.
2837 3 Object Not Number@\The object is passed as the third argument.
2839 4 Object Not Integer@\The object is passed as the third argument.
2841 5 Object Not Ratio@\The object is passed as the third argument.
2843 6 Object Not Complex@\The object is passed as the third argument.
2845 7 Object Not Vector@\The object is passed as the third argument.
2847 8 Object Not Simple Vector@\The object is passed as the third argument.
2849 9 Illegal Function Object@\The object is passed as the third argument.
2851 10 Object Not Header@\The object (which is not an array or function header)
2852 is passed as the third argument.
2854 11 Object Not I-Vector@\The object is passed as the third argument.
2856 12 Object Not Simple Bit Vector@\The object is passed as the third argument.
2858 13 Object Not Simple String@\The object is passed as the third argument.
2860 14 Object Not Character@\The object is passed as the third argument.
2862 15 Object Not Control Stack Pointer@\The object is passed as the third
2865 16 Object Not Binding Stack Pointer@\The object is passed as the third
2868 17 Object Not Array@\The object is passed as the third argument.
2870 18 Object Not Non-negative Fixnum@\The object is passed as the third
2873 19 Object Not System Area Pointer@\The object is passed as the third
2876 20 Object Not System Pointer@\The object is passed as the third argument.
2878 21 Object Not Float@\The object is passed as the third argument.
2880 22 Object Not Rational@\The object is passed as the third argument.
2882 23 Object Not Non-Complex Number@\A complex number has been passed to
2883 the comparison routine for < or >. The complex number is passed as the
2886 25 Unbound Symbol @\Attempted access to the special value of an unbound
2887 symbol. Passes the symbol as the third argument to %Sp-Internal-Error.
2889 26 Undefined Symbol @\Attempted access to the definition cell of an undefined
2890 symbol. Passes the symbol as the third argument to %Sp-Internal-Error.
2892 27 Altering NIL @\Attempt to bind or setq the special value of NIL.
2894 28 Altering T @\Attempt to bind or setq the special value of T.
2896 30 Illegal Vector Access Type @\The specified access type is returned as the
2899 31 Illegal Vector Size @\Attempt to allocate a vector with negative size or
2900 size too large for vectors of this type. Passes the requested size as the
2903 32 Vector Index Out of Range @\The specified index is out of bounds for
2904 this vector. The bad index is passed as the third argument.
2906 33 Illegal Vector Index@\The specified index is not a positive fixnum. The
2907 bad index is passed as the third argument.
2909 34 Illegal Shrink Vector Value@\The specified value to shrink a vector to is
2910 not a positive fixnum. The bad value is passed as the third argument.
2912 35 Not A Shrink@\The specified value is greater than the current size of the
2913 vector being shrunk. The bad value is passed as the third argument.
2915 36 Illegal Data Vector@\The data vector of an array is illegal. The bad
2916 vector is passed as the third value.
2918 37 Array has Too Few Indices@\An attempt has been made to access
2919 an array as a two or three dimensional array when it has fewer than two
2920 or three dimensions, respectively.
2922 38 Array has Too Many Indices@\An attempt has been made to access an array
2923 as a two or three dimensional array when it has more than two or three
2924 dimensions, respectively.
2926 40 Illegal Byte Specifier@\A bad byte specifier has been passed to one
2927 of the byte manipulation miscops. The offending byte specifier is passed
2928 as the third argument.
2930 41 Illegal Position in Byte Specifier@\A bad position has been given in a
2931 byte specifier that has been passed to one of the byte manipulation
2932 miscops. The offending byte specifier is passed as the third
2935 42 Illegal Size in Byte Specifier@\A bad size has been given in a
2936 byte specifier that has been passed to one of the byte manipulation
2937 miscops. The offending byte specifier is passed as the third
2940 43 Illegal Shift Count@\A shift miscop has encountered non fixnum shift
2941 count. The offending shift count is passed as the third argument.
2943 44 Illegal Boole Operation@\The operation code passed to the boole miscop
2944 is either not a fixnum or is out of range. The operation code is passed as
2947 50 Too Few Arguments@\Too few arguments have been passed to a function. The
2948 number of arguments actually passed is passed as the third argument, and the
2949 function is passed as the fourth.
2951 51 Too Many Arguments@\Too many arguments have been passed to a function.
2952 The number of arguments actually passed is passed as the third argument, and
2953 the function is passed as the fourth.
2955 52 Last Apply Arg Not a List@\The last argument to a function being
2956 invoked by apply is not a list. The last argument is passed as the third
2959 53 Deleted Link Table Entry@\An attempt has been made to call a function
2960 through a link table entry which no longer exists. This is a serious
2961 internal error and should never happen.
2963 55 Error Not <=@\The check-<= miscop will invoke this error if the condition
2964 is false. The two arguments are passed as the third and fourth arguments
2965 to %SP-internal-error.
2967 60 Divide by 0@\An division operation has done a division by zero. The
2968 two operands are passed as the third and fourth arguments.
2970 61 Unseen Throw Tag@\An attempt has been made to throw to a tag that is
2971 not in the current catch hierarchy. The offending tag is passed as the
2974 62 Short Float Underflow@\A short float operation has resulted in
2975 underflow. The two arguments to the operation are passed as the third
2976 and fourth arguments.
2978 63 Short Float Overflow@\A short float operation has resulted in
2979 overflow. The two arguments to the operation are passed as the third
2980 and fourth arguments.
2982 64 Single Float Underflow@\A single float operation has resulted in
2983 underflow. The two arguments to the operation are passed as the third
2984 and fourth arguments.
2986 65 Single Float Overflow@\A single float operation has resulted in
2987 overflow. The two arguments to the operation are passed as the third
2988 and fourth arguments.
2990 66 Long Float Underflow@\A long float operation has resulted in
2991 underflow. The two arguments to the operation are passed as the third
2992 and fourth arguments.
2994 67 Long Float Overflow@\A long float operation has resulted in
2995 overflow. The two arguments to the operation are passed as the third
2996 and fourth arguments.
2998 68 Monadic Short Float Underflow@\A short float operation has resulted in
2999 underflow. The argument to the operation is passed as the third argument.
3001 69 Monadic Short Float Overflow@\A short float operation has resulted in
3002 overflow. The argument to the operation is passed as the third argument.
3004 70 Monadic Long Float Underflow@\A long float operation has resulted in
3005 underflow. The argument to the operation is passed as the third argument.
3007 71 Monadic Long Float Overflow@\A long float operation has resulted in
3008 overflow. The argument to the operation is passed as the third argument.
3011 @section [Trapping to the Mach Kernel]
3013 @index [Trapping to the kernel]
3014 @index [Kernel traps]
3016 Trapping to the Mach kernel is done through one of the syscall0, syscall1,
3017 syscall2, syscall3, syscall4, or syscall miscops. The first argument to
3018 these miscops is the number of the Unix syscall that is to be invoked. Any
3019 other arguments the syscall requires are passed in order after the first
3020 one. Syscall0 accepts only the syscall number and no other arguments;
3021 syscall1 accepts the syscall number and a single argument to the syscall;
3022 etc. Syscall accepts the syscall number and five or more arguments to the
3023 Unix syscall. These syscalls generally return two values: the result twice
3024 if the syscall succeeded and a -1 and the Unix error code if the syscall
3027 @section [Interrupts]
3031 An interface has been built to the general signal mechanism defined by the
3032 Unix operating system. As mentioned in the section on function call and
3033 return miscops, several miscops are defined that support the lowest level
3034 interface to the Unix signal mechanism. The manual @I[CMU Common Lisp
3035 User's Manual, Mach/IBM RT PC Edition] contains descriptions of functions
3036 that allow a user to set up interrupt handlers for any of the Unix signals
3039 @appendix [Fasload File Format]
3042 The purpose of Fasload files is to allow concise storage and rapid
3043 loading of Lisp data, particularly function definitions. The intent
3044 is that loading a Fasload file has the same effect as loading the
3045 ASCII file from which the Fasload file was compiled, but accomplishes
3046 the tasks more efficiently. One noticeable difference, of course, is
3047 that function definitions may be in compiled form rather than
3048 S-expression form. Another is that Fasload files may specify in what
3049 parts of memory the Lisp data should be allocated. For example,
3050 constant lists used by compiled code may be regarded as read-only.
3052 In some Lisp implementations, Fasload file formats are designed to
3053 allow sharing of code parts of the file, possibly by direct mapping
3054 of pages of the file into the address space of a process. This
3055 technique produces great performance improvements in a paged
3056 time-sharing system. Since the Mach project is to produce a
3057 distributed personal-computer network system rather than a
3058 time-sharing system, efficiencies of this type are explicitly @i[not]
3059 a goal for the CMU Common Lisp Fasload file format.
3061 On the other hand, CMU Common Lisp is intended to be portable, as it will
3062 eventually run on a variety of machines. Therefore an explicit goal
3063 is that Fasload files shall be transportable among various
3064 implementations, to permit efficient distribution of programs in
3065 compiled form. The representations of data objects in Fasload files
3066 shall be relatively independent of such considerations as word
3067 length, number of type bits, and so on. If two implementations
3068 interpret the same macrocode (compiled code format), then Fasload
3069 files should be completely compatible. If they do not, then files
3070 not containing compiled code (so-called "Fasdump" data files) should
3071 still be compatible. While this may lead to a format which is not
3072 maximally efficient for a particular implementation, the sacrifice of
3073 a small amount of performance is deemed a worthwhile price to pay to
3074 achieve portability.
3076 The primary assumption about data format compatibility is that all
3077 implementations can support I/O on finite streams of eight-bit bytes.
3078 By "finite" we mean that a definite end-of-file point can be detected
3079 irrespective of the content of the data stream. A Fasload file will
3080 be regarded as such a byte stream.
3084 A Fasload file may be regarded as a human-readable prefix followed by
3085 code in a funny little language. When interpreted, this code will
3086 cause the construction of the encoded data structures. The virtual
3087 machine which interprets this code has a @i[stack] and a @i[table],
3088 both initially empty. The table may be thought of as an expandable
3089 register file; it is used to remember quantities which are needed
3090 more than once. The elements of both the stack and the table are
3091 Lisp data objects. Operators of the funny language may take as
3092 operands following bytes of the data stream, or items popped from the
3093 stack. Results may be pushed back onto the stack or pushed onto the
3094 table. The table is an indexable stack that is never popped; it is
3095 indexed relative to the base, not the top, so that an item once
3096 pushed always has the same index.
3098 More precisely, a Fasload file has the following macroscopic
3099 organization. It is a sequence of zero or more groups concatenated
3100 together. End-of-file must occur at the end of the last group. Each
3101 group begins with a series of seven-bit ASCII characters terminated
3102 by one or more bytes of all ones (FF@-(16)); this is called the
3103 @i[header]. Following the bytes which terminate the header is the
3104 @i[body], a stream of bytes in the funny binary language. The body
3105 of necessity begins with a byte other than FF@-(16). The body is
3106 terminated by the operation @f[FOP-END-GROUP].
3108 The first nine characters of the header must be "@f[FASL FILE]" in
3109 upper-case letters. The rest may be any ASCII text, but by
3110 convention it is formatted in a certain way. The header is divided
3111 into lines, which are grouped into paragraphs. A paragraph begins
3112 with a line which does @i[not] begin with a space or tab character,
3113 and contains all lines up to, but not including, the next such line.
3114 The first word of a paragraph, defined to be all characters up to but
3115 not including the first space, tab, or end-of-line character, is the
3116 @i[name] of the paragraph. A Fasload file header might look something like
3119 FASL FILE >SteelesPerq>User>Guy>IoHacks>Pretty-Print.Slisp
3120 Package Pretty-Print
3121 Compiled 31-Mar-1988 09:01:32 by some random luser
3122 Compiler Version 1.6, Lisp Version 3.0.
3123 Functions: INITIALIZE DRIVER HACK HACK1 MUNGE MUNGE1 GAZORCH
3124 MINGLE MUDDLE PERTURB OVERDRIVE GOBBLE-KEYBOARD
3125 FRY-USER DROP-DEAD HELP CLEAR-MICROCODE
3126 %AOS-TRIANGLE %HARASS-READTABLE-MAYBE
3127 Macros: PUSH POP FROB TWIDDLE
3128 @r[<one or more bytes of FF@-(16)>]
3130 The particular paragraph names and contents shown here are only intended as
3133 @section [Fasload Language]
3135 Each operation in the binary Fasload language is an eight-bit
3136 (one-byte) opcode. Each has a name beginning with "@f[FOP-]". In
3137 the following descriptions, the name is followed by operand
3138 descriptors. Each descriptor denotes operands that follow the opcode
3139 in the input stream. A quantity in parentheses indicates the number
3140 of bytes of data from the stream making up the operand. Operands
3141 which implicitly come from the stack are noted in the text. The
3142 notation "@PushArrow stack" means that the result is pushed onto the
3143 stack; "@PushArrow table" similarly means that the result is added to the
3144 table. A construction like "@i[n](1) @i[value](@i[n])" means that
3145 first a single byte @i[n] is read from the input stream, and this
3146 byte specifies how many bytes to read as the operand named @i[value].
3147 All numeric values are unsigned binary integers unless otherwise
3148 specified. Values described as "signed" are in two's-complement form
3149 unless otherwise specified. When an integer read from the stream
3150 occupies more than one byte, the first byte read is the least
3151 significant byte, and the last byte read is the most significant (and
3152 contains the sign bit as its high-order bit if the entire integer is
3155 Some of the operations are not necessary, but are rather special
3156 cases of or combinations of others. These are included to reduce the
3157 size of the file or to speed up important cases. As an example,
3158 nearly all strings are less than 256 bytes long, and so a special
3159 form of string operation might take a one-byte length rather than a
3160 four-byte length. As another example, some implementations may
3161 choose to store bits in an array in a left-to-right format within
3162 each word, rather than right-to-left. The Fasload file format may
3163 support both formats, with one being significantly more efficient
3164 than the other for a given implementation. The compiler for any
3165 implementation may generate the more efficient form for that
3166 implementation, and yet compatibility can be maintained by requiring
3167 all implementations to support both formats in Fasload files.
3169 Measurements are to be made to determine which operation codes are
3170 worthwhile; little-used operations may be discarded and new ones
3171 added. After a point the definition will be "frozen", meaning that
3172 existing operations may not be deleted (though new ones may be added;
3173 some operations codes will be reserved for that purpose).
3176 0 @f[ ] @f[FOP-NOP] @\
3177 No operation. (This is included because it is recognized
3178 that some implementations may benefit from alignment of operands to some
3179 operations, for example to 32-bit boundaries. This operation can be used
3180 to pad the instruction stream to a desired boundary.)
3182 1 @f[ ] @f[FOP-POP] @f[ ] @PushArrow @f[ ] table @\
3183 One item is popped from the stack and added to the table.
3185 2 @f[ ] @f[FOP-PUSH] @f[ ] @i[index](4) @f[ ] @PushArrow @f[ ] stack @\
3186 Item number @i[index] of the table is pushed onto the stack.
3187 The first element of the table is item number zero.
3189 3 @f[ ] @f[FOP-BYTE-PUSH] @f[ ] @i[index](1) @f[ ] @PushArrow @f[ ] stack @\
3190 Item number @i[index] of the table is pushed onto the stack.
3191 The first element of the table is item number zero.
3193 4 @f[ ] @f[FOP-EMPTY-LIST] @f[ ] @PushArrow @f[ ] stack @\
3194 The empty list (@f[()]) is pushed onto the stack.
3196 5 @f[ ] @f[FOP-TRUTH] @f[ ] @PushArrow @f[ ] stack @\
3197 The standard truth value (@f[T]) is pushed onto the stack.
3199 6 @f[ ] @f[FOP-SYMBOL-SAVE] @f[ ] @i[n](4) @f[ ] @i[name](@i[n])
3200 @f[ ] @PushArrow @f[ ] stack & table@\
3201 The four-byte operand @i[n] specifies the length of the print name
3202 of a symbol. The name follows, one character per byte,
3203 with the first byte of the print name being the first read.
3204 The name is interned in the default package,
3205 and the resulting symbol is both pushed onto the stack and added to the table.
3207 7 @f[ ] @f[FOP-SMALL-SYMBOL-SAVE] @f[ ] @i[n](1) @f[ ] @i[name](@i[n]) @f[ ] @PushArrow @f[ ] stack & table@\
3208 The one-byte operand @i[n] specifies the length of the print name
3209 of a symbol. The name follows, one character per byte,
3210 with the first byte of the print name being the first read.
3211 The name is interned in the default package,
3212 and the resulting symbol is both pushed onto the stack and added to the table.
3214 8 @f[ ] @f[FOP-SYMBOL-IN-PACKAGE-SAVE] @f[ ] @i[index](4)
3215 @f[ ] @i[n](4) @f[ ] @i[name](@i[n])
3216 @f[ ] @PushArrow @f[ ] stack & table@\
3217 The four-byte @i[index] specifies a package stored in the table.
3218 The four-byte operand @i[n] specifies the length of the print name
3219 of a symbol. The name follows, one character per byte,
3220 with the first byte of the print name being the first read.
3221 The name is interned in the specified package,
3222 and the resulting symbol is both pushed onto the stack and added to the table.
3224 9 @f[ ] @f[FOP-SMALL-SYMBOL-IN-PACKAGE-SAVE] @f[ ] @i[index](4)
3225 @f[ ] @i[n](1) @f[ ] @i[name](@i[n]) @f[ ]
3226 @PushArrow @f[ ] stack & table@\
3227 The four-byte @i[index] specifies a package stored in the table.
3228 The one-byte operand @i[n] specifies the length of the print name
3229 of a symbol. The name follows, one character per byte,
3230 with the first byte of the print name being the first read.
3231 The name is interned in the specified package,
3232 and the resulting symbol is both pushed onto the stack and added to the table.
3234 10 @f[ ] @f[FOP-SYMBOL-IN-BYTE-PACKAGE-SAVE] @f[ ] @i[index](1)
3235 @f[ ] @i[n](4) @f[ ] @i[name](@i[n])
3236 @f[ ] @PushArrow @f[ ] stack & table@\
3237 The one-byte @i[index] specifies a package stored in the table.
3238 The four-byte operand @i[n] specifies the length of the print name
3239 of a symbol. The name follows, one character per byte,
3240 with the first byte of the print name being the first read.
3241 The name is interned in the specified package,
3242 and the resulting symbol is both pushed onto the stack and added to the table.
3244 11@f[ ] @f[FOP-SMALL-SYMBOL-IN-BYTE-PACKAGE-SAVE] @f[ ] @i[index](1)
3245 @f[ ] @i[n](1) @f[ ] @i[name](@i[n]) @f[ ]
3246 @PushArrow @f[ ] stack & table@\
3247 The one-byte @i[index] specifies a package stored in the table.
3248 The one-byte operand @i[n] specifies the length of the print name
3249 of a symbol. The name follows, one character per byte,
3250 with the first byte of the print name being the first read.
3251 The name is interned in the specified package,
3252 and the resulting symbol is both pushed onto the stack and added to the table.
3256 13 @f[ ] @f[FOP-DEFAULT-PACKAGE] @f[ ] @i[index](4) @\
3257 A package stored in the table entry specified by @i[index] is made
3258 the default package for future @f[FOP-SYMBOL] and @f[FOP-SMALL-SYMBOL]
3259 interning operations. (These package FOPs may change or disappear
3260 as the package system is determined.)
3262 14 @f[ ] @f[FOP-PACKAGE] @f[ ] @PushArrow @f[ ] table @\
3263 An item is popped from the stack; it must be a symbol. The package of
3264 that name is located and pushed onto the table.
3266 15 @f[ ] @f[FOP-LIST] @f[ ] @i[length](1) @f[ ] @PushArrow @f[ ] stack @\
3267 The unsigned operand @i[length] specifies a number of
3268 operands to be popped from the stack. These are made into a list
3269 of that length, and the list is pushed onto the stack.
3270 The first item popped from the stack becomes the last element of
3271 the list, and so on. Hence an iterative loop can start with
3272 the empty list and perform "pop an item and cons it onto the list"
3274 (Lists of length greater than 255 can be made by using @f[FOP-LIST*]
3277 16 @f[ ] @f[FOP-LIST*] @f[ ] @i[length](1) @f[ ] @PushArrow @f[ ] stack @\
3278 This is like @f[FOP-LIST] except that the constructed list is terminated
3279 not by @f[()] (the empty list), but by an item popped from the stack
3280 before any others are. Therefore @i[length]+1 items are popped in all.
3281 Hence an iterative loop can start with
3282 a popped item and perform "pop an item and cons it onto the list"
3285 17-24 @f[ ] @f[FOP-LIST-1], @f[FOP-LIST-2], ..., @f[FOP-LIST-8] @\
3286 @f[FOP-LIST-@i{k}] is like @f[FOP-LIST] with a byte containing @i[k]
3287 following it. These exist purely to reduce the size of Fasload files.
3288 Measurements need to be made to determine the useful values of @i[k].
3290 25-32 @f[ ] @f[FOP-LIST*-1], @f[FOP-LIST*-2], ..., @f[FOP-LIST*-8] @\
3291 @f[FOP-LIST*-@i{k}] is like @f[FOP-LIST*] with a byte containing @i[k]
3292 following it. These exist purely to reduce the size of Fasload files.
3293 Measurements need to be made to determine the useful values of @i[k].
3295 33 @f[ ] @f[FOP-INTEGER] @f[ ] @i[n](4) @f[ ] @i[value](@i[n]) @f[ ]
3296 @PushArrow @f[ ] stack @\
3297 A four-byte unsigned operand specifies the number of following
3298 bytes. These bytes define the value of a signed integer in two's-complement
3299 form. The first byte of the value is the least significant byte.
3301 34 @f[ ] @f[FOP-SMALL-INTEGER] @f[ ] @i[n](1) @f[ ] @i[value](@i[n])
3302 @f[ ] @PushArrow @f[ ] stack @\
3303 A one-byte unsigned operand specifies the number of following
3304 bytes. These bytes define the value of a signed integer in two's-complement
3305 form. The first byte of the value is the least significant byte.
3307 35 @f[ ] @f[FOP-WORD-INTEGER] @f[ ] @i[value](4) @f[ ] @PushArrow @f[ ] stack @\
3308 A four-byte signed integer (in the range -2@+[31] to 2@+[31]-1) follows the
3309 operation code. A LISP integer (fixnum or bignum) with that value
3310 is constructed and pushed onto the stack.
3312 36 @f[ ] @f[FOP-BYTE-INTEGER] @f[ ] @i[value](1) @f[ ] @PushArrow @f[ ] stack @\
3313 A one-byte signed integer (in the range -128 to 127) follows the
3314 operation code. A LISP integer (fixnum or bignum) with that value
3315 is constructed and pushed onto the stack.
3317 37 @f[ ] @f[FOP-STRING] @f[ ] @i[n](4) @f[ ] @i[name](@i[n])
3318 @f[ ] @PushArrow @f[ ] stack @\
3319 The four-byte operand @i[n] specifies the length of a string to
3320 construct. The characters of the string follow, one per byte.
3321 The constructed string is pushed onto the stack.
3323 38 @f[ ] @f[FOP-SMALL-STRING] @f[ ] @i[n](1) @f[ ] @i[name](@i[n]) @f[ ] @PushArrow @f[ ] stack @\
3324 The one-byte operand @i[n] specifies the length of a string to
3325 construct. The characters of the string follow, one per byte.
3326 The constructed string is pushed onto the stack.
3328 39 @f[ ] @f[FOP-VECTOR] @f[ ] @i[n](4) @f[ ] @PushArrow @f[ ] stack @\
3329 The four-byte operand @i[n] specifies the length of a vector of LISP objects
3330 to construct. The elements of the vector are popped off the stack;
3331 the first one popped becomes the last element of the vector.
3332 The constructed vector is pushed onto the stack.
3334 40 @f[ ] @f[FOP-SMALL-VECTOR] @f[ ] @i[n](1) @f[ ] @PushArrow @f[ ] stack @\
3335 The one-byte operand @i[n] specifies the length of a vector of LISP objects
3336 to construct. The elements of the vector are popped off the stack;
3337 the first one popped becomes the last element of the vector.
3338 The constructed vector is pushed onto the stack.
3340 41 @f[ ] @f[FOP-UNIFORM-VECTOR] @f[ ] @i[n](4) @f[ ] @PushArrow @f[ ] stack @\
3341 The four-byte operand @i[n] specifies the length of a vector of LISP objects
3342 to construct. A single item is popped from the stack and used to initialize
3343 all elements of the vector. The constructed vector is pushed onto the stack.
3345 42 @f[ ] @f[FOP-SMALL-UNIFORM-VECTOR] @f[ ] @i[n](1) @f[ ] @PushArrow @f[ ] stack @\
3346 The one-byte operand @i[n] specifies the length of a vector of LISP objects
3347 to construct. A single item is popped from the stack and used to initialize
3348 all elements of the vector. The constructed vector is pushed onto the stack.
3350 43 @f[ ] @f[FOP-INT-VECTOR] @f[ ] @i[n](4) @f[ ] @i[size](1) @f[ ] @i[count](1) @f[ ]
3351 @i[data](@ceiling<@i[n]/@i[count]>@ceiling<@i[size]*@i[count]/8>) @f[ ]
3352 @PushArrow @f[ ] stack @\
3353 The four-byte operand @i[n] specifies the length of a vector of
3354 unsigned integers to be constructed. Each integer is @i[size]
3355 bits big, and are packed in the data stream in sections of
3356 @i[count] apiece. Each section occupies an integral number of bytes.
3357 If the bytes of a section are lined up in a row, with the first
3358 byte read at the right, and successive bytes placed to the left,
3359 with the bits within a byte being arranged so that the low-order bit
3360 is to the right, then the integers of the section are successive
3361 groups of @i[size] bits, starting from the right and running across
3362 byte boundaries. (In other words, this is a consistent
3363 right-to-left convention.) Any bits wasted at the left end of
3364 a section are ignored, and any wasted groups in the last section
3366 It is permitted for the loading implementation to use a vector
3367 format providing more precision than is required by @i[size].
3368 For example, if @i[size] were 3, it would be permitted to use a vector
3369 of 4-bit integers, or even vector of general LISP objects filled
3370 with integer LISP objects. However, an implementation is expected
3371 to use the most restrictive format that will suffice, and is expected
3372 to reconstruct objects identical to those output if the Fasload file
3373 was produced by the same implementation.
3374 (For the PERQ U-vector formats, one would have
3375 @i[size] an element of {1, 2, 4, 8, 16}, and @i[count]=32/@i[size];
3376 words could be read directly into the U-vector.
3377 This operation provides a very general format whereby almost
3378 any conceivable implementation can output in its preferred packed format,
3379 and another can read it meaningfully; by checking at the beginning
3380 for good cases, loading can still proceed quickly.)
3381 The constructed vector is pushed onto the stack.
3383 44 @f[ ] @f[FOP-UNIFORM-INT-VECTOR] @f[ ] @i[n](4) @f[ ] @i[size](1) @f[ ]
3384 @i[value](@ceiling<@i[size]/8>) @f[ ] @PushArrow @f[ ] stack @\
3385 The four-byte operand @i[n] specifies the length of a vector of unsigned
3386 integers to construct.
3387 Each integer is @i[size] bits big, and is initialized to the value
3388 of the operand @i[value].
3389 The constructed vector is pushed onto the stack.
3391 45 @f[ ] @f[FOP-FLOAT] @f[ ] @i[n](1) @f[ ] @i[exponent](@ceiling<@i[n]/8>) @f[ ]
3392 @i[m](1) @f[ ] @i[mantissa](@ceiling<@i[m]/8>) @f[ ] @PushArrow @f[ ] stack @\
3393 The first operand @i[n] is one unsigned byte, and describes the number of
3394 @i[bits] in the second operand @i[exponent], which is a signed
3395 integer in two's-complement format. The high-order bits of
3396 the last (most significant) byte of @i[exponent] shall equal the sign bit.
3397 Similar remarks apply to @i[m] and @i[mantissa]. The value denoted by these
3398 four operands is @i[mantissa]@f[x]2@+{@i[exponent]-length(@i[mantissa])}.
3399 A floating-point number shall be constructed which has this value,
3400 and then pushed onto the stack. That floating-point format should be used
3401 which is the smallest (most compact) provided by the implementation which
3402 nevertheless provides enough accuracy to represent both the exponent
3403 and the mantissa correctly.
3407 52 @f[ ] @f[FOP-ALTER] @f[ ] @i[index](1) @\
3408 Two items are popped from the stack; call the first @i[newval] and
3409 the second @i[object]. The component of @i[object] specified by
3410 @i[index] is altered to contain @i[newval]. The precise operation
3411 depends on the type of @i[object]:
3413 List @\ A zero @i[index] means alter the car (perform @f[RPLACA]),
3414 and @i[index]=1 means alter the cdr (@f[RPLACD]).
3416 Symbol @\ By definition these indices have the following meaning,
3417 and have nothing to do with the actual representation of symbols
3418 in a given implementation:
3420 0 @\ Alter value cell.
3422 1 @\ Alter function cell.
3424 2 @\ Alter property list (!).
3427 Vector (of any kind) @\ Alter component number @i[index] of the vector.
3429 String @\ Alter character number @i[index] of the string.
3432 53 @f[ ] @f[FOP-EVAL] @f[ ] @PushArrow @f[ ] stack @\
3433 Pop an item from the stack and evaluate it (give it to @f[EVAL]).
3434 Push the result back onto the stack.
3436 54 @f[ ] @f[FOP-EVAL-FOR-EFFECT] @\
3437 Pop an item from the stack and evaluate it (give it to @f[EVAL]).
3438 The result is ignored.
3440 55 @f[ ] @f[FOP-FUNCALL] @f[ ] @i[nargs](1) @f[ ] @PushArrow @f[ ] stack @\
3441 Pop @i[nargs]+1 items from the stack and apply the last one popped
3443 all the rest as arguments (the first one popped being the last argument).
3444 Push the result back onto the stack.
3446 56 @f[ ] @f[FOP-FUNCALL-FOR-EFFECT] @f[ ] @i[nargs](1) @\
3447 Pop @i[nargs]+1 items from the stack and apply the last one popped
3449 all the rest as arguments (the first one popped being the last argument).
3450 The result is ignored.
3452 57 @f[ ] @f[FOP-CODE-FORMAT] @f[ ] @i[id](1) @\
3453 The operand @i[id] is a unique identifier specifying the format
3454 for following code objects. The operations @f[FOP-CODE]
3455 and its relatives may not
3456 occur in a group until after @f[FOP-CODE-FORMAT] has appeared;
3457 there is no default format. This is provided so that several
3458 compiled code formats may co-exist in a file, and so that a loader
3459 can determine whether or not code was compiled by the correct
3460 compiler for the implementation being loaded into.
3461 So far the following code format identifiers are defined:
3467 3 @\ @value(DinkyMachine)
3470 58 @f[ ] @f[FOP-CODE] @f[ ] @i[nitems](4) @f[ ] @i[size](4) @f[ ]
3471 @i[code](@i[size]) @f[ ] @PushArrow @f[ ] stack @\
3472 A compiled function is constructed and pushed onto the stack.
3473 This object is in the format specified by the most recent
3474 occurrence of @f[FOP-CODE-FORMAT].
3475 The operand @i[nitems] specifies a number of items to pop off
3476 the stack to use in the "boxed storage" section. The operand @i[code]
3477 is a string of bytes constituting the compiled executable code.
3479 59 @f[ ] @f[FOP-SMALL-CODE] @f[ ] @i[nitems](1) @f[ ] @i[size](2) @f[ ]
3480 @i[code](@i[size]) @f[ ] @PushArrow @f[ ] stack @\
3481 A compiled function is constructed and pushed onto the stack.
3482 This object is in the format specified by the most recent
3483 occurrence of @f[FOP-CODE-FORMAT].
3484 The operand @i[nitems] specifies a number of items to pop off
3485 the stack to use in the "boxed storage" section. The operand @i[code]
3486 is a string of bytes constituting the compiled executable code.
3488 60 @f[ ] @f[FOP-STATIC-HEAP] @\
3489 Until further notice operations which allocate data structures
3490 may allocate them in the static area rather than the dynamic area.
3491 (The default area for allocation is the dynamic area; this
3492 default is reset whenever a new group is begun.
3493 This command is of an advisory nature; implementations with no
3494 static heap can ignore it.)
3496 61 @f[ ] @f[FOP-DYNAMIC-HEAP] @\
3497 Following storage allocation should be in the dynamic area.
3499 62 @f[ ] @f[FOP-VERIFY-TABLE-SIZE] @f[ ] @i[size](4) @\
3500 If the current size of the table is not equal to @i[size],
3501 then an inconsistency has been detected. This operation
3502 is inserted into a Fasload file purely for error-checking purposes.
3503 It is good practice for a compiler to output this at least at the
3504 end of every group, if not more often.
3506 63 @f[ ] @f[FOP-VERIFY-EMPTY-STACK] @\
3507 If the stack is not currently empty,
3508 then an inconsistency has been detected. This operation
3509 is inserted into a Fasload file purely for error-checking purposes.
3510 It is good practice for a compiler to output this at least at the
3511 end of every group, if not more often.
3513 64 @f[ ] @f[FOP-END-GROUP] @\
3514 This is the last operation of a group. If this is not the
3515 last byte of the file, then a new group follows; the next
3516 nine bytes must be "@f[FASL FILE]".
3518 65 @f[ ] @f[FOP-POP-FOR-EFFECT] @f[ ] stack @f[ ] @PushArrow @f[ ] @\
3519 One item is popped from the stack.
3521 66 @f[ ] @f[FOP-MISC-TRAP] @f[ ] @PushArrow @f[ ] stack @\
3522 A trap object is pushed onto the stack.
3524 67 @f[ ] @f[FOP-READ-ONLY-HEAP] @\
3525 Following storage allocation may be in a read-only heap.
3526 (For symbols, the symbol itself may not be in a read-only area,
3527 but its print name (a string) may be.
3528 This command is of an advisory nature; implementations with no
3529 read-only heap can ignore it, or use a static heap.)
3531 68 @f[ ] @f[FOP-CHARACTER] @f[ ] @i[character](3) @f[ ] @PushArrow @f[ ] stack @\
3532 The three bytes specify the 24 bits of a CMU Common Lisp character object.
3533 The bytes, lowest first, represent the code, control, and font bits.
3534 A character is constructed and pushed onto the stack.
3536 69 @f[ ] @f[FOP-SHORT-CHARACTER] @f[ ] @i[character](1) @f[ ]
3537 @PushArrow @f[ ] stack @\
3538 The one byte specifies the lower eight bits of a CMU Common Lisp character
3539 object (the code). A character is constructed with zero control
3540 and zero font attributes and pushed onto the stack.
3542 70 @f[ ] @f[FOP-RATIO] @f[ ] @PushArrow @f[ ] stack @\
3543 Creates a ratio from two integers popped from the stack.
3544 The denominator is popped first, the numerator second.
3546 71 @f[ ] @f[FOP-COMPLEX] @f[ ] @PushArrow @f[ ] stack @\
3547 Creates a complex number from two numbers popped from the stack.
3548 The imaginary part is popped first, the real part second.
3550 72 @f[ ] @f[FOP-LINK-ADDRESS-FIXUP] @f[ ] @i[nargs](1) @f[ ] @i[restp](1)
3551 @f[ ] @i[offset](4) @f[ ] @PushArrow @f[ ] stack @\
3552 Valid only for when FOP-CODE-FORMAT corresponds to the Vax or the
3553 @value(DinkyMachine).
3554 This operation pops a symbol and a code object from the stack and pushes
3555 a modified code object back onto the stack according to the needs of the
3556 runtime code linker on the Vax or @value(DinkyMachine).
3558 73 @f[ ] @f[FOP-LINK-FUNCTION-FIXUP] @f[ ] @i[offset](4) @f[ ]
3559 @PushArrow @f[ ] stack @\
3560 Valid only for when FOP-CODE-FORMAT corresponds to the Vax or the
3561 @value(DinkyMachine).
3562 This operation pops a symbol and a code object from the stack and pushes
3563 a modified code object back onto the stack according to the needs of the
3564 runtime code linker on the Vax or the @value(DinkyMachine).
3566 74 @f[ ] @f[FOP-FSET] @f[ ] @\
3567 Pops the top two things off of the stack and uses them as arguments to FSET
3568 (i.e. SETF of SYMBOL-FUNCTION).
3570 128 @f[ ] @f[FOP-LINK-ADDRESS-FIXUP] @f[ ] @i[nargs] @f[ ] @i[flag] @f[ ]
3571 @i[offset] @f[ ]@\Valid only when FOP-CODE-FORMAT corresponds to the
3572 @value(DinkyMachine). This operation pops a symbol and a function object
3573 off the stack. The code vector in the function object is modified
3574 according to the needs of the runtime code linker of the @value(DinkyMachine)
3575 and pushed back on the stack. This FOP links in calls to other functions.
3577 129 @f[ ] @f[FOP-MISCOP-FIXUP] @f[ ] @i[index](2) @f[ ] @i[offset](4) @f[ ]@\
3578 Valid only when FOP-CODE-FORMAT corresponds to the @value(DinkyMachine).
3579 This operation pops a code object from the stack and pushes a
3580 modified code object back onto the stack according to the needs of
3581 the runtime code linker on the @value(DinkyMachine). This FOP links in
3582 calls to the assembler language support routines.
3584 130 @f[ ] @f[FOP-ASSEMBLER-ROUTINE] @f[ ] @i[code-length] @f[ ] @\
3585 Valid only when FOP-CODE-FORMAT corresponds to the @value(DinkyMachine).
3586 This operation loads assembler code into the assembler code space of the
3587 currently running Lisp.
3589 131 @f[ ] @f[FOP-FIXUP-MISCOP-ROUTINE] @f[ ]@\Valid only when FOP-CODE-FORMAT
3590 corresponds to the @value(DinkyMachine). This operation pops a list of
3591 external references, a list of external labels defined, the name, and the
3592 code address off the stack. This information is saved, so that after
3593 everything is loaded, all the external references can be resolved.
3595 132 @f[ ] @f[FOP-FIXUP-ASSEMBLER-ROUTINE] @f[ ]@\is similar to
3596 FOP-FIXUP-MISCOP-ROUTINE, except it is for internal assembler routines
3597 rather than ones visible to Lisp.
3599 133 @f[ ] @f[FOP-FIXUP-USER-MISCOP-ROUTINE] @f[ ]@\is similar to
3600 FOP-FIXUP-MISCOP-ROUTINE, except it is for routines written by users who
3601 have an extremely good understanding of the system internals.
3603 134 @f[ ] @f[FOP-USER-MISCOP-FIXUP] @f[ ] @i[offset](4) @f[ ]@\is similar
3604 to FOP-MISCOP-FIXUP, but is used to link in user defined miscops.
3606 255 @f[ ] @f[FOP-END-HEADER] @\ Indicates the end of a group header, as described above.
3609 @Appendix[Building CMU Common Lisp]
3611 @section(Introduction)
3612 This document explains how to build a working Common Lisp from source code on
3613 the IBM RT PC under the Mach operating system. You should already have a
3614 working Common Lisp running on an IBM RT PC before trying to build a new Common
3617 Throughout this document the following terms are used:
3619 Core file@\A core file is a file containing an image of a Lisp system. The
3620 core file contains header information describing where the data in the rest of
3621 the file should be placed in memory. There is a simple C program which reads a
3622 core file into memory at the correct locations and then jumps to a location
3623 determined by the contents of the core file. The C code includes the X
3624 window system version 10 release 4 which may be called from Lisp.
3627 Cold core file @\A cold core file contains enough of the Lisp system to make it
3628 possible to load in the rest of the code necessary to generate a full Common
3629 Lisp. A cold core file is generated by the program Genesis.
3631 Miscops@\Miscops are assembler language routines that are used to support
3632 compiled Lisp code. A Lisp macro assembler provides a
3633 convenient mechanism for writing these assembler language routines.
3635 Matchmaker@\Matchmaker is a program developed to automatically generate
3636 remote procedure call interfaces between programs. Matchmaker accepts
3637 a description of a remote procedure call interface and generates code
3641 There are many steps required to go from sources to a working Common Lisp
3642 system. Each step will be explained in detail in the following sections.
3643 It is possible to perform more than one step with one invocation of Lisp.
3644 However, I recommend that each step be started with a fresh Lisp. There
3645 is some small chance that something done in one step will adversely affect
3646 a following step if the same Lisp is used. The scripts for each
3647 step assume that you are in the user package which is the default when
3648 Lisp first starts up. If you change to some other package, some of these
3649 steps may not work correctly.
3651 In many of the following steps, there are lines setting up search lists so that
3652 command files know where to find the sources. What I have done is create a
3653 init.lisp file that sets up these search lists for me. This file is
3654 automatically loaded from the user's home directory (as determined by the
3655 @b[HOME] environment variable) when you start up Lisp. Note that my init.lisp
3656 file is included with the sources. You may have to modify it, if you change
3657 where the lisp sources are.
3659 @section(Installing Source Code)
3660 With this document, you should also have received a tape cartridge in tar
3661 format containing the complete Common Lisp source code. You should create
3662 some directory where you want to put the source code. For the following
3663 discussion, I will assume that the source code lives in the directory
3664 /usr/lisp. To install the source code on your machine, issue the following
3668 tar xvf <tape device>
3670 The first command puts you into the directory where you want the source code,
3671 and the second extracts all the files and sub-directories from the tape into
3672 the current directory. <Tape device> should be the name of the tape device on
3673 your machine, usually /dev/st0.
3675 The following sub-directories will be created by tar:
3677 bin@\contains a single executable file, lisp, which is a C program
3678 used to start up Common Lisp.
3680 clc@\contains the Lisp source code for the Common Lisp compiler and assembler.
3682 code@\contains the Lisp source code that corresponds to all the functions,
3683 variables, macros, and special forms described in @i[Common Lisp: The Language]
3684 by Guy L. Steele Jr., as well as some Mach specific files.
3686 hemlock@\contains the Lisp source code for Hemlock, an emacs-like editor
3687 written completely in Common Lisp.
3689 icode@\contains Matchmaker generated code for interfaces to Inter Process
3690 Communication (IPC) routines. This code is used to communicate with other
3691 processes using a remote procedure call mechanism. Under Mach, all the
3692 facilities provided by Mach beyond the normal Berkeley Unix 4.3 system
3693 calls are accessed from Lisp using this IPC mechanism. Currently, the
3694 code for the Mach, name server, Lisp typescript, and Lisp eval server
3695 interfaces reside in this directory.
3697 idefs@\contains the Matchmaker definition files used to generate the Lisp
3698 code in the icode directory.
3700 lib@\contains files needed to run Lisp. The file lisp.core is known as a
3701 Lisp core file and is loaded into memory by the lisp program mentioned
3702 above in the entry for the bin directory. This file has a format which
3703 allows it to be mapped into memory at the correct locations. The files
3704 spell-dictionary.text and spell-dictionary.bin are the text and binary
3705 form of a dictionary, respectively, used by Hemlock's spelling checker and
3706 corrector. The two files hemlock.cursor and hemlock.mask are used by
3707 Hemlock when running under the X window system.
3709 miscops@\contains the Lisp assembler source code for all the miscops
3710 that support low level Lisp functions, such as storage allocation,
3711 complex operations that can not performed in-line, garbage collection, and
3712 other operations. These routines are written in assembler, so that they
3713 are as efficient as possible. These routines use a very short calling
3714 sequence, so calling them is very cheap compared to a normal Lisp
3717 mm@\contains the Lisp source code for the Matchmaker program. This program
3718 is used to generate the Lisp source code files in icode from the corresponding
3719 matchmaker definitions in idefs.
3721 pcl@\contains the Lisp source code for a version of the Common Lisp Object
3722 System (originally Portable Common Loops),
3723 an object oriented programming language built on top of Common Lisp.
3725 X@\contains the C object files for X version 10 release 4 C library
3726 routines. These are linked with the lisp startup code, so that X is
3727 available from Lisp.
3729 scribe@\contains Scribe source and postscript output for the manuals
3730 describing various aspects of the CMU Common Lisp implementation.
3732 demos@\contains the Lisp source code for various demonstration programs.
3733 This directory contains the Gabriel benchmark set (bmarks.lisp) and
3734 a sub-directory containing the Soar program which is also used for
3735 benchmarking purposes. There may be other programs and/or sub-directories
3736 here that you may look at.
3738 These directories contain source files as well as Lisp object files.
3739 This means it is not necessary to go through all the steps to
3740 build a new a Common Lisp, only those steps that are affected by
3741 a modification to the sources. For example, modifying the compiler
3742 will require recompiling everything. Modifying a miscop file should
3743 require only reassembling that particular file and rebuilding the
3744 cold core file and full core file.
3746 As well as the directories mentioned above, there are also several files
3747 contained in the top-level directory. These are:
3749 init.lisp@\is a Lisp init file I use. This sets up some standard search
3750 lists, as well as defines a Hemlock mode for editing miscop
3753 lisp.c@\contains the C code used to start up the lisp core image under Mach.
3755 lispstart.s@\contains some assembler language code that is invoked by lisp.c
3756 to finish the process of starting up the lisp process.
3758 makefile@\contains make definitions for compiling lisp.c and lispstart.s
3759 into the lisp program.
3761 rg@\contains some adb commands that can be read into adb while debugging a lisp
3762 process. It prints out all the registers, the name of the currently
3763 executing Lisp function, and sets an adb variable to the current stack frame
3764 which is used by the following file.
3766 st@\contains some adb commands that can be read into adb while debugging
3767 a lisp process. It prints out a Lisp stack frame and the name of the
3768 function associated with the stack frame. It also updates the adb variable
3769 mentioned above to point to the next stack frame. Repeatedly reading this
3770 file into adb will produce a backtrace of all the active call frames
3773 ac@\contains some adb commands that print out the current values of the
3774 active catch pointer. This points to the head of a list of catch frames
3775 that exist on the control stack.
3777 cs@\contains some adb commands that print out the contents of a catch
3778 frame. Reading cs into adb several times in a row (after reading ac once)
3779 will print out the catch frames in order.
3782 @section(Compiling the Lisp Startup Program)
3783 To compile the lisp start up program, you should be in the top level directory
3784 of the sources (/usr/lisp) and type:
3788 This will compile the file lisp.c, assemble the file lispstart.s and produce
3789 an executable file lisp. Currently the default location for the lisp core
3790 file is /usr/misc/.lisp/lib/lisp.core. If you want to change this default
3791 location, edit the file lisp.c and change the line
3793 #define COREFILE "/usr/misc/.lisp/lib/lisp.core"
3795 to refer to the file where you intend to put the core file.
3797 This step takes a few seconds.
3799 @section(Assembling Assembler routines)
3800 The standard core image includes a Lisp macro assembler. To assemble all
3801 the miscops, the following steps should be performed:
3803 (compile-file "/usr/lisp/clc/miscasm.lisp")
3804 (load "/usr/lisp/clc/miscasm.fasl")
3805 (setf (search-list "msc:") '("/usr/lisp/miscops/"))
3808 The first line compiles a file that contains a couple of functions used to
3809 assemble miscop source files. The second line loads the resulting compiled
3810 file into the currently executing core image. The third line defines the
3811 msc search list which is used by the function clc::asm-files to locate
3812 the miscop sources. The terminal will display information as each file
3813 is assembled. For each file a .fasl, a .list, and an .err file will be
3814 generated in /usr/lisp/miscops.
3816 This step takes about half an hour.
3818 @section(Compiling the Compiler)
3820 To compile the compiler is simple:
3822 (setf (search-list "clc:") '("/usr/lisp/clc/"))
3823 (load "clc:compclc.lisp")
3825 The first line just sets up a search list variable clc, so that the file
3826 compclc.lisp can find the compiler sources. The terminal will display
3827 information as each file is assembled. For each file a .fasl and an .err file
3828 will be generated. A log of the compiler output is also displayed on the
3831 This step takes about forty-five minutes.
3833 @section(Compiling the Lisp Sources)
3835 Compiling the Lisp source code is also easy:
3837 (setf (search-list "code:") '("/usr/lisp/code/"))
3838 (load "code:worldcom.lisp")
3840 Again, the first line defines a search list variable, so that the file
3841 worldcom.lisp can find the Lisp sources. As each file is compiled, the
3842 name of the file is printed on the terminal. For each file a .fasl will be
3843 generated. Also, a single error log will be generated in the file
3844 code:compile-lisp.log.
3846 This step takes about an hour and a half.
3848 @section(Compiling Hemlock)
3850 Compiling the Hemlock source code is done as follows:
3852 (setf (search-list "hem:") '("/usr/lisp/hemlock/"))
3853 (load "hem:ctw.lisp")
3855 Again, the first line defines a search list variable, so that ctw.lisp can
3856 find the Hemlock sources. As each file is compiled, the name of the file is
3857 printed on the terminal. For each file a .fasl will be generated. Also, a
3858 single error log will be generated in the file hem:lossage.log.
3860 This step takes about forty-five minutes.
3862 @section(Compiling Matchmaker)
3863 Compiling the matchmaker sources is done as follows:
3865 (setf (search-list "mm:") '("/usr/lisp/mm"))
3866 (compile-file "mm:mm.lisp")
3870 The first line sets up a search list, so that the matchmaker sources can be
3871 found. The second line compiles the file containing a function for compiling
3872 the matchmaker sources. The third line loads the file just
3873 compiled, and the final line invokes the function compile-mm which compiles the
3874 matchmaker sources. For each file, a .fasl and .err file is generated. Also,
3875 a log of the compiler output is printed to the terminal.
3877 This step takes about 15 minutes
3879 @section(Generating Lisp Source Files from Matchmaker Definition Files)
3880 The following sequence of commands is necessary to generate the Lisp
3881 files for the Mach interface:
3883 (setf (search-list "mm:") '("/usr/lisp/mm/"))
3884 (setf (search-list "idefs:") '("/usr/lisp/idefs/"))
3885 (setf (search-list "icode:") '("/usr/lisp/icode/"))
3886 (setf (search-list "code:") '("/usr/lisp/code/"))
3887 (setf (default-directory) "/usr/lisp/icode/")
3888 (load "code:mm-interfaces.lisp")
3890 The first four lines set up search lists for mm (matchmaker sources), idefs
3891 (matchmaker interface definition files), icode (Lisp matchmaker interface
3892 sources), and code (Lisp code sources). The fifth line changes the current
3893 working directory to be /usr/lisp/icode. This is where the output from
3894 matchmaker will be placed. And finally, the last line invokes matchmaker on
3895 the matchmaker definition files for all the interfaces.
3897 Matchmaker generates three files for each interface XXX:
3899 XXXdefs.lisp@\contains constants and record definitions for the interface.
3901 XXXmsgdefs.lisp@\contains definitions of offsets to important fields in the
3902 messages that are sent to and received from the interface.
3904 XXXuser.lisp@\contains code for each remote procedure, that sends a message
3905 to the server and receives the reply from the server (if appropriate).
3906 Each of these functions returns one or more values. The first value
3907 returned is a general return which specifies whether the remote procedure
3908 call succeeded or gives an indication of why it failed. Other values may
3909 be returned depending on the particular remote procedure. These values are
3910 returned using the multiple value mechanism of Common Lisp.
3913 This step takes about five minutes.
3915 @section(Compiling Matchmaker Generated Lisp Files)
3916 To compile the matchmaker generated Lisp files the following steps should
3919 (setf (search-list "code:") '("/usr/lisp/code/"))
3920 (setf (search-list "icode:") '("/usr/lisp/icode/"))
3921 (load "code:comutil.lisp")
3923 The first two lines set up search lists for the code and icode directory.
3924 The final line loads a command file that compiles the Mach interface
3925 definition in the correct order. Note that once the files are compiled,
3926 the XXXmsgdefs files are no longer needed. The file
3927 /usr/lisp/icode/lossage.log contains a listing of all the error messages
3928 generated by the compiler.
3930 This step takes about fifteen minutes.
3932 @section(Compiling the Common Lisp Object System)
3934 To compile the Common Lisp Object System (CLOS) do the following:
3936 (setf (search-list "pcl:") '("/usr/lisp/pcl/"))
3937 (rename-package (find-package "CLOS") "OLD-CLOS")
3938 (compile-file "pcl:defsys.lisp")
3939 (load "pcl:defsys.fasl")
3942 The first line sets up a search list as usual. The second line renames the
3943 CLOS package to be the OLD-CLOS package. This is so that the current version
3944 of CLOS doesn't interfere with the compilation process. The third line
3945 compiles a file containing some functions for building CLOS. The fourth
3946 line loads in the result of the previous compilation. The final line
3947 compiles all the CLOS files necessary for a working CLOS system.
3949 The file /usr/lisp/pcl/test.lisp is a file that contains some test functions.
3950 To run it through CLOS build a new Lisp and start up a fresh Lisp
3951 resulting from the build and do the following:
3954 (compile-file "/usr/lisp/pcl/test.lisp")
3955 (load "/usr/lisp/pcl/test.fasl")
3957 This sequence of function calls puts you in the CLOS package, compiles the
3958 test file and then loads it. As the test file is loaded, it executes several
3959 tests. It will print out a message specifying whether each test passed or
3962 Currently, CLOS is built into the standard core.
3964 This step takes about 30 minutes.
3966 @section(Compiling Genesis)
3967 To compile genesis do the following:
3969 (compile-file "/usr/lisp/clc/genesis.lisp")
3971 Genesis is used to build a cold core file. Compiling Genesis takes about five
3974 @section(Building a Cold Core File)
3975 Once all the files have been assembled or compiled as described above, it is
3976 necessary to build a cold core file as follows:
3978 (setf (search-list "code:") '("/usr/lisp/code/"))
3979 (setf (search-list "icode:") '("/usr/lisp/icode/"))
3980 (setf (search-list "msc:") '("/usr/lisp/miscops/"))
3981 (load "/usr/lisp/clc/genesis.fasl")
3982 (load "code:worldbuild.lisp")
3984 The first three lines set up search lists for the code, icode, and miscops
3985 subdirectories. The fourth line loads in the program Genesis which builds
3986 the cold core file. The last line calls Genesis on a list of the files that
3987 are necessary to build the cold core file. As each file is being processed,
3988 its name is printed to the terminal. Genesis generates two files:
3989 /usr/lisp/ilisp.core and /usr/lisp/lisp.map. Ilisp.core is the cold core
3990 file and lisp.map is a file containing the location of all the functions
3991 and miscops in the cold core file. Lisp.map is useful for debugging the
3994 This step takes from about fifteen minutes.
3996 @section(Building a Full Common Lisp)
3997 The cold core file built above does not contain some of the more useful
3998 programs such as the compiler and hemlock. To build these into a core, it is
3999 necessary to do the following:
4001 lisp -c /usr/lisp/ilisp.core
4003 (load (open "/usr/lisp/code/worldload.lisp"))
4005 The first line invokes the lisp startup program specifying the cold core
4006 file just built as the core file to load. This cold core file is set up
4007 to do a significant amount of initialization and it is quite possible that
4008 some bug will occur during this initialization process. After about a
4009 minute, you should get a prompt of the form:
4011 CMU Common Lisp kernel core image 2.7(?).
4012 [You are in the Lisp Package.]
4015 The following two lines should then be entered. The first of these puts
4016 you into the User package which is the package you should be in when the
4017 full core is first started up. It is necessary to add this line, because
4018 the current package is rebound while a file is loaded. The last line loads
4019 in a file that loads in the compiler, hemlock, and some other files not yet
4020 loaded. The open call is @b[essential] otherwise when the full core is
4021 started up, load will try to close the file and probably invalidate memory
4022 that is needed. When load is passed a stream, it does not automatically
4023 close the stream. With a file name it now does after a recent bug fix.
4024 This file prompts for the versions of the Lisp system, the compiler, and
4025 hemlock. You should enter versions that make sense for your installation.
4026 It then purifies the core image. Up to this point most of the Lisp system
4027 has been loaded into dynamic space. Only a few symbols and some other data
4028 structures are in static space. The process of purification moves Lisp
4029 objects into static and read-only space, leaving very little in dynamic
4030 space. Having the Lisp system in static and read-only space reduces the
4031 amount of work the garbage collector has to do. Only those objects needed
4032 in the final core file are retained. Finally, a new core file is generated
4033 and is written to the file /usr/lisp/nlisp.core. Also, the currently
4034 running Lisp should go through the default initialization process, finally
4035 prompting for input with an asterisk. At this point you have successfully
4036 built a new core file containing a complete Common Lisp implementation.
4038 This step takes about thirty minutes.
4041 Debugging Lisp code is much easier with a fully functional Lisp. However, it
4042 is quite possible that a change made in the system can cause a bug to happen
4043 while running the cold core file. If this happens, it is best to use adb to
4044 track down the problem. Unfortunately, the core file (i.e., the
4045 remains of a process normally created by Unix when a process dies) generated by
4046 such a bug will be of no use. To get some useful information, follow these
4049 Look at the file /usr/lisp/lisp.map and find the entry points for the
4050 miscop routines error0, error1, and error2. These entry points are
4051 used to invoke the Lisp error system from the miscops. Write down
4052 the numbers beside these names. They are the addresses (in hex) of where
4053 the miscops are located when the cold core file is loaded into memory.
4055 Run adb on the lisp file, i.e.:
4060 Set a breakpoint at the lispstart entry point:
4065 Start the lisp program running, telling it to use ilisp.core (I'm
4066 assuming you're in /usr/lisp):
4071 After a while, you will hit the lispstart breakpoint. The core file has been
4072 mapped into memory, but control is still in the C startup code. At this point,
4073 you should enter breakpoints for all the error entry points described above.
4075 Continue running the program by typing :c. Shortly after this, the C lisp
4076 program will give up control to Lisp proper. Lisp will start doing its
4077 initialization and will probably hit one of the error break points.
4078 At that point you can look around at the state and try and discover
4079 what has gone wrong. Note that the two files rg and st are useful at this
4080 point. Also, you should look at the document @i[Internal Design of Common
4081 Lisp on the IBM RT PC] by David B. McDonald, Scott E. Fahlman, and Skef
4082 Wholey so that you know the internal data structures.
4085 @section(Running the Soar Benchmark)
4086 To compile the soar benchmark, you should do the following:
4088 (compile-file "/usr/lisp/demos/soar/soar.lisp")
4091 To run the benchmark, you should start up a fresh Lisp and do the following:
4093 (load "/usr/lisp/demos/soar/soar.fasl")
4094 (load "/usr/lisp/demos/soar/default.soar")
4095 (load "/usr/lisp/demos/soar/eight.soar")
4096 (user-select 'first)
4100 The first two lines load in the standard Soar system. The third line loads in
4101 information about the eight puzzle which is a standard Soar puzzle that has
4102 been run on several different machines. The fourth line sets up the puzzle
4103 conditions so that it will select a goal to work on automatically. The fifth
4104 line initializes Soar's working memory, etc. The final line is the one that
4105 actually runs the benchmark. Soar prints out a fair amount of information as
4106 it solves the puzzle. The final state should be numbered 143 when it finishes.
4107 The time macro prints out information about information various resources after
4108 the eight puzzle has run.
4111 I have tried to present sufficient information here to allow anyone to be
4112 able to build a Common Lisp system under Mach from the sources. I am sure
4113 there are many tricks that I have learned to use to reduce the amount of grief
4114 necessary to build a system. My best recommendation is to go slowly. Start
4115 by building a system from the sources provided on the tape. Make sure you
4116 are comfortable doing that before you try modifying anything.
4118 Some hints on building the system which you may find useful:
4120 If you change the compiler, you will have to recompile all the sources before
4121 the change is reflected in a system. Changing the compiler is probably the
4122 most dangerous change you can make, since an error here means that
4123 nothing will work. In particular, this is the time you are going to need
4124 to get familiar with adb and the internal structure of the Lisp, since a
4125 serious error in the compiler will show up during the initialization of the
4128 Changing the miscops should be done with care. They follow a fairly rigid
4129 convention and you should understand all the information provided in
4130 @i[Internal Design of Common Lisp on the IBM RT PC] before making any changes
4131 to miscops. You will probably need to get familiar with adb to debug some of
4132 the changes. Note that this requires building a new cold core file and a final
4133 core file before the change is reflected in the system.
4135 Changing sources in the code directory should be fairly straight forward. The
4136 only time this will cause trouble is if you change something that a lot of
4137 files depend on in which case you will have to recompile everything and build
4138 a new cold core file and a core file.
4140 Changing hemlock should have no adverse effect on system integrity.
4142 If you make a fairly major change, it is a good idea to go through the complete
4143 process of building a core file at least two or three times. If things are
4144 still working at the end of this, your change is probably correct and shouldn't
4145 cause any serious trouble.
4147 Finally, always keep at least one backup copy of a good core image around.
4148 If you build a bad core file over an existing one and can't back up, it is
4149 possible that you may not be able to recover from a serious error.