mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-09 13:30:26 +02:00
Document new VM instructions
* doc/ref/vm.texi (Stack Layout): Add a note about unboxed values. (Instruction Set): Update for new instructions.
This commit is contained in:
parent
5fceaed5e1
commit
a653271f98
1 changed files with 205 additions and 26 deletions
231
doc/ref/vm.texi
231
doc/ref/vm.texi
|
@ -189,6 +189,12 @@ new call frame.
|
||||||
In this way, the dynamic link links the current frame to the previous
|
In this way, the dynamic link links the current frame to the previous
|
||||||
frame. Computing a stack trace involves traversing these frames.
|
frame. Computing a stack trace involves traversing these frames.
|
||||||
|
|
||||||
|
Each stack local in Guile is 64 bits wide, even on 32-bit architectures.
|
||||||
|
This allows Guile to preserve its uniform treatment of stack locals
|
||||||
|
while allowing for unboxed arithmetic on 64-bit integers and
|
||||||
|
floating-point numbers. @xref{Instruction Set}, for more on unboxed
|
||||||
|
arithmetic.
|
||||||
|
|
||||||
As an implementation detail, we actually store the dynamic link as an
|
As an implementation detail, we actually store the dynamic link as an
|
||||||
offset and not an absolute value because the stack can move at runtime
|
offset and not an absolute value because the stack can move at runtime
|
||||||
as it expands or during partial continuation calls. If it were an
|
as it expands or during partial continuation calls. If it were an
|
||||||
|
@ -461,7 +467,7 @@ compiled @code{.go} files. It's good times!
|
||||||
@node Instruction Set
|
@node Instruction Set
|
||||||
@subsection Instruction Set
|
@subsection Instruction Set
|
||||||
|
|
||||||
There are currently about 130 instructions in Guile's virtual machine.
|
There are currently about 175 instructions in Guile's virtual machine.
|
||||||
These instructions represent atomic units of a program's execution.
|
These instructions represent atomic units of a program's execution.
|
||||||
Ideally, they perform one task without conditional branches, then
|
Ideally, they perform one task without conditional branches, then
|
||||||
dispatch to the next instruction in the stream.
|
dispatch to the next instruction in the stream.
|
||||||
|
@ -551,6 +557,16 @@ In addition, some Scheme primitives have their own inline
|
||||||
implementations. For example, in the previous section we saw
|
implementations. For example, in the previous section we saw
|
||||||
@code{cons}.
|
@code{cons}.
|
||||||
|
|
||||||
|
Finally, for instructions with operands that encode references to the
|
||||||
|
stack, the interpretation of those stack values is up to the instruction
|
||||||
|
itself. Most instructions expect their operands to be tagged SCM values
|
||||||
|
(@code{scm} representation), but some instructions expect unboxed
|
||||||
|
integers (@code{u64} and @code{s64} representations) or floating-point
|
||||||
|
numbers (@var{f64} representation). Instructions have static types:
|
||||||
|
they must receive their operands in the format they expect. It's up to
|
||||||
|
the compiler to ensure this is the case. Unless otherwise mentioned,
|
||||||
|
all operands and results are boxed as SCM values.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Lexical Environment Instructions::
|
* Lexical Environment Instructions::
|
||||||
* Top-Level Environment Instructions::
|
* Top-Level Environment Instructions::
|
||||||
|
@ -564,6 +580,8 @@ implementations. For example, in the previous section we saw
|
||||||
* Inlined Scheme Instructions::
|
* Inlined Scheme Instructions::
|
||||||
* Inlined Mathematical Instructions::
|
* Inlined Mathematical Instructions::
|
||||||
* Inlined Bytevector Instructions::
|
* Inlined Bytevector Instructions::
|
||||||
|
* Unboxed Integer Arithmetic::
|
||||||
|
* Unboxed Floating-Point Arithmetic::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@ -707,10 +725,8 @@ in which to save the @code{ip} and @code{fp}.
|
||||||
|
|
||||||
Returning values is similar. Multiple-value returns should have values
|
Returning values is similar. Multiple-value returns should have values
|
||||||
already shuffled down to start from @code{fp}-relative slot 1 before
|
already shuffled down to start from @code{fp}-relative slot 1 before
|
||||||
emitting @code{return-values}. There is a short-cut in the single-value
|
emitting @code{return-values}. We start from slot 1 instead of slot 0
|
||||||
case, in that @code{return} handles the trivial shuffling itself. We
|
to make tail calls to @code{values} trivial.
|
||||||
start from slot 1 instead of slot 0 to make tail calls to @code{values}
|
|
||||||
trivial.
|
|
||||||
|
|
||||||
In both calls and returns, the @code{sp} is used to indicate to the
|
In both calls and returns, the @code{sp} is used to indicate to the
|
||||||
callee or caller the number of arguments or return values, respectively.
|
callee or caller the number of arguments or return values, respectively.
|
||||||
|
@ -772,10 +788,6 @@ return values equals @var{nvalues} exactly. After @code{receive-values}
|
||||||
has run, the values can be copied down via @code{mov}, or used in place.
|
has run, the values can be copied down via @code{mov}, or used in place.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} return s24:@var{src}
|
|
||||||
Return a value.
|
|
||||||
@end deftypefn
|
|
||||||
|
|
||||||
@deftypefn Instruction {} return-values c24:@var{nlocals}
|
@deftypefn Instruction {} return-values c24:@var{nlocals}
|
||||||
Return a number of values from a call frame. This opcode corresponds to
|
Return a number of values from a call frame. This opcode corresponds to
|
||||||
an application of @code{values} in tail position. As with tail calls,
|
an application of @code{values} in tail position. As with tail calls,
|
||||||
|
@ -935,6 +947,13 @@ not generated by the compiler.
|
||||||
Load a builtin stub by index into @var{dst}.
|
Load a builtin stub by index into @var{dst}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} apply-non-program x24:@var{_}
|
||||||
|
An instruction used only by a special trampoline that the VM uses to
|
||||||
|
apply non-programs. Using that trampoline allows profilers and
|
||||||
|
backtrace utilities to avoid seeing the instruction pointer from the
|
||||||
|
calling frame.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
@node Branch Instructions
|
@node Branch Instructions
|
||||||
@subsubsection Branch Instructions
|
@subsubsection Branch Instructions
|
||||||
|
@ -990,10 +1009,9 @@ See @code{libguile/tags.h} for all the details.
|
||||||
|
|
||||||
@deftypefn Instruction {} br-if-eq s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
@deftypefn Instruction {} br-if-eq s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
||||||
@deftypefnx Instruction {} br-if-eqv s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
@deftypefnx Instruction {} br-if-eqv s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
||||||
@deftypefnx Instruction {} br-if-equal s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
If the value in @var{a} is @code{eq?} or @code{eqv?} to the value in
|
||||||
If the value in @var{a} is @code{eq?}, @code{eqv?}, or @code{equal?} to
|
@var{b}, respectively, add @var{offset} to the current instruction
|
||||||
the value in @var{b}, respectively, add @var{offset} to the current
|
pointer.
|
||||||
instruction pointer.
|
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} br-if-= s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
@deftypefn Instruction {} br-if-= s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
||||||
|
@ -1179,6 +1197,10 @@ Reference the fluid in @var{src}, and place the value in @var{dst}.
|
||||||
Set the value of the fluid in @var{dst} to the value in @var{src}.
|
Set the value of the fluid in @var{dst} to the value in @var{src}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} current-thread s24:@var{dst}
|
||||||
|
Write the value of the current thread to @var{dst}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
@node Miscellaneous Instructions
|
@node Miscellaneous Instructions
|
||||||
@subsubsection Miscellaneous Instructions
|
@subsubsection Miscellaneous Instructions
|
||||||
|
@ -1234,12 +1256,14 @@ be filled with the value in slot @var{init}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} vector-length s12:@var{dst} s12:@var{src}
|
@deftypefn Instruction {} vector-length s12:@var{dst} s12:@var{src}
|
||||||
Store the length of the vector in @var{src} in @var{dst}.
|
Store the length of the vector in @var{src} in @var{dst}, as an unboxed
|
||||||
|
unsigned 64-bit integer.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} vector-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
@deftypefn Instruction {} vector-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
||||||
Fetch the item at position @var{idx} in the vector in @var{src}, and
|
Fetch the item at position @var{idx} in the vector in @var{src}, and
|
||||||
store it in @var{dst}.
|
store it in @var{dst}. The @var{idx} value should be an unboxed
|
||||||
|
unsigned 64-bit integer.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} vector-ref/immediate s8:@var{dst} s8:@var{src} c8:@var{idx}
|
@deftypefn Instruction {} vector-ref/immediate s8:@var{dst} s8:@var{src} c8:@var{idx}
|
||||||
|
@ -1248,7 +1272,8 @@ Fill @var{dst} with the item @var{idx} elements into the vector at
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} vector-set! s8:@var{dst} s8:@var{idx} s8:@var{src}
|
@deftypefn Instruction {} vector-set! s8:@var{dst} s8:@var{idx} s8:@var{src}
|
||||||
Store @var{src} into the vector @var{dst} at index @var{idx}.
|
Store @var{src} into the vector @var{dst} at index @var{idx}. The
|
||||||
|
@var{idx} value should be an unboxed unsigned 64-bit integer.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} vector-set!/immediate s8:@var{dst} c8:@var{idx} s8:@var{src}
|
@deftypefn Instruction {} vector-set!/immediate s8:@var{dst} c8:@var{idx} s8:@var{src}
|
||||||
|
@ -1263,16 +1288,19 @@ Store the vtable of @var{src} into @var{dst}.
|
||||||
@deftypefn Instruction {} allocate-struct s8:@var{dst} s8:@var{vtable} s8:@var{nfields}
|
@deftypefn Instruction {} allocate-struct s8:@var{dst} s8:@var{vtable} s8:@var{nfields}
|
||||||
Allocate a new struct with @var{vtable}, and place it in @var{dst}. The
|
Allocate a new struct with @var{vtable}, and place it in @var{dst}. The
|
||||||
struct will be constructed with space for @var{nfields} fields, which
|
struct will be constructed with space for @var{nfields} fields, which
|
||||||
should correspond to the field count of the @var{vtable}.
|
should correspond to the field count of the @var{vtable}. The @var{idx}
|
||||||
|
value should be an unboxed unsigned 64-bit integer.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} struct-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
@deftypefn Instruction {} struct-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
||||||
Fetch the item at slot @var{idx} in the struct in @var{src}, and store
|
Fetch the item at slot @var{idx} in the struct in @var{src}, and store
|
||||||
it in @var{dst}.
|
it in @var{dst}. The @var{idx} value should be an unboxed unsigned
|
||||||
|
64-bit integer.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} struct-set! s8:@var{dst} s8:@var{idx} s8:@var{src}
|
@deftypefn Instruction {} struct-set! s8:@var{dst} s8:@var{idx} s8:@var{src}
|
||||||
Store @var{src} into the struct @var{dst} at slot @var{idx}.
|
Store @var{src} into the struct @var{dst} at slot @var{idx}. The
|
||||||
|
@var{idx} value should be an unboxed unsigned 64-bit integer.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} allocate-struct/immediate s8:@var{dst} s8:@var{vtable} c8:@var{nfields}
|
@deftypefn Instruction {} allocate-struct/immediate s8:@var{dst} s8:@var{vtable} c8:@var{nfields}
|
||||||
|
@ -1291,12 +1319,14 @@ Make a new array with @var{type}, @var{fill}, and @var{bounds}, storing it in @v
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} string-length s12:@var{dst} s12:@var{src}
|
@deftypefn Instruction {} string-length s12:@var{dst} s12:@var{src}
|
||||||
Store the length of the string in @var{src} in @var{dst}.
|
Store the length of the string in @var{src} in @var{dst}, as an unboxed
|
||||||
|
unsigned 64-bit integer.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} string-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
@deftypefn Instruction {} string-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
||||||
Fetch the character at position @var{idx} in the string in @var{src}, and store
|
Fetch the character at position @var{idx} in the string in @var{src},
|
||||||
it in @var{dst}.
|
and store it in @var{dst}. The @var{idx} value should be an unboxed
|
||||||
|
unsigned 64-bit integer.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} cons s8:@var{dst} s8:@var{car} s8:@var{cdr}
|
@deftypefn Instruction {} cons s8:@var{dst} s8:@var{car} s8:@var{cdr}
|
||||||
|
@ -1340,16 +1370,16 @@ All of these operations place their result in their first operand,
|
||||||
Add @var{a} to @var{b}.
|
Add @var{a} to @var{b}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} add1 s12:@var{dst} s12:@var{src}
|
@deftypefn Instruction {} add/immediate s8:@var{dst} s8:@var{src} c8:@var{imm}
|
||||||
Add 1 to the value in @var{src}.
|
Add the unsigned integer @var{imm} to the value in @var{src}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} sub s8:@var{dst} s8:@var{a} s8:@var{b}
|
@deftypefn Instruction {} sub s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
Subtract @var{b} from @var{a}.
|
Subtract @var{b} from @var{a}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} sub1 s12:@var{dst} s12:@var{src}
|
@deftypefn Instruction {} sub/immediate s8:@var{dst} s8:@var{src} s8:@var{imm}
|
||||||
Subtract 1 from @var{src}.
|
Subtract the unsigned integer @var{imm} from the value in @var{src}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} mul s8:@var{dst} s8:@var{a} s8:@var{b}
|
@deftypefn Instruction {} mul s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
@ -1388,6 +1418,10 @@ Compute the bitwise inclusive @code{or} of @var{a} with @var{b}.
|
||||||
Compute the bitwise exclusive @code{or} of @var{a} with @var{b}.
|
Compute the bitwise exclusive @code{or} of @var{a} with @var{b}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} logsub s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
Place the bitwise @code{and} of @var{a} and the bitwise @code{not} of
|
||||||
|
@var{b} into @var{dst}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
@node Inlined Bytevector Instructions
|
@node Inlined Bytevector Instructions
|
||||||
@subsubsection Inlined Bytevector Instructions
|
@subsubsection Inlined Bytevector Instructions
|
||||||
|
@ -1398,6 +1432,11 @@ a clear path for eventual native compilation. Without this, Scheme
|
||||||
programs would need other primitives for accessing raw bytes -- but
|
programs would need other primitives for accessing raw bytes -- but
|
||||||
these primitives are as good as any.
|
these primitives are as good as any.
|
||||||
|
|
||||||
|
@deftypefn Instruction {} bv-length s12:@var{dst} s12:@var{src}
|
||||||
|
Store the length of the bytevector in @var{src} in @var{dst}, as an
|
||||||
|
unboxed unsigned 64-bit integer.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} bv-u8-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
@deftypefn Instruction {} bv-u8-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
||||||
@deftypefnx Instruction {} bv-s8-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
@deftypefnx Instruction {} bv-s8-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
||||||
@deftypefnx Instruction {} bv-u16-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
@deftypefnx Instruction {} bv-u16-ref s8:@var{dst} s8:@var{src} s8:@var{idx}
|
||||||
|
@ -1411,6 +1450,12 @@ these primitives are as good as any.
|
||||||
|
|
||||||
Fetch the item at byte offset @var{idx} in the bytevector @var{src}, and
|
Fetch the item at byte offset @var{idx} in the bytevector @var{src}, and
|
||||||
store it in @var{dst}. All accesses use native endianness.
|
store it in @var{dst}. All accesses use native endianness.
|
||||||
|
|
||||||
|
The @var{idx} value should be an unboxed unsigned 64-bit integer.
|
||||||
|
|
||||||
|
The results are all written to the stack as unboxed values, either as
|
||||||
|
signed 64-bit integers, unsigned 64-bit integers, or IEEE double
|
||||||
|
floating point numbers.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} bv-u8-set! s8:@var{dst} s8:@var{idx} s8:@var{src}
|
@deftypefn Instruction {} bv-u8-set! s8:@var{dst} s8:@var{idx} s8:@var{src}
|
||||||
|
@ -1426,4 +1471,138 @@ store it in @var{dst}. All accesses use native endianness.
|
||||||
|
|
||||||
Store @var{src} into the bytevector @var{dst} at byte offset @var{idx}.
|
Store @var{src} into the bytevector @var{dst} at byte offset @var{idx}.
|
||||||
Multibyte values are written using native endianness.
|
Multibyte values are written using native endianness.
|
||||||
|
|
||||||
|
The @var{idx} value should be an unboxed unsigned 64-bit integer.
|
||||||
|
|
||||||
|
The @var{src} values are all unboxed, either as signed 64-bit integers,
|
||||||
|
unsigned 64-bit integers, or IEEE double floating point numbers.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
|
@node Unboxed Integer Arithmetic
|
||||||
|
@subsubsection Unboxed Integer Arithmetic
|
||||||
|
|
||||||
|
Guile supports two kinds of unboxed integers: unsigned 64-bit integers,
|
||||||
|
and signed 64-bit integers. Guile prefers unsigned integers, in the
|
||||||
|
sense that Guile's compiler supports them better and the virtual machine
|
||||||
|
has more operations that work on them. Still, signed integers are
|
||||||
|
supported at least to allow @code{bv-s64-ref} and related instructions
|
||||||
|
to avoid boxing their values.
|
||||||
|
|
||||||
|
@deftypefn Instruction {} scm->u64 s12:@var{dst} s12:@var{src}
|
||||||
|
Unbox the SCM value at @var{src} to a unsigned 64-bit integer, placing
|
||||||
|
the result in @var{dst}. If the @var{src} value is not an exact integer
|
||||||
|
in the unsigned 64-bit range, signal an error.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} u64->scm s12:@var{dst} s12:@var{src}
|
||||||
|
Box the unsigned 64-bit integer at @var{src} to a SCM value and place
|
||||||
|
the result in @var{dst}. The result will be a fixnum or a bignum.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} load-u64 s24:@var{dst} au32:@var{high-bits} au32:@var{low-bits}
|
||||||
|
Load a 64-bit value formed by joining @var{high-bits} and
|
||||||
|
@var{low-bits}, and write it to @var{dst}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} scm->s64 s12:@var{dst} s12:@var{src}
|
||||||
|
@deftypefnx Instruction {} s64->scm s12:@var{dst} s12:@var{src}
|
||||||
|
@deftypefnx Instruction {} load-s64 s24:@var{dst} as32:@var{high-bits} as32:@var{low-bits}
|
||||||
|
Like @code{scm->u64}, @code{u64->scm}, and @code{load-u64}, but for
|
||||||
|
signed 64-bit integers.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
Sometimes the compiler can know that we will only need a subset of the
|
||||||
|
bits in an integer. In that case we can sometimes unbox an integer even
|
||||||
|
if it might be out of range.
|
||||||
|
|
||||||
|
@deftypefn Instruction {} scm->u64/truncate s12:@var{dst} s12:@var{src}
|
||||||
|
Take the SCM value in @var{dst} and @code{logand} it with @code{(1- (ash
|
||||||
|
1 64))}. Place the unboxed result in @var{dst}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} br-if-u64-= s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
||||||
|
@deftypefnx Instruction {} br-if-u64-< s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
||||||
|
@deftypefnx Instruction {} br-if-u64-<= s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
||||||
|
If the unboxed unsigned 64-bit integer value in @var{a} is @code{=},
|
||||||
|
@code{<}, or @code{<=} to the unboxed unsigned 64-bit integer value in
|
||||||
|
@var{b}, respectively, add @var{offset} to the current instruction
|
||||||
|
pointer.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} br-if-u64-=-scm s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
||||||
|
@deftypefnx Instruction {} br-if-u64-<-scm s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
||||||
|
@deftypefnx Instruction {} br-if-u64-<=-scm s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
|
||||||
|
If the unboxed unsigned 64-bit integer value in @var{a} is @code{=},
|
||||||
|
@code{<}, or @code{<=} to the SCM value in @var{b}, respectively, add
|
||||||
|
@var{offset} to the current instruction pointer.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} uadd s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
@deftypefnx Instruction {} usub s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
@deftypefnx Instruction {} umul s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
Like @code{add}, @code{sub}, and @code{mul}, except taking
|
||||||
|
the operands as unboxed unsigned 64-bit integers, and producing the
|
||||||
|
same. The result will be silently truncated to 64 bits.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} uadd/immediate s8:@var{dst} s8:@var{a} c8:@var{b}
|
||||||
|
@deftypefnx Instruction {} usub/immediate s8:@var{dst} s8:@var{a} c8:@var{b}
|
||||||
|
@deftypefnx Instruction {} umul/immediate s8:@var{dst} s8:@var{a} c8:@var{b}
|
||||||
|
Like @code{uadd}, @code{usub}, and @code{umul}, except the second
|
||||||
|
operand is an immediate unsigned 8-bit integer.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} ulogand s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
@deftypefnx Instruction {} ulogior s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
@deftypefnx Instruction {} ulogsub s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
Like @code{logand}, @code{logior}, and @code{logsub}, but operating on
|
||||||
|
unboxed unsigned 64-bit integers.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} ulsh s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
Shift the unboxed unsigned 64-bit integer in @var{a} left by @var{b}
|
||||||
|
bits, also an unboxed unsigned 64-bit integer. Truncate to 64 bits and
|
||||||
|
write to @var{dst} as an unboxed value. Only the lower 6 bits of
|
||||||
|
@var{b} are used.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} ursh s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
Like @code{ulsh}, but shifting right.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} ulsh/immediate s8:@var{dst} s8:@var{a} c8:@var{b}
|
||||||
|
@deftypefnx Instruction {} ursh/immediate s8:@var{dst} s8:@var{a} c8:@var{b}
|
||||||
|
Like @code{ulsh} and @code{ursh}, but encoding @code{b} as an immediate
|
||||||
|
8-bit unsigned integer.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
|
@node Unboxed Floating-Point Arithmetic
|
||||||
|
@subsubsection Unboxed Floating-Point Arithmetic
|
||||||
|
|
||||||
|
@deftypefn Instruction {} scm->f64 s12:@var{dst} s12:@var{src}
|
||||||
|
Unbox the SCM value at @var{src} to an IEEE double, placing the result
|
||||||
|
in @var{dst}. If the @var{src} value is not a real number, signal an
|
||||||
|
error.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} f64->scm s12:@var{dst} s12:@var{src}
|
||||||
|
Box the IEEE double at @var{src} to a SCM value and place the result in
|
||||||
|
@var{dst}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} load-f64 s24:@var{dst} au32:@var{high-bits} au32:@var{low-bits}
|
||||||
|
Load a 64-bit value formed by joining @var{high-bits} and
|
||||||
|
@var{low-bits}, and write it to @var{dst}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} fadd s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
@deftypefnx Instruction {} fsub s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
@deftypefnx Instruction {} fmul s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
@deftypefnx Instruction {} fdiv s8:@var{dst} s8:@var{a} s8:@var{b}
|
||||||
|
Like @code{add}, @code{sub}, @code{div}, and @code{mul}, except taking
|
||||||
|
the operands as unboxed IEEE double floating-point numbers, and producing
|
||||||
|
the same.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue