DRY arithmetic parsing
This commit is contained in:
@@ -189,7 +189,7 @@ impl<'a> TokenParser<'a> {
|
|||||||
|
|
||||||
Ok(Some((wr, rd1, rd2, mask)))
|
Ok(Some((wr, rd1, rd2, mask)))
|
||||||
} else {
|
} else {
|
||||||
Err(CrsnError::Parse("Instruction needs 2 (RW Rd) or 3 (Wr Rd Rd) arguments!".into(), self.start_pos.clone()))
|
Err(CrsnError::Parse("Instruction needs 2 (RW,Rd) or 3 (Wr,Rd,Rd) arguments!".into(), self.start_pos.clone()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@@ -232,7 +232,7 @@ impl<'a> TokenParser<'a> {
|
|||||||
|
|
||||||
Ok(Some((wr, rd, mask)))
|
Ok(Some((wr, rd, mask)))
|
||||||
} else {
|
} else {
|
||||||
Err(CrsnError::Parse("Instruction needs 1 (RW) or 2 (Wr Rd) arguments!".into(), self.start_pos.clone()))
|
Err(CrsnError::Parse("Instruction needs 1 (RW) or 2 (Wr,Rd) arguments!".into(), self.start_pos.clone()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@@ -262,7 +262,7 @@ impl<'a> TokenParser<'a> {
|
|||||||
|
|
||||||
Ok(Some((wr1, wr2, mask)))
|
Ok(Some((wr1, wr2, mask)))
|
||||||
} else {
|
} else {
|
||||||
Err(CrsnError::Parse("Instruction needs 2 (RW RW) arguments!".into(), self.start_pos.clone()))
|
Err(CrsnError::Parse("Instruction needs 2 (RW,RW) arguments!".into(), self.start_pos.clone()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@@ -270,6 +270,7 @@ impl<'a> TokenParser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parse combining binary instruction operands (i.e. add) without masks
|
/// Parse combining binary instruction operands (i.e. add) without masks
|
||||||
|
/// Accepts (Wr, Rd, Rd) and (RdWr, Rd)
|
||||||
pub fn parse_wr_rd_rd(&mut self) -> Result<(Wr, Rd, Rd), CrsnError> {
|
pub fn parse_wr_rd_rd(&mut self) -> Result<(Wr, Rd, Rd), CrsnError> {
|
||||||
if self.len() == 2 {
|
if self.len() == 2 {
|
||||||
let rw = self.next_rdwr()?;
|
let rw = self.next_rdwr()?;
|
||||||
@@ -281,11 +282,32 @@ impl<'a> TokenParser<'a> {
|
|||||||
let rd2 = self.next_rd()?;
|
let rd2 = self.next_rd()?;
|
||||||
Ok((wr, rd1, rd2))
|
Ok((wr, rd1, rd2))
|
||||||
} else {
|
} else {
|
||||||
Err(CrsnError::Parse("Instruction needs 2 (RW Rd) or 3 (Wr Rd Rd) arguments!".into(), self.start_pos.clone()))
|
Err(CrsnError::Parse("Instruction needs 2 (RW,Rd) or 3 (Wr,Rd,Rd) arguments!".into(), self.start_pos.clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse combining binary instruction operands (i.e. add) without masks
|
||||||
|
/// Accepts (Wr, Rd, Rd) and (RdWr, Rd)
|
||||||
|
pub fn parse_wr_rd_rd_or_n(&mut self, n : Value) -> Result<(Wr, Rd, Rd), CrsnError> {
|
||||||
|
if self.len() == 1 {
|
||||||
|
let rw = self.next_rdwr()?;
|
||||||
|
Ok((rw.wr(), rw.rd(), Rd::immediate(n)))
|
||||||
|
} else if self.len() == 2 {
|
||||||
|
let rw = self.next_rdwr()?;
|
||||||
|
let rd = self.next_rd()?;
|
||||||
|
Ok((rw.wr(), rw.rd(), rd))
|
||||||
|
} else if self.len() == 3 {
|
||||||
|
let wr = self.next_wr()?;
|
||||||
|
let rd1 = self.next_rd()?;
|
||||||
|
let rd2 = self.next_rd()?;
|
||||||
|
Ok((wr, rd1, rd2))
|
||||||
|
} else {
|
||||||
|
Err(CrsnError::Parse("Instruction needs 1 (RW,1), 2 (RW,Rd) or 3 (Wr,Rd,Rd) arguments!".into(), self.start_pos.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse unary instruction operands (i.e. complement) without masks
|
/// Parse unary instruction operands (i.e. complement) without masks
|
||||||
|
/// Accepts (Wr, Rd) and (RdWr)
|
||||||
pub fn parse_wr_rd(&mut self) -> Result<(Wr, Rd), CrsnError> {
|
pub fn parse_wr_rd(&mut self) -> Result<(Wr, Rd), CrsnError> {
|
||||||
if self.len() == 1 {
|
if self.len() == 1 {
|
||||||
let rw = self.next_rdwr()?;
|
let rw = self.next_rdwr()?;
|
||||||
@@ -295,18 +317,19 @@ impl<'a> TokenParser<'a> {
|
|||||||
let rd = self.next_rd()?;
|
let rd = self.next_rd()?;
|
||||||
Ok((wr, rd))
|
Ok((wr, rd))
|
||||||
} else {
|
} else {
|
||||||
Err(CrsnError::Parse("Instruction needs 1 (RW) or 2 (Wr Rd) arguments!".into(), self.start_pos.clone()))
|
Err(CrsnError::Parse("Instruction needs 1 (RW) or 2 (Wr,Rd) arguments!".into(), self.start_pos.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a swap-type binary instruction operands (i.e. exchange) without masks
|
/// Parse a swap-type binary instruction operands (i.e. exchange) without masks
|
||||||
|
/// Accepts (RdWr, RdWr)
|
||||||
pub fn parse_rdwr_rdwr(&mut self, _keyword: &str, _prefix: &str, _pos: &SourcePosition) -> Result<(RdWr, RdWr), CrsnError> {
|
pub fn parse_rdwr_rdwr(&mut self, _keyword: &str, _prefix: &str, _pos: &SourcePosition) -> Result<(RdWr, RdWr), CrsnError> {
|
||||||
if self.len() == 2 {
|
if self.len() == 2 {
|
||||||
let rw1 = self.next_rdwr()?;
|
let rw1 = self.next_rdwr()?;
|
||||||
let rw2 = self.next_rdwr()?;
|
let rw2 = self.next_rdwr()?;
|
||||||
Ok((rw1, rw2))
|
Ok((rw1, rw2))
|
||||||
} else {
|
} else {
|
||||||
Err(CrsnError::Parse("Instruction needs 2 (RW RW) arguments!".into(), self.start_pos.clone()))
|
Err(CrsnError::Parse("Instruction needs 2 (RW,RW) arguments!".into(), self.start_pos.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+53
-435
@@ -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 => {
|
||||||
|
|||||||
Reference in New Issue
Block a user