diff --git a/crsn/src/asm/data/literal.rs b/crsn/src/asm/data/literal.rs index 89d445a..4ed46e0 100644 --- a/crsn/src/asm/data/literal.rs +++ b/crsn/src/asm/data/literal.rs @@ -61,6 +61,13 @@ impl From for u64 { } } +impl From for i64 { + fn from(addr: Addr) -> Self { + addr.0 as i64 + } +} + + /// Label name #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub enum Label { diff --git a/crsn/src/asm/data/mod.rs b/crsn/src/asm/data/mod.rs index 6fe35d7..6fc4265 100644 --- a/crsn/src/asm/data/mod.rs +++ b/crsn/src/asm/data/mod.rs @@ -19,12 +19,10 @@ pub mod mask; pub enum DataDisp { /// Constant value Immediate(Value), - /// Constant memory address - ImmediatePtr(Addr), /// Register Register(Register), - /// Pointer into memory, stored in a numbered register - RegisterPtr(Register), + /// Object pointer + ObjectPtr(Register), /// Discard the written value Discard, } @@ -35,14 +33,11 @@ impl Display for DataDisp { DataDisp::Immediate(v) => { write!(f, "{}", as_signed(*v)) } - DataDisp::ImmediatePtr(a) => { - write!(f, "@0x{:#18x}", a.0) - } DataDisp::Register(r) => { write!(f, "{}", r) } - DataDisp::RegisterPtr(r) => { - write!(f, "@{}", r) + DataDisp::ObjectPtr(r) => { + write!(f, "%{}", r) } DataDisp::Discard => { write!(f, "_") @@ -55,9 +50,8 @@ impl From for DataDisp { fn from(s: SrcDisp) -> Self { match s { SrcDisp::Immediate(x) => DataDisp::Immediate(x), - SrcDisp::ImmediatePtr(x) => DataDisp::ImmediatePtr(x), SrcDisp::Register(x) => DataDisp::Register(x), - SrcDisp::RegisterPtr(x) => DataDisp::RegisterPtr(x), + SrcDisp::ObjectPtr(x) => DataDisp::ObjectPtr(x), } } } @@ -65,9 +59,8 @@ impl From for DataDisp { impl From for DataDisp { fn from(s: DstDisp) -> Self { match s { - DstDisp::ImmediatePtr(x) => DataDisp::ImmediatePtr(x), DstDisp::Register(x) => DataDisp::Register(x), - DstDisp::RegisterPtr(x) => DataDisp::RegisterPtr(x), + DstDisp::ObjectPtr(x) => DataDisp::ObjectPtr(x), DstDisp::Discard => DataDisp::Discard, } } @@ -78,12 +71,10 @@ impl From for DataDisp { pub enum SrcDisp { /// Constant value Immediate(Value), - /// Constant memory address - ImmediatePtr(Addr), /// Register Register(Register), /// Pointer into memory, stored in a numbered register - RegisterPtr(Register), + ObjectPtr(Register), } impl TryFrom for SrcDisp { @@ -92,9 +83,8 @@ impl TryFrom for SrcDisp { fn try_from(value: DataDisp) -> Result { match value { DataDisp::Immediate(x) => Ok(SrcDisp::Immediate(x)), - DataDisp::ImmediatePtr(x) => Ok(SrcDisp::ImmediatePtr(x)), DataDisp::Register(x) => Ok(SrcDisp::Register(x)), - DataDisp::RegisterPtr(x) => Ok(SrcDisp::RegisterPtr(x)), + DataDisp::ObjectPtr(x) => Ok(SrcDisp::ObjectPtr(x)), DataDisp::Discard => Err(AsmError::DiscardAsValue), } } @@ -103,12 +93,10 @@ impl TryFrom for SrcDisp { /// Data destination disposition #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum DstDisp { - /// Constant memory address - ImmediatePtr(Addr), /// Register Register(Register), /// Pointer into memory, stored in a numbered register - RegisterPtr(Register), + ObjectPtr(Register), /// Discard the written value Discard, } @@ -116,9 +104,8 @@ pub enum DstDisp { impl From for SrcDisp { fn from(s: DstDisp) -> Self { match s { - DstDisp::ImmediatePtr(x) => SrcDisp::ImmediatePtr(x), DstDisp::Register(x) => SrcDisp::Register(x), - DstDisp::RegisterPtr(x) => SrcDisp::RegisterPtr(x), + DstDisp::ObjectPtr(x) => SrcDisp::ObjectPtr(x), DstDisp::Discard => SrcDisp::Immediate(0), } } @@ -130,9 +117,8 @@ impl TryFrom for DstDisp { fn try_from(value: DataDisp) -> Result { match value { DataDisp::Immediate(_x) => Err(AsmError::ValueAsOutput), - DataDisp::ImmediatePtr(x) => Ok(DstDisp::ImmediatePtr(x)), DataDisp::Register(x) => Ok(DstDisp::Register(x)), - DataDisp::RegisterPtr(x) => Ok(DstDisp::RegisterPtr(x)), + DataDisp::ObjectPtr(x) => Ok(DstDisp::ObjectPtr(x)), DataDisp::Discard => Ok(DstDisp::Discard), } } diff --git a/crsn/src/asm/instr/op.rs b/crsn/src/asm/instr/op.rs index 6375caf..0b56f95 100644 --- a/crsn/src/asm/instr/op.rs +++ b/crsn/src/asm/instr/op.rs @@ -9,7 +9,7 @@ use crate::builtin::defs::BuiltinOp; use crate::runtime::fault::Fault; -use crate::runtime::run_thread::{RunState, ThreadInfo}; +use crate::runtime::run_thread::{state::RunState, ThreadInfo}; /// A higher level simple opration #[derive(Debug)] diff --git a/crsn/src/asm/parse/parse_data.rs b/crsn/src/asm/parse/parse_data.rs index e1c11a1..5cad326 100644 --- a/crsn/src/asm/parse/parse_data.rs +++ b/crsn/src/asm/parse/parse_data.rs @@ -32,13 +32,8 @@ pub fn parse_data_disp(tok: Option) -> Result { return Ok(DataDisp::Discard); } - if let Some(reference) = s.strip_prefix('@') { - if reference.starts_with(|c: char| c.is_ascii_digit()) { - let val: u64 = parse_u64(reference)?; - Ok(DataDisp::ImmediatePtr(Addr(val))) - } else { - Ok(DataDisp::RegisterPtr(reg::parse_reg(reference)?)) - } + if let Some(reference) = s.strip_prefix('%') { + Ok(DataDisp::ObjectPtr(reg::parse_reg(reference)?)) } else if s.starts_with(|c: char| c.is_ascii_digit()) { Ok(DataDisp::Immediate(unsafe { std::mem::transmute(parse_i64(s)?) })) } else { diff --git a/crsn/src/builtin/exec.rs b/crsn/src/builtin/exec.rs index 168dde6..f323a6a 100644 --- a/crsn/src/builtin/exec.rs +++ b/crsn/src/builtin/exec.rs @@ -8,11 +8,10 @@ use crate::runtime::frame::{StackFrame}; use crate::builtin::defs::BuiltinOp; use crate::asm::data::literal::Addr; -use crate::runtime::run_thread::{ThreadInfo, RunState}; +use crate::runtime::run_thread::{ThreadInfo, state::RunState}; impl OpTrait for BuiltinOp { fn execute(&self, info: &ThreadInfo, state: &mut RunState) -> Result { - let frame = &mut state.frame; let program = &info.program; let mut res = EvalRes::default(); match self { @@ -38,7 +37,7 @@ impl OpTrait for BuiltinOp { BuiltinOp::FarJump(name) => { match program.find_far_label(name) { Ok(pos) => { - frame.pc = pos; + state.set_pc(pos); } Err(e) => { return Err(e); @@ -46,9 +45,9 @@ impl OpTrait for BuiltinOp { } } BuiltinOp::Jump(name) => { - match program.find_local_label(frame.pc, name) { + match program.find_local_label(state.get_pc(), name) { Ok(pos) => { - frame.pc = pos; + state.set_pc(pos); } Err(e) => { return Err(e); @@ -56,10 +55,10 @@ impl OpTrait for BuiltinOp { } } BuiltinOp::JumpIf(cond, name) => { - if frame.status.test(*cond) { - match program.find_local_label(frame.pc, name) { + if state.test_cond(*cond) { + match program.find_local_label(state.get_pc(), name) { Ok(pos) => { - frame.pc = pos; + state.set_pc(pos); } Err(e) => { return Err(e); @@ -68,10 +67,10 @@ impl OpTrait for BuiltinOp { } } BuiltinOp::FarJumpIf(cond, name) => { - if frame.status.test(*cond) { + if state.test_cond(*cond) { match program.find_far_label(name) { Ok(pos) => { - frame.pc = pos; + state.set_pc(pos); } Err(e) => { return Err(e); @@ -84,11 +83,11 @@ impl OpTrait for BuiltinOp { Ok(pos) => { let mut values = Vec::with_capacity(args.len()); for arg in args { - values.push(frame.read(*arg)?); + values.push(state.read(*arg)?); } let mut frame2 = StackFrame::new(pos, &values); - std::mem::swap(frame, &mut frame2); + std::mem::swap(&mut state.frame, &mut frame2); state.call_stack.push(frame2); res.advance = 0; } @@ -102,10 +101,10 @@ impl OpTrait for BuiltinOp { Some(previous) => { let mut values = Vec::with_capacity(retvals.len()); for arg in retvals { - values.push(frame.read(*arg)?); + values.push(state.read(*arg)?); } - *frame = previous; - frame.set_retvals(&values); + state.frame = previous; + state.frame.set_retvals(&values); } None => { return Err(Fault::CallStackUnderflow); @@ -113,31 +112,33 @@ impl OpTrait for BuiltinOp { } } BuiltinOp::Skip(val) => { - let steps = frame.read(*val)?; + let steps = state.read(*val)?; res.advance = i64::from_ne_bytes(steps.to_ne_bytes()); - program.validate_jump(frame.pc, Addr((frame.pc.0 as i64 + res.advance) as u64))?; + let pc = state.get_pc(); + program.validate_jump(pc, Addr((pc.0 as i64 + res.advance) as u64))?; } BuiltinOp::SkipIf(cond, val) => { - if frame.status.test(*cond) { + if state.test_cond(*cond) { debug!("Skipping"); - let steps = frame.read(*val)?; + let steps = state.read(*val)?; res.advance = i64::from_ne_bytes(steps.to_ne_bytes()); - program.validate_jump(frame.pc, Addr((frame.pc.0 as i64 + res.advance) as u64))?; + let pc = state.get_pc(); + program.validate_jump(pc, Addr((pc.0 as i64 + res.advance) as u64))?; } } BuiltinOp::Move { dst, src } => { - frame.status.clear(); - let val = frame.read(*src)?; - frame.status.update(val); - frame.write(*dst, val)?; + state.clear_status(); + let val = state.read(*src)?; + state.update_status(val); + state.write(*dst, val)?; } BuiltinOp::StoreStatus { dst } => { - let packed = frame.status.store(); - frame.write(*dst, packed)?; + let packed = state.frame.status.store(); + state.write(*dst, packed)?; } BuiltinOp::LoadStatus { src } => { - let x = frame.read(*src)?; - frame.status.load(x); + let x = state.read(*src)?; + state.frame.status.load(x); } } diff --git a/crsn/src/runtime/frame.rs b/crsn/src/runtime/frame.rs index 9e9c7cf..c462ada 100644 --- a/crsn/src/runtime/frame.rs +++ b/crsn/src/runtime/frame.rs @@ -5,7 +5,7 @@ use crate::asm::data::literal::{Addr, Value}; use super::fault::Fault; -mod status; +pub(crate) mod status; pub const REG_COUNT: usize = 8; @@ -41,79 +41,4 @@ impl StackFrame { self.res[n] = vals[n]; } } - - pub fn read(&mut self, rd: Rd) -> Result { - match rd.d() { - SrcDisp::Immediate(v) => Ok(v), - SrcDisp::ImmediatePtr(_) => { - unimplemented!("Immediate ptr") - } - 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.res[rn as usize]); - Ok(self.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.arg[rn as usize]); - Ok(self.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.gen[rn as usize]); - Ok(self.gen[rn as usize]) - } - } - SrcDisp::RegisterPtr(_) => { - unimplemented!("Register ptr") - } - } - } - - pub fn write(&mut self, wr: Wr, val: Value) -> Result<(), Fault> { - trace!("WR {:?} := {}", wr, val); - - match wr.d() { - DstDisp::ImmediatePtr(_) => { - unimplemented!("Immediate ptr") - } - 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.gen[rn as usize] = val; - Ok(()) - } - } - DstDisp::RegisterPtr(_) => { - unimplemented!("Register ptr") - } - } - } } diff --git a/crsn/src/runtime/frame/status.rs b/crsn/src/runtime/frame/status.rs index 242a0c2..61c7e36 100644 --- a/crsn/src/runtime/frame/status.rs +++ b/crsn/src/runtime/frame/status.rs @@ -85,6 +85,43 @@ impl StatusFlags { Cond::NotCarry => !self.carry } } + + pub fn set(&mut self, cond: Cond) { + match cond { + Cond::Equal => { + self.equal = true; + }, + Cond::Zero => { + self.zero = true; + }, + Cond::Lower => { + self.lower = true; + }, + Cond::Greater => { + self.lower = false; + self.equal = false; + self.greater = true; + }, + Cond::Positive => { + self.positive = true; + }, + Cond::Negative => { + self.negative = true; + }, + Cond::Overflow => { + self.overflow = true; + }, + Cond::Invalid => { + self.invalid = true; + }, + Cond::Carry => { + self.carry = true; + }, + other => { + panic!("cannot set cond by {:?}", other); + } + } + } } impl Display for StatusFlags { diff --git a/crsn/src/runtime/run_thread.rs b/crsn/src/runtime/run_thread.rs index 69b4758..ba2297e 100644 --- a/crsn/src/runtime/run_thread.rs +++ b/crsn/src/runtime/run_thread.rs @@ -4,11 +4,13 @@ use std::sync::Arc; use std::thread::JoinHandle; use std::time::Duration; -use crate::asm::data::literal::Addr; +use crate::asm::data::literal::{Addr, Value}; use crate::asm::instr::op::EvalRes; -use crate::runtime::frame::{CallStack, StackFrame}; +use crate::runtime::frame::{CallStack, StackFrame, REG_COUNT, status::StatusFlags}; use crate::runtime::program::Program; use crate::runtime::fault::Fault; +use crate::asm::data::{Rd, SrcDisp, Register, Wr, DstDisp}; +use crate::runtime::run_thread::state::RunState; #[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)] pub struct ThreadToken(pub u32); @@ -27,25 +29,7 @@ pub struct ThreadInfo { pub cycle_time: Duration, } -pub struct RunState { - /// Active stack frame - pub frame: StackFrame, - /// Call stack - pub call_stack: CallStack, - /// Extension data - ext_data: HashMap>, -} - -impl RunState { - pub fn ext_mut(&mut self) -> &mut T { - if !self.ext_data.contains_key(&TypeId::of::()) { - self.ext_data.insert(TypeId::of::(), Box::new(T::default())); - } - - self.ext_data.get_mut(&TypeId::of::()).unwrap() - .downcast_mut().unwrap() - } -} +pub mod state; impl RunThread { pub fn new(id: ThreadToken, program: Arc, pc: Addr, args: &[u64]) -> Self { diff --git a/crsn/src/runtime/run_thread/state.rs b/crsn/src/runtime/run_thread/state.rs new file mode 100644 index 0000000..61750d7 --- /dev/null +++ b/crsn/src/runtime/run_thread/state.rs @@ -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>, +} + +impl RunState { + pub fn ext_mut(&mut self) -> &mut T { + if !self.ext_data.contains_key(&TypeId::of::()) { + self.ext_data.insert(TypeId::of::(), Box::new(T::default())); + } + + self.ext_data.get_mut(&TypeId::of::()).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 { + 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") + } + } + } +} diff --git a/crsn_arith/src/exec.rs b/crsn_arith/src/exec.rs index de7925e..d22c139 100644 --- a/crsn_arith/src/exec.rs +++ b/crsn_arith/src/exec.rs @@ -2,191 +2,189 @@ use std::ops::Rem; use num_traits::PrimInt; -use crsn::asm::instr::op::{OpTrait, EvalRes}; +use crsn::asm::instr::Cond; +use crsn::asm::instr::op::{EvalRes, OpTrait}; use crsn::runtime::fault::Fault; - - +use crsn::runtime::run_thread::{state::RunState, ThreadInfo}; use crate::defs::ArithOp; -use crsn::runtime::run_thread::{ThreadInfo, RunState}; impl OpTrait for ArithOp { - fn execute(&self, _ti : &ThreadInfo, state: &mut RunState) -> Result { - let frame = &mut state.frame; + fn execute(&self, _ti: &ThreadInfo, state: &mut RunState) -> Result { let eres = EvalRes::default(); match self { ArithOp::Test { a } => { - frame.status.clear(); - let res = frame.read(*a)?; - frame.status.update(res); + state.clear_status(); + let res = state.read(*a)?; + state.update_status(res); } ArithOp::Compare { a, b } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*b)?; - frame.status.equal = x == y; - frame.status.lower = x < y; - frame.status.greater = x > y; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*b)?; + state.set_flag(Cond::Equal, x == y); + state.set_flag(Cond::Lower, x < y); + state.set_flag(Cond::Greater, x > y); // Test flags are set when both arguments have the property if x == y { - frame.status.update(x); + state.update_status(x); } } ArithOp::Add { dst, a, b } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*b)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*b)?; let (res, ov) = if let Some(v) = x.checked_add(y) { (v, false) } else { (x.wrapping_add(y), true) }; - frame.status.update(res); - frame.status.overflow = ov; - frame.write(*dst, res)?; + state.update_status(res); + state.set_flag(Cond::Overflow, ov); + state.write(*dst, res)?; } ArithOp::Sub { dst, a, b } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*b)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*b)?; let (res, ov) = if let Some(v) = x.checked_sub(y) { (v, false) } else { (x.wrapping_sub(y), true) }; - frame.status.update(res); - frame.status.overflow = ov; - frame.write(*dst, res)?; + state.update_status(res); + state.set_flag(Cond::Overflow, ov); + state.write(*dst, res)?; } ArithOp::Mul { dst, a, b } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*b)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*b)?; let (res, ov) = if let Some(v) = x.checked_mul(y) { (v, false) } else { (x.wrapping_mul(y), true) }; - frame.status.update(res); - frame.status.overflow = ov; - frame.write(*dst, res)?; + state.update_status(res); + state.set_flag(Cond::Overflow, ov); + state.write(*dst, res)?; } ArithOp::Div { dst, rem, a, div } => { - frame.status.clear(); - let x = frame.read(*a)?; - let d = frame.read(*div)?; + state.clear_status(); + let x = state.read(*a)?; + let d = state.read(*div)?; if d == 0 { - frame.status.invalid = true; + state.set_flag(Cond::Invalid, true); } else { let (res, remainder, ov) = if let Some(v) = x.checked_div(d) { (v, x.rem(d), false) } else { (x.wrapping_div(d), x.wrapping_rem(d), true) }; - frame.status.update(res); - frame.status.overflow = ov; - frame.write(*dst, res)?; - frame.write(*rem, remainder)?; + state.update_status(res); + state.set_flag(Cond::Overflow, ov); + state.write(*dst, res)?; + state.write(*rem, remainder)?; } } ArithOp::Mod { dst, a, div } => { - frame.status.clear(); - let x = frame.read(*a)?; - let d = frame.read(*div)?; + state.clear_status(); + let x = state.read(*a)?; + let d = state.read(*div)?; if d == 0 { - frame.status.invalid = true; + state.set_flag(Cond::Invalid, true); } else { let (remainder, ov) = if let Some(v) = x.checked_rem(d) { (v, false) } else { (x.wrapping_rem(d), true) }; - frame.status.update(remainder); - frame.status.overflow = ov; - frame.write(*dst, remainder)?; + state.update_status(remainder); + state.set_flag(Cond::Overflow, ov); + state.write(*dst, remainder)?; } } ArithOp::And { dst, a, b } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*b)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*b)?; let res = x & y; - frame.status.update(res); - frame.write(*dst, res)?; + state.update_status(res); + state.write(*dst, res)?; } ArithOp::Or { dst, a, b } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*b)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*b)?; let res = x | y; - frame.status.update(res); - frame.write(*dst, res)?; + state.update_status(res); + state.write(*dst, res)?; } ArithOp::Xor { dst, a, b } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*b)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*b)?; let res = x ^ y; - frame.status.update(res); - frame.write(*dst, res)?; + state.update_status(res); + state.write(*dst, res)?; } ArithOp::Cpl { dst, a } => { - frame.status.clear(); - let x = frame.read(*a)?; + state.clear_status(); + let x = state.read(*a)?; let res = !x; - frame.status.update(res); - frame.write(*dst, res)?; + state.update_status(res); + state.write(*dst, res)?; } ArithOp::Rol { dst, a, n } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*n)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*n)?; if y > u32::MAX as u64 { - frame.status.invalid = true; + state.set_flag(Cond::Invalid, true); } else { let res = x.rotate_left(y as u32); - frame.status.update(res); - frame.write(*dst, res)?; + state.update_status(res); + state.write(*dst, res)?; } } ArithOp::Ror { dst, a, n } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*n)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*n)?; if y > u32::MAX as u64 { - frame.status.invalid = true; + state.set_flag(Cond::Invalid, true); } else { let res = x.rotate_right(y as u32); - frame.status.update(res); - frame.write(*dst, res)?; + state.update_status(res); + state.write(*dst, res)?; } } ArithOp::Lsl { dst, a, n } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*n)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*n)?; let res = x << y; - frame.status.update(res); - frame.write(*dst, res)?; + state.update_status(res); + state.write(*dst, res)?; } ArithOp::Lsr { dst, a, n } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*n)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*n)?; let res = x >> y; - frame.status.update(res); - frame.write(*dst, res)?; + state.update_status(res); + state.write(*dst, res)?; } ArithOp::Asr { dst, a, n } => { - frame.status.clear(); - let x = frame.read(*a)?; - let y = frame.read(*n)?; + state.clear_status(); + let x = state.read(*a)?; + let y = state.read(*n)?; if y > u32::MAX as u64 { - frame.status.invalid = true; + state.set_flag(Cond::Invalid, true); } else { let res = x.signed_shr(y as u32); - frame.status.update(res); - frame.write(*dst, res)?; + state.update_status(res); + state.write(*dst, res)?; } } } diff --git a/crsn_stacks/src/exec.rs b/crsn_stacks/src/exec.rs index 88da5f7..f44a2fa 100644 --- a/crsn_stacks/src/exec.rs +++ b/crsn_stacks/src/exec.rs @@ -1,14 +1,12 @@ use std::collections::VecDeque; - use crsn::asm::data::literal::Value; use crsn::asm::instr::op::{EvalRes, OpTrait}; use crsn::runtime::fault::Fault; - - -use crsn::runtime::run_thread::{RunState, ThreadInfo}; +use crsn::runtime::run_thread::{state::RunState, ThreadInfo}; use crate::defs::StackOp; +use crsn::asm::instr::Cond; struct Stacks { stacks: Vec>, @@ -27,34 +25,34 @@ impl OpTrait for StackOp { let eres = EvalRes::default(); match self { StackOp::Push { num, src } => { - state.frame.status.clear(); - let stack_num = state.frame.read(*num)?; - let val = state.frame.read(*src)?; + state.clear_status(); + let stack_num = state.read(*num)?; + let val = state.read(*src)?; if stack_num > 8 { - state.frame.status.invalid = true; + state.set_flag(Cond::Invalid, true); } else { let obj: &mut Stacks = state.ext_mut(); obj.stacks[stack_num as usize].push_back(val); } } StackOp::Pop { dst, num } => { - state.frame.status.clear(); - let stack_num = state.frame.read(*num)?; + state.clear_status(); + let stack_num = state.read(*num)?; if stack_num > 8 { - state.frame.status.invalid = true; + state.set_flag(Cond::Invalid, true); } else { let obj: &mut Stacks = state.ext_mut(); let val = obj.stacks[stack_num as usize].pop_back(); if obj.stacks[stack_num as usize].is_empty() { - state.frame.status.zero = true; + state.set_flag(Cond::Zero, true); } let val = match val { None => { - state.frame.status.overflow = true; + state.set_flag(Cond::Overflow, true); 0 } Some(val) => { @@ -62,7 +60,7 @@ impl OpTrait for StackOp { } }; - state.frame.write(*dst, val)?; + state.write(*dst, val)?; } // TODO diff --git a/launcher/src/main.rs b/launcher/src/main.rs index 2f23048..3ae587c 100644 --- a/launcher/src/main.rs +++ b/launcher/src/main.rs @@ -51,15 +51,15 @@ fn main() { (ld _ arg0) (fault) (:lbl) - (call fibo 5) + (call fac 5) (ld r0 res0) ) - (fibo + (fac (cmp arg0 2 (eq? (ret 2))) (ld r0 arg0) (dec r0) - (call fibo r0) + (call fac r0) (ld r0 arg0) (mul r0 res0) (ret r0)