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 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#[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}