@reg and @value reading and writing is now possible
This commit is contained in:
+29
-13
@@ -25,10 +25,12 @@ mod wr;
|
|||||||
pub enum DataDisp {
|
pub enum DataDisp {
|
||||||
/// Constant value
|
/// Constant value
|
||||||
Immediate(Value),
|
Immediate(Value),
|
||||||
|
/// Object pointer with immediate value
|
||||||
|
ImmObject(Value),
|
||||||
/// Register
|
/// Register
|
||||||
Register(Register),
|
Register(Register),
|
||||||
/// Object pointer
|
/// Object pointer in register
|
||||||
ObjectPtr(Register),
|
RegObject(Register),
|
||||||
/// Discard the written value
|
/// Discard the written value
|
||||||
Discard,
|
Discard,
|
||||||
}
|
}
|
||||||
@@ -42,9 +44,12 @@ impl Display for DataDisp {
|
|||||||
DataDisp::Register(r) => {
|
DataDisp::Register(r) => {
|
||||||
write!(f, "{}", r)
|
write!(f, "{}", r)
|
||||||
}
|
}
|
||||||
DataDisp::ObjectPtr(r) => {
|
DataDisp::RegObject(r) => {
|
||||||
write!(f, "@{}", r)
|
write!(f, "@{}", r)
|
||||||
}
|
}
|
||||||
|
DataDisp::ImmObject(r) => {
|
||||||
|
write!(f, "@{:#x}", r)
|
||||||
|
}
|
||||||
DataDisp::Discard => {
|
DataDisp::Discard => {
|
||||||
write!(f, "_")
|
write!(f, "_")
|
||||||
}
|
}
|
||||||
@@ -57,7 +62,8 @@ impl From<RdData> for DataDisp {
|
|||||||
match s {
|
match s {
|
||||||
RdData::Immediate(x) => DataDisp::Immediate(x),
|
RdData::Immediate(x) => DataDisp::Immediate(x),
|
||||||
RdData::Register(x) => DataDisp::Register(x),
|
RdData::Register(x) => DataDisp::Register(x),
|
||||||
RdData::ObjectPtr(x) => DataDisp::ObjectPtr(x),
|
RdData::RegObject(x) => DataDisp::RegObject(x),
|
||||||
|
RdData::ImmObject(x) => DataDisp::ImmObject(x),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +72,8 @@ impl From<WrData> for DataDisp {
|
|||||||
fn from(s: WrData) -> Self {
|
fn from(s: WrData) -> Self {
|
||||||
match s {
|
match s {
|
||||||
WrData::Register(x) => DataDisp::Register(x),
|
WrData::Register(x) => DataDisp::Register(x),
|
||||||
WrData::ObjectPtr(x) => DataDisp::ObjectPtr(x),
|
WrData::RegObject(x) => DataDisp::RegObject(x),
|
||||||
|
WrData::ImmObject(x) => DataDisp::ImmObject(x),
|
||||||
WrData::Discard => DataDisp::Discard,
|
WrData::Discard => DataDisp::Discard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,10 +84,12 @@ impl From<WrData> for DataDisp {
|
|||||||
pub enum RdData {
|
pub enum RdData {
|
||||||
/// Constant value
|
/// Constant value
|
||||||
Immediate(Value),
|
Immediate(Value),
|
||||||
|
/// Pointer into memory, address immediate
|
||||||
|
ImmObject(Value),
|
||||||
/// Register
|
/// Register
|
||||||
Register(Register),
|
Register(Register),
|
||||||
/// Pointer into memory, stored in a numbered register
|
/// Pointer into memory, stored in a numbered register
|
||||||
ObjectPtr(Register),
|
RegObject(Register),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for RdData {
|
impl Display for RdData {
|
||||||
@@ -94,7 +103,8 @@ impl Display for RdData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
RdData::Register(r) => write!(f, "{}", r),
|
RdData::Register(r) => write!(f, "{}", r),
|
||||||
RdData::ObjectPtr(r) => write!(f, "@{}", r)
|
RdData::RegObject(r) => write!(f, "@{}", r),
|
||||||
|
RdData::ImmObject(v) => write!(f, "@{:#x}", v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,8 +115,9 @@ impl TryFrom<DataDisp> for RdData {
|
|||||||
fn try_from(value: DataDisp) -> Result<Self, Self::Error> {
|
fn try_from(value: DataDisp) -> Result<Self, Self::Error> {
|
||||||
match value {
|
match value {
|
||||||
DataDisp::Immediate(x) => Ok(RdData::Immediate(x)),
|
DataDisp::Immediate(x) => Ok(RdData::Immediate(x)),
|
||||||
|
DataDisp::ImmObject(x) => Ok(RdData::ImmObject(x)),
|
||||||
DataDisp::Register(x) => Ok(RdData::Register(x)),
|
DataDisp::Register(x) => Ok(RdData::Register(x)),
|
||||||
DataDisp::ObjectPtr(x) => Ok(RdData::ObjectPtr(x)),
|
DataDisp::RegObject(x) => Ok(RdData::RegObject(x)),
|
||||||
DataDisp::Discard => Err(AsmError::DiscardAsValue),
|
DataDisp::Discard => Err(AsmError::DiscardAsValue),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,10 +126,12 @@ impl TryFrom<DataDisp> for RdData {
|
|||||||
/// Data destination disposition
|
/// Data destination disposition
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
pub enum WrData {
|
pub enum WrData {
|
||||||
|
/// Pointer into memory, address immediate
|
||||||
|
ImmObject(Value),
|
||||||
/// Register
|
/// Register
|
||||||
Register(Register),
|
Register(Register),
|
||||||
/// Pointer into memory, stored in a numbered register
|
/// Pointer into memory, stored in a numbered register
|
||||||
ObjectPtr(Register),
|
RegObject(Register),
|
||||||
/// Discard the written value
|
/// Discard the written value
|
||||||
Discard,
|
Discard,
|
||||||
}
|
}
|
||||||
@@ -128,7 +141,8 @@ impl Display for WrData {
|
|||||||
match self {
|
match self {
|
||||||
WrData::Discard => f.write_str("_"),
|
WrData::Discard => f.write_str("_"),
|
||||||
WrData::Register(r) => write!(f, "{}", r),
|
WrData::Register(r) => write!(f, "{}", r),
|
||||||
WrData::ObjectPtr(r) => write!(f, "@{}", r)
|
WrData::RegObject(r) => write!(f, "@{}", r),
|
||||||
|
WrData::ImmObject(v) => write!(f, "@{:#x}", v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,9 +150,10 @@ impl Display for WrData {
|
|||||||
impl From<WrData> for RdData {
|
impl From<WrData> for RdData {
|
||||||
fn from(s: WrData) -> Self {
|
fn from(s: WrData) -> Self {
|
||||||
match s {
|
match s {
|
||||||
|
WrData::ImmObject(x) => RdData::ImmObject(x),
|
||||||
WrData::Register(x) => RdData::Register(x),
|
WrData::Register(x) => RdData::Register(x),
|
||||||
WrData::ObjectPtr(x) => RdData::ObjectPtr(x),
|
WrData::RegObject(x) => RdData::RegObject(x),
|
||||||
WrData::Discard => RdData::Immediate(0),
|
WrData::Discard => RdData::Immediate(0), // this should not be allowed by the assembler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,8 +164,9 @@ impl TryFrom<DataDisp> for WrData {
|
|||||||
fn try_from(value: DataDisp) -> Result<Self, Self::Error> {
|
fn try_from(value: DataDisp) -> Result<Self, Self::Error> {
|
||||||
match value {
|
match value {
|
||||||
DataDisp::Immediate(_x) => Err(AsmError::ValueAsOutput),
|
DataDisp::Immediate(_x) => Err(AsmError::ValueAsOutput),
|
||||||
|
DataDisp::ImmObject(x) => Ok(WrData::ImmObject(x)),
|
||||||
DataDisp::Register(x) => Ok(WrData::Register(x)),
|
DataDisp::Register(x) => Ok(WrData::Register(x)),
|
||||||
DataDisp::ObjectPtr(x) => Ok(WrData::ObjectPtr(x)),
|
DataDisp::RegObject(x) => Ok(WrData::RegObject(x)),
|
||||||
DataDisp::Discard => Ok(WrData::Discard),
|
DataDisp::Discard => Ok(WrData::Discard),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ impl<'a> TokenParser<'a> {
|
|||||||
/// Get the next entry as read location
|
/// Get the next entry as read location
|
||||||
pub fn next_rdobj(&mut self) -> Result<RdObj, CrsnError> {
|
pub fn next_rdobj(&mut self) -> Result<RdObj, CrsnError> {
|
||||||
match parse_rd(self.next_or_err()?, self.pcx)? {
|
match parse_rd(self.next_or_err()?, self.pcx)? {
|
||||||
Rd(RdData::ObjectPtr(reg), Mask::FULL) => {
|
Rd(RdData::RegObject(reg), Mask::FULL) => {
|
||||||
Ok(RdObj::new(reg))
|
Ok(RdObj::new(reg))
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
|
|||||||
@@ -96,14 +96,14 @@ pub fn parse_data_disp(tok: Sexp, pcx: &ParserContext) -> Result<DataDisp, CrsnE
|
|||||||
if let Some(reference) = s.strip_prefix('@') {
|
if let Some(reference) = s.strip_prefix('@') {
|
||||||
let pstate = pcx.state.borrow();
|
let pstate = pcx.state.borrow();
|
||||||
if let Some(reg) = pstate.reg_aliases.get(reference) {
|
if let Some(reg) = pstate.reg_aliases.get(reference) {
|
||||||
Ok(DataDisp::ObjectPtr(*reg))
|
Ok(DataDisp::RegObject(*reg))
|
||||||
} else {
|
} else {
|
||||||
let reg = reg::parse_reg(reference, &pos)?;
|
let reg = reg::parse_reg(reference, &pos)?;
|
||||||
|
|
||||||
if pstate.reg_aliases.values().find(|v| **v == reg).is_some() {
|
if pstate.reg_aliases.values().find(|v| **v == reg).is_some() {
|
||||||
Err(CrsnError::Parse(format!("Sym exists for register {}, direct access denied. Unsym it if needed.", reg).into(), pos))
|
Err(CrsnError::Parse(format!("Sym exists for register {}, direct access denied. Unsym it if needed.", reg).into(), pos))
|
||||||
} else {
|
} else {
|
||||||
Ok(DataDisp::ObjectPtr(reg))
|
Ok(DataDisp::RegObject(reg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if s.starts_with(|c: char| c.is_ascii_digit() || c == '-') {
|
} else if s.starts_with(|c: char| c.is_ascii_digit() || c == '-') {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use crate::asm::instr::Flatten;
|
|||||||
use crate::asm::instr::op::OpKind;
|
use crate::asm::instr::op::OpKind;
|
||||||
use crate::asm::parse::arg_parser::TokenParser;
|
use crate::asm::parse::arg_parser::TokenParser;
|
||||||
use crate::runtime::fault::Fault;
|
use crate::runtime::fault::Fault;
|
||||||
use crate::runtime::run_thread::state::RunState;
|
use crate::runtime::run_thread::state::{RunState};
|
||||||
use crate::runtime::run_thread::ThreadInfo;
|
use crate::runtime::run_thread::ThreadInfo;
|
||||||
|
|
||||||
mod eval_res;
|
mod eval_res;
|
||||||
@@ -72,7 +72,7 @@ pub trait CrsnExtension: Debug + Send + Sync + 'static {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run-time method called to read an object (using the object handle syntax)
|
/// Run-time method called to read an object (using the object handle syntax)
|
||||||
fn read_obj(&self, ti: &ThreadInfo, state: &mut RunState, handle: Value, _mask: Mask)
|
fn read_obj(&self, state: &mut RunState, handle: Value, _mask: Mask)
|
||||||
-> Result<Option<Value>, Fault>
|
-> Result<Option<Value>, Fault>
|
||||||
{
|
{
|
||||||
// Default impl - we do not support reading this object
|
// Default impl - we do not support reading this object
|
||||||
@@ -80,8 +80,7 @@ pub trait CrsnExtension: Debug + Send + Sync + 'static {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run-time method called to write an object (using the object handle syntax)
|
/// Run-time method called to write an object (using the object handle syntax)
|
||||||
fn write_obj(&self, ti: &ThreadInfo, state: &mut RunState, handle: Value, mask: Mask)
|
fn write_obj(&self, state: &mut RunState, handle: Value, _mask: Mask, value: Value) -> Result<Option<()>, Fault>
|
||||||
-> Result<Option<()>, Fault>
|
|
||||||
{
|
{
|
||||||
// Default impl - we do not support writing this object
|
// Default impl - we do not support writing this object
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use crate::runtime::program::Program;
|
|||||||
pub struct ThreadToken(pub u32);
|
pub struct ThreadToken(pub u32);
|
||||||
|
|
||||||
pub struct RunThread {
|
pub struct RunThread {
|
||||||
pub(crate) info: ThreadInfo,
|
pub(crate) info: Arc<ThreadInfo>,
|
||||||
pub(crate) state: RunState,
|
pub(crate) state: RunState,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,25 +27,38 @@ pub fn new_uniq() -> Arc<AtomicU64> {
|
|||||||
Arc::new(AtomicU64::new(info::UNIQ_BASE))
|
Arc::new(AtomicU64::new(info::UNIQ_BASE))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ThreadParams<'a> {
|
||||||
|
pub id: ThreadToken,
|
||||||
|
pub uniq: Option<Arc<AtomicU64>>,
|
||||||
|
pub program: Arc<Program>,
|
||||||
|
pub pc: Addr,
|
||||||
|
pub cycle_time: Duration,
|
||||||
|
pub args: &'a [u64],
|
||||||
|
}
|
||||||
|
|
||||||
impl RunThread {
|
impl RunThread {
|
||||||
pub fn new(id: ThreadToken, uniq: Option<Arc<AtomicU64>>, program: Arc<Program>, pc: Addr, args: &[u64]) -> Self {
|
pub fn new(params: ThreadParams) -> Self {
|
||||||
Self {
|
let extensions = params.program.extensions.clone();
|
||||||
info: ThreadInfo {
|
|
||||||
id,
|
let ti = Arc::new(ThreadInfo {
|
||||||
uniq: uniq.unwrap_or_else(new_uniq),
|
id: params.id,
|
||||||
program,
|
uniq: params.uniq.unwrap_or_else(new_uniq),
|
||||||
cycle_time: Duration::default(),
|
program: params.program,
|
||||||
},
|
cycle_time: params.cycle_time,
|
||||||
state: RunState {
|
extensions,
|
||||||
frame: StackFrame::new(pc, args),
|
});
|
||||||
|
|
||||||
|
let rs = RunState {
|
||||||
|
thread_info: ti.clone(),
|
||||||
|
frame: StackFrame::new(params.pc, params.args),
|
||||||
call_stack: vec![],
|
call_stack: vec![],
|
||||||
ext_data: Default::default(),
|
ext_data: Default::default(),
|
||||||
},
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_speed(&mut self, cycle_time: Duration) {
|
Self {
|
||||||
self.info.cycle_time = cycle_time;
|
info: ti,
|
||||||
|
state: rs,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawn as a thread
|
/// Spawn as a thread
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use std::time::Duration;
|
|||||||
use crate::asm::data::literal::Value;
|
use crate::asm::data::literal::Value;
|
||||||
use crate::runtime::program::Program;
|
use crate::runtime::program::Program;
|
||||||
use crate::runtime::run_thread::ThreadToken;
|
use crate::runtime::run_thread::ThreadToken;
|
||||||
|
use crate::module::CrsnExtension;
|
||||||
|
|
||||||
pub struct ThreadInfo {
|
pub struct ThreadInfo {
|
||||||
/// Thread ID
|
/// Thread ID
|
||||||
@@ -15,12 +16,14 @@ pub struct ThreadInfo {
|
|||||||
pub program: Arc<Program>,
|
pub program: Arc<Program>,
|
||||||
/// Program to run
|
/// Program to run
|
||||||
pub(crate) cycle_time: Duration,
|
pub(crate) cycle_time: Duration,
|
||||||
|
/// Extensions
|
||||||
|
pub extensions: Arc<Vec<Box<dyn CrsnExtension>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const UNIQ_BASE: u64 = 0x6372_736e_0000_0000;
|
pub const UNIQ_BASE: u64 = 0x6372_736e_0000_0000;
|
||||||
|
|
||||||
impl ThreadInfo {
|
impl ThreadInfo {
|
||||||
pub fn uniq(&self) -> Value {
|
pub fn unique_value(&self) -> Value {
|
||||||
self.uniq.fetch_add(1, Ordering::Relaxed)
|
self.uniq.fetch_add(1, Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,51 @@
|
|||||||
use std::any::{Any, TypeId};
|
use std::any::{Any, TypeId};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::asm::data::{Rd, RdData, RdObj, Register, Wr, WrData};
|
use crate::asm::data::{Rd, RdData, RdObj, Register, Wr, WrData, Mask};
|
||||||
use crate::asm::data::literal::{Addr, Value};
|
use crate::asm::data::literal::{Addr, Value};
|
||||||
use crate::asm::instr::Cond;
|
use crate::asm::instr::Cond;
|
||||||
use crate::runtime::fault::Fault;
|
use crate::runtime::fault::Fault;
|
||||||
use crate::runtime::frame::{CallStack, REG_COUNT, StackFrame};
|
use crate::runtime::frame::{CallStack, REG_COUNT, StackFrame};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use crate::runtime::run_thread::ThreadInfo;
|
||||||
|
|
||||||
pub struct RunState {
|
pub struct RunState {
|
||||||
|
pub thread_info: Arc<ThreadInfo>,
|
||||||
/// Active stack frame
|
/// Active stack frame
|
||||||
pub frame: StackFrame,
|
pub frame: StackFrame,
|
||||||
/// Call stack
|
/// Call stack
|
||||||
pub call_stack: CallStack,
|
pub call_stack: CallStack,
|
||||||
/// Extension data
|
/// Extension data
|
||||||
pub ext_data: HashMap<TypeId, Box<dyn Any + Send>>,
|
pub ext_data: ExtensionDataStore,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug,Default)]
|
||||||
|
pub struct ExtensionDataStore {
|
||||||
|
store: HashMap<TypeId, Box<dyn Any + Send>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtensionDataStore {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get an extension's persistent data object for mutation.
|
||||||
|
/// It will be created using Default if not present before.
|
||||||
|
pub fn get_mut<T: Send + Default + 'static>(&mut self) -> &mut T {
|
||||||
|
if !self.store.contains_key(&TypeId::of::<T>()) {
|
||||||
|
self.store.insert(TypeId::of::<T>(), Box::new(T::default()));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.store.get_mut(&TypeId::of::<T>()).unwrap()
|
||||||
|
.downcast_mut().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RunState {
|
impl RunState {
|
||||||
/// Get an extension's persistent data object for mutation.
|
/// Get an extension's persistent data object for mutation.
|
||||||
/// It will be created using Default if not present before.
|
/// It will be created using Default if not present before.
|
||||||
pub fn ext_mut<T: Send + Default + 'static>(&mut self) -> &mut T {
|
pub fn ext_mut<T: Send + Default + 'static>(&mut self) -> &mut T {
|
||||||
if !self.ext_data.contains_key(&TypeId::of::<T>()) {
|
self.ext_data.get_mut()
|
||||||
self.ext_data.insert(TypeId::of::<T>(), Box::new(T::default()));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.ext_data.get_mut(&TypeId::of::<T>()).unwrap()
|
|
||||||
.downcast_mut().unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a status flag. Only supports simple, positive conds (i.e. not GreaterOrEqual)
|
/// Set a status flag. Only supports simple, positive conds (i.e. not GreaterOrEqual)
|
||||||
@@ -95,12 +115,46 @@ impl RunState {
|
|||||||
Ok(self.frame.gen[rn as usize])
|
Ok(self.frame.gen[rn as usize])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RdData::ObjectPtr(_) => {
|
RdData::RegObject(register) => {
|
||||||
unimplemented!("Read object ptr")
|
let reference = self.read(Rd::new(RdData::Register(register)))?;
|
||||||
|
self.read_object(reference, rd.mask())
|
||||||
|
}
|
||||||
|
RdData::ImmObject(reference) => {
|
||||||
|
self.read_object(reference, rd.mask())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_object(&mut self, reference: Value, mask: Mask) -> Result<Value, Fault> {
|
||||||
|
// This is a shitty dirty hack to allow iterating over the extensions while passing a mutable reference
|
||||||
|
// to self to the reading methods. Since the extensions array is in an Arc, it can't be mutated internally
|
||||||
|
// anyway, and we know it will still live after the method returns - unless someone does something incredibly stupid.
|
||||||
|
let ti: &ThreadInfo = unsafe { &*(self.thread_info.as_ref() as *const _) }; // If this fails, just clone the arc for the loop...
|
||||||
|
|
||||||
|
for ext in ti.extensions.iter() {
|
||||||
|
if let Some(value) = ext.read_obj(self, reference, mask)? {
|
||||||
|
return Ok(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(Fault::ObjectNotExist(reference))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_object(&mut self, reference: Value, mask: Mask, value: Value) -> Result<(), Fault> {
|
||||||
|
// This is a shitty dirty hack to allow iterating over the extensions while passing a mutable reference
|
||||||
|
// to self to the reading methods. Since the extensions array is in an Arc, it can't be mutated internally
|
||||||
|
// anyway, and we know it will still live after the method returns - unless someone does something incredibly stupid.
|
||||||
|
let ti: &ThreadInfo = unsafe { &*(self.thread_info.as_ref() as *const _) }; // If this fails, just clone the arc for the loop...
|
||||||
|
|
||||||
|
for ext in ti.extensions.iter() {
|
||||||
|
if ext.write_obj(self, reference, mask, value)?.is_some() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(Fault::ObjectNotExist(reference))
|
||||||
|
}
|
||||||
|
|
||||||
/// Write a value to a `Wr` location
|
/// Write a value to a `Wr` location
|
||||||
pub fn write(&mut self, wr: Wr, val: Value) -> Result<(), Fault> {
|
pub fn write(&mut self, wr: Wr, val: Value) -> Result<(), Fault> {
|
||||||
trace!("WR {:?} := {}", wr, val);
|
trace!("WR {:?} := {}", wr, val);
|
||||||
@@ -132,8 +186,12 @@ impl RunState {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WrData::ObjectPtr(_) => {
|
WrData::RegObject(register) => {
|
||||||
unimplemented!("Write object ptr")
|
let reference = self.read(Rd::new(RdData::Register(register)))?;
|
||||||
|
self.write_object(reference, wr.mask(), val)
|
||||||
|
}
|
||||||
|
WrData::ImmObject(reference) => {
|
||||||
|
self.write_object(reference, wr.mask(), val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ impl OpTrait for StackOp {
|
|||||||
let eres = EvalRes::default();
|
let eres = EvalRes::default();
|
||||||
match self {
|
match self {
|
||||||
StackOp::NewStack { dst } => {
|
StackOp::NewStack { dst } => {
|
||||||
let id = info.uniq();
|
let id = info.unique_value();
|
||||||
let stacks: &mut Stacks = state.ext_mut();
|
let stacks: &mut Stacks = state.ext_mut();
|
||||||
stacks.store.insert(id, VecDeque::new());
|
stacks.store.insert(id, VecDeque::new());
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crsn::asm::data::literal::Addr;
|
use crsn::asm::data::literal::Addr;
|
||||||
use crsn::module::OpTrait;
|
use crsn::module::OpTrait;
|
||||||
use crsn::runtime::run_thread::{RunThread, ThreadToken};
|
use crsn::runtime::run_thread::{RunThread, ThreadToken, ThreadParams};
|
||||||
use crsn_arith::ArithOps;
|
use crsn_arith::ArithOps;
|
||||||
use crsn_screen::ScreenOps;
|
use crsn_screen::ScreenOps;
|
||||||
use crsn_stacks::StackOps;
|
use crsn_stacks::StackOps;
|
||||||
@@ -145,8 +145,14 @@ fn main() -> anyhow::Result<()> {
|
|||||||
info!("Start runtime");
|
info!("Start runtime");
|
||||||
|
|
||||||
let args = &[];
|
let args = &[];
|
||||||
let mut thread = RunThread::new(ThreadToken(0), None, parsed.clone(), Addr(0), args);
|
let thread = RunThread::new(ThreadParams {
|
||||||
thread.set_speed(config.cycle_time);
|
id: ThreadToken(0),
|
||||||
|
uniq: None,
|
||||||
|
program: parsed,
|
||||||
|
pc: Addr(0),
|
||||||
|
cycle_time: config.cycle_time,
|
||||||
|
args
|
||||||
|
});
|
||||||
|
|
||||||
// run without spawning, so it is on the main thread - required by some extensions
|
// run without spawning, so it is on the main thread - required by some extensions
|
||||||
thread.run();
|
thread.run();
|
||||||
|
|||||||
Reference in New Issue
Block a user