|
|
@ -11,27 +11,25 @@ use crate::defs::ArithOp; |
|
|
|
pub(crate) fn parse<'a>(op_pos: &SourcePosition, keyword: &str, mut args: TokenParser<'a>) -> Result<ParseRes<'a, OpKind>, CrsnError> { |
|
|
|
pub(crate) fn parse<'a>(op_pos: &SourcePosition, keyword: &str, mut args: TokenParser<'a>) -> Result<ParseRes<'a, OpKind>, CrsnError> { |
|
|
|
Ok(ParseRes::ext(match keyword { |
|
|
|
Ok(ParseRes::ext(match keyword { |
|
|
|
"cmp" => { |
|
|
|
"cmp" => { |
|
|
|
ArithOp::Compare { |
|
|
|
let parsed = ArithOp::Compare { a: args.next_rd()?, b: args.next_rd()? }; |
|
|
|
a: args.next_rd()?, |
|
|
|
args.ensure_empty("two input arguments")?; |
|
|
|
b: args.next_rd()?, |
|
|
|
parsed |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"rcmp" => { |
|
|
|
"rcmp" => { |
|
|
|
ArithOp::RangeTest { |
|
|
|
let parsed = ArithOp::RangeTest { val: args.next_rd()?, a: args.next_rd()?, b: args.next_rd()? }; |
|
|
|
val: args.next_rd()?, |
|
|
|
args.ensure_empty("3 arguments (value, min, max)")?; |
|
|
|
a: args.next_rd()?, |
|
|
|
parsed |
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"tst" => { |
|
|
|
"tst" => { |
|
|
|
let arg = args.next_rd()?; |
|
|
|
let arg = args.next_rd()?; |
|
|
|
|
|
|
|
args.ensure_empty("1 input argument")?; |
|
|
|
ArithOp::Test { a: arg } |
|
|
|
ArithOp::Test { a: arg } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"rng" => { |
|
|
|
"rng" => { |
|
|
|
match args.len() { |
|
|
|
let parsed = match args.len() { |
|
|
|
1 => { |
|
|
|
1 => { |
|
|
|
ArithOp::Rng { |
|
|
|
ArithOp::Rng { |
|
|
|
dst: args.next_wr()?, |
|
|
|
dst: args.next_wr()?, |
|
|
@ -56,94 +54,34 @@ pub(crate) fn parse<'a>(op_pos: &SourcePosition, keyword: &str, mut args: TokenP |
|
|
|
_ => { |
|
|
|
_ => { |
|
|
|
return Err(CrsnError::Parse("Rng requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
return Err(CrsnError::Parse("Rng requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
args.ensure_empty("1 (dst) or 3 (dst, min, max) arguments")?; |
|
|
|
|
|
|
|
parsed |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"inc" => { |
|
|
|
"inc" => { |
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
let (dst, a) = args.parse_wr_rd()?; |
|
|
|
ArithOp::Add { |
|
|
|
ArithOp::Add { dst, a, b: Rd::immediate(1) } |
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
b: Rd::immediate(1), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"dec" => { |
|
|
|
"dec" => { |
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
let (dst, a) = args.parse_wr_rd()?; |
|
|
|
ArithOp::Sub { |
|
|
|
ArithOp::Sub { dst, a, b: Rd::immediate(1) } |
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
b: Rd::immediate(1), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"add" => { |
|
|
|
"add" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, b) = args.parse_wr_rd_rd()?; |
|
|
|
3 => { |
|
|
|
ArithOp::Add { dst, a, b } |
|
|
|
ArithOp::Add { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Add { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Add requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"sub" => { |
|
|
|
"sub" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, b) = args.parse_wr_rd_rd()?; |
|
|
|
3 => { |
|
|
|
ArithOp::Sub { dst, a, b } |
|
|
|
ArithOp::Sub { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Sub { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Sub requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"mul" => { |
|
|
|
"mul" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, b) = args.parse_wr_rd_rd()?; |
|
|
|
3 => { |
|
|
|
ArithOp::Mul { dst, a, b } |
|
|
|
ArithOp::Mul { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Mul { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Mul requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"divr" => { |
|
|
|
"divr" => { |
|
|
@ -174,403 +112,83 @@ pub(crate) fn parse<'a>(op_pos: &SourcePosition, keyword: &str, mut args: TokenP |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"div" => { |
|
|
|
"div" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, div) = args.parse_wr_rd_rd()?; |
|
|
|
3 => { |
|
|
|
ArithOp::Div { dst, rem: Wr::discard(), a, div } |
|
|
|
ArithOp::Div { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
rem: Wr::discard(), |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
div: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
let div = args.next_rd()?; |
|
|
|
|
|
|
|
ArithOp::Div { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
rem: Wr::discard(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
div, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Div requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"mod" => { |
|
|
|
"mod" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, div) = args.parse_wr_rd_rd()?; |
|
|
|
3 => { |
|
|
|
ArithOp::Mod { dst, a, div } |
|
|
|
ArithOp::Mod { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
div: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
let div = args.next_rd()?; |
|
|
|
|
|
|
|
ArithOp::Mod { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
div, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Mod requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"and" => { |
|
|
|
"and" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, b) = args.parse_wr_rd_rd()?; |
|
|
|
3 => { |
|
|
|
ArithOp::And { dst, a, b } |
|
|
|
ArithOp::And { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::And { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("And requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"or" => { |
|
|
|
"or" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, b) = args.parse_wr_rd_rd()?; |
|
|
|
3 => { |
|
|
|
ArithOp::Or { dst, a, b } |
|
|
|
ArithOp::Or { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Or { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Or requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"xor" => { |
|
|
|
"xor" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, b) = args.parse_wr_rd_rd()?; |
|
|
|
3 => { |
|
|
|
ArithOp::Xor { dst, a, b } |
|
|
|
ArithOp::Xor { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Xor { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
b: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Xor requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"cpl" => { |
|
|
|
"cpl" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a) = args.parse_wr_rd()?; |
|
|
|
2 => { |
|
|
|
ArithOp::Cpl { dst, a } |
|
|
|
ArithOp::Cpl { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Cpl { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Cpl requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"rol" => { |
|
|
|
"rol" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, n) = args.parse_wr_rd_rd_or_n(1)?; |
|
|
|
3 => { |
|
|
|
ArithOp::Rol { dst, a, n } |
|
|
|
ArithOp::Rol { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Rol { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Rol { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
n: Rd::immediate(1), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Rol requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"ror" => { |
|
|
|
"ror" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, n) = args.parse_wr_rd_rd_or_n(1)?; |
|
|
|
3 => { |
|
|
|
ArithOp::Ror { dst, a, n } |
|
|
|
ArithOp::Ror { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Ror { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Ror { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
n: Rd::immediate(1), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Ror requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"lsl" | "asl" => { |
|
|
|
"lsl" | "asl" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, n) = args.parse_wr_rd_rd_or_n(1)?; |
|
|
|
3 => { |
|
|
|
ArithOp::Lsl { dst, a, n } |
|
|
|
ArithOp::Lsl { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Lsl { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Lsl { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
n: Rd::immediate(1), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Lsl requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"lsr" => { |
|
|
|
"lsr" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, n) = args.parse_wr_rd_rd_or_n(1)?; |
|
|
|
3 => { |
|
|
|
ArithOp::Lsr { dst, a, n } |
|
|
|
ArithOp::Lsr { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Lsr { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Lsr { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
n: Rd::immediate(1), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Lsr requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"asr" => { |
|
|
|
"asr" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, a, n) = args.parse_wr_rd_rd_or_n(1)?; |
|
|
|
3 => { |
|
|
|
ArithOp::Asr { dst, a, n } |
|
|
|
ArithOp::Asr { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
a: args.next_rd()?, |
|
|
|
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
2 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Asr { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
n: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Asr { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
a: dst.rd(), |
|
|
|
|
|
|
|
n: Rd::immediate(1), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("Asr requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"sw32" => { |
|
|
|
"sw32" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, src) = args.parse_wr_rd()?; |
|
|
|
2 => { |
|
|
|
ArithOp::Sw32 { dst, src } |
|
|
|
ArithOp::Sw32 { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Sw32 { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
src: dst.rd(), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("SW32 requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"sw16" => { |
|
|
|
"sw16" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, src) = args.parse_wr_rd()?; |
|
|
|
2 => { |
|
|
|
ArithOp::Sw16 { dst, src } |
|
|
|
ArithOp::Sw16 { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Sw16 { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
src: dst.rd(), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("SW16 requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"sw8" => { |
|
|
|
"sw8" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, src) = args.parse_wr_rd()?; |
|
|
|
2 => { |
|
|
|
ArithOp::Sw8 { dst, src } |
|
|
|
ArithOp::Sw8 { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Sw8 { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
src: dst.rd(), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("SW8 requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"rev" => { |
|
|
|
"rev" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, src) = args.parse_wr_rd()?; |
|
|
|
2 => { |
|
|
|
ArithOp::Rev { dst, src } |
|
|
|
ArithOp::Rev { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Rev { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
src: dst.rd(), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("REV requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"rbit" => { |
|
|
|
"rbit" => { |
|
|
|
match args.len() { |
|
|
|
let (dst, src) = args.parse_wr_rd()?; |
|
|
|
2 => { |
|
|
|
ArithOp::Rbit { dst, src } |
|
|
|
ArithOp::Rbit { |
|
|
|
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
1 => { |
|
|
|
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
|
|
|
ArithOp::Rbit { |
|
|
|
|
|
|
|
dst: dst.wr(), |
|
|
|
|
|
|
|
src: dst.rd(), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(CrsnError::Parse("RBIT requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
other => { |
|
|
|
other => { |
|
|
|