Commit 937d44e9 authored by Vasili Skurydzin's avatar Vasili Skurydzin Committed by V8 LUCI CQ

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/+/3272206Reviewed-by: 's avatarJunliang Yan <junyan@redhat.com>
Commit-Queue: Vasili Skurydzin <vasili.skurydzin@ibm.com>
Cr-Commit-Position: refs/heads/main@{#77823}
parent fe0ec12a
......@@ -3734,12 +3734,80 @@ void TurboAssembler::CountLeadingZerosU64(Register dst, Register src, RCBit r) {
void TurboAssembler::CountTrailingZerosU32(Register dst, Register src,
RCBit r) {
cnttzw(dst, src, r);
if (CpuFeatures::IsSupported(PPC_9_PLUS)) {
cnttzw(dst, src, r);
} else {
Register scratch1 = GetRegisterThatIsNotOneOf(dst, src, sp);
Register scratch2 = GetRegisterThatIsNotOneOf(dst, src, sp, scratch1);
Push(scratch1, scratch2);
ReverseBitsU32(dst, src, scratch1, scratch2);
Pop(scratch1, scratch2);
cntlzw(dst, dst, r);
}
}
void TurboAssembler::CountTrailingZerosU64(Register dst, Register src,
RCBit r) {
cnttzd(dst, src, r);
if (CpuFeatures::IsSupported(PPC_9_PLUS)) {
cnttzd(dst, src, r);
} else {
Register scratch1 = GetRegisterThatIsNotOneOf(dst, src, sp);
Register scratch2 = GetRegisterThatIsNotOneOf(dst, src, sp, scratch1);
Push(scratch1, scratch2);
ReverseBitsU64(dst, src, scratch1, scratch2);
Pop(scratch1, scratch2);
cntlzd(dst, dst, r);
}
}
void TurboAssembler::ClearByteU64(Register dst, int byte_idx) {
CHECK(0 <= byte_idx && byte_idx <= 7);
int shift = byte_idx*8;
rldicl(dst, dst, shift, 8);
rldicl(dst, dst, 64-shift, 0);
}
void TurboAssembler::ReverseBitsU64(Register dst, Register src,
Register scratch1, Register scratch2) {
ByteReverseU64(dst, src);
for (int i = 0; i < 8; i++) {
ReverseBitsInSingleByteU64(dst, dst, scratch1, scratch2, i);
}
}
void TurboAssembler::ReverseBitsU32(Register dst, Register src,
Register scratch1, Register scratch2) {
ByteReverseU32(dst, src);
for (int i = 4; i < 8; i++) {
ReverseBitsInSingleByteU64(dst, dst, scratch1, scratch2, i);
}
}
// byte_idx=7 refers to least significant byte
void TurboAssembler::ReverseBitsInSingleByteU64(Register dst, Register src,
Register scratch1,
Register scratch2,
int byte_idx) {
CHECK(0 <= byte_idx && byte_idx <= 7);
int j = byte_idx;
// zero all bits of scratch1
li(scratch2, Operand(0));
for (int i = 0; i <= 7; i++) {
// zero all bits of scratch1
li(scratch1, Operand(0));
// move bit (j+1)*8-i-1 of src to bit j*8+i of scratch1, erase bits
// (j*8+i+1):end of scratch1
int shift = 7 - (2*i);
if (shift < 0) shift += 64;
rldicr(scratch1, src, shift, j*8+i);
// erase bits start:(j*8-1+i) of scratch1 (inclusive)
rldicl(scratch1, scratch1, 0, j*8+i);
// scratch2 = scratch2|scratch1
orx(scratch2, scratch2, scratch1);
}
// clear jth byte of dst and insert jth byte of scratch2
ClearByteU64(dst, j);
orx(dst, dst, scratch2);
}
} // namespace internal
......
......@@ -266,6 +266,15 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void CountTrailingZerosU32(Register dst, Register src, RCBit r = LeaveRC);
void CountTrailingZerosU64(Register dst, Register src, RCBit r = LeaveRC);
void ClearByteU64(Register dst, int byte_idx);
void ReverseBitsU64(Register dst, Register src, Register scratch1,
Register scratch2);
void ReverseBitsU32(Register dst, Register src, Register scratch1,
Register scratch2);
void ReverseBitsInSingleByteU64(Register dst, Register src,
Register scratch1, Register scratch2,
int byte_idx);
void AddF64(DoubleRegister dst, DoubleRegister lhs, DoubleRegister rhs,
RCBit r = LeaveRC);
void SubF64(DoubleRegister dst, DoubleRegister lhs, DoubleRegister rhs,
......
......@@ -62,6 +62,70 @@ TEST_F(TurboAssemblerTest, TestCheck) {
ASSERT_DEATH_IF_SUPPORTED({ f.Call(17); }, "abort: no reason");
}
TEST_F(TurboAssemblerTest, ReverseBitsU64) {
struct {
uint64_t expected; uint64_t input;
} values[] = {
{0x0000000000000000, 0x0000000000000000},
{0xffffffffffffffff, 0xffffffffffffffff},
{0x8000000000000000, 0x0000000000000001},
{0x0000000000000001, 0x8000000000000000},
{0x800066aa22cc4488, 0x1122334455660001},
{0x1122334455660001, 0x800066aa22cc4488},
{0xffffffff00000000, 0x00000000ffffffff},
{0x00000000ffffffff, 0xffffffff00000000},
{0xff01020304050607, 0xe060a020c04080ff},
{0xe060a020c04080ff, 0xff01020304050607},
};
auto buffer = AllocateAssemblerBuffer();
TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Push(r4, r5);
__ ReverseBitsU64(r3, r3, r4, r5);
__ Pop(r4, r5);
__ Ret();
CodeDesc desc;
tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
auto f = GeneratedCode<uint64_t, uint64_t>::FromBuffer(isolate(),
buffer->start());
for (unsigned int i=0; i < (sizeof(values) / sizeof(values[0])); i++) {
CHECK_EQ(values[i].expected, f.Call(values[i].input));
}
}
TEST_F(TurboAssemblerTest, ReverseBitsU32) {
struct {
uint64_t expected; uint64_t input;
} values[] = {
{0x00000000, 0x00000000},
{0xffffffff, 0xffffffff},
{0x00000001, 0x80000000},
{0x80000000, 0x00000001},
{0x22334455, 0xaa22cc44},
{0xaa22cc44, 0x22334455},
};
auto buffer = AllocateAssemblerBuffer();
TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Push(r4, r5);
__ ReverseBitsU32(r3, r3, r4, r5);
__ Pop(r4, r5);
__ Ret();
CodeDesc desc;
tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
auto f = GeneratedCode<uint64_t, uint64_t>::FromBuffer(isolate(),
buffer->start());
for (unsigned int i=0; i < (sizeof(values) / sizeof(values[0])); i++) {
CHECK_EQ(values[i].expected, f.Call(values[i].input));
}
}
#undef __
} // namespace internal
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment