@@ -3,13 +3,15 @@ use crate::jit::assembler::arm::branch_assembler::B;
33use crate :: jit:: assembler:: basic_block:: BasicBlock ;
44use crate :: jit:: assembler:: block_inst:: { BlockAluOp , BlockAluSetCond , BlockSystemRegOp , BlockTransferOp , GuestInstInfo } ;
55use crate :: jit:: assembler:: block_inst_list:: BlockInstList ;
6- use crate :: jit:: assembler:: block_reg_set:: { block_reg_set , BlockRegSet } ;
6+ use crate :: jit:: assembler:: block_reg_set:: BlockRegSet ;
77use crate :: jit:: assembler:: { block_reg_allocator, BlockAsmBuf , BlockInst , BlockLabel , BlockOperand , BlockOperandShift , BlockReg , ANY_REG_LIMIT } ;
88use crate :: jit:: inst_info:: InstInfo ;
99use crate :: jit:: reg:: { reg_reserve, Reg , RegReserve } ;
1010use crate :: jit:: { Cond , MemoryAmount , ShiftType } ;
1111use crate :: utils:: { NoHashMap , NoHashSet } ;
1212
13+ pub static mut BLOCK_LOG : bool = false ;
14+
1315macro_rules! alu3 {
1416 ( $name: ident, $inst: ident, $set_cond: ident, $thumb_pc_aligned: expr) => {
1517 pub fn $name( & mut self , op0: impl Into <BlockReg >, op1: impl Into <BlockReg >, op2: impl Into <BlockOperandShift >) {
@@ -317,7 +319,6 @@ impl<'a> BlockAsm<'a> {
317319 self . insert_inst ( BlockInst :: SaveContext {
318320 thread_regs_addr_reg : self . thread_regs_addr_reg ,
319321 tmp_guest_cpsr_reg : self . tmp_guest_cpsr_reg ,
320- regs_to_save : RegReserve :: new ( ) ,
321322 } ) ;
322323 }
323324
@@ -507,21 +508,6 @@ impl<'a> BlockAsm<'a> {
507508 }
508509 }
509510
510- fn resolve_guest_regs ( & mut self , basic_blocks : & mut [ BasicBlock ] , input_guest_regs_dirty : RegReserve , block_indices : & [ usize ] ) {
511- for i in block_indices {
512- let basic_block = & mut basic_blocks[ * i] ;
513- let sum_guest_regs_dirty = basic_block. input_guest_regs_dirty + input_guest_regs_dirty;
514- if sum_guest_regs_dirty != basic_block. input_guest_regs_dirty || !basic_block. guest_regs_resolved {
515- basic_block. guest_regs_resolved = true ;
516- basic_block. input_guest_regs_dirty = sum_guest_regs_dirty;
517- basic_block. init_resolve_guest_regs ( self ) ;
518- let exit_blocks = basic_block. exit_blocks . clone ( ) . into_iter ( ) . collect :: < Vec < usize > > ( ) ;
519- let output_guest_regs_dirty = basic_block. output_guest_regs_dirty ;
520- self . resolve_guest_regs ( basic_blocks, output_guest_regs_dirty, & exit_blocks) ;
521- }
522- }
523- }
524-
525511 fn resolve_io ( & self , basic_blocks : & mut [ BasicBlock ] , required_outputs : BlockRegSet , block_indices : & [ usize ] ) {
526512 for i in block_indices {
527513 let basic_block = & mut basic_blocks[ * i] ;
@@ -560,7 +546,7 @@ impl<'a> BlockAsm<'a> {
560546 }
561547 }
562548
563- fn assemble_basic_blocks < const THUMB : bool > ( & mut self , block_start_pc : u32 ) -> ( Vec < BasicBlock > , Vec < usize > ) {
549+ fn assemble_basic_blocks ( & mut self , block_start_pc : u32 , thumb : bool ) -> ( Vec < BasicBlock > , Vec < usize > ) {
564550 for i in 0 ..self . buf . insts . len ( ) {
565551 self . insts_link . insert_end ( i) ;
566552 }
@@ -671,8 +657,6 @@ impl<'a> BlockAsm<'a> {
671657 }
672658 }
673659
674- self . resolve_guest_regs ( & mut basic_blocks, RegReserve :: new ( ) , & [ 0 ] ) ;
675-
676660 for basic_block in & mut basic_blocks {
677661 let mut basic_block_start_pc = block_start_pc;
678662 let mut current_node = basic_block. block_entry_start ;
@@ -693,7 +677,7 @@ impl<'a> BlockAsm<'a> {
693677
694678 current_node = BlockInstList :: deref ( current_node) . previous ;
695679 }
696- basic_block. init_insts :: < THUMB > ( self , basic_block_start_pc) ;
680+ basic_block. init_insts ( self , basic_block_start_pc, thumb ) ;
697681 }
698682
699683 for i in ( 0 ..basic_blocks_len) . rev ( ) {
@@ -712,45 +696,6 @@ impl<'a> BlockAsm<'a> {
712696 let mut df_ordering_end = basic_blocks_len - 1 ;
713697 Self :: resolve_df_ordering ( & mut df_already_processed, & mut basic_blocks, 0 , & mut df_ordering, & mut df_ordering_start, & mut df_ordering_end) ;
714698
715- // Initialize all guest regs used in block
716- let first_basic_block = basic_blocks. first_mut ( ) . unwrap ( ) ;
717- let mut loaded_guest_regs = BlockRegSet :: new ( ) ;
718- let load_guest_regs_insts_start = self . buf . insts . len ( ) ;
719- let mut used_guest_regs = Vec :: new ( ) ;
720- for guest_reg in first_basic_block. get_required_inputs ( ) . get_guests ( ) {
721- loaded_guest_regs += BlockReg :: from ( guest_reg) ;
722- self . insert_inst ( BlockInst :: Transfer {
723- op : BlockTransferOp :: Read ,
724- operands : [ guest_reg. into ( ) , self . thread_regs_addr_reg . into ( ) , ( guest_reg as u32 * 4 ) . into ( ) ] ,
725- signed : false ,
726- amount : MemoryAmount :: Word ,
727- add_to_base : true ,
728- } ) ;
729- used_guest_regs. push ( block_reg_set ! ( Some ( BlockReg :: from( guest_reg) ) , Some ( self . thread_regs_addr_reg) ) ) ;
730- }
731-
732- let mut initialization_end_node = first_basic_block. insts_link . root ;
733- while !initialization_end_node. is_null ( ) && BlockInstList :: deref ( initialization_end_node) . value != self . block_start {
734- initialization_end_node = BlockInstList :: deref ( initialization_end_node) . next ;
735- }
736-
737- for i in load_guest_regs_insts_start..load_guest_regs_insts_start + used_guest_regs. len ( ) {
738- if initialization_end_node. is_null ( ) {
739- first_basic_block. insts_link . insert_end ( i) ;
740- } else {
741- first_basic_block. insts_link . insert_entry_begin ( initialization_end_node, i) ;
742- }
743- }
744-
745- first_basic_block. regs_live_ranges [ self . block_start ] += self . thread_regs_addr_reg ;
746- let regs_live_extensions = vec ! [ first_basic_block. regs_live_ranges[ self . block_start] ; used_guest_regs. len( ) ] ;
747- first_basic_block. regs_live_ranges . splice ( self . block_start ..self . block_start , regs_live_extensions) ;
748- first_basic_block. used_regs . splice ( self . block_start ..self . block_start , used_guest_regs) ;
749-
750- for i in 0 ..self . block_start {
751- first_basic_block. regs_live_ranges [ i] -= loaded_guest_regs;
752- }
753-
754699 ( basic_blocks, df_ordering)
755700 }
756701
@@ -778,8 +723,25 @@ impl<'a> BlockAsm<'a> {
778723 intervals
779724 }
780725
781- pub fn finalize < const THUMB : bool > ( mut self , block_start_pc : u32 ) -> Vec < u32 > {
782- let ( mut basic_blocks, basic_blocks_order) = self . assemble_basic_blocks :: < THUMB > ( block_start_pc) ;
726+ pub fn finalize ( mut self , block_start_pc : u32 , thumb : bool ) -> Vec < u32 > {
727+ let ( mut basic_blocks, basic_blocks_order) = self . assemble_basic_blocks ( block_start_pc, thumb) ;
728+
729+ if unsafe { BLOCK_LOG } {
730+ for ( i, basic_block) in basic_blocks. iter ( ) . enumerate ( ) {
731+ println ! ( "{i}[{i} {:x}]" , basic_block. start_pc) ;
732+ }
733+
734+ for ( i, basic_block) in basic_blocks. iter ( ) . enumerate ( ) {
735+ for & exit_i in & basic_block. exit_blocks {
736+ println ! ( "{i} --> {exit_i}" ) ;
737+ }
738+ }
739+
740+ for ( i, basic_block) in basic_blocks. iter ( ) . enumerate ( ) {
741+ println ! ( "{i}: {basic_block:?}" ) ;
742+ }
743+ }
744+
783745 let mut reg_intervals = Self :: assemble_intervals ( & basic_blocks, & basic_blocks_order) ;
784746
785747 self . buf . reg_allocator . global_mapping . clear ( ) ;
@@ -802,38 +764,19 @@ impl<'a> BlockAsm<'a> {
802764 self . buf . reg_allocator . global_mapping . insert ( reg, Reg :: None ) ;
803765 }
804766
805- for basic_block in & mut basic_blocks {
806- if ! basic_block. guest_regs_resolved {
767+ for ( i , basic_block) in basic_blocks. iter_mut ( ) . enumerate ( ) {
768+ if i != 0 && basic_block. enter_blocks . is_empty ( ) {
807769 continue ;
808770 }
809771 self . buf . reg_allocator . init_inputs ( * basic_block. get_required_inputs ( ) ) ;
810772 basic_block. allocate_regs ( & mut self ) ;
811773 }
812774
813- // Try to collapse cond blocks into cond opcodes
814- for i in 1 ..basic_blocks. len ( ) {
815- if basic_blocks[ i] . insts_link . len ( ) == 1 && basic_blocks[ i] . enter_blocks . len ( ) == 1 && * basic_blocks[ i] . enter_blocks . iter ( ) . next ( ) . unwrap ( ) == i - 1 {
816- let previous_entry_last = BlockInstList :: deref ( basic_blocks[ i - 1 ] . insts_link . end ) . value ;
817- let override_cond = if let BlockInst :: Branch { cond, block_index, skip, .. } = & mut self . buf . insts [ previous_entry_last] {
818- if * block_index == i + 1 {
819- * skip = true ;
820- !* cond
821- } else {
822- Cond :: AL
823- }
824- } else {
825- Cond :: AL
826- } ;
827- // override_cond != AL when a block can be collapsed
828- basic_blocks[ i] . cond_block = override_cond;
829- }
830- }
831-
832775 let mut opcodes = Vec :: new ( ) ;
833776 let mut branch_placeholders = Vec :: new ( ) ;
834777 let mut opcodes_offset = Vec :: with_capacity ( basic_blocks. len ( ) ) ;
835- for basic_block in basic_blocks {
836- if ! basic_block. guest_regs_resolved {
778+ for ( i , basic_block) in basic_blocks. iter ( ) . enumerate ( ) {
779+ if i != 0 && basic_block. enter_blocks . is_empty ( ) {
837780 continue ;
838781 }
839782 opcodes_offset. push ( opcodes. len ( ) ) ;
0 commit comments