From 01ab4e7e1f5c59f0105f454f64a896fc02a83d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Thu, 15 Oct 2020 00:41:07 +0200 Subject: [PATCH] add sign extend commands --- README.md | 12 ++++++++ crsn/src/builtin/parse.rs | 2 +- crsn_arith/src/defs.rs | 3 ++ crsn_arith/src/exec.rs | 36 ++++++++++++++++++++++ crsn_arith/src/parse.rs | 63 +++++++++++++++++++++++++++++++++++++++ test_examples.sh | 2 +- 6 files changed, 116 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0c14bfb..ab6bbb0 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/crsn/src/builtin/parse.rs b/crsn/src/builtin/parse.rs index de5bd44..779fde4 100644 --- a/crsn/src/builtin/parse.rs +++ b/crsn/src/builtin/parse.rs @@ -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)"), diff --git a/crsn_arith/src/defs.rs b/crsn_arith/src/defs.rs index a9470db..562395e 100644 --- a/crsn_arith/src/defs.rs +++ b/crsn_arith/src/defs.rs @@ -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 }, diff --git a/crsn_arith/src/exec.rs b/crsn_arith/src/exec.rs index e9bd165..ab2b4f1 100644 --- a/crsn_arith/src/exec.rs +++ b/crsn_arith/src/exec.rs @@ -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), } } } diff --git a/crsn_arith/src/parse.rs b/crsn_arith/src/parse.rs index 5a26bf6..67b42e6 100644 --- a/crsn_arith/src/parse.rs +++ b/crsn_arith/src/parse.rs @@ -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)); } diff --git a/test_examples.sh b/test_examples.sh index d354029..cdc0960 100755 --- a/test_examples.sh +++ b/test_examples.sh @@ -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"