pull/21/head
Ondřej Hruška 4 years ago
parent f493cc102a
commit 8f076e195a
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 94
      Cargo.lock
  2. 10
      asm/src/data/literal.rs
  3. 4
      asm/src/data/mask.rs
  4. 27
      asm/src/data/mod.rs
  5. 9
      asm/src/data/reg.rs
  6. 15
      asm/src/error.rs
  7. 9
      asm/src/instr/flatten.rs
  8. 13
      asm/src/instr/mod.rs
  9. 14
      asm/src/instr/op.rs
  10. 31
      asm/src/lib.rs
  11. 12
      asm/src/parse/mod.rs
  12. 5
      asm/src/parse/parse_cond.rs
  13. 28
      asm/src/parse/parse_data.rs
  14. 10
      asm/src/parse/parse_instr.rs
  15. 13
      asm/src/parse/parse_op.rs
  16. 7
      asm/src/parse/parse_routines.rs
  17. 3
      asm/src/parse/sexp_expect.rs
  18. 5
      asm/src/patches/mod.rs
  19. 39
      crsn/src/main.rs
  20. 13
      runtime/src/exec/mod.rs
  21. 9
      runtime/src/fault.rs
  22. 10
      runtime/src/frame.rs
  23. 5
      runtime/src/frame/status.rs
  24. 3
      runtime/src/lib.rs
  25. 7
      runtime/src/mlock.rs
  26. 8
      runtime/src/program.rs
  27. 11
      runtime/src/run_thread.rs
  28. 4
      runtime/src/span.rs

94
Cargo.lock generated

@ -10,9 +10,9 @@ checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b"
name = "asm" name = "asm"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"sexp", "sexp",
"thiserror", "thiserror",
] ]
[[package]] [[package]]
@ -21,9 +21,9 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi",
"libc", "libc",
"winapi", "winapi",
] ]
[[package]] [[package]]
@ -44,9 +44,9 @@ version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
dependencies = [ dependencies = [
"num-integer", "num-integer",
"num-traits", "num-traits",
"time", "time",
] ]
[[package]] [[package]]
@ -55,21 +55,21 @@ version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
dependencies = [ dependencies = [
"atty", "atty",
"lazy_static", "lazy_static",
"winapi", "winapi",
] ]
[[package]] [[package]]
name = "crsn" name = "crsn"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"asm", "asm",
"log", "log",
"runtime", "runtime",
"simple_logger", "simple_logger",
"thiserror", "thiserror",
] ]
[[package]] [[package]]
@ -78,7 +78,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151" checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]] [[package]]
@ -99,7 +99,7 @@ version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]] [[package]]
@ -108,8 +108,8 @@ version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"num-traits", "num-traits",
] ]
[[package]] [[package]]
@ -118,7 +118,7 @@ version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
[[package]] [[package]]
@ -127,7 +127,7 @@ version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]] [[package]]
@ -136,18 +136,18 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]] [[package]]
name = "runtime" name = "runtime"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"asm", "asm",
"log", "log",
"num-traits", "num-traits",
"thiserror", "thiserror",
] ]
[[package]] [[package]]
@ -162,11 +162,11 @@ version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13a53ed2efd04911c8280f2da7bf9abd350c931b86bc7f9f2386fbafbf525ff9" checksum = "13a53ed2efd04911c8280f2da7bf9abd350c931b86bc7f9f2386fbafbf525ff9"
dependencies = [ dependencies = [
"atty", "atty",
"chrono", "chrono",
"colored", "colored",
"log", "log",
"winapi", "winapi",
] ]
[[package]] [[package]]
@ -175,9 +175,9 @@ version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-xid", "unicode-xid",
] ]
[[package]] [[package]]
@ -186,7 +186,7 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
@ -195,9 +195,9 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
] ]
[[package]] [[package]]
@ -206,9 +206,9 @@ version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [ dependencies = [
"libc", "libc",
"wasi", "wasi",
"winapi", "winapi",
] ]
[[package]] [[package]]
@ -229,8 +229,8 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [ dependencies = [
"winapi-i686-pc-windows-gnu", "winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu",
] ]
[[package]] [[package]]

@ -1,21 +1,21 @@
use std::borrow::Cow;
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
use std::sync::atomic::AtomicU32; use std::sync::atomic::AtomicU32;
use std::borrow::Cow;
pub type DebugMsg = Cow<'static, str>; pub type DebugMsg = Cow<'static, str>;
/// Immediate value /// Immediate value
pub type Value = u64; pub type Value = u64;
pub fn is_positive(val : Value) -> bool { pub fn is_positive(val: Value) -> bool {
0 == (val & 0x8000_0000_0000_0000) 0 == (val & 0x8000_0000_0000_0000)
} }
pub fn is_negative(val : Value) -> bool { pub fn is_negative(val: Value) -> bool {
0 != (val & 0x8000_0000_0000_0000) 0 != (val & 0x8000_0000_0000_0000)
} }
pub fn as_signed(val : Value) -> i64 { pub fn as_signed(val: Value) -> i64 {
i64::from_ne_bytes(val.to_ne_bytes()) i64::from_ne_bytes(val.to_ne_bytes())
} }
@ -70,7 +70,7 @@ pub enum Label {
impl Label { impl Label {
/// Generate a unique numbered label from a counter /// Generate a unique numbered label from a counter
pub fn unique(counter : &AtomicU32) -> Self { pub fn unique(counter: &AtomicU32) -> Self {
Label::Numbered(counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed)) Label::Numbered(counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed))
} }
} }

@ -15,7 +15,7 @@ impl Default for Mask {
fn default() -> Self { fn default() -> Self {
Mask { Mask {
len: 64, len: 64,
offset: 0 offset: 0,
} }
} }
} }
@ -44,7 +44,7 @@ impl Mask {
// create the invalid mask to display it in the error // create the invalid mask to display it in the error
return Err(AsmError::BadMask(Mask { return Err(AsmError::BadMask(Mask {
len, len,
offset offset,
})); }));
} }

@ -1,20 +1,19 @@
use super::error::AsmError; use std::convert::TryFrom;
use std::fmt::{Debug, Display, Formatter};
use std::fmt;
use literal::Addr;
pub use mask::Mask;
pub use reg::Register;
use crate::data::literal::{as_signed, Value};
use super::error::AsmError;
pub mod literal; pub mod literal;
pub mod reg; pub mod reg;
pub mod mask; pub mod mask;
pub use reg::Register;
pub use mask::Mask;
use literal::Addr;
use std::convert::TryFrom;
use crate::data::literal::{Value, as_signed};
use std::fmt::{Debug, Formatter, Display};
use std::fmt;
/// Data source disposition /// Data source disposition
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum DataDisp { pub enum DataDisp {
@ -154,7 +153,7 @@ impl Rd {
self.1 self.1
} }
pub fn immediate(val : Value) -> Rd { pub fn immediate(val: Value) -> Rd {
Rd(SrcDisp::Immediate(val), Mask::default()) Rd(SrcDisp::Immediate(val), Mask::default())
} }
} }
@ -185,7 +184,7 @@ impl Wr {
impl Debug for Rd { impl Debug for Rd {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "Rd(")?; write!(f, "Rd(")?;
let disp : DataDisp = self.0.into(); let disp: DataDisp = self.0.into();
write!(f, "{}", disp)?; write!(f, "{}", disp)?;
if !self.mask().is_default() { if !self.mask().is_default() {
write!(f, ",{:?}", self.mask())?; write!(f, ",{:?}", self.mask())?;
@ -197,7 +196,7 @@ impl Debug for Rd {
impl Debug for Wr { impl Debug for Wr {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "Wr(")?; write!(f, "Wr(")?;
let disp : DataDisp = self.0.into(); let disp: DataDisp = self.0.into();
write!(f, "{}", disp)?; write!(f, "{}", disp)?;
if !self.mask().is_default() { if !self.mask().is_default() {
write!(f, ",{:?}", self.mask())?; write!(f, ",{:?}", self.mask())?;

@ -1,4 +1,5 @@
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
use crate::error::Error; use crate::error::Error;
/// Register name /// Register name
@ -22,15 +23,15 @@ impl Display for Register {
} }
} }
pub fn parse_reg(name : &str) -> anyhow::Result<Register> { pub fn parse_reg(name: &str) -> anyhow::Result<Register> {
if let Some(rn) = name.strip_prefix("arg") { if let Some(rn) = name.strip_prefix("arg") {
let val : u8 = rn.parse()?; let val: u8 = rn.parse()?;
Ok(Register::Arg(val)) Ok(Register::Arg(val))
} else if let Some(rn) = name.strip_prefix("res") { } else if let Some(rn) = name.strip_prefix("res") {
let val : u8 = rn.parse()?; let val: u8 = rn.parse()?;
Ok(Register::Res(val)) Ok(Register::Res(val))
} else if let Some(rn) = name.strip_prefix("r") { } else if let Some(rn) = name.strip_prefix("r") {
let val : u8 = rn.parse()?; let val: u8 = rn.parse()?;
Ok(Register::Gen(val)) Ok(Register::Gen(val))
} else { } else {
Err(Error::Parse(format!("Bad reg name: {}", name).into()))? Err(Error::Parse(format!("Bad reg name: {}", name).into()))?

@ -1,12 +1,13 @@
use crate::instr::{Cond};
use crate::data::{Mask, Register};
use thiserror::Error;
use std::borrow::Cow; use std::borrow::Cow;
use crate::data::literal::Label;
use thiserror::Error;
use crate::data::{Mask, Register};
use crate::data::literal::Label;
use crate::instr::Cond;
/// csn_asm unified error type /// csn_asm unified error type
#[derive(Error,Debug)] #[derive(Error, Debug)]
pub enum Error { pub enum Error {
#[error("S-expression syntax error: {0:?}")] #[error("S-expression syntax error: {0:?}")]
PreParse(#[from] Box<sexp::Error>), PreParse(#[from] Box<sexp::Error>),
@ -23,7 +24,7 @@ pub enum Error {
} }
/// Error from the assembler stage (after parsing S-expressions and basic validation) /// Error from the assembler stage (after parsing S-expressions and basic validation)
#[derive(Error,Debug)] #[derive(Error, Debug)]
pub enum AsmError { pub enum AsmError {
#[error("Unknown instruction")] #[error("Unknown instruction")]
UnknownInstruction, UnknownInstruction,
@ -44,7 +45,7 @@ pub enum AsmError {
} }
/// Architectural error - the code is syntactically OK, but cannot run /// Architectural error - the code is syntactically OK, but cannot run
#[derive(Error,Debug)] #[derive(Error, Debug)]
pub enum ArchError { pub enum ArchError {
#[error("Register {0} does not exist")] #[error("Register {0} does not exist")]
RegisterNotExist(Register), RegisterNotExist(Register),

@ -1,9 +1,10 @@
use std::sync::atomic::AtomicU32;
use crate::instr::{HLOp, Instr, Cond, Routine, Op};
use crate::error::{Error, AsmError};
use std::collections::HashMap; use std::collections::HashMap;
use crate::data::literal::{Label, Value}; use std::sync::atomic::AtomicU32;
use crate::data::{Rd, SrcDisp}; use crate::data::{Rd, SrcDisp};
use crate::data::literal::{Label, Value};
use crate::error::{AsmError, Error};
use crate::instr::{Cond, HLOp, Instr, Op, Routine};
/// A trait for something that can turn into multiple instructions /// A trait for something that can turn into multiple instructions
pub trait Flatten { pub trait Flatten {

@ -1,17 +1,14 @@
mod op; pub use cond::Cond;
mod cond;
mod flatten;
pub use flatten::Flatten; pub use flatten::Flatten;
pub use flatten::lower; pub use flatten::lower;
pub use op::HLOp; pub use op::HLOp;
pub use op::Op; pub use op::Op;
pub use cond::Cond;
use crate::data::literal::{RoutineName};
use crate::data::literal::RoutineName;
mod op;
mod cond;
mod flatten;
/// A higher-level instruction /// A higher-level instruction
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]

@ -1,10 +1,10 @@
use crate::data::{ use crate::data::{
Wr, Rd, literal::DebugMsg, literal::Label,
literal::Label,
literal::RoutineName, literal::RoutineName,
literal::DebugMsg, Rd,
Wr,
}; };
use crate::instr::{Cond}; use crate::instr::Cond;
/// A higher level simple opration /// A higher level simple opration
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
@ -64,9 +64,11 @@ pub enum Op {
Or { dst: Wr, a: Rd, b: Rd }, Or { dst: Wr, a: Rd, b: Rd },
Xor { dst: Wr, a: Rd, b: Rd }, Xor { dst: Wr, a: Rd, b: Rd },
Cpl { dst: Wr, a: Rd }, Cpl { dst: Wr, a: Rd },
Rol { dst: Wr, a: Rd, n: Rd }, // Rotate (with wrap-around) Rol { dst: Wr, a: Rd, n: Rd },
// Rotate (with wrap-around)
Ror { dst: Wr, a: Rd, n: Rd }, Ror { dst: Wr, a: Rd, n: Rd },
Lsl { dst: Wr, a: Rd, n: Rd }, // Shift Lsl { dst: Wr, a: Rd, n: Rd },
// Shift
Lsr { dst: Wr, a: Rd, n: Rd }, Lsr { dst: Wr, a: Rd, n: Rd },
Asr { dst: Wr, a: Rd, n: Rd }, Asr { dst: Wr, a: Rd, n: Rd },
} }

@ -1,25 +1,26 @@
use crate::instr::{lower, Op};
pub mod data; pub mod data;
pub mod error; pub mod error;
pub mod instr; pub mod instr;
pub mod parse; pub mod parse;
pub mod patches; pub mod patches;
use crate::instr::{Op, lower};
/// Parse a program from string and assemble a low level instruction sequence from it. /// Parse a program from string and assemble a low level instruction sequence from it.
pub fn assemble(source : &str) -> Result<Vec<Op>, error::Error> { pub fn assemble(source: &str) -> Result<Vec<Op>, error::Error> {
let parsed = parse::parse(source)?; let parsed = parse::parse(source)?;
Ok(lower(parsed)?) Ok(lower(parsed)?)
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::parse::{parse, parse_instructions};
use crate::instr::{HLOp, Op, Flatten, Instr, lower};
use crate::data::{Wr, DstDisp, Register, SrcDisp, Rd};
use crate::data::literal::{Addr, Label};
use std::sync::atomic::AtomicU32; use std::sync::atomic::AtomicU32;
use crate::data::{DstDisp, Rd, Register, SrcDisp, Wr};
use crate::data::literal::{Addr, Label};
use crate::instr::{Flatten, HLOp, Instr, lower, Op};
use crate::instr::Cond; use crate::instr::Cond;
use crate::parse::{parse, parse_instructions};
#[test] #[test]
fn test_parse_empty() { fn test_parse_empty() {
@ -147,11 +148,11 @@ mod tests {
], parsed); ], parsed);
} }
fn parse_single_instr(src : &str) -> anyhow::Result<Instr> { fn parse_single_instr(src: &str) -> anyhow::Result<Instr> {
Ok(parse_instructions(vec![sexp::parse(src)?])?.remove(0)) Ok(parse_instructions(vec![sexp::parse(src)?])?.remove(0))
} }
fn parse_single_op(src : &str) -> anyhow::Result<Vec<HLOp>> { fn parse_single_op(src: &str) -> anyhow::Result<Vec<HLOp>> {
let num = AtomicU32::new(0); let num = AtomicU32::new(0);
Ok(parse_single_instr(src)?.flatten(&num)?) Ok(parse_single_instr(src)?.flatten(&num)?)
} }
@ -187,14 +188,14 @@ mod tests {
Wr::new(DstDisp::Register(Register::Gen(0))), Wr::new(DstDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(0))), Rd::new(SrcDisp::Register(Register::Gen(0))),
)), )),
branches: None branches: None,
}, },
Instr { Instr {
op: HLOp::L(Op::Mov( op: HLOp::L(Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(1))), Wr::new(DstDisp::Register(Register::Gen(1))),
Rd::new(SrcDisp::Register(Register::Gen(2))), Rd::new(SrcDisp::Register(Register::Gen(2))),
)), )),
branches: None branches: None,
} }
] ]
), ),
@ -206,20 +207,20 @@ mod tests {
Wr::new(DstDisp::Register(Register::Gen(0))), Wr::new(DstDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(0))), Rd::new(SrcDisp::Register(Register::Gen(0))),
)), )),
branches: None branches: None,
}, },
Instr { Instr {
op: HLOp::L(Op::Mov( op: HLOp::L(Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(1))), Wr::new(DstDisp::Register(Register::Gen(1))),
Rd::new(SrcDisp::Register(Register::Gen(1))), Rd::new(SrcDisp::Register(Register::Gen(1))),
)), )),
branches: None branches: None,
} }
] ]
) )
]) ]),
} }
, parsed); , parsed);
} }
#[test] #[test]

@ -1,9 +1,10 @@
use std::sync::atomic::AtomicU32;
use crate::instr::{Routine, HLOp, Flatten}; pub use parse_instr::parse_instructions;
use crate::error::Error; use parse_routines::parse_routines;
use std::sync::atomic::AtomicU32; use crate::error::Error;
use crate::instr::{Flatten, HLOp, Routine};
use crate::parse::sexp_expect::expect_list; use crate::parse::sexp_expect::expect_list;
mod parse_cond; mod parse_cond;
@ -13,9 +14,6 @@ mod parse_routines;
mod sexp_expect; mod sexp_expect;
mod parse_op; mod parse_op;
use parse_routines::parse_routines;
pub use parse_instr::parse_instructions;
pub fn parse(source: &str) -> Result<Vec<HLOp>, Error> { pub fn parse(source: &str) -> Result<Vec<HLOp>, Error> {
let root = sexp::parse(source)?; let root = sexp::parse(source)?;

@ -1,8 +1,9 @@
use crate::parse::sexp_expect::{expect_list, expect_string_atom};
use sexp::Sexp; use sexp::Sexp;
use crate::instr::{Cond, Instr};
use crate::error::Error; use crate::error::Error;
use crate::instr::{Cond, Instr};
use crate::parse::parse_instr::parse_instructions; use crate::parse::parse_instr::parse_instructions;
use crate::parse::sexp_expect::{expect_list, expect_string_atom};
use crate::patches::TryRemove; use crate::patches::TryRemove;
pub fn parse_cond_branch(tok: Sexp) -> Result<(Cond, Vec<Instr>), Error> { pub fn parse_cond_branch(tok: Sexp) -> Result<(Cond, Vec<Instr>), Error> {

@ -1,12 +1,14 @@
use sexp::{Sexp, Atom};
use crate::data::{DataDisp, Rd, Wr, DstDisp, SrcDisp, reg};
use crate::error::Error;
use crate::data::literal::{Addr, Label};
use std::convert::TryFrom; use std::convert::TryFrom;
use sexp::{Atom, Sexp};
use crate::data::{DataDisp, DstDisp, Rd, reg, SrcDisp, Wr};
use crate::data::literal::{Addr, Label};
use crate::error::Error;
use crate::parse::sexp_expect::expect_string_atom; use crate::parse::sexp_expect::expect_string_atom;
/// Parse a label /// Parse a label
pub fn parse_label(name : Option<Sexp>) -> Result<Label, Error> { pub fn parse_label(name: Option<Sexp>) -> Result<Label, Error> {
let name = expect_string_atom(name)?; let name = expect_string_atom(name)?;
Ok(Label::Named(name.trim_start_matches(':').into())) Ok(Label::Named(name.trim_start_matches(':').into()))
} }
@ -24,32 +26,32 @@ pub fn parse_data_disp(tok: Option<Sexp>) -> Result<DataDisp, Error> {
match &tok { match &tok {
Sexp::Atom(Atom::I(val)) => { Sexp::Atom(Atom::I(val)) => {
Ok(DataDisp::Immediate(unsafe { std::mem::transmute(*val) })) Ok(DataDisp::Immediate(unsafe { std::mem::transmute(*val) }))
}, }
Sexp::Atom(Atom::S(s)) => { Sexp::Atom(Atom::S(s)) => {
if s == "_" { if s == "_" {
return Ok(DataDisp::Discard); return Ok(DataDisp::Discard);
} }
if let Some(reference) = s.strip_prefix('@') { if let Some(reference) = s.strip_prefix('@') {
if reference.starts_with(|c : char| c.is_ascii_digit()) { if reference.starts_with(|c: char| c.is_ascii_digit()) {
let val : u64 = parse_u64(reference)?; let val: u64 = parse_u64(reference)?;
Ok(DataDisp::ImmediatePtr(Addr(val))) Ok(DataDisp::ImmediatePtr(Addr(val)))
} else { } else {
Ok(DataDisp::RegisterPtr(reg::parse_reg(reference)?)) Ok(DataDisp::RegisterPtr(reg::parse_reg(reference)?))
} }
} else if s.starts_with(|c : char| c.is_ascii_digit()) { } else if s.starts_with(|c: char| c.is_ascii_digit()) {
Ok(DataDisp::Immediate(unsafe { std::mem::transmute(parse_i64(s)?) })) Ok(DataDisp::Immediate(unsafe { std::mem::transmute(parse_i64(s)?) }))
} else { } else {
Ok(DataDisp::Register(reg::parse_reg(s)?)) Ok(DataDisp::Register(reg::parse_reg(s)?))
} }
}, }
_ => { _ => {
Err(Error::Parse(format!("bad data disp: {:?}", tok).into())) Err(Error::Parse(format!("bad data disp: {:?}", tok).into()))
}, }
} }
} }
pub fn parse_u64(literal : &str) -> anyhow::Result<u64> { pub fn parse_u64(literal: &str) -> anyhow::Result<u64> {
if let Some(hex) = literal.strip_prefix("0x") { if let Some(hex) = literal.strip_prefix("0x") {
Ok(u64::from_str_radix(hex, 16)?) Ok(u64::from_str_radix(hex, 16)?)
} else if let Some(hex) = literal.strip_prefix("0b") { } else if let Some(hex) = literal.strip_prefix("0b") {
@ -59,7 +61,7 @@ pub fn parse_u64(literal : &str) -> anyhow::Result<u64> {
} }
} }
pub fn parse_i64(literal : &str) -> anyhow::Result<i64> { pub fn parse_i64(literal: &str) -> anyhow::Result<i64> {
if let Some(_value) = literal.strip_prefix("-") { if let Some(_value) = literal.strip_prefix("-") {
Ok(-1 * i64::try_from(parse_u64(literal)?)?) Ok(-1 * i64::try_from(parse_u64(literal)?)?)
} else { } else {

@ -1,11 +1,11 @@
use sexp::Sexp; use sexp::Sexp;
use crate::instr::{Instr};
use crate::error::Error;
use crate::parse::parse_cond::{parse_cond_branch};
use crate::error::Error;
use crate::instr::Instr;
use crate::parse::parse_cond::parse_cond_branch;
use crate::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::parse::sexp_expect::{expect_list, expect_string_atom};
use crate::patches::SexpIsA; use crate::patches::SexpIsA;
use super::parse_op::parse_op; use super::parse_op::parse_op;
pub fn parse_instructions(instrs: Vec<Sexp>) -> Result<Vec<Instr>, Error> { pub fn parse_instructions(instrs: Vec<Sexp>) -> Result<Vec<Instr>, Error> {
@ -43,7 +43,7 @@ pub fn parse_instructions(instrs: Vec<Sexp>) -> Result<Vec<Instr>, Error> {
parsed.push(Instr { parsed.push(Instr {
op: parse_op(name.as_str(), far, arg_tokens.into_iter())?, op: parse_op(name.as_str(), far, arg_tokens.into_iter())?,
branches branches,
}); });
} }
Ok(parsed) Ok(parsed)

@ -1,11 +1,12 @@
use crate::instr::{HLOp, Op};
use sexp::Sexp; use sexp::Sexp;
use crate::data::{Rd, Wr};
use crate::data::literal::{Label, RoutineName};
use crate::error::Error; use crate::error::Error;
use crate::data::literal::{RoutineName, Label}; use crate::instr::{HLOp, Op};
use crate::parse::sexp_expect::expect_string_atom;
use crate::parse::parse_data::{parse_rd, parse_wr, parse_label};
use crate::parse::parse_cond::parse_cond; use crate::parse::parse_cond::parse_cond;
use crate::data::{Rd, Wr}; use crate::parse::parse_data::{parse_label, parse_rd, parse_wr};
use crate::parse::sexp_expect::expect_string_atom;
pub fn parse_op(keyword: &str, far: bool, mut arg_tokens: impl ExactSizeIterator<Item=Sexp> + Clone) -> Result<HLOp, Error> { pub fn parse_op(keyword: &str, far: bool, mut arg_tokens: impl ExactSizeIterator<Item=Sexp> + Clone) -> Result<HLOp, Error> {
Ok(match keyword { Ok(match keyword {
@ -193,7 +194,7 @@ pub fn parse_op(keyword: &str, far: bool, mut arg_tokens: impl ExactSizeIterator
4 => { 4 => {
Op::Div { Op::Div {
dst: parse_wr(arg_tokens.next())?, dst: parse_wr(arg_tokens.next())?,
rem : parse_wr(arg_tokens.next())?, rem: parse_wr(arg_tokens.next())?,
a: parse_rd(arg_tokens.next())?, a: parse_rd(arg_tokens.next())?,
div: parse_rd(arg_tokens.next())?, div: parse_rd(arg_tokens.next())?,
} }

@ -1,8 +1,9 @@
use crate::parse::parse_instr::parse_instructions;
use crate::instr::Routine;
use crate::data::literal::RoutineName;
use sexp::Sexp; use sexp::Sexp;
use crate::data::literal::RoutineName;
use crate::error::Error; use crate::error::Error;
use crate::instr::Routine;
use crate::parse::parse_instr::parse_instructions;
use crate::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::parse::sexp_expect::{expect_list, expect_string_atom};
use crate::patches::TryRemove; use crate::patches::TryRemove;

@ -1,4 +1,5 @@
use sexp::{Sexp, Atom}; use sexp::{Atom, Sexp};
use crate::error::Error; use crate::error::Error;
pub fn expect_list(expr: Option<Sexp>, allow_empty: bool) -> Result<Vec<Sexp>, Error> { pub fn expect_list(expr: Option<Sexp>, allow_empty: bool) -> Result<Vec<Sexp>, Error> {

@ -1,5 +1,6 @@
pub use sexp_is_a::SexpIsA;
pub use try_remove::TryRemove;
mod try_remove; mod try_remove;
mod sexp_is_a; mod sexp_is_a;
pub use try_remove::TryRemove;
pub use sexp_is_a::SexpIsA;

@ -2,9 +2,10 @@
extern crate log; extern crate log;
use simple_logger::SimpleLogger; use simple_logger::SimpleLogger;
use runtime::run_thread::{RunThread, ThreadToken};
use runtime::program::Program;
use asm::data::literal::Addr; use asm::data::literal::Addr;
use runtime::program::Program;
use runtime::run_thread::{RunThread, ThreadToken};
fn main() { fn main() {
SimpleLogger::new().init().unwrap(); SimpleLogger::new().init().unwrap();
@ -21,24 +22,24 @@ fn main() {
) )
) )
";*/ ";*/
/* /*
let program = " let program = "
( (
(main (main
(ld r0 2) (ld r0 2)
(call add2x r0 15) (call add2x r0 15)
(ld r0 res0) (ld r0 res0)
(fault \"that's it\") (fault \"that's it\")
) )
(add2x (add2x
(ld r0 arg0) (ld r0 arg0)
(ld r1 arg1) (ld r1 arg1)
(add r0 r1) (add r0 r1)
(add r0 r1) (add r0 r1)
(ret r0) (ret r0)
)
) )
) ";*/
";*/
let program = " let program = "
( (

@ -1,10 +1,13 @@
use crate::run_thread::{RunThread}; use std::ops::Rem;
use asm::instr::{Op};
use num_traits::PrimInt;
use asm::data::literal::Addr;
use asm::instr::Op;
use crate::fault::Fault; use crate::fault::Fault;
use crate::frame::StackFrame; use crate::frame::StackFrame;
use asm::data::literal::{Addr}; use crate::run_thread::RunThread;
use std::ops::{Rem};
use num_traits::PrimInt;
pub type CyclesSpent = usize; pub type CyclesSpent = usize;

@ -1,15 +1,16 @@
use thiserror::Error; use thiserror::Error;
// use super::span::MemorySpan; // use super::span::MemorySpan;
// use crate::run_thread::ThreadToken; // use crate::run_thread::ThreadToken;
// use crate::mlock::ClaimId; // use crate::mlock::ClaimId;
use asm::data::literal::{DebugMsg, RoutineName, Label}; use asm::data::literal::{DebugMsg, Label, RoutineName};
use asm::data::Register; use asm::data::Register;
#[derive(Error,Debug)] #[derive(Error, Debug)]
pub enum Fault { pub enum Fault {
#[error("Bad instruction at addr {addr:#10x}: {cause}")] #[error("Bad instruction at addr {addr:#10x}: {cause}")]
BadInstruction { BadInstruction {
addr : u32, addr: u32,
cause: InstrError, cause: InstrError,
}, },
@ -64,7 +65,7 @@ pub enum Fault {
CallStackUnderflow, CallStackUnderflow,
} }
#[derive(Error,Debug)] #[derive(Error, Debug)]
pub enum InstrError { pub enum InstrError {
#[error("Instruction not recognized")] #[error("Instruction not recognized")]
UnknownInstruction, UnknownInstruction,

@ -1,12 +1,10 @@
use asm::data::{DstDisp, Rd, Register, SrcDisp, Wr};
use asm::data::literal::{Addr, Value}; use asm::data::literal::{Addr, Value};
use asm::data::{Rd, SrcDisp, Register, Wr, DstDisp}; use status::StatusFlags;
use crate::fault::Fault;
use crate::fault::Fault;
mod status; mod status;
use status::StatusFlags;
pub const REG_COUNT: usize = 8; pub const REG_COUNT: usize = 8;
@ -35,7 +33,7 @@ impl StackFrame {
sf sf
} }
pub fn set_retvals(&mut self, vals: &[Value]) { pub fn set_retvals(&mut self, vals: &[Value]) {
for n in 0..(vals.len().min(REG_COUNT)) { for n in 0..(vals.len().min(REG_COUNT)) {
self.res[n] = vals[n]; self.res[n] = vals[n];
} }

@ -1,6 +1,7 @@
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::fmt; use std::fmt;
use asm::data::literal::{Value, is_positive, is_negative};
use asm::data::literal::{is_negative, is_positive, Value};
use asm::instr::Cond; use asm::instr::Cond;
#[derive(Default, Clone, Debug)] #[derive(Default, Clone, Debug)]
@ -44,7 +45,7 @@ impl StatusFlags {
val val
} }
pub fn load(&mut self, val : Value) { pub fn load(&mut self, val: Value) {
if val & 0x01 != 0 { self.equal = true; } if val & 0x01 != 0 { self.equal = true; }
if val & 0x02 != 0 { self.lower = true; } if val & 0x02 != 0 { self.lower = true; }
if val & 0x04 != 0 { self.greater = true; } if val & 0x04 != 0 { self.greater = true; }

@ -1,4 +1,5 @@
#[macro_use] extern crate log; #[macro_use]
extern crate log;
pub mod run_thread; pub mod run_thread;
// pub mod mlock; // pub mod mlock;

@ -1,8 +1,9 @@
use std::sync::atomic::{AtomicU32, Ordering};
use std::fmt; use std::fmt;
use std::fmt::Formatter; use std::fmt::Formatter;
use crate::run_thread::ThreadToken; use std::sync::atomic::{AtomicU32, Ordering};
use crate::fault::Fault; use crate::fault::Fault;
use crate::run_thread::ThreadToken;
use crate::span::MemorySpan; use crate::span::MemorySpan;
/// Records memory claims and protects from illegal access /// Records memory claims and protects from illegal access
@ -85,7 +86,7 @@ impl MemoryGuard {
/// Release all owned by a thread, with claim ID >= a given value /// Release all owned by a thread, with claim ID >= a given value
/// (return from a subroutine) /// (return from a subroutine)
pub fn release_owned_after(&mut self, owner: ThreadToken, epoch : ClaimId) { pub fn release_owned_after(&mut self, owner: ThreadToken, epoch: ClaimId) {
self.claims.retain(|c| c.owner != owner || c.id >= epoch); self.claims.retain(|c| c.owner != owner || c.id >= epoch);
} }
} }

@ -1,8 +1,10 @@
use asm::instr::{Op};
use asm::data::literal::{Addr, RoutineName, Label};
use crate::fault::Fault;
use std::collections::HashMap; use std::collections::HashMap;
use asm::data::literal::{Addr, Label, RoutineName};
use asm::instr::Op;
use crate::fault::Fault;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Program { pub struct Program {
ops: Vec<Op>, ops: Vec<Op>,

@ -1,16 +1,13 @@
use std::time::Duration;
use std::thread::JoinHandle; use std::thread::JoinHandle;
use std::time::Duration;
use asm::data::literal::{Addr}; use asm::data::literal::Addr;
use crate::exec::EvalRes;
use crate::frame::StackFrame; use crate::frame::StackFrame;
use crate::program::Program; use crate::program::Program;
use crate::exec::EvalRes;
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);
#[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)] #[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)]

@ -1,8 +1,6 @@
use asm::data::literal::Addr; use asm::data::literal::Addr;
#[derive(Debug,Clone,Copy)] #[derive(Debug, Clone, Copy)]
pub struct MemorySpan { pub struct MemorySpan {
addr: usize, addr: usize,
len: usize, len: usize,

Loading…
Cancel
Save