1#[derive(Copy, Clone, Debug, PartialEq)]
2pub enum OpFunction {
3 ADD,
4 SUB,
5 SLL,
6 SLT,
7 SLTU,
8 XOR,
9 SRL,
10 SRA,
11 OR,
12 AND,
13
14 MUL,
15 MULH,
16 MULHSU,
17 MULHU,
18 DIV,
19 DIVU,
20 REM,
21 REMU,
22}
23
24impl OpFunction {
25 pub fn from_func3_func7(func3: u8, func7: u8) -> Self {
26 match (func7, func3) {
27 (0b0000000, 0b000) => Self::ADD,
28 (0b0100000, 0b000) => Self::SUB,
29 (0b0000000, 0b001) => Self::SLL,
30 (0b0000000, 0b010) => Self::SLT,
31 (0b0000000, 0b011) => Self::SLTU,
32 (0b0000000, 0b100) => Self::XOR,
33 (0b0000000, 0b101) => Self::SRL,
34 (0b0100000, 0b101) => Self::SRA,
35 (0b0000000, 0b110) => Self::OR,
36 (0b0000000, 0b111) => Self::AND,
37 (0b0000001, 0b000) => Self::MUL,
38 (0b0000001, 0b001) => Self::MULH,
39 (0b0000001, 0b010) => Self::MULHSU,
40 (0b0000001, 0b011) => Self::MULHU,
41 (0b0000001, 0b100) => Self::DIV,
42 (0b0000001, 0b101) => Self::DIVU,
43 (0b0000001, 0b110) => Self::REM,
44 (0b0000001, 0b111) => Self::REMU,
45
46 _ => unimplemented!("Op func7={:07b} func3={:03b}", func7, func3),
47 }
48 }
49
50 pub fn to_func3(&self) -> i32 {
51 match self {
52 Self::ADD => 0b000,
53 Self::SUB => 0b000,
54 Self::SLL => 0b001,
55 Self::SLT => 0b010,
56 Self::SLTU => 0b011,
57 Self::XOR => 0b100,
58 Self::SRL => 0b101,
59 Self::SRA => 0b101,
60 Self::OR => 0b110,
61 Self::AND => 0b111,
62 Self::MUL => 0b000,
63 Self::MULH => 0b001,
64 Self::MULHSU => 0b010,
65 Self::MULHU => 0b011,
66 Self::DIV => 0b100,
67 Self::DIVU => 0b101,
68 Self::REM => 0b110,
69 Self::REMU => 0b111,
70 }
71 }
72
73 pub fn to_func7(&self) -> i32 {
74 match self {
75 Self::ADD => 0b0000000,
76 Self::SUB => 0b0100000,
77 Self::SLL => 0b0000000,
78 Self::SLT => 0b0000000,
79 Self::SLTU => 0b0000000,
80 Self::XOR => 0b0000000,
81 Self::SRL => 0b0000000,
82 Self::SRA => 0b0100000,
83 Self::OR => 0b0000000,
84 Self::AND => 0b0000000,
85 Self::MUL => 0b0000001,
86 Self::MULH => 0b0000001,
87 Self::MULHSU => 0b0000001,
88 Self::MULHU => 0b0000001,
89 Self::DIV => 0b0000001,
90 Self::DIVU => 0b0000001,
91 Self::REM => 0b0000001,
92 Self::REMU => 0b0000001,
93 }
94 }
95}