deimos-lang/src/vm/op_codes.rs
2024-12-28 15:10:56 -06:00

202 lines
4.7 KiB
Rust

use crate::push_bytes;
/// ## mov(register: u8, operand: u32)
/// - 0: opcode
/// - 1: register
/// - 2..5: operand
pub const MOV_INT: u8 = 0x01;
pub const MOV_LONG: u8 = 0x02;
pub const MOV_DOUBLE: u8 = 0x03;
/// ## mov(target_register: u8, source_register: u8)
/// 0: opcode
/// 1: target_register
/// 2: source_register
pub const MOV_REGISTER: u8 = 0x04;
/// ## alloc(register: u8, size: u32)
/// 0: opcode
/// 1: register
/// 2..5: size
pub const ALLOC: u8 = 0x05;
/// ## dealloc(register: u8)
/// 0: opcode
/// 1: register
pub const DEALLOC: u8 = 0x06;
/// ## mov_int_to(register: u8, offset: u32, operand: u32)
/// 0: opcode
/// 1: register
/// 2..5: offset
/// 6..9: operand
pub const MOV_INT_TO: u8 = 0x07;
pub const MOV_LONG_TO: u8 = 0x08;
pub const MOV_DOUBLE_TO: u8 = 0x09;
pub const MOV_REGISTER_TO: u8 = 0x0a;
pub const MOV_CONST: u8 = 0x0b;
pub const ALLOC_RAW: u8 = 0x0d;
pub const DEALLOC_RAW: u8 = 0x0e;
pub const PLATFORM_CALL: u8 = 0x10;
pub const INVOKE_FN: u8 = 0x11;
pub const INVOKE_VIRTUAL: u8 = 0x12;
pub const INVOKE_DYNAMIC: u8 = 0x14;
pub const MOV_SIZE_OF: u8 = 0x30;
pub const MULTIPLY: u8 = 0x40;
pub const LOAD: u8 = 0x50;
pub const STORE: u8 = 0x60;
macro_rules! push_number {
( $dest: expr, $num: expr ) => {
push_bytes!($dest, $num.to_le_bytes())
};
}
macro_rules! push_string {
( $dest: expr, $s: expr ) => {
push_bytes!($dest, $s.bytes())
};
}
pub fn add_mov_int(code: &mut Vec<u8>, register: u8, operand: u32) {
code.push(MOV_INT);
code.push(register);
push_number!(code, operand);
}
pub fn add_mov_register(code: &mut Vec<u8>, target_register: u8, source_register: u8) {
code.push(MOV_REGISTER);
code.push(target_register);
code.push(source_register);
}
pub fn add_alloc(code: &mut Vec<u8>, target_register: u8, implementation_name: &str) {
code.push(ALLOC);
code.push(target_register);
push_number!(code, implementation_name.len() as u32);
push_string!(code, implementation_name);
}
pub fn add_alloc_raw_from(code: &mut Vec<u8>, target_register: u8, source_register: u8) {
code.push(ALLOC_RAW);
code.push(target_register);
code.push(source_register);
}
pub fn add_dealloc(code: &mut Vec<u8>, register: u8) {
code.push(DEALLOC);
code.push(register);
}
pub fn add_mov_int_to(code: &mut Vec<u8>, register: u8, offset: u32, operand: u32) {
code.push(MOV_INT_TO);
code.push(register);
push_number!(code, offset);
push_number!(code, operand);
}
pub fn add_mov_register_to(
code: &mut Vec<u8>,
target_register: u8,
offset: u32,
source_register: u8,
) {
code.push(MOV_REGISTER_TO);
code.push(target_register);
push_number!(code, offset);
code.push(source_register);
}
pub fn add_load(
code: &mut Vec<u8>,
target_register: u8,
source_register: u8,
field_index: usize
) {
code.push(LOAD);
code.push(target_register);
code.push(source_register);
push_number!(code, field_index);
}
pub fn add_store(
code: &mut Vec<u8>,
target_register: u8,
field_index: usize,
source_register: u8,
) {
code.push(STORE);
code.push(target_register);
push_number!(code, field_index);
code.push(source_register);
}
pub fn add_mov_const(
code: &mut Vec<u8>,
address_register: u8,
size_register: u8,
lib_name: &str,
const_id: u32,
) {
code.push(MOV_CONST);
code.push(address_register);
code.push(size_register);
push_number!(code, lib_name.len() as u32);
push_string!(code, lib_name);
push_number!(code, const_id);
}
pub fn add_platform_call(
code: &mut Vec<u8>,
symbol_name: &str,
return_register: u8,
arg_registers: &[u8],
) {
code.push(PLATFORM_CALL);
push_number!(code, symbol_name.len() as u32);
push_string!(code, symbol_name);
push_number!(code, return_register);
push_number!(code, arg_registers.len() as u8);
for &b in arg_registers {
code.push(b);
}
}
pub fn add_invoke_fn(code: &mut Vec<u8>, fn_name: &str, return_register: u8, arg_registers: &[u8]) {
code.push(INVOKE_FN);
push_number!(code, fn_name.len() as u32);
push_string!(code, fn_name);
push_number!(code, return_register);
push_number!(code, arg_registers.len() as u8);
for &b in arg_registers {
code.push(b);
}
}
pub fn add_mov_size_of(code: &mut Vec<u8>, target_register: u8, source_register: u8) {
code.push(MOV_SIZE_OF);
code.push(target_register);
code.push(source_register);
}
pub fn add_multiply(
code: &mut Vec<u8>,
target_register: u8,
left_register: u8,
right_register: u8,
) {
code.push(MULTIPLY);
code.push(target_register);
code.push(left_register);
code.push(right_register);
}