@@ -2818,19 +2818,55 @@ void TurboAssembler::DivU32(Register dst, Register src, Register value, OEBit s,
28182818}
28192819
28202820void 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+ }
28222831}
28232832
28242833void 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+ }
28262844}
28272845
28282846void 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+ }
28302857 extsw (dst, dst);
28312858}
28322859void 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+ }
28342870 ZeroExtWord32 (dst, dst);
28352871}
28362872
@@ -3732,14 +3768,88 @@ void TurboAssembler::CountLeadingZerosU64(Register dst, Register src, RCBit r) {
37323768 cntlzd (dst, src, r);
37333769}
37343770
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);
37353784void TurboAssembler::CountTrailingZerosU32 (Register dst, Register src,
3785+ Register scratch1, Register scratch2,
37363786 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+ }
37383792}
37393793
37403794void TurboAssembler::CountTrailingZerosU64 (Register dst, Register src,
3795+ Register scratch1, Register scratch2,
37413796 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);
37433853}
37443854
37453855} // namespace internal
0 commit comments