The BibbleVM Instruction Set
This page gives details about the format of each instruction and the operation it performs.
The Meaning of "must"
The description of each instruction is always given in the context of bytecode following the constraints of The Code Section.
In the descriptions of many instructions, it is stated that something "must" or "must not" be the case: "Both a and b must be 64-bit integers."
If some constraint (a "must" or "must not") in a description is not satisfied at runtime, behavior is undefined.
Instruction Encoding
An instruction consists of a 1-3 byte opcode followed directly by zero or more operands.
By default, an opcode consists of 1 byte, but when set to the hexadecimal value FF, the following 2 bytes are read and assembled as an extended opcode.
Operands are encoded in little-endian byte order in the same order as specified per instruction with no padding between them unless an instruction specifies otherwise.
Format of Instruction Descriptions
MNEMONIC
Opcode
Opcode for this instruction
Operation
Short description of the instruction
Operands
type op1, type op2
Accumulator
oldvalue → newvalue
Stack Pointer (Register)
oldvalue → newvalue
Stack
[..., value1, value2] → [..., value3]
Description
A longer description detailing constraints, the operation performed, the type of the data operated on, etc.
Errors
A list of potential runtime errors and why they can happen.
Notes
Comments not strictly part of the specification of an instruction are set aside as notes.
The instruction's mnemonic is its name. Its opcode is its numeric representation in hexadecimal form.
If the opcode consists of 2 digits, it's a single byte opcode, if it consists of FF followed by 4 digits, it's a extended 3 byte opcode.
Instructions
Disclaimer: I got really bored of writing 10 versions of the same arithmetic instructions, so I had an AI do it for me. This means that there could be some writing inconsistencies, but the overall logic of them should be accurate. Readers are encouraged to suggest edits to improve clarity and consistency for these instructions.
NOP
Opcode
0x00
Operation
Do nothing
Operands
None
Accumulator
No change
Stack
No change
Description
Do nothing.
HLT
Opcode
0x01
Operation
Halt execution
Operands
i8 exitcode
Accumulator
No change
Stack
No change
Description
Forcibly terminates the current BibbleVM.
Notes
Even though this terminates the BibbleVM, it doesn't necessarily terminate the host process running the it.
TRAP
Opcode
0x02
Operation
Execute a implementation-defined VM trap routine
Operands
i8 code
Accumulator
Implementation-defined
Stack
Implementation-defined
Description
Executes an implementation-defined VM routine identified by code.
Notes
Intended for use by standard library implementations. Not typically used in user code.
TRAP_IF_ZERO
Opcode
0x03
Operation
Execute a implementation-defined VM trap routine if accumulator is 0
Operands
i8 code
Accumulator
x → Implementation-defined if x == 0
Stack
Implementation-defined
Description
If the value in accumulator is equal to 0, executes an implementation-defined VM routine identified by code.
Otherwise, does nothing.
Notes
Intended for use by standard library implementations. Not typically used in user code.
TRAP_IF_NOT_ZERO
Opcode
0x04
Operation
Execute a implementation-defined VM trap routine if accumulator isn't 0
Operands
i8 code
Accumulator
x → Implementation-defined if x != 0
Stack
Implementation-defined
Description
If the value in accumulator isn't equal to 0, executes an implementation-defined VM routine identified by code.
Otherwise, does nothing.
Notes
Intended for use by standard library implementations. Not typically used in user code.
BRK
Opcode
0x05
Operation
Trigger debug break
Operands
None
Accumulator
No change
Stack
No change
Description
When a debugger is attached, triggers a breakpoint. Otherwise does nothing.
ADD
Opcode
0x10
Operation
Add integers
Operands
None
Accumulator
a → a + b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit signed integers. b is popped from the stack and added to a directly in the accumulator.
Overflow behavior is undefined, but never results in runtime errors.
SUB
Opcode
0x11
Operation
Subtract integers
Operands
None
Accumulator
a → a - b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit signed integers. b is popped from the stack and subtracted from a directly in the accumulator.
Overflow behavior is undefined, but never results in runtime errors.
MUL
Opcode
0x12
Operation
Multiply integers
Operands
None
Accumulator
a → a * b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit signed integers. b is popped from the stack and a is multiplied by it directly in the accumulator.
Overflow behavior is undefined, but never results in runtime errors.
DIV
Opcode
0x13
Operation
Divide integers
Operands
None
Accumulator
a → a / b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit signed integers. b is popped from the stack and a is divided by it directly in the accumulator.
Division of the most negative 64-bit value by -1 produces a result that cannot be represented. This case is undefined behavior, but does not raise a runtime error.
Errors
If the divisor is 0, causes a runtime error.
MOD
Opcode
0x14
Operation
Modulo integers
Operands
None
Accumulator
a → result
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit signed integers. b is popped from the stack. he result is a - (a / b) * b and is moved to the accumulator.
Applying modulo to the most negative 64-bit value with a divisor of -1 is undefined due to the underlying division step, but does not raise a runtime error.
Errors
If the divisor is 0, causes a runtime error.
AND
Opcode
0x15
Operation
Bitwise AND integers
Operands
None
Accumulator
a → a & b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack and the accumulator is set to the result of bitwise AND (conjunction) of a and b.
OR
Opcode
0x16
Operation
Bitwise OR integers
Operands
None
Accumulator
a → a | b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack and the accumulator is set to the result of bitwise OR of a and b.
XOR
Opcode
0x17
Operation
Bitwise XOR integers
Operands
None
Accumulator
a → a ^ b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack and the accumulator is set to the result of bitwise exclusive OR of a and b.
SHL
Opcode
0x18
Operation
Shift left integer
Operands
None
Accumulator
a → a << b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack and the value in accumulator is shifted left by s bit positions, where s is the value of the low 6 bits of b.
SHR
Opcode
0x19
Operation
Shift right integer
Operands
None
Accumulator
a → a >> b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack and the value in accumulator is shifted right by s bit positions, where s is the value of the low 6 bits of b.
NEG
Opcode
0x1A
Operation
Negate integer
Operands
None
Accumulator
a → -a
Stack
No change
Description
a must be a 64-bit integer. The value in the accumulator is set to the negation of a.
Negation is the same as subtraction from 0.
NOT
Opcode
0x1B
Operation
Bitwise NOT integer
Operands
None
Accumulator
a → ~a
Stack
No change
Description
a must be a 64-bit integer. The value in the accumulator is set to the bitwise complement of a (all bits inverted).
ADD2
Opcode
0x1C
Operation
Add integers
Operands
None
Accumulator
... → a + b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a + b and is moved to the accumulator.
Overflow behavior is undefined, but never results in runtime errors.
SUB2
Opcode
0x1D
Operation
Subtract integers
Operands
None
Accumulator
... → a - b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a - b and is moved to the accumulator.
Overflow behavior is undefined, but never results in runtime errors.
MUL2
Opcode
0x1E
Operation
Multiply integers
Operands
None
Accumulator
... → a * b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a * b and is moved to the accumulator.
Overflow behavior is undefined, but never results in runtime errors.
DIV2
Opcode
0x1F
Operation
Divide integers
Operands
None
Accumulator
... → a / b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a / b and is moved to the accumulator.
Division of the most negative 64-bit value by -1 produces a result that cannot be represented. This case is undefined behavior, but does not raise a runtime error.
Errors
If the divisor is 0, causes a runtime error.
MOD2
Opcode
0x20
Operation
Modulo integers
Operands
None
Accumulator
... → result
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a - (a / b) * b and is moved to the accumulator.
Applying modulo to the most negative 64-bit value with a divisor of -1 is undefined due to the underlying division step, but does not raise a runtime error.
Errors
If the divisor is 0, causes a runtime error.
None
AND2
Opcode
0x21
Operation
Bitwise AND integers
Operands
None
Accumulator
... → a & b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is the bitwise AND (conjunction) of a and b and is moved to the accumulator.
OR2
Opcode
0x22
Operation
Bitwise OR integers
Operands
None
Accumulator
... → a | b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is the bitwise OR of a and b and is moved to the accumulator.
XOR2
Opcode
0x23
Operation
Bitwise XOR integers
Operands
None
Accumulator
... → a ^ b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is the bitwise exclusive OR of a and b and is moved to the accumulator.
SHL2
Opcode
0x24
Operation
Shift left integer
Operands
None
Accumulator
... → a << b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a shifted left by s bit positions, where s is the value of the low 6 bits of b and is moved to the accumulator.
SHR2
Opcode
0x25
Operation
Shift right integer
Operands
None
Accumulator
... → a >> b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a shifted left by s bit positions, where s is the value of the low 6 bits of b and is moved to the accumulator.
ADD_ST
Opcode
0x26
Operation
Add integers
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a + b]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a + b and is pushed onto the stack.
Overflow behavior is undefined, but never results in runtime errors.
SUB_ST
Opcode
0x27
Operation
Subtract integers
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a - b]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a - b and is pushed onto the stack.
Overflow behavior is undefined, but never results in runtime errors.
MUL_ST
Opcode
0x28
Operation
Multiply integers
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a * b]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a * b and is pushed onto the stack.
Overflow behavior is undefined, but never results in runtime errors.
DIV_ST
Opcode
0x29
Operation
Divide integers
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a / b]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a / b and is pushed onto the stack.
Division of the most negative 64-bit value by -1 produces a result that cannot be represented. This case is undefined behavior, but does not raise a runtime error.
Errors
If the divisor is 0, causes a runtime error.
MOD_ST
Opcode
0x2A
Operation
Modulo integers
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., result]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a - (a / b) * b and is pushed onto the stack.
Applying modulo to the most negative 64-bit value with a divisor of -1 is undefined due to the underlying division step, but does not raise a runtime error.
Errors
If the divisor is 0, causes a runtime error.
AND_ST
Opcode
0x2B
Operation
Bitwise AND integers
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a & b]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is bitwise AND (conjunction) of a and b and is pushed onto the stack.
OR_ST
Opcode
0x2C
Operation
Bitwise OR integers
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a | b]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is bitwise OR of a and b and is pushed onto the stack.
XOR_ST
Opcode
0x2D
Operation
Bitwise XOR integers
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a ^ b]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is bitwise exclusive OR of a and b and is pushed onto the stack.
SHL_ST
Opcode
0x2E
Operation
Shift left integer
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a << b]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a shifted left by s bit positions, where s is the value of the low 6 bits of b and is pushed onto the stack.
SHR_ST
Opcode
0x2F
Operation
Shift right integer
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a >> b]
Description
Both a and b must be 64-bit integers. The values are popped from the stack. The result is a shifted right by s bit positions, where s is the value of the low 6 bits of b and is pushed onto the stack.
NEG_ST
Opcode
0x30
Operation
Negate integer
Operands
None
Accumulator
No change
Stack
[..., a] → [..., -a]
Description
a must be a 64-bit integer. The top value of the stack is set to the negation of a.
Negation is the same as subtraction from 0.
NOT_ST
Opcode
0x31
Operation
Bitwise NOT integer
Operands
None
Accumulator
No change
Stack
[..., a] → [..., ~a]
Description
a must be a 64-bit integer. The top value of the stack is set to the bitwise complement of a (all bits inverted).
ADD_IMM
Opcode
0x32
Operation
Add immediate to accumulator
Operands
i32 value
Accumulator
a → a + value
Stack
No change
Description
a must be a 64-bit integer. The value in the accumulator is increased by the 32-bit immediate value.
Overflow behavior is undefined, but never results in runtime errors.
SUB_IMM
Opcode
0x33
Operation
Subtract immediate from accumulator
Operands
i32 value
Accumulator
a → a - value
Stack
No change
Description
a must be a 64-bit integer. The value in the accumulator is decreased by the 32-bit immediate value.
Overflow behavior is undefined, but never results in runtime errors.
MUL_IMM
Opcode
0x34
Operation
Multiply accumulator by immediate
Operands
i32 value
Accumulator
a → a * value
Stack
No change
Description
a must be a 64-bit integer. The value in the accumulator is multiplied by the 32-bit immediate value.
Overflow behavior is undefined, but never results in runtime errors.
DIV_IMM
Opcode
0x35
Operation
Divide accumulator by immediate
Operands
i32 value
Accumulator
a → a / value
Stack
No change
Description
a must be a 64-bit integer. The accumulator is divided by the 32-bit immediate value.
Division of the most negative 64-bit value by -1 produces a result that cannot be represented. This case is undefined behavior, but does not raise a runtime error.
Errors
If the divisor is 0, causes a runtime error.
MOD_IMM
Opcode
0x36
Operation
Modulo accumulator by immediate
Operands
i32 value
Accumulator
a → result
Stack
No change
Description
a must be a 64-bit integer. The accumulator is set to the result of a - (a / value) * value.
Applying modulo to the most negative 64-bit value with a divisor of -1 is undefined due to the underlying division step, but does not raise a runtime error.
Errors
If the divisor is 0, causes a runtime error.
AND_IMM
Opcode
0x37
Operation
Bitwise AND accumulator with immediate
Operands
i32 value
Accumulator
a → a & value
Stack
No change
Description
a must be a 64-bit integer. The value in the accumulator is set to the result of bitwise AND (conjunction) of a and the 32-bit immediate value.
OR_IMM
Opcode
0x38
Operation
Bitwise OR accumulator with immediate
Operands
i32 value
Accumulator
a → a | value
Stack
No change
Description
a must be a 64-bit integer. The value in the accumulator is set to the result of bitwise OR of a and the 32-bit immediate value.
XOR_IMM
Opcode
0x39
Operation
Bitwise XOR accumulator with immediate
Operands
i32 value
Accumulator
a → a ^ value
Stack
No change
Description
a must be a 64-bit integer. The value in the accumulator is set to the result of bitwise exclusive OR of a and the 32-bit immediate value.
SHL_IMM
Opcode
0x3A
Operation
Shift left accumulator by immediate
Operands
i32 value
Accumulator
a → a << value
Stack
No change
Description
a must be a 64-bit integer. The value in the accumulator is shifted left by s bit positions, where s is the value of the low 6 bits of the 32-bit immediate value.
SHR_IMM
Opcode
0x3B
Operation
Shift right accumulator by immediate
Operands
i32 value
Accumulator
a → a >> value
Stack
No change
Description
a must be a 64-bit integer. The value in the accumulator is shifted right by s bit positions, where s is the value of the low 6 bits of the 32-bit immediate value.
ADD_IMM_ST
Opcode
0x3C
Operation
Add immediate to top of stack
Operands
i32 value
Accumulator
No change
Stack
[..., a] → [..., a + value]
Description
a must be a 64-bit integer. The top value of the stack is increased by the 32-bit immediate value.
Overflow behavior is undefined, but never results in runtime errors.
SUB_IMM_ST
Opcode
0x3D
Operation
Subtract immediate from top of stack
Operands
i32 value
Accumulator
No change
Stack
[..., a] → [..., a - value]
Description
a must be a 64-bit integer. The top value of the stack is decreased by the 32-bit immediate value.
Overflow behavior is undefined, but never results in runtime errors.
MUL_IMM_ST
Opcode
0x3E
Operation
Multiply top of stack by immediate
Operands
i32 value
Accumulator
No change
Stack
[..., a] → [..., a * value]
Description
a must be a 64-bit integer. The top value of the stack is multiplied by the 32-bit immediate value.
Overflow behavior is undefined, but never results in runtime errors.
DIV_IMM_ST
Opcode
0x3F
Operation
Divide top of stack by immediate
Operands
i32 value
Accumulator
No change
Stack
[..., a] → [..., a / value]
Description
a must be a 64-bit integer. The top value of the stack is divided by the 32-bit immediate value.
Division of the most negative 64-bit value by -1 produces a result that cannot be represented. This case is undefined behavior, but does not raise a runtime error.
Errors
If the divisor is 0, causes a runtime error.
MOD_IMM_ST
Opcode
0x40
Operation
Modulo top of stack by immediate
Operands
i32 value
Accumulator
No change
Stack
[..., a] → [..., result]
Description
a must be a 64-bit integer. The top value of the stack is replaced with the result of a - (a / value) * value.
Applying modulo to the most negative 64-bit value with a divisor of -1 is undefined due to the underlying division step, but does not raise a runtime error.
Errors
If the divisor is 0, causes a runtime error.
AND_IMM_ST
Opcode
0x41
Operation
Bitwise AND top of stack with immediate
Operands
i32 value
Accumulator
No change
Stack
[..., a] → [..., a & value]
Description
a must be a 64-bit integer. The top value of the stack is set to the result of bitwise AND (conjunction) of a and the 32-bit immediate value.
OR_IMM_ST
Opcode
0x42
Operation
Bitwise OR top of stack with immediate
Operands
i32 value
Accumulator
No change
Stack
[..., a] → [..., a | value]
Description
a must be a 64-bit integer. The top value of the stack is set to the result of bitwise OR of a and the 32-bit immediate value.
XOR_IMM_ST
Opcode
0x43
Operation
Bitwise XOR top of stack with immediate
Operands
i32 value
Accumulator
No change
Stack
[..., a] → [..., a ^ value]
Description
a must be a 64-bit integer. The top value of the stack is set to the result of bitwise exclusive OR of a and the 32-bit immediate value.
SHL_IMM_ST
Opcode
0x44
Operation
Shift left top of stack by immediate
Operands
i32 value
Accumulator
No change
Stack
[..., a] → [..., a << 0x3F]
Description
a must be a 64-bit integer. The top value of the stack is shifted left by s bit positions, where s is the value of the low 6 bits of the 32-bit immediate value.
SHR_IMM_ST
Opcode
0x45
Operation
Shift right top of stack by immediate
Operands
i32 value
Accumulator
No change
Stack
[..., a] → [..., a >> value]
Description
a must be a 64-bit integer. The top value of the stack is shifted right by s bit positions, where s is the value of the low 6 bits of the 32-bit immediate value.
FADD
Opcode
0x50
Operation
Add floats
Operands
None
Accumulator
a → a + b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit floating-point values. b is popped from the stack and added to the accumulator a.
FSUB
Opcode
0x51
Operation
Subtract floats
Operands
None
Accumulator
a → a - b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit floating-point values. b is popped from the stack and subtracted from the accumulator a.
FMUL
Opcode
0x52
Operation
Multiply floats
Operands
None
Accumulator
a → a * b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit floating-point values. b is popped from the stack and multiplied with the accumulator a.
FDIV
Opcode
0x53
Operation
Divide floats
Operands
None
Accumulator
a → a / b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit floating-point values. b is popped from the stack and the accumulator a is divided by b.
If b is 0.0, the result is IEEE 754-defined (±Inf or NaN).
FADD2
Opcode
0x54
Operation
Add floats
Operands
None
Accumulator
... → a + b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit floating-point values. The values are popped from the stack. The result a + b is moved to the accumulator.
FSUB2
Opcode
0x55
Operation
Subtract floats
Operands
None
Accumulator
... → a - b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit floating-point values. The values are popped from the stack. The result a - b is moved to the accumulator.
FMUL2
Opcode
0x56
Operation
Multiply floats
Operands
None
Accumulator
... → a * b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit floating-point values. The values are popped from the stack. The result a * b is moved to the accumulator.
FDIV2
Opcode
0x57
Operation
Divide floats
Operands
None
Accumulator
... → a / b
Stack
[..., a, b] → [...]
Description
Both a and b must be 64-bit floating-point values. The values are popped from the stack. The result a / b is moved to the accumulator.
If b is 0.0, the result is IEEE 754-defined (±Inf or NaN).
FADD_ST
Opcode
0x58
Operation
Add floats
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a + b]
Description
Both a and b must be 64-bit floating-point values. The values are popped from the stack and their sum is pushed back.
FSUB_ST
Opcode
0x59
Operation
Subtract floats
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a - b]
Description
Both a and b must be 64-bit floating-point values. The values are popped from the stack and the difference is pushed back.
FMUL_ST
Opcode
0x5A
Operation
Multiply floats
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a * b]
Description
Both a and b must be 64-bit floating-point values. The values are popped from the stack and the product is pushed back.
FDIV_ST
Opcode
0x5B
Operation
Divide floats
Operands
None
Accumulator
No change
Stack
[..., a, b] → [..., a / b]
Description
Both a and b must be 64-bit floating-point values. The values are popped from the stack and the quotient is pushed back.
If b is 0.0, the result is IEEE 754-defined (±Inf or NaN).
FNEG
Opcode
0x5C
Operation
Negate float
Operands
None
Accumulator
a → -a
Stack
No change
Description
a must be a 64-bit floating-point value. The value in the accumulator is negated.
FADD_IMM
Opcode
0x5D
Operation
Add float immediate
Operands
f32 value
Accumulator
a → a + value
Stack
No change
Description
Adds a 32-bit floating-point immediate value to the accumulator.
FSUB_IMM
Opcode
0x5E
Operation
Subtract float immediate
Operands
f32 value
Accumulator
a → a - value
Stack
No change
Description
Subtracts a 32-bit floating-point immediate value from the accumulator.
FMUL_IMM
Opcode
0x5F
Operation
Multiply by float immediate
Operands
f32 value
Accumulator
a → a * value
Stack
No change
Description
Multiplies the accumulator by a 32-bit floating-point immediate value.
FDIV_IMM
Opcode
0x60
Operation
Divide by float immediate
Operands
f32 value
Accumulator
a → a / value
Stack
No change
Description
Divides the accumulator by a 32-bit floating-point immediate value.
If value is 0.0, the result is IEEE 754-defined (±Inf or NaN).
FADD_IMM_ST
Opcode
0x61
Operation
Add float immediate to stack
Operands
f32 value
Accumulator
No change
Stack
[..., a] → [..., a + value]
Description
Pops the top float from the stack, adds a 32-bit immediate value, and pushes the result.
FSUB_IMM_ST
Opcode
0x62
Operation
Subtract float immediate from stack
Operands
f32 value
Accumulator
No change
Stack
[..., a] → [..., a - value]
Description
Pops the top float from the stack, subtracts a 32-bit immediate value, and pushes the result.
FMUL_IMM_ST
Opcode
0x63
Operation
Multiply stack top by float immediate
Operands
f32 value
Accumulator
No change
Stack
[..., a] → [..., a * value]
Description
Pops the top float from the stack, multiplies by a 32-bit immediate value, and pushes the result.
FDIV_IMM_ST
Opcode
0x64
Operation
Divide stack top by float immediate
Operands
f32 value
Accumulator
No change
Stack
[..., a] → [..., a / value]
Description
Pops the top float from the stack, divides by a 32-bit immediate value, and pushes the result.
If value is 0.0, the result is IEEE 754-defined (±Inf or NaN).
CMP_EQ
Opcode
0x65
Operation
Compare integers equal
Operands
None
Accumulator
a → a == b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack. The result is a == b and is pushed to the stack.
CMP_NE
Opcode
0x66
Operation
Compare integers not equal
Operands
None
Accumulator
a → a != b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack. The result is a != b and is pushed to the stack.
CMP_LT
Opcode
0x67
Operation
Compare integers less than
Operands
None
Accumulator
a → a < b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack. The result is a < b and is pushed to the stack.
CMP_GT
Opcode
0x68
Operation
Compare integers greater than
Operands
None
Accumulator
a → a > b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack. The result is a > b and is pushed to the stack.
CMP_LTE
Opcode
0x69
Operation
Compare integers less than or equal
Operands
None
Accumulator
a → a <= b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack. The result is a <= b and is pushed to the stack.
CMP_GTE
Opcode
0x6A
Operation
Compare integers greater than or equal
Operands
None
Accumulator
a → a >= b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit integers. b is popped from the stack. The result is a >= b and is pushed to the stack.
FCMP_EQ
Opcode
0x6B
Operation
Compare floats equal
Operands
None
Accumulator
a → a == b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit floats. b is popped from the stack. The result is a == b and is pushed to the stack.
FCMP_NE
Opcode
0x6C
Operation
Compare floats not equal
Operands
None
Accumulator
a → a != b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit floats. b is popped from the stack. The result is a != b and is pushed to the stack.
FCMP_LT
Opcode
0x6D
Operation
Compare floats less than
Operands
None
Accumulator
a → a < b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit floats. b is popped from the stack. The result is a < b and is pushed to the stack.
FCMP_GT
Opcode
0x6E
Operation
Compare floats greater than
Operands
None
Accumulator
a → a > b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit floats. b is popped from the stack. The result is a > b and is pushed to the stack.
FCMP_LTE
Opcode
0x6F
Operation
Compare floats less than or equal
Operands
None
Accumulator
a → a <= b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit floats. b is popped from the stack. The result is a <= b and is pushed to the stack.
FCMP_GTE
Opcode
0x70
Operation
Compare floats greater than or equal
Operands
None
Accumulator
a → a >= b
Stack
[..., b] → [...]
Description
Both a and b must be 64-bit floats. b is popped from the stack. The result is a >= b and is pushed to the stack.
CMP_EQ0
Opcode
0x71
Operation
Compare integer to zero
Operands
None
Accumulator
a → a == 0
Stack
No change
Description
a must be a 64-bit integer. The result is a == 0 and is pushed to the stack.
CMP_NE0
Opcode
0x72
Operation
Compare integer to zero
Operands
None
Accumulator
a → a != 0
Stack
No change
Description
a must be a 64-bit integer. The result is a != 0 and is pushed to the stack.
CMP_LT0
Opcode
0x73
Operation
Compare integer to zero
Operands
None
Accumulator
a → a < 0
Stack
No change
Description
a must be a 64-bit integer. The result is a < 0 and is pushed to the stack.
CMP_GT0
Opcode
0x74
Operation
Compare integer to zero
Operands
None
Accumulator
a → a > 0
Stack
No change
Description
a must be a 64-bit integer. The result is a > 0 and is pushed to the stack.
CMP_LTE0
Opcode
0x75
Operation
Compare integer to zero
Operands
None
Accumulator
a → a <= 0
Stack
No change
Description
a must be a 64-bit integer. The result is a <= 0 and is pushed to the stack.
CMP_GTE0
Opcode
0x76
Operation
Compare integer to zero
Operands
None
Accumulator
a → a >= 0
Stack
No change
Description
a must be a 64-bit integer. The result is a >= 0 and is pushed to the stack.
FCMP_EQ0
Opcode
0x77
Operation
Compare float to zero
Operands
None
Accumulator
a → a == 0f
Stack
No change
Description
a must be a 64-bit float. The result is a == 0.0 and is pushed to the stack.
FCMP_NE0
Opcode
0x78
Operation
Compare float to zero
Operands
None
Accumulator
a → a != 0f
Stack
No change
Description
a must be a 64-bit float. The result is a != 0.0 and is pushed to the stack.
FCMP_LT0
Opcode
0x79
Operation
Compare float to zero
Operands
None
Accumulator
a → a < 0f
Stack
No change
Description
a must be a 64-bit float. The result is a < 0.0 and is pushed to the stack.
FCMP_GT0
Opcode
0x7A
Operation
Compare float to zero
Operands
None
Accumulator
a → a > 0f
Stack
No change
Description
a must be a 64-bit float. The result is a > 0.0 and is pushed to the stack.
FCMP_LTE0
Opcode
0x7B
Operation
Compare float to zero
Operands
None
Accumulator
a → a <= 0f
Stack
No change
Description
a must be a 64-bit float. The result is a <= 0.0 and is pushed to the stack.
FCMP_GTE0
Opcode
0x7C
Operation
Compare float to zero
Operands
None
Accumulator
a → a >= 0f
Stack
No change
Description
a must be a 64-bit float. The result is a >= 0.0 and is pushed to the stack.
PUSH_ACC
Opcode
0x80
Operation
Push accumulator
Operands
None
Accumulator
No change
Stack
[...] → [..., acc]
Description
acc is the current 64-bit value in the accumulator. acc is pushed onto the stack.
PUSH_SP
Opcode
0x81
Operation
Push stack pointer
Operands
None
Accumulator
No change
Stack
[...] → [..., sp]
Description
sp is the current 64-bit value in the stack pointer register. sp is pushed onto the stack.
Notes
The stack pointer will never be a real memory pointer in sandbox mode. Other than that, its value is implementation-defined.
POP_ACC
Opcode
0x82
Operation
Pop stack value into accumulator
Operands
None
Accumulator
... → value
Stack
[..., value] → [...]
Description
The topmost stack value is popped and moved into the accumulator.
POP_SP
Opcode
0x83
Operation
Pop stack value into stack pointer
Operands
None
Accumulator
No change
Stack Pointer (Register)
... → value
Stack
[..., value] → [...]
Description
The topmost stack value is popped and moved into the stack pointer register.
POP_DISCARD
Opcode
0x84
Operation
Pop n stack values and discard them
Operands
u8 n
Accumulator
No change
Stack
[..., [elem1, ...]] → [...]
Description
Pops n elements from the stack and discards their values.
CONST
Opcode
0x85
Operation
Move constant value into accumulator
Operands
i8 value
Accumulator
... → value
Stack
No change
Description
Loads an 8-bit immediate value and moves it into the accumulator.
CONST32
Opcode
0x86
Operation
Move constant value into accumulator
Operands
i32 value
Accumulator
... → value
Stack
No change
Description
Loads an 32-bit immediate value and moves it into the accumulator.
CONST64
Opcode
0x87
Operation
Move constant value into accumulator
Operands
i64 value
Accumulator
... → value
Stack
No change
Description
Loads an 64-bit immediate value and moves it into the accumulator.
CONST_ST
Opcode
0x88
Operation
Push constant value to stack
Operands
i8 value
Accumulator
... → value
Stack
No change
Description
Loads an 8-bit immediate value and pushes it to the stack.
CONST32_ST
Opcode
0x89
Operation
Push constant value to stack
Operands
i32 value
Accumulator
... → value
Stack
No change
Description
Loads an 32-bit immediate value and pushes it to the stack.
CONST64_ST
Opcode
0x8A
Operation
Push constant value to stack
Operands
i64 value
Accumulator
... → value
Stack
No change
Description
Loads an 64-bit immediate value and pushes it to the stack.
LOAD
Opcode
0x8B
Operation
Load stack value into accumulator
Operands
i16 index
Accumulator
... → value
Stack
No change
Description
The way this instruction loads a value depends on whether index is positive or negative.
If index is positive (>= 0), load from the current frame's stack base plus index.
If index is negative (< 0), load from the stack pointer register minus the absolute value of index.
For example, a given index of -1 would load the topmost stack value, and a given index of 0 would load the first stack value.
LOAD_ST
Opcode
0x8C
Operation
Load stack value and push to stack
Operands
i16 index
Accumulator
No change
Stack
[...] → [..., value]
Description
The way this instruction loads a value depends on whether index is positive or negative.
If index is positive (>= 0), load from the current frame’s stack base plus index.
If index is negative (< 0), load from the stack pointer register minus the absolute value of index.
For example, an index of -1 would load the topmost stack value and push it, while an index of 0 would load the first stack value and push it.
STORE
Opcode
0x8D
Operation
Store accumulator value in stack
Operands
i16 index
Accumulator
No change
Stack
No change
Description
The way this instruction stores a value depends on whether index is positive or negative.
If index is positive (>= 0), store to the current frame’s stack base plus index.
If index is negative (< 0), store to the stack pointer register minus the absolute value of index.
For example, an index of -1 stores the accumulator to the topmost stack slot, while an index of 0 stores to the first slot.
STORE_ST
Opcode
0x8E
Operation
Pop value and store in stack
Operands
i16 index
Accumulator
No change
Stack
[..., value] → [...]
Description
The way this instruction stores a value depends on whether index is positive or negative.
If index is positive (>= 0), store to the current frame’s stack base plus index.
If index is negative (< 0), store to the stack pointer register minus the absolute value of index before the value is popped.
For example, an index of -1 stores the popped value to the topmost slot before popping, while an index of 0 stores to the first slot.
RESERVE
Opcode
0x8F
Operation
Reserve slots on the stack
Operands
u8 count
Accumulator
No change
Stack
[...] → [..., _ x count]
Description
Allocates count uninitialized slots on the stack. These slots are meant to be used for local storage.
No values are popped or written. This operation is the equivalent of sp += count.
JMP
Opcode
0x97
Operation
Branch always
Operands
i16 branch
Accumulator
No change
Stack
No change
Description
Unconditionally increments the program counter by branch as a signed integer.
JZ
Opcode
0x98
Operation
Branch if zero
Operands
i16 branch
Accumulator
No change
Stack
No change
Description
Increments the program counter by branch as a signed integer if the value in the accumulator is equal to 0.
JNZ
Opcode
0x99
Operation
Branch if not zero
Operands
i16 branch
Accumulator
No change
Stack
No change
Description
Increments the program counter by branch as a signed integer if the value in the accumulator is not equal to 0.
CALL
Opcode
0x9A
Operation
Invoke CallEntry
Operands
u32 target, u8 argc
Accumulator
... → garbage or a return value
Stack
[..., [arg1, ...]] → [...]
Description
target is an address pointing to a CallEntry within the data section.
The stack must contain argc values.
For simplicity, we will refer to the addressed CallEntry as 'the function.' This does not mean that a CallEntry always has to be a function symbol.
If the function is not yet resolved, its module and entry point are resolved and cached for future use.
If the function is not native, the argc values are popped from the stack. A new stack frame is created on the current thread.
The argc values are pushed in reverse order so that they appear in the same order on the new frame as they were in the previous frame.
The new frame is then made the current, and the program counter is set to the specified entry of the function.
If the function is native, the argc values are popped from the stack and are passed as parameters to the implementation of the function.
The code is executed in an implementation-dependent manner. When the platform-dependent code returns, the return value storage is moved to the accumulator regardless of the functions return type.
In the case of a void function, the accumulator will contain garbage data.
CALL_EX
Opcode
0x9B
Operation
Invoke CallEntry
Operands
u32 target, u16 argc
Accumulator
... → garbage or a return value
Stack
[.., [arg1, ...]] → [...]
Description
Works like the CALL instruction, but with a wide argc operand.
CALL_DYN
Opcode
0x9C
Operation
Invoke CallEntry dynamically
Operands
u16 argc
Accumulator
target → garbage or a return value
Stack
[.., [arg1, ...]] → [...]
Description
Works like the CALL_EX instruction, but the target address is determined at runtime.
The target address is taken from the low 32 bits of the accumulator and treated as an unsigned 32-bit integer.
This instruction is meant to be used with dynamic method dispatch, not on its own.
CALL_TINY
Opcode
0x9D
Operation
Invoke CallEntry
Operands
u16 target, u8 argc
Accumulator
... → garbage or a return value
Stack
[.., [arg1, ...]] → [...]
Description
Works like the CALL instruction, but with a narrow target operand.
CALL_TINY_EX
Opcode
0x9E
Operation
Invoke CallEntry
Operands
u16 target, u16 argc
Accumulator
... → garbage or a return value
Stack
[.., [arg1, ...]] → [...]
Description
Works like the CALL instruction, but with a narrow target operand and wide argc operand.
RET
Opcode
0x9F
Operation
Return from callable
Operands
None
Accumulator
No change
Stack
[...] → empty
Description
Any values on the current stack frame are discarded. The interpreter then returns control to the caller by updating the program counter to a saved value.