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 ;
88use crate :: jit:: reg:: Reg ;
9- use crate :: jit:: { Cond , MemoryAmount } ;
9+ use crate :: jit:: Cond ;
1010use crate :: DEBUG_LOG_BRANCH_OUT ;
1111use CpuType :: ARM9 ;
1212
@@ -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 }
@@ -77,15 +87,15 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
7787 if DEBUG_LOG_BRANCH_OUT {
7888 let pc_reg = block_asm. new_reg ( ) ;
7989 block_asm. mov ( pc_reg, self . jit_buf . current_pc ) ;
80- block_asm. transfer_write ( pc_reg, runtime_data_addr_reg, JitRuntimeData :: get_out_pc_offset ( ) as u32 , false , MemoryAmount :: Word ) ;
90+ block_asm. store_u32 ( pc_reg, runtime_data_addr_reg, JitRuntimeData :: get_out_pc_offset ( ) as u32 ) ;
8191
8292 block_asm. free_reg ( pc_reg) ;
8393 }
84- block_asm. transfer_write ( total_cycles_reg, runtime_data_addr_reg, JitRuntimeData :: get_out_total_cycles_offset ( ) as u32 , false , MemoryAmount :: Word ) ;
94+ block_asm. store_u32 ( total_cycles_reg, runtime_data_addr_reg, JitRuntimeData :: get_out_total_cycles_offset ( ) as u32 ) ;
8595 if set_idle_loop {
8696 let idle_loop_reg = block_asm. new_reg ( ) ;
8797 block_asm. mov ( idle_loop_reg, 1 ) ;
88- block_asm. transfer_write ( idle_loop_reg, runtime_data_addr_reg, JitRuntimeData :: get_idle_loop_offset ( ) as u32 , false , MemoryAmount :: Byte ) ;
98+ block_asm. store_u8 ( idle_loop_reg, runtime_data_addr_reg, JitRuntimeData :: get_idle_loop_offset ( ) as u32 ) ;
8999
90100 block_asm. free_reg ( idle_loop_reg) ;
91101 }
@@ -102,73 +112,55 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
102112 self . _emit_branch_out_metadata ( block_asm, true )
103113 }
104114
105- pub fn emit_flush_cycles < ContinueFn : Fn ( & mut Self , & mut BlockAsm , BlockReg ) , BreakoutFn : Fn ( & mut Self , & mut BlockAsm ) > (
115+ pub fn emit_flush_cycles < ContinueFn : Fn ( & mut Self , & mut BlockAsm , BlockReg , BlockLabel ) , BreakoutFn : Fn ( & mut Self , & mut BlockAsm ) > (
106116 & mut self ,
107117 block_asm : & mut BlockAsm ,
108- target_pre_cycle_count_sum : u16 ,
118+ target_pre_cycle_count_sum : Option < u16 > ,
109119 continue_fn : ContinueFn ,
110120 breakout_fn : BreakoutFn ,
111121 ) {
112122 let runtime_data_addr_reg = block_asm. new_reg ( ) ;
113123 block_asm. mov ( runtime_data_addr_reg, self . runtime_data . get_addr ( ) as u32 ) ;
114124
115125 let accumulated_cycles_reg = block_asm. new_reg ( ) ;
116- block_asm. transfer_read (
117- accumulated_cycles_reg,
118- runtime_data_addr_reg,
119- JitRuntimeData :: get_accumulated_cycles_offset ( ) as u32 ,
120- false ,
121- MemoryAmount :: Half ,
122- ) ;
126+ block_asm. load_u16 ( accumulated_cycles_reg, runtime_data_addr_reg, JitRuntimeData :: get_accumulated_cycles_offset ( ) as u32 ) ;
123127
124128 let pre_cycle_count_sum_reg = block_asm. new_reg ( ) ;
125- block_asm. transfer_read (
126- pre_cycle_count_sum_reg,
127- runtime_data_addr_reg,
128- JitRuntimeData :: get_pre_cycle_count_sum_offset ( ) as u32 ,
129- false ,
130- MemoryAmount :: Half ,
131- ) ;
129+ block_asm. load_u16 ( pre_cycle_count_sum_reg, runtime_data_addr_reg, JitRuntimeData :: get_pre_cycle_count_sum_offset ( ) as u32 ) ;
132130
133131 let total_cycles_reg = block_asm. new_reg ( ) ;
134132 // +2 for branching
135133 block_asm. add ( total_cycles_reg, accumulated_cycles_reg, self . jit_buf . insts_cycle_counts [ self . jit_buf . current_index ] as u32 + 2 ) ;
136134 block_asm. sub ( total_cycles_reg, total_cycles_reg, pre_cycle_count_sum_reg) ;
137135
138- const MAX_LOOP_CYCLE_COUNT : u32 = 256 ;
136+ const MAX_LOOP_CYCLE_COUNT : u32 = 255 ;
139137 block_asm. cmp (
140138 total_cycles_reg,
141139 match CPU {
142140 ARM9 => MAX_LOOP_CYCLE_COUNT * 2 ,
143141 ARM7 => MAX_LOOP_CYCLE_COUNT ,
144- } - 1 ,
142+ } ,
145143 ) ;
146144
145+ let continue_label = block_asm. new_label ( ) ;
147146 let breakout_label = block_asm. new_label ( ) ;
148- block_asm. branch ( breakout_label, Cond :: HI ) ;
147+ block_asm. branch ( breakout_label, Cond :: HS ) ;
149148
150- block_asm. transfer_write (
151- total_cycles_reg,
152- runtime_data_addr_reg,
153- JitRuntimeData :: get_accumulated_cycles_offset ( ) as u32 ,
154- false ,
155- MemoryAmount :: Half ,
156- ) ;
149+ block_asm. store_u16 ( total_cycles_reg, runtime_data_addr_reg, JitRuntimeData :: get_accumulated_cycles_offset ( ) as u32 ) ;
157150
158151 let target_pre_cycle_count_sum_reg = block_asm. new_reg ( ) ;
159- block_asm. mov ( target_pre_cycle_count_sum_reg, target_pre_cycle_count_sum as u32 ) ;
160- block_asm. transfer_write (
161- target_pre_cycle_count_sum_reg,
162- runtime_data_addr_reg,
163- JitRuntimeData :: get_pre_cycle_count_sum_offset ( ) as u32 ,
164- false ,
165- MemoryAmount :: Half ,
166- ) ;
167- continue_fn ( self , block_asm, runtime_data_addr_reg) ;
152+ if let Some ( target_pre_cycle_count_sum) = target_pre_cycle_count_sum {
153+ block_asm. mov ( target_pre_cycle_count_sum_reg, target_pre_cycle_count_sum as u32 ) ;
154+ block_asm. store_u16 ( target_pre_cycle_count_sum_reg, runtime_data_addr_reg, JitRuntimeData :: get_pre_cycle_count_sum_offset ( ) as u32 ) ;
155+ }
156+ continue_fn ( self , block_asm, runtime_data_addr_reg, breakout_label) ;
157+ block_asm. branch ( continue_label, Cond :: AL ) ;
168158
169159 block_asm. label ( breakout_label) ;
170160 breakout_fn ( self , block_asm) ;
171161
162+ block_asm. label ( continue_label) ;
163+
172164 block_asm. free_reg ( target_pre_cycle_count_sum_reg) ;
173165 block_asm. free_reg ( total_cycles_reg) ;
174166 block_asm. free_reg ( pre_cycle_count_sum_reg) ;
0 commit comments