]> Witch of Git - jade-rose/blob - toolchain/src/inst/test.rs
Update ISA spec to v0.2.2
[jade-rose] / toolchain / src / inst / test.rs
1 use super::{decode::Decode, encode::Encode, parse, Inst};
2 use proptest::prelude::*;
3 use std::io::Cursor;
4
5 proptest! {
6 #[test]
7 fn roundtrip(inst: Inst) {
8 let mut buf = [0, 0];
9 let mut cursor = Cursor::new(&mut buf[..]);
10 inst.encode(&mut cursor).expect("to encode");
11 cursor.set_position(0);
12 let decoded = Inst::decode(&mut cursor).expect("to decode");
13 prop_assert_eq!(inst, decoded);
14 }
15
16 #[test]
17 fn format_roundtrip(inst: Inst) {
18 let formatted = format!("{}", inst);
19 prop_assert_eq!(parse::parse_inst(&formatted).unwrap(), inst, "formatted as {:?}", formatted);
20 }
21 }
22
23 fn display(buf: &[u8]) -> String {
24 match buf.len() {
25 1 => format!("{:04b}_{:04b}", buf[0] >> 4, buf[0] & 0xf),
26 2 => format!(
27 "{:04b}_{:04b} {:04b}_{:04b}",
28 buf[0] >> 4,
29 buf[0] & 0xf,
30 buf[1] >> 4,
31 buf[1] & 0xf
32 ),
33 n => unreachable!("Shouldn't be instructions of length {}", n),
34 }
35 }
36
37 macro_rules! case {
38 ($txt:expr => !) => {
39 assert!(
40 parse::parse_inst($txt).is_none(),
41 "expect to not parse {:?}",
42 $txt,
43 );
44 };
45 ($txt:expr => $res:expr) => {
46 let mut buf = [0, 0];
47 let mut cursor = Cursor::new(&mut buf[..]);
48 let parsed = parse::parse_inst($txt).expect(&format!("to parse {:?}", $txt));
49 parsed
50 .encode(&mut cursor)
51 .expect(&format!("to encode {:?}", parsed));
52 let pos = cursor.position() as usize;
53 assert_eq!($res, &display(&buf[..pos]), "While parsing {:?}", $txt);
54 };
55 }
56
57 macro_rules! test_parse {
58 ($($txt:expr => $res:tt),* $(,)?) => {
59 $(
60 case!($txt => $res);
61 )*
62 }
63 }
64
65 #[test]
66 fn stop() {
67 test_parse! {
68 "STOP" => "0000_0000",
69 "stop" => "0000_0000",
70 }
71 }
72
73 #[test]
74 fn nope() {
75 test_parse! {
76 "NOPE" => "0000_0001",
77 }
78 }
79
80 #[test]
81 fn prnt() {
82 test_parse! {
83 "PRNT" => "0000_0010",
84 }
85 }
86
87 #[test]
88 fn jump_call() {
89 test_parse! {
90 "CABA" => "0000_0110",
91 "COFA" => "0000_0111",
92 }
93 }
94
95 #[test]
96 fn alu1() {
97 test_parse! {
98 "zero" => "0000_1000",
99 "lsl1" => "0000_1001",
100 "lsr1" => "0000_1010",
101 "asr1" => "0000_1011",
102 "incr" => "0000_1100",
103 "decr" => "0000_1101",
104 "comp" => "0000_1110",
105 "negt" => "0000_1111",
106 }
107 }
108
109 #[test]
110 fn get_set_special() {
111 test_parse! {
112 "GET1" => "0001_0000",
113 "GET2" => "0001_0001",
114 "GETC" => "0001_0010",
115
116 "SET1" => "0001_1000",
117 "SET2" => "0001_1001",
118 "SETC" => "0001_1010",
119 }
120 }
121
122 #[test]
123 fn getr_setr() {
124 test_parse! {
125 "getr r3" => "0010_0011",
126 "GETR r7" => "0010_0111",
127 "GETR r9" => !,
128 "GETRr0" => !,
129
130 "SETR r0" => "0010_1000",
131 "SETR r7" => "0010_1111",
132 }
133 }
134
135 #[test]
136 fn swap() {
137 test_parse! {
138 "swap r0" => "0011_0000",
139 "SWAP r1" => "0011_0001",
140 "Swap\tr2" => "0011_0010",
141 "SWAP\t\tr3" => "0011_0011",
142 "SWAP r4" => "0011_0100",
143 "SWAP r5" => "0011_0101",
144 "SWAP r6" => "0011_0110",
145 "SWAP r7" => "0011_0111",
146 "SWAP r8" => !,
147 "swapr0" => !,
148 "swap 0" => !,
149 "swap g0" => !,
150 "swap" => !,
151 }
152 }
153
154 #[test]
155 fn islt() {
156 test_parse! {
157 "islt r0" => "0011_1000",
158 "islt r7" => "0011_1111",
159 "islt r8" => !,
160 "islt" => !,
161 }
162 }
163
164 #[test]
165 fn alu_r() {
166 test_parse! {
167 "addr r0" => "0100_0000",
168 "addr r4" => "0100_0100",
169 "subr r1" => "0100_1001",
170 "subr r5" => "0100_1101",
171 "andr r2" => "0101_0010",
172 "andr r6" => "0101_0110",
173 "iorr r3" => "0101_1011",
174 "iorr r7" => "0101_1111",
175 "xorr r0" => "0110_0000",
176 "xorr r4" => "0110_0100",
177 "lslr r1" => "0110_1001",
178 "lslr r5" => "0110_1101",
179 "lsrr r2" => "0111_0010",
180 "lsrr r6" => "0111_0110",
181 "asrr r3" => "0111_1011",
182 "asrr r7" => "0111_1111",
183 }
184 }
185
186 #[test]
187 fn ldst() {
188 test_parse! {
189 "ld1u r0" => "1000_0000",
190 "ld1u r3!" => "1001_0011",
191 "ld2u r2!" => "1011_0010",
192 "ld2u r4" => "1010_0100",
193
194 "st1u r1" => "1000_1001",
195 "st1u r7!" => "1001_1111",
196 "st2u r7!" => "1011_1111",
197 "st2u r7" => "1010_1111",
198 }
199 }
200
201 #[test]
202 fn alu_i() {
203 test_parse! {
204 "andi 00" => "1111_0000 0000_0000",
205 "andi 0000" => "1111_0000 0000_0000",
206 "andi 10" => "1111_0000 0000_1010",
207 "andi 255" => "1111_0000 1111_1111",
208 "andi -1" => !,
209 "andi -23" => !,
210 "andi 256" => !,
211
212 "andi 0d00" => "1111_0000 0000_0000",
213 "andi 0D0000" => "1111_0000 0000_0000",
214 "andi 0d10" => "1111_0000 0000_1010",
215 "andi 0D255" => "1111_0000 1111_1111",
216 "andi -0d1" => !,
217 "andi -0d23" => !,
218 "andi 0d256" => !,
219
220 "andi 0x00" => "1111_0000 0000_0000",
221 "andi 0XFF" => "1111_0000 1111_1111",
222 "andi 0xAA" => "1111_0000 1010_1010",
223 "andi 0o177" => "1111_0000 0111_1111",
224 "andi 0O177" => "1111_0000 0111_1111",
225 "andi 0b11010000" => "1111_0000 1101_0000",
226
227 "iori 00" => "1111_0001 0000_0000",
228 "iori 32" => "1111_0001 0010_0000",
229 "iori 01" => "1111_0001 0000_0001",
230 "iori -1" => !,
231
232 "xori 00" => "1111_0010 0000_0000",
233 "xori 07" => "1111_0010 0000_0111",
234 "xori 255" => "1111_0010 1111_1111",
235 "xori 300" => !,
236
237 "addi 0" => "1111_0011 0000_0000",
238 "addi 1" => "1111_0011 0000_0001",
239 "addi 127" => "1111_0011 0111_1111",
240 "addi 128" => !,
241 "addi 250" => !,
242 "addi -1" => "1111_0011 1111_1111",
243 "addi -10" => "1111_0011 1111_0110",
244 "addi -64" => "1111_0011 1100_0000",
245 "addi -65" => !,
246 "addi -100" => !,
247
248 "addi 0x7F" => "1111_0011 0111_1111",
249 "addi 0xFF" => !,
250 }
251 }
252
253 #[test]
254 fn alu_compact() {
255 test_parse! {
256 "roli 0" => "1111_0011 1000_0000",
257 "roli 7" => "1111_0011 1000_0111",
258 "roli -1" => !,
259 "roli 8" => !,
260
261 "lsli 0" => "1111_0011 1000_1000",
262 "lsli 7" => "1111_0011 1000_1111",
263 "lsri 0" => "1111_0011 1001_0000",
264 "lsri 7" => "1111_0011 1001_0111",
265 "asri 0" => "1111_0011 1001_1000",
266 "asri 7" => "1111_0011 1001_1111",
267
268 "clri 0" => "1111_0011 1010_0000",
269 "clri 7" => "1111_0011 1010_0111",
270 "insi 0" => "1111_0011 1010_1000",
271 "insi 7" => "1111_0011 1010_1111",
272 "togi 0" => "1111_0011 1011_0000",
273 "togi 7" => "1111_0011 1011_0111",
274 "exti 0" => "1111_0011 1011_1000",
275 "exti 7" => "1111_0011 1011_1111",
276 }
277 }
278
279 #[test]
280 fn imm_jumps() {
281 test_parse! {
282 "bezi 0" => "1111_0100 0000_0000",
283 "bezi 1" => "1111_0100 0000_0001",
284 "bezi -1" => "1111_0100 1111_1111",
285 "bezi -128" => "1111_0100 1000_0000",
286 "bezi 127" => "1111_0100 0111_1111",
287 "bezi -129" => !,
288 "bezi 128" => !,
289
290 "jofi 0" => "1111_0101 0000_0000",
291 "jofi 1" => "1111_0101 0000_0001",
292 "jofi -1" => "1111_0101 1111_1111",
293
294 "cabi 0" => "1111_0110 0000_0000",
295 "cabi 1" => "1111_0110 0000_0001",
296 "cabi -1" => !,
297
298 "cofi 0" => "1111_0111 0000_0000",
299 "cofi 1" => "1111_0111 0000_0001",
300 "cofi -1" => "1111_0111 1111_1111",
301 }
302 }
303
304 #[test]
305 fn geti() {
306 test_parse! {
307 "geti 0" => "1111_1110 0000_0000",
308 "geti 1" => "1111_1110 0000_0001",
309 "geti 0xFF" => "1111_1110 1111_1111",
310 "geti 0x100" => !,
311 "geti -1" => "1111_1110 1111_1111",
312 "geti -128" => "1111_1110 1000_0000",
313 "geti -129" => !,
314 }
315 }