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