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:
2020-10-11 22:01:12 +02:00
parent 4062ff4d09
commit c953e39b34
11 changed files with 619 additions and 31 deletions
+9
View File
@@ -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 {
+9 -3
View File
@@ -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
+27 -3
View File
@@ -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)?;
+36 -9
View File
@@ -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)"),