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"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
log = "*"
hashbrown = "0.13.2"

View File

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

View File

@ -1,32 +1,67 @@
#[rustfmt::skip]
#[derive(Debug, Clone, Copy)]
pub struct Registers {
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,
}
use core::{
fmt::Debug,
ops::{Index, IndexMut},
};
impl Registers {
#[rustfmt::skip]
pub fn new() -> Self{
Self {
a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0,
a1: 0, b1: 0, c1: 0, d1: 0, e1: 0, f1: 0,
a2: 0, b2: 0, c2: 0, d2: 0, e2: 0, f2: 0,
a3: 0, b3: 0, c3: 0, d3: 0, e3: 0, f3: 0,
a4: 0, b4: 0, c4: 0, d4: 0, e4: 0, f4: 0,
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,
a9: 0, b9: 0, c9: 0, d9: 0, e9: 0, f9: 0,
}
#[derive(Debug, Clone, Copy)]
pub struct Registers([Value; 60]);
impl Index<u8> for Registers {
type Output = Value;
#[inline]
fn index(&self, index: u8) -> &Self::Output {
&self.0[index as usize]
}
}
impl IndexMut<u8> for Registers {
#[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::{
bytecode::ops::{Operations::*, RWSubTypes::*},
bytecode::ops::{opcode::*},
engine::Engine,
RuntimeErrors,
RuntimeErrors, HaltStatus,
};
fn main() -> Result<(), RuntimeErrors> {
// TODO: Grab program from cmdline
#[rustfmt::skip]
let prog: Vec<u8> = vec![
NOP as u8,
JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0,
NOP,
JUMP, 0, 0, 0, 0, 0, 0, 0, 0,
];
let mut eng = Engine::new(prog);
// eng.set_timer_callback(time);
eng.enviroment_call_table[10] = Some(print_fn);
eng.run()?;
while eng.run()? != HaltStatus::Halted {}
eng.dump();
println!("{:#?}", eng.registers);
@ -25,6 +25,7 @@ fn main() -> Result<(), RuntimeErrors> {
pub fn time() -> u32 {
9
}
pub fn print_fn(engine: &mut Engine) -> Result<&mut Engine, u64> {
println!("hello");
Ok(engine)

View File

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