@@ -2804,19 +2804,55 @@ void TurboAssembler::DivU32(Register dst, Register src, Register value, OEBit s,
2804
2804
}
2805
2805
2806
2806
void TurboAssembler::ModS64 (Register dst, Register src, Register value) {
2807
- modsd (dst, src, value);
2807
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
2808
+ modsd (dst, src, value);
2809
+ } else {
2810
+ Register scratch = GetRegisterThatIsNotOneOf (dst, src, value);
2811
+ Push (scratch);
2812
+ divd (scratch, src, value);
2813
+ mulld (scratch, scratch, value);
2814
+ sub (dst, src, scratch);
2815
+ Pop (scratch);
2816
+ }
2808
2817
}
2809
2818
2810
2819
void TurboAssembler::ModU64 (Register dst, Register src, Register value) {
2811
- modud (dst, src, value);
2820
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
2821
+ modud (dst, src, value);
2822
+ } else {
2823
+ Register scratch = GetRegisterThatIsNotOneOf (dst, src, value);
2824
+ Push (scratch);
2825
+ divdu (scratch, src, value);
2826
+ mulld (scratch, scratch, value);
2827
+ sub (dst, src, scratch);
2828
+ Pop (scratch);
2829
+ }
2812
2830
}
2813
2831
2814
2832
void TurboAssembler::ModS32 (Register dst, Register src, Register value) {
2815
- modsw (dst, src, value);
2833
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
2834
+ modsw (dst, src, value);
2835
+ } else {
2836
+ Register scratch = GetRegisterThatIsNotOneOf (dst, src, value);
2837
+ Push (scratch);
2838
+ divw (scratch, src, value);
2839
+ mullw (scratch, scratch, value);
2840
+ sub (dst, src, scratch);
2841
+ Pop (scratch);
2842
+ }
2816
2843
extsw (dst, dst);
2817
2844
}
2818
2845
void TurboAssembler::ModU32 (Register dst, Register src, Register value) {
2819
- moduw (dst, src, value);
2846
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
2847
+ moduw (dst, src, value);
2848
+ } else {
2849
+ Register scratch = GetRegisterThatIsNotOneOf (dst, src, value);
2850
+ Push (scratch);
2851
+ divwu (scratch, src, value);
2852
+ mullw (scratch, scratch, value);
2853
+ sub (dst, src, scratch);
2854
+ Pop (scratch);
2855
+ }
2820
2856
ZeroExtWord32 (dst, dst);
2821
2857
}
2822
2858
@@ -3718,14 +3754,88 @@ void TurboAssembler::CountLeadingZerosU64(Register dst, Register src, RCBit r) {
3718
3754
cntlzd (dst, src, r);
3719
3755
}
3720
3756
3757
+ #define COUNT_TRAILING_ZEROES_SLOW (max_count, scratch1, scratch2 ) \
3758
+ Label loop, done; \
3759
+ li (scratch1, Operand (max_count)); \
3760
+ mtctr (scratch1); \
3761
+ mr (scratch1, src); \
3762
+ li (dst, Operand::Zero ()); \
3763
+ bind (&loop); /* while ((src & 1) == 0) */ \
3764
+ andi (scratch2, scratch1, Operand (1 )); \
3765
+ bne (&done, cr0); \
3766
+ srdi (scratch1, scratch1, Operand (1 )); /* src >>= 1;*/ \
3767
+ addi (dst, dst, Operand (1 )); /* dst++ */ \
3768
+ bdnz (&loop); \
3769
+ bind (&done);
3721
3770
void TurboAssembler::CountTrailingZerosU32 (Register dst, Register src,
3771
+ Register scratch1, Register scratch2,
3722
3772
RCBit r) {
3723
- cnttzw (dst, src, r);
3773
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
3774
+ cnttzw (dst, src, r);
3775
+ } else {
3776
+ COUNT_TRAILING_ZEROES_SLOW (32 , scratch1, scratch2);
3777
+ }
3724
3778
}
3725
3779
3726
3780
void TurboAssembler::CountTrailingZerosU64 (Register dst, Register src,
3781
+ Register scratch1, Register scratch2,
3727
3782
RCBit r) {
3728
- cnttzd (dst, src, r);
3783
+ if (CpuFeatures::IsSupported (PPC_9_PLUS)) {
3784
+ cnttzd (dst, src, r);
3785
+ } else {
3786
+ COUNT_TRAILING_ZEROES_SLOW (64 , scratch1, scratch2);
3787
+ }
3788
+ }
3789
+ #undef COUNT_TRAILING_ZEROES_SLOW
3790
+
3791
+ void TurboAssembler::ClearByteU64 (Register dst, int byte_idx) {
3792
+ CHECK (0 <= byte_idx && byte_idx <= 7 );
3793
+ int shift = byte_idx*8 ;
3794
+ rldicl (dst, dst, shift, 8 );
3795
+ rldicl (dst, dst, 64 -shift, 0 );
3796
+ }
3797
+
3798
+ void TurboAssembler::ReverseBitsU64 (Register dst, Register src,
3799
+ Register scratch1, Register scratch2) {
3800
+ ByteReverseU64 (dst, src);
3801
+ for (int i = 0 ; i < 8 ; i++) {
3802
+ ReverseBitsInSingleByteU64 (dst, dst, scratch1, scratch2, i);
3803
+ }
3804
+ }
3805
+
3806
+ void TurboAssembler::ReverseBitsU32 (Register dst, Register src,
3807
+ Register scratch1, Register scratch2) {
3808
+ ByteReverseU32 (dst, src);
3809
+ for (int i = 4 ; i < 8 ; i++) {
3810
+ ReverseBitsInSingleByteU64 (dst, dst, scratch1, scratch2, i);
3811
+ }
3812
+ }
3813
+
3814
+ // byte_idx=7 refers to least significant byte
3815
+ void TurboAssembler::ReverseBitsInSingleByteU64 (Register dst, Register src,
3816
+ Register scratch1,
3817
+ Register scratch2,
3818
+ int byte_idx) {
3819
+ CHECK (0 <= byte_idx && byte_idx <= 7 );
3820
+ int j = byte_idx;
3821
+ // zero all bits of scratch1
3822
+ li (scratch2, Operand (0 ));
3823
+ for (int i = 0 ; i <= 7 ; i++) {
3824
+ // zero all bits of scratch1
3825
+ li (scratch1, Operand (0 ));
3826
+ // move bit (j+1)*8-i-1 of src to bit j*8+i of scratch1, erase bits
3827
+ // (j*8+i+1):end of scratch1
3828
+ int shift = 7 - (2 *i);
3829
+ if (shift < 0 ) shift += 64 ;
3830
+ rldicr (scratch1, src, shift, j*8 +i);
3831
+ // erase bits start:(j*8-1+i) of scratch1 (inclusive)
3832
+ rldicl (scratch1, scratch1, 0 , j*8 +i);
3833
+ // scratch2 = scratch2|scratch1
3834
+ orx (scratch2, scratch2, scratch1);
3835
+ }
3836
+ // clear jth byte of dst and insert jth byte of scratch2
3837
+ ClearByteU64 (dst, j);
3838
+ orx (dst, dst, scratch2);
3729
3839
}
3730
3840
3731
3841
} // namespace internal
0 commit comments