forked from MightyPork/crsn
add sign extend commands
This commit is contained in:
@@ -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 },
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user