37.5. The instruction set
Prev | Chapter 37. The CLISP bytecode specification | Next

## 37.5. The instruction set

### 37.5.1. Instructions for constants

mnemonic | description | semantics
--- | --- | ---
`(`NIL`)` | Load `NIL` into values. | `value1` := `NIL`, `mv_count` := 1
`(PUSH-NIL `n`)` | Push `n` `NIL`s into the `STACK`. | `n` times do: *--`STACK` := `NIL`, values undefined
`(`T`)` | Load `T` into values. | `value1` := `T`, `mv_count` := 1
`(CONST `n`)` | Load the function's `n`th constant into values. | `value1` := `consts`[`n`], `mv_count` := 1

### 37.5.2. Instructions for lexical variables

mnemonic | description | semantics
--- | --- | ---
`(LOAD `n`)` | Load a directly accessible local variable into values. | `value1` := *(`STACK`+`n`), `mv_count` := 1
`(LOADI `k1` `k2` `n`)` | Load an indirectly accessible local variable into values. | `k` := `k1` + `jmpbufsize` * `k2`, `value1` := *(*(`SP`+`k`)+ `n`), `mv_count` := 1
`(LOADC `n` `m`)` | 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 `k` `m`)` | 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 `k1` `k2` `n` `m`)` | 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 `n`)` | Store values into a directly accessible local variable. | *(`STACK`+`n`) := `value1`, `mv_count` := 1
`(STOREI `k1` `k2` `n`)` | Store values into an indirectly accessible local variable. | `k` := `k1` + `jmpbufsize` * `k2`, *(*(`SP`+`k`)+ `n`) := `value1`, `mv_count` := 1
`(STOREC `n` `m`)` | 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 `k` `m`)` | 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 `k1` `k2` `n` `m`)` | 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

### 37.5.3. Instructions for dynamic variables

mnemonic | description | semantics
--- | --- | ---
`(GETVALUE `n`)` | Load a symbol's value into values. | `value1` := symbol-value(`consts`[`n`]), `mv_count` := 1
`(SETVALUE `n`)` | Store values into a symbol's value. | symbol-value(`consts`[`n`]) := `value1`, `mv_count` := 1
`(BIND `n`)` | Bind a symbol dynamically. | Bind the value of the symbol `consts`[`n`] to `value1`, implicitly `STACK` -= 3, values undefined
`(UNBIND1)` | Dissolve one binding frame. | Unbind the binding frame `STACK` is pointing to, implicitly `STACK` += 3
`(UNBIND `n`)` | 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`, values undefined

### 37.5.4. Instructions for stack operations

mnemonic | description | semantics
--- | --- | ---
`(PUSH)` | Push one object onto the `STACK`. | *--`STACK` := `value1`, values undefined
`(POP)` | Pop one object from the `STACK`, into values. | `value1` := *`STACK`++, `mv_count` := 1
`(SKIP `n`)` | Restore a previous `STACK` pointer. Remove `n` objects from the `STACK`. | `STACK` := `STACK` + `n`
`(SKIPI `k1` `k2` `n`)` | 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 `k1` `k2`)` | Restore a previous `SP` pointer. | `k` := `k1` + `jmpbufsize` * `k2`, `SP` := `SP`+`k`

### 37.5.5. Instructions for control flow, jumps

mnemonic | description | semantics
--- | --- | ---
`(SKIP&RET `n`)` | Clean up the `STACK`, and return from the function. | `STACK` := `STACK`+`n`, return from the function, returning values.
`(SKIP&RETGF `n`)` | 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 `label`)` | Jump to `label`. | PC := `label`.
`(JMPIF `label`)` | Jump to `label`, if `value1` is true. | If `value1` is not `NIL`, PC := `label`.
`(JMPIFNOT `label`)` | Jump to `label`, if `value1` is false. | If `value1` is `NIL`, PC := `label`.
`(JMPIF1 `label`)` | Jump to `label` and forget secondary values, if `value1` is true. | If `value1` is not `NIL`, `mv_count` := 1, PC := `label`.
`(JMPIFNOT1 `label`)` | Jump to `label` and forget secondary values, if `value1` is false. | If `value1` is `NIL`, `mv_count` := 1, PC := `label`.
`(JMPIFATOM `label`)` | Jump to `label`, if `value1` is not a cons. | If `value1` is not a cons, PC := `label`. values undefined
`(JMPIFCONSP `label`)` | Jump to `label`, if `value1` is a cons. | If `value1` is a cons, PC := `label`. values undefined
`(JMPIFEQ `label`)` | Jump to `label`, if `value1` is `EQ` to the top-of-stack. | If eq(`value1`,*`STACK`++), PC := `label`. values undefined
`(JMPIFNOTEQ `label`)` | Jump to `label`, if `value1` is not `EQ` to the top-of-stack. | If not eq(`value1`,*`STACK`++), PC := `label`. values undefined
`(JMPIFEQTO `n` `label`)` | Jump to `label`, if the top-of-stack is `EQ` to a constant. | If eq(*`STACK`++,`consts`[`n`]), PC := `label`. values undefined
`(JMPIFNOTEQTO `n` `label`)` | Jump to `label`, if the top-of-stack is not `EQ` to a constant. | If not eq(*`STACK`++,`consts`[`n`]), PC := `label`. values undefined
`(JMPHASH `n` `label`)` | 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`. values undefined
`(JMPHASHV `n` `label`)` | 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`. values undefined
`(JSR `label`)` | 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 `label`)`.
`(JMPTAIL `m` `n` `label`)` | 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.

### 37.5.6. Instructions for lexical environment, creation of closures

mnemonic | description | semantics
--- | --- | ---
`(VENV)` | Load the `venv-const` into values. | `value1` := `consts`[0], `mv_count` := 1.
`(MAKE-VECTOR1&PUSH `n`)` | Create a `SIMPLE-VECTOR` used for closed-up variables. | `v` := new `SIMPLE-VECTOR` of size `n`+1. `SVREF`(`v`,0) := `value1`. *--`STACK` := `v`. values undefined
`(COPY-CLOSURE `m` `n`)` | 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

### 37.5.7. Instructions for function calls

mnemonic | description | semantics
--- | --- | ---
`(CALL `k` `n`)` | 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 `n`)` | Calls a constant function with 0 arguments. | The function `consts`[`n`] is called with 0 arguments. The returned values go into values.
`(CALL1 `n`)` | 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 `n`)` | 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 `b`)` | 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 `b`)` | 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 `m` `b`)` | 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 `&KEY`. | 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 `&KEY`. | 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 `n`)` | 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 `n`)` | 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.

### 37.5.8. Instructions for optional and keyword parameters

mnemonic | description | semantics
--- | --- | ---
`(PUSH-UNBOUND `n`)` | Push `n` `#<UNBOUND>`s into the `STACK`. | `n` times do: *--`STACK` := `#<UNBOUND>`. values undefined
`(UNLIST `n` `m`)` | 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`. values undefined
`(UNLIST* `n` `m`)` | 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` `CDR`s, *--`STACK` := `value1`. values undefined
`(JMPIFBOUNDP `n` `label`)` | 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: values undefined.
`(BOUNDP `n`)` | 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 `n`)` | If a local variable is unbound, assign a default value `NIL` to it. | If *(`STACK`+`n`) is `#<UNBOUND>`, *(`STACK`+`n`) := `NIL`.

### 37.5.9. Instructions for multiple values

mnemonic | description | semantics
--- | --- | ---
`(VALUES0)` | Load no values into values. | `value1` := `NIL`, `mv_count` := 0
`(VALUES1)` | Forget secondary values. | `mv_count` := 1
`(`STACK`-TO-MV `n`)` | Pop the first `n` objects from `STACK` into values. | Load values(*(`STACK`+`n`-1),...,*(`STACK`+0)) into values. `STACK` += `n`.
`(MV-TO-`STACK`)` | Save values on `STACK`. | Push the `mv_count` values onto the `STACK` (in order: `value1` comes first). `STACK` -= `mv_count`. values undefined
`(NV-TO-`STACK` `n`)` | Save `n` values on `STACK`. | Push the first `n` values onto the `STACK` (in order: `value1` comes first). `STACK` -= `n`. values undefined
`(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.

### 37.5.10. Instructions for `BLOCK` and `RETURN-FROM`

mnemonic | description | semantics
--- | --- | ---
`(BLOCK-OPEN `n` `label`)` | 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`. values undefined.
`(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 `n`)` | Leave a `BLOCK` whose `block-cons` is given. | `block-cons` := `consts`[`n`]. If `CDR`(`block-cons`) = `#<DISABLED>`, an `ERROR` is `SIGNAL`ed. Else `CDR`(`block-cons`) is a frame-pointer. Unwind the stack up to this frame, pass it values.
`(RETURN-FROM-I `k1` `k2` `n`)` | 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 `SIGNAL`ed. Else `CDR`(`block-cons`) is a frame-pointer. Unwind the stack up to this frame, pass it values.

### 37.5.11. Instructions for `TAGBODY` and `GO`

mnemonic | description | semantics
--- | --- | ---
`(TAGBODY-OPEN `m` `label1` ... `labeln`)` | 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`. values undefined
`(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 `n` `label`)` | Jump into a `TAGBODY` whose `tagbody-cons` is given. | `tagbody-cons` := `consts`[`n`]. If `CDR`(`tagbody-cons`) = `#<DISABLED>`, an `ERROR` is `SIGNAL`ed. Else `CDR`(`tagbody-cons`) is a frame-pointer. Unwind the stack up to this frame, pass it the number `label`.
`(GO-I `k1` `k2` `n` `label`)` | 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 `SIGNAL`ed. Else `CDR`(`tagbody-cons`) is a frame-pointer. Unwind the stack up to this frame, pass it the number `label`.

### 37.5.12. Instructions for `CATCH` and `THROW`

mnemonic | description | semantics
--- | --- | ---
`(CATCH-OPEN `label`)` | 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.

### 37.5.13. Instructions for `UNWIND-PROTECT`

mnemonic | description | semantics
--- | --- | ---
`(UNWIND-PROTECT-OPEN `label`)` | 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`.

### 37.5.14. Instructions for `HANDLER-BIND`

mnemonic | description | semantics
--- | --- | ---
`(HANDLER-OPEN `n`)` | 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`.

### 37.5.15. Instructions for some inlined functions

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 `(`SETF` `SVREF``. | `arg1` := *(`STACK`+1), `arg2` := *(`STACK`+0), `STACK` += 2. `SVREF`(`arg2`,`value1`) := `arg1`. `value1` := `arg1`, `mv_count` := 1.
`(LIST `n`)` | Inlined call to `LIST`. | `value1` := `LIST`(*(`STACK`+`n`-1),...,*(`STACK`+0)), `mv_count` := 1, `STACK` += `n`.
`(LIST* `n`)` | Inlined call to `LIST*`. | `value1` := `LIST*`(*(`STACK`+`n`-1),..., *(`STACK`+0),`value1`), `mv_count` := 1, `STACK` += `n`.

### 37.5.16. Combined instructions

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 `n`)` | `(CONST `n`) (PUSH)`
`(LOAD&PUSH `n`)` | `(LOAD `n`) (PUSH)`
`(LOADI&PUSH `k1` `k2` `n`)` | `(LOADI `k1` `k2` `n`) (PUSH)`
`(LOADC&PUSH `n` `m`)` | `(LOADC `n` `m`) (PUSH)`
`(LOADV&PUSH `k` `m`)` | `(LOADV `k` `m`) (PUSH)`
`(POP&STORE `n`)` | `(POP) (STORE `n`)`
`(GETVALUE&PUSH `n`)` | `(GETVALUE `n`) (PUSH)`
`(JSR&PUSH `label`)` | `(JSR `label`) (PUSH)`
`(COPY-CLOSURE&PUSH `m` `n`)` | `(COPY-CLOSURE `m` `n`) (PUSH)`
`(CALL&PUSH `k` `n`)` | `(CALL `k` `n`) (PUSH)`
`(CALL1&PUSH `n`)` | `(CALL1 `n`) (PUSH)`
`(CALL2&PUSH `n`)` | `(CALL2 `n`) (PUSH)`
`(CALLS1&PUSH `b`)` | `(CALLS1 `b`) (PUSH)`
`(CALLS2&PUSH `b`)` | `(CALLS2 `b`) (PUSH)`
`(CALLSR&PUSH `m` `n`)` | `(CALLSR `m` `n`) (PUSH)`
`(CALLC&PUSH)` | `(CALLC) (PUSH)`
`(CALLCKEY&PUSH)` | `(CALLCKEY) (PUSH)`
`(FUNCALL&PUSH `n`)` | `(FUNCALL `n`) (PUSH)`
`(APPLY&PUSH `n`)` | `(APPLY `n`) (PUSH)`
`(CAR&PUSH)` | `(CAR) (PUSH)`
`(CDR&PUSH)` | `(CDR) (PUSH)`
`(CONS&PUSH)` | `(CONS) (PUSH)`
`(LIST&PUSH `n`)` | `(LIST `n`) (PUSH)`
`(LIST*&PUSH `n`)` | `(LIST* `n`) (PUSH)`
`(NIL&STORE `n`)` | `(NIL) (STORE `n`)`
`(T&STORE `n`)` | `(T) (STORE `n`)`
`(LOAD&STOREC `k` `n` `m`)` | `(LOAD `k`) (STOREC `n` `m`)`
`(CALLS1&STORE `b` `k`)` | `(CALLS1 `b`) (STORE `k`)`
`(CALLS2&STORE `b` `k`)` | `(CALLS2 `b`) (STORE `k`)`
`(CALLSR&STORE `m` `n` `k`)` | `(CALLSR `m` `n`) (STORE `k`)`
`(LOAD&CDR&STORE `n`)` | `(LOAD `n`) (CDR) (STORE `n`)`
`(LOAD&CONS&STORE `n`)` | `(LOAD `n`+1) (CONS) (STORE `n`)`
`(LOAD&INC&STORE `n`)` | `(LOAD `n`) (CALL1 #'1+) (STORE `n`)`
`(LOAD&DEC&STORE `n`)` | `(LOAD `n`) (CALL1 #'1-) (STORE `n`)`
`(LOAD&CAR&STORE `m` `n`)` | `(LOAD `m`) (CAR) (STORE `n`)`
`(CALL1&JMPIF `n` `label`)` | `(CALL1 `n`) (JMPIF `label`)`
`(CALL1&JMPIFNOT `n` `label`)` | `(CALL1 `n`) (JMPIFNOT `label`)`
`(CALL2&JMPIF `n` `label`)` | `(CALL2 `n`) (JMPIF `label`)`
`(CALL2&JMPIFNOT `n` `label`)` | `(CALL2 `n`) (JMPIFNOT `label`)`
`(CALLS1&JMPIF `b` `label`)` | `(CALLS1 `b`) (JMPIF `label`)`
`(CALLS1&JMPIFNOT `b` `label`)` | `(CALLS1 `b`) (JMPIFNOT `label`)`
`(CALLS2&JMPIF `b` `label`)` | `(CALLS2 `b`) (JMPIF `label`)`
`(CALLS2&JMPIFNOT `b` `label`)` | `(CALLS2 `b`) (JMPIFNOT `label`)`
`(CALLSR&JMPIF `m` `n` `label`)` | `(CALLSR `m` `n`) (JMPIF `label`)`
`(CALLSR&JMPIFNOT `m` `n` `label`)` | `(CALLSR `m` `n`) (JMPIFNOT `label`)`
`(LOAD&JMPIF `n` `label`)` | `(LOAD `n`) (JMPIF `label`)`
`(LOAD&JMPIFNOT `n` `label`)` | `(LOAD `n`) (JMPIFNOT `label`)`
`(LOAD&CAR&PUSH `n`)` | `(LOAD `n`) (CAR) (PUSH)`
`(LOAD&CDR&PUSH `n`)` | `(LOAD `n`) (CDR) (PUSH)`
`(LOAD&INC&PUSH `n`)` | `(LOAD `n`) (CALL1 #'1+) (PUSH)`
`(LOAD&DEC&PUSH `n`)` | `(LOAD `n`) (CALL1 #'1-) (PUSH)`
`(CONST&SYMBOL-FUNCTION `n`)` | `(CONST `n`) (SYMBOL-FUNCTION)`
`(CONST&SYMBOL-FUNCTION&PUSH `n`)` | `(CONST `n`) (SYMBOL-FUNCTION) (PUSH)`
`(CONST&SYMBOL-FUNCTION&STORE `n` `k`)` | `(CONST `n`) (SYMBOL-FUNCTION) (STORE `k`)`
`(APPLY&SKIP&RET `n` `k`)` | `(APPLY `n`) (SKIP&RET `k`)`
`(FUNCALL&SKIP&RETGF `n` `k`)` | `(FUNCALL `n`) (SKIP&RETGF `k`)`

### 37.5.17. Shortcut instructions

There are special one-byte instructions (without explicit operands) for the following frequent instructions:

mnemonic | operand range
--- | ---
`(LOAD `n`)` | 0 ≤ `n` < 15
`(LOAD&PUSH `n`)` | 0 ≤ `n` < 25
`(CONST `n`)` | 0 ≤ `n` < 21
`(CONST&PUSH `n`)` | 0 ≤ `n` < 30
`(STORE `n`)` | 0 ≤ `n` < 8

| These notes document CLISP version 2.45 | Last modified: 2008-05-14

Enter your search termsSubmit search form
Webclisp.cons.orgclisp.podval.orgwww.lisp.org

Prev | Up | Next
37.4. The general structure of the instructions | Home | 37.6. Examining compiled closures