1- use  crate :: core:: emu:: { get_cpu_regs,  get_jit,  get_jit_mut,  get_regs,  get_regs_mut,  Emu } ; 
1+ use  crate :: core:: emu:: { get_cpu_regs,  get_cpu_regs_mut ,   get_jit,  get_jit_mut,  get_regs,  get_regs_mut,  Emu } ; 
22use  crate :: core:: hle:: bios; 
33use  crate :: core:: thread_regs:: ThreadRegs ; 
44use  crate :: core:: CpuType ; 
5+ use  crate :: core:: CpuType :: ARM9 ; 
56use  crate :: jit:: assembler:: block_asm:: { BlockAsm ,  BLOCK_LOG } ; 
67use  crate :: jit:: assembler:: BlockAsmBuf ; 
78use  crate :: jit:: disassembler:: lookup_table:: lookup_opcode; 
89use  crate :: jit:: disassembler:: thumb:: lookup_table_thumb:: lookup_thumb_opcode; 
10+ use  crate :: jit:: inst_branch_handler:: { branch_lr,  call_jit_fun} ; 
911use  crate :: jit:: inst_info:: InstInfo ; 
1012use  crate :: jit:: jit_asm_common_funs:: { exit_guest_context,  JitAsmCommonFuns } ; 
1113use  crate :: jit:: op:: Op ; 
@@ -14,6 +16,7 @@ use crate::jit::reg::{reg_reserve, RegReserve};
1416use  crate :: logging:: debug_println; 
1517use  crate :: { get_jit_asm_ptr,  DEBUG_LOG ,  IS_DEBUG } ; 
1618use  std:: cell:: UnsafeCell ; 
19+ use  std:: hint:: unreachable_unchecked; 
1720use  std:: intrinsics:: unlikely; 
1821use  std:: { mem,  ptr} ; 
1922
@@ -50,7 +53,8 @@ impl JitBuf {
5053
5154pub  const  RETURN_STACK_SIZE :  usize  = 16 ; 
5255
53- #[ repr( C ,  align( 64 ) ) ]  
56+ #[ repr( C ) ]  
57+ #[ derive( Default ) ]  
5458pub  struct  JitRuntimeData  { 
5559    pub  idle_loop :  bool , 
5660    pub  return_stack_ptr :  u8 , 
@@ -59,19 +63,13 @@ pub struct JitRuntimeData {
5963    pub  accumulated_cycles :  u16 , 
6064    pub  host_sp :  usize , 
6165    pub  branch_out_pc :  u32 , 
66+     guest_irq_table_addr :  u32 , 
67+     guest_irq_handler_thread_switch_addr :  u32 , 
6268} 
6369
6470impl  JitRuntimeData  { 
6571    fn  new ( )  -> Self  { 
66-         let  instance = JitRuntimeData  { 
67-             branch_out_pc :  u32:: MAX , 
68-             pre_cycle_count_sum :  0 , 
69-             accumulated_cycles :  0 , 
70-             idle_loop :  false , 
71-             host_sp :  0 , 
72-             return_stack_ptr :  0 , 
73-             return_stack :  [ 0 ;  RETURN_STACK_SIZE ] , 
74-         } ; 
72+         let  instance = JitRuntimeData :: default ( ) ; 
7573        assert_eq ! ( size_of_val( & instance. return_stack) ,  RETURN_STACK_SIZE  *  4 ) ; 
7674        instance
7775    } 
@@ -106,7 +104,7 @@ impl JitRuntimeData {
106104} 
107105
108106pub  extern  "C"  fn  hle_bios_uninterrupt < const  CPU :  CpuType > ( store_host_sp :  bool )  { 
109-     let  asm = unsafe  {  get_jit_asm_ptr :: < CPU > ( ) . as_mut ( ) . unwrap_unchecked ( )  } ; 
107+     let  asm = unsafe  {  get_jit_asm_ptr :: < CPU > ( ) . as_mut_unchecked ( )  } ; 
110108    if  IS_DEBUG  { 
111109        asm. runtime_data . branch_out_pc  = get_regs ! ( asm. emu,  CPU ) . pc ; 
112110    } 
@@ -129,8 +127,38 @@ pub extern "C" fn hle_bios_uninterrupt<const CPU: CpuType>(store_host_sp: bool)
129127    } 
130128} 
131129
130+ pub  extern  "C"  fn  hle_interrupt_handler_arm9 ( store_host_sp :  bool )  { 
131+     let  asm = unsafe  {  get_jit_asm_ptr :: < {  ARM9  } > ( ) . as_mut_unchecked ( )  } ; 
132+ 
133+     let  regs = get_regs_mut ! ( asm. emu,  ARM9 ) ; 
134+     let  cpu_regs = get_cpu_regs_mut ! ( asm. emu,  ARM9 ) ; 
135+ 
136+     let  enabled_interrupts = cpu_regs. ie  &  cpu_regs. irf ; 
137+     if  cpu_regs. ime  == 0  || enabled_interrupts == 0  { 
138+         regs. pc  = regs. lr ; 
139+         unsafe  {  branch_lr :: < {  ARM9  } ,  false > ( 0 ,  regs. pc ,  store_host_sp,  0x1ff8000 )  } ; 
140+         return ; 
141+     } 
142+ 
143+     regs. sp  -= 4 ; 
144+     asm. emu . mem_write :: < {  ARM9  } ,  _ > ( regs. sp ,  regs. lr ) ; 
145+ 
146+     let  interrupt_number = enabled_interrupts. trailing_zeros ( ) ; 
147+     let  ack_interrupt = 1  << interrupt_number; 
148+     cpu_regs. set_irf ( 0xFFFFFFFF ,  ack_interrupt) ; 
149+ 
150+     let  handler_addr = asm. emu . mem_read :: < {  ARM9  } ,  u32 > ( asm. runtime_data . guest_irq_table_addr  + ( interrupt_number << 2 ) ) ; 
151+     regs. lr  = asm. runtime_data . guest_irq_handler_thread_switch_addr ; 
152+     regs. pc  = handler_addr; 
153+ 
154+     unsafe  {  call_jit_fun :: < {  ARM9  } > ( asm,  regs. pc ,  store_host_sp)  } ; 
155+     if  !store_host_sp { 
156+         unsafe  {  unreachable_unchecked ( )  } ; 
157+     } 
158+ } 
159+ 
132160pub  extern  "C"  fn  emit_code_block < const  CPU :  CpuType > ( store_host_sp :  bool )  { 
133-     let  asm = unsafe  {  get_jit_asm_ptr :: < CPU > ( ) . as_mut ( ) . unwrap_unchecked ( )  } ; 
161+     let  asm = unsafe  {  get_jit_asm_ptr :: < CPU > ( ) . as_mut_unchecked ( )  } ; 
134162
135163    let  guest_pc = get_regs ! ( asm. emu,  CPU ) . pc ; 
136164    let  thumb = ( guest_pc &  1 )  == 1 ; 
@@ -141,7 +169,35 @@ pub extern "C" fn emit_code_block<const CPU: CpuType>(store_host_sp: bool) {
141169    } 
142170} 
143171
172+ fn  emit_hle_interrupt_handler_arm9 ( asm :  & mut  JitAsm < {  ARM9  } > ,  store_host_sp :  bool )  { 
173+     { 
174+         let  ldr_irq_table_op = asm. emu . mem_read :: < {  ARM9  } ,  u32 > ( 0x1ff8040 ) ; 
175+         let  ( op,  func)  = lookup_opcode ( ldr_irq_table_op) ; 
176+         let  inst_info = func ( ldr_irq_table_op,  * op) ; 
177+         assert ! ( * op == Op :: LdrOfip  && * inst_info. operands( ) [ 1 ] . as_reg_no_shift( ) . unwrap( )  == Reg :: PC  && * inst_info. operands( ) [ 2 ] . as_imm( ) . unwrap( )  == 8 ) ; 
178+     } 
179+ 
180+     { 
181+         let  ldr_irq_handler_thread_switch_op = asm. emu . mem_read :: < {  ARM9  } ,  u32 > ( 0x1ff8048 ) ; 
182+         let  ( op,  func)  = lookup_opcode ( ldr_irq_handler_thread_switch_op) ; 
183+         let  inst_info = func ( ldr_irq_handler_thread_switch_op,  * op) ; 
184+         assert ! ( * op == Op :: LdrOfip  && * inst_info. operands( ) [ 1 ] . as_reg_no_shift( ) . unwrap( )  == Reg :: PC  && * inst_info. operands( ) [ 2 ] . as_imm( ) . unwrap( )  == 4 ) ; 
185+     } 
186+ 
187+     asm. runtime_data . guest_irq_table_addr  = asm. emu . mem_read :: < {  ARM9  } ,  _ > ( 0x1ff8040  + 16 ) ; 
188+     asm. runtime_data . guest_irq_handler_thread_switch_addr  = asm. emu . mem_read :: < {  ARM9  } ,  _ > ( 0x1ff8048  + 12 ) ; 
189+ 
190+     get_jit_mut ! ( asm. emu) . insert_function :: < {  ARM9  } > ( 0x1ff8000 ,  hle_interrupt_handler_arm9 as  _ ) ; 
191+ 
192+     hle_interrupt_handler_arm9 ( store_host_sp) ; 
193+ } 
194+ 
144195fn  emit_code_block_internal < const  CPU :  CpuType ,  const  THUMB :  bool > ( asm :  & mut  JitAsm < CPU > ,  store_host_sp :  bool ,  guest_pc :  u32 )  { 
196+     if  CPU  == ARM9  && unlikely ( guest_pc == 0x1ff8000 )  { 
197+         unsafe  {  emit_hle_interrupt_handler_arm9 ( mem:: transmute ( asm) ,  store_host_sp)  } ; 
198+         return ; 
199+     } 
200+ 
145201    let  mut  uncond_branch_count = 0 ; 
146202    let  mut  pc_offset = 0 ; 
147203    loop  { 
@@ -227,9 +283,7 @@ fn emit_code_block_internal<const CPU: CpuType, const THUMB: bool>(asm: &mut Jit
227283        } 
228284        let  jit_entry:  extern  "C"  fn ( bool )  = unsafe  {  mem:: transmute ( insert_entry)  } ; 
229285
230-         if  DEBUG_LOG  { 
231-             // println!("{CPU:?} Mapping {guest_pc:#010x} to {:#010x}", jit_entry as *const fn() as usize); 
232-         } 
286+         debug_println ! ( "{CPU:?} Mapping {guest_pc:#010x} to {:#010x}" ,  jit_entry as  * const  fn ( )  as  usize ) ; 
233287        asm. jit_buf . clear_all ( ) ; 
234288        jit_entry
235289    } ; 
@@ -238,7 +292,7 @@ fn emit_code_block_internal<const CPU: CpuType, const THUMB: bool>(asm: &mut Jit
238292} 
239293
240294fn  execute_internal < const  CPU :  CpuType > ( guest_pc :  u32 )  -> u16  { 
241-     let  asm = unsafe  {  get_jit_asm_ptr :: < CPU > ( ) . as_mut ( ) . unwrap_unchecked ( )  } ; 
295+     let  asm = unsafe  {  get_jit_asm_ptr :: < CPU > ( ) . as_mut_unchecked ( )  } ; 
242296
243297    let  thumb = ( guest_pc &  1 )  == 1 ; 
244298    debug_println ! ( "{:?} Execute {:x} thumb {}" ,  CPU ,  guest_pc,  thumb) ; 
0 commit comments