]> Witch of Git - jade-mouse/blob - toolchain/src/inst.rs
Implement instruction execution
[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 }
157
158 impl Size {
159 pub fn bytes(&self) -> u16 {
160 match *self {
161 Size::Byte => 1,
162 Size::Word => 2,
163 }
164 }
165 }
166
167 impl U4 {
168 pub fn get(&self) -> usize {
169 self.0 as usize
170 }
171 }
172
173 impl U7 {
174 pub fn get(&self) -> u16 {
175 self.0 as u16
176 }
177 }
178
179 impl I5 {
180 pub fn get(&self) -> i8 {
181 self.0
182 }
183 }
184
185 impl Into<i32> for I5 {
186 fn into(self) -> i32 {
187 self.0 as i32
188 }
189 }
190
191 impl Into<i32> for I7 {
192 fn into(self) -> i32 {
193 self.0 as i32
194 }
195 }
196
197 /*
198 pub struct I5(#[cfg_attr(test, proptest(strategy = "-16..=15i8"))] i8);
199 */