1use rrs_lib::{
2 instruction_formats::{
3 BType, IType, ITypeCSR, ITypeShamt, ITypeShamtW, JType, RType, SType, UType,
4 },
5 process_instruction, InstructionProcessor,
6};
7
8use crate::{Instruction, Opcode, Register};
9
10impl Instruction {
11 #[must_use]
13 pub const fn from_r_type(opcode: Opcode, dec_insn: &RType) -> Self {
14 Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1, dec_insn.rs2, false, false)
15 }
16
17 #[must_use]
19 pub const fn from_i_type(opcode: Opcode, dec_insn: &IType) -> Self {
20 Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1, dec_insn.imm as u64, false, true)
21 }
22
23 #[must_use]
25 pub const fn from_i_type_shamt(opcode: Opcode, dec_insn: &ITypeShamt) -> Self {
26 Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1, dec_insn.shamt, false, true)
27 }
28
29 #[must_use]
31 pub const fn from_i_type_shamt_w(opcode: Opcode, dec_insn: &ITypeShamtW) -> Self {
32 Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1, dec_insn.shamt, false, true)
33 }
34
35 #[must_use]
37 pub const fn from_s_type(opcode: Opcode, dec_insn: &SType) -> Self {
38 Self::new(opcode, dec_insn.rs2 as u8, dec_insn.rs1, dec_insn.imm as u64, false, true)
39 }
40
41 #[must_use]
43 pub const fn from_b_type(opcode: Opcode, dec_insn: &BType) -> Self {
44 Self::new(opcode, dec_insn.rs1 as u8, dec_insn.rs2, dec_insn.imm as u64, false, true)
45 }
46
47 #[must_use]
49 pub const fn from_u_type(opcode: Opcode, dec_insn: &UType) -> Self {
50 Self::new(opcode, dec_insn.rd as u8, dec_insn.imm, dec_insn.imm, true, true)
51 }
52
53 #[must_use]
55 pub const fn unimp() -> Self {
56 Self::new(Opcode::UNIMP, 0, 0, 0, true, true)
57 }
58
59 #[inline]
61 #[must_use]
62 pub const fn is_r_type(&self) -> bool {
63 !self.imm_c
64 }
65
66 #[inline]
68 #[must_use]
69 pub const fn is_i_type(&self) -> bool {
70 self.imm_c
71 }
72
73 #[inline]
75 #[must_use]
76 pub fn r_type(&self) -> (Register, Register, Register) {
77 (
78 Register::from_u8(self.op_a),
79 Register::from_u8(self.op_b as u8),
80 Register::from_u8(self.op_c as u8),
81 )
82 }
83
84 #[inline]
86 #[must_use]
87 pub fn i_type(&self) -> (Register, Register, u64) {
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 s_type(&self) -> (Register, Register, u64) {
95 (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c)
96 }
97
98 #[inline]
100 #[must_use]
101 pub fn b_type(&self) -> (Register, Register, u64) {
102 (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c)
103 }
104
105 #[inline]
107 #[must_use]
108 pub fn j_type(&self) -> (Register, u64) {
109 (Register::from_u8(self.op_a), self.op_b)
110 }
111
112 #[inline]
114 #[must_use]
115 pub fn u_type(&self) -> (Register, u64) {
116 (Register::from_u8(self.op_a), self.op_b)
117 }
118}
119
120pub(crate) struct InstructionTranspiler;
122
123impl InstructionProcessor for InstructionTranspiler {
124 type InstructionResult = Instruction;
125
126 fn process_add(&mut self, dec_insn: RType) -> Self::InstructionResult {
127 Instruction::from_r_type(Opcode::ADD, &dec_insn)
128 }
129
130 fn process_addi(&mut self, dec_insn: IType) -> Self::InstructionResult {
131 Instruction::from_i_type(Opcode::ADDI, &dec_insn)
132 }
133
134 fn process_sub(&mut self, dec_insn: RType) -> Self::InstructionResult {
135 Instruction::from_r_type(Opcode::SUB, &dec_insn)
136 }
137
138 fn process_xor(&mut self, dec_insn: RType) -> Self::InstructionResult {
139 Instruction::from_r_type(Opcode::XOR, &dec_insn)
140 }
141
142 fn process_xori(&mut self, dec_insn: IType) -> Self::InstructionResult {
143 Instruction::from_i_type(Opcode::XOR, &dec_insn)
144 }
145
146 fn process_or(&mut self, dec_insn: RType) -> Self::InstructionResult {
147 Instruction::from_r_type(Opcode::OR, &dec_insn)
148 }
149
150 fn process_ori(&mut self, dec_insn: IType) -> Self::InstructionResult {
151 Instruction::from_i_type(Opcode::OR, &dec_insn)
152 }
153
154 fn process_and(&mut self, dec_insn: RType) -> Self::InstructionResult {
155 Instruction::from_r_type(Opcode::AND, &dec_insn)
156 }
157
158 fn process_andi(&mut self, dec_insn: IType) -> Self::InstructionResult {
159 Instruction::from_i_type(Opcode::AND, &dec_insn)
160 }
161
162 fn process_sll(&mut self, dec_insn: RType) -> Self::InstructionResult {
163 Instruction::from_r_type(Opcode::SLL, &dec_insn)
164 }
165
166 fn process_slli(&mut self, dec_insn: ITypeShamt) -> Self::InstructionResult {
167 Instruction::from_i_type_shamt(Opcode::SLL, &dec_insn)
168 }
169
170 fn process_srl(&mut self, dec_insn: RType) -> Self::InstructionResult {
171 Instruction::from_r_type(Opcode::SRL, &dec_insn)
172 }
173
174 fn process_srli(&mut self, dec_insn: ITypeShamt) -> Self::InstructionResult {
175 Instruction::from_i_type_shamt(Opcode::SRL, &dec_insn)
176 }
177
178 fn process_sra(&mut self, dec_insn: RType) -> Self::InstructionResult {
179 Instruction::from_r_type(Opcode::SRA, &dec_insn)
180 }
181
182 fn process_srai(&mut self, dec_insn: ITypeShamt) -> Self::InstructionResult {
183 Instruction::from_i_type_shamt(Opcode::SRA, &dec_insn)
184 }
185
186 fn process_slt(&mut self, dec_insn: RType) -> Self::InstructionResult {
187 Instruction::from_r_type(Opcode::SLT, &dec_insn)
188 }
189
190 fn process_slti(&mut self, dec_insn: IType) -> Self::InstructionResult {
191 Instruction::from_i_type(Opcode::SLT, &dec_insn)
192 }
193
194 fn process_sltu(&mut self, dec_insn: RType) -> Self::InstructionResult {
195 Instruction::from_r_type(Opcode::SLTU, &dec_insn)
196 }
197
198 fn process_sltui(&mut self, dec_insn: IType) -> Self::InstructionResult {
199 Instruction::from_i_type(Opcode::SLTU, &dec_insn)
200 }
201
202 fn process_lb(&mut self, dec_insn: IType) -> Self::InstructionResult {
203 Instruction::from_i_type(Opcode::LB, &dec_insn)
204 }
205
206 fn process_lh(&mut self, dec_insn: IType) -> Self::InstructionResult {
207 Instruction::from_i_type(Opcode::LH, &dec_insn)
208 }
209
210 fn process_lw(&mut self, dec_insn: IType) -> Self::InstructionResult {
211 Instruction::from_i_type(Opcode::LW, &dec_insn)
212 }
213
214 fn process_lbu(&mut self, dec_insn: IType) -> Self::InstructionResult {
215 Instruction::from_i_type(Opcode::LBU, &dec_insn)
216 }
217
218 fn process_lhu(&mut self, dec_insn: IType) -> Self::InstructionResult {
219 Instruction::from_i_type(Opcode::LHU, &dec_insn)
220 }
221
222 fn process_sb(&mut self, dec_insn: SType) -> Self::InstructionResult {
223 Instruction::from_s_type(Opcode::SB, &dec_insn)
224 }
225
226 fn process_sh(&mut self, dec_insn: SType) -> Self::InstructionResult {
227 Instruction::from_s_type(Opcode::SH, &dec_insn)
228 }
229
230 fn process_sw(&mut self, dec_insn: SType) -> Self::InstructionResult {
231 Instruction::from_s_type(Opcode::SW, &dec_insn)
232 }
233
234 fn process_beq(&mut self, dec_insn: BType) -> Self::InstructionResult {
235 Instruction::from_b_type(Opcode::BEQ, &dec_insn)
236 }
237
238 fn process_bne(&mut self, dec_insn: BType) -> Self::InstructionResult {
239 Instruction::from_b_type(Opcode::BNE, &dec_insn)
240 }
241
242 fn process_blt(&mut self, dec_insn: BType) -> Self::InstructionResult {
243 Instruction::from_b_type(Opcode::BLT, &dec_insn)
244 }
245
246 fn process_bge(&mut self, dec_insn: BType) -> Self::InstructionResult {
247 Instruction::from_b_type(Opcode::BGE, &dec_insn)
248 }
249
250 fn process_bltu(&mut self, dec_insn: BType) -> Self::InstructionResult {
251 Instruction::from_b_type(Opcode::BLTU, &dec_insn)
252 }
253
254 fn process_bgeu(&mut self, dec_insn: BType) -> Self::InstructionResult {
255 Instruction::from_b_type(Opcode::BGEU, &dec_insn)
256 }
257
258 fn process_jal(&mut self, dec_insn: JType) -> Self::InstructionResult {
259 Instruction::new(Opcode::JAL, dec_insn.rd as u8, dec_insn.imm as u64, 0, true, true)
260 }
261
262 fn process_jalr(&mut self, dec_insn: IType) -> Self::InstructionResult {
263 Instruction::new(
264 Opcode::JALR,
265 dec_insn.rd as u8,
266 dec_insn.rs1,
267 dec_insn.imm as u64,
268 false,
269 true,
270 )
271 }
272
273 fn process_lui(&mut self, dec_insn: UType) -> Self::InstructionResult {
274 Instruction::from_u_type(Opcode::LUI, &dec_insn)
275 }
276
277 fn process_auipc(&mut self, dec_insn: UType) -> Self::InstructionResult {
279 Instruction::from_u_type(Opcode::AUIPC, &dec_insn)
280 }
281
282 fn process_ecall(&mut self) -> Self::InstructionResult {
283 Instruction::new(
284 Opcode::ECALL,
285 Register::X5 as u8,
286 Register::X10 as u64,
287 Register::X11 as u64,
288 false,
289 false,
290 )
291 }
292
293 fn process_ebreak(&mut self) -> Self::InstructionResult {
294 Instruction::new(Opcode::EBREAK, 0, 0, 0, false, false)
295 }
296
297 fn process_mul(&mut self, dec_insn: RType) -> Self::InstructionResult {
298 Instruction::from_r_type(Opcode::MUL, &dec_insn)
299 }
300
301 fn process_mulh(&mut self, dec_insn: RType) -> Self::InstructionResult {
302 Instruction::from_r_type(Opcode::MULH, &dec_insn)
303 }
304
305 fn process_mulhu(&mut self, dec_insn: RType) -> Self::InstructionResult {
306 Instruction::from_r_type(Opcode::MULHU, &dec_insn)
307 }
308
309 fn process_mulhsu(&mut self, dec_insn: RType) -> Self::InstructionResult {
310 Instruction::from_r_type(Opcode::MULHSU, &dec_insn)
311 }
312
313 fn process_div(&mut self, dec_insn: RType) -> Self::InstructionResult {
314 Instruction::from_r_type(Opcode::DIV, &dec_insn)
315 }
316
317 fn process_divu(&mut self, dec_insn: RType) -> Self::InstructionResult {
318 Instruction::from_r_type(Opcode::DIVU, &dec_insn)
319 }
320
321 fn process_rem(&mut self, dec_insn: RType) -> Self::InstructionResult {
322 Instruction::from_r_type(Opcode::REM, &dec_insn)
323 }
324
325 fn process_remu(&mut self, dec_insn: RType) -> Self::InstructionResult {
326 Instruction::from_r_type(Opcode::REMU, &dec_insn)
327 }
328
329 fn process_csrrc(&mut self, _: ITypeCSR) -> Self::InstructionResult {
330 Instruction::unimp()
331 }
332
333 fn process_csrrci(&mut self, _: ITypeCSR) -> Self::InstructionResult {
334 Instruction::unimp()
335 }
336
337 fn process_csrrs(&mut self, _: ITypeCSR) -> Self::InstructionResult {
338 Instruction::unimp()
339 }
340
341 fn process_csrrsi(&mut self, _: ITypeCSR) -> Self::InstructionResult {
342 Instruction::unimp()
343 }
344
345 fn process_csrrw(&mut self, _: ITypeCSR) -> Self::InstructionResult {
346 Instruction::unimp()
347 }
348
349 fn process_csrrwi(&mut self, _: ITypeCSR) -> Self::InstructionResult {
350 Instruction::unimp()
351 }
352
353 fn process_fence(&mut self, _: IType) -> Self::InstructionResult {
354 Instruction::unimp()
355 }
356
357 fn process_mret(&mut self) -> Self::InstructionResult {
358 Instruction::unimp()
359 }
360
361 fn process_wfi(&mut self) -> Self::InstructionResult {
362 Instruction::unimp()
363 }
364
365 fn process_addw(&mut self, dec_insn: RType) -> Self::InstructionResult {
367 Instruction::from_r_type(Opcode::ADDW, &dec_insn)
368 }
369
370 fn process_subw(&mut self, dec_insn: RType) -> Self::InstructionResult {
371 Instruction::from_r_type(Opcode::SUBW, &dec_insn)
372 }
373
374 fn process_sllw(&mut self, dec_insn: RType) -> Self::InstructionResult {
375 Instruction::from_r_type(Opcode::SLLW, &dec_insn)
376 }
377
378 fn process_srlw(&mut self, dec_insn: RType) -> Self::InstructionResult {
379 Instruction::from_r_type(Opcode::SRLW, &dec_insn)
380 }
381
382 fn process_sraw(&mut self, dec_insn: RType) -> Self::InstructionResult {
383 Instruction::from_r_type(Opcode::SRAW, &dec_insn)
384 }
385
386 fn process_addiw(&mut self, dec_insn: IType) -> Self::InstructionResult {
387 Instruction::from_i_type(Opcode::ADDW, &dec_insn)
388 }
389
390 fn process_slliw(&mut self, dec_insn: ITypeShamtW) -> Self::InstructionResult {
391 Instruction::from_i_type_shamt_w(Opcode::SLLW, &dec_insn)
392 }
393
394 fn process_srliw(&mut self, dec_insn: ITypeShamtW) -> Self::InstructionResult {
395 Instruction::from_i_type_shamt_w(Opcode::SRLW, &dec_insn)
396 }
397
398 fn process_sraiw(&mut self, dec_insn: ITypeShamtW) -> Self::InstructionResult {
399 Instruction::from_i_type_shamt_w(Opcode::SRAW, &dec_insn)
400 }
401
402 fn process_lwu(&mut self, dec_insn: IType) -> Self::InstructionResult {
403 Instruction::from_i_type(Opcode::LWU, &dec_insn)
404 }
405
406 fn process_ld(&mut self, dec_insn: IType) -> Self::InstructionResult {
407 Instruction::from_i_type(Opcode::LD, &dec_insn)
408 }
409
410 fn process_sd(&mut self, dec_insn: SType) -> Self::InstructionResult {
411 Instruction::from_s_type(Opcode::SD, &dec_insn)
412 }
413
414 fn process_mulw(&mut self, dec_insn: RType) -> Self::InstructionResult {
416 Instruction::from_r_type(Opcode::MULW, &dec_insn)
417 }
418
419 fn process_divw(&mut self, dec_insn: RType) -> Self::InstructionResult {
420 Instruction::from_r_type(Opcode::DIVW, &dec_insn)
421 }
422
423 fn process_divuw(&mut self, dec_insn: RType) -> Self::InstructionResult {
424 Instruction::from_r_type(Opcode::DIVUW, &dec_insn)
425 }
426
427 fn process_remw(&mut self, dec_insn: RType) -> Self::InstructionResult {
428 Instruction::from_r_type(Opcode::REMW, &dec_insn)
429 }
430
431 fn process_remuw(&mut self, dec_insn: RType) -> Self::InstructionResult {
432 Instruction::from_r_type(Opcode::REMUW, &dec_insn)
433 }
434}
435
436#[must_use]
442pub(crate) fn transpile(instructions_u32: &[u32]) -> Vec<(Instruction, u32)> {
443 let mut instructions: Vec<(Instruction, u32)> = Vec::new();
444 let mut transpiler = InstructionTranspiler;
445 for instruction_u32 in instructions_u32 {
446 let instruction = process_instruction(&mut transpiler, *instruction_u32).unwrap();
447 instructions.push((instruction, *instruction_u32));
448 }
449 instructions
450}