add sign extend commands

pull/21/head
Ondřej Hruška 4 years ago
parent 3b9e89674c
commit 01ab4e7e1f
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 12
      README.md
  2. 2
      crsn/src/builtin/parse.rs
  3. 3
      crsn_arith/src/defs.rs
  4. 36
      crsn_arith/src/exec.rs
  5. 63
      crsn_arith/src/parse.rs
  6. 2
      test_examples.sh

@ -469,6 +469,18 @@ Many instructions have two forms:
(clo8 Wr Rd)
(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 Wr Rd Rd)
(and RW Rd)

@ -411,7 +411,7 @@ mod test {
("(fault)", "(fault)"),
("(fault kur*a)", "(fault kur*a)"),
("(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)"),
("(ld8 r0 r1)", "(ld8 r0 r1)"),
("(ld16 r0 r1)", "(ld16 r0 r1)"),

@ -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));
}

@ -4,7 +4,7 @@ set -e
cargo build
for file in examples/*
for file in examples/*.csn
do
echo "--- $file ---"
target/debug/launcher -P "$file"

Loading…
Cancel
Save