@@ -2804,19 +2804,55 @@ void TurboAssembler::DivU32(Register dst, Register src, Register value, OEBit s,
28042804}
28052805
28062806void 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+ }
28082817}
28092818
28102819void 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+ }
28122830}
28132831
28142832void 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+ }
28162843 extsw (dst, dst);
28172844}
28182845void 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+ }
28202856 ZeroExtWord32 (dst, dst);
28212857}
28222858
@@ -3718,14 +3754,88 @@ void TurboAssembler::CountLeadingZerosU64(Register dst, Register src, RCBit r) {
37183754 cntlzd (dst, src, r);
37193755}
37203756
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);
37213770void TurboAssembler::CountTrailingZerosU32 (Register dst, Register src,
3771+ Register scratch1, Register scratch2,
37223772 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+ }
37243778}
37253779
37263780void TurboAssembler::CountTrailingZerosU64 (Register dst, Register src,
3781+ Register scratch1, Register scratch2,
37273782 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);
37293839}
37303840
37313841} // namespace internal
0 commit comments