mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48: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()
|
int CeBuilder::GetCodePos()
|
||||||
{
|
{
|
||||||
return (int)mCeFunction->mCode.size();
|
return (int)mCeFunction->mCode.size();
|
||||||
|
@ -2396,32 +2427,7 @@ void CeBuilder::Build()
|
||||||
{
|
{
|
||||||
auto castedInst = (BeLoadInst*)inst;
|
auto castedInst = (BeLoadInst*)inst;
|
||||||
auto ceTarget = GetOperand(castedInst->mTarget, true);
|
auto ceTarget = GetOperand(castedInst->mTarget, true);
|
||||||
|
result = EmitLoad(ceTarget, inst->mRefCount);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BeBinaryOpInst::TypeId:
|
case BeBinaryOpInst::TypeId:
|
||||||
|
@ -3135,6 +3141,33 @@ void CeBuilder::Build()
|
||||||
case BfIRIntrinsic_DebugTrap:
|
case BfIRIntrinsic_DebugTrap:
|
||||||
Emit(CeOp_DbgBreak);
|
Emit(CeOp_DbgBreak);
|
||||||
break;
|
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:
|
default:
|
||||||
Emit(CeOp_Error);
|
Emit(CeOp_Error);
|
||||||
Emit((int32)CeErrorKind_Intrinsic);
|
Emit((int32)CeErrorKind_Intrinsic);
|
||||||
|
|
|
@ -886,6 +886,7 @@ public:
|
||||||
void EmitZeroes(int size);
|
void EmitZeroes(int size);
|
||||||
void EmitJump(CeOp op, const CeOperand& block);
|
void EmitJump(CeOp op, const CeOperand& block);
|
||||||
void EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx);
|
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);
|
CeOperand EmitNumericCast(const CeOperand& ceValue, BeType* toType, bool valSigned, bool toSigned);
|
||||||
|
|
||||||
void EmitFrameOffset(const CeOperand& val);
|
void EmitFrameOffset(const CeOperand& val);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue