forked from MightyPork/crsn
parent
d489b214e0
commit
8222efe6da
@ -0,0 +1,126 @@ |
|||||||
|
use std::any::{Any, TypeId}; |
||||||
|
use std::collections::HashMap; |
||||||
|
|
||||||
|
use crate::asm::data::{DstDisp, Rd, Register, SrcDisp, Wr}; |
||||||
|
use crate::asm::data::literal::{Addr, Value}; |
||||||
|
use crate::asm::instr::op::EvalRes; |
||||||
|
use crate::runtime::fault::Fault; |
||||||
|
use crate::runtime::frame::{CallStack, REG_COUNT, StackFrame}; |
||||||
|
use crate::runtime::program::Program; |
||||||
|
use crate::asm::instr::Cond; |
||||||
|
use crate::runtime::frame::status::StatusFlags; |
||||||
|
|
||||||
|
pub struct RunState { |
||||||
|
/// Active stack frame
|
||||||
|
pub frame: StackFrame, |
||||||
|
/// Call stack
|
||||||
|
pub call_stack: CallStack, |
||||||
|
/// Extension data
|
||||||
|
pub ext_data: HashMap<TypeId, Box<dyn Any + Send>>, |
||||||
|
} |
||||||
|
|
||||||
|
impl RunState { |
||||||
|
pub fn ext_mut<T: Send + Default + 'static>(&mut self) -> &mut T { |
||||||
|
if !self.ext_data.contains_key(&TypeId::of::<T>()) { |
||||||
|
self.ext_data.insert(TypeId::of::<T>(), Box::new(T::default())); |
||||||
|
} |
||||||
|
|
||||||
|
self.ext_data.get_mut(&TypeId::of::<T>()).unwrap() |
||||||
|
.downcast_mut().unwrap() |
||||||
|
} |
||||||
|
|
||||||
|
pub fn set_flag(&mut self, cond : Cond, set : bool) { |
||||||
|
if set { |
||||||
|
self.frame.status.set(cond); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn test_cond(&self, cond : Cond) -> bool { |
||||||
|
self.frame.status.test(cond) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn set_pc(&mut self, pc: Addr) { |
||||||
|
self.frame.pc = pc; |
||||||
|
} |
||||||
|
|
||||||
|
pub fn get_pc(&self) -> Addr { |
||||||
|
self.frame.pc |
||||||
|
} |
||||||
|
|
||||||
|
pub fn clear_status(&mut self) { |
||||||
|
self.frame.status.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
pub fn update_status(&mut self, val: Value) { |
||||||
|
self.frame.status.update(val); |
||||||
|
} |
||||||
|
|
||||||
|
pub fn read(&mut self, rd: Rd) -> Result<Value, Fault> { |
||||||
|
match rd.d() { |
||||||
|
SrcDisp::Immediate(v) => Ok(v), |
||||||
|
SrcDisp::Register(Register::Res(rn)) => { |
||||||
|
if rn >= REG_COUNT as u8 { |
||||||
|
Err(Fault::RegisterNotExist { reg: Register::Res(rn) }) // TODO use match after @ when stabilized https://github.com/rust-lang/rust/issues/65490
|
||||||
|
} else { |
||||||
|
trace!("Rd {:?} = {}", rd, self.frame.res[rn as usize]); |
||||||
|
Ok(self.frame.res[rn as usize]) |
||||||
|
} |
||||||
|
} |
||||||
|
SrcDisp::Register(Register::Arg(rn)) => { |
||||||
|
if rn >= REG_COUNT as u8 { |
||||||
|
Err(Fault::RegisterNotExist { reg: Register::Arg(rn) }) |
||||||
|
} else { |
||||||
|
trace!("Rd {:?} = {}", rd, self.frame.arg[rn as usize]); |
||||||
|
Ok(self.frame.arg[rn as usize]) |
||||||
|
} |
||||||
|
} |
||||||
|
SrcDisp::Register(Register::Gen(rn)) => { |
||||||
|
if rn >= REG_COUNT as u8 { |
||||||
|
Err(Fault::RegisterNotExist { reg: Register::Gen(rn) }) |
||||||
|
} else { |
||||||
|
trace!("Rd {:?} = {}", rd, self.frame.gen[rn as usize]); |
||||||
|
Ok(self.frame.gen[rn as usize]) |
||||||
|
} |
||||||
|
} |
||||||
|
SrcDisp::ObjectPtr(_) => { |
||||||
|
unimplemented!("Read object ptr") |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn write(&mut self, wr: Wr, val: Value) -> Result<(), Fault> { |
||||||
|
trace!("WR {:?} := {}", wr, val); |
||||||
|
|
||||||
|
match wr.d() { |
||||||
|
DstDisp::Discard => { |
||||||
|
/* Discard */ |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
DstDisp::Register(Register::Res(rn)) => { |
||||||
|
if rn >= REG_COUNT as u8 { |
||||||
|
Err(Fault::RegisterNotExist { reg: Register::Res(rn) }) // TODO use match after @ when stabilized https://github.com/rust-lang/rust/issues/65490
|
||||||
|
} else { |
||||||
|
Err(Fault::RegisterNotWritable { reg: Register::Res(rn) }) |
||||||
|
} |
||||||
|
} |
||||||
|
DstDisp::Register(Register::Arg(rn)) => { |
||||||
|
if rn >= REG_COUNT as u8 { |
||||||
|
Err(Fault::RegisterNotExist { reg: Register::Arg(rn) }) |
||||||
|
} else { |
||||||
|
Err(Fault::RegisterNotWritable { reg: Register::Res(rn) }) |
||||||
|
} |
||||||
|
} |
||||||
|
DstDisp::Register(Register::Gen(rn)) => { |
||||||
|
if rn >= REG_COUNT as u8 { |
||||||
|
Err(Fault::RegisterNotExist { reg: Register::Gen(rn) }) |
||||||
|
} else { |
||||||
|
self.frame.gen[rn as usize] = val; |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
DstDisp::ObjectPtr(_) => { |
||||||
|
unimplemented!("Write object ptr") |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue