Expand description
Tape bytecode format
Fidget’s bytecode is a packed representation of a
RegTape. It may be used as the
evaluation tape for non-Rust VMs, e.g. an interpreter running on a GPU.
The format is not stable; it may change without notice. It would be
wise to dynamically check any interpreter against iter_ops, which
associates opcode integers with their names.
The bytecode format is a list of little-endian u32 words, representing
tape operations in forward-evaluation order. Each operation in the tape maps
to two words, though the second word is not always used. Having a
fixed-length representation makes it easier to iterate both forwards (for
evaluation) and backwards (for simplification).
The first two words are always 0xFFFF_FFFF 0x0000_0000, and the last two
words are always 0xFFFF_FFFF 0xFFFF_FFFF. Note that this is equivalent to
an operation with opcode 0xFF; this special opcode may also be used with
user-defined semantics, as long as the immediate is not either reserved
value.
Operations are packed into the first u32 as follows:
| Byte | Value |
|---|---|
| 0 | opcode |
| 1 | output register |
| 2 | first input register |
| 3 | second input register |
The opcode byte is generated automatically from BytecodeOp tags.
Depending on the opcode, the input register bytes may not be used.
An input register byte of 0xFF indicates that the second word should be
used as an immediate value; the u32 should be bitcast to an f32.
Load and Store are implemented with
BytecodeOp::Mem, using the immediate flag 0xFF to indicate whether the
operation reads or writes to memory. The second word is the u32 immediate
representing a memory slot.
Structs§
- Bytecode
- Serialized bytecode for external evaluation
- Bytecode
OpIter - An iterator over the variants of BytecodeOp
- Reserved
Register - Error type indicating that the reserved register (255) was used
Enums§
- Bytecode
Op - Operations in the bytecode tape
Functions§
- iter_
ops - Iterates over opcode
(names, value)tuples, with names inCamelCase