risc_v_disassembler/
registers.rs

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}