Commit d151feeb authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC64: Implemented the Word64Popcnt TurboFan operator.

R=ahaas@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, dstence@us.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1413833013

Cr-Commit-Position: refs/heads/master@{#31931}
parent 56c7a053
......@@ -998,6 +998,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ popcntw(i.OutputRegister(), i.InputRegister(0));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
#if V8_TARGET_ARCH_PPC64
case kPPC_Popcnt64:
__ popcntd(i.OutputRegister(), i.InputRegister(0));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
#endif
case kPPC_Cmp32:
ASSEMBLE_COMPARE(cmpw, cmplw);
break;
......
......@@ -64,6 +64,7 @@ namespace compiler {
V(PPC_Cntlz32) \
V(PPC_Cntlz64) \
V(PPC_Popcnt32) \
V(PPC_Popcnt64) \
V(PPC_Cmp32) \
V(PPC_Cmp64) \
V(PPC_CmpDouble) \
......
......@@ -774,6 +774,15 @@ void InstructionSelector::VisitWord32Popcnt(Node* node) {
}
#if V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitWord64Popcnt(Node* node) {
PPCOperandGenerator g(this);
Emit(kPPC_Popcnt64, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(0)));
}
#endif
void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
......@@ -1616,7 +1625,8 @@ InstructionSelector::SupportedMachineOperatorFlags() {
return MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat64RoundTruncate |
MachineOperatorBuilder::kFloat64RoundTiesAway |
MachineOperatorBuilder::kWord32Popcnt;
MachineOperatorBuilder::kWord32Popcnt |
MachineOperatorBuilder::kWord64Popcnt;
// We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f.
}
......
......@@ -1476,6 +1476,11 @@ void Assembler::cntlzd_(Register ra, Register rs, RCBit rc) {
}
void Assembler::popcntd(Register ra, Register rs) {
emit(EXT2 | POPCNTD | rs.code() * B21 | ra.code() * B16);
}
void Assembler::mulld(Register dst, Register src1, Register src2, OEBit o,
RCBit r) {
xo_form(EXT2 | MULLD, dst, src1, src2, o, r);
......
......@@ -907,6 +907,7 @@ class Assembler : public AssemblerBase {
void rotldi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
void rotrdi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
void cntlzd_(Register dst, Register src, RCBit rc = LeaveRC);
void popcntd(Register dst, Register src);
void mulld(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
RCBit r = LeaveRC);
void divd(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
......
......@@ -238,6 +238,7 @@ enum OpcodeExt2 {
MTSPR = 467 << 1, // Move to Special-Purpose-Register
DIVD = 489 << 1, // Divide Double Word
DIVW = 491 << 1, // Divide Word
POPCNTD = 506 << 1, // Population Count Doubleword
// Below represent bits 10-1 (any value >= 512)
LFSX = 535 << 1, // load float-single w/ x-form
......
......@@ -613,6 +613,12 @@ void Decoder::DecodeExt2(Instruction* instr) {
Format(instr, "popcntw 'ra, 'rs");
return;
}
#if V8_TARGET_ARCH_PPC64
case POPCNTD: {
Format(instr, "popcntd 'ra, 'rs");
return;
}
#endif
}
switch (instr->Bits(10, 2) << 2) {
......
......@@ -1863,6 +1863,22 @@ bool Simulator::ExecuteExt2_10bit(Instruction* instr) {
set_register(ra, count);
break;
}
#if V8_TARGET_ARCH_PPC64
case POPCNTD: {
int rs = instr->RSValue();
int ra = instr->RAValue();
uintptr_t rs_val = get_register(rs);
uintptr_t count = 0;
int n = 0;
uintptr_t bit = 0x8000000000000000UL;
for (; n < 64; n++) {
if (bit & rs_val) count++;
bit >>= 1;
}
set_register(ra, count);
break;
}
#endif
case SYNC: {
// todo - simulate sync
break;
......
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