Skip to content

Commit 937d44e

Browse files
Vasili SkurydzinV8 LUCI CQ
authored andcommitted
ppc: Don't emit cnttzd, cnttzw if Power proc. version is less than 9
Change-Id: Ic868b6f9bb17bb9d6e6fe2a7203a41383aef5cf7 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3272206 Reviewed-by: Junliang Yan <[email protected]> Commit-Queue: Vasili Skurydzin <[email protected]> Cr-Commit-Position: refs/heads/main@{#77823}
1 parent fe0ec12 commit 937d44e

File tree

3 files changed

+143
-2
lines changed

3 files changed

+143
-2
lines changed

src/codegen/ppc/macro-assembler-ppc.cc

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,12 +3734,80 @@ void TurboAssembler::CountLeadingZerosU64(Register dst, Register src, RCBit r) {
37343734

37353735
void TurboAssembler::CountTrailingZerosU32(Register dst, Register src,
37363736
RCBit r) {
3737-
cnttzw(dst, src, r);
3737+
if (CpuFeatures::IsSupported(PPC_9_PLUS)) {
3738+
cnttzw(dst, src, r);
3739+
} else {
3740+
Register scratch1 = GetRegisterThatIsNotOneOf(dst, src, sp);
3741+
Register scratch2 = GetRegisterThatIsNotOneOf(dst, src, sp, scratch1);
3742+
Push(scratch1, scratch2);
3743+
ReverseBitsU32(dst, src, scratch1, scratch2);
3744+
Pop(scratch1, scratch2);
3745+
cntlzw(dst, dst, r);
3746+
}
37383747
}
37393748

37403749
void TurboAssembler::CountTrailingZerosU64(Register dst, Register src,
37413750
RCBit r) {
3742-
cnttzd(dst, src, r);
3751+
if (CpuFeatures::IsSupported(PPC_9_PLUS)) {
3752+
cnttzd(dst, src, r);
3753+
} else {
3754+
Register scratch1 = GetRegisterThatIsNotOneOf(dst, src, sp);
3755+
Register scratch2 = GetRegisterThatIsNotOneOf(dst, src, sp, scratch1);
3756+
Push(scratch1, scratch2);
3757+
ReverseBitsU64(dst, src, scratch1, scratch2);
3758+
Pop(scratch1, scratch2);
3759+
cntlzd(dst, dst, r);
3760+
}
3761+
}
3762+
3763+
void TurboAssembler::ClearByteU64(Register dst, int byte_idx) {
3764+
CHECK(0 <= byte_idx && byte_idx <= 7);
3765+
int shift = byte_idx*8;
3766+
rldicl(dst, dst, shift, 8);
3767+
rldicl(dst, dst, 64-shift, 0);
3768+
}
3769+
3770+
void TurboAssembler::ReverseBitsU64(Register dst, Register src,
3771+
Register scratch1, Register scratch2) {
3772+
ByteReverseU64(dst, src);
3773+
for (int i = 0; i < 8; i++) {
3774+
ReverseBitsInSingleByteU64(dst, dst, scratch1, scratch2, i);
3775+
}
3776+
}
3777+
3778+
void TurboAssembler::ReverseBitsU32(Register dst, Register src,
3779+
Register scratch1, Register scratch2) {
3780+
ByteReverseU32(dst, src);
3781+
for (int i = 4; i < 8; i++) {
3782+
ReverseBitsInSingleByteU64(dst, dst, scratch1, scratch2, i);
3783+
}
3784+
}
3785+
3786+
// byte_idx=7 refers to least significant byte
3787+
void TurboAssembler::ReverseBitsInSingleByteU64(Register dst, Register src,
3788+
Register scratch1,
3789+
Register scratch2,
3790+
int byte_idx) {
3791+
CHECK(0 <= byte_idx && byte_idx <= 7);
3792+
int j = byte_idx;
3793+
// zero all bits of scratch1
3794+
li(scratch2, Operand(0));
3795+
for (int i = 0; i <= 7; i++) {
3796+
// zero all bits of scratch1
3797+
li(scratch1, Operand(0));
3798+
// move bit (j+1)*8-i-1 of src to bit j*8+i of scratch1, erase bits
3799+
// (j*8+i+1):end of scratch1
3800+
int shift = 7 - (2*i);
3801+
if (shift < 0) shift += 64;
3802+
rldicr(scratch1, src, shift, j*8+i);
3803+
// erase bits start:(j*8-1+i) of scratch1 (inclusive)
3804+
rldicl(scratch1, scratch1, 0, j*8+i);
3805+
// scratch2 = scratch2|scratch1
3806+
orx(scratch2, scratch2, scratch1);
3807+
}
3808+
// clear jth byte of dst and insert jth byte of scratch2
3809+
ClearByteU64(dst, j);
3810+
orx(dst, dst, scratch2);
37433811
}
37443812

37453813
} // namespace internal

src/codegen/ppc/macro-assembler-ppc.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,15 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
266266
void CountTrailingZerosU32(Register dst, Register src, RCBit r = LeaveRC);
267267
void CountTrailingZerosU64(Register dst, Register src, RCBit r = LeaveRC);
268268

269+
void ClearByteU64(Register dst, int byte_idx);
270+
void ReverseBitsU64(Register dst, Register src, Register scratch1,
271+
Register scratch2);
272+
void ReverseBitsU32(Register dst, Register src, Register scratch1,
273+
Register scratch2);
274+
void ReverseBitsInSingleByteU64(Register dst, Register src,
275+
Register scratch1, Register scratch2,
276+
int byte_idx);
277+
269278
void AddF64(DoubleRegister dst, DoubleRegister lhs, DoubleRegister rhs,
270279
RCBit r = LeaveRC);
271280
void SubF64(DoubleRegister dst, DoubleRegister lhs, DoubleRegister rhs,

test/unittests/assembler/turbo-assembler-ppc-unittest.cc

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,70 @@ TEST_F(TurboAssemblerTest, TestCheck) {
6262
ASSERT_DEATH_IF_SUPPORTED({ f.Call(17); }, "abort: no reason");
6363
}
6464

65+
TEST_F(TurboAssemblerTest, ReverseBitsU64) {
66+
struct {
67+
uint64_t expected; uint64_t input;
68+
} values[] = {
69+
{0x0000000000000000, 0x0000000000000000},
70+
{0xffffffffffffffff, 0xffffffffffffffff},
71+
{0x8000000000000000, 0x0000000000000001},
72+
{0x0000000000000001, 0x8000000000000000},
73+
{0x800066aa22cc4488, 0x1122334455660001},
74+
{0x1122334455660001, 0x800066aa22cc4488},
75+
{0xffffffff00000000, 0x00000000ffffffff},
76+
{0x00000000ffffffff, 0xffffffff00000000},
77+
{0xff01020304050607, 0xe060a020c04080ff},
78+
{0xe060a020c04080ff, 0xff01020304050607},
79+
};
80+
auto buffer = AllocateAssemblerBuffer();
81+
TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
82+
buffer->CreateView());
83+
__ set_root_array_available(false);
84+
__ set_abort_hard(true);
85+
__ Push(r4, r5);
86+
__ ReverseBitsU64(r3, r3, r4, r5);
87+
__ Pop(r4, r5);
88+
__ Ret();
89+
CodeDesc desc;
90+
tasm.GetCode(isolate(), &desc);
91+
buffer->MakeExecutable();
92+
auto f = GeneratedCode<uint64_t, uint64_t>::FromBuffer(isolate(),
93+
buffer->start());
94+
for (unsigned int i=0; i < (sizeof(values) / sizeof(values[0])); i++) {
95+
CHECK_EQ(values[i].expected, f.Call(values[i].input));
96+
}
97+
}
98+
99+
TEST_F(TurboAssemblerTest, ReverseBitsU32) {
100+
struct {
101+
uint64_t expected; uint64_t input;
102+
} values[] = {
103+
{0x00000000, 0x00000000},
104+
{0xffffffff, 0xffffffff},
105+
{0x00000001, 0x80000000},
106+
{0x80000000, 0x00000001},
107+
{0x22334455, 0xaa22cc44},
108+
{0xaa22cc44, 0x22334455},
109+
};
110+
auto buffer = AllocateAssemblerBuffer();
111+
TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
112+
buffer->CreateView());
113+
__ set_root_array_available(false);
114+
__ set_abort_hard(true);
115+
__ Push(r4, r5);
116+
__ ReverseBitsU32(r3, r3, r4, r5);
117+
__ Pop(r4, r5);
118+
__ Ret();
119+
CodeDesc desc;
120+
tasm.GetCode(isolate(), &desc);
121+
buffer->MakeExecutable();
122+
auto f = GeneratedCode<uint64_t, uint64_t>::FromBuffer(isolate(),
123+
buffer->start());
124+
for (unsigned int i=0; i < (sizeof(values) / sizeof(values[0])); i++) {
125+
CHECK_EQ(values[i].expected, f.Call(values[i].input));
126+
}
127+
}
128+
65129
#undef __
66130

67131
} // namespace internal

0 commit comments

Comments
 (0)