Skip to content

Commit

Permalink
fixup! Add atomics support to asmjs
Browse files Browse the repository at this point in the history
  • Loading branch information
Maqrkk committed Feb 16, 2024
1 parent b5d90a8 commit 9a521c1
Showing 1 changed file with 8 additions and 25 deletions.
33 changes: 8 additions & 25 deletions llvm/lib/CheerpWriter/CheerpWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4876,20 +4876,6 @@ void CheerpWriter::compileAtomicCmpXchg(const AtomicCmpXchgInst& ai, PARENT_PRIO
if (shift == 0)
shiftPrio = LOWEST;

// Compare Exchange can be called even if there are no uses, because it has side effects. In
// this specific case, we do not (and cannot) assign the result to a value and do the comparison.
StringRef reg2;
if (!ai.use_empty())
{
// We need to use the compare operand twice, so we load it into the second register first.
reg2 = namegen.getName(&ai, 1);
stream << "((" << reg2 << "=";
// We end up using compileOperand on the cmpOp twice. But this is ok, since we make sure
// that a compare operand to an AtomicCmpXchg instruction is never inlineable.
compileOperand(cmpOp, BIT_OR);
stream << "|0),";
}
// Now we compile the main atomic compare exchange function.
stream << namegen.getBuiltinName(NameGenerator::Builtin::ATOMICCMPXCHG) << "(";
if (t->isIntegerTy(1) || t->isIntegerTy(8))
stream << "8,";
Expand All @@ -4905,24 +4891,21 @@ void CheerpWriter::compileAtomicCmpXchg(const AtomicCmpXchgInst& ai, PARENT_PRIO
if (shift != 0)
stream << ">>" << shift;
stream << ",";
// If this instruction has uses, the compare operand has been stored in the second register
// for this instruction. Otherwise, use the compare operand directly.
if (!ai.use_empty())
stream << reg2;
else
compileOperand(cmpOp, BIT_OR);
compileOperand(cmpOp, BIT_OR);
stream << "|0,";
compileOperand(newValOp, BIT_OR);
stream << "|0)|0";
if (!ai.use_empty())
stream << ")";

// Finally compile the second part of this instruction, the comparison between the loaded value
// and the compare operand (which is in the second register for this instruction).
// Compile the second part of this instruction, the comparison between the loaded value
// and the compare operand. A compare operand to a cmpxchg instruction cannot be inlined, so
// calling compileOperand twice is safe.
// We only compile this part if this instruction has uses.
if (!ai.use_empty())
{
stream << ";" << NewLine;
stream << reg2 << "=(" << namegen.getName(&ai, 0) << "|0)==(" << reg2 << "|0)";
stream << namegen.getName(&ai, 1) << "=(" << namegen.getName(&ai, 0) << "|0)==(";
compileOperand(cmpOp, BIT_OR);
stream << "|0)";
}
}

Expand Down

0 comments on commit 9a521c1

Please sign in to comment.