Add macros for fetching 32 and 64 bits from instruction pipeline.

This commit is contained in:
Jesse Brault 2024-11-29 13:13:16 -06:00
parent e4ee8fd2db
commit 6c8911e7c9

View File

@ -9,33 +9,45 @@ struct DmObject {
layout: Layout, layout: Layout,
} }
macro_rules! get_32_le {
( $code: expr, $i: expr, $offset: literal, $T: ident ) => {
$code[$i + $offset] as $T
+ (($code[$i + $offset + 1] as $T) << 8)
+ (($code[$i + $offset + 2] as $T) << 16)
+ (($code[$i + $offset + 3] as $T) << 24)
};
}
macro_rules! get_64_le {
( $code: expr, $i: expr, $offset: literal, $T: ident ) => {
$code[$i + $offset] as $T
+ (($code[$i + $offset + 1] as $T) << 8)
+ (($code[$i + $offset + 2] as $T) << 16)
+ (($code[$i + $offset + 3] as $T) << 24)
+ (($code[$i + $offset + 4] as $T) << 32)
+ (($code[$i + $offset + 5] as $T) << 40)
+ (($code[$i + $offset + 6] as $T) << 48)
+ (($code[$i + $offset + 7] as $T) << 56)
};
}
pub fn run(code: &Vec<u8>, registers: &mut Vec<u64>, register_types: &mut Vec<RegisterType>) { pub fn run(code: &Vec<u8>, registers: &mut Vec<u64>, register_types: &mut Vec<RegisterType>) {
let mut i = 0; let mut i = 0;
while i < code.len() { while i < code.len() {
match code[i] { match code[i] {
MOV_INT => { MOV_INT => {
let target_register = code[i + 1] as usize; let target_register = code[i + 1] as usize;
let operand: u32 = code[i + 2] as u32 let operand = get_32_le!(code, i, 2, u32);
+ ((code[i + 3] as u32) << 8)
+ ((code[i + 4] as u32) << 16)
+ ((code[i + 5] as u32) << 24);
registers[target_register] = operand as u64; registers[target_register] = operand as u64;
register_types[target_register] = RegisterType::Int; register_types[target_register] = RegisterType::Int;
i += 6 i += 6;
} }
MOV_LONG => { MOV_LONG => {
let target_register = code[i + 1] as usize; let target_register = code[i + 1] as usize;
let operand: u64 = code[i + 2] as u64 let operand = get_64_le!(code, i, 2, u64);
+ ((code[i + 3] as u64) << 8)
+ ((code[i + 4] as u64) << 16)
+ ((code[i + 5] as u64) << 24)
+ ((code[i + 6] as u64) << 32)
+ ((code[i + 7] as u64) << 40)
+ ((code[i + 8] as u64) << 48)
+ ((code[i + 9] as u64) << 56);
registers[target_register] = operand; registers[target_register] = operand;
register_types[target_register] = RegisterType::Long; register_types[target_register] = RegisterType::Long;
i += 10 i += 10;
} }
MOV_DOUBLE => { /* todo */ } MOV_DOUBLE => { /* todo */ }
MOV_REGISTER => { MOV_REGISTER => {
@ -47,10 +59,7 @@ pub fn run(code: &Vec<u8>, registers: &mut Vec<u64>, register_types: &mut Vec<Re
} }
ALLOC => { ALLOC => {
let target_register = code[i + 1] as usize; let target_register = code[i + 1] as usize;
let size = code[i + 2] as usize let size = get_32_le!(code, i, 2, usize);
+ ((code[i + 3] as usize) << 8)
+ ((code[i + 4] as usize) << 16)
+ ((code[i + 5] as usize) << 24);
let layout = Layout::from_size_align(size, 4).unwrap(); let layout = Layout::from_size_align(size, 4).unwrap();
let pointer = unsafe { alloc_zeroed(layout) }; let pointer = unsafe { alloc_zeroed(layout) };
let dm_object = Box::new(DmObject { let dm_object = Box::new(DmObject {
@ -79,7 +88,7 @@ pub fn run(code: &Vec<u8>, registers: &mut Vec<u64>, register_types: &mut Vec<Re
if register_types[target_register] != RegisterType::Pointer { if register_types[target_register] != RegisterType::Pointer {
panic!("target_register {} is not a Pointer", target_register); panic!("target_register {} is not a Pointer", target_register);
} }
let offset = convert_to_u32(&code[(i + 2)..(i + 6)]) as isize; let offset = get_32_le!(code, i, 2, isize);
let box_address = registers[target_register]; let box_address = registers[target_register];
let new_address = unsafe { let new_address = unsafe {
let dm_object = Box::from_raw(box_address as *mut DmObject); let dm_object = Box::from_raw(box_address as *mut DmObject);
@ -98,10 +107,6 @@ pub fn run(code: &Vec<u8>, registers: &mut Vec<u64>, register_types: &mut Vec<Re
} }
} }
fn convert_to_u32(bytes: &[u8]) -> u32 {
bytes[0] as u32 | (bytes[1] as u32) << 8 | (bytes[2] as u32) << 16 | (bytes[3] as u32) << 24
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;