forked from MightyPork/crsn
Add ld{32,16,8},sw{32,16,8},clz{,32,16,8},clo{,32,16,8},rng,rev,rbit; rename swap->xch
This commit is contained in:
@@ -15,6 +15,15 @@ impl Rd {
|
||||
pub const fn immediate(val: Value) -> Rd {
|
||||
Rd(RdData::Immediate(val))
|
||||
}
|
||||
|
||||
pub fn is_immediate_equal(self, other: Value) -> bool {
|
||||
match self.0 {
|
||||
RdData::Immediate(val) => {
|
||||
val == other
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Rd> for Rd {
|
||||
|
||||
@@ -71,11 +71,17 @@ pub enum BuiltinOp {
|
||||
/// The object is released and the handle becomes invalid.
|
||||
Delete(RdObj),
|
||||
/// Move a value
|
||||
MoveValue { dst: Wr, src: Rd },
|
||||
Move { dst: Wr, src: Rd },
|
||||
/// Move lower 32 bits
|
||||
Move32 { dst: RdWr, src: Rd },
|
||||
/// Move lower 16 bits
|
||||
Move16 { dst: RdWr, src: Rd },
|
||||
/// Move lower 8 bits
|
||||
Move8 { dst: RdWr, src: Rd },
|
||||
/// Move N values
|
||||
MoveMultipleValues { dst: Wr, src: Rd, count: Rd },
|
||||
MoveMultiple { dst: Wr, src: Rd, count: Rd },
|
||||
/// Swap two registers
|
||||
SwapValues { a: RdWr, b: RdWr },
|
||||
Exchange { a: RdWr, b: RdWr },
|
||||
/// Store runtime status to a register
|
||||
StoreFlags { dst: Wr },
|
||||
/// Load runtime status from a register
|
||||
|
||||
@@ -103,13 +103,13 @@ impl OpTrait for BuiltinOp {
|
||||
let pc = state.get_pc();
|
||||
program.validate_jump(pc, Addr((pc.0 as i64 + res.advance) as u64))?;
|
||||
}
|
||||
BuiltinOp::MoveValue { dst, src } => {
|
||||
BuiltinOp::Move { dst, src } => {
|
||||
state.clear_status();
|
||||
let val = state.read(src)?;
|
||||
state.update_status(val);
|
||||
state.write(dst, val)?;
|
||||
}
|
||||
BuiltinOp::MoveMultipleValues { dst, src, count } => {
|
||||
BuiltinOp::MoveMultiple { dst, src, count } => {
|
||||
state.clear_status();
|
||||
let mut count = state.read(count)?;
|
||||
let mut last = 0;
|
||||
@@ -120,7 +120,31 @@ impl OpTrait for BuiltinOp {
|
||||
}
|
||||
state.update_status(last);
|
||||
}
|
||||
BuiltinOp::SwapValues { a, b } => {
|
||||
BuiltinOp::Move32 { dst, src } => {
|
||||
state.clear_status();
|
||||
let new = state.read(src)?;
|
||||
let old = state.read(dst)?;
|
||||
let val = (old & !0xFFFFFFFF) | (new & 0xFFFFFFFF);
|
||||
state.update_status(val);
|
||||
state.write(dst, val)?;
|
||||
}
|
||||
BuiltinOp::Move16 { dst, src } => {
|
||||
state.clear_status();
|
||||
let new = state.read(src)?;
|
||||
let old = state.read(dst)?;
|
||||
let val = (old & !0xFFFF) | (new & 0xFFFF);
|
||||
state.update_status(val);
|
||||
state.write(dst, val)?;
|
||||
}
|
||||
BuiltinOp::Move8 { dst, src } => {
|
||||
state.clear_status();
|
||||
let new = state.read(src)?;
|
||||
let old = state.read(dst)?;
|
||||
let val = (old & !0xFF) | (new & 0xFF);
|
||||
state.update_status(val);
|
||||
state.write(dst, val)?;
|
||||
}
|
||||
BuiltinOp::Exchange { a, b } => {
|
||||
let aa = state.read(a)?;
|
||||
let bb = state.read(b)?;
|
||||
state.write(a, bb)?;
|
||||
|
||||
@@ -183,22 +183,43 @@ pub(crate) fn parse_op<'a>(op_pos: &SourcePosition, keyword: &str, mut args: Tok
|
||||
}
|
||||
|
||||
"ld" => {
|
||||
BuiltinOp::MoveValue {
|
||||
BuiltinOp::Move {
|
||||
dst: args.next_wr()?,
|
||||
src: args.next_rd()?,
|
||||
}
|
||||
}
|
||||
|
||||
"ld32" => {
|
||||
BuiltinOp::Move32 {
|
||||
dst: args.next_rdwr()?,
|
||||
src: args.next_rd()?,
|
||||
}
|
||||
}
|
||||
|
||||
"ld16" => {
|
||||
BuiltinOp::Move16 {
|
||||
dst: args.next_rdwr()?,
|
||||
src: args.next_rd()?,
|
||||
}
|
||||
}
|
||||
|
||||
"ld8" => {
|
||||
BuiltinOp::Move8 {
|
||||
dst: args.next_rdwr()?,
|
||||
src: args.next_rd()?,
|
||||
}
|
||||
}
|
||||
|
||||
"ldn" => {
|
||||
BuiltinOp::MoveMultipleValues {
|
||||
BuiltinOp::MoveMultiple {
|
||||
dst: args.next_wr()?,
|
||||
src: args.next_rd()?,
|
||||
count: args.next_rd()?,
|
||||
}
|
||||
}
|
||||
|
||||
"swap" => {
|
||||
BuiltinOp::SwapValues {
|
||||
"xch" => {
|
||||
BuiltinOp::Exchange {
|
||||
a: args.next_rdwr()?,
|
||||
b: args.next_rdwr()?,
|
||||
}
|
||||
@@ -316,11 +337,14 @@ pub(crate) fn to_sexp(op: &BuiltinOp) -> Sexp {
|
||||
}
|
||||
}
|
||||
BuiltinOp::Delete(obj) => sexp::list(&[A("del"), A(obj)]),
|
||||
BuiltinOp::MoveValue { dst, src } => sexp::list(&[A("ld"), A(dst), A(src)]),
|
||||
BuiltinOp::MoveMultipleValues { dst, src, count } => sexp::list(&[A("ldn"), A(dst), A(src), A(count)]),
|
||||
BuiltinOp::SwapValues { a, b } => sexp::list(&[A("swap"), A(a), A(b)]),
|
||||
BuiltinOp::Move { dst, src } => sexp::list(&[A("ld"), A(dst), A(src)]),
|
||||
BuiltinOp::Move32 { dst, src } => sexp::list(&[A("ld32"), A(dst), A(src)]),
|
||||
BuiltinOp::Move16 { dst, src } => sexp::list(&[A("ld16"), A(dst), A(src)]),
|
||||
BuiltinOp::Move8 { dst, src } => sexp::list(&[A("ld8"), A(dst), A(src)]),
|
||||
BuiltinOp::MoveMultiple { dst, src, count } => sexp::list(&[A("ldn"), A(dst), A(src), A(count)]),
|
||||
BuiltinOp::Exchange { a, b } => sexp::list(&[A("xch"), A(a), A(b)]),
|
||||
BuiltinOp::StoreFlags { dst } => sexp::list(&[A("stf"), A(dst)]),
|
||||
BuiltinOp::LoadFlags { src } => sexp::list(&[A("ldf"), A(src)])
|
||||
BuiltinOp::LoadFlags { src } => sexp::list(&[A("ldf"), A(src)]),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,8 +411,11 @@ mod test {
|
||||
("(fault)", "(fault)"),
|
||||
("(fault kur*a)", "(fault kur*a)"),
|
||||
("(fault \"do pr*ele\")", "(fault \"do pr*ele\")"),
|
||||
("(swap r0 r1)", "(swap r0 r1)"),
|
||||
("(xchxch r0 r1)", "(xch r0 r1)"),
|
||||
("(ld r0 r0)", "(ld r0 r0)"),
|
||||
("(ld8 r0 r1)", "(ld8 r0 r1)"),
|
||||
("(ld16 r0 r1)", "(ld16 r0 r1)"),
|
||||
("(ld32 r0 r1)", "(ld32 r0 r1)"),
|
||||
("(ld r0 156)", "(ld r0 156)"),
|
||||
("(ld _ -32767)", "(ld _ -32767)"),
|
||||
("(ldn _ @r0 7)", "(ldn _ @r0 7)"),
|
||||
|
||||
Reference in New Issue
Block a user