@@ -70,14 +70,19 @@ impl HifAssembler {
7070 /// Disassemble ops into raw syntax with hex and symbolic comments.
7171 ///
7272 /// The output is wrapped in `raw { }` and is valid assembler input.
73+ /// Each line has the raw op, byte offset, hex encoding, and a
74+ /// symbolic annotation where the op's role can be inferred from
75+ /// context (e.g. "controller (mid)" for a push before I2cRead).
7376 pub fn disassemble ( & self , ops : & [ hif:: Op ] ) -> String {
7477 use postcard:: to_allocvec;
7578
79+ let annotations = annotate_ops ( ops, self ) ;
80+
7681 let mut out = String :: new ( ) ;
7782 out. push_str ( "raw {\n " ) ;
7883
7984 let mut offset = 0usize ;
80- for op in ops {
85+ for ( i , op ) in ops. iter ( ) . enumerate ( ) {
8186 let raw = format_op ( op, self ) ;
8287 let hex = to_allocvec ( op)
8388 . map ( |bytes| {
@@ -89,7 +94,14 @@ impl HifAssembler {
8994 } )
9095 . unwrap_or_else ( |_| "??" . into ( ) ) ;
9196
92- out. push_str ( & format ! ( " {raw:<26} # {offset:02x}: {hex}\n " , ) ) ;
97+ let annotation = annotations
98+ . get ( i)
99+ . map ( |s| format ! ( " {s}" ) )
100+ . unwrap_or_default ( ) ;
101+
102+ out. push_str ( & format ! (
103+ " {raw:<26} # {offset:02x}: {hex}{annotation}\n " ,
104+ ) ) ;
93105 offset += to_allocvec ( op) . map ( |b| b. len ( ) ) . unwrap_or ( 0 ) ;
94106 }
95107
@@ -98,6 +110,113 @@ impl HifAssembler {
98110 }
99111}
100112
113+ /// Produce symbolic annotations for each op by recognizing patterns.
114+ fn annotate_ops ( ops : & [ hif:: Op ] , asm : & HifAssembler ) -> Vec < String > {
115+ let mut notes: Vec < String > = vec ! [ String :: new( ) ; ops. len( ) ] ;
116+
117+ // Find I2cRead/Write call patterns: 7 pushes + Call + DropN(7)
118+ let i2c_read_id = asm
119+ . list_functions ( )
120+ . iter ( )
121+ . find ( |f| f. name . eq_ignore_ascii_case ( "I2cRead" ) )
122+ . map ( |f| f. id ) ;
123+ let i2c_write_id = asm
124+ . list_functions ( )
125+ . iter ( )
126+ . find ( |f| f. name . eq_ignore_ascii_case ( "I2cWrite" ) )
127+ . map ( |f| f. id ) ;
128+
129+ for ( i, op) in ops. iter ( ) . enumerate ( ) {
130+ if let hif:: Op :: Call ( hif:: TargetFunction ( id) ) = op {
131+ if Some ( * id) == i2c_read_id || Some ( * id) == i2c_write_id {
132+ // Annotate the 7 pushes before this call
133+ if i >= 7 {
134+ let labels = [
135+ "controller" ,
136+ "port" ,
137+ "mux" ,
138+ "segment" ,
139+ "address" ,
140+ "register" ,
141+ if Some ( * id) == i2c_read_id {
142+ "nbytes"
143+ } else {
144+ "data/len"
145+ } ,
146+ ] ;
147+ for ( j, label) in labels. iter ( ) . enumerate ( ) {
148+ let idx = i - 7 + j;
149+ // Enrich with bus/device names where possible
150+ let extra = match ( j, & ops[ idx] ) {
151+ ( 0 , hif:: Op :: Push ( ctrl) ) => {
152+ // Find bus name for this controller
153+ asm. target_config ( )
154+ . buses
155+ . iter ( )
156+ . find ( |b| b. controller == * ctrl)
157+ . map ( |b| format ! ( " ({})" , b. name) )
158+ . unwrap_or_default ( )
159+ }
160+ ( 4 , hif:: Op :: Push ( addr) ) => {
161+ // Find device name for this address
162+ // on any bus (best effort)
163+ asm. target_config ( )
164+ . buses
165+ . iter ( )
166+ . flat_map ( |b| b. devices . iter ( ) )
167+ . find ( |d| d. address == * addr)
168+ . map ( |d| format ! ( " ({})" , d. device) )
169+ . unwrap_or_default ( )
170+ }
171+ _ => String :: new ( ) ,
172+ } ;
173+ notes[ idx] = format ! ( "{label}{extra}" ) ;
174+ }
175+ }
176+ }
177+
178+ // Annotate Send calls (Idol): task_id, op_code
179+ let send_id = asm
180+ . list_functions ( )
181+ . iter ( )
182+ . find ( |f| f. name == "Send" )
183+ . map ( |f| f. id ) ;
184+ if Some ( * id) == send_id && i >= 4 {
185+ if let hif:: Op :: Push ( task_id) = ops[ i - 4 ] {
186+ let task_name = asm
187+ . target_config ( )
188+ . idol_interfaces
189+ . iter ( )
190+ . find ( |iface| iface. task_id == task_id as u32 )
191+ . map ( |iface| iface. task . as_str ( ) )
192+ . unwrap_or ( "?" ) ;
193+ notes[ i - 4 ] = format ! ( "task ({task_name})" ) ;
194+ }
195+ notes[ i - 3 ] = "op_code" . into ( ) ;
196+ }
197+ }
198+
199+ // Annotate loop patterns
200+ if let hif:: Op :: BranchGreaterThan ( _)
201+ | hif:: Op :: BranchGreaterThanOrEqualTo ( _) = op
202+ {
203+ if i >= 2 {
204+ if let hif:: Op :: Add = ops[ i - 2 ] {
205+ notes[ i - 2 ] = "counter += 1" . into ( ) ;
206+ notes[ i - 1 ] = "limit" . into ( ) ;
207+ notes[ i] = "loop" . into ( ) ;
208+ }
209+ }
210+ }
211+
212+ if let hif:: Op :: Label ( _) = op {
213+ notes[ i] = "loop_start" . into ( ) ;
214+ }
215+ }
216+
217+ notes
218+ }
219+
101220/// Format a single op as raw assembler syntax.
102221fn format_op ( op : & hif:: Op , asm : & HifAssembler ) -> String {
103222 match op {
0 commit comments