Skip to content

Intrinsic Call Instructions ​

Guile’s instruction set is low-level. This is good because the separate components of, say, a vector-ref operation might be able to be optimized out, leaving only the operations that need to be performed at run-time.

However some macro-operations may need to perform large amounts of computation at run-time to handle all the edge cases, and whose micro-operation components aren’t amenable to optimization. Residualizing code for the entire macro-operation would lead to code bloat with no benefit.

In this kind of a case, Guile’s VM calls out to intrinsics: run-time routines written in the host language (currently C, possibly more in the future if Guile gains more run-time targets like WebAssembly). There is one instruction for each instrinsic prototype; the intrinsic is specified by index in the instruction.

Instruction: call-thread x24:_ c32:idx ​

Call the void-returning instrinsic with index idx, passing the current scm_thread* as the argument.

Instruction: call-thread-scm s24:a c32:idx ​

Call the void-returning instrinsic with index idx, passing the current scm_thread* and the scm local a as arguments.

Instruction: call-thread-scm-scm s12:a s12:b c32:idx ​

Call the void-returning instrinsic with index idx, passing the current scm_thread* and the scm locals a and b as arguments.

Instruction: call-scm-sz-u32 s12:a s12:b c32:idx ​

Call the void-returning instrinsic with index idx, passing the locals a, b, and c as arguments. a is a scm value, while b and c are raw u64 values which fit into size_t and uint32_t types, respectively.

Instruction: call-scm<-thread s24:dst c32:idx ​

Call the SCM-returning instrinsic with index idx, passing the current scm_thread* as the argument. Place the result in dst.

Instruction: call-scm<-u64 s12:dst s12:a c32:idx ​

Call the SCM-returning instrinsic with index idx, passing u64 local a as the argument. Place the result in dst.

Instruction: call-scm<-s64 s12:dst s12:a c32:idx ​

Call the SCM-returning instrinsic with index idx, passing s64 local a as the argument. Place the result in dst.

Instruction: call-scm<-scm s12:dst s12:a c32:idx ​

Call the SCM-returning instrinsic with index idx, passing scm local a as the argument. Place the result in dst.

Instruction: call-u64<-scm s12:dst s12:a c32:idx ​

Call the uint64_t-returning instrinsic with index idx, passing scm local a as the argument. Place the u64 result in dst.

Instruction: call-s64<-scm s12:dst s12:a c32:idx ​

Call the int64_t-returning instrinsic with index idx, passing scm local a as the argument. Place the s64 result in dst.

Instruction: call-f64<-scm s12:dst s12:a c32:idx ​

Call the double-returning instrinsic with index idx, passing scm local a as the argument. Place the f64 result in dst.

Instruction: call-scm<-scm-scm s8:dst s8:a s8:b c32:idx ​

Call the SCM-returning instrinsic with index idx, passing scm locals a and b as arguments. Place the scm result in dst.

Instruction: call-scm<-scm-uimm s8:dst s8:a c8:b c32:idx ​

Call the SCM-returning instrinsic with index idx, passing scm local a and uint8_t immediate b as arguments. Place the scm result in dst.

Instruction: call-scm<-thread-scm s12:dst s12:a c32:idx ​

Call the SCM-returning instrinsic with index idx, passing the current scm_thread* and scm local a as arguments. Place the scm result in dst.

Instruction: call-scm<-scm-u64 s8:dst s8:a s8:b c32:idx ​

Call the SCM-returning instrinsic with index idx, passing scm local a and u64 local b as arguments. Place the scm result in dst.

Instruction: call-scm-scm s12:a s12:b c32:idx ​

Call the void-returning instrinsic with index idx, passing scm locals a and b as arguments.

Instruction: call-scm-scm-scm s8:a s8:b s8:c c32:idx ​

Call the void-returning instrinsic with index idx, passing scm locals a, b, and c as arguments.

Instruction: call-scm-uimm-scm s8:a c8:b s8:c c32:idx ​

Call the void-returning instrinsic with index idx, passing scm local a, uint8_t immediate b, and scm local c as arguments.

There are corresponding macro-instructions for specific intrinsics. These are equivalent to call-instrinsic-kind instructions with the appropriate intrinsic idx arguments.

Macro Instruction: add dst a b ​

Macro Instruction: add/immediate dst a b/imm ​

Add SCM values a and b and place the result in dst.

Macro Instruction: sub dst a b ​

Macro Instruction: sub/immediate dst a b/imm ​

Subtract SCM value b from a and place the result in dst.

Macro Instruction: mul dst a b ​

Multiply SCM values a and b and place the result in dst.

Macro Instruction: div dst a b ​

Divide SCM value a by b and place the result in dst.

Macro Instruction: quo dst a b ​

Compute the quotient of SCM values a and b and place the result in dst.

Macro Instruction: rem dst a b ​

Compute the remainder of SCM values a and b and place the result in dst.

Macro Instruction: mod dst a b ​

Compute the modulo of SCM value a by b and place the result in dst.

Macro Instruction: logand dst a b ​

Compute the bitwise and of SCM values a and b and place the result in dst.

Macro Instruction: logior dst a b ​

Compute the bitwise inclusive or of SCM values a and b and place the result in dst.

Macro Instruction: logxor dst a b ​

Compute the bitwise exclusive or of SCM values a and b and place the result in dst.

Macro Instruction: logsub dst a b ​

Compute the bitwise and of SCM value a and the bitwise not of b and place the result in dst.

Macro Instruction: lsh dst a b ​

Macro Instruction: lsh/immediate a b/imm ​

Shift SCM value a left by u64 value b bits and place the result in dst.

Macro Instruction: rsh dst a b ​

Macro Instruction: rsh/immediate dst a b/imm ​

Shifts SCM value a right by u64 value b bits and place the result in dst.

Macro Instruction: scm->f64 dst src ​

Convert src to an unboxed f64 and place the result in dst, or raises an error if src is not a real number.

Macro Instruction: scm->u64 dst src ​

Convert src to an unboxed u64 and place the result in dst, or raises an error if src is not an integer within range.

Macro Instruction: scm->u64/truncate dst src ​

Convert src to an unboxed u64 and place the result in dst, truncating to the low 64 bits, or raises an error if src is not an integer.

Macro Instruction: scm->s64 dst src ​

Convert src to an unboxed s64 and place the result in dst, or raises an error if src is not an integer within range.

Macro Instruction: u64->scm dst src ​

Convert u64 value src to a Scheme integer in dst.

Macro Instruction: s64->scm scm<-s64 ​

Convert s64 value src to a Scheme integer in dst.

Macro Instruction: string-set! str idx ch ​

Sets the character idx (a u64) of string str to ch (a u64 that is a valid character value).

Macro Instruction: string->number dst src ​

Call string->number on src and place the result in dst.

Macro Instruction: string->symbol dst src ​

Call string->symbol on src and place the result in dst.

Macro Instruction: symbol->keyword dst src ​

Call symbol->keyword on src and place the result in dst.

Macro Instruction: class-of dst src ​

Set dst to the GOOPS class of src.

Macro Instruction: wind winder unwinder ​

Push wind and unwind procedures onto the dynamic stack. Note that neither are actually called; the compiler should emit calls to winder and unwinder for the normal dynamic-wind control flow. Also note that the compiler should have inserted checks that winder and unwinder are thunks, if it could not prove that to be the case. See Dynamic Wind.

Macro Instruction: unwind ​

Exit from the dynamic extent of an expression, popping the top entry off of the dynamic stack.

Macro Instruction: push-fluid fluid value ​

Dynamically bind value to fluid by creating a with-fluids object, pushing that object on the dynamic stack. See Fluids and Dynamic States.

Macro Instruction: pop-fluid ​

Leave the dynamic extent of a with-fluid* expression, restoring the fluid to its previous value. push-fluid should always be balanced with pop-fluid.

Macro Instruction: fluid-ref dst fluid ​

Place the value associated with the fluid fluid in dst.

Macro Instruction: fluid-set! fluid value ​

Set the value of the fluid fluid to value.

Macro Instruction: push-dynamic-state state ​

Save the current set of fluid bindings on the dynamic stack and instate the bindings from state instead. See Fluids and Dynamic States.

Macro Instruction: pop-dynamic-state ​

Restore a saved set of fluid bindings from the dynamic stack. push-dynamic-state should always be balanced with pop-dynamic-state.

Macro Instruction: resolve-module dst name public? ​

Look up the module named name, resolve its public interface if the immediate operand public? is true, then place the result in dst.

Macro Instruction: lookup dst mod sym ​

Look up sym in module mod, placing the resulting variable (or #f if not found) in dst.

Macro Instruction: define! dst mod sym ​

Look up sym in module mod, placing the resulting variable in dst, creating the variable if needed.

Macro Instruction: current-module dst ​

Set dst to the current module.

Macro Instruction: $car dst src ​

Macro Instruction: $cdr dst src ​

Macro Instruction: $set-car! x val ​

Macro Instruction: $set-cdr! x val ​

Macro Instruction: $variable-ref dst src ​

Macro Instruction: $variable-set! x val ​

Macro Instruction: $vector-length dst x ​

Macro Instruction: $vector-ref dst x idx ​

Macro Instruction: $vector-ref/immediate dst x idx/imm ​

Macro Instruction: $vector-set! x idx v ​

Macro Instruction: $vector-set!/immediate x idx/imm v ​

Macro Instruction: $allocate-struct dst vtable nwords ​

Macro Instruction: $struct-vtable dst src ​

Macro Instruction: $struct-ref dst src idx ​

Macro Instruction: $struct-ref/immediate dst src idx/imm ​

Macro Instruction: $struct-set! x idx v ​

Macro Instruction: $struct-set!/immediate x idx/imm v ​

Intrinsics for use by the baseline compiler. The usual strategy for CPS compilation is to expose the component parts of e.g. vector-ref so that the compiler can learn from them and eliminate needless bits. However in the non-optimizing baseline compiler, that’s just overhead, so we have some intrinsics that encapsulate all the usual type checks.