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