1use crate::DisassemblerError;
2use std::fmt;
3
4pub trait Register {
5 fn as_u8(&self) -> u8;
6 fn try_from_u8(value: u8) -> Result<Self, DisassemblerError>
7 where
8 Self: Sized;
9 fn as_str(&self) -> &'static str;
10}
11
12impl Register for NumberedRegister {
13 fn as_u8(&self) -> u8 {
14 *self as u8
15 }
16
17 fn try_from_u8(value: u8) -> Result<Self, DisassemblerError> {
18 NumberedRegister::try_from(value)
19 }
20
21 fn as_str(&self) -> &'static str {
22 match self {
23 NumberedRegister::x0 => "x0",
24 NumberedRegister::x1 => "x1",
25 NumberedRegister::x2 => "x2",
26 NumberedRegister::x3 => "x3",
27 NumberedRegister::x4 => "x4",
28 NumberedRegister::x5 => "x5",
29 NumberedRegister::x6 => "x6",
30 NumberedRegister::x7 => "x7",
31 NumberedRegister::x8 => "x8",
32 NumberedRegister::x9 => "x9",
33 NumberedRegister::x10 => "x10",
34 NumberedRegister::x11 => "x11",
35 NumberedRegister::x12 => "x12",
36 NumberedRegister::x13 => "x13",
37 NumberedRegister::x14 => "x14",
38 NumberedRegister::x15 => "x15",
39 NumberedRegister::x16 => "x16",
40 NumberedRegister::x17 => "x17",
41 NumberedRegister::x18 => "x18",
42 NumberedRegister::x19 => "x19",
43 NumberedRegister::x20 => "x20",
44 NumberedRegister::x21 => "x21",
45 NumberedRegister::x22 => "x22",
46 NumberedRegister::x23 => "x23",
47 NumberedRegister::x24 => "x24",
48 NumberedRegister::x25 => "x25",
49 NumberedRegister::x26 => "x26",
50 NumberedRegister::x27 => "x27",
51 NumberedRegister::x28 => "x28",
52 NumberedRegister::x29 => "x29",
53 NumberedRegister::x30 => "x30",
54 NumberedRegister::x31 => "x31",
55 }
56 }
57}
58
59impl Register for ABIRegister {
60 fn as_u8(&self) -> u8 {
61 *self as u8
62 }
63
64 fn try_from_u8(value: u8) -> Result<Self, DisassemblerError> {
65 ABIRegister::try_from(value)
66 }
67
68 fn as_str(&self) -> &'static str {
69 match self {
70 ABIRegister::zero => "zero",
71 ABIRegister::ra => "ra",
72 ABIRegister::sp => "sp",
73 ABIRegister::gp => "gp",
74 ABIRegister::tp => "tp",
75 ABIRegister::t0 => "t0",
76 ABIRegister::t1 => "t1",
77 ABIRegister::t2 => "t2",
78 ABIRegister::s0 => "s0",
79 ABIRegister::s1 => "s1",
80 ABIRegister::a0 => "a0",
81 ABIRegister::a1 => "a1",
82 ABIRegister::a2 => "a2",
83 ABIRegister::a3 => "a3",
84 ABIRegister::a4 => "a4",
85 ABIRegister::a5 => "a5",
86 ABIRegister::a6 => "a6",
87 ABIRegister::a7 => "a7",
88 ABIRegister::s2 => "s2",
89 ABIRegister::s3 => "s3",
90 ABIRegister::s4 => "s4",
91 ABIRegister::s5 => "s5",
92 ABIRegister::s6 => "s6",
93 ABIRegister::s7 => "s7",
94 ABIRegister::s8 => "s8",
95 ABIRegister::s9 => "s9",
96 ABIRegister::s10 => "s10",
97 ABIRegister::s11 => "s11",
98 ABIRegister::t3 => "t3",
99 ABIRegister::t4 => "t4",
100 ABIRegister::t5 => "t5",
101 ABIRegister::t6 => "t6",
102 }
103 }
104}
105
106#[derive(Debug, PartialEq, Clone, Copy)]
107#[repr(u8)]
108#[allow(non_camel_case_types)]
109pub enum NumberedRegister {
110 x0 = 0,
111 x1 = 1,
112 x2 = 2,
113 x3 = 3,
114 x4 = 4,
115 x5 = 5,
116 x6 = 6,
117 x7 = 7,
118 x8 = 8,
119 x9 = 9,
120 x10 = 10,
121 x11 = 11,
122 x12 = 12,
123 x13 = 13,
124 x14 = 14,
125 x15 = 15,
126 x16 = 16,
127 x17 = 17,
128 x18 = 18,
129 x19 = 19,
130 x20 = 20,
131 x21 = 21,
132 x22 = 22,
133 x23 = 23,
134 x24 = 24,
135 x25 = 25,
136 x26 = 26,
137 x27 = 27,
138 x28 = 28,
139 x29 = 29,
140 x30 = 30,
141 x31 = 31,
142}
143
144#[derive(Debug, PartialEq, Clone, Copy)]
145#[repr(u8)]
146#[allow(non_camel_case_types)]
147pub enum ABIRegister {
148 zero = 0,
149 ra = 1,
150 sp = 2,
151 gp = 3,
152 tp = 4,
153 t0 = 5,
154 t1 = 6,
155 t2 = 7,
156 s0 = 8,
157 s1 = 9,
158 a0 = 10,
159 a1 = 11,
160 a2 = 12,
161 a3 = 13,
162 a4 = 14,
163 a5 = 15,
164 a6 = 16,
165 a7 = 17,
166 s2 = 18,
167 s3 = 19,
168 s4 = 20,
169 s5 = 21,
170 s6 = 22,
171 s7 = 23,
172 s8 = 24,
173 s9 = 25,
174 s10 = 26,
175 s11 = 27,
176 t3 = 28,
177 t4 = 29,
178 t5 = 30,
179 t6 = 31,
180}
181
182impl TryFrom<u8> for NumberedRegister {
183 type Error = DisassemblerError;
184
185 fn try_from(value: u8) -> Result<Self, Self::Error> {
186 match value {
187 0 => Ok(NumberedRegister::x0),
188 1 => Ok(NumberedRegister::x1),
189 2 => Ok(NumberedRegister::x2),
190 3 => Ok(NumberedRegister::x3),
191 4 => Ok(NumberedRegister::x4),
192 5 => Ok(NumberedRegister::x5),
193 6 => Ok(NumberedRegister::x6),
194 7 => Ok(NumberedRegister::x7),
195 8 => Ok(NumberedRegister::x8),
196 9 => Ok(NumberedRegister::x9),
197 10 => Ok(NumberedRegister::x10),
198 11 => Ok(NumberedRegister::x11),
199 12 => Ok(NumberedRegister::x12),
200 13 => Ok(NumberedRegister::x13),
201 14 => Ok(NumberedRegister::x14),
202 15 => Ok(NumberedRegister::x15),
203 16 => Ok(NumberedRegister::x16),
204 17 => Ok(NumberedRegister::x17),
205 18 => Ok(NumberedRegister::x18),
206 19 => Ok(NumberedRegister::x19),
207 20 => Ok(NumberedRegister::x20),
208 21 => Ok(NumberedRegister::x21),
209 22 => Ok(NumberedRegister::x22),
210 23 => Ok(NumberedRegister::x23),
211 24 => Ok(NumberedRegister::x24),
212 25 => Ok(NumberedRegister::x25),
213 26 => Ok(NumberedRegister::x26),
214 27 => Ok(NumberedRegister::x27),
215 28 => Ok(NumberedRegister::x28),
216 29 => Ok(NumberedRegister::x29),
217 30 => Ok(NumberedRegister::x30),
218 31 => Ok(NumberedRegister::x31),
219 _ => Err(DisassemblerError::InvalidRegister(value)),
220 }
221 }
222}
223
224impl TryFrom<u8> for ABIRegister {
225 type Error = DisassemblerError;
226
227 fn try_from(value: u8) -> Result<Self, Self::Error> {
228 match value {
229 0 => Ok(ABIRegister::zero),
230 1 => Ok(ABIRegister::ra),
231 2 => Ok(ABIRegister::sp),
232 3 => Ok(ABIRegister::gp),
233 4 => Ok(ABIRegister::tp),
234 5 => Ok(ABIRegister::t0),
235 6 => Ok(ABIRegister::t1),
236 7 => Ok(ABIRegister::t2),
237 8 => Ok(ABIRegister::s0),
238 9 => Ok(ABIRegister::s1),
239 10 => Ok(ABIRegister::a0),
240 11 => Ok(ABIRegister::a1),
241 12 => Ok(ABIRegister::a2),
242 13 => Ok(ABIRegister::a3),
243 14 => Ok(ABIRegister::a4),
244 15 => Ok(ABIRegister::a5),
245 16 => Ok(ABIRegister::a6),
246 17 => Ok(ABIRegister::a7),
247 18 => Ok(ABIRegister::s2),
248 19 => Ok(ABIRegister::s3),
249 20 => Ok(ABIRegister::s4),
250 21 => Ok(ABIRegister::s5),
251 22 => Ok(ABIRegister::s6),
252 23 => Ok(ABIRegister::s7),
253 24 => Ok(ABIRegister::s8),
254 25 => Ok(ABIRegister::s9),
255 26 => Ok(ABIRegister::s10),
256 27 => Ok(ABIRegister::s11),
257 28 => Ok(ABIRegister::t3),
258 29 => Ok(ABIRegister::t4),
259 30 => Ok(ABIRegister::t5),
260 31 => Ok(ABIRegister::t6),
261 _ => Err(DisassemblerError::InvalidRegister(value)),
262 }
263 }
264}
265
266impl fmt::Display for NumberedRegister {
267 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
268 write!(f, "x{}", *self as u8)
269 }
270}
271
272impl fmt::Display for ABIRegister {
273 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
274 match self {
275 ABIRegister::zero => write!(f, "zero"),
276 ABIRegister::ra => write!(f, "ra"),
277 ABIRegister::sp => write!(f, "sp"),
278 ABIRegister::gp => write!(f, "gp"),
279 ABIRegister::tp => write!(f, "tp"),
280 ABIRegister::t0 => write!(f, "t0"),
281 ABIRegister::t1 => write!(f, "t1"),
282 ABIRegister::t2 => write!(f, "t2"),
283 ABIRegister::s0 => write!(f, "s0"),
284 ABIRegister::s1 => write!(f, "s1"),
285 ABIRegister::a0 => write!(f, "a0"),
286 ABIRegister::a1 => write!(f, "a1"),
287 ABIRegister::a2 => write!(f, "a2"),
288 ABIRegister::a3 => write!(f, "a3"),
289 ABIRegister::a4 => write!(f, "a4"),
290 ABIRegister::a5 => write!(f, "a5"),
291 ABIRegister::a6 => write!(f, "a6"),
292 ABIRegister::a7 => write!(f, "a7"),
293 ABIRegister::s2 => write!(f, "s2"),
294 ABIRegister::s3 => write!(f, "s3"),
295 ABIRegister::s4 => write!(f, "s4"),
296 ABIRegister::s5 => write!(f, "s5"),
297 ABIRegister::s6 => write!(f, "s6"),
298 ABIRegister::s7 => write!(f, "s7"),
299 ABIRegister::s8 => write!(f, "s8"),
300 ABIRegister::s9 => write!(f, "s9"),
301 ABIRegister::s10 => write!(f, "s10"),
302 ABIRegister::s11 => write!(f, "s11"),
303 ABIRegister::t3 => write!(f, "t3"),
304 ABIRegister::t4 => write!(f, "t4"),
305 ABIRegister::t5 => write!(f, "t5"),
306 ABIRegister::t6 => write!(f, "t6"),
307 }
308 }
309}
310
311#[cfg(test)]
312mod tests {
313 use super::*;
314
315 #[test]
316 fn test_try_from_register() {
317 assert_eq!(0.try_into(), Ok(NumberedRegister::x0));
318 assert_eq!(1.try_into(), Ok(NumberedRegister::x1));
319 assert_eq!(2.try_into(), Ok(NumberedRegister::x2));
320 assert_eq!(3.try_into(), Ok(NumberedRegister::x3));
321 assert_eq!(4.try_into(), Ok(NumberedRegister::x4));
322 assert_eq!(5.try_into(), Ok(NumberedRegister::x5));
323 assert_eq!(6.try_into(), Ok(NumberedRegister::x6));
324 assert_eq!(7.try_into(), Ok(NumberedRegister::x7));
325 assert_eq!(8.try_into(), Ok(NumberedRegister::x8));
326 assert_eq!(9.try_into(), Ok(NumberedRegister::x9));
327 assert_eq!(10.try_into(), Ok(NumberedRegister::x10));
328 assert_eq!(11.try_into(), Ok(NumberedRegister::x11));
329 assert_eq!(12.try_into(), Ok(NumberedRegister::x12));
330 assert_eq!(13.try_into(), Ok(NumberedRegister::x13));
331 assert_eq!(14.try_into(), Ok(NumberedRegister::x14));
332 assert_eq!(15.try_into(), Ok(NumberedRegister::x15));
333 assert_eq!(16.try_into(), Ok(NumberedRegister::x16));
334 assert_eq!(17.try_into(), Ok(NumberedRegister::x17));
335 assert_eq!(18.try_into(), Ok(NumberedRegister::x18));
336 assert_eq!(19.try_into(), Ok(NumberedRegister::x19));
337 assert_eq!(20.try_into(), Ok(NumberedRegister::x20));
338 assert_eq!(21.try_into(), Ok(NumberedRegister::x21));
339 assert_eq!(22.try_into(), Ok(NumberedRegister::x22));
340 assert_eq!(23.try_into(), Ok(NumberedRegister::x23));
341 assert_eq!(24.try_into(), Ok(NumberedRegister::x24));
342 assert_eq!(25.try_into(), Ok(NumberedRegister::x25));
343 assert_eq!(26.try_into(), Ok(NumberedRegister::x26));
344 assert_eq!(27.try_into(), Ok(NumberedRegister::x27));
345 assert_eq!(28.try_into(), Ok(NumberedRegister::x28));
346 assert_eq!(29.try_into(), Ok(NumberedRegister::x29));
347 assert_eq!(30.try_into(), Ok(NumberedRegister::x30));
348 assert_eq!(31.try_into(), Ok(NumberedRegister::x31));
349 }
350
351 #[test]
352 fn test_try_from_abi_register() {
353 assert_eq!(0.try_into(), Ok(ABIRegister::zero));
354 assert_eq!(1.try_into(), Ok(ABIRegister::ra));
355 assert_eq!(2.try_into(), Ok(ABIRegister::sp));
356 assert_eq!(3.try_into(), Ok(ABIRegister::gp));
357 assert_eq!(4.try_into(), Ok(ABIRegister::tp));
358 assert_eq!(5.try_into(), Ok(ABIRegister::t0));
359 assert_eq!(6.try_into(), Ok(ABIRegister::t1));
360 assert_eq!(7.try_into(), Ok(ABIRegister::t2));
361 assert_eq!(8.try_into(), Ok(ABIRegister::s0));
362 assert_eq!(9.try_into(), Ok(ABIRegister::s1));
363 assert_eq!(10.try_into(), Ok(ABIRegister::a0));
364 assert_eq!(11.try_into(), Ok(ABIRegister::a1));
365 assert_eq!(12.try_into(), Ok(ABIRegister::a2));
366 assert_eq!(13.try_into(), Ok(ABIRegister::a3));
367 assert_eq!(14.try_into(), Ok(ABIRegister::a4));
368 assert_eq!(15.try_into(), Ok(ABIRegister::a5));
369 assert_eq!(16.try_into(), Ok(ABIRegister::a6));
370 assert_eq!(17.try_into(), Ok(ABIRegister::a7));
371 assert_eq!(18.try_into(), Ok(ABIRegister::s2));
372 assert_eq!(19.try_into(), Ok(ABIRegister::s3));
373 assert_eq!(20.try_into(), Ok(ABIRegister::s4));
374 assert_eq!(21.try_into(), Ok(ABIRegister::s5));
375 assert_eq!(22.try_into(), Ok(ABIRegister::s6));
376 assert_eq!(23.try_into(), Ok(ABIRegister::s7));
377 assert_eq!(24.try_into(), Ok(ABIRegister::s8));
378 assert_eq!(25.try_into(), Ok(ABIRegister::s9));
379 assert_eq!(26.try_into(), Ok(ABIRegister::s10));
380 assert_eq!(27.try_into(), Ok(ABIRegister::s11));
381 assert_eq!(28.try_into(), Ok(ABIRegister::t3));
382 assert_eq!(29.try_into(), Ok(ABIRegister::t4));
383 assert_eq!(30.try_into(), Ok(ABIRegister::t5));
384 assert_eq!(31.try_into(), Ok(ABIRegister::t6));
385 }
386}