]> Witch of Git - jade-rose/blob - toolchain/src/inst/encode.rs
Add decoding with proptest round-trip test
[jade-rose] / toolchain / src / inst / encode.rs
1 use super::{AluI, Data, Inst, Reg, Special, Target, U3};
2 use std::io::{self, Write};
3
4 pub trait Encode {
5 fn encode(&self, writer: &mut impl Write) -> io::Result<()>;
6 }
7
8 fn reg(Reg(U3(x)): Reg) -> u8 {
9 x
10 }
11
12 fn sp(s: Special) -> u8 {
13 match s {
14 Special::Data(Data::D1) => 0b00,
15 Special::Data(Data::D2) => 0b01,
16 Special::Code => 0b10,
17 }
18 }
19
20 impl Encode for Inst {
21 fn encode(&self, writer: &mut impl Write) -> io::Result<()> {
22 match *self {
23 Inst::Trap => writer.write(&[0x00])?,
24 Inst::Jump(Target::Abs) => writer.write(&[0x04])?,
25 Inst::Call(Target::Abs) => writer.write(&[0x05])?,
26 Inst::Jump(Target::Off) => writer.write(&[0x06])?,
27 Inst::Call(Target::Off) => writer.write(&[0x07])?,
28 Inst::Swap(r) => writer.write(&[0x08 | reg(r)])?,
29 Inst::GetR(r) => writer.write(&[0x10 | reg(r)])?,
30 Inst::SetR(r) => writer.write(&[0x18 | reg(r)])?,
31 Inst::Get(s) => writer.write(&[0x20 | sp(s)])?,
32 Inst::Set(s) => writer.write(&[0x28 | sp(s)])?,
33 Inst::Alu1(op) => writer.write(&[0x30 | op as u8])?,
34 Inst::IsLt(r) => writer.write(&[0x38 | reg(r)])?,
35 Inst::AluR(op, r) => writer.write(&[0x40 | (op as u8) << 3 | reg(r)])?,
36 Inst::LdD(d, r, inc) => {
37 writer.write(&[0x80 | (d as u8) << 5 | (inc as u8) << 4 | reg(r)])?
38 }
39 Inst::StD(d, r, inc) => {
40 writer.write(&[0x88 | (d as u8) << 5 | (inc as u8) << 4 | reg(r)])?
41 }
42 Inst::AluI(alu) => match alu {
43 AluI::And(imm) => writer.write(&[0xf0, imm])?,
44 AluI::Ior(imm) => writer.write(&[0xf1, imm])?,
45 AluI::Xor(imm) => writer.write(&[0xf2, imm])?,
46 AluI::Add(imm) => writer.write(&[0xf3, imm.0 as u8])?,
47 AluI::Compact(op, imm) => writer.write(&[0xf3, 0x80 | (op as u8) << 3 | imm.0])?,
48 },
49 Inst::BEzI(off) => writer.write(&[0xf4, off as u8])?,
50 Inst::Jump(Target::OffImm(off)) => writer.write(&[0xf6, off as u8])?,
51 Inst::Call(Target::OffImm(off)) => writer.write(&[0xf7, off as u8])?,
52 };
53 Ok(())
54 }
55 }