@@ -492,34 +492,8 @@ static bool do_fuse4(riscv_t *rv, rv_insn_t *ir, uint64_t cycle, uint32_t PC)
492
492
MUST_TAIL return next -> impl (rv , next , cycle , PC );
493
493
}
494
494
495
- /* memset */
496
- static bool do_fuse5 (riscv_t * rv ,
497
- const rv_insn_t * ir UNUSED ,
498
- uint64_t cycle ,
499
- uint32_t PC UNUSED )
500
- {
501
- /* FIXME: specify the correct cycle count for memset routine */
502
- cycle += 2 ;
503
- rv -> io .on_memset (rv );
504
- rv -> csr_cycle = cycle ;
505
- return true;
506
- }
507
-
508
- /* memcpy */
509
- static bool do_fuse6 (riscv_t * rv ,
510
- const rv_insn_t * ir UNUSED ,
511
- uint64_t cycle ,
512
- uint32_t PC UNUSED )
513
- {
514
- /* FIXME: specify the correct cycle count for memcpy routine */
515
- cycle += 2 ;
516
- rv -> io .on_memcpy (rv );
517
- rv -> csr_cycle = cycle ;
518
- return true;
519
- }
520
-
521
495
/* multiple shift immediate */
522
- static bool do_fuse7 (riscv_t * rv ,
496
+ static bool do_fuse5 (riscv_t * rv ,
523
497
const rv_insn_t * ir ,
524
498
uint64_t cycle ,
525
499
uint32_t PC )
@@ -676,50 +650,6 @@ static void block_translate(riscv_t *rv, block_t *block)
676
650
remove_next_nth_ir(rv, ir, block, count - 1); \
677
651
}
678
652
679
- #include "rv32_libc.h"
680
-
681
- static bool detect_memset (riscv_t * rv , size_t type )
682
- {
683
- static const struct rv32libc_impl rv32_memset [] = {
684
- {memset0_insn , ARRAYS_SIZE (memset0_insn )},
685
- {memset1_insn , ARRAYS_SIZE (memset1_insn )},
686
- };
687
- assert (type < ARRAYS_SIZE (rv32_memset ));
688
-
689
- const uint32_t * memset_insn = rv32_memset [type ].insn ;
690
- const size_t memset_len = rv32_memset [type ].len ;
691
-
692
- uint32_t tmp_pc = rv -> PC ;
693
- for (uint32_t i = 0 ; i < memset_len ; i ++ ) {
694
- const uint32_t insn = rv -> io .mem_ifetch (tmp_pc );
695
- if (unlikely (insn != memset_insn [i ]))
696
- return false;
697
- tmp_pc += 4 ;
698
- }
699
- return true;
700
- }
701
-
702
- static bool detect_memcpy (riscv_t * rv , size_t type )
703
- {
704
- static const struct rv32libc_impl rv32_memcpy [] = {
705
- {memcpy0_insn , ARRAYS_SIZE (memcpy0_insn )},
706
- {memcpy1_insn , ARRAYS_SIZE (memcpy1_insn )},
707
- };
708
- assert (type < ARRAYS_SIZE (rv32_memcpy ));
709
-
710
- const uint32_t * memcpy_insn = rv32_memcpy [type ].insn ;
711
- const size_t memcpy_len = rv32_memcpy [type ].len ;
712
-
713
- uint32_t tmp_pc = rv -> PC ;
714
- for (uint32_t i = 0 ; i < memcpy_len ; i ++ ) {
715
- const uint32_t insn = rv -> io .mem_ifetch (tmp_pc );
716
- if (unlikely (insn != memcpy_insn [i ]))
717
- return false;
718
- tmp_pc += 4 ;
719
- }
720
- return true;
721
- }
722
-
723
653
static inline void remove_next_nth_ir (const riscv_t * rv ,
724
654
rv_insn_t * ir ,
725
655
block_t * block ,
@@ -735,88 +665,6 @@ static inline void remove_next_nth_ir(const riscv_t *rv,
735
665
block -> n_insn -= n ;
736
666
}
737
667
738
- static bool libc_substitute (riscv_t * rv , block_t * block )
739
- {
740
- rv_insn_t * ir = block -> ir_head , * next_ir = NULL ;
741
- switch (ir -> opcode ) {
742
- case rv_insn_addi :
743
- /* Compare the target block with the first basic block of memset and
744
- * memcpy.
745
- * If the two blocks match, extract the instruction sequence starting
746
- * from pc_start of the basic block and compare it with the pre-recorded
747
- * memset/memcpy instruction sequence.
748
- */
749
- if (IF_imm (ir , 15 ) && IF_rd (ir , t1 ) && IF_rs1 (ir , zero )) {
750
- next_ir = ir -> next ;
751
- assert (next_ir );
752
- if (IF_insn (next_ir , addi ) && IF_rd (next_ir , a4 ) &&
753
- IF_rs1 (next_ir , a0 ) && IF_rs2 (next_ir , zero )) {
754
- next_ir = next_ir -> next ;
755
- if (IF_insn (next_ir , bgeu ) && IF_imm (next_ir , 60 ) &&
756
- IF_rs1 (next_ir , t1 ) && IF_rs2 (next_ir , a2 )) {
757
- if (detect_memset (rv , 0 )) {
758
- ir -> opcode = rv_insn_fuse5 ;
759
- ir -> impl = dispatch_table [ir -> opcode ];
760
- remove_next_nth_ir (rv , ir , block , 2 );
761
- return true;
762
- }
763
- }
764
- }
765
- } else if (IF_imm (ir , 0 ) && IF_rd (ir , t1 ) && IF_rs1 (ir , a0 )) {
766
- next_ir = ir -> next ;
767
- assert (next_ir );
768
- if (IF_insn (next_ir , beq ) && IF_rs1 (next_ir , a2 ) &&
769
- IF_rs2 (next_ir , zero )) {
770
- if (IF_imm (next_ir , 20 ) && detect_memset (rv , 1 )) {
771
- ir -> opcode = rv_insn_fuse5 ;
772
- ir -> impl = dispatch_table [ir -> opcode ];
773
- remove_next_nth_ir (rv , ir , block , 1 );
774
- return true;
775
- }
776
- if (IF_imm (next_ir , 28 ) && detect_memcpy (rv , 1 )) {
777
- ir -> opcode = rv_insn_fuse6 ;
778
- ir -> impl = dispatch_table [ir -> opcode ];
779
- remove_next_nth_ir (rv , ir , block , 1 );
780
- return true;
781
- };
782
- }
783
- }
784
- break ;
785
- case rv_insn_xor :
786
- /* Compare the target block with the first basic block of memcpy, if
787
- * two block is match, we would extract the instruction sequence
788
- * starting from the pc_start of the basic block and then compare
789
- * it with the pre-recorded memcpy instruction sequence.
790
- */
791
- if (IF_rd (ir , a5 ) && IF_rs1 (ir , a0 ) && IF_rs2 (ir , a1 )) {
792
- next_ir = ir -> next ;
793
- assert (next_ir );
794
- if (IF_insn (next_ir , andi ) && IF_imm (next_ir , 3 ) &&
795
- IF_rd (next_ir , a5 ) && IF_rs1 (next_ir , a5 )) {
796
- next_ir = next_ir -> next ;
797
- if (IF_insn (next_ir , add ) && IF_rd (next_ir , a7 ) &&
798
- IF_rs1 (next_ir , a0 ) && IF_rs2 (next_ir , a2 )) {
799
- next_ir = next_ir -> next ;
800
- if (IF_insn (next_ir , bne ) && IF_imm (next_ir , 104 ) &&
801
- IF_rs1 (next_ir , a5 ) && IF_rs2 (next_ir , zero )) {
802
- if (detect_memcpy (rv , 0 )) {
803
- ir -> opcode = rv_insn_fuse6 ;
804
- ir -> impl = dispatch_table [ir -> opcode ];
805
- remove_next_nth_ir (rv , ir , block , 3 );
806
- return true;
807
- }
808
- }
809
- }
810
- }
811
- }
812
- break ;
813
- /* TODO: Inject other frequently used function calls from the C standard
814
- * library.
815
- */
816
- }
817
- return false;
818
- }
819
-
820
668
/* Check if instructions in a block match a specific pattern. If they do,
821
669
* rewrite them as fused instructions.
822
670
*
@@ -902,7 +750,7 @@ static void match_pattern(riscv_t *rv, block_t *block)
902
750
ir -> fuse = malloc (count * sizeof (opcode_fuse_t ));
903
751
assert (ir -> fuse );
904
752
memcpy (ir -> fuse , ir , sizeof (opcode_fuse_t ));
905
- ir -> opcode = rv_insn_fuse7 ;
753
+ ir -> opcode = rv_insn_fuse5 ;
906
754
ir -> imm2 = count ;
907
755
ir -> impl = dispatch_table [ir -> opcode ];
908
756
next_ir = ir -> next ;
@@ -971,14 +819,13 @@ static block_t *block_find_or_translate(riscv_t *rv)
971
819
next = block_alloc (rv );
972
820
block_translate (rv , next );
973
821
974
- if (!libc_substitute (rv , next )) {
975
- optimize_constant (rv , next );
822
+ optimize_constant (rv , next );
976
823
#if RV32_HAS (GDBSTUB )
977
- if (likely (!rv -> debug_mode ))
824
+ if (likely (!rv -> debug_mode ))
978
825
#endif
979
- /* macro operation fusion */
980
- match_pattern (rv , next );
981
- }
826
+ /* macro operation fusion */
827
+ match_pattern (rv , next );
828
+
982
829
#if !RV32_HAS (JIT )
983
830
/* insert the block into block map */
984
831
block_insert (& rv -> block_map , next );
0 commit comments