|
|
|
@ -1,10 +1,11 @@ |
|
|
|
|
use crsn::asm::data::{Rd, Wr}; |
|
|
|
|
use crsn::asm::error::{AsmError, Error}; |
|
|
|
|
use crsn::asm::instr::op::{OpParser, OpTrait}; |
|
|
|
|
use crsn::asm::parse::parse_data::{parse_rd, parse_wr}; |
|
|
|
|
use crsn::sexp::Sexp; |
|
|
|
|
use crsn::asm::error::{Error}; |
|
|
|
|
use crsn::asm::instr::op::{AsmModule, ParseOpResult}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use crate::defs::ArithOp; |
|
|
|
|
use crsn::asm::parse::arg_parser::ArgParser; |
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)] |
|
|
|
|
pub struct ArithOpParser { |
|
|
|
@ -12,31 +13,34 @@ pub struct ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl ArithOpParser { |
|
|
|
|
pub fn new() -> Box<dyn OpParser> { |
|
|
|
|
pub fn new() -> Box<dyn AsmModule> { |
|
|
|
|
Box::new(Self { |
|
|
|
|
_internal: () |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl OpParser for ArithOpParser { |
|
|
|
|
fn parse_op(&self, keyword: &str, _far: bool, arg_tokens_sl: Vec<Sexp>) -> Result<Box<dyn OpTrait>, Error> { |
|
|
|
|
let mut arg_tokens = arg_tokens_sl.into_iter(); |
|
|
|
|
Ok(Box::new(match keyword { |
|
|
|
|
impl AsmModule for ArithOpParser { |
|
|
|
|
fn name(&self) -> &'static str { |
|
|
|
|
"arith" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpResult, Error> { |
|
|
|
|
Ok(ParseOpResult::Parsed(Box::new(match keyword { |
|
|
|
|
"cmp" => { |
|
|
|
|
ArithOp::Compare { |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"tst" => { |
|
|
|
|
let arg = parse_rd(arg_tokens.next())?; |
|
|
|
|
let arg = args.next_rd()?; |
|
|
|
|
ArithOp::Test { a: arg } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"inc" => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Add { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
@ -45,7 +49,7 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"dec" => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Sub { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
@ -54,20 +58,20 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"add" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Add { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Add { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
@ -77,20 +81,20 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"sub" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Sub { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Sub { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
@ -100,20 +104,20 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"mul" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Mul { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Mul { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
@ -123,11 +127,11 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"divr" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let rem = parse_wr(arg_tokens.next())?; |
|
|
|
|
let div = parse_rd(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
let rem = args.next_wr()?; |
|
|
|
|
let div = args.next_rd()?; |
|
|
|
|
ArithOp::Div { |
|
|
|
|
dst, |
|
|
|
|
rem, |
|
|
|
@ -137,10 +141,10 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
4 => { |
|
|
|
|
ArithOp::Div { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
rem: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
div: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
rem: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
div: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
@ -150,18 +154,18 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"div" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Div { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
rem: Wr::discard(), |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
div: parse_rd(arg_tokens.next())?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
div: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let div = parse_rd(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
let div = args.next_rd()?; |
|
|
|
|
ArithOp::Div { |
|
|
|
|
dst, |
|
|
|
|
rem: Wr::discard(), |
|
|
|
@ -176,17 +180,17 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"mod" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Mod { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
div: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
div: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let div = parse_rd(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
let div = args.next_rd()?; |
|
|
|
|
ArithOp::Mod { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
@ -200,20 +204,20 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"and" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::And { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::And { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
@ -223,20 +227,20 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"or" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Or { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Or { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
@ -246,20 +250,20 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"xor" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Xor { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Xor { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
b: parse_rd(arg_tokens.next())?, |
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
@ -269,15 +273,15 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"cpl" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Cpl { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Cpl { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
@ -290,24 +294,24 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"rol" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Rol { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
n: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Rol { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
n: parse_rd(arg_tokens.next())?, |
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Rol { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
@ -321,24 +325,24 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"ror" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Ror { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
n: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Ror { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
n: parse_rd(arg_tokens.next())?, |
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Ror { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
@ -352,24 +356,24 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"lsl" | "asl" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Lsl { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
n: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Lsl { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
n: parse_rd(arg_tokens.next())?, |
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Lsl { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
@ -383,24 +387,24 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"lsr" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Lsr { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
n: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Lsr { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
n: parse_rd(arg_tokens.next())?, |
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Lsr { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
@ -414,24 +418,24 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"asr" => { |
|
|
|
|
match arg_tokens.len() { |
|
|
|
|
match args.len() { |
|
|
|
|
3 => { |
|
|
|
|
ArithOp::Asr { |
|
|
|
|
dst: parse_wr(arg_tokens.next())?, |
|
|
|
|
a: parse_rd(arg_tokens.next())?, |
|
|
|
|
n: parse_rd(arg_tokens.next())?, |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
2 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Asr { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
|
n: parse_rd(arg_tokens.next())?, |
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = parse_wr(arg_tokens.next())?; |
|
|
|
|
let dst = args.next_wr()?; |
|
|
|
|
ArithOp::Asr { |
|
|
|
|
dst, |
|
|
|
|
a: dst.as_rd(), |
|
|
|
@ -445,8 +449,8 @@ impl OpParser for ArithOpParser { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_other => { |
|
|
|
|
return Err(Error::Asm(AsmError::UnknownInstruction)); |
|
|
|
|
return Ok(ParseOpResult::Unknown(args)); |
|
|
|
|
} |
|
|
|
|
})) |
|
|
|
|
}))) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|