Skip to content

Commit

Permalink
Merge pull request eclipse-omr#7553 from Spencer-Comin/popcnt
Browse files Browse the repository at this point in the history
X: Implement popcnt
  • Loading branch information
hzongaro authored Nov 29, 2024
2 parents 7a568a0 + 35faffb commit 37e9b35
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 16 deletions.
15 changes: 8 additions & 7 deletions compiler/x/amd64/codegen/OMRTreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2195,12 +2195,6 @@ OMR::X86::AMD64::TreeEvaluator::inotzEvaluator(TR::Node *node, TR::CodeGenerator
return TR::TreeEvaluator::badILOpEvaluator(node, cg);
}

TR::Register*
OMR::X86::AMD64::TreeEvaluator::ipopcntEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
return TR::TreeEvaluator::badILOpEvaluator(node, cg);
}

TR::Register*
OMR::X86::AMD64::TreeEvaluator::lhbitEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
Expand Down Expand Up @@ -2228,7 +2222,14 @@ OMR::X86::AMD64::TreeEvaluator::lnotzEvaluator(TR::Node *node, TR::CodeGenerator
TR::Register*
OMR::X86::AMD64::TreeEvaluator::lpopcntEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
return TR::TreeEvaluator::badILOpEvaluator(node, cg);
TR::Node *child = node->getFirstChild();
TR::Register *inputReg = cg->longClobberEvaluate(child);

generateRegRegInstruction(TR::InstOpCode::POPCNT8RegReg, node, inputReg, inputReg, cg);

node->setRegister(inputReg);
cg->decReferenceCount(child);
return inputReg;
}

TR::Register*
Expand Down
1 change: 0 additions & 1 deletion compiler/x/amd64/codegen/OMRTreeEvaluator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,6 @@ class OMR_EXTENSIBLE TreeEvaluator: public OMR::X86::TreeEvaluator
static TR::Register *ilbitEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *inolzEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *inotzEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *ipopcntEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *lhbitEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *llbitEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *lnolzEvaluator(TR::Node *node, TR::CodeGenerator *cg);
Expand Down
1 change: 1 addition & 0 deletions compiler/x/codegen/OMRTreeEvaluator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class OMR_EXTENSIBLE TreeEvaluator: public OMR::TreeEvaluator
static TR::Register *s2iEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *su2iEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *c2iEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *ipopcntEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *ibits2fEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *fbits2iEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *compareFloatAndBranchEvaluator(TR::Node *node, TR::CodeGenerator *cg);
Expand Down
12 changes: 12 additions & 0 deletions compiler/x/codegen/UnaryEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,3 +455,15 @@ TR::Register *OMR::X86::TreeEvaluator::c2iEvaluator(TR::Node *node, TR::CodeGene
{
return TR::TreeEvaluator::conversionAnalyser(node, TR::InstOpCode::MOVZXReg4Mem2, TR::InstOpCode::MOVZXReg4Reg2, cg);
}

TR::Register *OMR::X86::TreeEvaluator::ipopcntEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
TR::Node *child = node->getFirstChild();
TR::Register *inputReg = cg->intClobberEvaluate(child);

generateRegRegInstruction(TR::InstOpCode::POPCNT4RegReg, node, inputReg, inputReg, cg);

node->setRegister(inputReg);
cg->decReferenceCount(child);
return inputReg;
}
9 changes: 9 additions & 0 deletions compiler/x/env/OMRCPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,15 @@ OMR::X86::CPU::getSupportsHardwareSQRT()
return true;
}

bool
OMR::X86::CPU::hasPopulationCountInstruction()
{
if ((self()->getX86ProcessorFeatureFlags2() & TR_POPCNT) != 0x00000000)
return true;
else
return false;
}

bool
OMR::X86::CPU::supportsTransactionalMemoryInstructions()
{
Expand Down
6 changes: 6 additions & 0 deletions compiler/x/env/OMRCPU.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ class OMR_EXTENSIBLE CPU : public OMR::CPU

bool getSupportsHardwareSQRT();

/** @brief Determines whether the popcnt instruction is available on the current processor.
*
* @return true if popcnt is available, false otherwise.
*/
bool hasPopulationCountInstruction();

/** @brief Determines whether the Transactional Memory (TM) facility is available on the current processor.
*
* @return true if TM is available, false otherwise.
Expand Down
22 changes: 15 additions & 7 deletions compiler/x/i386/codegen/OMRTreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2274,12 +2274,6 @@ OMR::X86::I386::TreeEvaluator::inotzEvaluator(TR::Node *node, TR::CodeGenerator
return TR::TreeEvaluator::badILOpEvaluator(node, cg);
}

TR::Register*
OMR::X86::I386::TreeEvaluator::ipopcntEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
return TR::TreeEvaluator::badILOpEvaluator(node, cg);
}

TR::Register*
OMR::X86::I386::TreeEvaluator::lhbitEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
Expand Down Expand Up @@ -2307,7 +2301,21 @@ OMR::X86::I386::TreeEvaluator::lnotzEvaluator(TR::Node *node, TR::CodeGenerator
TR::Register*
OMR::X86::I386::TreeEvaluator::lpopcntEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
return TR::TreeEvaluator::badILOpEvaluator(node, cg);
TR::Node *child = node->getFirstChild();
TR::Register *inputReg = cg->longClobberEvaluate(child);
TR::Register *inputHigh = inputReg->getHighOrder();
TR::Register *inputLow = inputReg->getLowOrder();
TR::Register *resultReg = inputLow;

//add low result and high result together
generateRegRegInstruction(TR::InstOpCode::POPCNT4RegReg, node, inputLow, inputLow, cg);
generateRegRegInstruction(TR::InstOpCode::POPCNT4RegReg, node, inputHigh, inputHigh, cg);
generateRegRegInstruction(TR::InstOpCode::ADD4RegReg, node, inputLow, inputHigh, cg);

cg->stopUsingRegister(inputHigh);
node->setRegister(resultReg);
cg->decReferenceCount(child);
return resultReg;
}

TR::Register*
Expand Down
1 change: 0 additions & 1 deletion compiler/x/i386/codegen/OMRTreeEvaluator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,6 @@ class OMR_EXTENSIBLE TreeEvaluator: public OMR::X86::TreeEvaluator
static TR::Register *ilbitEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *inolzEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *inotzEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *ipopcntEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *lhbitEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *llbitEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *lnolzEvaluator(TR::Node *node, TR::CodeGenerator *cg);
Expand Down

0 comments on commit 37e9b35

Please sign in to comment.