1use super::instruction_formats;
6use super::InstructionProcessor;
7
8fn process_opcode_op<T: InstructionProcessor>(
9 processor: &mut T,
10 insn_bits: u32,
11) -> Option<T::InstructionResult> {
12 let dec_insn = instruction_formats::RType::new(insn_bits);
13
14 match dec_insn.funct3 {
15 0b000 => match dec_insn.funct7 {
16 0b000_0000 => Some(processor.process_add(dec_insn)),
17 0b000_0001 => Some(processor.process_mul(dec_insn)),
18 0b010_0000 => Some(processor.process_sub(dec_insn)),
19 _ => None,
20 },
21 0b001 => match dec_insn.funct7 {
22 0b000_0000 => Some(processor.process_sll(dec_insn)),
23 0b000_0001 => Some(processor.process_mulh(dec_insn)),
24 _ => None,
25 },
26 0b010 => match dec_insn.funct7 {
27 0b000_0000 => Some(processor.process_slt(dec_insn)),
28 0b000_0001 => Some(processor.process_mulhsu(dec_insn)),
29 _ => None,
30 },
31 0b011 => match dec_insn.funct7 {
32 0b000_0000 => Some(processor.process_sltu(dec_insn)),
33 0b000_0001 => Some(processor.process_mulhu(dec_insn)),
34 _ => None,
35 },
36 0b100 => match dec_insn.funct7 {
37 0b000_0000 => Some(processor.process_xor(dec_insn)),
38 0b000_0001 => Some(processor.process_div(dec_insn)),
39 _ => None,
40 },
41 0b101 => match dec_insn.funct7 {
42 0b000_0000 => Some(processor.process_srl(dec_insn)),
43 0b000_0001 => Some(processor.process_divu(dec_insn)),
44 0b010_0000 => Some(processor.process_sra(dec_insn)),
45 _ => None,
46 },
47 0b110 => match dec_insn.funct7 {
48 0b000_0000 => Some(processor.process_or(dec_insn)),
49 0b000_0001 => Some(processor.process_rem(dec_insn)),
50 _ => None,
51 },
52 0b111 => match dec_insn.funct7 {
53 0b000_0000 => Some(processor.process_and(dec_insn)),
54 0b000_0001 => Some(processor.process_remu(dec_insn)),
55 _ => None,
56 },
57 _ => None,
58 }
59}
60
61fn process_opcode_op_imm<T: InstructionProcessor>(
62 processor: &mut T,
63 insn_bits: u32,
64) -> Option<T::InstructionResult> {
65 let dec_insn = instruction_formats::IType::new(insn_bits);
66
67 match dec_insn.funct3 {
68 0b000 => Some(processor.process_addi(dec_insn)),
69 0b001 => Some(processor.process_slli(instruction_formats::ITypeShamt::new(insn_bits))),
70 0b010 => Some(processor.process_slti(dec_insn)),
71 0b011 => Some(processor.process_sltui(dec_insn)),
72 0b100 => Some(processor.process_xori(dec_insn)),
73 0b101 => {
74 let dec_insn_shamt = instruction_formats::ITypeShamt::new(insn_bits);
75 match dec_insn_shamt.funct7 {
76 0b000_0000 => Some(processor.process_srli(dec_insn_shamt)),
77 0b010_0000 => Some(processor.process_srai(dec_insn_shamt)),
78 _ => None,
79 }
80 }
81 0b110 => Some(processor.process_ori(dec_insn)),
82 0b111 => Some(processor.process_andi(dec_insn)),
83 _ => None,
84 }
85}
86
87fn process_opcode_branch<T: InstructionProcessor>(
88 processor: &mut T,
89 insn_bits: u32,
90) -> Option<T::InstructionResult> {
91 let dec_insn = instruction_formats::BType::new(insn_bits);
92
93 match dec_insn.funct3 {
94 0b000 => Some(processor.process_beq(dec_insn)),
95 0b001 => Some(processor.process_bne(dec_insn)),
96 0b100 => Some(processor.process_blt(dec_insn)),
97 0b101 => Some(processor.process_bge(dec_insn)),
98 0b110 => Some(processor.process_bltu(dec_insn)),
99 0b111 => Some(processor.process_bgeu(dec_insn)),
100 _ => None,
101 }
102}
103
104fn process_opcode_load<T: InstructionProcessor>(
105 processor: &mut T,
106 insn_bits: u32,
107) -> Option<T::InstructionResult> {
108 let dec_insn = instruction_formats::IType::new(insn_bits);
109
110 match dec_insn.funct3 {
111 0b000 => Some(processor.process_lb(dec_insn)),
112 0b001 => Some(processor.process_lh(dec_insn)),
113 0b010 => Some(processor.process_lw(dec_insn)),
114 0b100 => Some(processor.process_lbu(dec_insn)),
115 0b101 => Some(processor.process_lhu(dec_insn)),
116 _ => None,
117 }
118}
119
120fn process_opcode_store<T: InstructionProcessor>(
121 processor: &mut T,
122 insn_bits: u32,
123) -> Option<T::InstructionResult> {
124 let dec_insn = instruction_formats::SType::new(insn_bits);
125
126 match dec_insn.funct3 {
127 0b000 => Some(processor.process_sb(dec_insn)),
128 0b001 => Some(processor.process_sh(dec_insn)),
129 0b010 => Some(processor.process_sw(dec_insn)),
130 _ => None,
131 }
132}
133
134pub fn process_instruction<T: InstructionProcessor>(
139 processor: &mut T,
140 insn_bits: u32,
141) -> Option<T::InstructionResult> {
142 let opcode: u32 = insn_bits & 0x7f;
143
144 match opcode {
145 instruction_formats::OPCODE_OP => process_opcode_op(processor, insn_bits),
146 instruction_formats::OPCODE_OP_IMM => process_opcode_op_imm(processor, insn_bits),
147 instruction_formats::OPCODE_LUI => {
148 Some(processor.process_lui(instruction_formats::UType::new(insn_bits)))
149 }
150 instruction_formats::OPCODE_AUIPC => {
151 Some(processor.process_auipc(instruction_formats::UType::new(insn_bits)))
152 }
153 instruction_formats::OPCODE_BRANCH => process_opcode_branch(processor, insn_bits),
154 instruction_formats::OPCODE_LOAD => process_opcode_load(processor, insn_bits),
155 instruction_formats::OPCODE_STORE => process_opcode_store(processor, insn_bits),
156 instruction_formats::OPCODE_JAL => {
157 Some(processor.process_jal(instruction_formats::JType::new(insn_bits)))
158 }
159 instruction_formats::OPCODE_JALR => {
160 Some(processor.process_jalr(instruction_formats::IType::new(insn_bits)))
161 }
162 instruction_formats::OPCODE_MISC_MEM => {
163 let dec_insn = instruction_formats::IType::new(insn_bits);
164 match dec_insn.funct3 {
165 0b000 => Some(processor.process_fence(dec_insn)),
166 _ => None,
167 }
168 }
169 _ => None,
170 }
171}