riscv_codec/
register.rs

1use std::fmt::{Display, Formatter};
2
3#[derive(Debug, PartialEq, Clone, Copy)]
4pub enum IRegister {
5    Zero = 0,
6    ReturnAddress = 1,
7    StackPointer = 2,
8    GlobalPointer = 3,
9    ThreadPointer = 4,
10    T0 = 5,
11    T1 = 6,
12    T2 = 7,
13    /// Also called s0
14    FramePointer = 8,
15    S1 = 9,
16    A0 = 10,
17    A1 = 11,
18    A2 = 12,
19    A3 = 13,
20    A4 = 14,
21    A5 = 15,
22    A6 = 16,
23    A7 = 17,
24    S2 = 18,
25    S3 = 19,
26    S4 = 20,
27    S5 = 21,
28    S6 = 22,
29    S7 = 23,
30    S8 = 24,
31    S9 = 25,
32    S10 = 26,
33    S11 = 27,
34    T3 = 28,
35    T4 = 29,
36    T5 = 30,
37    T6 = 31,
38}
39
40impl Display for IRegister {
41    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
42        write!(
43            f,
44            "{}",
45            match self {
46                IRegister::Zero => "zero",
47                IRegister::ReturnAddress => "ra",
48                IRegister::StackPointer => "sp",
49                IRegister::GlobalPointer => "gp",
50                IRegister::ThreadPointer => "tp",
51                IRegister::T0 => "t0",
52                IRegister::T1 => "t1",
53                IRegister::T2 => "t2",
54                IRegister::FramePointer => "s0",
55                IRegister::S1 => "s1",
56                IRegister::A0 => "a0",
57                IRegister::A1 => "a1",
58                IRegister::A2 => "a2",
59                IRegister::A3 => "a3",
60                IRegister::A4 => "a4",
61                IRegister::A5 => "a5",
62                IRegister::A6 => "a6",
63                IRegister::A7 => "a7",
64                IRegister::S2 => "s2",
65                IRegister::S3 => "s3",
66                IRegister::S4 => "s4",
67                IRegister::S5 => "s5",
68                IRegister::S6 => "s6",
69                IRegister::S7 => "s7",
70                IRegister::S8 => "s8",
71                IRegister::S9 => "s9",
72                IRegister::S10 => "s10",
73                IRegister::S11 => "s11",
74                IRegister::T3 => "t3",
75                IRegister::T4 => "t4",
76                IRegister::T5 => "t5",
77                IRegister::T6 => "t6",
78            }
79        )
80    }
81}
82
83impl Into<u32> for IRegister {
84    fn into(self) -> u32 {
85        match self {
86            Self::Zero => 0,
87            Self::ReturnAddress => 1,
88            Self::StackPointer => 2,
89            Self::GlobalPointer => 3,
90            Self::ThreadPointer => 4,
91            Self::T0 => 5,
92            Self::T1 => 6,
93            Self::T2 => 7,
94            Self::FramePointer => 8,
95            Self::S1 => 9,
96            Self::A0 => 10,
97            Self::A1 => 11,
98            Self::A2 => 12,
99            Self::A3 => 13,
100            Self::A4 => 14,
101            Self::A5 => 15,
102            Self::A6 => 16,
103            Self::A7 => 17,
104            Self::S2 => 18,
105            Self::S3 => 19,
106            Self::S4 => 20,
107            Self::S5 => 21,
108            Self::S6 => 22,
109            Self::S7 => 23,
110            Self::S8 => 24,
111            Self::S9 => 25,
112            Self::S10 => 26,
113            Self::S11 => 27,
114            Self::T3 => 28,
115            Self::T4 => 29,
116            Self::T5 => 30,
117            Self::T6 => 31,
118        }
119    }
120}
121
122impl IRegister {
123    pub fn from_int(int: u32) -> Self {
124        match int {
125            0 => Self::Zero,
126            1 => Self::ReturnAddress,
127            2 => Self::StackPointer,
128            3 => Self::GlobalPointer,
129            4 => Self::ThreadPointer,
130            5 => Self::T0,
131            6 => Self::T1,
132            7 => Self::T2,
133            8 => Self::FramePointer,
134            9 => Self::S1,
135            10 => Self::A0,
136            11 => Self::A1,
137            12 => Self::A2,
138            13 => Self::A3,
139            14 => Self::A4,
140            15 => Self::A5,
141            16 => Self::A6,
142            17 => Self::A7,
143            18 => Self::S2,
144            19 => Self::S3,
145            20 => Self::S4,
146            21 => Self::S5,
147            22 => Self::S6,
148            23 => Self::S7,
149            24 => Self::S8,
150            25 => Self::S9,
151            26 => Self::S10,
152            27 => Self::S11,
153            28 => Self::T3,
154            29 => Self::T4,
155            30 => Self::T5,
156            31 => Self::T6,
157            x => panic!("converted invalid to integer register {}", x),
158        }
159    }
160
161    pub fn from_string(str: &str) -> Result<Self, String> {
162        match str {
163            "zero" => Ok(Self::Zero),
164            "ra" => Ok(Self::ReturnAddress),
165            "sp" => Ok(Self::StackPointer),
166            "gp" => Ok(Self::GlobalPointer),
167            "tp" => Ok(Self::ThreadPointer),
168            "t0" => Ok(Self::T0),
169            "t1" => Ok(Self::T1),
170            "t2" => Ok(Self::T2),
171            "fp" => Ok(Self::FramePointer),
172            "s0" => Ok(Self::FramePointer),
173            "s1" => Ok(Self::S1),
174            "a0" => Ok(Self::A0),
175            "a1" => Ok(Self::A1),
176            "a2" => Ok(Self::A2),
177            "a3" => Ok(Self::A3),
178            "a4" => Ok(Self::A4),
179            "a5" => Ok(Self::A5),
180            "a6" => Ok(Self::A6),
181            "a7" => Ok(Self::A7),
182            "s2" => Ok(Self::S2),
183            "s3" => Ok(Self::S3),
184            "s4" => Ok(Self::S4),
185            "s5" => Ok(Self::S5),
186            "s6" => Ok(Self::S6),
187            "s7" => Ok(Self::S7),
188            "s8" => Ok(Self::S8),
189            "s9" => Ok(Self::S9),
190            "s10" => Ok(Self::S10),
191            "s11" => Ok(Self::S11),
192            "t3" => Ok(Self::T3),
193            "t4" => Ok(Self::T4),
194            "t5" => Ok(Self::T5),
195            "t6" => Ok(Self::T6),
196            x => Err(format!("converted invalid str to integer register {}", x)),
197        }
198    }
199
200    pub fn rd(self) -> u32 {
201        let v: u32 = self.into();
202        return v << 7;
203    }
204    pub fn rs1(self) -> u32 {
205        let v: u32 = self.into();
206        return v << 15;
207    }
208    pub fn rs2(self) -> u32 {
209        let v: u32 = self.into();
210        return v << 20;
211    }
212}
213
214#[derive(Debug, PartialEq, Clone, Copy)]
215pub enum FRegister {
216    FT0 = 0,
217    FT1 = 1,
218    FT2 = 2,
219    FT3 = 3,
220    FT4 = 4,
221    FT5 = 5,
222    FT6 = 6,
223    FT7 = 7,
224    FS0 = 8,
225    FS1 = 9,
226    FA0 = 10,
227    FA1 = 11,
228    FA2 = 12,
229    FA3 = 13,
230    FA4 = 14,
231    FA5 = 15,
232    FA6 = 16,
233    FA7 = 17,
234    FS2 = 18,
235    FS3 = 19,
236    FS4 = 20,
237    FS5 = 21,
238    FS6 = 22,
239    FS7 = 23,
240    FS8 = 24,
241    FS9 = 25,
242    FS10 = 26,
243    FS11 = 27,
244    FT8 = 28,
245    FT9 = 29,
246    FT10 = 30,
247    FT11 = 31,
248}
249
250impl Display for FRegister {
251    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
252        write!(
253            f,
254            "{}",
255            match self {
256                FRegister::FT0 => "ft0",
257                FRegister::FT1 => "ft1",
258                FRegister::FT2 => "ft2",
259                FRegister::FT3 => "ft3",
260                FRegister::FT4 => "ft4",
261                FRegister::FT5 => "ft5",
262                FRegister::FT6 => "ft6",
263                FRegister::FT7 => "ft7",
264                FRegister::FS0 => "fs0",
265                FRegister::FS1 => "fs1",
266                FRegister::FA0 => "fa0",
267                FRegister::FA1 => "fa1",
268                FRegister::FA2 => "fa2",
269                FRegister::FA3 => "fa3",
270                FRegister::FA4 => "fa4",
271                FRegister::FA5 => "fa5",
272                FRegister::FA6 => "fa6",
273                FRegister::FA7 => "fa7",
274                FRegister::FS2 => "fs2",
275                FRegister::FS3 => "fs3",
276                FRegister::FS4 => "fs4",
277                FRegister::FS5 => "fs5",
278                FRegister::FS6 => "fs6",
279                FRegister::FS7 => "fs7",
280                FRegister::FS8 => "fs8",
281                FRegister::FS9 => "fs9",
282                FRegister::FS10 => "fs10",
283                FRegister::FS11 => "fs11",
284                FRegister::FT8 => "ft8",
285                FRegister::FT9 => "ft9",
286                FRegister::FT10 => "ft10",
287                FRegister::FT11 => "ft11",
288            }
289        )
290    }
291}
292
293impl TryFrom<u32> for FRegister {
294    type Error = String;
295
296    fn try_from(value: u32) -> Result<Self, Self::Error> {
297        match value {
298            0 => Ok(Self::FT0),
299            1 => Ok(Self::FT1),
300            2 => Ok(Self::FT2),
301            3 => Ok(Self::FT3),
302            4 => Ok(Self::FT4),
303            5 => Ok(Self::FT5),
304            6 => Ok(Self::FT6),
305            7 => Ok(Self::FT7),
306            8 => Ok(Self::FS0),
307            9 => Ok(Self::FS1),
308            10 => Ok(Self::FA0),
309            11 => Ok(Self::FA1),
310            12 => Ok(Self::FA2),
311            13 => Ok(Self::FA3),
312            14 => Ok(Self::FA4),
313            15 => Ok(Self::FA5),
314            16 => Ok(Self::FA6),
315            17 => Ok(Self::FA7),
316            18 => Ok(Self::FS2),
317            19 => Ok(Self::FS3),
318            20 => Ok(Self::FS4),
319            21 => Ok(Self::FS5),
320            22 => Ok(Self::FS6),
321            23 => Ok(Self::FS7),
322            24 => Ok(Self::FS8),
323            25 => Ok(Self::FS9),
324            26 => Ok(Self::FS10),
325            27 => Ok(Self::FS11),
326            28 => Ok(Self::FT8),
327            29 => Ok(Self::FT9),
328            30 => Ok(Self::FT10),
329            31 => Ok(Self::FT11),
330            x => Err(format!("converted invalid integer to float register {}", x)),
331        }
332    }
333}
334
335impl TryFrom<&str> for FRegister {
336    type Error = String;
337
338    fn try_from(value: &str) -> Result<Self, Self::Error> {
339        match value {
340            "ft0" => Ok(Self::FT0),
341            "ft1" => Ok(Self::FT1),
342            "ft2" => Ok(Self::FT2),
343            "ft3" => Ok(Self::FT3),
344            "ft4" => Ok(Self::FT4),
345            "ft5" => Ok(Self::FT5),
346            "ft6" => Ok(Self::FT6),
347            "ft7" => Ok(Self::FT7),
348            "fs0" => Ok(Self::FS0),
349            "fs1" => Ok(Self::FS1),
350            "fa0" => Ok(Self::FA0),
351            "fa1" => Ok(Self::FA1),
352            "fa2" => Ok(Self::FA2),
353            "fa3" => Ok(Self::FA3),
354            "fa4" => Ok(Self::FA4),
355            "fa5" => Ok(Self::FA5),
356            "fa6" => Ok(Self::FA6),
357            "fa7" => Ok(Self::FA7),
358            "fs2" => Ok(Self::FS2),
359            "fs3" => Ok(Self::FS3),
360            "fs4" => Ok(Self::FS4),
361            "fs5" => Ok(Self::FS5),
362            "fs6" => Ok(Self::FS6),
363            "fs7" => Ok(Self::FS7),
364            "fs8" => Ok(Self::FS8),
365            "fs9" => Ok(Self::FS9),
366            "fs10" => Ok(Self::FS10),
367            "fs11" => Ok(Self::FS11),
368            "ft8" => Ok(Self::FT8),
369            "ft9" => Ok(Self::FT9),
370            "ft10" => Ok(Self::FT10),
371            "ft11" => Ok(Self::FT11),
372            x => Err(format!("converted invalid str to float register {}", x)),
373        }
374    }
375}
376
377impl Into<u32> for FRegister {
378    fn into(self) -> u32 {
379        match self {
380            FRegister::FT0 => 0,
381            FRegister::FT1 => 1,
382            FRegister::FT2 => 2,
383            FRegister::FT3 => 3,
384            FRegister::FT4 => 4,
385            FRegister::FT5 => 5,
386            FRegister::FT6 => 6,
387            FRegister::FT7 => 7,
388            FRegister::FS0 => 8,
389            FRegister::FS1 => 9,
390            FRegister::FA0 => 10,
391            FRegister::FA1 => 11,
392            FRegister::FA2 => 12,
393            FRegister::FA3 => 13,
394            FRegister::FA4 => 14,
395            FRegister::FA5 => 15,
396            FRegister::FA6 => 16,
397            FRegister::FA7 => 17,
398            FRegister::FS2 => 18,
399            FRegister::FS3 => 19,
400            FRegister::FS4 => 20,
401            FRegister::FS5 => 21,
402            FRegister::FS6 => 22,
403            FRegister::FS7 => 23,
404            FRegister::FS8 => 24,
405            FRegister::FS9 => 25,
406            FRegister::FS10 => 26,
407            FRegister::FS11 => 27,
408            FRegister::FT8 => 28,
409            FRegister::FT9 => 29,
410            FRegister::FT10 => 30,
411            FRegister::FT11 => 31,
412        }
413    }
414}
415
416impl FRegister {
417    pub fn rd(self) -> u32 {
418        let v: u32 = self.into();
419        return v << 7;
420    }
421    pub fn rs1(self) -> u32 {
422        let v: u32 = self.into();
423        return v << 15;
424    }
425    pub fn rs2(self) -> u32 {
426        let v: u32 = self.into();
427        return v << 20;
428    }
429    pub fn rs3(self) -> u32 {
430        let v: u32 = self.into();
431        return v << 27;
432    }
433}
434
435/// One of the limited set of registers available in compressed instructions
436#[derive(Debug, PartialEq, Clone, Copy)]
437pub enum CIRegister {
438    FramePointer,
439    S1,
440    A0,
441    A1,
442    A2,
443    A3,
444    A4,
445    A5,
446}
447
448impl From<u16> for CIRegister {
449    fn from(value: u16) -> Self {
450        match value {
451            0 => Self::FramePointer,
452            1 => Self::S1,
453            2 => Self::A0,
454            3 => Self::A1,
455            4 => Self::A2,
456            5 => Self::A3,
457            6 => Self::A4,
458            7 => Self::A5,
459            x => panic!(
460                "converted invalid integer to register in compressed instruction: {}",
461                x
462            ),
463        }
464    }
465}
466
467impl TryFrom<&str> for CIRegister {
468    type Error = String;
469
470    fn try_from(value: &str) -> Result<Self, Self::Error> {
471        match value {
472            "fp" => Ok(Self::FramePointer),
473            "s0" => Ok(Self::FramePointer),
474            "s1" => Ok(Self::S1),
475            "a0" => Ok(Self::A0),
476            "a1" => Ok(Self::A1),
477            "a2" => Ok(Self::A2),
478            "a3" => Ok(Self::A3),
479            "a4" => Ok(Self::A4),
480            "a5" => Ok(Self::A5),
481            x => Err(format!(
482                "converted invalid str to integer register in compressed instruction: {}",
483                x
484            )),
485        }
486    }
487}
488
489impl CIRegister {
490    pub fn expand(&self) -> IRegister {
491        match self {
492            CIRegister::FramePointer => IRegister::FramePointer,
493            CIRegister::S1 => IRegister::S1,
494            CIRegister::A0 => IRegister::A0,
495            CIRegister::A1 => IRegister::A1,
496            CIRegister::A2 => IRegister::A2,
497            CIRegister::A3 => IRegister::A3,
498            CIRegister::A4 => IRegister::A4,
499            CIRegister::A5 => IRegister::A5,
500        }
501    }
502
503    pub fn rs2(&self) -> u16 {
504        return (*self as u16) << 2;
505    }
506
507    pub fn rs1(&self) -> u16 {
508        return (*self as u16) << 7;
509    }
510}
511
512impl Display for CIRegister {
513    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
514        write!(
515            f,
516            "{}",
517            match self {
518                CIRegister::FramePointer => "s0",
519                CIRegister::S1 => "s1",
520                CIRegister::A0 => "a0",
521                CIRegister::A1 => "a1",
522                CIRegister::A2 => "a2",
523                CIRegister::A3 => "a3",
524                CIRegister::A4 => "a4",
525                CIRegister::A5 => "a5",
526            }
527        )
528    }
529}
530
531#[derive(Debug, PartialEq, Clone, Copy)]
532pub enum CFRegister {
533    FS0,
534    FS1,
535    FA0,
536    FA1,
537    FA2,
538    FA3,
539    FA4,
540    FA5,
541}
542
543impl TryFrom<u16> for CFRegister {
544    type Error = String;
545
546    fn try_from(value: u16) -> Result<Self, Self::Error> {
547        match value {
548            0 => Ok(Self::FS0),
549            1 => Ok(Self::FS1),
550            2 => Ok(Self::FA0),
551            3 => Ok(Self::FA1),
552            4 => Ok(Self::FA2),
553            5 => Ok(Self::FA3),
554            6 => Ok(Self::FA4),
555            7 => Ok(Self::FA5),
556            x => Err(format!(
557                "converted invalid integer to float register in compressed instruction: {}",
558                x
559            )),
560        }
561    }
562}
563
564impl TryFrom<&str> for CFRegister {
565    type Error = String;
566
567    fn try_from(value: &str) -> Result<Self, Self::Error> {
568        match value {
569            "fs0" => Ok(Self::FS0),
570            "fs1" => Ok(Self::FS1),
571            "fa0" => Ok(Self::FA0),
572            "fa1" => Ok(Self::FA1),
573            "fa2" => Ok(Self::FA2),
574            "fa3" => Ok(Self::FA3),
575            "fa4" => Ok(Self::FA4),
576            "fa5" => Ok(Self::FA5),
577            x => Err(format!(
578                "converted invalid str to float register in compressed instruction {}",
579                x
580            )),
581        }
582    }
583}
584
585impl CFRegister {
586    pub fn expand(&self) -> FRegister {
587        match self {
588            CFRegister::FS0 => FRegister::FS0,
589            CFRegister::FS1 => FRegister::FS1,
590            CFRegister::FA0 => FRegister::FA0,
591            CFRegister::FA1 => FRegister::FA1,
592            CFRegister::FA2 => FRegister::FA2,
593            CFRegister::FA3 => FRegister::FA3,
594            CFRegister::FA4 => FRegister::FA4,
595            CFRegister::FA5 => FRegister::FA5,
596        }
597    }
598
599    pub fn rs2(&self) -> u16 {
600        return (*self as u16) << 2;
601    }
602
603    pub fn rs1(&self) -> u16 {
604        return (*self as u16) << 7;
605    }
606}
607
608impl Display for CFRegister {
609    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
610        write!(
611            f,
612            "{}",
613            match self {
614                CFRegister::FS0 => "fs0",
615                CFRegister::FS1 => "fs1",
616                CFRegister::FA0 => "fa0",
617                CFRegister::FA1 => "fa1",
618                CFRegister::FA2 => "fa2",
619                CFRegister::FA3 => "fa3",
620                CFRegister::FA4 => "fa4",
621                CFRegister::FA5 => "fa5",
622            }
623        )
624    }
625}