Skip to content

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.