BLOCK and RETURN-FROMTAGBODY and GOCATCH and THROWUNWIND-PROTECTHANDLER-BIND| mnemonic | description | semantics | 
|---|---|---|
( | Load NIL into values. | value1 := NIL, mv_count := 1 | 
(PUSH-NIL  | Push n NILs into the STACK. | n times do: *--STACK := NIL,
             Invalidate values. | 
( | Load T into values. | value1 := T, mv_count := 1 | 
(CONST  | Load the function's nth constant into values. | value1 := consts[n],
             mv_count := 1 | 
| mnemonic | description | semantics | 
|---|---|---|
(LOAD  | Load a directly accessible local variable into values. | value1 := *(STACK+n),
         mv_count := 1 | 
(LOADI  | Load an indirectly accessible local variable into values. | k := k1 + jmpbufsize * k2,
         value1 := *(*(SP+k)+ n),
         mv_count := 1 | 
(LOADC  | Load a closed-up variable, defined in the same function and
         directly accessible, into values. | value1 := SVREF(*(STACK+n),1+m),
         mv_count := 1 | 
(LOADV  | Load a closed-up variable, defined in an outer function,
         into values. | v := venv-const,
         m times do: v := SVREF(v,0),
         value1 := SVREF(v,m),
         mv_count := 1 | 
(LOADIC  | Load a closed-up variable, defined in the same function and
             indirectly accessible, into values. | k := k1 + jmpbufsize * k2,
             value1 := SVREF(*(*(SP+k)+n),1+m),
             mv_count := 1 | 
(STORE  | Store values into a directly accessible local variable. | *(STACK+n) := value1,
             mv_count := 1 | 
(STOREI  | Store values into an indirectly accessible local variable. | k := k1 + jmpbufsize * k2,
              *(*(SP+k)+ n) := value1,
              mv_count := 1 | 
(STOREC  | Store values into a closed-up variable, defined in the same function and directly accessible. | SVREF(*(STACK+n),1+m) := value1,
             mv_count := 1 | 
(STOREV  | Store values into a closed-up variable, defined in an outer function. | v := venv-const,
             m times do: v := SVREF(v,0),
             SVREF(v,m) := value1,
             mv_count := 1 | 
(STOREIC  | Store values into a closed-up variable, defined in the same function and indirectly accessible. | k := k1 + jmpbufsize * k2,
             SVREF(*(*(SP+k)+n),1+m) := value1,
             mv_count := 1 | 
| mnemonic | description | semantics | 
|---|---|---|
(GETVALUE  | Load a symbol's value into values. | value1 := symbol-value(consts[n]),
             mv_count := 1 | 
(SETVALUE  | Store values into a symbol's value. | symbol-value(consts[n]) := value1,
             mv_count := 1 | 
(BIND  | Bind a symbol dynamically. | Bind the value of the symbol
             consts[n] to value1,
             implicitly STACK -= 3,
             Invalidate values. | 
(UNBIND1) | Dissolve one binding frame. | Unbind the binding frame STACK is pointing to,
             implicitly STACK += 3 | 
(UNBIND  | Dissolve n binding frames. | n times do:
              Unbind the binding frame STACK is pointing to, thereby
              incrementing STACK
             Thus, STACK += 1+2*n | 
(PROGV) | Bind a set of symbols dynamically to a set of values. | symbols := *STACK++,
             *--SP := STACK,
             build a single binding frame binding the symbols in
             symbols to the values in value1,
             Invalidate values. | 
| mnemonic | description | semantics | 
|---|---|---|
(PUSH) | Push one object onto the STACK. | *--STACK := value1,
             Invalidate values. | 
(POP) | Pop one object from the STACK, into values. | value1 := *STACK++, mv_count := 1 | 
(SKIP  | Restore a previous STACK pointer.
             Remove n objects from the STACK. | STACK := STACK + n | 
(SKIPI  | Restore a previous STACK pointer. Remove an unknown
             number of objects from the STACK. | k := k1 + jmpbufsize * k2,
             STACK := *(SP+k),
             SP := SP+k+1,
             STACK := STACK + n | 
(SKIPSP  | Restore a previous SP pointer. | k := k1 + jmpbufsize * k2,
             SP := SP+k | 
| mnemonic | description | semantics | 
|---|---|---|
(SKIP&RET  | Clean up the STACK, and return from the function. | STACK := STACK+n,
            return from the function, returning values. | 
(SKIP&RETGF  | Clean up the STACK, and return from the generic
             function. | If bit 3 is set in the function's flags,
                then STACK := STACK+n, mv_count := 1,
                     and return from the function.
             Otherwise: if the current function has no &REST argument,
                then STACK := STACK+n-numreq,
                     apply value1 to the numreq arguments
                           still on the STACK, and
                           return from the function.
                Else STACK := STACK+n-numreq-1,
                     apply value1 to the numreq arguments and the
                           &REST argument, all still on the STACK, and
                           return from the function. | 
(JMP  | Jump to label. | PC := label. | 
(JMPIF  | Jump to label, if value1 is true. | If value1 is not NIL, PC := label. | 
(JMPIFNOT  | Jump to label, if value1 is false. | If value1 is NIL, PC := label. | 
(JMPIF1  | Jump to label and forget secondary values,
             if value1 is true. | If value1 is not NIL,
                mv_count := 1, PC := label. | 
(JMPIFNOT1  | Jump to label and forget secondary values,
             if value1 is false. | If value1 is NIL,
                mv_count := 1, PC := label. | 
(JMPIFATOM  | Jump to label, if value1 is not a cons. | If value1 is not a cons, PC := label.
             Invalidate values. | 
(JMPIFCONSP  | Jump to label, if value1 is a cons. | If value1 is a cons, PC := label.
                Invalidate values. | 
(JMPIFEQ  | Jump to label, if value1 is EQ to the top-of-stack. | If eq(value1,*STACK++), PC := label.
             Invalidate values. | 
(JMPIFNOTEQ  | Jump to label, if value1 is not EQ
             to the top-of-stack. | If not eq(value1,*STACK++), PC := label.
             Invalidate values. | 
(JMPIFEQTO  | Jump to label,
             if the top-of-stack is EQ to a constant. | If eq(*STACK++,consts[n]), PC := label.
             Invalidate values. | 
(JMPIFNOTEQTO  | Jump to label, if the top-of-stack is not EQ
             to a constant. | If not eq(*STACK++,consts[n]), PC := label.
             Invalidate values. | 
(JMPHASH  | Table-driven jump, depending on value1. | Lookup value1 in the hash table consts[n].
             (The hash table's test is either EQ or EQL.)
             If found, the hash table value is a signed FIXNUM,
             jump to it: PC := PC + value.  Else jump to label.
             Invalidate values. | 
(JMPHASHV  | Table-driven jump, depending on value1,
             inside a generic function. | Lookup value1 in the hash table SVREF(consts[0],n).
             (The hash table's test is either EQ or EQL.)
             If found, the hash table value is a signed FIXNUM,
             jump to it: PC := PC + value.  Else jump to label.
             Invalidate values. | 
(JSR  | Subroutine call. | *--STACK := function. Then start interpreting the
             bytecode at label, with values undefined.
             When a (RET) is encountered,
             program execution is resumed at the instruction after
             (JSR . | 
(JMPTAIL  | Tail subroutine call. | n >= m.
             The STACK frame of size n is reduced to size m:
             {*(STACK+n-m), ..., *(STACK+n-1)} :=
               {*STACK, ..., *(STACK+m-1)}.
             STACK += n-m.
             *--STACK := function.
             Then jump to label, with values undefined. | 
| mnemonic | description | semantics | 
|---|---|---|
(VENV) | Load the venv-const into values. | value1 := consts[0], mv_count := 1. | 
(MAKE-VECTOR1&PUSH  | Create a SIMPLE-VECTOR used for closed-up variables. | v := new SIMPLE-VECTOR of size n+1.
             SVREF(v,0) := value1.
             *--STACK := v. Invalidate values. | 
(COPY-CLOSURE  | Create a closure by copying the prototype and filling in the lexical environment. | f := copy-function(consts[m]).
             For i=0,..,n-1:
                 f_consts[i] := *(STACK+n-1-i).
             STACK += n.
             value1 := f, mv_count := 1 | 
| mnemonic | description | semantics | 
|---|---|---|
(CALL  | Calls a constant function with k arguments. | The function consts[n] is called
             with the arguments *(STACK+k-1), ..., *(STACK+0).
             STACK += k. The returned values go into values. | 
(CALL0  | Calls a constant function with 0 arguments. | The function consts[n] is called with 0 arguments.
             The returned values go into values. | 
(CALL1  | Calls a constant function with 1 argument. | The function consts[n] is called with one argument *STACK.
             STACK += 1. The returned values go into values. | 
(CALL2  | Calls a constant function with 2 arguments. | The function consts[n] is called
             with two arguments *(STACK+1) and *(STACK+0).
             STACK += 2. The returned values go into values. | 
(CALLS1  | Calls a system function with no &REST. | Calls the system function FUNTAB[b].
             The right number of arguments is already on the STACK
             (including #<UNBOUND>s in place of absent &OPTIONAL or
              &KEY parameters).
             The arguments are removed from the STACK. The returned values go into values. | 
(CALLS2  | Calls a system function with no &REST. | Calls the system function FUNTAB[256+b].
             The right number of arguments is already on the STACK
             (including #<UNBOUND>s in place of absent &OPTIONAL or
              &KEY parameters).
             The arguments are removed from the STACK. The returned values go into values. | 
(CALLSR  | Calls a system function with &REST. | Calls the system function FUNTABR[b].
             The minimum number of arguments is already on the STACK,
             and m additional arguments as well.
             The arguments are removed from the STACK. The returned values go into values. | 
(CALLC) | Calls a computed compiled function with no &KEYs. | Calls the compiled function value1.
             The right number of arguments is already on the STACK
             (including #<UNBOUND>s in place of absent &OPTIONAL
              parameters).
             The arguments are removed from the STACK. The returned values go into values. | 
(CALLCKEY) | Calls a computed compiled function with &KEYs. | Calls the compiled function value1.
             The right number of arguments is already on the STACK
             (including #<UNBOUND>s in place of absent &OPTIONAL
              or &KEY parameters).
             The arguments are removed from the STACK. The returned values go into values. | 
(FUNCALL  | Calls a computed function. | Calls the function *(STACK+n)
             with the arguments *(STACK+n-1), ..., *(STACK+0).
             STACK += n+1. The returned values go into values. | 
(APPLY  | Calls a computed function with an unknown number of arguments. | Calls the function *(STACK+n)
         with the arguments *(STACK+n-1), ..., *(STACK+0)
         and a list of additional arguments value1.
         STACK += n+1. The returned values go into values. | 
| mnemonic | description | semantics | 
|---|---|---|
(PUSH-UNBOUND  | Push n #<UNBOUND>s into the STACK. | n times do: *--STACK := #<UNBOUND>.
             Invalidate values. | 
(UNLIST  | Destructure a proper LIST. | 0 ≤ m ≤ n.
             n times do: *--STACK := CAR(value1),
             value1 := CDR(value1).
             During the last m iterations, the list value1
             may already have reached its end;
             in this case, *--STACK := #<UNBOUND>.
             At the end, value1 must be NIL.
             Invalidate values. | 
(UNLIST*  | Destructure a proper or dotted LIST. | 0 ≤ m ≤ n, n > 0.
             n times do: *--STACK := CAR(value1),
             value1 := CDR(value1).
             During the last m iterations, the list value1
             may already have reached its end;
             in this case, *--STACK := #<UNBOUND>.
             At the end, after n CDRs, *--STACK := value1.
             Invalidate values. | 
(JMPIFBOUNDP  | Jump to label, if a local variable is not unbound. | If *(STACK+n) is not #<UNBOUND>,
                value1 := *(STACK+n), mv_count := 1, PC := label.
             Else: Invalidate values.. | 
(BOUNDP  | Load T or NIL into values, depending on whether a local
             variable is bound. | If *(STACK+n) is not #<UNBOUND>,
                value1 := T, mv_count := 1.
             Else: value1 := NIL, mv_count := 1. | 
(UNBOUND->NIL  | If a local variable is unbound, assign a default value
             NIL to it. | If *(STACK+n) is #<UNBOUND>,
             *(STACK+n) := NIL. | 
| mnemonic | description | semantics | 
|---|---|---|
(VALUES0) | Load no values into values. | value1 := NIL, mv_count := 0 | 
(VALUES1) | Forget secondary values. | mv_count := 1 | 
( | Pop the first n objects from STACK into values. | Load values(*(STACK+n-1),...,*(STACK+0)) into
             values. STACK += n. | 
(MV-TO- | Save values on STACK. | Push the mv_count values onto the STACK
             (in order: value1 comes first).
             STACK -= mv_count. Invalidate values. | 
(NV-TO- | Save n values on STACK. | Push the first n values onto the STACK
             (in order: value1 comes first).
             STACK -= n. Invalidate values. | 
(MV-TO-LIST) | Convert multiple values into a list. | value1 := list of values, mv_count := 1 | 
(LIST-TO-MV) | Convert a LIST into multiple values. | Call the function VALUES-LIST with value1 as argument.
             The returned values go into values. | 
(MVCALLP) | Start a MULTIPLE-VALUE-CALL invocation. | *--SP := STACK. *--STACK := value1. | 
(MVCALL) | Finish a MULTIPLE-VALUE-CALL invocation. | newSTACK := *SP++.
             Call the function *(newSTACK-1), passing it
             *(newSTACK-2), ..., *(STACK+0) as arguments.
             STACK := newSTACK. The returned values go into values. | 
BLOCK and RETURN-FROM| mnemonic | description | semantics | 
|---|---|---|
(BLOCK-OPEN  | Create a BLOCK frame. | Create a BLOCK frame, STACK -= 3, SP -= 2+jmpbufsize.
   The topmost (third) object in the block frame is
   CONS(consts[n],frame-pointer) (its block-cons).
   Upon a RETURN-FROM to this frame, execution will continue at label.
   Invalidate values.. | 
(BLOCK-CLOSE) | Dissolve a BLOCK frame. | Dissolve the BLOCK frame at STACK, STACK += 3,
             SP += 2+jmpbufsize. Mark the block-cons as invalid. | 
(RETURN-FROM  | Leave a BLOCK whose block-cons is given. | block-cons := consts[n].
             If CDR(block-cons) = #<DISABLED>, an ERROR is SIGNALed.
             Else CDR(block-cons) is a frame-pointer.
             Unwind the stack up to this frame, pass it values. | 
(RETURN-FROM-I  | Leave a BLOCK whose block-cons is indirectly accessible. | k := k1 + jmpbufsize * k2,
             block-cons := *(*(SP+k)+n).
             If CDR(block-cons) = #<DISABLED>, an ERROR is SIGNALed.
             Else CDR(block-cons) is a frame-pointer.
             Unwind the stack up to this frame, pass it values. | 
| mnemonic | description | semantics | 
|---|---|---|
(TAGBODY-OPEN  | Create a TAGBODY frame. | Fetch consts[m], this is a SIMPLE-VECTOR with
             n elements, then decode n label operands.
             Create a TAGBODY frame, STACK -= 3+n, SP -= 1+jmpbufsize.
             The third object in the TAGBODY frame is
             CONS(consts[m],frame-pointer) (the tagbody-cons)
             Upon a GO to tag label of this frame, execution
             will continue at labell.
             Invalidate values. | 
(TAGBODY-CLOSE-NIL) | Dissolve a TAGBODY frame, and load NIL into values. | Dissolve the TAGBODY frame at STACK,
             STACK += 3+m, SP += 1+jmpbufsize.
             Mark the tagbody-cons as invalid.
             value1 := NIL, mv_count := 1. | 
(TAGBODY-CLOSE) | Dissolve a TAGBODY frame. | Dissolve the TAGBODY frame at STACK,
             STACK += 3+m, SP += 1+jmpbufsize.
             Mark the tagbody-cons as invalid. | 
(GO  | Jump into a TAGBODY whose tagbody-cons is given. | tagbody-cons := consts[n].
             If CDR(tagbody-cons) = #<DISABLED>, an ERROR is SIGNALed.
             Else CDR(tagbody-cons) is a frame-pointer. Unwind the stack up
             to this frame, pass it the number label. | 
(GO-I  | Jump into a TAGBODY whose tagbody-cons is indirectly
             accessible. | k := k1 + jmpbufsize * k2,
             tagbody-cons := *(*(SP+k)+n).
             If CDR(tagbody-cons) = #<DISABLED>, an ERROR is SIGNALed.
             Else CDR(tagbody-cons) is a frame-pointer. Unwind the stack up
             to this frame, pass it the number label. | 
| mnemonic | description | semantics | 
|---|---|---|
(CATCH-OPEN  | Create a CATCH frame. | Create a CATCH frame, with value1 as tag.
             STACK -= 3, SP -= 2+jmpbufsize.
             Upon a THROW to this tag execution continues at
             label. | 
(CATCH-CLOSE) | Dissolve a CATCH frame. | Dissolve the CATCH frame at STACK.
             STACK += 3, SP += 2+jmpbufsize. | 
(THROW) | Non-local exit to a CATCH frame. | tag := *STACK++.
             Search the innermost CATCH frame with tag
             tag on the STACK, unwind the
             stack up to it, pass it values. | 
UNWIND-PROTECT| mnemonic | description | semantics | 
|---|---|---|
(UNWIND-PROTECT-OPEN
              | Create an UNWIND-PROTECT frame. | Create an UNWIND-PROTECT frame.
             STACK -= 2, SP -= 2+jmpbufsize.
             When the stack will be unwound by a non-local exit,
             values will be saved on STACK, and execution will be
             transferred to label. | 
(UNWIND-PROTECT-NORMAL-EXIT) | Dissolve an UNWIND-PROTECT frame, and start the cleanup
             code. | Dissolve the UNWIND-PROTECT frame at STACK.
             STACK += 2, SP += 2+jmpbufsize.
             *--SP := 0, *--SP := 0, *--SP := STACK.
             Save the values on the STACK,
             STACK -= mv_count. | 
(UNWIND-PROTECT-CLOSE) | Terminate the cleanup code. | newSTACK := *SP++. Load
             values(*(newSTACK-1), ..., *(STACK+0)) into values.
             STACK := newSTACK. SPword1 := *SP++, SPword2 := *SP++.
             Continue depending on SPword1 and SPword2.
             If both are 0, simply continue execution.
             If SPword2 is 0 but SPword1 is nonzero, interpret it as a
             label and jump to it. | 
(UNWIND-PROTECT-CLEANUP) | Dissolve an UNWIND-PROTECT frame, and execute the cleanup
             code like a subroutine call. | Dissolve the UNWIND-PROTECT frame at STACK,
             get label out of the frame.
             STACK += 2, SP += 2+jmpbufsize.
             *--SP := 0, *--SP := PC, *--SP := STACK.
             Save the values on the STACK, STACK -= mv_count.
             PC := label. | 
HANDLER-BIND| mnemonic | description | semantics | 
|---|---|---|
(HANDLER-OPEN  | Create a handler frame. | Create a handler frame, using consts[n] which
             contains the CONDITION types, the corresponding labels and
             the current SP depth (= function entry SP - current SP).
              | 
(HANDLER-BEGIN&PUSH) | Start a handler. | Restore the same SP state as after the HANDLER-OPEN.
             value1 := the CONDITION that was passed to the handler,
             mv_count := 1.
             *--STACK := value1. | 
| mnemonic | description | semantics | 
|---|---|---|
(NOT) | Inlined call to NOT. | value1 := not(value1), mv_count := 1. | 
(EQ) | Inlined call to EQ. | value1 := eq(*STACK++,value1),
             mv_count := 1. | 
(CAR) | Inlined call to CAR. | value1 := CAR(value1), mv_count := 1. | 
(CDR) | Inlined call to CDR. | value1 := CDR(value1), mv_count := 1. | 
(CONS) | Inlined call to CONS. | value1 := cons(*STACK++,value1),
             mv_count := 1. | 
(SYMBOL-FUNCTION) | Inlined call to SYMBOL-FUNCTION. | value1 := SYMBOL-FUNCTION(value1),
             mv_count := 1. | 
(SVREF) | Inlined call to SVREF. | value1 := SVREF(*STACK++,value1),
             mv_count := 1. | 
(SVSET) | Inlined call to (. | arg1 := *(STACK+1),
             arg2 := *(STACK+0), STACK += 2.
             SVREF(arg2,value1) :=
                  arg1.
             value1 := arg1,
             mv_count := 1. | 
(LIST  | Inlined call to LIST. | value1 := LIST(*(STACK+n-1),...,*(STACK+0)),
             mv_count := 1, STACK += n. | 
(LIST*  | Inlined call to LIST*. | value1 := LIST*(*(STACK+n-1),...,
                                     *(STACK+0),value1),
             mv_count := 1, STACK += n. | 
The most frequent short sequences of instructions have an
equivalent combined instruction.  They are only present for space and
speed optimization. The only exception is
FUNCALL&SKIP&RETGF, which is needed for
generic functions.
| mnemonic | equivalent | 
|---|---|
(NIL&PUSH) | (NIL) (PUSH) | 
(T&PUSH) | (T) (PUSH) | 
(CONST&PUSH  | (CONST  | 
(LOAD&PUSH  | (LOAD  | 
(LOADI&PUSH  | (LOADI  | 
(LOADC&PUSH  | (LOADC  | 
(LOADV&PUSH  | (LOADV  | 
(POP&STORE  | (POP) (STORE  | 
(GETVALUE&PUSH  | (GETVALUE  | 
(JSR&PUSH  | (JSR  | 
(COPY-CLOSURE&PUSH  | (COPY-CLOSURE  | 
(CALL&PUSH  | (CALL  | 
(CALL1&PUSH  | (CALL1  | 
(CALL2&PUSH  | (CALL2  | 
(CALLS1&PUSH  | (CALLS1  | 
(CALLS2&PUSH  | (CALLS2  | 
(CALLSR&PUSH  | (CALLSR  | 
(CALLC&PUSH) | (CALLC) (PUSH) | 
(CALLCKEY&PUSH) | (CALLCKEY) (PUSH) | 
(FUNCALL&PUSH  | (FUNCALL  | 
(APPLY&PUSH  | (APPLY  | 
(CAR&PUSH) | (CAR) (PUSH) | 
(CDR&PUSH) | (CDR) (PUSH) | 
(CONS&PUSH) | (CONS) (PUSH) | 
(LIST&PUSH  | (LIST  | 
(LIST*&PUSH  | (LIST*  | 
(NIL&STORE  | (NIL) (STORE  | 
(T&STORE  | (T) (STORE  | 
(LOAD&STOREC  | (LOAD  | 
(CALLS1&STORE  | (CALLS1  | 
(CALLS2&STORE  | (CALLS2  | 
(CALLSR&STORE  | (CALLSR  | 
(LOAD&CDR&STORE  | (LOAD  | 
(LOAD&CONS&STORE  | (LOAD  | 
(LOAD&INC&STORE  | (LOAD  | 
(LOAD&DEC&STORE  | (LOAD  | 
(LOAD&CAR&STORE  | (LOAD  | 
(CALL1&JMPIF  | (CALL1  | 
(CALL1&JMPIFNOT  | (CALL1  | 
(CALL2&JMPIF  | (CALL2  | 
(CALL2&JMPIFNOT  | (CALL2  | 
(CALLS1&JMPIF  | (CALLS1  | 
(CALLS1&JMPIFNOT  | (CALLS1  | 
(CALLS2&JMPIF  | (CALLS2  | 
(CALLS2&JMPIFNOT  | (CALLS2  | 
(CALLSR&JMPIF  | (CALLSR  | 
(CALLSR&JMPIFNOT  | (CALLSR  | 
(LOAD&JMPIF  | (LOAD  | 
(LOAD&JMPIFNOT  | (LOAD  | 
(LOAD&CAR&PUSH  | (LOAD  | 
(LOAD&CDR&PUSH  | (LOAD  | 
(LOAD&INC&PUSH  | (LOAD  | 
(LOAD&DEC&PUSH  | (LOAD  | 
(CONST&SYMBOL-FUNCTION  | (CONST  | 
(CONST&SYMBOL-FUNCTION&PUSH  | (CONST  | 
(CONST&SYMBOL-FUNCTION&STORE  | (CONST  | 
(APPLY&SKIP&RET  | (APPLY  | 
(FUNCALL&SKIP&RETGF  | (FUNCALL  | 
| These notes document CLISP version 2.49.93+ | Last modified: 2018-02-19 |