Add macros for fetching 32 and 64 bits from instruction pipeline.
This commit is contained in:
parent
e4ee8fd2db
commit
6c8911e7c9
@ -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::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user