add sign extend commands

This commit is contained in:
2020-10-15 00:41:07 +02:00
parent 3b9e89674c
commit 01ab4e7e1f
6 changed files with 116 additions and 2 deletions
+3
View File
@@ -21,6 +21,9 @@ pub enum ArithOp {
Clo32 { dst: Wr, src: Rd },
Clo16 { dst: Wr, src: Rd },
Clo8 { dst: Wr, src: Rd },
SignExtend32 { dst: Wr, src: Rd },
SignExtend16 { dst: Wr, src: Rd },
SignExtend8 { dst: Wr, src: Rd },
Add { dst: Wr, a: Rd, b: Rd },
Sub { dst: Wr, a: Rd, b: Rd },
+36
View File
@@ -306,6 +306,39 @@ impl OpTrait for ArithOp {
state.update_status(res);
state.write(dst, res)?;
}
ArithOp::SignExtend32 { dst, src } => {
state.clear_status();
let val = state.read(src)?;
let res = if 0 != (val & 0x8000_0000) {
0xFFFF_FFFF_0000_0000 | val
} else {
val
};
state.update_status(res);
state.write(dst, res)?;
}
ArithOp::SignExtend16 { dst, src } => {
state.clear_status();
let val = state.read(src)?;
let res = if 0 != (val & 0x8000) {
0xFFFF_FFFF_FFFF_0000 | val
} else {
val
};
state.update_status(res);
state.write(dst, res)?;
}
ArithOp::SignExtend8 { dst, src } => {
state.clear_status();
let val = state.read(src)?;
let res = if 0 != (val & 0x80) {
0xFFFF_FFFF_FFFF_FF00 | val
} else {
val
};
state.update_status(res);
state.write(dst, res)?;
}
}
Ok(eres)
@@ -362,6 +395,9 @@ impl OpTrait for ArithOp {
ArithOp::Clo32 { dst, src } => to_sexp_1_or_2("clo32", dst, src),
ArithOp::Clo16 { dst, src } => to_sexp_1_or_2("clo16", dst, src),
ArithOp::Clo8 { dst, src } => to_sexp_1_or_2("clo8", dst, src),
ArithOp::SignExtend32 { dst, src } => to_sexp_1_or_2("se32", dst, src),
ArithOp::SignExtend16 { dst, src } => to_sexp_1_or_2("se16", dst, src),
ArithOp::SignExtend8 { dst, src } => to_sexp_1_or_2("se8", dst, src),
}
}
}
+63
View File
@@ -740,6 +740,69 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars
}
}
"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));
}