|
|
|
@ -6,8 +6,9 @@ use crsn::module::ParseRes; |
|
|
|
|
use crsn::sexp::SourcePosition; |
|
|
|
|
|
|
|
|
|
use crate::defs::ArithOp; |
|
|
|
|
use crsn::builtin::defs::BitSlice; |
|
|
|
|
|
|
|
|
|
pub(crate) fn parse<'a>(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 { |
|
|
|
|
"cmp" => { |
|
|
|
|
ArithOp::Compare { |
|
|
|
@ -53,7 +54,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Rng requires 1, 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Rng requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -94,7 +95,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Add requires 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Add requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -117,7 +118,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Sub requires 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Sub requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -140,7 +141,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Mul requires 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Mul requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -167,7 +168,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("DivR requires 3 or 4 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("DivR requires 3 or 4 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -193,7 +194,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Div requires 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Div requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -217,7 +218,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Mod requires 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Mod requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -240,7 +241,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("And requires 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("And requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -263,7 +264,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Or requires 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Or requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -286,7 +287,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Xor requires 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Xor requires 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -307,7 +308,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Cpl requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Cpl requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -338,7 +339,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Rol requires 1, 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Rol requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -369,7 +370,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Ror requires 1, 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Ror requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -400,7 +401,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Lsl requires 1, 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Lsl requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -431,7 +432,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Lsr requires 1, 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Lsr requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -462,7 +463,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Asr requires 1, 2 or 3 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("Asr requires 1, 2 or 3 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -483,7 +484,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("SW32 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("SW32 requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -504,7 +505,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("SW16 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("SW16 requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -525,7 +526,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("SW8 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("SW8 requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -546,7 +547,7 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("REV requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("REV requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -567,243 +568,66 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("RBIT requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
return Err(CrsnError::Parse("RBIT requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"clz" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Clz { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::Clz { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Clz requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
other => { |
|
|
|
|
if let Some(s) = other.strip_prefix("clz") { |
|
|
|
|
if let Some(slice) = BitSlice::parse2(s, op_pos)? { |
|
|
|
|
return Ok(ParseRes::ext(match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Clz { dst: args.next_wr()?, src: args.next_rd()?, slice } |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::Clz { dst: dst.wr(), src: dst.rd(), slice } |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Clz requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
})); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"clz32" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Clz32 { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::Clz32 { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Clz32 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
if let Some(s) = other.strip_prefix("clo") { |
|
|
|
|
if let Some(slice) = BitSlice::parse2(s, op_pos)? { |
|
|
|
|
return Ok(ParseRes::ext(match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Clo { dst: args.next_wr()?, src: args.next_rd()?, slice } |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::Clo { dst: dst.wr(), src: dst.rd(), slice } |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Clz requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
})); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"clz16" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Clz16 { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::Clz16 { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
if let Some(s) = other.strip_prefix("se") { |
|
|
|
|
if let Some(slice) = BitSlice::parse1(s, op_pos)? { |
|
|
|
|
if slice.is_full() { |
|
|
|
|
return Err(CrsnError::Parse("Sign extend requires a bit size (< 64)".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Clz16 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
return Ok(ParseRes::ext(match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::SignExtend { dst: args.next_wr()?, src: args.next_rd()?, slice } |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::SignExtend { dst: dst.wr(), src: dst.rd(), slice } |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Sign extend requires 1 or 2 arguments".into(), op_pos.clone())); |
|
|
|
|
} |
|
|
|
|
})); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"clz8" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Clz8 { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::Clz8 { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Clz8 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"clo" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Clo { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::Clo { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Clo requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"clo32" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Clo32 { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::Clo32 { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Clo32 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"clo16" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Clo16 { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::Clo16 { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Clo16 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"clo8" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::Clo8 { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::Clo8 { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("Clo8 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"se32" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::SignExtend32 { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::SignExtend32 { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("SignExtend32 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"se16" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::SignExtend16 { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::SignExtend16 { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("SignExtend16 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"se8" => { |
|
|
|
|
match args.len() { |
|
|
|
|
2 => { |
|
|
|
|
ArithOp::SignExtend8 { |
|
|
|
|
dst: args.next_wr()?, |
|
|
|
|
src: args.next_rd()?, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
1 => { |
|
|
|
|
let dst = args.next_rdwr()?; |
|
|
|
|
ArithOp::SignExtend8 { |
|
|
|
|
dst: dst.wr(), |
|
|
|
|
src: dst.rd(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => { |
|
|
|
|
return Err(CrsnError::Parse("SignExtend8 requires 1 or 2 arguments".into(), pos.clone())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_other => { |
|
|
|
|
return Ok(ParseRes::Unknown(args)); |
|
|
|
|
} |
|
|
|
|
})) |
|
|
|
|