= Deimos Virtual Machine
Jesse Brault <jbrault@mac.com>
0.1.0, December 2024
:toc:

== Op Codes

All numbers larger than `u8` are stored in **little-endian** format in raw bytecode.

=== Move Byte

Copies the operand into the target register.

[source]
----
mov_byte(
  target_register: u8,
  operand: u8
)
----

=== Move Int

Copies the operand into the target register.

[source]
----
mov_int(
  target_register: u8,
  operand: u32
)
----

The operand is converted to an `i32` at runtime by the virtual machine.

=== Move Long

Copies the operand to the target register.

[source]
----
mov_long(
  target_register: u8,
  operand: u64
)
----

The operand is converted to an `i64` at runtime by the virtual machine.

=== Move USize

Copies the operand to the target register.

[source]
----
mov_usize(
  target_register: u8,
  operand: usize
)
----

Unlike most other operand types, this operand remains unsigned at runtime.

=== Move Double

Copies the operand to the target register.

[source]
----
mov_double(
  target_register: u8,
  operand: u64
)
----

The operand is converted to an `f64` at runtime by the virtual machine.

=== Move Boolean

Copies the operand to the target register.

[source]
----
mov_boolean(
  target_register: u8,
  operand: u8
)
----

The operand is converted to a `bool` at runtime by the virtual machine.

=== Move Register

Copies the value in one register to another.

[source]
----
mov_register(
  target_register: u8,
  source_register: u8
)
----

=== Load Byte

Loads the target register with the `u8` stored at the offset from the base of the object stored in the source register.

[source]
----
load_byte(
  target_register: u8,
  source_register: u8,
  offset: usize
)
----

The source register must contain a `DvmValue::Object` at runtime.

=== Load Int

Loads the target register with the `i32` stored at the offset from the base of the object stored in the source register.

[source]
----
load_int(
  target_register: u8,
  source_register: u8,
  offset: usize
)
----

The source register must contain a `DvmValue::Object` at runtime.

=== Load Long

Loads the target register with the `i64` stored at the offset from the base of the object stored in the source register.

[source]
----
load_long(
  target_register: u8,
  source_register: u8,
  offset: usize
)
----

The source register must contain a `DvmValue::Object` at runtime.

=== Load Double

=== Load USize

=== Load Boolean

=== Load Object

Loads the target register with the `DvmValue::Object` stored at the offset from the base of the object stored in the
source register.

[source]
----
load_object(
  target_register: u8,
  source_register: u8,
  offset: usize
)
----

The source register must contain a `DvmValue::Object` at runtime, and the data at the offset from that object's base
must be a valid `Rc<DvmObject>`.

=== Store

Stores the value contained in the source register to the offset from the base of the object contained in the target
register.

[source]
----
store(
  target_register: u8,
  offset: usize,
  source_register: u8
)
----

The target register must contain a `DvmValue::Object` at runtime.

=== Allocate

Allocates memory for an object of the specified type and stores the allocated `DvmValue::Object` in the target register.

[source]
----
alloc(
  target_register: u8,
  implementation_name_length: usize,
  implementation_name: [u8]
)
----

The `implementation_name` is the bytes array of a UTF-8-encoded string, and `implementation_name_length` is the length
of that array.

=== Deallocate

Deallocates the memory for the object stored in the target register.

[source]
----
dealloc(
  target_register: u8
)
----

The target register must contain a `DvmValue::Object` at runtime.

=== Platform Call

=== Invoke Function

=== Invoke Virtual

=== Invoke Dynamic

=== Add

[source]
----
add(
  target_register: u8,
  left_register: u8,
  right_register: u8
)
----

=== Subtract

=== Multiply

=== Divide

=== Modulo

=== Power
