@@ -2818,19 +2818,55 @@ void TurboAssembler::DivU32(Register dst, Register src, Register value, OEBit s,
2818
2818
}
2819
2819
2820
2820
void TurboAssembler::ModS64 (Register dst, Register src, Register value) {
2821
- modsd (dst, src, value);
2821
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
2822
+ modsd (dst, src, value);
2823
+ } else {
2824
+ Register scratch = GetRegisterThatIsNotOneOf (dst, src, value);
2825
+ Push (scratch);
2826
+ divd (scratch, src, value);
2827
+ mulld (scratch, scratch, value);
2828
+ sub (dst, src, scratch);
2829
+ Pop (scratch);
2830
+ }
2822
2831
}
2823
2832
2824
2833
void TurboAssembler::ModU64 (Register dst, Register src, Register value) {
2825
- modud (dst, src, value);
2834
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
2835
+ modud (dst, src, value);
2836
+ } else {
2837
+ Register scratch = GetRegisterThatIsNotOneOf (dst, src, value);
2838
+ Push (scratch);
2839
+ divdu (scratch, src, value);
2840
+ mulld (scratch, scratch, value);
2841
+ sub (dst, src, scratch);
2842
+ Pop (scratch);
2843
+ }
2826
2844
}
2827
2845
2828
2846
void TurboAssembler::ModS32 (Register dst, Register src, Register value) {
2829
- modsw (dst, src, value);
2847
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
2848
+ modsw (dst, src, value);
2849
+ } else {
2850
+ Register scratch = GetRegisterThatIsNotOneOf (dst, src, value);
2851
+ Push (scratch);
2852
+ divw (scratch, src, value);
2853
+ mullw (scratch, scratch, value);
2854
+ sub (dst, src, scratch);
2855
+ Pop (scratch);
2856
+ }
2830
2857
extsw (dst, dst);
2831
2858
}
2832
2859
void TurboAssembler::ModU32 (Register dst, Register src, Register value) {
2833
- moduw (dst, src, value);
2860
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
2861
+ moduw (dst, src, value);
2862
+ } else {
2863
+ Register scratch = GetRegisterThatIsNotOneOf (dst, src, value);
2864
+ Push (scratch);
2865
+ divwu (scratch, src, value);
2866
+ mullw (scratch, scratch, value);
2867
+ sub (dst, src, scratch);
2868
+ Pop (scratch);
2869
+ }
2834
2870
ZeroExtWord32 (dst, dst);
2835
2871
}
2836
2872
@@ -3732,14 +3768,88 @@ void TurboAssembler::CountLeadingZerosU64(Register dst, Register src, RCBit r) {
3732
3768
cntlzd (dst, src, r);
3733
3769
}
3734
3770
3771
+ #define COUNT_TRAILING_ZEROES_SLOW (max_count, scratch1, scratch2 ) \
3772
+ Label loop, done; \
3773
+ li (scratch1, Operand (max_count)); \
3774
+ mtctr (scratch1); \
3775
+ mr (scratch1, src); \
3776
+ li (dst, Operand::Zero ()); \
3777
+ bind (&loop); /* while ((src & 1) == 0) */ \
3778
+ andi (scratch2, scratch1, Operand (1 )); \
3779
+ bne (&done, cr0); \
3780
+ srdi (scratch1, scratch1, Operand (1 )); /* src >>= 1;*/ \
3781
+ addi (dst, dst, Operand (1 )); /* dst++ */ \
3782
+ bdnz (&loop); \
3783
+ bind (&done);
3735
3784
void TurboAssembler::CountTrailingZerosU32 (Register dst, Register src,
3785
+ Register scratch1, Register scratch2,
3736
3786
RCBit r) {
3737
- cnttzw (dst, src, r);
3787
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
3788
+ cnttzw (dst, src, r);
3789
+ } else {
3790
+ COUNT_TRAILING_ZEROES_SLOW (32 , scratch1, scratch2);
3791
+ }
3738
3792
}
3739
3793
3740
3794
void TurboAssembler::CountTrailingZerosU64 (Register dst, Register src,
3795
+ Register scratch1, Register scratch2,
3741
3796
RCBit r) {
3742
- cnttzd (dst, src, r);
3797
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
3798
+ cnttzd (dst, src, r);
3799
+ } else {
3800
+ COUNT_TRAILING_ZEROES_SLOW (64 , scratch1, scratch2);
3801
+ }
3802
+ }
3803
+ #undef COUNT_TRAILING_ZEROES_SLOW
3804
+
3805
+ void TurboAssembler::ClearByteU64 (Register dst, int byte_idx) {
3806
+ CHECK (0 <= byte_idx && byte_idx <= 7 );
3807
+ int shift = byte_idx*8 ;
3808
+ rldicl (dst, dst, shift, 8 );
3809
+ rldicl (dst, dst, 64 -shift, 0 );
3810
+ }
3811
+
3812
+ void TurboAssembler::ReverseBitsU64 (Register dst, Register src,
3813
+ Register scratch1, Register scratch2) {
3814
+ ByteReverseU64 (dst, src);
3815
+ for (int i = 0 ; i < 8 ; i++) {
3816
+ ReverseBitsInSingleByteU64 (dst, dst, scratch1, scratch2, i);
3817
+ }
3818
+ }
3819
+
3820
+ void TurboAssembler::ReverseBitsU32 (Register dst, Register src,
3821
+ Register scratch1, Register scratch2) {
3822
+ ByteReverseU32 (dst, src);
3823
+ for (int i = 4 ; i < 8 ; i++) {
3824
+ ReverseBitsInSingleByteU64 (dst, dst, scratch1, scratch2, i);
3825
+ }
3826
+ }
3827
+
3828
+ // byte_idx=7 refers to least significant byte
3829
+ void TurboAssembler::ReverseBitsInSingleByteU64 (Register dst, Register src,
3830
+ Register scratch1,
3831
+ Register scratch2,
3832
+ int byte_idx) {
3833
+ CHECK (0 <= byte_idx && byte_idx <= 7 );
3834
+ int j = byte_idx;
3835
+ // zero all bits of scratch1
3836
+ li (scratch2, Operand (0 ));
3837
+ for (int i = 0 ; i <= 7 ; i++) {
3838
+ // zero all bits of scratch1
3839
+ li (scratch1, Operand (0 ));
3840
+ // move bit (j+1)*8-i-1 of src to bit j*8+i of scratch1, erase bits
3841
+ // (j*8+i+1):end of scratch1
3842
+ int shift = 7 - (2 *i);
3843
+ if (shift < 0 ) shift += 64 ;
3844
+ rldicr (scratch1, src, shift, j*8 +i);
3845
+ // erase bits start:(j*8-1+i) of scratch1 (inclusive)
3846
+ rldicl (scratch1, scratch1, 0 , j*8 +i);
3847
+ // scratch2 = scratch2|scratch1
3848
+ orx (scratch2, scratch2, scratch1);
3849
+ }
3850
+ // clear jth byte of dst and insert jth byte of scratch2
3851
+ ClearByteU64 (dst, j);
3852
+ orx (dst, dst, scratch2);
3743
3853
}
3744
3854
3745
3855
} // namespace internal
0 commit comments