1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00

Improved calling convention for aarch64

This commit is contained in:
Brian Fiete 2022-01-14 06:23:36 -05:00
parent a69dd47cea
commit 5bc9642d26
6 changed files with 136 additions and 13 deletions

View file

@ -317,12 +317,13 @@ namespace IDE
bool QueueProjectGNULink(Project project, String targetPath, Workspace.Options workspaceOptions, Project.Options options, String objectsArg)
{
if (options.mBuildOptions.mBuildKind == .Intermediate)
return true;
bool isDebug = gApp.mConfigName.IndexOf("Debug", true) != -1;
bool isMinGW = false;
#if BF_PLATFORM_WINDOWS
bool isWSL = mPlatformType == .Linux;
String llvmDir = scope String(IDEApp.sApp.mInstallDir);

View file

@ -879,6 +879,7 @@ namespace IDE
case Test;
case StaticLib;
case DynamicLib;
case Intermediate;
case NotSupported;
}

View file

@ -350,6 +350,15 @@ int BfIRConstHolder::GetSize(BfTypeCode typeCode)
case BfTypeCode_Enum: return 0;
case BfTypeCode_TypeAlias: return 0;
case BfTypeCode_Extension: return 0;
case BfTypeCode_FloatX2: return 4*2;
case BfTypeCode_FloatX3: return 4*3;
case BfTypeCode_FloatX4: return 4*4;
case BfTypeCode_DoubleX2: return 8*2;
case BfTypeCode_DoubleX3: return 8*3;
case BfTypeCode_DoubleX4: return 8*4;
case BfTypeCode_Int64X2: return 8*2;
case BfTypeCode_Int64X3: return 8*3;
case BfTypeCode_Int64X4: return 8*4;
default: return 0;
}
}

View file

@ -109,7 +109,15 @@ enum BfTypeCode : uint8
BfTypeCode_Enum,
BfTypeCode_TypeAlias,
BfTypeCode_Extension,
BfTypeCode_FloatX2,
BfTypeCode_FloatX3,
BfTypeCode_FloatX4,
BfTypeCode_DoubleX2,
BfTypeCode_DoubleX3,
BfTypeCode_DoubleX4,
BfTypeCode_Int64X2,
BfTypeCode_Int64X3,
BfTypeCode_Int64X4,
BfTypeCode_Length
};

View file

@ -601,6 +601,24 @@ llvm::Type* BfIRCodeGen::GetLLVMType(BfTypeCode typeCode, bool& isSigned)
return llvm::Type::getDoubleTy(*mLLVMContext);
case BfTypeCode_Float2:
return llvm::FixedVectorType::get(llvm::Type::getFloatTy(*mLLVMContext), 2);
case BfTypeCode_FloatX2:
return llvm::ArrayType::get(llvm::Type::getFloatTy(*mLLVMContext), 2);
case BfTypeCode_FloatX3:
return llvm::ArrayType::get(llvm::Type::getFloatTy(*mLLVMContext), 3);
case BfTypeCode_FloatX4:
return llvm::ArrayType::get(llvm::Type::getFloatTy(*mLLVMContext), 4);
case BfTypeCode_DoubleX2:
return llvm::ArrayType::get(llvm::Type::getDoubleTy(*mLLVMContext), 2);
case BfTypeCode_DoubleX3:
return llvm::ArrayType::get(llvm::Type::getDoubleTy(*mLLVMContext), 3);
case BfTypeCode_DoubleX4:
return llvm::ArrayType::get(llvm::Type::getDoubleTy(*mLLVMContext), 4);
case BfTypeCode_Int64X2:
return llvm::ArrayType::get(llvm::Type::getInt64Ty(*mLLVMContext), 2);
case BfTypeCode_Int64X3:
return llvm::ArrayType::get(llvm::Type::getInt64Ty(*mLLVMContext), 3);
case BfTypeCode_Int64X4:
return llvm::ArrayType::get(llvm::Type::getInt64Ty(*mLLVMContext), 4);
default: break;
}
return NULL;

View file

@ -842,7 +842,8 @@ bool BfMethodInstance::WantsStructsAttribByVal(BfType* paramType)
if ((owner->mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows) &&
(owner->mModule->mCompiler->mOptions.mMachineType == BfMachineType_x64))
return false;
if (owner->mModule->mCompiler->mOptions.mMachineType == BfMachineType_AArch64)
return false;
auto typeInst = paramType->ToTypeInstance();
return (typeInst != NULL) && (typeInst->mIsCRepr);
}
@ -1202,7 +1203,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
if ((!module->mIsComptimeModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2, forceStatic)))
if ((!module->mIsComptimeModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2, forceStatic)) && (loweredReturnTypeCode != BfTypeCode_None))
{
auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
returnType = irReturnType;
@ -1842,8 +1843,8 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
{
// Odd Windows rule: composite returns for non-static methods are always sret
if (typeUsage == BfTypeUsage_Return_NonStatic)
return false;
}
return false;
}
else
{
// Non-Win64 systems allow lowered splitting of composites over multiple params
@ -1860,12 +1861,15 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
}
}
int maxInstSize = 16;
if (mModule->mCompiler->mOptions.mMachineType == BfMachineType_AArch64)
maxInstSize = 32;
if (deepCheck)
{
if ((mInstSize >= 4) && (mInstSize <= 16))
if ((mInstSize >= 4) && (mInstSize <= maxInstSize))
{
BfTypeCode types[4] = { BfTypeCode_None };
BfTypeCode types[8] = { BfTypeCode_None };
std::function<void(BfType*, int)> _CheckType = [&](BfType* type, int offset)
{
@ -1883,12 +1887,14 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
}
}
else
types[offset / 4] = BfTypeCode_Object;
{
types[offset / 4] = BfTypeCode_Object;
}
}
else if (type->IsPrimitiveType())
{
auto primType = (BfPrimitiveType*)type;
types[offset / 4] = primType->mTypeDef->mTypeCode;
types[offset / 4] = primType->mTypeDef->mTypeCode;
}
else if (type->IsSizedArray())
{
@ -1902,7 +1908,87 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
bool handled = false;
if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows)
if (mModule->mCompiler->mOptions.mMachineType == BfMachineType_AArch64)
{
// For returns, we want to avoid sret but not actually lower
bool writeOutCode = (typeUsage != BfTypeUsage_Return_NonStatic) && (typeUsage != BfTypeUsage_Return_Static);
if ((types[0] == BfTypeCode_Float) &&
(types[1] == BfTypeCode_Float) &&
(types[2] == BfTypeCode_None))
{
if ((outTypeCode != NULL) && (writeOutCode))
*outTypeCode = BfTypeCode_FloatX2;
return true;
}
if ((types[0] == BfTypeCode_Float) &&
(types[1] == BfTypeCode_Float) &&
(types[2] == BfTypeCode_Float) &&
(types[3] == BfTypeCode_None))
{
if ((outTypeCode != NULL) && (writeOutCode))
*outTypeCode = BfTypeCode_FloatX3;
return true;
}
if ((types[0] == BfTypeCode_Float) &&
(types[1] == BfTypeCode_Float) &&
(types[2] == BfTypeCode_Float) &&
(types[3] == BfTypeCode_Float) &&
(types[4] == BfTypeCode_None))
{
if ((outTypeCode != NULL) && (writeOutCode))
*outTypeCode = BfTypeCode_FloatX4;
return true;
}
if ((types[0] == BfTypeCode_Double) &&
(types[2] == BfTypeCode_Double) &&
(types[4] == BfTypeCode_None))
{
if ((outTypeCode != NULL) && (writeOutCode))
*outTypeCode = BfTypeCode_DoubleX2;
return true;
}
if ((types[0] == BfTypeCode_Double) &&
(types[2] == BfTypeCode_Double) &&
(types[4] == BfTypeCode_Double) &&
(types[6] == BfTypeCode_None))
{
if ((outTypeCode != NULL) && (writeOutCode))
*outTypeCode = BfTypeCode_DoubleX3;
return true;
}
if ((types[0] == BfTypeCode_Double) &&
(types[2] == BfTypeCode_Double) &&
(types[4] == BfTypeCode_Double) &&
(types[6] == BfTypeCode_Double))
{
if ((outTypeCode != NULL) && (writeOutCode))
*outTypeCode = BfTypeCode_DoubleX4;
return true;
}
if (mInstSize <= 8)
{
if ((outTypeCode != NULL) && (writeOutCode))
*outTypeCode = BfTypeCode_Int64;
return true;
}
if (mInstSize <= 16)
{
if ((outTypeCode != NULL) && (writeOutCode))
*outTypeCode = BfTypeCode_Int64X2;
return true;
}
return false;
}
else if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows)
{
bool hasFloat = false;
for (int type = 0; type < 4; type++)