pulley_interpreter/interp/
debug.rs1use super::Interpreter;
17use crate::decode::{ExtendedOpVisitor, OpVisitor};
18use crate::imms::*;
19use crate::regs::*;
20use alloc::string::ToString;
21
22const DEBUG: bool = false;
24
25const DEBUG_X_REGS: bool = true;
27const DEBUG_F_REGS: bool = false;
28
29#[cfg(not(feature = "std"))]
30macro_rules! print {
31 ($($t:tt)*) => ({ let _ = format_args!($($t)*); })
32}
33#[cfg(not(feature = "std"))]
34macro_rules! println {
35 () => ();
36 ($($t:tt)*) => ({ let _ = format_args!($($t)*); })
37}
38
39#[repr(transparent)]
40pub(super) struct Debug<'a>(pub Interpreter<'a>);
41
42macro_rules! debug_then_delegate {
43 (
44 $(
45 $( #[$attr:meta] )*
46 $snake_name:ident = $name:ident $( {
47 $(
48 $( #[$field_attr:meta] )*
49 $field:ident : $field_ty:ty
50 ),*
51 } )? ;
52 )*
53 ) => {
54 $(
55 $( #[$attr] )*
56 fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) -> Self::Return {
57 if DEBUG {
58 println!(
59 concat!(
60 stringify!($snake_name),
61 $(
62 $(
63 " ",
64 stringify!($field),
65 "={:?}",
66 )*
67 )?
68 ),
69 $($($field),*)?
70 );
71 }
72 self.0.$snake_name($( $($field),* )?)
73 }
74 )*
75 }
76}
77
78impl<'a> OpVisitor for Debug<'a> {
79 type BytecodeStream = <Interpreter<'a> as OpVisitor>::BytecodeStream;
80 type Return = <Interpreter<'a> as OpVisitor>::Return;
81
82 fn bytecode(&mut self) -> &mut Self::BytecodeStream {
83 self.0.bytecode()
84 }
85
86 fn before_visit(&mut self) {
87 self.0.record_executing_pc_for_profiling();
88 if !DEBUG {
89 return;
90 }
91 print!("\t{:?}\t", self.bytecode().as_ptr());
92 }
93
94 fn after_visit(&mut self) {
95 if !DEBUG {
96 return;
97 }
98 if DEBUG_X_REGS {
99 for (i, regs) in self.0.state.x_regs.chunks(4).enumerate() {
100 print!("\t\t");
101 for (j, reg) in regs.iter().enumerate() {
102 let n = i * 4 + j;
103 let val = reg.get_u64();
104 let reg = XReg::new(n as u8).unwrap().to_string();
105 print!(" {reg:>3}={val:#018x}");
106 }
107 println!();
108 }
109 }
110 if DEBUG_F_REGS {
111 for (i, regs) in self.0.state.f_regs.chunks(4).enumerate() {
112 print!("\t\t");
113 for (j, reg) in regs.iter().enumerate() {
114 let n = i * 4 + j;
115 let val = reg.get_f64().to_bits();
116 let reg = FReg::new(n as u8).unwrap().to_string();
117 print!(" {reg:>3}={val:#018x}");
118 }
119 println!();
120 }
121 }
122 }
123
124 for_each_op!(debug_then_delegate);
125}
126
127impl<'a> ExtendedOpVisitor for Debug<'a> {
128 for_each_extended_op!(debug_then_delegate);
129}