|
|
|
use crsn::asm::data::{Rd, Wr};
|
|
|
|
use crsn::asm::error::CrsnError;
|
|
|
|
use crsn::asm::instr::op::OpKind;
|
|
|
|
use crsn::asm::parse::arg_parser::TokenParser;
|
|
|
|
use crsn::module::ParseRes;
|
|
|
|
use crsn::sexp::SourcePosition;
|
|
|
|
|
|
|
|
use crate::defs::ArithOp;
|
|
|
|
use crsn::builtin::defs::BitSlice;
|
|
|
|
|
|
|
|
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 {
|
|
|
|
a: args.next_rd()?,
|
|
|
|
b: args.next_rd()?,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
"rcmp" => {
|
|
|
|
ArithOp::RangeTest {
|
|
|
|
val: args.next_rd()?,
|
|
|
|
a: args.next_rd()?,
|
|
|
|
b: args.next_rd()?,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
"tst" => {
|
|
|
|
let arg = args.next_rd()?;
|
|
|
|
ArithOp::Test { a: arg }
|
|
|
|
}
|
|
|
|
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
"rng" => {
|
|
|
|
match args.len() {
|
|
|
|
1 => {
|
|
|
|
ArithOp::Rng {
|
|
|
|
dst: args.next_wr()?,
|
|
|
|
min: Rd::immediate(0),
|
|
|
|
max: Rd::immediate(u64::MAX),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
2 => {
|
|
|
|
ArithOp::Rng {
|
|
|
|
dst: args.next_wr()?,
|
|
|
|
min: Rd::immediate(0),
|
|
|
|
max: args.next_rd()?,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
3 => {
|
|
|
|
ArithOp::Rng {
|
|
|
|
dst: args.next_wr()?,
|
|
|
|
min: args.next_rd()?,
|
|
|
|
max: args.next_rd()?,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
return Err(CrsnError::Parse("Rng requires 1, 2 or 3 arguments".into(), op_pos.clone()));
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
"inc" => {
|
|
|
|
let dst = args.next_rdwr()?;
|
|
|
|
ArithOp::Add {
|
|
|
|
dst: dst.wr(),
|
|
|
|
a: dst.rd(),
|
|
|
|
b: Rd::immediate(1),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
"dec" => {
|
|
|
|
let dst = args.next_rdwr()?;
|
|
|
|
ArithOp::Sub {
|
|
|
|
dst: dst.wr(),
|
|
|
|
a: dst.rd(),
|
|
|
|
b: Rd::immediate(1),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
"add" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
let dst = args.next_rdwr()?;
|
|
|
|
let rem = args.next_wr()?;
|
|
|
|
let div = args.next_rd()?;
|
|
|
|
ArithOp::Div {
|
|
|
|
dst: dst.wr(),
|
|
|
|
rem,
|
|
|
|
a: dst.rd(),
|
|
|
|
div,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
4 => {
|
|
|
|
ArithOp::Div {
|
|
|
|
dst: args.next_wr()?,
|
|
|
|
rem: args.next_wr()?,
|
|
|
|
a: args.next_rd()?,
|
|
|
|
div: args.next_rd()?,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
return Err(CrsnError::Parse("DivR requires 3 or 4 arguments".into(), op_pos.clone()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
"div" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
2 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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" => {
|
|
|
|
match args.len() {
|
|
|
|
3 => {
|
|
|
|
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()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
"sw32" => {
|
|
|
|
match args.len() {
|
|
|
|
2 => {
|
|
|
|
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()));
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
"sw16" => {
|
|
|
|
match args.len() {
|
|
|
|
2 => {
|
|
|
|
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()));
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
"sw8" => {
|
|
|
|
match args.len() {
|
|
|
|
2 => {
|
|
|
|
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()));
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
"rev" => {
|
|
|
|
match args.len() {
|
|
|
|
2 => {
|
|
|
|
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()));
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
"rbit" => {
|
|
|
|
match args.len() {
|
|
|
|
2 => {
|
|
|
|
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()));
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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()));
|
|
|
|
}
|
|
|
|
}));
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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()));
|
|
|
|
}
|
|
|
|
}));
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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()));
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
}
|
|
|
|
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()));
|
|
|
|
}
|
|
|
|
}));
|
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
4 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ok(ParseRes::Unknown(args));
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|