forked from MightyPork/crsn
add sign extend commands
This commit is contained in:
@@ -469,6 +469,18 @@ Many instructions have two forms:
|
|||||||
(clo8 Wr Rd)
|
(clo8 Wr Rd)
|
||||||
(clo8 RW)
|
(clo8 RW)
|
||||||
|
|
||||||
|
; Sign extend 32-bit to 64 bits
|
||||||
|
(se32 Wr Rd)
|
||||||
|
(se32 RW)
|
||||||
|
|
||||||
|
; Sign extend 16-bit to 64 bits
|
||||||
|
(se16 Wr Rd)
|
||||||
|
(se16 RW)
|
||||||
|
|
||||||
|
; Sign extend 8-bit to 64 bits
|
||||||
|
(se8 Wr Rd)
|
||||||
|
(se8 RW)
|
||||||
|
|
||||||
; AND A&B
|
; AND A&B
|
||||||
(and Wr Rd Rd)
|
(and Wr Rd Rd)
|
||||||
(and RW Rd)
|
(and RW Rd)
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ mod test {
|
|||||||
("(fault)", "(fault)"),
|
("(fault)", "(fault)"),
|
||||||
("(fault kur*a)", "(fault kur*a)"),
|
("(fault kur*a)", "(fault kur*a)"),
|
||||||
("(fault \"do pr*ele\")", "(fault \"do pr*ele\")"),
|
("(fault \"do pr*ele\")", "(fault \"do pr*ele\")"),
|
||||||
("(xchxch r0 r1)", "(xch r0 r1)"),
|
("(xch r0 r1)", "(xch r0 r1)"),
|
||||||
("(ld r0 r0)", "(ld r0 r0)"),
|
("(ld r0 r0)", "(ld r0 r0)"),
|
||||||
("(ld8 r0 r1)", "(ld8 r0 r1)"),
|
("(ld8 r0 r1)", "(ld8 r0 r1)"),
|
||||||
("(ld16 r0 r1)", "(ld16 r0 r1)"),
|
("(ld16 r0 r1)", "(ld16 r0 r1)"),
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ pub enum ArithOp {
|
|||||||
Clo32 { dst: Wr, src: Rd },
|
Clo32 { dst: Wr, src: Rd },
|
||||||
Clo16 { dst: Wr, src: Rd },
|
Clo16 { dst: Wr, src: Rd },
|
||||||
Clo8 { 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 },
|
Add { dst: Wr, a: Rd, b: Rd },
|
||||||
Sub { 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.update_status(res);
|
||||||
state.write(dst, 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)
|
Ok(eres)
|
||||||
@@ -362,6 +395,9 @@ impl OpTrait for ArithOp {
|
|||||||
ArithOp::Clo32 { dst, src } => to_sexp_1_or_2("clo32", dst, src),
|
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::Clo16 { dst, src } => to_sexp_1_or_2("clo16", dst, src),
|
||||||
ArithOp::Clo8 { dst, src } => to_sexp_1_or_2("clo8", 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 => {
|
_other => {
|
||||||
return Ok(ParseRes::Unknown(args));
|
return Ok(ParseRes::Unknown(args));
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ set -e
|
|||||||
|
|
||||||
cargo build
|
cargo build
|
||||||
|
|
||||||
for file in examples/*
|
for file in examples/*.csn
|
||||||
do
|
do
|
||||||
echo "--- $file ---"
|
echo "--- $file ---"
|
||||||
target/debug/launcher -P "$file"
|
target/debug/launcher -P "$file"
|
||||||
|
|||||||
Reference in New Issue
Block a user