]> Witch of Git - jade-mouse/blob - toolchain/src/inst.rs
Implement instruction decoder
[jade-mouse] / toolchain / src / inst.rs
1 pub mod decode;
2 pub mod encode;
3 #[cfg(test)]
4 mod test;
5 #[cfg(test)]
6 use proptest_derive::Arbitrary;
7
8 pub use self::{decode::Decode, encode::Encode};
9
10 use std::cmp::PartialEq;
11
12 #[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
13 #[cfg_attr(test, derive(Arbitrary))]
14 #[repr(u8)]
15 pub enum Reg {
16 R0,
17 R1,
18 R2,
19 R3,
20 }
21
22 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
23 #[cfg_attr(test, derive(Arbitrary))]
24 #[repr(u8)]
25 pub enum LdSt {
26 Ld,
27 St,
28 }
29
30 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
31 #[cfg_attr(test, derive(Arbitrary))]
32 #[repr(u8)]
33 pub enum Op1 {
34 Inc,
35 Dec,
36 Neg,
37 Compl,
38 }
39
40 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
41 #[cfg_attr(test, derive(Arbitrary))]
42 #[repr(u8)]
43 pub enum OpC {
44 Lsl,
45 Lsr,
46 Asr,
47 Rol,
48 Clr,
49 Set,
50 Tog,
51 Ext,
52 }
53
54 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
55 #[cfg_attr(test, derive(Arbitrary))]
56 #[repr(u8)]
57 pub enum Op2 {
58 Add = 2,
59 Sub,
60 AddPc,
61 And,
62 Or,
63 Xor,
64 }
65
66 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
67 #[cfg_attr(test, derive(Arbitrary))]
68 pub struct U4(#[cfg_attr(test, proptest(strategy = "0..=15u8"))] u8);
69 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
70 #[cfg_attr(test, derive(Arbitrary))]
71 pub struct I5(#[cfg_attr(test, proptest(strategy = "-16..=15i8"))] i8);
72 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
73 #[cfg_attr(test, derive(Arbitrary))]
74 pub struct I7(#[cfg_attr(test, proptest(strategy = "-64..=63i8"))] i8);
75 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
76 #[cfg_attr(test, derive(Arbitrary))]
77 pub struct U7(#[cfg_attr(test, proptest(strategy = "0..=127u8"))] u8);
78
79 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
80 #[cfg_attr(test, derive(Arbitrary))]
81 #[repr(u8)]
82 pub enum Size {
83 Byte,
84 Word,
85 }
86
87 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
88 #[cfg_attr(test, derive(Arbitrary))]
89 #[repr(u8)]
90 pub enum Half {
91 Low,
92 High,
93 }
94
95 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
96 #[cfg_attr(test, derive(Arbitrary))]
97 pub enum Addr {
98 Fixed(U7),
99 Reg(Reg),
100 Extended {
101 base: Reg,
102 offset: I5,
103 stack: bool,
104 size: Size,
105 },
106 }
107
108 #[derive(Clone, Copy, Debug, Eq)]
109 #[cfg_attr(test, derive(Arbitrary))]
110 pub enum Cond {
111 #[cfg_attr(test, proptest(strategy = "test::regpair(Cond::Eql)"))]
112 Eql(Reg, Reg),
113 #[cfg_attr(test, proptest(strategy = "test::regpair(Cond::Neq)"))]
114 Neq(Reg, Reg),
115 #[cfg_attr(test, proptest(strategy = "test::regpair(Cond::Test)"))]
116 Test(Reg, Reg),
117 #[cfg_attr(test, proptest(strategy = "test::regpair(Cond::TestNot)"))]
118 TestNot(Reg, Reg),
119 #[cfg_attr(test, proptest(strategy = "test::regpair(Cond::Lt)"))]
120 Lt(Reg, Reg),
121 #[cfg_attr(test, proptest(strategy = "test::regpair(Cond::Ult)"))]
122 Ult(Reg, Reg),
123 }
124
125 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
126 #[cfg_attr(test, derive(Arbitrary))]
127 pub enum Inst {
128 Halt,
129 Nope,
130 Alu2(Reg, Op2, Reg),
131 Jalr(Reg),
132 #[cfg_attr(test, proptest(strategy = "test::regpair(Inst::Move)"))]
133 Move(Reg, Reg),
134 Alu1(Reg, Op1),
135 Mem(LdSt, Reg, Addr),
136 Branch(Cond, I7),
137 JumpI(i8),
138 AddI(Reg, i8),
139 AluCompact(Reg, OpC, U4),
140 LdImm(Half, Reg, u8),
141 }
142
143 impl PartialEq for Cond {
144 fn eq(&self, other: &Cond) -> bool {
145 use Cond::*;
146 match (self, other) {
147 (Eql(a1, b1), Eql(a2, b2)) => (a1, b1) == (a2, b2) || (a1, b1) == (b2, a2),
148 (Neq(a1, b1), Neq(a2, b2)) => (a1, b1) == (a2, b2) || (a1, b1) == (b2, a2),
149 (Test(a1, b1), Test(a2, b2)) => (a1, b1) == (a2, b2) || (a1, b1) == (b2, a2),
150 (TestNot(a1, b1), TestNot(a2, b2)) => (a1, b1) == (a2, b2) || (a1, b1) == (b2, a2),
151 (Lt(a1, b1), Lt(a2, b2)) => (a1, b1) == (a2, b2),
152 (Ult(a1, b1), Ult(a2, b2)) => (a1, b1) == (a2, b2),
153 _ => false,
154 }
155 }
156 }