11use crate :: core:: CpuType ;
22use crate :: core:: CpuType :: ARM7 ;
33use crate :: jit:: assembler:: block_asm:: BlockAsm ;
4- use crate :: jit:: assembler:: BlockReg ;
4+ use crate :: jit:: assembler:: { BlockLabel , BlockReg } ;
55use crate :: jit:: inst_threag_regs_handler:: { register_restore_spsr, restore_thumb_after_restore_spsr, set_pc_arm_mode} ;
66use crate :: jit:: jit_asm:: { JitAsm , JitRuntimeData } ;
77use crate :: jit:: op:: Op ;
@@ -60,6 +60,16 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
6060 block_asm. call ( restore_thumb_after_restore_spsr :: < CPU > as * const ( ) ) ;
6161 }
6262
63+ if ( op. is_mov ( ) && self . jit_buf . current_inst ( ) . src_regs . is_reserved ( Reg :: LR ) && !self . jit_buf . current_inst ( ) . out_regs . is_reserved ( Reg :: CPSR ) )
64+ || ( op. is_multiple_mem_transfer ( ) && * self . jit_buf . current_inst ( ) . operands ( ) [ 0 ] . as_reg_no_shift ( ) . unwrap ( ) == Reg :: SP )
65+ || ( op. is_single_mem_transfer ( ) && self . jit_buf . current_inst ( ) . src_regs . is_reserved ( Reg :: SP ) )
66+ {
67+ let guest_pc_reg = block_asm. new_reg ( ) ;
68+ block_asm. load_u32 ( guest_pc_reg, block_asm. thread_regs_addr_reg , Reg :: PC as u32 * 4 ) ;
69+ self . emit_branch_return_stack_common ( block_asm, guest_pc_reg) ;
70+ block_asm. free_reg ( guest_pc_reg) ;
71+ }
72+
6373 self . emit_branch_out_metadata ( block_asm) ;
6474 block_asm. epilogue ( ) ;
6575 }
@@ -73,7 +83,7 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
7383
7484 let accumulated_cycles_reg = block_asm. new_reg ( ) ;
7585 block_asm. load_u16 ( accumulated_cycles_reg, runtime_data_addr_reg, JitRuntimeData :: get_accumulated_cycles_offset ( ) as u32 ) ;
76-
86+
7787 // +2 for branching
7888 block_asm. add (
7989 result_accumulated_cycles_reg,
@@ -127,10 +137,11 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
127137 self . _emit_branch_out_metadata ( block_asm, true , true )
128138 }
129139
130- pub fn emit_flush_cycles < ContinueFn : Fn ( & mut Self , & mut BlockAsm , BlockReg ) , BreakoutFn : Fn ( & mut Self , & mut BlockAsm ) > (
140+ pub fn emit_flush_cycles < ContinueFn : Fn ( & mut Self , & mut BlockAsm , BlockReg , BlockLabel ) , BreakoutFn : Fn ( & mut Self , & mut BlockAsm ) > (
131141 & mut self ,
132142 block_asm : & mut BlockAsm ,
133- target_pre_cycle_count_sum : u16 ,
143+ target_pre_cycle_count_sum : Option < u16 > ,
144+ add_continue_label : bool ,
134145 continue_fn : ContinueFn ,
135146 breakout_fn : BreakoutFn ,
136147 ) {
@@ -140,7 +151,7 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
140151 let result_accumulated_cycles_reg = block_asm. new_reg ( ) ;
141152 self . emit_count_cycles ( block_asm, runtime_data_addr_reg, result_accumulated_cycles_reg) ;
142153
143- const MAX_LOOP_CYCLE_COUNT : u32 = 255 ;
154+ const MAX_LOOP_CYCLE_COUNT : u32 = 127 ;
144155 block_asm. cmp (
145156 result_accumulated_cycles_reg,
146157 match CPU {
@@ -149,18 +160,28 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
149160 } ,
150161 ) ;
151162
163+ let continue_label = if add_continue_label { Some ( block_asm. new_label ( ) ) } else { None } ;
152164 let breakout_label = block_asm. new_label ( ) ;
153165 block_asm. branch ( breakout_label, Cond :: HS ) ;
154166
155- let target_pre_cycle_count_sum_reg = block_asm. new_reg ( ) ;
156- block_asm. mov ( target_pre_cycle_count_sum_reg, target_pre_cycle_count_sum as u32 ) ;
157- block_asm. store_u16 ( target_pre_cycle_count_sum_reg, runtime_data_addr_reg, JitRuntimeData :: get_pre_cycle_count_sum_offset ( ) as u32 ) ;
158- continue_fn ( self , block_asm, runtime_data_addr_reg) ;
167+ if let Some ( target_pre_cycle_count_sum) = target_pre_cycle_count_sum {
168+ let target_pre_cycle_count_sum_reg = block_asm. new_reg ( ) ;
169+ block_asm. mov ( target_pre_cycle_count_sum_reg, target_pre_cycle_count_sum as u32 ) ;
170+ block_asm. store_u16 ( target_pre_cycle_count_sum_reg, runtime_data_addr_reg, JitRuntimeData :: get_pre_cycle_count_sum_offset ( ) as u32 ) ;
171+ block_asm. free_reg ( target_pre_cycle_count_sum_reg) ;
172+ }
173+ continue_fn ( self , block_asm, runtime_data_addr_reg, breakout_label) ;
174+ if add_continue_label {
175+ block_asm. branch ( continue_label. unwrap ( ) , Cond :: AL ) ;
176+ }
159177
160178 block_asm. label ( breakout_label) ;
161179 breakout_fn ( self , block_asm) ;
162180
163- block_asm. free_reg ( target_pre_cycle_count_sum_reg) ;
181+ if add_continue_label {
182+ block_asm. label ( continue_label. unwrap ( ) ) ;
183+ }
184+
164185 block_asm. free_reg ( result_accumulated_cycles_reg) ;
165186 block_asm. free_reg ( runtime_data_addr_reg) ;
166187 }
0 commit comments