riscv_codec/
register.rs

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