mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Support for AtomicCmpXChg
This commit is contained in:
parent
2a2913f857
commit
f67eaa6d8a
2 changed files with 60 additions and 26 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue