mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Made abs an intrinsic
This commit is contained in:
parent
567662b3c3
commit
dce4a3ecf2
7 changed files with 182 additions and 112 deletions
|
@ -288,6 +288,10 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
[Intrinsic("abs")]
|
||||
public static extern float Abs(float value);
|
||||
[Intrinsic("abs")]
|
||||
public static extern double Abs(double value);
|
||||
[Inline]
|
||||
public static T Abs<T>(T value) where T : IOpComparable, IOpNegatable
|
||||
{
|
||||
|
|
|
@ -112,6 +112,10 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
[Intrinsic("abs")]
|
||||
public static extern float Abs(float value);
|
||||
[Intrinsic("abs")]
|
||||
public static extern double Abs(double value);
|
||||
[Inline]
|
||||
public static T Abs<T>(T value) where T : IOpComparable, IOpNegatable
|
||||
{
|
||||
|
|
|
@ -1919,6 +1919,9 @@ void BeIRCodeGen::HandleNextCmd()
|
|||
|
||||
switch (intrin->mKind)
|
||||
{
|
||||
case BfIRIntrinsic_Abs:
|
||||
intrin->mReturnType = paramTypes[0];
|
||||
break;
|
||||
case BfIRIntrinsic_AtomicAdd:
|
||||
case BfIRIntrinsic_AtomicAnd:
|
||||
case BfIRIntrinsic_AtomicCmpXChg:
|
||||
|
|
|
@ -2064,10 +2064,10 @@ String BeMCContext::ToString(const BeMCOperand& operand)
|
|||
else
|
||||
str += "null";
|
||||
return str;
|
||||
case BeMCOperandKind_Immediate_f32: return StrFormat("f32 %f", operand.mImmFloat);
|
||||
case BeMCOperandKind_Immediate_f32_Packed128: return StrFormat("f32_packed %f", operand.mImmFloat);
|
||||
case BeMCOperandKind_Immediate_f64: return StrFormat("f64 %f", operand.mImmFloat);
|
||||
case BeMCOperandKind_Immediate_f64_Packed128: return StrFormat("f64_packed %f", operand.mImmFloat);
|
||||
case BeMCOperandKind_Immediate_f32: return StrFormat("f32 %f", operand.mImmF32);
|
||||
case BeMCOperandKind_Immediate_f32_Packed128: return StrFormat("f32_packed %f", operand.mImmF32);
|
||||
case BeMCOperandKind_Immediate_f64: return StrFormat("f64 %f", operand.mImmF64);
|
||||
case BeMCOperandKind_Immediate_f64_Packed128: return StrFormat("f64_packed %f", operand.mImmF64);
|
||||
}
|
||||
//if (operand.mImmediate < 10)
|
||||
str += StrFormat("%lld", operand.mImmediate);
|
||||
|
@ -2196,11 +2196,11 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a
|
|||
case BeTypeCode_Int32: mcOperand.mKind = BeMCOperandKind_Immediate_i32; break;
|
||||
case BeTypeCode_Int64: mcOperand.mKind = BeMCOperandKind_Immediate_i64; break;
|
||||
case BeTypeCode_Float:
|
||||
mcOperand.mImmFloat = constant->mDouble;
|
||||
mcOperand.mImmF32 = constant->mDouble;
|
||||
mcOperand.mKind = BeMCOperandKind_Immediate_f32;
|
||||
return mcOperand;
|
||||
case BeTypeCode_Double:
|
||||
mcOperand.mImmFloat = constant->mDouble;
|
||||
mcOperand.mImmF64 = constant->mDouble;
|
||||
mcOperand.mKind = BeMCOperandKind_Immediate_f64;
|
||||
return mcOperand;
|
||||
case BeTypeCode_Pointer:
|
||||
|
@ -6026,28 +6026,24 @@ void BeMCContext::EmitModRM_XMM_IMM(int rx, BeMCOperand & imm)
|
|||
BeMCSymbol* sym = NULL;
|
||||
if (imm.mKind == BeMCOperandKind_Immediate_f32)
|
||||
{
|
||||
float floatVal = (float)imm.mImmFloat;
|
||||
String name = StrFormat("__real@%08x", *(int*)&floatVal);
|
||||
sym = mCOFFObject->GetCOMDAT(name, &floatVal, 4, 4);
|
||||
String name = StrFormat("__real@%08x", *(int*)&imm.mImmF32);
|
||||
sym = mCOFFObject->GetCOMDAT(name, &imm.mImmF32, 4, 4);
|
||||
}
|
||||
else if (imm.mKind == BeMCOperandKind_Immediate_f64)
|
||||
{
|
||||
double floatVal = imm.mImmFloat;
|
||||
String name = StrFormat("__real@%016llx", *(int64*)&floatVal);
|
||||
sym = mCOFFObject->GetCOMDAT(name, &floatVal, 8, 8);
|
||||
String name = StrFormat("__real@%016llx", *(int64*)&imm.mImmF64);
|
||||
sym = mCOFFObject->GetCOMDAT(name, &imm.mImmF64, 8, 8);
|
||||
}
|
||||
else if (imm.mKind == BeMCOperandKind_Immediate_f32_Packed128)
|
||||
{
|
||||
float floatVal = (float)imm.mImmFloat;
|
||||
String name = StrFormat("__real@%08x_packed", *(int*)&floatVal);
|
||||
float data[4] = { floatVal, 0, 0, 0 };
|
||||
String name = StrFormat("__real@%08x_packed", *(int*)&imm.mImmF32);
|
||||
float data[4] = { imm.mImmF32, 0, 0, 0 };
|
||||
sym = mCOFFObject->GetCOMDAT(name, data, 16, 16);
|
||||
}
|
||||
else if (imm.mKind == BeMCOperandKind_Immediate_f64_Packed128)
|
||||
{
|
||||
double floatVal = imm.mImmFloat;
|
||||
String name = StrFormat("__real@%016llx_packed", *(int64*)&floatVal);
|
||||
double data[2] = { floatVal, 0 };
|
||||
String name = StrFormat("__real@%016llx_packed", *(int64*)&imm.mImmF64);
|
||||
double data[2] = { imm.mImmF64, 0 };
|
||||
sym = mCOFFObject->GetCOMDAT(name, data, 16, 16);
|
||||
}
|
||||
else
|
||||
|
@ -6464,9 +6460,19 @@ void BeMCContext::DoInitInjectionPass()
|
|||
else
|
||||
zeroVal.mKind = BeMCOperandKind_Immediate_f64;
|
||||
if (initType == BfIRInitType_Uninitialized)
|
||||
zeroVal.mImmFloat = NAN;
|
||||
{
|
||||
if (varType->mTypeCode == BeTypeCode_Float)
|
||||
zeroVal.mImmF32 = NAN;
|
||||
else
|
||||
zeroVal.mImmFloat = 0;
|
||||
zeroVal.mImmF64 = NAN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (varType->mTypeCode == BeTypeCode_Float)
|
||||
zeroVal.mImmF32 = 0;
|
||||
else
|
||||
zeroVal.mImmF64 = 0;
|
||||
}
|
||||
AllocInst(BeMCInstKind_Mov, BeMCOperand::FromVReg(vregIdx), zeroVal, instIdx + 1);
|
||||
}
|
||||
else if (varType->IsComposite())
|
||||
|
@ -9136,10 +9142,15 @@ bool BeMCContext::DoLegalization()
|
|||
{
|
||||
inst->mKind = BeMCInstKind_Xor;
|
||||
if (arg0Type->mTypeCode == BeTypeCode_Float)
|
||||
{
|
||||
inst->mArg1.mKind = BeMCOperandKind_Immediate_f32_Packed128;
|
||||
inst->mArg1.mImmF32 = -0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
inst->mArg1.mKind = BeMCOperandKind_Immediate_f64_Packed128;
|
||||
inst->mArg1.mImmFloat = -0.0;
|
||||
inst->mArg1.mImmF64 = -0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -9706,10 +9717,16 @@ bool BeMCContext::DoLegalization()
|
|||
AllocInst(BeMCInstKind_CondBr, BeMCOperand::FromLabel(labelIdx), BeMCOperand::FromCmpKind(BeCmpKind_SGE), instIdx + 4);
|
||||
BeMCOperand mcOffset;
|
||||
if (arg0Type->mSize == 8)
|
||||
{
|
||||
mcOffset.mKind = BeMCOperandKind_Immediate_f64;
|
||||
mcOffset.mImmF64 = 1.8446744073709552e+19;
|
||||
}
|
||||
else
|
||||
{
|
||||
mcOffset.mKind = BeMCOperandKind_Immediate_f32;
|
||||
mcOffset.mImmFloat = 1.8446744073709552e+19;
|
||||
mcOffset.mImmF32 = 1.8446744073709552e+19;
|
||||
}
|
||||
|
||||
AllocInst(BeMCInstKind_Add, inst->mArg0, mcOffset, instIdx + 5);
|
||||
AllocInst(BeMCInstKind_RestoreVolatiles, BeMCOperand::FromReg(X64Reg_RAX), BeMCOperand(), instIdx + 7);
|
||||
|
||||
|
@ -11345,7 +11362,7 @@ bool BeMCContext::EmitStdXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 op
|
|||
case BeMCInstForm_XMM32_RM32:
|
||||
case BeMCInstForm_XMM32_IMM:
|
||||
case BeMCInstForm_XMM32_FRM32:
|
||||
case BeMCInstForm_XMM64_FRM32: // CVTSS2SD
|
||||
case BeMCInstForm_XMM64_FRM32:
|
||||
Emit(0xF3); EmitREX(inst->mArg0, inst->mArg1, is64Bit);
|
||||
Emit(0x0F); Emit(opcode);
|
||||
EmitModRM(inst->mArg0, inst->mArg1);
|
||||
|
@ -11359,7 +11376,7 @@ bool BeMCContext::EmitStdXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 op
|
|||
case BeMCInstForm_XMM64_RM32:
|
||||
case BeMCInstForm_XMM64_IMM:
|
||||
case BeMCInstForm_XMM64_FRM64:
|
||||
case BeMCInstForm_XMM32_FRM64: // CVTSD2SS
|
||||
case BeMCInstForm_XMM32_FRM64:
|
||||
Emit(0xF2); EmitREX(inst->mArg0, inst->mArg1, is64Bit);
|
||||
Emit(0x0F); Emit(opcode);
|
||||
EmitModRM(inst->mArg0, inst->mArg1);
|
||||
|
@ -12530,7 +12547,7 @@ void BeMCContext::DoCodeEmission()
|
|||
EmitREX(BeMCOperand(), inst->mArg0, false);
|
||||
Emit(0xC7);
|
||||
EmitModRM(0, inst->mArg0, -4);
|
||||
float val = inst->mArg1.mImmFloat;
|
||||
float val = inst->mArg1.mImmF32;
|
||||
mOut.Write(*(int32*)&val);
|
||||
break;
|
||||
}
|
||||
|
@ -13631,6 +13648,14 @@ void BeMCContext::DoCodeEmission()
|
|||
break;
|
||||
}
|
||||
|
||||
if (modInst.mArg1.IsImmediateFloat())
|
||||
{ //ANDPS
|
||||
bool is64Bit = (modInst.mArg1.mKind == BeMCOperandKind_Immediate_f64_Packed128);
|
||||
Emit(0x0F); Emit(0x54);
|
||||
EmitModRM(inst->mArg0, inst->mArg1);
|
||||
break;
|
||||
}
|
||||
|
||||
EmitStdInst(instForm, &modInst, 0x21, 0x23, 0x81, 0x4, 0x83, 0x4);
|
||||
}
|
||||
break;
|
||||
|
@ -14652,14 +14677,14 @@ BeMCOperand BeMCContext::AllocBinaryOp(BeMCInstKind instKind, const BeMCOperand&
|
|||
|
||||
if (identityKind == BeMCBinIdentityKind_Any_IsOne)
|
||||
{
|
||||
if (((lhs.IsImmediateFloat()) && (lhs.mImmFloat == 1.0)) ||
|
||||
if (((lhs.IsImmediateFloat()) && (lhs.GetImmediateDouble() == 1.0)) ||
|
||||
((lhs.IsImmediateInt()) && (lhs.mImmediate == 1)))
|
||||
return rhs;
|
||||
}
|
||||
|
||||
if (identityKind == BeMCBinIdentityKind_Right_IsOne_Result_Zero)
|
||||
{
|
||||
if (((rhs.IsImmediateFloat()) && (rhs.mImmFloat == 1.0)) ||
|
||||
if (((rhs.IsImmediateFloat()) && (rhs.GetImmediateDouble() == 1.0)) ||
|
||||
((rhs.IsImmediateInt()) && (rhs.mImmediate == 1)))
|
||||
{
|
||||
BeMCOperand operand = rhs;
|
||||
|
@ -14670,21 +14695,21 @@ BeMCOperand BeMCContext::AllocBinaryOp(BeMCInstKind instKind, const BeMCOperand&
|
|||
|
||||
if ((identityKind == BeMCBinIdentityKind_Right_IsOne) || (identityKind == BeMCBinIdentityKind_Any_IsOne))
|
||||
{
|
||||
if (((rhs.IsImmediateFloat()) && (rhs.mImmFloat == 1.0)) ||
|
||||
if (((rhs.IsImmediateFloat()) && (rhs.GetImmediateDouble() == 1.0)) ||
|
||||
((rhs.IsImmediateInt()) && (rhs.mImmediate == 1)))
|
||||
return lhs;
|
||||
}
|
||||
|
||||
if ((identityKind == BeMCBinIdentityKind_Right_IsZero) || (identityKind == BeMCBinIdentityKind_Any_IsZero))
|
||||
{
|
||||
if (((rhs.IsImmediateFloat()) && (rhs.mImmFloat == 0.0)) ||
|
||||
if (((rhs.IsImmediateFloat()) && (rhs.GetImmediateDouble() == 0.0)) ||
|
||||
((rhs.IsImmediateInt()) && (rhs.mImmediate == 0)))
|
||||
return lhs;
|
||||
}
|
||||
|
||||
if (identityKind == BeMCBinIdentityKind_Any_IsZero)
|
||||
{
|
||||
if (((lhs.IsImmediateFloat()) && (lhs.mImmFloat == 0.0)) ||
|
||||
if (((lhs.IsImmediateFloat()) && (lhs.GetImmediateDouble() == 0.0)) ||
|
||||
((lhs.IsImmediateInt()) && (lhs.mImmediate == 0)))
|
||||
return rhs;
|
||||
}
|
||||
|
@ -14714,7 +14739,7 @@ void BeMCContext::Generate(BeFunction* function)
|
|||
mDbgPreferredRegs[32] = X64Reg_R8;*/
|
||||
|
||||
//mDbgPreferredRegs[8] = X64Reg_RAX;
|
||||
mDebugging = function->mName == "?Dequeue@?$Queue@Tint@@@Generic@Collections@System@bf@@QEAATint@@XZ";
|
||||
mDebugging = function->mName == "?Hey@Blurg@bf@@SAXXZ";
|
||||
//"?ColorizeCodeString@IDEUtils@IDE@bf@@SAXPEAVString@System@3@W4CodeKind@123@@Z";
|
||||
//"?Main@Program@bf@@CAHPEAV?$Array1@PEAVString@System@bf@@@System@2@@Z";
|
||||
|
||||
|
@ -15118,7 +15143,7 @@ void BeMCContext::Generate(BeFunction* function)
|
|||
|
||||
if (castedInst->mOpKind == BeBinaryOpKind_Subtract)
|
||||
{
|
||||
if (((mcLHS.IsImmediateFloat()) && (mcLHS.mImmFloat == 0.0)) ||
|
||||
if (((mcLHS.IsImmediateFloat()) && (mcLHS.GetImmediateDouble() == 0.0)) ||
|
||||
((mcLHS.IsImmediateInt()) && (mcLHS.mImmediate == 0)))
|
||||
{
|
||||
auto castedInst = (BeNumericCastInst*)inst;
|
||||
|
@ -15865,6 +15890,30 @@ void BeMCContext::Generate(BeFunction* function)
|
|||
{
|
||||
switch (intrin->mKind)
|
||||
{
|
||||
case BfIRIntrinsic_Abs:
|
||||
{
|
||||
auto mcValue = GetOperand(castedInst->mArgs[0].mValue);
|
||||
|
||||
auto mcType = GetType(mcValue);
|
||||
BeMCOperand andValue;
|
||||
|
||||
if (mcType->mSize == 4)
|
||||
{
|
||||
andValue.mKind = BeMCOperandKind_Immediate_f32_Packed128;
|
||||
andValue.mImmediate = 0x7FFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
andValue.mKind = BeMCOperandKind_Immediate_f64_Packed128;
|
||||
andValue.mImmediate = 0x7FFFFFFFFFFFFFFFLL;
|
||||
}
|
||||
|
||||
result = AllocVirtualReg(GetType(mcValue));
|
||||
CreateDefineVReg(result);
|
||||
AllocInst(BeMCInstKind_Mov, result, mcValue);
|
||||
AllocInst(BeMCInstKind_And, result, andValue);
|
||||
}
|
||||
break;
|
||||
case BfIRIntrinsic_AtomicAdd:
|
||||
case BfIRIntrinsic_AtomicSub:
|
||||
{
|
||||
|
@ -15887,8 +15936,10 @@ void BeMCContext::Generate(BeFunction* function)
|
|||
if ((intrin->mKind == BfIRIntrinsic_AtomicSub) && (mcVal.IsImmediate()))
|
||||
{
|
||||
BeMCOperand mcNeg = mcVal;
|
||||
if (mcVal.IsImmediateFloat())
|
||||
mcNeg.mImmFloat = -mcNeg.mImmFloat;
|
||||
if (mcVal.mKind == BeMCOperandKind_Immediate_f32)
|
||||
mcNeg.mImmF32 = -mcNeg.mImmF32;
|
||||
else if (mcVal.mKind == BeMCOperandKind_Immediate_f64)
|
||||
mcNeg.mImmF64 = -mcNeg.mImmF64;
|
||||
else
|
||||
mcNeg.mImmediate = -mcNeg.mImmediate;
|
||||
AllocInst(BeMCInstKind_Mov, scratchReg, mcNeg);
|
||||
|
|
|
@ -234,7 +234,8 @@ public:
|
|||
int mFrameObjNum;
|
||||
int64 mImmediate;
|
||||
BeType* mType;
|
||||
double mImmFloat;
|
||||
float mImmF32;
|
||||
double mImmF64;
|
||||
BeMCBlock* mBlock;
|
||||
BeMCPhi* mPhi;
|
||||
BeNotResult* mNotResult;
|
||||
|
@ -308,8 +309,10 @@ public:
|
|||
// Either intptr or int
|
||||
if (mKind == BeMCOperandKind_CmpKind)
|
||||
return mCmpKind == other.mCmpKind;
|
||||
if ((mKind == BeMCOperandKind_Immediate_f32) || (mKind == BeMCOperandKind_Immediate_f64))
|
||||
return mImmFloat == other.mImmFloat;
|
||||
if (mKind == BeMCOperandKind_Immediate_f32)
|
||||
return mImmF32 == other.mImmF32;
|
||||
if (mKind == BeMCOperandKind_Immediate_f64)
|
||||
return mImmF64 == other.mImmF64;
|
||||
if ((mKind >= BeMCOperandKind_Immediate_i8) && (mKind <= BeMCOperandKind_Block))
|
||||
return mImmediate == other.mImmediate;
|
||||
if (mKind == BeMCOperandKind_Immediate_Null)
|
||||
|
@ -333,13 +336,22 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
int64 GetImmediateInt()
|
||||
int64 GetImmediateInt() const
|
||||
{
|
||||
if ((mKind >= BeMCOperandKind_Immediate_i8) && (mKind <= BeMCOperandKind_Immediate_i64))
|
||||
return mImmediate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
double GetImmediateDouble() const
|
||||
{
|
||||
if (mKind == BeMCOperandKind_Immediate_f32)
|
||||
return mImmF32;
|
||||
if (mKind == BeMCOperandKind_Immediate_f64)
|
||||
return mImmF64;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BeMCOperand FromEncoded(int vregIdx)
|
||||
{
|
||||
BeMCOperand operand;
|
||||
|
|
|
@ -386,6 +386,7 @@ enum BfIRConfigConst : uint8
|
|||
|
||||
enum BfIRIntrinsic : uint8
|
||||
{
|
||||
BfIRIntrinsic_Abs,
|
||||
BfIRIntrinsic_AtomicAdd,
|
||||
BfIRIntrinsic_AtomicAnd,
|
||||
BfIRIntrinsic_AtomicCmpStore,
|
||||
|
|
|
@ -125,6 +125,7 @@ struct BuiltinEntry
|
|||
|
||||
static const BuiltinEntry gIntrinEntries[] =
|
||||
{
|
||||
{"abs"},
|
||||
{"atomic_add"},
|
||||
{"atomic_and"},
|
||||
{"atomic_cmpstore"},
|
||||
|
@ -1847,9 +1848,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
}
|
||||
|
||||
llvm::Function* func = NULL;
|
||||
llvm::Function** funcPtr = NULL;
|
||||
if (mIntrinsicMap.TryAdd(intrinId, NULL, &funcPtr))
|
||||
{
|
||||
|
||||
struct _Intrinsics
|
||||
{
|
||||
llvm::Intrinsic::ID mID;
|
||||
|
@ -1860,6 +1859,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
|
||||
static _Intrinsics intrinsics[] =
|
||||
{
|
||||
{ llvm::Intrinsic::fabs, 0, -1},
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicAdd,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicAnd,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicCmpStore,
|
||||
|
@ -1879,12 +1879,12 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicXor,
|
||||
{ llvm::Intrinsic::bswap, -1},
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // cast,
|
||||
{ llvm::Intrinsic::cos, -1},
|
||||
{ llvm::Intrinsic::floor, -1},
|
||||
{ llvm::Intrinsic::cos, 0, -1},
|
||||
{ llvm::Intrinsic::floor, 0, -1},
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // free
|
||||
{ llvm::Intrinsic::log, -1},
|
||||
{ llvm::Intrinsic::log10, -1},
|
||||
{ llvm::Intrinsic::log2, -1},
|
||||
{ llvm::Intrinsic::log, 0, -1},
|
||||
{ llvm::Intrinsic::log10, 0, -1},
|
||||
{ llvm::Intrinsic::log2, 0, -1},
|
||||
{ (llvm::Intrinsic::ID)-1}, // memset
|
||||
{ llvm::Intrinsic::memcpy, 0, 1, 2},
|
||||
{ llvm::Intrinsic::memmove, 0, 2},
|
||||
|
@ -1913,13 +1913,8 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
|
||||
BF_ASSERT(intrinsics[intrinId].mID != (llvm::Intrinsic::ID) - 1);
|
||||
func = llvm::Intrinsic::getDeclaration(mLLVMModule, intrinsics[intrinId].mID, useParams);
|
||||
*funcPtr = func;
|
||||
mIntrinsicReverseMap[func] = intrinId;
|
||||
}
|
||||
else
|
||||
{
|
||||
func = *funcPtr;
|
||||
}
|
||||
|
||||
SetResult(curId, func);
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue