Changed register handling

feature/trap-handlers
ondra05 2023-05-28 16:49:01 +02:00
parent eb3edea2e7
commit 908ee5b922
No known key found for this signature in database
GPG Key ID: 0DA6D2BB2285E881
5 changed files with 84 additions and 48 deletions

View File

@ -3,8 +3,6 @@ name = "hbvm"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
log = "*" log = "*"
hashbrown = "0.13.2" hashbrown = "0.13.2"

View File

@ -1,3 +1,5 @@
use log::info;
pub mod call_stack; pub mod call_stack;
pub mod config; pub mod config;
pub mod enviroment_calls; pub mod enviroment_calls;
@ -7,12 +9,13 @@ pub mod tests;
use { use {
self::call_stack::CallStack, self::call_stack::CallStack,
crate::{memory, HaltStatus, RuntimeErrors}, crate::{engine::enviroment_calls::EnviromentCall, memory, HaltStatus, RuntimeErrors},
alloc::vec::Vec, alloc::vec::Vec,
config::EngineConfig, config::EngineConfig,
log::trace, log::trace,
regs::Registers, regs::Registers,
}; };
// pub const PAGE_SIZE: usize = 8192; // pub const PAGE_SIZE: usize = 8192;
pub struct RealPage { pub struct RealPage {
@ -23,8 +26,8 @@ pub struct RealPage {
pub struct VMPage { pub struct VMPage {
pub data: [u8; 8192], pub data: [u8; 8192],
} }
impl VMPage { impl Default for VMPage {
pub fn new() -> Self { fn default() -> Self {
Self { Self {
data: [0; 4096 * 2], data: [0; 4096 * 2],
} }
@ -52,10 +55,10 @@ pub fn empty_enviroment_call(engine: &mut Engine) -> Result<&mut Engine, u64> {
} }
pub struct Engine { pub struct Engine {
pub index: usize, pub pc: usize,
pub program: Vec<u8>, pub program: Vec<u8>,
pub registers: Registers, pub registers: Registers,
pub config: EngineConfig, pub config: EngineConfig,
/// BUG: This DOES NOT account for overflowing /// BUG: This DOES NOT account for overflowing
pub last_timer_count: u32, pub last_timer_count: u32,
@ -64,12 +67,11 @@ pub struct Engine {
pub enviroment_call_table: [Option<EnviromentCall>; 256], pub enviroment_call_table: [Option<EnviromentCall>; 256],
pub call_stack: CallStack, pub call_stack: CallStack,
} }
use crate::engine::enviroment_calls::EnviromentCall;
impl Engine { impl Engine {
pub fn set_timer_callback(&mut self, func: fn() -> u32) { pub fn set_timer_callback(&mut self, func: fn() -> u32) {
self.timer_callback = Some(func); self.timer_callback = Some(func);
} }
pub fn set_register(&mut self, register: u8, value: u64) {}
} }
impl Engine { impl Engine {
@ -81,9 +83,9 @@ impl Engine {
trace!("{:?}", mem.read_addr8(0)); trace!("{:?}", mem.read_addr8(0));
let ecall_table: [Option<EnviromentCall>; 256] = [None; 256]; let ecall_table: [Option<EnviromentCall>; 256] = [None; 256];
Self { Self {
index: 0, pc: 0,
program, program,
registers: Registers::new(), registers: Registers::default(),
config: EngineConfig::default(), config: EngineConfig::default(),
last_timer_count: 0, last_timer_count: 0,
timer_callback: None, timer_callback: None,
@ -95,6 +97,6 @@ impl Engine {
pub fn dump(&self) {} pub fn dump(&self) {}
pub fn run(&mut self) -> Result<HaltStatus, RuntimeErrors> { pub fn run(&mut self) -> Result<HaltStatus, RuntimeErrors> {
Ok(HaltStatus::Halted) Ok(HaltStatus::Running)
} }
} }

View File

@ -1,32 +1,67 @@
#[rustfmt::skip] use core::{
#[derive(Debug, Clone, Copy)] fmt::Debug,
pub struct Registers { ops::{Index, IndexMut},
pub a0: u64, pub b0: u64, pub c0: u64, pub d0: u64, pub e0: u64, pub f0: u64, };
pub a1: u64, pub b1: u64, pub c1: u64, pub d1: u64, pub e1: u64, pub f1: u64,
pub a2: u64, pub b2: u64, pub c2: u64, pub d2: u64, pub e2: u64, pub f2: u64,
pub a3: u64, pub b3: u64, pub c3: u64, pub d3: u64, pub e3: u64, pub f3: u64,
pub a4: u64, pub b4: u64, pub c4: u64, pub d4: u64, pub e4: u64, pub f4: u64,
pub a5: u64, pub b5: u64, pub c5: u64, pub d5: u64, pub e5: u64, pub f5: u64,
pub a6: u64, pub b6: u64, pub c6: u64, pub d6: u64, pub e6: u64, pub f6: u64,
pub a7: u64, pub b7: u64, pub c7: u64, pub d7: u64, pub e7: u64, pub f7: u64,
pub a8: u64, pub b8: u64, pub c8: u64, pub d8: u64, pub e8: u64, pub f8: u64,
pub a9: u64, pub b9: u64, pub c9: u64, pub d9: u64, pub e9: u64, pub f9: u64,
}
impl Registers { #[derive(Debug, Clone, Copy)]
#[rustfmt::skip] pub struct Registers([Value; 60]);
pub fn new() -> Self{
Self { impl Index<u8> for Registers {
a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, type Output = Value;
a1: 0, b1: 0, c1: 0, d1: 0, e1: 0, f1: 0,
a2: 0, b2: 0, c2: 0, d2: 0, e2: 0, f2: 0, #[inline]
a3: 0, b3: 0, c3: 0, d3: 0, e3: 0, f3: 0, fn index(&self, index: u8) -> &Self::Output {
a4: 0, b4: 0, c4: 0, d4: 0, e4: 0, f4: 0, &self.0[index as usize]
a5: 0, b5: 0, c5: 0, d5: 0, e5: 0, f5: 0, }
a6: 0, b6: 0, c6: 0, d6: 0, e6: 0, f6: 0, }
a7: 0, b7: 0, c7: 0, d7: 0, e7: 0, f7: 0,
a8: 0, b8: 0, c8: 0, d8: 0, e8: 0, f8: 0, impl IndexMut<u8> for Registers {
a9: 0, b9: 0, c9: 0, d9: 0, e9: 0, f9: 0, #[inline]
} fn index_mut(&mut self, index: u8) -> &mut Self::Output {
&mut self.0[index as usize]
}
}
impl Default for Registers {
fn default() -> Self {
Self([Value { u: 0 }; 60])
}
}
/// # Safety
/// The macro invoker shall make sure that byte reinterpret-cast
/// won't cause undefined behaviour.
macro_rules! value_def {
($($fname:ident : $fty:ident, $getter:ident);* $(;)?) => {
#[derive(Clone, Copy)]
pub union Value {
$($fname: $fty),*
}
impl Value {$(
#[inline]
pub fn $getter(&self) -> $fty {
unsafe { self.$fname }
}
)*}
$(impl From<$fty> for Value {
#[inline]
fn from($fname: $fty) -> Self {
Self { $fname }
}
})*
}
}
value_def! {
u: u64, unsigned;
s: i64, signed;
f: f64, float;
}
impl Debug for Value {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.unsigned().fmt(f)
} }
} }

View File

@ -1,21 +1,21 @@
use hbvm::{ use hbvm::{
bytecode::ops::{Operations::*, RWSubTypes::*}, bytecode::ops::{opcode::*},
engine::Engine, engine::Engine,
RuntimeErrors, RuntimeErrors, HaltStatus,
}; };
fn main() -> Result<(), RuntimeErrors> { fn main() -> Result<(), RuntimeErrors> {
// TODO: Grab program from cmdline // TODO: Grab program from cmdline
#[rustfmt::skip] #[rustfmt::skip]
let prog: Vec<u8> = vec![ let prog: Vec<u8> = vec![
NOP as u8, NOP,
JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0, JUMP, 0, 0, 0, 0, 0, 0, 0, 0,
]; ];
let mut eng = Engine::new(prog); let mut eng = Engine::new(prog);
// eng.set_timer_callback(time); // eng.set_timer_callback(time);
eng.enviroment_call_table[10] = Some(print_fn); eng.enviroment_call_table[10] = Some(print_fn);
eng.run()?; while eng.run()? != HaltStatus::Halted {}
eng.dump(); eng.dump();
println!("{:#?}", eng.registers); println!("{:#?}", eng.registers);
@ -25,6 +25,7 @@ fn main() -> Result<(), RuntimeErrors> {
pub fn time() -> u32 { pub fn time() -> u32 {
9 9
} }
pub fn print_fn(engine: &mut Engine) -> Result<&mut Engine, u64> { pub fn print_fn(engine: &mut Engine) -> Result<&mut Engine, u64> {
println!("hello"); println!("hello");
Ok(engine) Ok(engine)

View File

@ -52,7 +52,7 @@ impl Memory {
page.data()[offset as usize] = value; page.data()[offset as usize] = value;
} }
None => { None => {
let mut pg = VMPage::new(); let mut pg = VMPage::default();
pg.data[offset as usize] = value; pg.data[offset as usize] = value;
self.inner.insert(page, Page::VMPage(pg)); self.inner.insert(page, Page::VMPage(pg));
trace!("Mapped page {}", page); trace!("Mapped page {}", page);