@@ -5,7 +5,7 @@ use crate::jit::inst_threag_regs_handler::{register_restore_spsr, restore_thumb_
55use crate :: jit:: jit_asm:: { JitAsm , JitRuntimeData } ;
66use crate :: jit:: op:: Op ;
77use crate :: jit:: reg:: Reg ;
8- use crate :: jit:: MemoryAmount ;
8+ use crate :: jit:: { Cond , MemoryAmount } ;
99use crate :: DEBUG_LOG_BRANCH_OUT ;
1010
1111impl < ' a , const CPU : CpuType > JitAsm < ' a , CPU > {
@@ -98,4 +98,72 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
9898 pub fn emit_branch_out_metadata_with_idle_loop ( & mut self , block_asm : & mut BlockAsm ) {
9999 self . _emit_branch_out_metadata ( block_asm, true )
100100 }
101+
102+ pub fn emit_flush_cycles < ContinueFn : Fn ( & mut Self , & mut BlockAsm ) , BreakoutFn : Fn ( & mut Self , & mut BlockAsm ) > (
103+ & mut self ,
104+ block_asm : & mut BlockAsm ,
105+ target_pre_cycle_count_sum : u16 ,
106+ continue_fn : ContinueFn ,
107+ breakout_fn : BreakoutFn ,
108+ ) {
109+ let runtime_data_addr_reg = block_asm. new_reg ( ) ;
110+ block_asm. mov ( runtime_data_addr_reg, self . runtime_data . get_addr ( ) as u32 ) ;
111+
112+ let accumulated_cycles_reg = block_asm. new_reg ( ) ;
113+ block_asm. transfer_read (
114+ accumulated_cycles_reg,
115+ runtime_data_addr_reg,
116+ JitRuntimeData :: get_accumulated_cycles_offset ( ) as u32 ,
117+ false ,
118+ MemoryAmount :: Half ,
119+ ) ;
120+
121+ let pre_cycle_count_sum_reg = block_asm. new_reg ( ) ;
122+ block_asm. transfer_read (
123+ pre_cycle_count_sum_reg,
124+ runtime_data_addr_reg,
125+ JitRuntimeData :: get_pre_cycle_count_sum_offset ( ) as u32 ,
126+ false ,
127+ MemoryAmount :: Half ,
128+ ) ;
129+
130+ let total_cycles_reg = block_asm. new_reg ( ) ;
131+ // +2 for branching
132+ block_asm. add ( total_cycles_reg, accumulated_cycles_reg, self . jit_buf . insts_cycle_counts [ self . jit_buf . current_index ] as u32 + 2 ) ;
133+ block_asm. sub ( total_cycles_reg, total_cycles_reg, pre_cycle_count_sum_reg) ;
134+
135+ const MAX_LOOP_CYCLE_COUNT : u32 = 200 ;
136+ block_asm. cmp ( total_cycles_reg, MAX_LOOP_CYCLE_COUNT - 1 ) ;
137+
138+ let breakout_label = block_asm. new_label ( ) ;
139+ block_asm. branch ( breakout_label, Cond :: HI ) ;
140+
141+ block_asm. transfer_write (
142+ total_cycles_reg,
143+ runtime_data_addr_reg,
144+ JitRuntimeData :: get_accumulated_cycles_offset ( ) as u32 ,
145+ false ,
146+ MemoryAmount :: Half ,
147+ ) ;
148+
149+ let target_pre_cycle_count_sum_reg = block_asm. new_reg ( ) ;
150+ block_asm. mov ( target_pre_cycle_count_sum_reg, target_pre_cycle_count_sum as u32 ) ;
151+ block_asm. transfer_write (
152+ target_pre_cycle_count_sum_reg,
153+ runtime_data_addr_reg,
154+ JitRuntimeData :: get_pre_cycle_count_sum_offset ( ) as u32 ,
155+ false ,
156+ MemoryAmount :: Half ,
157+ ) ;
158+ continue_fn ( self , block_asm) ;
159+
160+ block_asm. label ( breakout_label) ;
161+ breakout_fn ( self , block_asm) ;
162+
163+ block_asm. free_reg ( target_pre_cycle_count_sum_reg) ;
164+ block_asm. free_reg ( total_cycles_reg) ;
165+ block_asm. free_reg ( pre_cycle_count_sum_reg) ;
166+ block_asm. free_reg ( accumulated_cycles_reg) ;
167+ block_asm. free_reg ( runtime_data_addr_reg) ;
168+ }
101169}
0 commit comments