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

PPC: Implement Popcnt operator.

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

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

Cr-Commit-Position: refs/heads/master@{#31346}
parent a1e9a6d7
......@@ -939,6 +939,10 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ cntlzw_(i.OutputRegister(), i.InputRegister(0));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kPPC_Popcnt32:
__ popcntw(i.OutputRegister(), i.InputRegister(0));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kPPC_Cmp32:
ASSEMBLE_COMPARE(cmpw, cmplw);
break;
......
......@@ -62,6 +62,7 @@ namespace compiler {
V(PPC_MinDouble) \
V(PPC_AbsDouble) \
V(PPC_Cntlz32) \
V(PPC_Popcnt32) \
V(PPC_Cmp32) \
V(PPC_Cmp64) \
V(PPC_CmpDouble) \
......
......@@ -737,10 +737,14 @@ void InstructionSelector::VisitWord32Clz(Node* node) {
}
void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitWord32Popcnt(Node* node) {
PPCOperandGenerator g(this);
Emit(kPPC_Popcnt32, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(0)));
}
void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitInt32Add(Node* node) {
......@@ -1708,7 +1712,8 @@ MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
return MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat64RoundTruncate |
MachineOperatorBuilder::kFloat64RoundTiesAway;
MachineOperatorBuilder::kFloat64RoundTiesAway |
MachineOperatorBuilder::kWord32Popcnt;
// We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f.
}
......
......@@ -737,6 +737,11 @@ void Assembler::cntlzw_(Register ra, Register rs, RCBit rc) {
}
void Assembler::popcntw(Register ra, Register rs) {
emit(EXT2 | POPCNTW | rs.code() * B21 | ra.code() * B16);
}
void Assembler::and_(Register ra, Register rs, Register rb, RCBit rc) {
x_form(EXT2 | ANDX, ra, rs, rb, rc);
}
......
......@@ -936,6 +936,7 @@ class Assembler : public AssemblerBase {
void rotrwi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
void cntlzw_(Register dst, Register src, RCBit rc = LeaveRC);
void popcntw(Register dst, Register src);
void subi(Register dst, Register src1, const Operand& src2);
......
......@@ -228,6 +228,7 @@ enum OpcodeExt2 {
LHAUX = 375 << 1, // load half-word algebraic w/ update x-form
XORX = 316 << 1, // Exclusive OR
MFSPR = 339 << 1, // Move from Special-Purpose-Register
POPCNTW = 378 << 1, // Population Count Words
STHX = 407 << 1, // store half-word w/ x-form
ORC = 412 << 1, // Or with Complement
STHUX = 439 << 1, // store half-word w/ update x-form
......
......@@ -609,6 +609,10 @@ void Decoder::DecodeExt2(Instruction* instr) {
Format(instr, "stfdux 'rs, 'ra, 'rb");
return;
}
case POPCNTW: {
Format(instr, "popcntw 'ra, 'rs");
return;
}
}
switch (instr->Bits(10, 2) << 2) {
......
......@@ -1849,6 +1849,20 @@ bool Simulator::ExecuteExt2_10bit(Instruction* instr) {
}
break;
}
case POPCNTW: {
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 = 0x80000000;
for (; n < 32; n++) {
if (bit & rs_val) count++;
bit >>= 1;
}
set_register(ra, count);
break;
}
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