Skip to main content

sp1_jit/backends/
debug.rs

1use crate::{
2    debug, ComputeInstructions, ControlFlowInstructions, DebugFn, Debuggable, EcallHandler,
3    ExternFn, JitContext, JitFunction, JitMemory, MemoryInstructions, RiscOperand, RiscRegister,
4    RiscvTranspiler, SystemInstructions, TraceCollector,
5};
6use std::io;
7
8pub struct DebugBackend<B: RiscvTranspiler> {
9    backend: B,
10}
11
12impl<B: RiscvTranspiler> DebugBackend<B> {
13    pub const fn new(backend: B) -> Self {
14        Self { backend }
15    }
16}
17
18impl<B: RiscvTranspiler + Debuggable> RiscvTranspiler for DebugBackend<B> {
19    fn new(
20        program_size: usize,
21        memory_size: usize,
22        max_trace_size: u64,
23        pc_start: u64,
24        pc_base: u64,
25        clk_bump: u64,
26    ) -> Result<Self, std::io::Error> {
27        let backend =
28            B::new(program_size, memory_size, max_trace_size, pc_start, pc_base, clk_bump)?;
29
30        Ok(Self::new(backend))
31    }
32
33    fn register_ecall_handler(&mut self, handler: EcallHandler) {
34        self.backend.register_ecall_handler(handler);
35    }
36
37    fn start_instr(&mut self) {
38        extern "C" fn print_bar(_: *mut JitContext) {
39            eprintln!("--------------------------------");
40        }
41
42        extern "C" fn collect_registers(ctx: *mut JitContext) {
43            let ctx = unsafe { &mut *ctx };
44            if let Some(sender) = &ctx.debug_sender {
45                sender
46                    .send(Some(debug::State {
47                        pc: ctx.pc,
48                        clk: ctx.clk,
49                        global_clk: ctx.global_clk,
50                        registers: ctx.registers,
51                    }))
52                    .expect("Failed to send debug state");
53            }
54        }
55
56        self.backend.start_instr();
57        self.backend.call_extern_fn(collect_registers);
58        self.backend.call_extern_fn(print_bar);
59        self.backend.print_ctx();
60    }
61
62    fn end_instr(&mut self) {
63        self.backend.end_instr();
64    }
65
66    fn inspect_register(&mut self, reg: RiscRegister, handler: DebugFn) {
67        self.backend.inspect_register(reg, handler);
68    }
69
70    fn inspect_immediate(&mut self, imm: u64, handler: DebugFn) {
71        self.backend.inspect_immediate(imm, handler);
72    }
73
74    fn call_extern_fn(&mut self, handler: ExternFn) {
75        self.backend.call_extern_fn(handler);
76    }
77
78    fn finalize<M: JitMemory>(self) -> io::Result<JitFunction<M>> {
79        self.backend.finalize()
80    }
81}
82
83impl<B: RiscvTranspiler> MemoryInstructions for DebugBackend<B> {
84    fn lb(&mut self, rd: RiscRegister, rs1: RiscRegister, imm: u64) {
85        extern "C" fn lb(ctx: *mut JitContext) {
86            let ctx = unsafe { &mut *ctx };
87            eprintln!("-- opcode = lb: pc={}", ctx.pc);
88        }
89
90        self.backend.call_extern_fn(lb);
91        self.backend.lb(rd, rs1, imm);
92    }
93
94    fn lh(&mut self, rd: RiscRegister, rs1: RiscRegister, imm: u64) {
95        extern "C" fn lh(ctx: *mut JitContext) {
96            let ctx = unsafe { &mut *ctx };
97            eprintln!("-- opcode = lh: pc={}", ctx.pc);
98        }
99
100        self.backend.call_extern_fn(lh);
101        self.backend.lh(rd, rs1, imm);
102    }
103
104    fn lw(&mut self, rd: RiscRegister, rs1: RiscRegister, imm: u64) {
105        extern "C" fn lw(ctx: *mut JitContext) {
106            let ctx = unsafe { &mut *ctx };
107            eprintln!("-- opcode = lw: pc={}", ctx.pc);
108        }
109
110        extern "C" fn lw_imm_value(imm: u64) {
111            eprintln!("-- lw_imm_value: value={imm}");
112        }
113
114        extern "C" fn lw_rs1_value(rs1: u64) {
115            eprintln!("-- lw_rs1_value={rs1}");
116        }
117
118        extern "C" fn lw_rs1(rs1: u64) {
119            eprintln!("-- lw_rs1={rs1}");
120        }
121
122        extern "C" fn lw_rd(rd: u64) {
123            eprintln!("-- lw_rd={rd}");
124        }
125
126        self.inspect_immediate(imm, lw_imm_value);
127        self.inspect_immediate(rd as u8 as u64, lw_rd);
128        self.inspect_immediate(rs1 as u8 as u64, lw_rs1);
129        self.inspect_register(rs1, lw_rs1_value);
130
131        self.backend.call_extern_fn(lw);
132        self.backend.lw(rd, rs1, imm);
133    }
134
135    fn lbu(&mut self, rd: RiscRegister, rs1: RiscRegister, imm: u64) {
136        extern "C" fn lbu(ctx: *mut JitContext) {
137            let ctx = unsafe { &mut *ctx };
138            eprintln!("-- opcode = lbu: pc={}", ctx.pc);
139        }
140
141        self.backend.call_extern_fn(lbu);
142        self.backend.lbu(rd, rs1, imm);
143    }
144
145    fn lhu(&mut self, rd: RiscRegister, rs1: RiscRegister, imm: u64) {
146        extern "C" fn lhu(ctx: *mut JitContext) {
147            let ctx = unsafe { &mut *ctx };
148            eprintln!("-- opcode = lhu: pc={}", ctx.pc);
149        }
150
151        self.backend.call_extern_fn(lhu);
152        self.backend.lhu(rd, rs1, imm);
153    }
154
155    fn ld(&mut self, rd: RiscRegister, rs1: RiscRegister, imm: u64) {
156        extern "C" fn ld(ctx: *mut JitContext) {
157            let ctx = unsafe { &mut *ctx };
158            eprintln!("-- opcode = ld: pc={}", ctx.pc);
159        }
160
161        extern "C" fn ld_imm_value(imm: u64) {
162            eprintln!("-- ld_imm_value: value={imm}");
163        }
164
165        extern "C" fn ld_rs1_value(rs1: u64) {
166            eprintln!("-- ld_rs1_value={rs1}");
167        }
168
169        self.backend.call_extern_fn(ld);
170        self.inspect_immediate(imm, ld_imm_value);
171        self.inspect_register(rs1, ld_rs1_value);
172        self.backend.ld(rd, rs1, imm);
173    }
174
175    fn lwu(&mut self, rd: RiscRegister, rs1: RiscRegister, imm: u64) {
176        extern "C" fn lwu(ctx: *mut JitContext) {
177            let ctx = unsafe { &mut *ctx };
178            eprintln!("-- opcode = lwu: pc={}", ctx.pc);
179        }
180
181        self.backend.call_extern_fn(lwu);
182        self.backend.lwu(rd, rs1, imm);
183    }
184
185    fn sb(&mut self, rs1: RiscRegister, rs2: RiscRegister, imm: u64) {
186        extern "C" fn sb(ctx: *mut JitContext) {
187            let ctx = unsafe { &mut *ctx };
188            eprintln!("-- opcode = sb: pc={}", ctx.pc);
189        }
190
191        self.backend.call_extern_fn(sb);
192        self.backend.sb(rs1, rs2, imm);
193    }
194
195    fn sh(&mut self, rs1: RiscRegister, rs2: RiscRegister, imm: u64) {
196        extern "C" fn sh(ctx: *mut JitContext) {
197            let ctx = unsafe { &mut *ctx };
198            eprintln!("-- opcode = sh: pc={}", ctx.pc);
199        }
200
201        self.backend.call_extern_fn(sh);
202        self.backend.sh(rs1, rs2, imm);
203    }
204
205    fn sw(&mut self, rs1: RiscRegister, rs2: RiscRegister, imm: u64) {
206        extern "C" fn sw(ctx: *mut JitContext) {
207            let ctx = unsafe { &mut *ctx };
208            eprintln!("-- opcode = sw: pc={}", ctx.pc);
209        }
210
211        extern "C" fn sw_imm_value(imm: u64) {
212            eprintln!("-- sw_imm_value: value={imm}");
213        }
214
215        extern "C" fn sw_rs1_value(rs1: u64) {
216            eprintln!("-- sw_rs1_value={rs1}");
217        }
218
219        extern "C" fn sw_rs2_value(rs2: u64) {
220            eprintln!("-- sw_rs2_value={rs2}");
221        }
222
223        extern "C" fn sw_rs2(rs2: u64) {
224            eprintln!("-- sw_rs2={rs2}");
225        }
226
227        extern "C" fn sw_rs1(rs1: u64) {
228            eprintln!("-- sw_rs1={rs1}");
229        }
230
231        self.inspect_immediate(rs1 as u8 as u64, sw_rs1);
232        self.inspect_immediate(rs2 as u8 as u64, sw_rs2);
233        self.inspect_immediate(imm, sw_imm_value);
234
235        self.inspect_register(rs1, sw_rs1_value);
236        self.inspect_register(rs2, sw_rs2_value);
237
238        self.backend.call_extern_fn(sw);
239        self.backend.sw(rs1, rs2, imm);
240    }
241
242    fn sd(&mut self, rs1: RiscRegister, rs2: RiscRegister, imm: u64) {
243        extern "C" fn sd(ctx: *mut JitContext) {
244            let ctx = unsafe { &mut *ctx };
245            eprintln!("-- opcode = sd: pc={}", ctx.pc);
246        }
247
248        extern "C" fn sd_imm_value(imm: u64) {
249            eprintln!("-- sd_imm_value: value={imm}");
250        }
251
252        extern "C" fn sd_rs1_value(rs1: u64) {
253            eprintln!("-- sd_rs1_value={rs1}");
254        }
255
256        extern "C" fn sd_rs2_value(rs2: u64) {
257            eprintln!("-- sd_rs2_value={rs2}");
258        }
259
260        self.backend.call_extern_fn(sd);
261        self.inspect_immediate(imm, sd_imm_value);
262        self.inspect_register(rs1, sd_rs1_value);
263        self.inspect_register(rs2, sd_rs2_value);
264        self.backend.sd(rs1, rs2, imm);
265    }
266}
267
268impl<B: RiscvTranspiler> ControlFlowInstructions for DebugBackend<B> {
269    fn beq(&mut self, rs1: RiscRegister, rs2: RiscRegister, imm: u64) {
270        extern "C" fn beq(ctx: *mut JitContext) {
271            let ctx = unsafe { &mut *ctx };
272            eprintln!("-- opcode = beq: pc={}", ctx.pc);
273        }
274
275        self.backend.call_extern_fn(beq);
276        self.backend.beq(rs1, rs2, imm);
277    }
278
279    fn bne(&mut self, rs1: RiscRegister, rs2: RiscRegister, imm: u64) {
280        extern "C" fn bne(ctx: *mut JitContext) {
281            let ctx = unsafe { &mut *ctx };
282            eprintln!("-- opcode = bne: pc={}", ctx.pc);
283        }
284
285        self.backend.call_extern_fn(bne);
286        self.backend.bne(rs1, rs2, imm);
287    }
288
289    fn blt(&mut self, rs1: RiscRegister, rs2: RiscRegister, imm: u64) {
290        extern "C" fn blt(ctx: *mut JitContext) {
291            let ctx = unsafe { &mut *ctx };
292            eprintln!("-- opcode = blt: pc={}", ctx.pc);
293        }
294
295        self.backend.call_extern_fn(blt);
296        self.backend.blt(rs1, rs2, imm);
297    }
298
299    fn bge(&mut self, rs1: RiscRegister, rs2: RiscRegister, imm: u64) {
300        extern "C" fn bge(ctx: *mut JitContext) {
301            let ctx = unsafe { &mut *ctx };
302            eprintln!("-- opcode = bge: pc={}", ctx.pc);
303        }
304
305        self.backend.call_extern_fn(bge);
306        self.backend.bge(rs1, rs2, imm);
307    }
308
309    fn bltu(&mut self, rs1: RiscRegister, rs2: RiscRegister, imm: u64) {
310        extern "C" fn bltu(ctx: *mut JitContext) {
311            let ctx = unsafe { &mut *ctx };
312            eprintln!("-- opcode = bltu: pc={}", ctx.pc);
313        }
314
315        self.backend.call_extern_fn(bltu);
316        self.backend.bltu(rs1, rs2, imm);
317    }
318
319    fn bgeu(&mut self, rs1: RiscRegister, rs2: RiscRegister, imm: u64) {
320        extern "C" fn bgeu(ctx: *mut JitContext) {
321            let ctx = unsafe { &mut *ctx };
322            eprintln!("-- opcode = bgeu: pc={}", ctx.pc);
323        }
324
325        self.backend.call_extern_fn(bgeu);
326        self.backend.bgeu(rs1, rs2, imm);
327    }
328
329    fn jal(&mut self, rd: RiscRegister, imm: u64) {
330        extern "C" fn jal(ctx: *mut JitContext) {
331            let ctx = unsafe { &mut *ctx };
332            eprintln!("-- opcode = jal: pc={}", ctx.pc);
333        }
334
335        self.backend.call_extern_fn(jal);
336        self.backend.jal(rd, imm);
337    }
338
339    fn jalr(&mut self, rd: RiscRegister, rs1: RiscRegister, imm: u64) {
340        extern "C" fn jalr(ctx: *mut JitContext) {
341            let ctx = unsafe { &mut *ctx };
342            eprintln!("-- opcode = jalr: pc={}", ctx.pc);
343        }
344
345        self.backend.call_extern_fn(jalr);
346
347        extern "C" fn jalr_reg_value(register: u64) {
348            eprintln!("-- jalr_reg_value: value={register}");
349        }
350
351        extern "C" fn jalr_imm_value(imm: u64) {
352            eprintln!("-- jalr_imm_value: value={imm}");
353        }
354
355        extern "C" fn jalr_rs1(rs1: u64) {
356            eprintln!("-- jalr_rs1={rs1}");
357        }
358
359        extern "C" fn jalr_rd(rd: u64) {
360            eprintln!("-- jalr_rd={rd}");
361        }
362
363        self.inspect_immediate(rd as u8 as u64, jalr_rd);
364        self.backend.inspect_register(rs1, jalr_reg_value);
365        self.backend.inspect_immediate(rs1 as u8 as u64, jalr_rs1);
366        self.backend.inspect_immediate(imm, jalr_imm_value);
367
368        self.backend.jalr(rd, rs1, imm);
369    }
370}
371
372impl<B: RiscvTranspiler> SystemInstructions for DebugBackend<B> {
373    fn ecall(&mut self) {
374        extern "C" fn ecall(ctx: *mut JitContext) {
375            let ctx = unsafe { &mut *ctx };
376            eprintln!("ecall at pc: {}", ctx.pc);
377        }
378
379        self.backend.call_extern_fn(ecall);
380        self.backend.ecall();
381    }
382
383    fn unimp(&mut self) {
384        extern "C" fn unimp(ctx: *mut JitContext) {
385            let ctx = unsafe { &mut *ctx };
386            eprintln!("Unimplemented instruction at pc: {}", ctx.pc);
387            // Trap via SIGILL so the parent maps this to a typed `Unimplemented`
388            // cause instead of a generic abort.
389            unsafe { libc::raise(libc::SIGILL) };
390        }
391
392        self.backend.call_extern_fn(unimp);
393    }
394}
395
396impl<B: RiscvTranspiler> ComputeInstructions for DebugBackend<B> {
397    fn add(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
398        extern "C" fn add(ctx: *mut JitContext) {
399            let ctx = unsafe { &mut *ctx };
400            eprintln!("-- opcode = add: pc={}", ctx.pc);
401        }
402
403        self.backend.call_extern_fn(add);
404        self.backend.add(rd, rs1, rs2);
405    }
406
407    fn sub(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
408        extern "C" fn sub(ctx: *mut JitContext) {
409            let ctx = unsafe { &mut *ctx };
410            eprintln!("-- opcode = sub: pc={}", ctx.pc);
411        }
412
413        self.backend.call_extern_fn(sub);
414        self.backend.sub(rd, rs1, rs2);
415    }
416
417    fn xor(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
418        extern "C" fn xor(ctx: *mut JitContext) {
419            let ctx = unsafe { &mut *ctx };
420            eprintln!("-- opcode = xor: pc={}", ctx.pc);
421        }
422
423        self.backend.call_extern_fn(xor);
424        self.backend.xor(rd, rs1, rs2);
425    }
426
427    fn or(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
428        extern "C" fn or(ctx: *mut JitContext) {
429            let ctx = unsafe { &mut *ctx };
430            eprintln!("-- opcode = or: pc={}", ctx.pc);
431        }
432
433        self.backend.call_extern_fn(or);
434        self.backend.or(rd, rs1, rs2);
435    }
436
437    fn and(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
438        extern "C" fn and(ctx: *mut JitContext) {
439            let ctx = unsafe { &mut *ctx };
440            eprintln!("-- opcode = and: pc={}", ctx.pc);
441        }
442
443        self.backend.call_extern_fn(and);
444        self.backend.and(rd, rs1, rs2);
445    }
446
447    fn sll(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
448        extern "C" fn sll(ctx: *mut JitContext) {
449            let ctx = unsafe { &mut *ctx };
450            eprintln!("-- opcode = sll: pc={}", ctx.pc);
451        }
452
453        self.backend.call_extern_fn(sll);
454        self.backend.sll(rd, rs1, rs2);
455    }
456
457    fn srl(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
458        extern "C" fn srl(ctx: *mut JitContext) {
459            let ctx = unsafe { &mut *ctx };
460            eprintln!("-- opcode = srl: pc={}", ctx.pc);
461        }
462
463        self.backend.call_extern_fn(srl);
464        self.backend.srl(rd, rs1, rs2);
465    }
466
467    fn sra(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
468        extern "C" fn sra(ctx: *mut JitContext) {
469            let ctx = unsafe { &mut *ctx };
470            eprintln!("-- opcode = sra: pc={}", ctx.pc);
471        }
472
473        self.backend.call_extern_fn(sra);
474        self.backend.sra(rd, rs1, rs2);
475    }
476
477    fn slt(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
478        extern "C" fn slt(ctx: *mut JitContext) {
479            let ctx = unsafe { &mut *ctx };
480            eprintln!("-- opcode = slt: pc={}", ctx.pc);
481        }
482
483        self.backend.call_extern_fn(slt);
484        self.backend.slt(rd, rs1, rs2);
485    }
486
487    fn sltu(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
488        extern "C" fn sltu(ctx: *mut JitContext) {
489            let ctx = unsafe { &mut *ctx };
490            eprintln!("-- opcode = sltu: pc={}", ctx.pc);
491        }
492
493        self.backend.call_extern_fn(sltu);
494        self.backend.sltu(rd, rs1, rs2);
495    }
496
497    fn mul(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
498        extern "C" fn mul(ctx: *mut JitContext) {
499            let ctx = unsafe { &mut *ctx };
500            eprintln!("-- opcode = mul: pc={}", ctx.pc);
501        }
502
503        self.backend.call_extern_fn(mul);
504        self.backend.mul(rd, rs1, rs2);
505    }
506
507    fn mulh(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
508        extern "C" fn mulh(ctx: *mut JitContext) {
509            let ctx = unsafe { &mut *ctx };
510            eprintln!("-- opcode = mulh: pc={}", ctx.pc);
511        }
512
513        self.backend.call_extern_fn(mulh);
514        self.backend.mulh(rd, rs1, rs2);
515    }
516
517    fn mulhu(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
518        extern "C" fn mulhu(ctx: *mut JitContext) {
519            let ctx = unsafe { &mut *ctx };
520            eprintln!("-- opcode = mulhu: pc={}", ctx.pc);
521        }
522
523        self.backend.call_extern_fn(mulhu);
524        self.backend.mulhu(rd, rs1, rs2);
525    }
526
527    fn mulhsu(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
528        extern "C" fn mulhsu(ctx: *mut JitContext) {
529            let ctx = unsafe { &mut *ctx };
530            eprintln!("-- opcode = mulhsu: pc={}", ctx.pc);
531        }
532
533        self.backend.call_extern_fn(mulhsu);
534        self.backend.mulhsu(rd, rs1, rs2);
535    }
536
537    fn div(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
538        extern "C" fn div(ctx: *mut JitContext) {
539            let ctx = unsafe { &mut *ctx };
540            eprintln!("-- opcode = div: pc={}", ctx.pc);
541        }
542
543        self.backend.call_extern_fn(div);
544        self.backend.div(rd, rs1, rs2);
545    }
546
547    fn divu(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
548        extern "C" fn divu(ctx: *mut JitContext) {
549            let ctx = unsafe { &mut *ctx };
550            eprintln!("-- opcode = divu: pc={}", ctx.pc);
551        }
552
553        self.backend.call_extern_fn(divu);
554        self.backend.divu(rd, rs1, rs2);
555    }
556
557    fn rem(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
558        extern "C" fn rem(ctx: *mut JitContext) {
559            let ctx = unsafe { &mut *ctx };
560            eprintln!("-- opcode = rem: pc={}", ctx.pc);
561        }
562
563        self.backend.call_extern_fn(rem);
564        self.backend.rem(rd, rs1, rs2);
565    }
566
567    fn remu(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
568        extern "C" fn remu(ctx: *mut JitContext) {
569            let ctx = unsafe { &mut *ctx };
570            eprintln!("-- opcode = remu: pc={}", ctx.pc);
571        }
572
573        self.backend.call_extern_fn(remu);
574        self.backend.remu(rd, rs1, rs2);
575    }
576
577    fn addw(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
578        extern "C" fn addw(ctx: *mut JitContext) {
579            let ctx = unsafe { &mut *ctx };
580            eprintln!("-- opcode = addw: pc={}", ctx.pc);
581        }
582
583        self.backend.call_extern_fn(addw);
584        self.backend.addw(rd, rs1, rs2);
585    }
586
587    fn subw(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
588        extern "C" fn subw(ctx: *mut JitContext) {
589            let ctx = unsafe { &mut *ctx };
590            eprintln!("-- opcode = subw: pc={}", ctx.pc);
591        }
592
593        self.backend.call_extern_fn(subw);
594        self.backend.subw(rd, rs1, rs2);
595    }
596
597    fn sllw(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
598        extern "C" fn sllw(ctx: *mut JitContext) {
599            let ctx = unsafe { &mut *ctx };
600            eprintln!("-- opcode = sllw: pc={}", ctx.pc);
601        }
602
603        self.backend.call_extern_fn(sllw);
604        self.backend.sllw(rd, rs1, rs2);
605    }
606
607    fn srlw(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
608        extern "C" fn srlw(ctx: *mut JitContext) {
609            let ctx = unsafe { &mut *ctx };
610            eprintln!("-- opcode = srlw: pc={}", ctx.pc);
611        }
612
613        self.backend.call_extern_fn(srlw);
614        self.backend.srlw(rd, rs1, rs2);
615    }
616
617    fn sraw(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
618        extern "C" fn sraw(ctx: *mut JitContext) {
619            let ctx = unsafe { &mut *ctx };
620            eprintln!("-- opcode = sraw: pc={}", ctx.pc);
621        }
622
623        self.backend.call_extern_fn(sraw);
624        self.backend.sraw(rd, rs1, rs2);
625    }
626
627    fn mulw(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
628        extern "C" fn mulw(ctx: *mut JitContext) {
629            let ctx = unsafe { &mut *ctx };
630            eprintln!("-- opcode = mulw: pc={}", ctx.pc);
631        }
632
633        self.backend.call_extern_fn(mulw);
634        self.backend.mulw(rd, rs1, rs2);
635    }
636
637    fn divw(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
638        extern "C" fn divw(ctx: *mut JitContext) {
639            let ctx = unsafe { &mut *ctx };
640            eprintln!("-- opcode = divw: pc={}", ctx.pc);
641        }
642
643        self.backend.call_extern_fn(divw);
644        self.backend.divw(rd, rs1, rs2);
645    }
646
647    fn divuw(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
648        extern "C" fn divuw(ctx: *mut JitContext) {
649            let ctx = unsafe { &mut *ctx };
650            eprintln!("-- opcode = divuw: pc={}", ctx.pc);
651        }
652
653        self.backend.call_extern_fn(divuw);
654        self.backend.divuw(rd, rs1, rs2);
655    }
656
657    fn remw(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
658        extern "C" fn remw(ctx: *mut JitContext) {
659            let ctx = unsafe { &mut *ctx };
660            eprintln!("-- opcode = remw: pc={}", ctx.pc);
661        }
662
663        self.backend.call_extern_fn(remw);
664        self.backend.remw(rd, rs1, rs2);
665    }
666
667    fn remuw(&mut self, rd: RiscRegister, rs1: RiscOperand, rs2: RiscOperand) {
668        extern "C" fn remuw(ctx: *mut JitContext) {
669            let ctx = unsafe { &mut *ctx };
670            eprintln!("-- opcode = remuw: pc={}", ctx.pc);
671        }
672
673        self.backend.call_extern_fn(remuw);
674        self.backend.remuw(rd, rs1, rs2);
675    }
676
677    fn auipc(&mut self, rd: RiscRegister, imm: u64) {
678        extern "C" fn auipc(ctx: *mut JitContext) {
679            let ctx = unsafe { &mut *ctx };
680            eprintln!("-- opcode = auipc: pc={}", ctx.pc);
681        }
682
683        extern "C" fn auipc_rd(rd: u64) {
684            eprintln!("-- auipc_rd={rd}");
685        }
686
687        extern "C" fn auipc_imm(imm: u64) {
688            eprintln!("-- auipc_imm={imm}");
689        }
690
691        self.inspect_immediate(rd as u8 as u64, auipc_rd);
692        self.inspect_immediate(imm, auipc_imm);
693
694        self.backend.call_extern_fn(auipc);
695        self.backend.auipc(rd, imm);
696    }
697
698    fn lui(&mut self, rd: RiscRegister, imm: u64) {
699        extern "C" fn lui(ctx: *mut JitContext) {
700            let ctx = unsafe { &mut *ctx };
701            eprintln!("-- opcode = lui: pc={}", ctx.pc);
702        }
703
704        extern "C" fn lui_rd(rd: u64) {
705            eprintln!("-- lui_rd={rd}");
706        }
707
708        extern "C" fn lui_imm(imm: u64) {
709            eprintln!("-- lui_imm={imm}");
710        }
711
712        self.inspect_immediate(rd as u8 as u64, lui_rd);
713        self.inspect_immediate(imm, lui_imm);
714
715        self.backend.call_extern_fn(lui);
716        self.backend.lui(rd, imm);
717    }
718}
719
720impl<B: RiscvTranspiler> TraceCollector for DebugBackend<B> {
721    fn trace_clk_end(&mut self) {
722        self.backend.trace_clk_end();
723    }
724
725    fn trace_clk_start(&mut self) {
726        self.backend.trace_clk_start();
727    }
728
729    fn trace_mem_value(&mut self, rs1: RiscRegister, imm: u64) {
730        self.backend.trace_mem_value(rs1, imm);
731    }
732
733    fn trace_pc_start(&mut self) {
734        self.backend.trace_pc_start();
735    }
736
737    fn trace_registers(&mut self) {
738        self.backend.trace_registers();
739    }
740}