]> Witch of Git - jade-rose/blob - toolchain/src/inst/test.rs
Add instruction formatter
[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 trap() {
67 test_parse! {
68 "TRAP" => "0000_0000",
69 "trap" => "0000_0000",
70 }
71 }
72
73 #[test]
74 fn jump_call() {
75 test_parse! {
76 "JABS" => "0000_0100",
77 "CABS" => "0000_0101",
78 "JOFF" => "0000_0110",
79 "COFF" => "0000_0111",
80 }
81 }
82
83 #[test]
84 fn swap() {
85 test_parse! {
86 "swap r0" => "0000_1000",
87 "SWAP r1" => "0000_1001",
88 "Swap\tr2" => "0000_1010",
89 "SWAP\t\tr3" => "0000_1011",
90 "SWAP r4" => "0000_1100",
91 "SWAP r5" => "0000_1101",
92 "SWAP r6" => "0000_1110",
93 "SWAP r7" => "0000_1111",
94 "SWAP r8" => !,
95 "swapr0" => !,
96 "swap 0" => !,
97 "swap g0" => !,
98 "swap" => !,
99 }
100 }
101
102 #[test]
103 fn getr_setr() {
104 test_parse! {
105 "getr r3" => "0001_0011",
106 "GETR r7" => "0001_0111",
107 "GETR r9" => !,
108
109 "SETR r0" => "0001_1000",
110 "SETR r7" => "0001_1111",
111 }
112 }
113
114 #[test]
115 fn get_set_special() {
116 test_parse! {
117 "GET1" => "0010_0000",
118 "GET2" => "0010_0001",
119 "GETC" => "0010_0010",
120
121 "SET1" => "0010_1000",
122 "SET2" => "0010_1001",
123 "SETC" => "0010_1010",
124 }
125 }
126
127 #[test]
128 fn alu1() {
129 test_parse! {
130 "zero" => "0011_0000",
131 "lsl1" => "0011_0001",
132 "lsr1" => "0011_0010",
133 "asr1" => "0011_0011",
134 "incr" => "0011_0100",
135 "decr" => "0011_0101",
136 "comp" => "0011_0110",
137 "negt" => "0011_0111",
138 }
139 }
140
141 #[test]
142 fn islt() {
143 test_parse! {
144 "islt r0" => "0011_1000",
145 "islt r7" => "0011_1111",
146 "islt r8" => !,
147 "islt" => !,
148 }
149 }
150
151 #[test]
152 fn alu_r() {
153 test_parse! {
154 "addr r0" => "0100_0000",
155 "addr r4" => "0100_0100",
156 "subr r1" => "0100_1001",
157 "subr r5" => "0100_1101",
158 "andr r2" => "0101_0010",
159 "andr r6" => "0101_0110",
160 "iorr r3" => "0101_1011",
161 "iorr r7" => "0101_1111",
162 "xorr r0" => "0110_0000",
163 "xorr r4" => "0110_0100",
164 "lslr r1" => "0110_1001",
165 "lslr r5" => "0110_1101",
166 "lsrr r2" => "0111_0010",
167 "lsrr r6" => "0111_0110",
168 "asrr r3" => "0111_1011",
169 "asrr r7" => "0111_1111",
170 }
171 }
172
173 #[test]
174 fn ldst() {
175 test_parse! {
176 "ld1u r0" => "1000_0000",
177 "ld1u r3!" => "1001_0011",
178 "ld2u r2!" => "1011_0010",
179 "ld2u r4" => "1010_0100",
180
181 "st1u r1" => "1000_1001",
182 "st1u r7!" => "1001_1111",
183 "st2u r7!" => "1011_1111",
184 "st2u r7" => "1010_1111",
185 }
186 }
187
188 #[test]
189 fn alu_i() {
190 test_parse! {
191 "andi #00" => "1111_0000 0000_0000",
192 "andi #0000" => "1111_0000 0000_0000",
193 "andi #10" => "1111_0000 0000_1010",
194 "andi #255" => "1111_0000 1111_1111",
195 "andi #-1" => !,
196 "andi #-23" => !,
197 "andi #256" => !,
198
199 "andi #d00" => "1111_0000 0000_0000",
200 "andi #D0000" => "1111_0000 0000_0000",
201 "andi #d10" => "1111_0000 0000_1010",
202 "andi #D255" => "1111_0000 1111_1111",
203 "andi #d-1" => !,
204 "andi #d-23" => !,
205 "andi #d256" => !,
206
207 "andi #x00" => "1111_0000 0000_0000",
208 "andi #XFF" => "1111_0000 1111_1111",
209 "andi #xAA" => "1111_0000 1010_1010",
210 "andi #o177" => "1111_0000 0111_1111",
211 "andi #O177" => "1111_0000 0111_1111",
212 "andi #b11010000" => "1111_0000 1101_0000",
213
214 "iori #00" => "1111_0001 0000_0000",
215 "iori #32" => "1111_0001 0010_0000",
216 "iori #01" => "1111_0001 0000_0001",
217 "iori #-1" => !,
218
219 "xori #00" => "1111_0010 0000_0000",
220 "xori #07" => "1111_0010 0000_0111",
221 "xori #255" => "1111_0010 1111_1111",
222 "xori #300" => !,
223
224 "addi #0" => "1111_0011 0000_0000",
225 "addi #1" => "1111_0011 0000_0001",
226 "addi #127" => "1111_0011 0111_1111",
227 "addi #128" => !,
228 "addi #250" => !,
229 "addi #-1" => "1111_0011 1111_1111",
230 "addi #-10" => "1111_0011 1111_0110",
231 "addi #-64" => "1111_0011 1100_0000",
232 "addi #-65" => !,
233 "addi #-100" => !,
234
235 "addi #x7F" => "1111_0011 0111_1111",
236 "addi #xFF" => !,
237 }
238 }
239
240 #[test]
241 fn alu_compact() {
242 test_parse! {
243 "roli #0" => "1111_0011 1000_0000",
244 "roli #7" => "1111_0011 1000_0111",
245 "roli #-1" => !,
246 "roli #8" => !,
247
248 "lsli #0" => "1111_0011 1000_1000",
249 "lsli #7" => "1111_0011 1000_1111",
250 "lsri #0" => "1111_0011 1001_0000",
251 "lsri #7" => "1111_0011 1001_0111",
252 "asri #0" => "1111_0011 1001_1000",
253 "asri #7" => "1111_0011 1001_1111",
254
255 "clri #0" => "1111_0011 1010_0000",
256 "clri #7" => "1111_0011 1010_0111",
257 "seti #0" => "1111_0011 1010_1000",
258 "seti #7" => "1111_0011 1010_1111",
259 "togi #0" => "1111_0011 1011_0000",
260 "togi #7" => "1111_0011 1011_0111",
261 "exti #0" => "1111_0011 1011_1000",
262 "exti #7" => "1111_0011 1011_1111",
263 }
264 }
265
266 #[test]
267 fn branch() {
268 test_parse! {
269 "bezi #0" => "1111_0100 0000_0000",
270 "bezi #1" => "1111_0100 0000_0001",
271 "bezi #-1" => "1111_0100 1111_1111",
272 "bezi #-128" => "1111_0100 1000_0000",
273 "bezi #127" => "1111_0100 0111_1111",
274 "bezi #-129" => !,
275 "bezi #128" => !,
276
277 "jofi #0" => "1111_0110 0000_0000",
278 "jofi #1" => "1111_0110 0000_0001",
279 "jofi #-1" => "1111_0110 1111_1111",
280
281 "cofi #0" => "1111_0111 0000_0000",
282 "cofi #1" => "1111_0111 0000_0001",
283 "cofi #-1" => "1111_0111 1111_1111",
284 }
285 }