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
|
||||
(tst SRC)
|
||||
|
||||
; Compare two values
|
||||
; Compare two values. Sets EQ, LT, GT, and Z, POS and NEG if the values equal
|
||||
(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 Wr Rd Rd)
|
||||
(add RW Rd)
|
||||
|
||||
@@ -5,6 +5,7 @@ use crsn::asm::data::{Rd, Wr};
|
||||
pub enum ArithOp {
|
||||
Test { a: Rd },
|
||||
Compare { a: Rd, b: Rd },
|
||||
RangeTest { val: Rd, a: Rd, b: Rd },
|
||||
|
||||
Add { 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);
|
||||
}
|
||||
}
|
||||
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 } => {
|
||||
state.clear_status();
|
||||
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::Test { a } => sexp::list(&[A("test"), A(a)]),
|
||||
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::Mul { dst, a, b } => to_sexp_2_or_3("mul", dst, a, b),
|
||||
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" => {
|
||||
let arg = args.next_rd()?;
|
||||
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