@@ -567,7 +567,19 @@ if_block(
567
567
OffsetAfter = StreamModule :offset (Stream2 ),
568
568
% % Patch the conditional branch instruction to jump to the end of the block
569
569
BranchOffset = OffsetAfter - (Offset + BranchInstrOffset ),
570
- NewBranchInstr = jit_aarch64_asm :bcc (CC , BranchOffset ),
570
+ NewBranchInstr =
571
+ case CC of
572
+ {cbz , Reg } ->
573
+ jit_aarch64_asm :cbz (Reg , BranchOffset );
574
+ {cbz_w , Reg } ->
575
+ jit_aarch64_asm :cbz_w (Reg , BranchOffset );
576
+ {tbz , Reg , Bit } ->
577
+ jit_aarch64_asm :tbz (Reg , Bit , BranchOffset );
578
+ {tbnz , Reg , Bit } ->
579
+ jit_aarch64_asm :tbnz (Reg , Bit , BranchOffset );
580
+ CC when is_atom (CC ) ->
581
+ jit_aarch64_asm :bcc (CC , BranchOffset )
582
+ end ,
571
583
Stream3 = StreamModule :replace (Stream2 , Offset + BranchInstrOffset , NewBranchInstr ),
572
584
merge_used_regs (State2 # state {stream = Stream3 }, State1 # state .used_regs ).
573
585
@@ -621,16 +633,10 @@ if_else_block(
621
633
622
634
-spec if_block_cond (state (), condition ()) -> {state (), jit_aarch64_asm :cc (), non_neg_integer ()}.
623
635
if_block_cond (# state {stream_module = StreamModule , stream = Stream0 } = State0 , {Reg , '<' , 0 }) ->
624
- I1 = jit_aarch64_asm :tst (Reg , Reg ),
625
- % pl = positive or zero (>=0)
626
- I2 = jit_aarch64_asm :bcc (pl , 0 ),
627
- Code = <<
628
- I1 /binary ,
629
- I2 /binary
630
- >>,
631
- Stream1 = StreamModule :append (Stream0 , Code ),
636
+ I = jit_aarch64_asm :tbz (Reg , 63 , 0 ),
637
+ Stream1 = StreamModule :append (Stream0 , I ),
632
638
State1 = State0 # state {stream = Stream1 },
633
- {State1 , pl , byte_size ( I1 ) };
639
+ {State1 , { tbz , Reg , 63 }, 0 };
634
640
if_block_cond (
635
641
# state {stream_module = StreamModule , stream = Stream0 } = State0 ,
636
642
{RegA , '<' , RegB }
@@ -653,17 +659,11 @@ if_block_cond(
653
659
{free , Reg0 } -> Reg0 ;
654
660
RegOrTuple -> RegOrTuple
655
661
end ,
656
- I1 = jit_aarch64_asm :tst (Reg , Reg ),
657
- % ne = not equal
658
- I2 = jit_aarch64_asm :bcc (ne , 0 ),
659
- Code = <<
660
- I1 /binary ,
661
- I2 /binary
662
- >>,
663
- Stream1 = StreamModule :append (Stream0 , Code ),
662
+ I = jit_aarch64_asm :cbz (Reg , 0 ),
663
+ Stream1 = StreamModule :append (Stream0 , I ),
664
664
State1 = if_block_free_reg (RegOrTuple , State0 ),
665
665
State2 = State1 # state {stream = Stream1 },
666
- {State2 , ne , byte_size ( I1 ) };
666
+ {State2 , { cbz , Reg }, 0 };
667
667
if_block_cond (
668
668
# state {stream_module = StreamModule , stream = Stream0 } = State0 , {'(int)' , RegOrTuple , '==' , 0 }
669
669
) ->
@@ -672,16 +672,11 @@ if_block_cond(
672
672
{free , Reg0 } -> Reg0 ;
673
673
RegOrTuple -> RegOrTuple
674
674
end ,
675
- I1 = jit_aarch64_asm :tst_w (Reg , Reg ),
676
- I2 = jit_aarch64_asm :bcc (ne , 0 ),
677
- Code = <<
678
- I1 /binary ,
679
- I2 /binary
680
- >>,
681
- Stream1 = StreamModule :append (Stream0 , Code ),
675
+ I = jit_aarch64_asm :cbz_w (Reg , 0 ),
676
+ Stream1 = StreamModule :append (Stream0 , I ),
682
677
State1 = if_block_free_reg (RegOrTuple , State0 ),
683
678
State2 = State1 # state {stream = Stream1 },
684
- {State2 , ne , byte_size ( I1 ) };
679
+ {State2 , { cbz_w , Reg }, 0 };
685
680
if_block_cond (
686
681
# state {stream_module = StreamModule , stream = Stream0 } = State0 ,
687
682
{RegOrTuple , '!=' , Val }
@@ -783,17 +778,12 @@ if_block_cond(
783
778
{free , Reg0 } -> Reg0 ;
784
779
RegOrTuple -> RegOrTuple
785
780
end ,
786
- % Test low 8 bits
787
- I1 = jit_aarch64_asm :tst_w (Reg , 16#FF ),
788
- I2 = jit_aarch64_asm :bcc (ne , 0 ),
789
- Code = <<
790
- I1 /binary ,
791
- I2 /binary
792
- >>,
793
- Stream1 = StreamModule :append (Stream0 , Code ),
781
+ % Test lowest bit
782
+ I = jit_aarch64_asm :tbnz (Reg , 0 , 0 ),
783
+ Stream1 = StreamModule :append (Stream0 , I ),
794
784
State1 = if_block_free_reg (RegOrTuple , State0 ),
795
785
State2 = State1 # state {stream = Stream1 },
796
- {State2 , ne , byte_size ( I1 ) };
786
+ {State2 , { tbnz , Reg , 0 }, 0 };
797
787
if_block_cond (
798
788
# state {stream_module = StreamModule , stream = Stream0 } = State0 ,
799
789
{'(bool)' , RegOrTuple , '!=' , false }
@@ -803,8 +793,26 @@ if_block_cond(
803
793
{free , Reg0 } -> Reg0 ;
804
794
RegOrTuple -> RegOrTuple
805
795
end ,
806
- % Test low 8 bits
807
- I1 = jit_aarch64_asm :tst_w (Reg , 16#FF ),
796
+ % Test lowest bit
797
+ I = jit_aarch64_asm :tbz (Reg , 0 , 0 ),
798
+ Stream1 = StreamModule :append (Stream0 , I ),
799
+ State1 = if_block_free_reg (RegOrTuple , State0 ),
800
+ State2 = State1 # state {stream = Stream1 },
801
+ {State2 , {tbz , Reg , 0 }, 0 };
802
+ if_block_cond (
803
+ # state {
804
+ stream_module = StreamModule ,
805
+ stream = Stream0
806
+ } = State0 ,
807
+ {RegOrTuple , '&' , Val , '!=' , 0 }
808
+ ) ->
809
+ Reg =
810
+ case RegOrTuple of
811
+ {free , Reg0 } -> Reg0 ;
812
+ RegOrTuple -> RegOrTuple
813
+ end ,
814
+ % Test bits
815
+ I1 = jit_aarch64_asm :tst (Reg , Val ),
808
816
I2 = jit_aarch64_asm :bcc (eq , 0 ),
809
817
Code = <<
810
818
I1 /binary ,
@@ -853,53 +861,7 @@ if_block_cond(
853
861
Stream3 = StreamModule :append (Stream2 , I3 ),
854
862
State3 = State1 # state {stream = Stream3 },
855
863
State4 = if_block_free_reg (RegTuple , State3 ),
856
- {State4 , eq , OffsetAfter - OffsetBefore };
857
- if_block_cond (
858
- # state {
859
- stream_module = StreamModule ,
860
- stream = Stream0
861
- } = State0 ,
862
- {RegOrTuple , '&' , Val }
863
- ) ->
864
- Reg =
865
- case RegOrTuple of
866
- {free , Reg0 } -> Reg0 ;
867
- RegOrTuple -> RegOrTuple
868
- end ,
869
- % Test bits
870
- I1 = jit_aarch64_asm :tst (Reg , Val ),
871
- I2 = jit_aarch64_asm :bcc (eq , 0 ),
872
- Code = <<
873
- I1 /binary ,
874
- I2 /binary
875
- >>,
876
- Stream1 = StreamModule :append (Stream0 , Code ),
877
- State1 = if_block_free_reg (RegOrTuple , State0 ),
878
- State2 = State1 # state {stream = Stream1 },
879
- {State2 , eq , byte_size (I1 )};
880
- if_block_cond (
881
- # state {
882
- stream_module = StreamModule ,
883
- stream = Stream0
884
- } = State0 ,
885
- {'(bool)' , RegOrTuple , '&' , Val }
886
- ) ->
887
- Reg =
888
- case RegOrTuple of
889
- {free , Reg0 } -> Reg0 ;
890
- RegOrTuple -> RegOrTuple
891
- end ,
892
- % Test 8-bit value
893
- I1 = jit_aarch64_asm :tst_w (Reg , Val ),
894
- I2 = jit_aarch64_asm :bcc (eq , 0 ),
895
- Code = <<
896
- I1 /binary ,
897
- I2 /binary
898
- >>,
899
- Stream1 = StreamModule :append (Stream0 , Code ),
900
- State1 = if_block_free_reg (RegOrTuple , State0 ),
901
- State2 = State1 # state {stream = Stream1 },
902
- {State2 , eq , byte_size (I1 )}.
864
+ {State4 , eq , OffsetAfter - OffsetBefore }.
903
865
904
866
-spec if_block_free_reg (aarch64_register () | {free , aarch64_register ()}, state ()) -> state ().
905
867
if_block_free_reg ({free , Reg }, State0 ) ->
0 commit comments