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

@ -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"

Loading…
Cancel
Save