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, register: u8, operand: u32) { code.push(MOV_INT); code.push(register); push_number!(code, operand); } pub fn add_mov_register(code: &mut Vec, 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, 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, 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, register: u8) { code.push(DEALLOC); code.push(register); } pub fn add_mov_int_to(code: &mut Vec, 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, 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, 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, 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, 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, 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, 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, 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, target_register: u8, left_register: u8, right_register: u8, ) { code.push(MULTIPLY); code.push(target_register); code.push(left_register); code.push(right_register); }