+@node Function Prologue Instructions
+@subsubsection Function Prologue Instructions
+
+A function call in Guile is very cheap: the VM simply hands control to
+the procedure. The procedure itself is responsible for asserting that it
+has been passed an appropriate number of arguments. This strategy allows
+arbitrarily complex argument parsing idioms to be developed, without
+harming the common case.
+
+For example, only calls to keyword-argument procedures ``pay'' for the
+cost of parsing keyword arguments. (At the time of this writing, calling
+procedures with keyword arguments is typically two to four times as
+costly as calling procedures with a fixed set of arguments.)
+
+@deffn Instruction assert-nargs-ee n
+@deffnx Instruction assert-nargs-ge n
+Assert that the current procedure has been passed exactly @var{n}
+arguments, for the @code{-ee} case, or @var{n} or more arguments, for
+the @code{-ge} case. @var{n} is encoded over two bytes.
+
+The number of arguments is determined by subtracting the frame pointer
+from the stack pointer (@code{sp - (fp -1)}). @xref{Stack Layout}, for
+more details on stack frames.
+@end deffn
+
+@deffn Instruction br-if-nargs-ne n offset
+@deffnx Instruction br-if-nargs-gt n offset
+@deffnx Instruction br-if-nargs-lt n offset
+Jump to @var{offset} if the number of arguments is not equal to, greater
+than, or less than @var{n}. @var{n} is encoded over two bytes, and
+@var{offset} has the normal three-byte encoding.
+
+These instructions are used to implement muliple arities, as in
+@code{case-lambda}. @xref{Case-lambda}, for more information.
+@end deffn
+
+@deffn Instruction bind-optionals n
+If the procedure has been called with fewer than @var{n} arguments, fill
+in the remaining arguments with an unbound value (@code{SCM_UNDEFINED}).
+@var{n} is encoded over two bytes.
+
+The optionals can be later initialized conditionally via the
+@code{local-bound?} instruction.
+@end deffn
+
+@deffn Instruction push-rest n
+Pop off excess arguments (more than @var{n}), collecting them into a
+list, and push that list. Used to bind a rest argument, if the procedure
+has no keyword arguments. Procedures with keyword arguments use
+@code{bind-rest} instead.
+@end deffn
+
+@deffn Instruction bind-rest n idx
+Pop off excess arguments (more than @var{n}), collecting them into a
+list. The list is then assigned to the @var{idx}th local variable.
+@end deffn
+
+@deffn Instruction bind-optionals/shuffle nreq nreq-and-opt ntotal
+Shuffle keyword arguments to the top of the stack, filling in the holes
+with @code{SCM_UNDEFINED}. Each argument is encoded over two bytes.
+
+This instruction is used by procedures with keyword arguments.
+@var{nreq} is the number of required arguments to the procedure, and
+@var{nreq-and-opt} is the total number of positional arguments (required
+plus optional). @code{bind-optionals/shuffle} will scan the stack from
+the @var{nreq}th argument up to the @var{nreq-and-opt}th, and start
+shuffling when it sees the first keyword argument or runs out of
+positional arguments.
+
+Shuffling simply moves the keyword arguments past the total number of
+arguments, @var{ntotal}, which includes keyword and rest arguments. The
+free slots created by the shuffle are filled in with
+@code{SCM_UNDEFINED}, so they may be conditionally initialized later in
+the function's prologue.
+@end deffn
+
+@deffn Instruction bind-kwargs idx ntotal flags
+Parse keyword arguments, assigning their values to the corresponding
+local variables. The keyword arguments should already have been shuffled
+above the @var{ntotal}th stack slot by @code{bind-optionals/shuffle}.
+
+The parsing is driven by a keyword arguments association list, looked up
+from the @var{idx}th element of the procedures object array. The alist
+is a list of pairs of the form @code{(@var{kw} . @var{index})}, mapping
+keyword arguments to their local variable indices.
+
+There are two bitflags that affect the parser, @code{allow-other-keys?}
+(@code{0x1}) and @code{rest?} (@code{0x2}). Unless
+@code{allow-other-keys?} is set, the parser will signal an error if an
+unknown key is found. If @code{rest?} is set, errors parsing the the
+keyword arguments will be ignored, as a later @code{bind-rest}
+instruction will collect all of the tail arguments, including the
+keywords, into a list. Otherwise if the keyword arguments are invalid,
+an error is signalled.
+
+@var{idx} and @var{ntotal} are encoded over two bytes each, and
+@var{flags} is encoded over one byte.
+@end deffn
+
+@deffn Instruction reserve-locals n
+Resets the stack pointer to have space for @var{n} local variables,
+including the arguments. If this operation increments the stack pointer,
+as in a push, the new slots are filled with @code{SCM_UNBOUND}. If this
+operation decrements the stack pointer, any excess values are dropped.
+
+@code{reserve-locals} is typically used after argument parsing to
+reserve space for local variables.
+@end deffn
+
+@deffn Instruction assert-nargs-ee/locals n
+@deffnx Instruction assert-nargs-ge/locals n
+A combination of @code{assert-nargs-ee} and @code{reserve-locals}. The
+number of arguments is encoded in the lower three bits of @var{n}, a
+one-byte value. The number of additional local variables is take from
+the upper 5 bits of @var{n}.
+@end deffn
+
+
+@node Trampoline Instructions
+@subsubsection Trampoline Instructions
+
+Though most applicable objects in Guile are procedures implemented
+in bytecode, not all are. There are primitives, continuations, and other
+procedure-like objects that have their own calling convention. Instead
+of adding special cases to the @code{call} instruction, Guile wraps
+these other applicable objects in VM trampoline procedures, then
+provides special support for these objects in bytecode.
+
+Trampoline procedures are typically generated by Guile at runtime, for
+example in response to a call to @code{scm_c_make_gsubr}. As such, a
+compiler probably shouldn't emit code with these instructions. However,
+it's still interesting to know how these things work, so we document
+these trampoline instructions here.
+
+@deffn Instruction subr-call nargs
+Pop off a foreign pointer (which should have been pushed on by the
+trampoline), and call it directly, with the @var{nargs} arguments from
+the stack. Return the resulting value or values to the calling
+procedure.
+@end deffn
+
+@deffn Instruction foreign-call nargs
+Pop off an internal foreign object (which should have been pushed on by
+the trampoline), and call that foreign function with the @var{nargs}
+arguments from the stack. Return the resulting value to the calling
+procedure.
+@end deffn
+
+@deffn Instruction smob-call nargs
+Pop off the smob object from the stack (which should have been pushed on
+by the trampoline), and call its descriptor's @code{apply} function with
+the @var{nargs} arguments from the stack. Return the resulting value or
+values to the calling procedure.
+@end deffn
+
+@deffn Instruction continuation-call
+Pop off an internal continuation object (which should have been pushed
+on by the trampoline), and reinstate that continuation. All of the
+procedure's arguments are passed to the continuation. Does not return.
+@end deffn
+
+@deffn Instruction partial-cont-call
+Pop off two objects from the stack: the dynamic winds associated with
+the partial continuation, and the VM continuation object. Unroll the
+continuation onto the stack, rewinding the dynamic environment and
+overwriting the current frame, and pass all arguments to the
+continuation. Control flow proceeds where the continuation was captured.
+@end deffn
+
+
+@node Branch Instructions
+@subsubsection Branch Instructions
+
+All the conditional branch instructions described below work in the
+same way:
+
+@itemize
+@item They pop off Scheme object(s) located on the stack for use in the
+branch condition
+@item If the condition is true, then the instruction pointer is
+increased by the offset passed as an argument to the branch
+instruction;
+@item Program execution proceeds with the next instruction (that is,
+the one to which the instruction pointer points).
+@end itemize
+
+Note that the offset passed to the instruction is encoded as three 8-bit
+integers, in big-endian order, effectively giving Guile a 24-bit
+relative address space.
+
+@deffn Instruction br offset
+Jump to @var{offset}. No values are popped.
+@end deffn
+
+@deffn Instruction br-if offset
+Jump to @var{offset} if the object on the stack is not false.
+@end deffn
+
+@deffn Instruction br-if-not offset
+Jump to @var{offset} if the object on the stack is false.
+@end deffn
+
+@deffn Instruction br-if-eq offset
+Jump to @var{offset} if the two objects located on the stack are
+equal in the sense of @var{eq?}. Note that, for this instruction, the
+stack pointer is decremented by two Scheme objects instead of only
+one.
+@end deffn
+
+@deffn Instruction br-if-not-eq offset
+Same as @var{br-if-eq} for non-@code{eq?} objects.
+@end deffn
+
+@deffn Instruction br-if-null offset
+Jump to @var{offset} if the object on the stack is @code{'()}.
+@end deffn
+
+@deffn Instruction br-if-not-null offset
+Jump to @var{offset} if the object on the stack is not @code{'()}.
+@end deffn
+
+
+@node Data Constructor Instructions
+@subsubsection Data Constructor Instructions
+
+These instructions push simple immediate values onto the stack,
+or constructo compound data structures from values the stack.