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,
}
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>) {
let mut i = 0;
while i < code.len() {
match code[i] {
MOV_INT => {
let target_register = code[i + 1] as usize;
let operand: u32 = code[i + 2] as u32
+ ((code[i + 3] as u32) << 8)
+ ((code[i + 4] as u32) << 16)
+ ((code[i + 5] as u32) << 24);
let operand = get_32_le!(code, i, 2, u32);
registers[target_register] = operand as u64;
register_types[target_register] = RegisterType::Int;
i += 6
i += 6;
}
MOV_LONG => {
let target_register = code[i + 1] as usize;
let operand: u64 = code[i + 2] as 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);
let operand = get_64_le!(code, i, 2, u64);
registers[target_register] = operand;
register_types[target_register] = RegisterType::Long;
i += 10
i += 10;
}
MOV_DOUBLE => { /* todo */ }
MOV_REGISTER => {
@ -47,10 +59,7 @@ pub fn run(code: &Vec<u8>, registers: &mut Vec<u64>, register_types: &mut Vec<Re
}
ALLOC => {
let target_register = code[i + 1] as usize;
let size = code[i + 2] as usize
+ ((code[i + 3] as usize) << 8)
+ ((code[i + 4] as usize) << 16)
+ ((code[i + 5] as usize) << 24);
let size = get_32_le!(code, i, 2, usize);
let layout = Layout::from_size_align(size, 4).unwrap();
let pointer = unsafe { alloc_zeroed(layout) };
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 {
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 new_address = unsafe {
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)]
mod tests {
use super::*;