|
|
|
@ -8,6 +8,10 @@ use crsn::runtime::fault::Fault; |
|
|
|
|
use crsn::runtime::run_thread::{state::RunState, ThreadInfo}; |
|
|
|
|
|
|
|
|
|
use crate::defs::ArithOp; |
|
|
|
|
use crsn::sexp::Sexp; |
|
|
|
|
use crsn::sexp; |
|
|
|
|
use crsn::utils::A; |
|
|
|
|
use crsn::asm::data::{Rd, Wr}; |
|
|
|
|
|
|
|
|
|
impl OpTrait for ArithOp { |
|
|
|
|
fn execute(&self, _ti: &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault> { |
|
|
|
@ -191,6 +195,53 @@ impl OpTrait for ArithOp { |
|
|
|
|
|
|
|
|
|
Ok(eres) |
|
|
|
|
} |
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
fn to_sexp(&self) -> Sexp { |
|
|
|
|
match self { |
|
|
|
|
ArithOp::Add { dst, a, b } => to_sexp_2_or_3("add", dst, a, b), |
|
|
|
|
ArithOp::Test { a } => sexp::list(&[A("test"), A(a)]), |
|
|
|
|
ArithOp::Compare { a, b } => sexp::list(&[A("cmp"), A(a), A(b)]), |
|
|
|
|
ArithOp::Sub { dst, a, b } => to_sexp_2_or_3("sub", dst, a, b), |
|
|
|
|
ArithOp::Mul { dst, a, b } => to_sexp_2_or_3("mul", dst, a, b), |
|
|
|
|
ArithOp::Div { dst, rem, a, div } => { |
|
|
|
|
if rem.is_discard() { |
|
|
|
|
if &dst.as_rd() == a { |
|
|
|
|
sexp::list(&[A("div"), A(dst), A(div)]) |
|
|
|
|
} else { |
|
|
|
|
sexp::list(&[A("div"), A(dst), A(a), A(div)]) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if &dst.as_rd() == a { |
|
|
|
|
sexp::list(&[A("divr"), A(dst), A(rem), A(div)]) |
|
|
|
|
} else { |
|
|
|
|
sexp::list(&[A("divr"), A(dst), A(rem), A(a), A(div)]) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
ArithOp::Mod { dst, a, div } => to_sexp_2_or_3("mod", dst, a, div), |
|
|
|
|
ArithOp::And { dst, a, b } => to_sexp_2_or_3("and", dst, a, b), |
|
|
|
|
ArithOp::Or { dst, a, b } => to_sexp_2_or_3("or", dst, a, b), |
|
|
|
|
ArithOp::Xor { dst, a, b } => to_sexp_2_or_3("xor", dst, a, b), |
|
|
|
|
ArithOp::Cpl { dst, a } => { |
|
|
|
|
if &dst.as_rd() == a { |
|
|
|
|
sexp::list(&[A("cpl"), A(dst)]) |
|
|
|
|
} else { |
|
|
|
|
sexp::list(&[A("cpl"), A(dst), A(a)]) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
ArithOp::Rol { dst, a, n } => to_sexp_2_or_3("rol", dst, a, n), |
|
|
|
|
ArithOp::Ror { dst, a, n } => to_sexp_2_or_3("ror", dst, a, n), |
|
|
|
|
ArithOp::Lsl { dst, a, n } => to_sexp_2_or_3("lsl", dst, a, n), |
|
|
|
|
ArithOp::Lsr { dst, a, n } => to_sexp_2_or_3("lsr", dst, a, n), |
|
|
|
|
ArithOp::Asr { dst, a, n } => to_sexp_2_or_3("asr", dst, a, n), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn to_sexp_2_or_3(name: &str, dst : &Wr, a: &Rd, b: &Rd) -> Sexp { |
|
|
|
|
if &dst.as_rd() == a { |
|
|
|
|
sexp::list(&[A(name), A(dst), A(b)]) |
|
|
|
|
} else { |
|
|
|
|
sexp::list(&[A(name), A(dst), A(a), A(b)]) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|