forked from MightyPork/crsn
preparations for module data storage, remove broken tests (dyn trait can't implement PartialEq because ???)
This commit is contained in:
@@ -11,7 +11,7 @@ pub mod cond;
|
|||||||
mod flatten;
|
mod flatten;
|
||||||
|
|
||||||
/// A higher-level instruction
|
/// A higher-level instruction
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct Instr {
|
pub struct Instr {
|
||||||
pub op: OpWrapper,
|
pub op: OpWrapper,
|
||||||
pub branches: Option<Vec<(Cond, Vec<Instr>)>>,
|
pub branches: Option<Vec<(Cond, Vec<Instr>)>>,
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use dyn_clonable::*;
|
|
||||||
use sexp::Sexp;
|
|
||||||
|
|
||||||
use crate::asm::data::{
|
use crate::asm::data::{
|
||||||
literal::DebugMsg, literal::Label,
|
literal::DebugMsg, literal::Label,
|
||||||
literal::RoutineName,
|
literal::RoutineName,
|
||||||
@@ -11,13 +8,13 @@ use crate::asm::data::{
|
|||||||
};
|
};
|
||||||
use crate::asm::error::Error;
|
use crate::asm::error::Error;
|
||||||
use crate::asm::instr::Cond;
|
use crate::asm::instr::Cond;
|
||||||
|
use crate::asm::parse::arg_parser::ArgParser;
|
||||||
use crate::runtime::fault::Fault;
|
use crate::runtime::fault::Fault;
|
||||||
use crate::runtime::frame::{CallStack, StackFrame};
|
use crate::runtime::frame::{CallStack, StackFrame};
|
||||||
use crate::runtime::program::Program;
|
use crate::runtime::program::Program;
|
||||||
use crate::asm::parse::arg_parser::ArgParser;
|
|
||||||
|
|
||||||
/// A higher level simple opration
|
/// A higher level simple opration
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub enum OpWrapper {
|
pub enum OpWrapper {
|
||||||
/// Mark a jump target.
|
/// Mark a jump target.
|
||||||
Label(Label),
|
Label(Label),
|
||||||
@@ -30,7 +27,7 @@ pub enum OpWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A low level instruction
|
/// A low level instruction
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Op {
|
pub enum Op {
|
||||||
/// Do nothing
|
/// Do nothing
|
||||||
Nop,
|
Nop,
|
||||||
@@ -72,18 +69,16 @@ impl From<Op> for OpWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[clonable]
|
pub trait OpTrait: Debug + Send + Sync + 'static {
|
||||||
pub trait OpTrait: Clone + Debug + Send + 'static {
|
|
||||||
fn execute(&self, program: &Program, call_stack: &mut CallStack, frame: &mut StackFrame) -> Result<(), Fault>;
|
fn execute(&self, program: &Program, call_stack: &mut CallStack, frame: &mut StackFrame) -> Result<(), Fault>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ParseOpResult {
|
pub enum ParseOpResult {
|
||||||
Parsed(Box<dyn OpTrait>),
|
Parsed(Box<dyn OpTrait + Send>),
|
||||||
Unknown(ArgParser),
|
Unknown(ArgParser),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[clonable]
|
pub trait AsmModule: Debug + Send + 'static {
|
||||||
pub trait AsmModule: Clone + Debug + Send + 'static {
|
|
||||||
/// Get name of the module
|
/// Get name of the module
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
|
||||||
|
|||||||
@@ -12,326 +12,3 @@ pub fn assemble(source: &str, parsers: &[Box<dyn AsmModule>]) -> Result<Vec<Op>,
|
|||||||
let parsed = parse::parse(source, parsers)?;
|
let parsed = parse::parse(source, parsers)?;
|
||||||
Ok(lower(parsed)?)
|
Ok(lower(parsed)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use std::sync::atomic::AtomicU32;
|
|
||||||
|
|
||||||
use crate::asm::data::{DstDisp, Rd, Register, SrcDisp, Wr};
|
|
||||||
use crate::asm::data::literal::{Addr, Label};
|
|
||||||
use crate::asm::instr::{Flatten, OpWrapper, Instr, lower, Op};
|
|
||||||
use crate::asm::instr::Cond;
|
|
||||||
use crate::asm::parse::{parse, parse_instructions};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_empty() {
|
|
||||||
let parsed = parse("
|
|
||||||
()
|
|
||||||
").unwrap();
|
|
||||||
assert_eq!(Vec::<OpWrapper>::new(), parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_empty_routine() {
|
|
||||||
let parsed = parse("
|
|
||||||
(
|
|
||||||
(hello)
|
|
||||||
)
|
|
||||||
").unwrap();
|
|
||||||
assert_eq!(vec![
|
|
||||||
OpWrapper::Op(Op::Routine("hello".into())),
|
|
||||||
OpWrapper::Op(Op::Barrier(Some("Routine \"hello\" overrun".into())))
|
|
||||||
], parsed);
|
|
||||||
|
|
||||||
let parsed = parse("
|
|
||||||
(
|
|
||||||
(hello)
|
|
||||||
(world)
|
|
||||||
)
|
|
||||||
").unwrap();
|
|
||||||
assert_eq!(vec![
|
|
||||||
OpWrapper::Op(Op::Routine("hello".into())),
|
|
||||||
OpWrapper::Op(Op::Barrier(Some("Routine \"hello\" overrun".into()))),
|
|
||||||
OpWrapper::Op(Op::Routine("world".into())),
|
|
||||||
OpWrapper::Op(Op::Barrier(Some("Routine \"world\" overrun".into())))
|
|
||||||
], parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_data_formats() {
|
|
||||||
let parsed = parse("
|
|
||||||
(
|
|
||||||
(move
|
|
||||||
(mov r0 r1)
|
|
||||||
(mov r15 7)
|
|
||||||
(mov r15 0xabcd)
|
|
||||||
(mov r7 0b11110000)
|
|
||||||
(mov r7 arg1)
|
|
||||||
(mov r255 arg255)
|
|
||||||
(mov r7 res0)
|
|
||||||
(mov r7 res255)
|
|
||||||
(mov @r0 @r0) ; test in both Rd and Wr positions
|
|
||||||
(mov @r0 @arg0)
|
|
||||||
(mov @r0 @res0)
|
|
||||||
(mov @123456 @0x123456)
|
|
||||||
(mov @0b010101 @0b010101)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
").unwrap();
|
|
||||||
assert_eq!(vec![
|
|
||||||
OpWrapper::Op(Op::Routine("move".into())),
|
|
||||||
// (mov r0 r1)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(1))),
|
|
||||||
)),
|
|
||||||
// (mov r15 7)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(15))),
|
|
||||||
Rd::new(SrcDisp::Immediate(7)),
|
|
||||||
)),
|
|
||||||
// (mov r15 0xabcd)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(15))),
|
|
||||||
Rd::new(SrcDisp::Immediate(0xabcd)),
|
|
||||||
)),
|
|
||||||
// (mov r7 0b11110000)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(7))),
|
|
||||||
Rd::new(SrcDisp::Immediate(0b11110000)),
|
|
||||||
)),
|
|
||||||
// (mov r7 arg1)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(7))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Arg(1))),
|
|
||||||
)),
|
|
||||||
// (mov r255 arg255)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(255))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Arg(255))),
|
|
||||||
)),
|
|
||||||
// (mov r7 res0)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(7))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Res(0))),
|
|
||||||
)),
|
|
||||||
// (mov r7 res255)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(7))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Res(255))),
|
|
||||||
)),
|
|
||||||
// (mov @r0 @r0)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::RegisterPtr(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::RegisterPtr(Register::Gen(0))),
|
|
||||||
)),
|
|
||||||
// (mov @r0 @arg0)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::RegisterPtr(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::RegisterPtr(Register::Arg(0))),
|
|
||||||
)),
|
|
||||||
// (mov @r0 @res0)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::RegisterPtr(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::RegisterPtr(Register::Res(0))),
|
|
||||||
)),
|
|
||||||
// (mov @123456 @0x123456)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::ImmediatePtr(Addr(123456))),
|
|
||||||
Rd::new(SrcDisp::ImmediatePtr(Addr(0x123456))),
|
|
||||||
)),
|
|
||||||
// (mov @0b010101 @0b010101)
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::ImmediatePtr(Addr(0b010101))),
|
|
||||||
Rd::new(SrcDisp::ImmediatePtr(Addr(0b010101))),
|
|
||||||
)),
|
|
||||||
OpWrapper::Op(Op::Barrier(Some("Routine \"move\" overrun".into()))),
|
|
||||||
], parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_single_instr(src: &str) -> anyhow::Result<Instr> {
|
|
||||||
Ok(parse_instructions(vec![sexp::parse(src)?])?.remove(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_single_op(src: &str) -> anyhow::Result<Vec<OpWrapper>> {
|
|
||||||
let num = AtomicU32::new(0);
|
|
||||||
Ok(parse_single_instr(src)?.flatten(&num)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_single() {
|
|
||||||
let parsed = parse_single_op("(mov r0 r1)").unwrap();
|
|
||||||
assert_eq!(vec![
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(1))),
|
|
||||||
)),
|
|
||||||
], parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_branches_instr() {
|
|
||||||
let parsed = parse_single_instr("
|
|
||||||
(cmp r0 r1 (eq? (mov r0 r0) (mov r1 r2)) (>? (mov r0 r0) (mov r1 r1)))
|
|
||||||
").unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
Instr {
|
|
||||||
op: OpWrapper::Op(Op::Cmp(
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(1))),
|
|
||||||
)),
|
|
||||||
branches: Some(vec![
|
|
||||||
(
|
|
||||||
Cond::Equal,
|
|
||||||
vec![
|
|
||||||
Instr {
|
|
||||||
op: OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
)),
|
|
||||||
branches: None,
|
|
||||||
},
|
|
||||||
Instr {
|
|
||||||
op: OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(1))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(2))),
|
|
||||||
)),
|
|
||||||
branches: None,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Cond::Greater,
|
|
||||||
vec![
|
|
||||||
Instr {
|
|
||||||
op: OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
)),
|
|
||||||
branches: None,
|
|
||||||
},
|
|
||||||
Instr {
|
|
||||||
op: OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(1))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(1))),
|
|
||||||
)),
|
|
||||||
branches: None,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
}
|
|
||||||
, parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_branches_op() {
|
|
||||||
let parsed = parse_single_op("
|
|
||||||
(cmp r0 r1
|
|
||||||
(eq?
|
|
||||||
(mov r0 r0)
|
|
||||||
(mov r1 r2))
|
|
||||||
(>?
|
|
||||||
(mov r0 r0)
|
|
||||||
(mov r1 r1)))
|
|
||||||
").unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
vec![
|
|
||||||
OpWrapper::Op(Op::Cmp(
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(1))),
|
|
||||||
)),
|
|
||||||
OpWrapper::JumpIf(Cond::NotEqual, Label::Numbered(1)),
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
)),
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(1))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(2))),
|
|
||||||
)),
|
|
||||||
OpWrapper::Jump(Label::Numbered(0)),
|
|
||||||
OpWrapper::Label(Label::Numbered(1)),
|
|
||||||
OpWrapper::JumpIf(Cond::LowerOrEqual, Label::Numbered(0)),
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
)),
|
|
||||||
OpWrapper::Op(Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(1))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(1))),
|
|
||||||
)),
|
|
||||||
OpWrapper::Label(Label::Numbered(0)),
|
|
||||||
], parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_jumps_to_skips() {
|
|
||||||
let parsed = parse("(
|
|
||||||
(foo
|
|
||||||
(:foo)
|
|
||||||
(:unused)
|
|
||||||
(:whatever)
|
|
||||||
(mov r0 r0)
|
|
||||||
(j :foo)
|
|
||||||
(j :foo)
|
|
||||||
(mov r0 r0)
|
|
||||||
(mov r0 r0)
|
|
||||||
(j :whatever)
|
|
||||||
(j.if eq :whatever)
|
|
||||||
)
|
|
||||||
)").unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
vec![
|
|
||||||
Op::Routine("foo".into()).into(),
|
|
||||||
OpWrapper::Label(Label::Named("foo".to_string())),
|
|
||||||
OpWrapper::Label(Label::Named("unused".to_string())),
|
|
||||||
OpWrapper::Label(Label::Named("whatever".to_string())),
|
|
||||||
Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
).into(),
|
|
||||||
OpWrapper::Jump(Label::Named("foo".to_string())),
|
|
||||||
OpWrapper::Jump(Label::Named("foo".to_string())),
|
|
||||||
Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
).into(),
|
|
||||||
Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
).into(),
|
|
||||||
OpWrapper::Jump(Label::Named("whatever".to_string())),
|
|
||||||
OpWrapper::JumpIf(Cond::Equal, Label::Named("whatever".to_string())),
|
|
||||||
Op::Barrier(Some("Routine \"foo\" overrun".into())).into(),
|
|
||||||
], parsed);
|
|
||||||
|
|
||||||
// Labels are removed and jumps become skips
|
|
||||||
|
|
||||||
let cleaned = lower(parsed).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
vec![
|
|
||||||
Op::Routine("foo".into()),
|
|
||||||
Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
),
|
|
||||||
Op::Skip(Rd::new(SrcDisp::Immediate(-1))),
|
|
||||||
Op::Skip(Rd::new(SrcDisp::Immediate(-2))),
|
|
||||||
Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
),
|
|
||||||
Op::Mov(
|
|
||||||
Wr::new(DstDisp::Register(Register::Gen(0))),
|
|
||||||
Rd::new(SrcDisp::Register(Register::Gen(0))),
|
|
||||||
),
|
|
||||||
Op::Skip(Rd::new(SrcDisp::Immediate(-5))),
|
|
||||||
Op::SkipIf(Cond::Equal, Rd::new(SrcDisp::Immediate(-6))),
|
|
||||||
Op::Barrier(Some("Routine \"foo\" overrun".into())),
|
|
||||||
], cleaned);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
use sexp::Sexp;
|
|
||||||
|
|
||||||
use crate::asm::data::literal::{Label, RoutineName};
|
use crate::asm::data::literal::{Label, RoutineName};
|
||||||
use crate::asm::error::{AsmError, Error};
|
use crate::asm::error::Error;
|
||||||
use crate::asm::instr::{OpWrapper, Op};
|
use crate::asm::instr::{Op, OpWrapper};
|
||||||
use crate::asm::instr::cond::parse_cond;
|
use crate::asm::instr::cond::parse_cond;
|
||||||
use crate::asm::instr::op::{AsmModule, ParseOpResult};
|
use crate::asm::instr::op::{AsmModule, ParseOpResult};
|
||||||
use crate::asm::parse::parse_data::{parse_label, parse_rd, parse_wr};
|
|
||||||
use crate::asm::parse::sexp_expect::expect_string_atom;
|
|
||||||
use crate::asm::parse::arg_parser::ArgParser;
|
use crate::asm::parse::arg_parser::ArgParser;
|
||||||
|
use crate::asm::parse::parse_data::{parse_label, parse_rd};
|
||||||
|
use crate::asm::parse::sexp_expect::expect_string_atom;
|
||||||
|
|
||||||
pub fn parse_op(keyword: &str, far: bool, mut arg_tokens: ArgParser, parsers: &[Box<dyn AsmModule>]) -> Result<OpWrapper, Error> {
|
pub fn parse_op(keyword: &str, far: bool, mut arg_tokens: ArgParser, parsers: &[Box<dyn AsmModule>]) -> Result<OpWrapper, Error> {
|
||||||
|
|
||||||
Ok(match keyword {
|
Ok(match keyword {
|
||||||
"j" => {
|
"j" => {
|
||||||
let dest = parse_label(arg_tokens.next())?;
|
let dest = parse_label(arg_tokens.next())?;
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ pub enum Fault {
|
|||||||
|
|
||||||
#[error("Call stack underflow")]
|
#[error("Call stack underflow")]
|
||||||
CallStackUnderflow,
|
CallStackUnderflow,
|
||||||
|
|
||||||
|
#[error("Attempt to read undefined extension data store")]
|
||||||
|
ExtDataNotDefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::asm::data::literal::{Addr, Label, RoutineName};
|
use crate::asm::data::literal::{Addr, Label, RoutineName};
|
||||||
use crate::asm::instr::Op;
|
use crate::asm::instr::Op;
|
||||||
use crate::runtime::fault::Fault;
|
use crate::runtime::fault::Fault;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Program {
|
pub struct Program {
|
||||||
ops: Vec<Op>,
|
ops: Vec<Op>,
|
||||||
routines: HashMap<RoutineName, Addr>,
|
routines: HashMap<RoutineName, Addr>,
|
||||||
@@ -13,7 +15,7 @@ pub struct Program {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Program {
|
impl Program {
|
||||||
pub fn new(ops: Vec<Op>) -> Self {
|
pub fn new(ops: Vec<Op>) -> Arc<Self> {
|
||||||
let mut p = Self {
|
let mut p = Self {
|
||||||
ops,
|
ops,
|
||||||
routines: Default::default(),
|
routines: Default::default(),
|
||||||
@@ -21,7 +23,7 @@ impl Program {
|
|||||||
barriers: Default::default(),
|
barriers: Default::default(),
|
||||||
};
|
};
|
||||||
p.scan();
|
p.scan();
|
||||||
p
|
Arc::new(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find all the named things
|
/// Find all the named things
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::any::{Any, TypeId};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::thread::JoinHandle;
|
use std::thread::JoinHandle;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@@ -5,6 +7,8 @@ use crate::asm::data::literal::Addr;
|
|||||||
use crate::runtime::exec::EvalRes;
|
use crate::runtime::exec::EvalRes;
|
||||||
use crate::runtime::frame::{CallStack, StackFrame};
|
use crate::runtime::frame::{CallStack, StackFrame};
|
||||||
use crate::runtime::program::Program;
|
use crate::runtime::program::Program;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
|
||||||
const CYCLE_TIME: Duration = Duration::from_millis(0);
|
const CYCLE_TIME: Duration = Duration::from_millis(0);
|
||||||
//const CYCLE_TIME : Duration = Duration::from_millis(100);
|
//const CYCLE_TIME : Duration = Duration::from_millis(100);
|
||||||
@@ -20,11 +24,13 @@ pub struct RunThread {
|
|||||||
/// Call stack
|
/// Call stack
|
||||||
pub call_stack: CallStack,
|
pub call_stack: CallStack,
|
||||||
/// Program to run
|
/// Program to run
|
||||||
pub program: Program,
|
pub program: Arc<Program>,
|
||||||
|
/// Extension data
|
||||||
|
ext_data: HashMap<TypeId, Box<dyn Any + Send>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RunThread {
|
impl RunThread {
|
||||||
pub fn new(id: ThreadToken, program: Program, pc: Addr, args: &[u64]) -> Self {
|
pub fn new(id: ThreadToken, program: Arc<Program>, pc: Addr, args: &[u64]) -> Self {
|
||||||
let sf = StackFrame::new(pc, args);
|
let sf = StackFrame::new(pc, args);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@@ -32,6 +38,7 @@ impl RunThread {
|
|||||||
frame: sf,
|
frame: sf,
|
||||||
call_stack: vec![],
|
call_stack: vec![],
|
||||||
program,
|
program,
|
||||||
|
ext_data: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,5 +65,13 @@ impl RunThread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use crsn::asm::data::{Rd, Wr};
|
use crsn::asm::data::{Rd, Wr};
|
||||||
use crsn::asm::error::{AsmError, Error};
|
use crsn::asm::error::{Error};
|
||||||
use crsn::asm::instr::op::{AsmModule, OpTrait, ParseOpResult};
|
use crsn::asm::instr::op::{AsmModule, ParseOpResult};
|
||||||
use crsn::asm::parse::parse_data::{parse_rd, parse_wr};
|
|
||||||
use crsn::sexp::Sexp;
|
|
||||||
|
|
||||||
use crate::defs::ArithOp;
|
use crate::defs::ArithOp;
|
||||||
use crsn::asm::parse::arg_parser::ArgParser;
|
use crsn::asm::parse::arg_parser::ArgParser;
|
||||||
|
|||||||
Reference in New Issue
Block a user