;;; -*- Mode:Text; Base:10.; Package:User;-*-
THE DISASSEMBLER                               



Introduction             22.1 Studying the machine language code (or macrocode) produced by the
			Explorer's compiler can be useful in analyzing errors or in checking for a
			suspected compiler problem. This section explains how the Explorer instruction
			set works and how to understand the behavior of code written in this
			instruction set. Fortunately, the translation between Lisp and this instruction
			set is not difficult. Once you become familiar with the instruction set, you can
			easily move between the two representations. This section requires no special
			knowledge of the Explorer system, although you should be somewhat familiar
			with computer science in general.

			No one examines machine language code by manually interpreting octal numbers.
			Instead, a program called the disassembler converts the numeric representation
			of the instruction set into a more readable textual representation. This program
			is called the disassembler because it does the opposite of what an assembler
			does. No assembler accepts this input, however, since the Explorer system
			requires no written assembly language.

			The error handler and the Inspector also use the disassembler. If you see code
			similar to that in Example 2 (later in this section) while using either the error
			handler or the Inspector, it is disassembled code in the same format as the 
			disassemble function uses. Inspecting a compiled code object shows the
			disassembled code.
------------------------------------------------------------------------------------------------     

The disassemble           22.2 The simplest way to invoke the disassembler is with the disassemble
Function                 function. 

               disassemble function &key :base :verbose :start :end                                 [c] Function
			This function prints a humanly readable version of the instructions in function
			.

                          function - This argument should be a function object, lambda expression, a
			    closure, or a function spec with a function definition. If the function is not
			    compiled, a compiled version is generated, although this version is not
			    used to update the function spec.
                          :base - This keyword manipulates the print base for all numbers output by this
			    function. The default value for this parameter is the value of *print-base*.
                          :verbose - This keyword enables the printing of the numeric representation of
			    the macrocode. The numeric base is octal (8.) unless :base is 16.
                          :start, :end - These keywords allow you to specify that only a portion of the
			    macrocode is to be printed. The :start keyword specifies where in the
			    macrocode to start printing, and the :end keyword specifies where to stop
			    printing.

			The display format is also affected by the *print-case* variable. To see a simple
			example of disassembly, enter the code in Example 1:

            Example 1:                  (defun foo (x)
			 (assoc 'key (cdr (get x 'propname))))
			  
			(compile 'foo)
			  
			(disassemble 'foo)

			The code you just entered defines the function foo, compiles it, and invokes the
			disassembler to print the textual representation of the result of the compilation.
			The disassembled code should appear similar to that in Example 2.

            Example 2:                  12 PUSH                      FEF|3         ; 'KEY
			13 PUSH                      ARG|0         ; X
			14 PUSH-GET                                FEF|4          ; 'PROPNAME
			15 (MISC) PUSH CDR
			16 RETURN CALL-2             FEF|5         ; #'SYS:ASSOC-EQL

			Before translating the disassembled code into its component actions, you must
			first become familiar with some terminology.

			The acronym PDL stands for push-down list. A PDL is a stack, a last-in
			first-out (LIFO) memory. You will see the terms PDL and stack used
			interchangeably. The Explorer system's architecture is typical of stack
			machines; that is, it has a stack (PDL) with which most instructions deal. The
			stack holds the following items:

                          J       Values being computed

                          J       Arguments

                          J       Local variables

                          J       Flow-of-control information (function call frames and the like)

			An important use of the stack is to pass arguments to instructions, though not
			all instructions take their arguments from the stack.

			After the defun form above is evaluated, the function cell of the symbol foo contains
			a lambda expression. When the function foo is compiled, the contents of the
			function cell are replaced by a compiled function object. The printed
			representation of the compiled function object for foo appears as follows:

			#<DTP-FUNCTION FOO 11464337>

			Stated somewhat simply, the compiled function has three parts:

                          J       A header with various fixed-format fields

                          J       A part holding constants and invisible pointers

                          J       The main body, holding the machine language instructions (macrocode)

			Compiled functions are also called function entry frames (FEFs).

			The first part, the header, is not discussed in this manual. You can look at a
			representation of the information contained in the header with the describe 
			function.

			The second part holds various constants referred to by the function; for
			example, the function foo refers to two constants (the symbols key and propname
			), so pointers to these symbols are saved. This part of the function also holds
			invisible pointers to the value cells of all symbols that the function uses as
			special variables or calls as functions.

			The third part holds the macrocode itself.

			Now you can read the disassembled code. The first instruction from the
			preceding example appears as follows:

			12 PUSH                      FEF|3         ; 'KEY

			This instruction has several parts. The 12 is the address of this instruction
			within the compiled function. The disassembler prints out the address of each
			instruction before it prints out the instruction so that you can interpret
			branching instructions when you see them (one of these is discussed later in
			this section). You can control the base of the address printed by using the :base
			keyword.

			The PUSH moves a piece of data from one place onto the stack.

			The next field of the instruction is FEF|3. This is an address that specifies
			where the data item comes from. The vertical bar serves to separate the two parts
			of the address. The part before the vertical bar can be thought of as a base
			register, and the part after the bar can be regarded as an offset from this
			register (which is zero-origined). FEF as a base register means the address of
			the FEF that you are disassembling, so this address denotes the location four
			words into the FEF (zero-origined). Thus, this instruction takes the data
			located four words into the FEF and pushes it onto the PDL. 

			The instruction is followed by a comment field, which looks like ;'KEY. This is
			not a comment written by a person; the disassembler produces these comments to
			explain what is going on. The semicolon serves to start the comment the way
			semicolons in Lisp code do. In this case, the body of the comment, 'KEY, tells
			you that the address field (FEF|3) is addressing a constant (this is what the
			single quotation mark in 'KEY means) and that the printed representation of
			this constant is KEY. This comment helps explain what this instruction is
			actually doing: it is pushing (a pointer to) the key symbol onto the stack.

			The next instruction is as follows:

			13 PUSH                      ARG|0         ; X

			This is much like the previous instruction; the only difference is that a
			different base register is being used in this address. The ARG base register is
			used for addressing your arguments: ARG|0 means that the data item being
			addressed is the zeroth argument. Again, the comment field explains that the
			value of X (which was the zeroth argument) is being pushed onto the stack.

			The third instruction is as follows:

			14 PUSH-GET                                FEF|4          ; 'PROPNAME

			This instruction is much like the previous two; however, it differs in that it
			pushes the value of a symbol's property and thus uses two arguments. The
			symbol is received from the top of the stack (the result of the preceding
			instruction X), and the property name is received with the FEF|4 base
			addressing described previously.

			The fourth instruction is something new:

			15 (MISC) PUSH CDR

			The (MISC) form means that this is one of the so-called miscellaneous instructions.
			There are quite a few of these instructions. With some exceptions, each
			miscellaneous instruction corresponds to a Lisp function and has the same
			name as this Lisp function. If a Lisp function has a corresponding
			miscellaneous instruction, then this function is implemented in Explorer
			microcode.

			Miscellaneous instructions only have a destination field; they do not have any
			address field. The input to the instruction comes from the stack: the top n elements
			on the stack are used as input to the instruction and popped off the stack,
			where n is the number of arguments taken by the function. The result of the
			function is stored wherever indicated by the destination field. In this case, the
			function being executed is cdr, a Lisp function of one argument. The top value
			is popped off the stack and used as the argument to cdr (generally, the value
			pushed first is the first argument; the value pushed second is the second
			argument, and so on). Functions that have optional arguments or that return
			multiple values cannot become miscellaneous instructions. Functions that
			return multiple values are almost never miscellaneous instructions.

			The fifth and last instruction is as follows:

			16 RETURN CALL-2             FEF|5         ; #'SYS:ASSOC-EQL

			This is a CALL macroinstruction, which is discussed in more detail in
			paragraph 22.4.4, Call Instructions. Here the function at FEF|5 (
			SYS:ASSOC-EQL) is called with two arguments (CALL-2). Also, the result of
			this function call is returned (RETURN) as the result of the function foo.

			The original Lisp program compiled is as follows:

			(defun foo (x)
			 (assoc 'key (cdr (get x 'propname))))

			Now, recall the program as a whole and observe what it produces:

			12 PUSH                      FEF|3         ; 'KEY
			13 PUSH                      ARG|0         ; X
			14 PUSH-GET                                FEF|4          ; 'PROPNAME
			15 (MISC) PUSH CDR
			16 RETURN CALL-2             FEF|5         ; #'SYS:ASSOC-EQL

			First, it pushes the key symbol. Then it pushes the value of x. Then it invokes 
			push-get, which pops the value of x, gets the propname symbol from FEF|4, and
			uses them as arguments, thus performing the equivalent of evaluating the
			following form:

			(get x 'propname)

			The result is pushed on the stack, which now contains the result of the get on
			top and the symbol key underneath that. Next, it invokes cdr on the result of
			the get, thus performing the equivalent of evaluating the following form:

			(cdr (get x 'propname))

			Finally, it calls the function using the result of the cdr and the symbol key,
			thus performing the equivalent of evaluating the following form:

			(assoc 'key (cdr (get x 'propname)))

			The code produced by the compiler is correct: it produces the same result as the
			function you defined (SYS:ASSOC-EQL is a compiler optimization of assoc).

			The following four examples show the use of disassemble with each of the four
			keywords. Example 3 demonstrates the use of the :base keyword:

            Example 3:                  (disassemble 'foo :base 16.)

			The disassembled code appears as follows:

			 C PUSH                           FEF|3            ; 'KEY
			 D PUSH                              ARG|0            ; X
			 E PUSH-GET                                   FEF|4          ; 'PROPNAME
			 F (MISC) PUSH CDR
			10 RETURN CALL-2                  FEF|5            #'SYS:ASSOC-EQL

			Example 4 shows the use of the :verbose keyword, which is set to t:

            Example 4:                  (disassemble 'foo :verbose t)

			The disassembled code appears as follows. Note that a macroinstruction word is
			16 bits long and is displayed as six octal digits:

			12 050003 PUSH                    FEF|3            ; 'KEY
			13 050600 PUSH                    ARG|0            ; X
			14 057004 PUSH-GET                FEF|4            ; 'PROPNAME
			15 041003 (MISC) PUSH CDR
			16 112005 RETURN CALL-2           FEF|5            ; #'SYS:ASSOC-EQL

			Example 5 shows the use of both :base and :verbose:

            Example 5:                  (disassemble 'foo :verbose t :base 16.)

			The disassembled code appears as follows:

			 C 5003 PUSH                      FEF|3            ; 'KEY
			 D 5180 PUSH                         ARG|0            ; X
			 E 5E04 PUSH-GET                     FEF|4            ; 'PROPNAME
			 F 4203 (MISC) PUSH CDR
			10 9405 RETURN CALL-2             FEF|5            ; #'SYS:ASSOC-EQL

			Notice that :base affects both the instruction address and the numeric
			representation.

			Example 6 shows the use of the two previous keywords and the :start and :end 
			keywords:

            Example 6:                  (disassemble 'foo :verbose t :base 16. :start 12. :end 14.)

			The disassembled code appears as follows:

			C 5003 PUSH                                FEF|3          ; 'KEY
			D 5180 PUSH                                ARG|0          ; X

			In summary, four kinds of instructions have been presented thus far: the PUSH
			instruction, which takes an address for an operand and places the operand onto
			the stack; the PUSH-GET instruction, which uses two operands and thus must
			pop one of them off the stack; the (MISC) instruction, one of the members of the
			large set of miscellaneous instructions, which take only a destination and
			implicitly receive their input from the stack; and, finally, the CALL instruction,
			which returns as the result of the function the single value returned by the 
			SYS:ASSOC-EQL function call. Moreover, two forms of addressing (FEF
			addressing and ARG addressing) have been discussed. 
------------------------------------------------------------------------------------------------     

An Advanced                22.3 Example 7 is a more complex function than those discussed in the
Example                   previous paragraph demonstrating local variables, function calling, conditional
			branching, and some other new instructions.

            Example 7:                  (defun bar (y)
			 (let ((z (car y)))
			   (cond ((atom z)
			          (setq z (cdr y))
			          (foo y))
			         (t nil))))
			(disassemble 'foo)
			 8 PUSH-CAR                                ARG|0          ; Y
			 9 POP                          LOCAL|0       ; Z
			10 BR-NOT-ATOM  15
			11 PUSH-CDR                                ARG|0          ; Y
			12 POP                       LOCAL|0       ; Z
			13 PUSH                      ARG|0         ; Y
			14 RETURN CALL-1             FEF|3         ; #'FOO
			15 (AUX) RETURN-NIL

			The first instruction here is a PUSH-CAR instruction that has the same format
			as PUSH: with a destination and an address. The PUSH-CAR instruction reads
			the data addressed by the address, takes the car of it, and pushes the result
			onto the stack. In our example, the first instruction addresses the zeroth
			argument, so it computes the following:

			(car y)

			Then it pushes the result onto the stack (the destination).

			The next instruction is something new: the POP instruction. It has an address
			field, but it uses this field as a destination rather than as a source. The POP 
			instruction pops the top value off the stack and stores this value into the
			address specified by the address field. In our example, the value on the top of
			the stack is popped off and stored into address LOCAL|0. This is a new form of
			address, which means the zeroth local variable. 

			The ordering of the local variables is chosen by the compiler, so it is not fully
			predictable, although it tends to be by order of appearance in the code. Fortunately,
			you seldom have to look at these numbers because the comment field explains
			what is going on. In this case, the variable being addressed is z. Thus, this
			instruction pops the top value on the stack into the variable z. The first two
			instructions work together to take the car of y and store it into z, which is
			indeed the first action that the function bar should take. 

			If you have two local variables with the same name, as happens with lexical
			shadowing, then the comment field does not distinguish between the two. You
			can distinguish between two local variables with the same name by looking at
			the number in the address.

			Every instruction that moves or produces a data item sets the indicator bits from
			this data item so that subsequent instructions can test them. As a result, the POP
			instruction allows someone to test the indicators set up by the value that was
			moved, namely the value of z .

			The next instruction is a conditional branch, which changes the flow of control
			on the basis of the values in the indicator bits. The instruction is BR-NOT-ATOM
			15, which means "Branch, if the quantity was not an atom, to location 15;
			otherwise, proceed with execution". If z was not an atom, execution branches to
			location 15 and proceeds from there. Location 15 contains a RETURN-NIL 
			instruction, which causes the function to return nil.

			If z is an atom, the program continues, and the PUSH-CDR instruction is
			executed next. This instruction resembles PUSH-CAR except that it takes the
			cdr. It pushes onto the stack the value of the following:

			(cdr y)

			The next instruction pops this value off into the z variable.

			The last two instructions provide an example of how function calling is
			compiled. The following demonstrates how it works in our example:

			13 PUSH                      ARG|0         ; Y
			14 RETURN CALL-1             FEF|3         ; #'FOO

			The form being compiled here is the following:

			(foo y)

			Thus, you apply the function in the function cell of the symbol foo and pass it
			one argument: the value of y. Simple function calling works in the following two
			steps. First, all the arguments being passed to the function are pushed onto the
			stack. Second, the CALL-1 instruction specifies the function object being
			applied to the arguments. This instruction creates a new stack frame on the
			stack and stores the function object there. There are variations to the CALL-1 
			macroinstruction, namely CALL-0 to CALL-6 and CALL-N. The number
			following the CALL- indicates the number of arguments that the function object
			expects. CALL-N is a generic calling macroinstruction. After N arguments are
			pushed, then the actual number of the arguments, N, is pushed and the
			instruction CALL-N is invoked. For example, if a function is called with seven
			arguments, the seven arguments are pushed, then the number 7 is pushed, and
			finally the CALL-N macroinstruction is invoked specifying the function object
			to call.

			When the function returns, the destination field of the CALL-1 instruction
			determines what happens to the returned value (RETURN). When the function
			actually returns, its result is stored into this destination. A destination of RETURN
			causes the result of the function call also to be the value returned from this
			function.

			Thus, in the two-instruction sequence above, the first instruction is a PUSH;
			the value to push is located at ARG|0, which, as the comment indicates, is the
			value Y. Next, the CALL-1 instruction is executed; the function object it
			specifies is at FEF|3, which, as the comment indicates, is the contents of the
			function cell of FOO (the FEF contains an invisible pointer to this function
			cell). The destination field of the CALL-1 is RETURN, indicating that the
			result of this function call is also the returned value for this function.

			The following is another example to illustrate function calling. This Lisp
			function calls one function on the results of another function:

            Example 8:                  (defun a (x y)
			 (b (c x y) y))

			The disassembled code is as follows:

			10 PUSH                      ARG|0         ; X
			11 PUSH                      ARG|1         ; Y
			12 PUSH CALL-2               FEF|3         ; #'C
			13 PUSH                      ARG|1         ; Y
			14 RETURN CALL-2             FEF|4         ; #'B

			The first two macroinstructions push the arguments x and y for the function c.
			Next, the function c is called with the CALL-2 macroinstruction. Notice that
			the destination of this call is PUSH, indicating that the result of the function
			call is to be pushed onto the stack. Then the argument y is pushed for the
			function b (the other argument is the result of the CALL-2). Finally, the
			function b is called with two arguments on the stack and with a destination of 
			RETURN, indicating that the value returned by b is also to be returned as the
			result of function a.
------------------------------------------------------------------------------------------------     

Macroinstruction            22.4 In general, macroinstructions fall into seven classes:
Classes
                          J       Main operations (or main ops)

                          J       Short branches

                          J       Immediate operations

                          J       Call instructions

                          J       Miscellaneous operations (or misc ops)

                          J       Auxiliary operations (or aux ops)

                          J       Module operations (or module ops)

			The instruction set is defined by the file SYS:UCODE;DEFOP.LISP, which uses
			several special forms that are defined in the file SYS:COMPILER;TARGET. What
			follows is a description of the various instruction formats. See the Explorer
			System Software Design Notes for more detailed information about individual
			macroinstructions.

			                                                                          


              Main Operation  22.4.1 Main op instructions have an operand address as part of the instruc-
              Instructions        tion (like PUSH, described earlier) and can take additional operands from the
			stack (like PUSH-GET, described earlier). The result of the main op is implied
			by the operation; for example, PUSH places the result on the top of the stack.
			Table 22-1 lists the 54 main ops.

                          ------------------------------------------------------------------------   
Table 22-1                  Main Operation Instructions
                          ------------------------------------------------------------------------   
			ARRAYP             POP                                       SETE-1+
			BIND-CURRENT         PUSH                                 SETE-1-
			BIND-NIL             PUSH-AR-1                                STRINGP
			BIND-POP            PUSH-CADDR                           TEST
			BIND-T                 PUSH-CADR                         TEST-CAAR
			EQ                  PUSH-CAR                              TEST-CADR
			EQL                      PUSH-CDDR                               TEST-CAR
			EQUAL                    PUSH-CDR                             TEST-CDDR
			EQUALP                  PUSH-CDR-STORE-CAR-IF-CONS         TEST-CDR
			FIXNUMP               PUSH-CONS                          TEST-MEMQ
			INTEGERP                PUSH-GET                             1+
			LISTP                PUSH-LOC                              1-
			LOGAND             RETURN                                +
			LOGXOR                 SET-NIL                                -
			MINUSP                   SET-T                                    *
			MOVEM             SET-ZERO                           =
			NUMBERP           SETE-CDDR                           >
			PLUSP                  SETE-CDR                                <
			--------------------     ------------------------------------    -----------   ---       
			The PUSH instruction has already been discussed. PUSH-CADDR, PUSH-CADR,
			PUSH-CAR, PUSH-CDDR, and PUSH-CDR are similar to PUSH except that the 
			CADDR, CADR, CAR, CDDR, or CDR, respectively, is taken from the operand
			addressed as part of the instruction and returned on top of the stack.

			PUSH-CONS and PUSH-AR-1 are similar to PUSH-GET in that an additional
			operand is taken from the stack. PUSH-CONS pops the car from the stack,
			receives the cdr from the addressed operand, and pushes the resultant cons on
			the stack. PUSH-AR-1 is used to access elements within a one-dimensional
			array. The index for the array element to be accessed is taken from the stack,
			and the array itself is received from the addressed operand. The resultant array
			element is pushed on the stack. The stack level does not change with PUSH-GET
			, PUSH-CONS, or PUSH-AR-1.

			PUSH-CDR-STORE-CAR-IF-CONS is used primarily to implement the Lisp form 
			dolist. Consider the following example:

            Example 9:                  (defun p (list)
			   (dolist (x list)
			      (print x)))

			The disassembled code is as follows:

			 8 PUSH                                    ARG|0          ; LIST
			 9 PUSH-CDR-STORE-CAR-IF-CONS          LOCAL|0        ; X
			10 BR-NULL                                                14
			11 PUSH                                    LOCAL|0        ; X
			12 TEST CALL-1                             FEF|3          ; #'PRINT
			13 BR                                      9
			14 (AUX) RETURN-NIL

			In this example, instruction 8 pushes onto the stack the argument for the
			function (list). Instruction 9 is the new instruction 
			PUSH-CDR-STORE-CAR-IF-CONS. This instruction takes its first argument
			from the stack (list in this case) and its second argument from the specified
			address (LOCAL|0). This instruction pops list, and if list is a cons, then it
			pushes the cdr of list to replace it and stores the car of list in LOCAL|0. If list 
			is not a cons (which is eventually the case because successive cars of list are
			removed), then nothing is pushed or stored and the symbol nil is left in the
			indicators. Instruction 10 checks for this last case and branches to instruction
			14 when the end of list is reached. Instruction 11 immediately retrieves the car
			of list stored in LOCAL|0 by PUSH-CDR-STORE-CAR-IF-CONS. This car is
			used as a functional argument for print, which is called in instruction 12 with
			the CALL-1 instruction. The destination type TEST in the CALL-1 instruction
			implies that the result of the print functional call is not used (it is not pushed
			on the stack or returned as the result of this function). Rather, only the
			indicators are set in case the code desires to test it. Instruction 13 is an
			unconditional branch to instruction 9. Instruction 14 (an aux op) is executed
			when all of list has been traversed and returns nil as the result of this
			function.

			The TEST instructions (TEST, TEST-CAAR, TEST-CADR, TEST-CAR, TEST-CDDR
			, and TEST-CDR) are exactly like their associated PUSH instructions except that
			these instructions have the same destination type as the CALL-1 instruction in
			the previous example. That is, the result of these instructions is not pushed on
			the stack but is used only to set the indicators for immediate testing (the
			conditional branch instructions).

			TEST-MEMQ is used to set the indicators based on the result of a MEMQ on the
			list received from the addressed operand and the element popped off the stack.
			This instruction corresponds to the Common Lisp function member with a :test 
			argument of #'eq.

			The two instructions 1+ and 1- are examples of frequently used one-argument
			functions. These instructions take their argument from the specified address,
			increment or decrement this argument, and leave the result of top of the stack.

			Five main op instructions implement heavily used two-argument functions: +, -
			, *, LOGAND, and LOGXOR. These instructions take their first argument from
			the top of the stack (popping it off) and their second argument from the
			specified address. Then, they push their result on the stack. Thus, the stack
			level does not change because of these instructions.

			The following small function shows some of the previously mentioned main ops:
            Example 10:                 (defun foo (x y)
			 (setq x (logxor y (* x 5.))))

			The disassembled code is as follows:
			 6 PUSH-NUMBER               5
			 7 *                         ARG|0         ; X
			 8 LOGXOR                       ARG|1         ; Y
			 9 MOVEM                        ARG|0         ; X
			10 RETURN                    PDL-POP

			Instructions 7 and 8 use two of the new main op instructions: the * and LOGXOR
			instructions. Instruction 9 uses the MOVEM instruction; the compiler wants to
			use the top value of the stack to store it into the value of x, but it does not want
			to pop it off the stack because it plans to return it from the function.
			Instruction 10 then returns the argument addressed by its operand, PDL-POP.
			Another 15 main op instructions implement some commonly used predicates: 
			ARRAYP, EQ, EQL, EQUAL, EQUALP, FIXNUMP, INTEGERP, LISTP, MINUSP,
			NUMBERP, PLUSP, STRINGP, =, >, and <. The arguments come from the top of
			the stack (if two arguments are needed) and the specified address; the stack is
			popped, the predicate is applied to the two objects, and the result is left in the
			indicators so that a branch instruction can test it and then branch, according to
			the result of the comparison. These instructions remove the top item on the
			stack and do not put anything back.
			Next, four main op instructions read, modify, and write a quantity in ways that
			are common in Lisp code. These instructions are SETE-CDR, SETE-CDDR, 
			SETE-1+, and SETE-1-. The SETE- means to set the addressed value to the
			result of applying the specified one-argument function to the present value. For
			example, SETE-CDR means to read the value addressed, apply cdr to it, and store
			the result back in the specified address. This instruction is used when
			compiling the following form, which commonly occurs in loops:
			(setq x (cdr x))

			Four instructions bind special variables (that is, they save the current value of
			the variable), but they differ in what they bind the variable with. The first, 
			BIND-NIL, binds the cell addressed by the address field to nil; the second, 
			BIND-POP, binds the cell to an object popped off the stack. The third
			instruction, BIND-T, binds the cell addressed by the address field to T. The
			fourth instruction, BIND-CURRENT, binds the cell to its current value (that
			is, it leaves its value as it was).
			Three instructions store common values into addressed cells. SET-NIL stores nil
			into the cell specified by the address field, SET-ZERO stores 0, and SET-T stores
			T. These instructions do not use the stack at all.
			Finally, the PUSH-LOC instruction creates a locative pointer to the cell
			referenced by the specified address and pushes it onto the stack. This
			instruction is used in compiling the following form:
			(variable-location z)

			In this example, z is an argument or a local variable rather than a special
			variable.

			Example 11 uses some of these instructions to show what they look like:

            Example 11:                 (defvar *foo*)
			(defvar *bar*)
			(defun weird (x y)
			   (cond ((= x y)
			          (let ((*foo* nil) (*bar* 5))
			            (setq x (cdr x)))
			          nil)
			         (t
			          (setq x nil)
			          (caar (variable-location y)))))

			The disassembled code appears as follows:

			16 PUSH                      ARG|0         ; X
			17 =                         ARG|1         ; Y
			18 BR-NULL  24
			19 BIND-NIL                                FEF|3          ; *FOO*
			20 PUSH-NUMBER               5
			21 BIND-POP                                FEF|4          ; *BAR*
			22 SETE-CDR                                ARG|0          ; X
			23 (AUX) RETURN-NIL
			24 SET-NIL                   ARG|0         ; X
			25 PUSH-LOC                                ARG|1          ; Y
			26 (MISC) PUSH CAAR
			27 RETURN                    PDL-POP

			Instruction 17 is an = instruction; it numerically compares the top of the stack,
			x, with the addressed quantity, y. The x is popped off the stack, and the
			indicators are set to the result of the equality test. Instruction 18 checks the
			indicators, branching to instruction 24 if the result of = is nil; that is, the
			machine branches to 24 if the two values are not equal. Instruction 19 binds *foo*
			to nil. Instructions 20 and 21 bind *bar* to 5. Instruction 22 demonstrates the
			use of SETE-CDR to compile the following form:

			(setq x (cdr x))

			Instruction 24 demonstrates the use of SET-NIL to compile the form:

			(setq x nil)

			Instruction 25 demonstrates the use of PUSH-LOC to compile the form:

			(variable-location y)
                          ------------------------------------------------------------------------   

           Short Branch   22.4.2 Short branch instructions are the branch instructions that contain a
              Instructions        branch address rather than a general base-and-offset address. These
			instructions have neither addresses nor destinations of the usual sort. Instead,
			they have branch addresses and indicate where to branch if the branch is going
			to happen. Branching instructions differ in the conditions under which they
			branch and whether they pop the stack. Branch addresses are stored internally
			as self-relative addresses to make Explorer code relocatable, but the
			disassembler performs the addition for you and prints out FEF-relative
			addresses so that you can easily see where the branch is going. If the relative
			address into the FEF is too large for encoding within this instruction, the long
			branch instruction is used. Long branch instructions are discussed in
			paragraph 22.4.6.3, Long Branches.

			The branch instructions discussed so far decide whether to branch on the basis
			of the nil indicator, that is, whether the last value dealt with was nil or non-
			nil. BR-NIL branches if it was nil, and BR-NOT-NIL branches if it was not nil
			. Three other pairs of branch instructions use the atom, zerop, and symbolp 
			predicates, respectively. BR-ATOM branches if the value was an atom (that is,
			if it was anything besides a cons), and BR-NOT-ATOM branches if the value
			was not an atom (that is, if it was a cons). BR-ZEROP branches if the value is
			zero, and BR-NOT-ZEROP branches if the value is not zero. BR-SYMBOLP branches
			if the value is a symbol, and BR-NOT-SYMBOLP branches if the value was not
			a symbol.

			The BR instruction is an unconditional branch (it always branches).

			Table 22-2 lists all of the short branch instructions.

                          ------------------------------------------------------------------------   
Table 22-2                  Short Branch Instructions
                          ------------------------------------------------------------------------   
			BR                       BR-NOT-ATOM                   BR-NOT-ZEROP
			BR-ATOM                   BR-NOT-NIL                       BR-SYMBOLP
			BR-NIL                BR-NOT-NIL-ELSE-POP           BR-ZEROP
			BR-NIL-ELSE-POP           BR-NOT-SYMBOLP
			----------------------       ------------------------------    --------------- ---       
			None of the above branching instructions deal with the stack. The two
			instructions called BR-NIL-ELSE-POP and BR-NOT-NIL-ELSE-POP are the
			same as BR-NIL and BR-NOT-NIL except that if the branch is not performed,
			the top value on the stack is popped off the stack. These are used for compiling 
			and and or special forms.
                          ------------------------------------------------------------------------   

          Immediate Operation  22.4.3 Immediate operation instructions use the lower nine bits of the
              Instructions        instruction word (immediate operand) in special ways.

			No Lisp functions directly correspond to the immediate operations, which are
			used strictly by the compiler.

			A previous example has already shown the use of PUSH-NUMBER, which
			pushes the number in the lower nine bits of the instruction onto the stack. 
			PUSH-NEG-NUMBER negates the number before pushing it. PUSH-LONG-FEF 
			uses the immediate operand as an index into the current FEF and pushes the
			contents that reside at that location. This instruction is used only when the
			regular FEF base addressing can no longer reach the desired location.

			The =-IMMED, >-IMMED, <-IMMED, and EQ-IMMED instructions all perform
			the condition on the immediate operand and the value popped off the stack.
			Nothing is pushed as a result of these instructions, but the indicators are set.

			ADD-IMMED adds the immediate operand to the value on top of the stack. The
			result is left on top of the stack.

			LDB-IMMED uses the immediate operand to describe the bits to extract from the
			operand on top of the stack, and the resultant value is pushed on top of the
			stack. This immediate value is broken up into a five-bit position value
			(immediate operand bits 4 through 8) and a four-bit length value (immediate
			operand bits 0 through 3). Note that the format for this immediate value is
			different from that for a byte specifier.

			The DISPATCH instruction is similar to a BR instruction except that it allows a
			multiway transfer of control. The compiler uses the DISPATCH instruction to
			initialize optional arguments to a function. Consider the following example:

            Example 12:                 (defun f (&optional (a 1) (b 2) (c 3))
			   (list a b c))

			The disassembled code appears as follows:

			20 DISPATCH                                FEF|4          ; 
			[0->21;1->23;2->25;3->27;ELSE->27]
			21 PUSH-NUMBER               1
			22 POP                       ARG|0         ; A
			23 PUSH-NUMBER               2
			24 POP                       ARG|1         ; B
			25 PUSH-NUMBER               3
			26 POP                       ARG|2         ; C
			27 PUSH                      ARG|0         ; A
			28 PUSH                      ARG|1         ; B
			29 PUSH                      ARG|2         ; C
			30 RETURN CALL-3             FEF|3         ; #'LIST

			The DISPATCH instruction uses the number of &optional parameters supplied
			(this argument is supplied on top of the stack by the function-calling
			microcode) as the index into the table at FEF|4. The comment for the DISPATCH 
			instruction indicates where control will be transferred for the various number
			of &optional parameters supplied. For example, if no optional parameters are
			supplied, control is transferred to the instruction at 21 where a, b, and c are
			initialized. 

			The SELECT instruction uses the immediate operand as a nine-bit FEF offset,
			which addresses a select table. The value on top of the stack is looked up in
			this table. The offset of the selected slot within the select table is then used as
			an index into the dispatch table to allow a multiway transfer of control. The SELECT
			instruction is used by the compiler optimization of Lisp forms such as selectq and
			case. 

			The LEXICAL-UNSHARE and LOCATE-LEXICAL-ENVIRONMENT instructions
			use only the immediate operand and are used by the compiler in the
			implementation of lexical closures.

			Table 22-3 lists all the immediate operation instructions.

                          ------------------------------------------------------------------------   
Table 22-3                  Immediate Operation Instructions
                          ------------------------------------------------------------------------   
			ADD-IMMED                                  PUSH-NEG-NUMBER
			DISPATCH                                PUSH-NUMBER
			EQ-IMMED                                  SELECT
			LDB-IMMED                              =-IMMED
			LEXICAL-UNSHARE                        >-IMMED
			LOCATE-LEXICAL-ENVIRONMENT          <-IMMED
			PUSH-LONG-FEF                             
			-----------------------------------------       -----------    --------------- ---       
                          ------------------------------------------------------------------------   
        Call Instructions      22.4.4 The simple call instructions consist of CALL-0 through CALL-6 and 
			CALL-N. The base and offset field is used to specify the function to be called.
			The function arguments are pushed on the stack before executing these
			instructions. If the number of arguments is more than six, then the CALL-N 
			instruction is used, and the number of arguments is the last item pushed on
			the stack.

			Complex function calling (such as returning multiple values) is described in
			paragraph 22.4.6.1, Simple Aux Ops.

			Table 22-4 lists all the simple call instructions.

                          ------------------------------------------------------------------------   
Table 22-4                  Call Instructions
                          ------------------------------------------------------------------------   
			CALL-0                                         
			CALL-1                                         
			CALL-2                                         
			CALL-3                                         
			CALL-4
			CALL-5
			CALL-6
			CALL-N
			-----------------------------------------       -----------    --------------- ---       
			
                          ------------------------------------------------------------------------   
               Miscellaneous     22.4.5 Miscellaneous operation instructions (or misc ops) take their argu-
              Operation   ments from the stack and produce a resultant value that sets the indicators
                Instructions        and is optionally pushed on the stack.

			Table 22-5 lists all the misc ops.

------------------------  ------------------------------------------------------------------------   
Table 22-5 Miscellaneous Operation Instructions
------------------------  ------------------------------------------------------------------------   
ABS                                              CAAAR
AP-LEADER                                          CAADAR
AP-1                                                CAADDR
AP-1-FORCE                                       CAADR
AP-2                                                CAAR
AP-3                                                CADAAR
ARRAY-ACTIVE-LENGTH                         CADADR
ARRAY-DIMENSION                              CADAR
ARRAY-HAS-FILL-POINTER-P                   CADDAR
ARRAY-HAS-LEADER-P                         CADDDR
ARRAY-LEADER                                      CADDR
ARRAY-LEADER-LENGTH                            CADR
ARRAY-LENGTH                                   CAR
ARRAYP                                           CARCDR
ARRAY-PUSH                                      CAR-SAFE
ARRAY-RANK                                    CDAAAR
ARRAY-TOTAL-SIZE                             CDAADR
AR-1                                               CDAAR
AR-1-FORCE                                      CDADAR
AR-2                                               CDADDR
AR-2-REVERSE                                       CDADR
AR-3                                               CDAR
ASH                                            CDDAAR
ASSQ                                           CDDADR
AS-1                                                CDDAR
AS-1-FORCE                                       CDDDAR
AS-2                                                CDDDDR
AS-2-REVERSE                                 CDDDR
NOTE:  The functions that are microcoded are subject to change. Functions may be added to or deleted from
this list without notice.
------------------------  ------------------------------------------------------------------------   
Table 22-5  Miscellaneous Operation Instructions (Continued)
------------------------  ------------------------------------------------------------------------   
AS-3                                                CDDR
ATOM                                            CDR
BIGNUM-TO-ARRAY                            CDR-SAFE
BIND                                           CEILING-1
BITBLT                                         CEILING-2
BIT-VECTOR-P                                  CHARACTERP
BOUNDP                                             CHAR-INT
CAAAAR                                        CLOSURE
CAAADR                                       COMMON-LISP-AR-1
COMMON-LISP-AR-1-FORCE                       LOGIOR
COMMON-LISP-AR-2                                LSH
COMMON-LISP-AR-3                                MAKE-EPHEMERAL-LEXICAL-CLOSURE
COMMON-LISP-ELT                               MAKE-LEXICAL-CLOSURE
COMMON-LISP-LISTP                               MASK-FIELD
COMPLEXP                                          MAX
CONS                                                MEMQ
CONS-IN-AREA                                     MIN
CONSP-OR-POP                                      MINUS
COPY-ARRAY-CONTENTS                          MINUSP
COPY-ARRAY-CONTENTS-AND-LEADER            NAMED-STRUCTURE-P
COPY-ARRAY-PORTION                           NCONS
DEPOSIT-FIELD                                      NCONS-IN-AREA
DOUBLE-FLOAT                                    NLISTP
DOUBLE-FLOATP                                  NOT
DPB                                             NOT-INDICATORS
ELT                                              NSYMBOLP
ENDP                                               NTH
EQ                                                NTHCDR
EQL                                             NUMBERP
EQ-T                                             PDL-WORD
EQUAL                                           PLUSP
EQUALP                                         PREDICATE
FBOUNDP                                          PROPERTY-CELL-LOCATION
FIND-POSITION-IN-LIST                            QUOTIENT
FIX                                                  RATIONALP
FIXNUMP                                      RATIOP
FIXP                                                REMAINDER
FLOAT-EXPONENT                               ROT
FLOAT-FRACTION                                   ROUND-1
FLOATP                                           ROUND-2
FLOOR-1                                            RPLACA
FLOOR-2                                            RPLACD
FSYMEVAL                                       SCALE-FLOAT
FUNCTION-CELL-LOCATION                          SET
GCD                                                 SET-ARRAY-LEADER
GETL                                                SET-AR-1
GET-LEXICAL-VALUE-CELL                      SET-AR-1-FORCE
GET-LOCATION-OR-NIL                          SET-AR-2
GET-PNAME                                     SET-AR-3
G-L-P                                             SET-CAR
HAULONG                                      SET-CDR
INT-CHAR                                        SETELT
INTERNAL-CHAR-EQUAL                        SHRINK-PDL-SAVE-TOP
NOTE:  The functions that are microcoded are subject to change. Functions may be added to or deleted from
this list without notice.
------------------------  ------------------------------------------------------------------------   
Table 22-5  Miscellaneous Operation Instructions (Continued)
------------------------  ------------------------------------------------------------------------   
INTERNAL-FLOAT                                  SIMPLE-ARRAY-P
INTERNAL-GET-2                                SIMPLE-BIT-VECTOR-P
INTERNAL-GET-3                                SIMPLE-STRING-P
LAST                                           SIMPLE-VECTOR-P
LDB                                            SINGLE-FLOATP
LENGTH                                             SMALL-FLOAT
LENGTH-GREATERP                                 SMALL-FLOATP
LIST-OR-ARRAY                                      SPECIAL-PDL-INDEX
LISTP                                              STACK-GROUP-RESUME
LOAD-FROM-HIGHER-CONTEXT                    STACK-GROUP-RETURN
LOCATE-IN-HIGHER-CONTEXT                      STORE-ARRAY-LEADER
LOCATE-IN-INSTANCE                            STRINGP
SYMBOL-FUNCTION                                  %MICROSECOND-TIME
SYMBOL-NAME                                   %NUBUS-READ
SYMBOLP                                      %NUBUS-READ-8B
SYMBOL-PACKAGE                             %NUBUS-READ-8B-CAREFUL
SYMBOL-VALUE                                  %NUBUS-READ-16B
SYMEVAL                                          %NUBUS-WRITE
TIME-IN-60THS                                  %NUBUS-WRITE-8B
TRUNCATE-1                                       %NUBUS-WRITE-16B
TRUNCATE-2                                       %NUBUS-WRITE-32B
TYPEP-STRUCTURE-OR-FLAVOR                  %P-CDR-CODE
UNBIND-TO-INDEX-MOVE                           %P-CONTENTS-AS-LOCATIVE
VALUE-CELL-LOCATION                          %P-CONTENTS-AS-LOCATIVE-OFFSET
VECTORP                                       %P-DATA-TYPE
VECTOR-PUSH                                  %P-DEPOSIT-FIELD
ZEROP                                         %P-DEPOSIT-FIELD-OFFSET
%ADD-INTERRUPT                              %P-DPB
%ADD-PAGE-DEVICE                               %P-DPB-OFFSET
%ALLOCATE-AND-INITIALIZE                    %P-LDB
%ALLOCATE-AND-INITIALIZE-ARRAY                 %P-LDB-OFFSET
%ALLOCATE-AND-INITIALIZE-INSTANCE          %P-MASK-FIELD
%AREA-NUMBER                                     %P-MASK-FIELD-OFFSET
%BLT                                               %P-POINTER
%BLT-FROM-PHYSICAL                              %P-STORE-CDR-CODE
%BLT-TO-PHYSICAL                                 %P-STORE-CONTENTS
%BLT-TYPED                                      %P-STORE-CONTENTS-OFFSET
%CHANGE-PAGE-STATUS                          %P-STORE-DATA-TYPE
%COMPUTE-PAGE-HASH                           %P-STORE-POINTER
%DATA-TYPE                                    %P-STORE-TAG-AND-POINTER
%DELETE-PHYSICAL-PAGE                      %PAGE-IN
%DIV                                               %PAGE-STATUS
%EXTERNAL-VALUE-CELL                         %PAGE-TRACE
%FINDCORE                                      %PHYSICAL-ADDRESS
%FIND-STRUCTURE-HEADER                   %POINTER
%FIND-STRUCTURE-LEADER                     %POINTER-DIFFERENCE
%FIXNUM-MICROSECOND-TIME                   %RATIO-CONS
%FUNCTION-INSIDE-SELF                          %RECORD-EVENT
%GC-SCAV-RESET                                  %REGION-NUMBER
%GET-SELF-MAPPING-TABLE                      %STACK-FRAME-POINTER
%INSTANCE-LOC                                    %STORE-CONDITIONAL
%INSTANCE-REF                                     %STRING-EQUAL
NOTE:  The functions that are microcoded are subject to change. Functions may be added to or deleted from
this list without notice.
------------------------  ------------------------------------------------------------------------   
Table 22-5  Miscellaneous Operation Instructions (Continued)
------------------------  ------------------------------------------------------------------------   
%IO                                              %STRING-SEARCH-CHAR
%LOGDPB                                         %STRING-WIDTH
%LOGLDB                                        %STRUCTURE-BOXED-SIZE
%MAKE-EXPLICIT-STACK-LIST                     %STRUCTURE-TOTAL-SIZE
%MAKE-EXPLICIT-STACK-LIST*                  %SXHASH-STRING
%MAKE-LIST                                      %TEST&SET-68K
%MAKE-POINTER                                 %WRITE-INTERNAL-PROCESSOR-MEMORIES
%MAKE-POINTER-OFFSET                      *BOOLE
%MAKE-REGION                                 =
%MAKE-STACK-LIST                             <
%MAKE-STACK-LIST*                          >
NOTE:  The functions that are microcoded are subject to change. Functions may be added to or deleted from
this list without notice.
----------------------------------------------- ---------       -----------    ---------------------------- 
			Most misc ops correspond to Lisp functions, including the subprimitives,
			although some of these functions are very low level internals that may not be
			documented anywhere (do not expect to understand all of them). The compiler
			automatically uses these functions to speed up processing when it can.
			The only definitive way to tell if your code is using a microcoded function is to
			compile some code that uses it and then look at the results, since the compiler
			occasionally converts a documented function with one name into an
			undocumented subprimitive.
                          ------------------------------------------------------------------------   
          Auxiliary Operation        22.4.6 Auxiliary operation instructions (or aux ops) are similar to misc ops
              Instructions        except that they do not produce any resultant value, although some of them set
			the indicators. Aux ops can be divided into four groups: simple aux ops,
			complex call, long branches, and aux ops with a count field. 
           Simple Aux Ops    22.4.6.1 Table 22-6 lists all the simple aux ops.
                          ------------------------------------------------------------------------   
Table 22-6                  Simple Auxiliary Operation Instructions
                          ------------------------------------------------------------------------   
			BREAKPOINT                      %ENABLE-NUPI-LOCKING
			CRASH                            %GC-CONS-WORK
			EXCHANGE                            %GC-FLIP
			HALT                              %GC-FREE-REGION
			LEXICAL-UNSHARE-ALL           %GC-SCAVENGE
			POPJ                              %OPEN-CATCH
			POP-M-UNDER-N                  %OPEN-CATCH-MULTIPLE-VALUE
			RETURN-NOT-INDS                     %OPEN-CATCH-MV-LIST
			RETURN-PRED                        %SET-SELF-MAPPING-TABLE
			STORE-IN-HIGHER-CONTEXT          %SPREAD
			UNBIND-TO-INDEX                      %THROW
			%CLOSE-CATCH-RETURN            %THROW-N
			%CREATE-PHYSICAL-PAGE             %USING-BINDING-INSTANCES
			%DISABLE-NUPI-LOCKING              *UNWIND-STACK
			%DISK-RESTORE
			NOTE: The functions that are microcoded are subject to change. Functions may
			be added to or deleted from this list without notice.
			----------------------------------    ------------------       --------------- ---       
             Complex Call    22.4.6.2 When you call a function and expect more than one value returned, a
			slightly different kind of function calling is used. Example 13 uses 
			multiple-value-setq to receive two values from a function call:

            Example 13:                 (defun foo (x)
			 (let (y z)
			   (multiple-value-setq (y z)
			     (bar 3))
			   (* x y z)))

			The disassembled code appears as follows:

			10 PUSH-NUMBER               3
			11 PUSH                      FEF|3         ; '36865
			12 PUSH                      FEF|4         ; #'BAR
			13 (AUX) COMPLEX-CALL-TO-PUSH
			14 POP                       LOCAL|1       ; Z
			15 MOVEM                     LOCAL|0       ; Y
			16 *                         ARG|0         ; X
			17 *                         LOCAL|1       ; Z
			18 RETURN                    PDL-POP

			An (AUX) COMPLEX-CALL-TO-PUSH instruction is used instead of a CALL 
			instruction. The destination field of (AUX) COMPLEX-CALL-TO-PUSH is 
			PUSH, meaning that the result is pushed on the stack. The (AUX)
			COMPLEX-CALL-TO-PUSH instruction takes two arguments, which it finds on
			the stack. It pops both of them. The first one is the function object to be applied;
			the second is the call-info word. The call-info word is an integer containing the
			fields shown in Figure 22-1. 

------------------------  ------------------------------------------------------------------------   
 Figure 22-1 Call-Info Word
                                                                                                         


			The rest of the call proceeds as usual, and when the call returns, the returned
			values are left on the stack. The number of objects left on the stack is encoded
			in the call-info word. In this example, the two values returned are left on the
			stack, and they are immediately popped off into z and y.

			The multiple-value-bind form works similarly, as in Example 14:

            Example 14:                 (defun foo (x)
			 (multiple-value-bind (y *foo* z)
			     (bar 3)
			   (+ x y z)))

			The disassembled code appears as follows:

			12 PUSH-NUMBER                  3
			13 PUSH                                FEF|4              ; '53249
			14 PUSH                                FEF|5              ; #'BAR
			15 (AUX) COMPLEX-CALL-TO-PUSH
			16 POP                                 LOCAL|1            ; Z
			17 BIND-POP                         FEF|3          ; *FOO*
			18 MOVEM                               LOCAL|0            ; Y
			19 *                                   ARG|0              ; X
			20 *                                   LOCAL|1            ; Z
			21 RETURN                              PDL-POP

			The (AUX) COMPLEX-CALL-TO-PUSH instruction is again used, leaving the
			results on the stack; these results are used to bind the variables.

			Calls performed with multiple-value-list also work with the (AUX)
			COMPLEX-CALL-TO-PUSH instruction. Note that the call-info word has a
			multiple-value list return encoded within it. When the function returns, the
			list of values is left on the top of the stack. The following is an example of the
			use of this instruction:

            Example 15:                 (defun foo (x y)
			 (multiple-value-list (foo y x)))

			The disassembled code appears as follows:

			10 PUSH                                ARG|1              ; Y
			11 PUSH                                ARG|0              ; X
			12 PUSH                                FEF|3              ;  '8194
			13 PUSH                                FEF|4              ; #'FOO
			14 (AUX) COMPLEX-CALL-TO-PUSH
			15 RETURN                              PDL-POP

			The call-info argument has room for 63 values to be returned (bits 14-19)
			which is meaningful only when the return type is 1 (see Figure 22-1). The
			return type of 3 is used when the caller does not know how many values it
			wants (as in Example 17).

			The apply function is also compiled using a complex call. Consider the following
			example:

            Example 16:                 (defun foo (a b &rest c)
			 (apply #'format t a c)
			 b)

			The disassembled code appears as follows:

			 8 SET-T                               PDL-PUSH
			 9 PUSH                                ARG|0              ; A
			10 PUSH                                LOCAL|0            ; C
			11 PUSH-NUMBER                  67
			12 PUSH                                FEF|3              ; #'FORMAT
			13 (AUX) COMPLEX-CALL-TO-INDS
			14 RETURN                              ARG|1              ; B

			Note that bit 6 of the call-info word is set, indicating that this is an APPLY 
			operation. Thus, the microcode passes the next three values on the stack (t, a,
			and c in this example) to the first argument to this function (#'format).

			Also note that in instruction 10, the address LOCAL|0 is used to access the
			&rest argument.

			------------------------------------------------------------------------   

			The catch special form is also handled specially by the compiler. The following
			is a simple example of catch:

            Example 17:                 (defun a ()
			 (catch 'foo (bar)))

			The disassembled code appears as follows:

			14 PUSH                                       FEF|3                     ; 'FOO
			15 PUSH                                       FEF|4                     ; '21
			16 SET-NIL                                    PDL-PUSH           
			17 (AUX) %OPEN-CATCH-MULTIPLE-VALUE
			18 PUSH                                       FEF|5                     ; '12288
			19 PUSH                                       FEF|6                     ; #'BAR
			20 (AUX) COMPLEX-CALL-TO-PUSH
			21 (AUX) %CLOSE-CATCH
			22 (AUX) RETURN-N

			The (AUX) %OPEN-CATCH-MULTIPLE-VALUE takes three arguments on the
			stack. Instruction 14 pushes the first argument, which is the catch tag 'FOO.
			Instruction 15 pushes the second argument, '21, which is the restart for the
			program counter (PC). This restart PC is the location in the function a that
			should be branched to if this catch is thrown to. Instruction 16 pushes the
			third argument, the symbol nil. This argument indicates that this 
			%OPEN-CATCH-MULTIPLE-VALUE is expecting an unknown number of
			values. If the %OPEN-CATCH-MULTIPLE-VALUE knew the number of values
			being returned by the throw, then this argument would reflect that number. A
			value of 0 for the third argument indicates that all values returned are to be
			ignored. 

			The (AUX) %OPEN-CATCH-MULTIPLE-VALUE instruction receives its three
			arguments and saves both the state of the stack and the state of the
			special-variable binding so that they can be restored should a throw occur.
			Thus, instructions 14 through 17 start a catch block, and the rest of the
			function passes its two arguments. The catch form itself simply returns the
			value of its second argument; but if a throw happens during the evaluation of
			the (bar) form, then the stack is unwound and execution resumes at instruction
			21.

           Long Branches    22.4.6.3 Long branch instructions are similar to the short branches (except for 
			LONG-PUSHJ). However, long branches use two macroinstruction words; the
			second word contains the new PC offset from the start of the FEF, rather than a
			signed relative displacement. Table 22-7 lists all the long branch instructions.

                          ------------------------------------------------------------------------   
Table 22-7                  Long Branch Instructions
                          ------------------------------------------------------------------------   
			LONG-BR                              LONG-BR-NOT-ZEROP
			LONG-BR-ATOM                          LONG-BR-NULL
			LONG-BR-NOT-ATOM                     LONG-BR-NULL-ELSE-POP
			LONG-BR-NOT-NULL                       LONG-BR-SYMBOLP
			LONG-BR-NOT-NULL-ELSE-POP           LONG-BR-ZEROP
			LONG-BR-NOT-SYMBOLP               LONG-PUSHJ
			-------------------------------------- ----------------------       -----------   
			LONG-PUSHJ is used to implement a macroinstruction subroutine call. The
			second word contains the new PC offset as described previously. The return PC
			(the relative address of the instruction after a LONG-PUSHJ) is saved on the
			stack. Control is then transferred to the macroinstruction stream at the new PC
			and returns via a POPJ instruction (a simple aux op). This instruction pops
			the return PC saved on the stack by LONG-PUSHJ and resumes execution where
			the LONG-PUSHJ left off.

               AUX Op With      22.4.6.4 There are three instructions in this group: POP-PDL, which pops
             Count Field      values off the stack, UNBIND, which unbinds special variables, and RETURN,
			which returns values from the stack as the result of the current function. Each
			of these instructions has a count field that specifies the number of values, up
			to a maximum of 63.
                          ------------------------------------------------------------------------   

           Module Operations   22.4.7 These instructions are similar to misc ops, except that they tend to be
			specific for certain applications or environments, and the presence of the
			microcode that implements a module is not required.

			The operations to be performed and the module number are encoded in the
			instruction. Support is provided for 64 modules with eight operations for each
			module. The currently assigned modules and their instructions are listed in
			Table 22-8 in the form (module)instruction.

                          ------------------------------------------------------------------------   
Table 22-8                  Module Operation Instructions
                          ------------------------------------------------------------------------   
			(W:)%DRAW-CHARACTER         (W:)%DRAW-SHADED-RASTER-LINE
			(W:)%DRAW-RECTANGLE        (W:)%DRAW-SHADED-TRIANGLE
			(W:)%DRAW-STRING                
			(MOUSE)%SET-MOUSE-SCREEN
			(MOUSE)%OPEN-MOUSE-CURSOR
			NOTE: The functions that are microcoded are subject to change. Functions may
			be added to or deleted from this list without notice.
			------------------------------------------------------------------------   
