1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Support for AtomicCmpXChg

This commit is contained in:
Brian Fiete 2024-08-25 09:31:20 -04:00
parent 2a2913f857
commit f67eaa6d8a
2 changed files with 60 additions and 26 deletions

View file

@ -973,6 +973,37 @@ void CeBuilder::EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx,
}
}
CeOperand CeBuilder::EmitLoad(CeOperand ceTarget, int loadRefCount)
{
CeOperand result;
if (ceTarget.mKind == CeOperandKind_AllocaAddr)
{
if (loadRefCount <= 1)
{
result = ceTarget;
result.mKind = CeOperandKind_FrameOfs;
}
else
{
ceTarget.mKind = CeOperandKind_FrameOfs;
result = FrameAlloc(ceTarget.mType);
EmitSizedOp(CeOp_Move_8, ceTarget, NULL, true);
Emit((int32)result.mFrameOfs);
}
}
else
{
BF_ASSERT(ceTarget.mType->IsPointer());
auto pointerType = (BePointerType*)ceTarget.mType;
auto elemType = pointerType->mElementType;
CeOperand refOperand = ceTarget;
refOperand.mType = elemType;
EmitSizedOp(CeOp_Load_8, refOperand, &result, true);
}
return result;
}
int CeBuilder::GetCodePos()
{
return (int)mCeFunction->mCode.size();
@ -2396,32 +2427,7 @@ void CeBuilder::Build()
{
auto castedInst = (BeLoadInst*)inst;
auto ceTarget = GetOperand(castedInst->mTarget, true);
if (ceTarget.mKind == CeOperandKind_AllocaAddr)
{
if (inst->mRefCount <= 1)
{
result = ceTarget;
result.mKind = CeOperandKind_FrameOfs;
}
else
{
ceTarget.mKind = CeOperandKind_FrameOfs;
result = FrameAlloc(ceTarget.mType);
EmitSizedOp(CeOp_Move_8, ceTarget, NULL, true);
Emit((int32)result.mFrameOfs);
}
}
else
{
BF_ASSERT(ceTarget.mType->IsPointer());
auto pointerType = (BePointerType*)ceTarget.mType;
auto elemType = pointerType->mElementType;
CeOperand refOperand = ceTarget;
refOperand.mType = elemType;
EmitSizedOp(CeOp_Load_8, refOperand, &result, true);
}
result = EmitLoad(ceTarget, inst->mRefCount);
}
break;
case BeBinaryOpInst::TypeId:
@ -3135,6 +3141,33 @@ void CeBuilder::Build()
case BfIRIntrinsic_DebugTrap:
Emit(CeOp_DbgBreak);
break;
case BfIRIntrinsic_AtomicCmpXChg:
{
auto mcPtr = GetOperand(castedInst->mArgs[0].mValue, true);
auto mcComparand = GetOperand(castedInst->mArgs[1].mValue);
auto mcValue = GetOperand(castedInst->mArgs[2].mValue);
CeOperand mcPrev = EmitLoad(mcPtr);
CeOperand cmpResult;
EmitBinaryOp(CeOp_Cmp_EQ_I8, CeOp_InvalidOp, mcPrev, mcComparand, cmpResult);
Emit(CeOp_JmpIfNot);
Emit((int32)14);
EmitFrameOffset(cmpResult);
if (mcPtr.mKind == CeOperandKind_AllocaAddr)
{
EmitSizedOp(CeOp_Move_8, mcValue, NULL, true);
Emit((int32)mcPtr.mFrameOfs);
}
else
{
EmitSizedOp(CeOp_Store_8, mcValue, NULL, true);
EmitFrameOffset(mcPtr);
}
result = mcPrev;
}
break;
default:
Emit(CeOp_Error);
Emit((int32)CeErrorKind_Intrinsic);

View file

@ -886,6 +886,7 @@ public:
void EmitZeroes(int size);
void EmitJump(CeOp op, const CeOperand& block);
void EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx);
CeOperand EmitLoad(CeOperand mcPtr, int loadRefCount = 1);
CeOperand EmitNumericCast(const CeOperand& ceValue, BeType* toType, bool valSigned, bool toSigned);
void EmitFrameOffset(const CeOperand& val);