1use rrs_lib::{
2 instruction_formats::{BType, IType, ITypeCSR, ITypeShamt, JType, RType, SType, UType},
3 process_instruction, InstructionProcessor,
4};
5
6use crate::{Instruction, Opcode, Register};
7
8impl Instruction {
9 #[must_use]
11 pub const fn from_r_type(opcode: Opcode, dec_insn: &RType) -> Self {
12 Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.rs2 as u32, false, false)
13 }
14
15 #[must_use]
17 pub const fn from_i_type(opcode: Opcode, dec_insn: &IType) -> Self {
18 Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true)
19 }
20
21 #[must_use]
23 pub const fn from_i_type_shamt(opcode: Opcode, dec_insn: &ITypeShamt) -> Self {
24 Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.shamt, false, true)
25 }
26
27 #[must_use]
29 pub const fn from_s_type(opcode: Opcode, dec_insn: &SType) -> Self {
30 Self::new(opcode, dec_insn.rs2 as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true)
31 }
32
33 #[must_use]
35 pub const fn from_b_type(opcode: Opcode, dec_insn: &BType) -> Self {
36 Self::new(opcode, dec_insn.rs1 as u8, dec_insn.rs2 as u32, dec_insn.imm as u32, false, true)
37 }
38
39 #[must_use]
41 pub const fn unimp() -> Self {
42 Self::new(Opcode::UNIMP, 0, 0, 0, true, true)
43 }
44
45 #[inline]
47 #[must_use]
48 pub const fn is_r_type(&self) -> bool {
49 !self.imm_c
50 }
51
52 #[inline]
54 #[must_use]
55 pub const fn is_i_type(&self) -> bool {
56 self.imm_c
57 }
58
59 #[inline]
61 #[must_use]
62 pub fn r_type(&self) -> (Register, Register, Register) {
63 (
64 Register::from_u8(self.op_a),
65 Register::from_u8(self.op_b as u8),
66 Register::from_u8(self.op_c as u8),
67 )
68 }
69
70 #[inline]
72 #[must_use]
73 pub fn i_type(&self) -> (Register, Register, u32) {
74 (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c)
75 }
76
77 #[inline]
79 #[must_use]
80 pub fn s_type(&self) -> (Register, Register, u32) {
81 (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c)
82 }
83
84 #[inline]
86 #[must_use]
87 pub fn b_type(&self) -> (Register, Register, u32) {
88 (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c)
89 }
90
91 #[inline]
93 #[must_use]
94 pub fn j_type(&self) -> (Register, u32) {
95 (Register::from_u8(self.op_a), self.op_b)
96 }
97
98 #[inline]
100 #[must_use]
101 pub fn u_type(&self) -> (Register, u32) {
102 (Register::from_u8(self.op_a), self.op_b)
103 }
104}
105
106pub(crate) struct InstructionTranspiler;
108
109impl InstructionProcessor for InstructionTranspiler {
110 type InstructionResult = Instruction;
111
112 fn process_add(&mut self, dec_insn: RType) -> Self::InstructionResult {
113 Instruction::from_r_type(Opcode::ADD, &dec_insn)
114 }
115
116 fn process_addi(&mut self, dec_insn: IType) -> Self::InstructionResult {
117 Instruction::from_i_type(Opcode::ADD, &dec_insn)
118 }
119
120 fn process_sub(&mut self, dec_insn: RType) -> Self::InstructionResult {
121 Instruction::from_r_type(Opcode::SUB, &dec_insn)
122 }
123
124 fn process_xor(&mut self, dec_insn: RType) -> Self::InstructionResult {
125 Instruction::from_r_type(Opcode::XOR, &dec_insn)
126 }
127
128 fn process_xori(&mut self, dec_insn: IType) -> Self::InstructionResult {
129 Instruction::from_i_type(Opcode::XOR, &dec_insn)
130 }
131
132 fn process_or(&mut self, dec_insn: RType) -> Self::InstructionResult {
133 Instruction::from_r_type(Opcode::OR, &dec_insn)
134 }
135
136 fn process_ori(&mut self, dec_insn: IType) -> Self::InstructionResult {
137 Instruction::from_i_type(Opcode::OR, &dec_insn)
138 }
139
140 fn process_and(&mut self, dec_insn: RType) -> Self::InstructionResult {
141 Instruction::from_r_type(Opcode::AND, &dec_insn)
142 }
143
144 fn process_andi(&mut self, dec_insn: IType) -> Self::InstructionResult {
145 Instruction::from_i_type(Opcode::AND, &dec_insn)
146 }
147
148 fn process_sll(&mut self, dec_insn: RType) -> Self::InstructionResult {
149 Instruction::from_r_type(Opcode::SLL, &dec_insn)
150 }
151
152 fn process_slli(&mut self, dec_insn: ITypeShamt) -> Self::InstructionResult {
153 Instruction::from_i_type_shamt(Opcode::SLL, &dec_insn)
154 }
155
156 fn process_srl(&mut self, dec_insn: RType) -> Self::InstructionResult {
157 Instruction::from_r_type(Opcode::SRL, &dec_insn)
158 }
159
160 fn process_srli(&mut self, dec_insn: ITypeShamt) -> Self::InstructionResult {
161 Instruction::from_i_type_shamt(Opcode::SRL, &dec_insn)
162 }
163
164 fn process_sra(&mut self, dec_insn: RType) -> Self::InstructionResult {
165 Instruction::from_r_type(Opcode::SRA, &dec_insn)
166 }
167
168 fn process_srai(&mut self, dec_insn: ITypeShamt) -> Self::InstructionResult {
169 Instruction::from_i_type_shamt(Opcode::SRA, &dec_insn)
170 }
171
172 fn process_slt(&mut self, dec_insn: RType) -> Self::InstructionResult {
173 Instruction::from_r_type(Opcode::SLT, &dec_insn)
174 }
175
176 fn process_slti(&mut self, dec_insn: IType) -> Self::InstructionResult {
177 Instruction::from_i_type(Opcode::SLT, &dec_insn)
178 }
179
180 fn process_sltu(&mut self, dec_insn: RType) -> Self::InstructionResult {
181 Instruction::from_r_type(Opcode::SLTU, &dec_insn)
182 }
183
184 fn process_sltui(&mut self, dec_insn: IType) -> Self::InstructionResult {
185 Instruction::from_i_type(Opcode::SLTU, &dec_insn)
186 }
187
188 fn process_lb(&mut self, dec_insn: IType) -> Self::InstructionResult {
189 Instruction::from_i_type(Opcode::LB, &dec_insn)
190 }
191
192 fn process_lh(&mut self, dec_insn: IType) -> Self::InstructionResult {
193 Instruction::from_i_type(Opcode::LH, &dec_insn)
194 }
195
196 fn process_lw(&mut self, dec_insn: IType) -> Self::InstructionResult {
197 Instruction::from_i_type(Opcode::LW, &dec_insn)
198 }
199
200 fn process_lbu(&mut self, dec_insn: IType) -> Self::InstructionResult {
201 Instruction::from_i_type(Opcode::LBU, &dec_insn)
202 }
203
204 fn process_lhu(&mut self, dec_insn: IType) -> Self::InstructionResult {
205 Instruction::from_i_type(Opcode::LHU, &dec_insn)
206 }
207
208 fn process_sb(&mut self, dec_insn: SType) -> Self::InstructionResult {
209 Instruction::from_s_type(Opcode::SB, &dec_insn)
210 }
211
212 fn process_sh(&mut self, dec_insn: SType) -> Self::InstructionResult {
213 Instruction::from_s_type(Opcode::SH, &dec_insn)
214 }
215
216 fn process_sw(&mut self, dec_insn: SType) -> Self::InstructionResult {
217 Instruction::from_s_type(Opcode::SW, &dec_insn)
218 }
219
220 fn process_beq(&mut self, dec_insn: BType) -> Self::InstructionResult {
221 Instruction::from_b_type(Opcode::BEQ, &dec_insn)
222 }
223
224 fn process_bne(&mut self, dec_insn: BType) -> Self::InstructionResult {
225 Instruction::from_b_type(Opcode::BNE, &dec_insn)
226 }
227
228 fn process_blt(&mut self, dec_insn: BType) -> Self::InstructionResult {
229 Instruction::from_b_type(Opcode::BLT, &dec_insn)
230 }
231
232 fn process_bge(&mut self, dec_insn: BType) -> Self::InstructionResult {
233 Instruction::from_b_type(Opcode::BGE, &dec_insn)
234 }
235
236 fn process_bltu(&mut self, dec_insn: BType) -> Self::InstructionResult {
237 Instruction::from_b_type(Opcode::BLTU, &dec_insn)
238 }
239
240 fn process_bgeu(&mut self, dec_insn: BType) -> Self::InstructionResult {
241 Instruction::from_b_type(Opcode::BGEU, &dec_insn)
242 }
243
244 fn process_jal(&mut self, dec_insn: JType) -> Self::InstructionResult {
245 Instruction::new(Opcode::JAL, dec_insn.rd as u8, dec_insn.imm as u32, 0, true, true)
246 }
247
248 fn process_jalr(&mut self, dec_insn: IType) -> Self::InstructionResult {
249 Instruction::new(
250 Opcode::JALR,
251 dec_insn.rd as u8,
252 dec_insn.rs1 as u32,
253 dec_insn.imm as u32,
254 false,
255 true,
256 )
257 }
258
259 fn process_lui(&mut self, dec_insn: UType) -> Self::InstructionResult {
260 Instruction::new(Opcode::ADD, dec_insn.rd as u8, 0, dec_insn.imm as u32, true, true)
265 }
266
267 fn process_auipc(&mut self, dec_insn: UType) -> Self::InstructionResult {
269 Instruction::new(
270 Opcode::AUIPC,
271 dec_insn.rd as u8,
272 dec_insn.imm as u32,
273 dec_insn.imm as u32,
274 true,
275 true,
276 )
277 }
278
279 fn process_ecall(&mut self) -> Self::InstructionResult {
280 Instruction::new(
281 Opcode::ECALL,
282 Register::X5 as u8,
283 Register::X10 as u32,
284 Register::X11 as u32,
285 false,
286 false,
287 )
288 }
289
290 fn process_ebreak(&mut self) -> Self::InstructionResult {
291 Instruction::new(Opcode::EBREAK, 0, 0, 0, false, false)
292 }
293
294 fn process_mul(&mut self, dec_insn: RType) -> Self::InstructionResult {
295 Instruction::from_r_type(Opcode::MUL, &dec_insn)
296 }
297
298 fn process_mulh(&mut self, dec_insn: RType) -> Self::InstructionResult {
299 Instruction::from_r_type(Opcode::MULH, &dec_insn)
300 }
301
302 fn process_mulhu(&mut self, dec_insn: RType) -> Self::InstructionResult {
303 Instruction::from_r_type(Opcode::MULHU, &dec_insn)
304 }
305
306 fn process_mulhsu(&mut self, dec_insn: RType) -> Self::InstructionResult {
307 Instruction::from_r_type(Opcode::MULHSU, &dec_insn)
308 }
309
310 fn process_div(&mut self, dec_insn: RType) -> Self::InstructionResult {
311 Instruction::from_r_type(Opcode::DIV, &dec_insn)
312 }
313
314 fn process_divu(&mut self, dec_insn: RType) -> Self::InstructionResult {
315 Instruction::from_r_type(Opcode::DIVU, &dec_insn)
316 }
317
318 fn process_rem(&mut self, dec_insn: RType) -> Self::InstructionResult {
319 Instruction::from_r_type(Opcode::REM, &dec_insn)
320 }
321
322 fn process_remu(&mut self, dec_insn: RType) -> Self::InstructionResult {
323 Instruction::from_r_type(Opcode::REMU, &dec_insn)
324 }
325
326 fn process_csrrc(&mut self, _: ITypeCSR) -> Self::InstructionResult {
327 Instruction::unimp()
328 }
329
330 fn process_csrrci(&mut self, _: ITypeCSR) -> Self::InstructionResult {
331 Instruction::unimp()
332 }
333
334 fn process_csrrs(&mut self, _: ITypeCSR) -> Self::InstructionResult {
335 Instruction::unimp()
336 }
337
338 fn process_csrrsi(&mut self, _: ITypeCSR) -> Self::InstructionResult {
339 Instruction::unimp()
340 }
341
342 fn process_csrrw(&mut self, _: ITypeCSR) -> Self::InstructionResult {
343 Instruction::unimp()
344 }
345
346 fn process_csrrwi(&mut self, _: ITypeCSR) -> Self::InstructionResult {
347 Instruction::unimp()
348 }
349
350 fn process_fence(&mut self, _: IType) -> Self::InstructionResult {
351 Instruction::unimp()
352 }
353
354 fn process_mret(&mut self) -> Self::InstructionResult {
355 Instruction::unimp()
356 }
357
358 fn process_wfi(&mut self) -> Self::InstructionResult {
359 Instruction::unimp()
360 }
361}
362
363#[must_use]
369pub(crate) fn transpile(instructions_u32: &[u32]) -> Vec<Instruction> {
370 let mut instructions = Vec::new();
371 let mut transpiler = InstructionTranspiler;
372 for instruction_u32 in instructions_u32 {
373 let instruction = process_instruction(&mut transpiler, *instruction_u32).unwrap();
374 instructions.push(instruction);
375 }
376 instructions
377}