]> Witch of Git - jade-rose/blob - toolchain/src/inst/test.rs
Add parser and encoder tests, fix a parser bug
[jade-rose] / toolchain / src / inst / test.rs
1 use super::{parse, encode::Encode};
2 use std::io::Cursor;
3
4 fn display(buf: &[u8]) -> String {
5 match buf.len() {
6 1 => format!("{:04b}_{:04b}", buf[0] >> 4, buf[0] & 0xf),
7 2 => format!("{:04b}_{:04b} {:04b}_{:04b}", buf[0] >> 4, buf[0] & 0xf, buf[1] >> 4, buf[1] & 0xf),
8 n => unreachable!("Shouldn't be instructions of length {}", n),
9 }
10 }
11
12 macro_rules! case {
13 ($txt:expr => !) => {
14 assert!(
15 parse::parse_inst($txt).is_none(),
16 "expect to not parse {:?}",
17 $txt,
18 );
19 };
20 ($txt:expr => $res:expr) => {
21 let mut buf = [0, 0];
22 let mut cursor = Cursor::new(&mut buf[..]);
23 let parsed = parse::parse_inst($txt).expect(&format!("to parse {:?}", $txt));
24 parsed.encode(&mut cursor).expect(&format!("to encode {:?}", parsed));
25 let pos = cursor.position() as usize;
26 assert_eq!($res, &display(&buf[..pos]), "While parsing {:?}", $txt);
27 };
28 }
29
30 macro_rules! test_parse {
31 ($($txt:expr => $res:tt),* $(,)?) => {
32 $(
33 case!($txt => $res);
34 )*
35 }
36 }
37
38 #[test]
39 fn trap() {
40 test_parse! {
41 "TRAP" => "0000_0000",
42 "trap" => "0000_0000",
43 }
44 }
45
46 #[test]
47 fn jump_call() {
48 test_parse! {
49 "JABS" => "0000_0100",
50 "CABS" => "0000_0101",
51 "JOFF" => "0000_0110",
52 "COFF" => "0000_0111",
53 }
54 }
55
56 #[test]
57 fn swap() {
58 test_parse! {
59 "swap r0" => "0000_1000",
60 "SWAP r1" => "0000_1001",
61 "Swap\tr2" => "0000_1010",
62 "SWAP\t\tr3" => "0000_1011",
63 "SWAP r4" => "0000_1100",
64 "SWAP r5" => "0000_1101",
65 "SWAP r6" => "0000_1110",
66 "SWAP r7" => "0000_1111",
67 "SWAP r8" => !,
68 "swapr0" => !,
69 "swap 0" => !,
70 "swap g0" => !,
71 "swap" => !,
72 }
73 }
74
75 #[test]
76 fn getr_setr() {
77 test_parse! {
78 "getr r3" => "0001_0011",
79 "GETR r7" => "0001_0111",
80 "GETR r9" => !,
81
82 "SETR r0" => "0001_1000",
83 "SETR r7" => "0001_1111",
84 }
85 }
86
87 #[test]
88 fn get_set_special() {
89 test_parse! {
90 "GET1" => "0010_0000",
91 "GET2" => "0010_0001",
92 "GETC" => "0010_0010",
93
94 "SET1" => "0010_1000",
95 "SET2" => "0010_1001",
96 "SETC" => "0010_1010",
97 }
98 }
99
100 #[test]
101 fn alu1() {
102 test_parse! {
103 "zero" => "0011_0000",
104 "lsl1" => "0011_0001",
105 "lsr1" => "0011_0010",
106 "asr1" => "0011_0011",
107 "incr" => "0011_0100",
108 "decr" => "0011_0101",
109 "comp" => "0011_0110",
110 "negt" => "0011_0111",
111 }
112 }
113
114 #[test]
115 fn islt() {
116 test_parse! {
117 "islt r0" => "0011_1000",
118 "islt r7" => "0011_1111",
119 "islt r8" => !,
120 "islt" => !,
121 }
122 }
123
124 #[test]
125 fn alu_r() {
126 test_parse! {
127 "addr r0" => "0100_0000",
128 "addr r4" => "0100_0100",
129 "subr r1" => "0100_1001",
130 "subr r5" => "0100_1101",
131 "andr r2" => "0101_0010",
132 "andr r6" => "0101_0110",
133 "iorr r3" => "0101_1011",
134 "iorr r7" => "0101_1111",
135 "xorr r0" => "0110_0000",
136 "xorr r4" => "0110_0100",
137 "lslr r1" => "0110_1001",
138 "lslr r5" => "0110_1101",
139 "lsrr r2" => "0111_0010",
140 "lsrr r6" => "0111_0110",
141 "asrr r3" => "0111_1011",
142 "asrr r7" => "0111_1111",
143 }
144 }
145
146 #[test]
147 fn ldst() {
148 test_parse! {
149 "ld1u r0" => "1000_0000",
150 "ld1u r3!" => "1001_0011",
151 "ld2u r2!" => "1011_0010",
152 "ld2u r4" => "1010_0100",
153
154 "st1u r1" => "1000_1001",
155 "st1u r7!" => "1001_1111",
156 "st2u r7!" => "1011_1111",
157 "st2u r7" => "1010_1111",
158 }
159 }
160
161 #[test]
162 fn alu_i() {
163 test_parse! {
164 "andi #00" => "1111_0000 0000_0000",
165 "andi #0000" => "1111_0000 0000_0000",
166 "andi #10" => "1111_0000 0000_1010",
167 "andi #255" => "1111_0000 1111_1111",
168 "andi #-1" => !,
169 "andi #-23" => !,
170 "andi #256" => !,
171
172 "iori #00" => "1111_0001 0000_0000",
173 "iori #32" => "1111_0001 0010_0000",
174 "iori #01" => "1111_0001 0000_0001",
175 "iori #-1" => !,
176
177 "xori #00" => "1111_0010 0000_0000",
178 "xori #07" => "1111_0010 0000_0111",
179 "xori #255" => "1111_0010 1111_1111",
180 "xori #300" => !,
181
182 "addi #0" => "1111_0011 0000_0000",
183 "addi #1" => "1111_0011 0000_0001",
184 "addi #127" => "1111_0011 0111_1111",
185 "addi #128" => !,
186 "addi #250" => !,
187 "addi #-1" => "1111_0011 1111_1111",
188 "addi #-10" => "1111_0011 1111_0110",
189 "addi #-64" => "1111_0011 1100_0000",
190 "addi #-65" => !,
191 "addi #-100" => !,
192 }
193 }
194
195 #[test]
196 fn alu_compact() {
197 test_parse! {
198 "roli #0" => "1111_0011 1000_0000",
199 "roli #7" => "1111_0011 1000_0111",
200 "roli #-1" => !,
201 "roli #8" => !,
202
203 "lsli #0" => "1111_0011 1000_1000",
204 "lsli #7" => "1111_0011 1000_1111",
205 "lsri #0" => "1111_0011 1001_0000",
206 "lsri #7" => "1111_0011 1001_0111",
207 "asri #0" => "1111_0011 1001_1000",
208 "asri #7" => "1111_0011 1001_1111",
209
210 "clri #0" => "1111_0011 1010_0000",
211 "clri #7" => "1111_0011 1010_0111",
212 "seti #0" => "1111_0011 1010_1000",
213 "seti #7" => "1111_0011 1010_1111",
214 "togi #0" => "1111_0011 1011_0000",
215 "togi #7" => "1111_0011 1011_0111",
216 "exti #0" => "1111_0011 1011_1000",
217 "exti #7" => "1111_0011 1011_1111",
218 }
219 }
220
221 #[test]
222 fn branch() {
223 test_parse! {
224 "bezi #0" => "1111_0100 0000_0000",
225 "bezi #1" => "1111_0100 0000_0001",
226 "bezi #-1" => "1111_0100 1111_1111",
227 "bezi #-128" => "1111_0100 1000_0000",
228 "bezi #127" => "1111_0100 0111_1111",
229 "bezi #-129" => !,
230 "bezi #128" => !,
231
232 "jofi #0" => "1111_0110 0000_0000",
233 "jofi #1" => "1111_0110 0000_0001",
234 "jofi #-1" => "1111_0110 1111_1111",
235
236 "cofi #0" => "1111_0111 0000_0000",
237 "cofi #1" => "1111_0111 0000_0001",
238 "cofi #-1" => "1111_0111 1111_1111",
239 }
240 }