forked from MightyPork/crsn
add rcmp instr, add rot13 example
This commit is contained in:
@@ -341,9 +341,13 @@ Many instructions have two forms:
|
|||||||
; Test properties of a value - zero, positive, negative
|
; Test properties of a value - zero, positive, negative
|
||||||
(tst SRC)
|
(tst SRC)
|
||||||
|
|
||||||
; Compare two values
|
; Compare two values. Sets EQ, LT, GT, and Z, POS and NEG if the values equal
|
||||||
(cmp Rd Rd)
|
(cmp Rd Rd)
|
||||||
|
|
||||||
|
; Check if a value is in a range (inclusive).
|
||||||
|
; Sets the EQ, LT and GT flags. Also sets Z, POS and NEG based on the value.
|
||||||
|
(rcmp Rd:val Rd:start Rd:end)
|
||||||
|
|
||||||
; Add A+B
|
; Add A+B
|
||||||
(add Wr Rd Rd)
|
(add Wr Rd Rd)
|
||||||
(add RW Rd)
|
(add RW Rd)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crsn::asm::data::{Rd, Wr};
|
|||||||
pub enum ArithOp {
|
pub enum ArithOp {
|
||||||
Test { a: Rd },
|
Test { a: Rd },
|
||||||
Compare { a: Rd, b: Rd },
|
Compare { a: Rd, b: Rd },
|
||||||
|
RangeTest { val: Rd, a: Rd, b: 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 },
|
||||||
|
|||||||
@@ -34,6 +34,16 @@ impl OpTrait for ArithOp {
|
|||||||
state.update_status(x);
|
state.update_status(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ArithOp::RangeTest { val, a, b } => {
|
||||||
|
state.clear_status();
|
||||||
|
let val = state.read(*val)?;
|
||||||
|
let a = state.read(*a)?;
|
||||||
|
let b = state.read(*b)?;
|
||||||
|
state.set_flag(Cond::Equal, val >= a && val <= b);
|
||||||
|
state.set_flag(Cond::Lower, val < a);
|
||||||
|
state.set_flag(Cond::Greater, val > b);
|
||||||
|
state.update_status(val);
|
||||||
|
}
|
||||||
ArithOp::Add { dst, a, b } => {
|
ArithOp::Add { dst, a, b } => {
|
||||||
state.clear_status();
|
state.clear_status();
|
||||||
let x = state.read(*a)?;
|
let x = state.read(*a)?;
|
||||||
@@ -201,6 +211,7 @@ impl OpTrait for ArithOp {
|
|||||||
ArithOp::Add { dst, a, b } => to_sexp_2_or_3("add", dst, a, b),
|
ArithOp::Add { dst, a, b } => to_sexp_2_or_3("add", dst, a, b),
|
||||||
ArithOp::Test { a } => sexp::list(&[A("test"), A(a)]),
|
ArithOp::Test { a } => sexp::list(&[A("test"), A(a)]),
|
||||||
ArithOp::Compare { a, b } => sexp::list(&[A("cmp"), A(a), A(b)]),
|
ArithOp::Compare { a, b } => sexp::list(&[A("cmp"), A(a), A(b)]),
|
||||||
|
ArithOp::RangeTest { val, a: start, b: end } => sexp::list(&[A("rcmp"), A(val), A(start), A(end)]),
|
||||||
ArithOp::Sub { dst, a, b } => to_sexp_2_or_3("sub", dst, a, b),
|
ArithOp::Sub { dst, a, b } => to_sexp_2_or_3("sub", dst, a, b),
|
||||||
ArithOp::Mul { dst, a, b } => to_sexp_2_or_3("mul", dst, a, b),
|
ArithOp::Mul { dst, a, b } => to_sexp_2_or_3("mul", dst, a, b),
|
||||||
ArithOp::Div { dst, rem, a, div } => {
|
ArithOp::Div { dst, rem, a, div } => {
|
||||||
|
|||||||
@@ -16,6 +16,14 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"rcmp" => {
|
||||||
|
ArithOp::RangeTest {
|
||||||
|
val: args.next_rd()?,
|
||||||
|
a: args.next_rd()?,
|
||||||
|
b: args.next_rd()?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
"tst" => {
|
"tst" => {
|
||||||
let arg = args.next_rd()?;
|
let arg = args.next_rd()?;
|
||||||
ArithOp::Test { a: arg }
|
ArithOp::Test { a: arg }
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
(
|
||||||
|
(:again)
|
||||||
|
(ld r0 @stdin (inval? (halt)))
|
||||||
|
(rcmp r0 'A' 'Z'
|
||||||
|
(eq? (ld r1 'A'))
|
||||||
|
(ne? (rcmp r0 'a' 'z'
|
||||||
|
(eq? (ld r1 'a'))
|
||||||
|
(ne? (j :print)))))
|
||||||
|
(sub r0 r1)
|
||||||
|
(add r0 13)
|
||||||
|
(mod r0 26)
|
||||||
|
(add r0 r1)
|
||||||
|
(:print)
|
||||||
|
(ld @stdout r0)
|
||||||
|
(j :again)
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user