1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +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) 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 isDebug = gApp.mConfigName.IndexOf("Debug", true) != -1;
bool isMinGW = false; bool isMinGW = false;
#if BF_PLATFORM_WINDOWS #if BF_PLATFORM_WINDOWS
bool isWSL = mPlatformType == .Linux; bool isWSL = mPlatformType == .Linux;
String llvmDir = scope String(IDEApp.sApp.mInstallDir); String llvmDir = scope String(IDEApp.sApp.mInstallDir);

View file

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

View file

@ -350,6 +350,15 @@ int BfIRConstHolder::GetSize(BfTypeCode typeCode)
case BfTypeCode_Enum: return 0; case BfTypeCode_Enum: return 0;
case BfTypeCode_TypeAlias: return 0; case BfTypeCode_TypeAlias: return 0;
case BfTypeCode_Extension: 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; default: return 0;
} }
} }

View file

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

View file

@ -601,6 +601,24 @@ llvm::Type* BfIRCodeGen::GetLLVMType(BfTypeCode typeCode, bool& isSigned)
return llvm::Type::getDoubleTy(*mLLVMContext); return llvm::Type::getDoubleTy(*mLLVMContext);
case BfTypeCode_Float2: case BfTypeCode_Float2:
return llvm::FixedVectorType::get(llvm::Type::getFloatTy(*mLLVMContext), 2); 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; default: break;
} }
return NULL; return NULL;

View file

@ -842,7 +842,8 @@ bool BfMethodInstance::WantsStructsAttribByVal(BfType* paramType)
if ((owner->mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows) && if ((owner->mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows) &&
(owner->mModule->mCompiler->mOptions.mMachineType == BfMachineType_x64)) (owner->mModule->mCompiler->mOptions.mMachineType == BfMachineType_x64))
return false; return false;
if (owner->mModule->mCompiler->mOptions.mMachineType == BfMachineType_AArch64)
return false;
auto typeInst = paramType->ToTypeInstance(); auto typeInst = paramType->ToTypeInstance();
return (typeInst != NULL) && (typeInst->mIsCRepr); return (typeInst != NULL) && (typeInst->mIsCRepr);
} }
@ -1202,7 +1203,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
BfTypeCode loweredReturnTypeCode = BfTypeCode_None; BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
BfTypeCode loweredReturnTypeCode2 = 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); auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
returnType = irReturnType; 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 // Odd Windows rule: composite returns for non-static methods are always sret
if (typeUsage == BfTypeUsage_Return_NonStatic) if (typeUsage == BfTypeUsage_Return_NonStatic)
return false; return false;
} }
else else
{ {
// Non-Win64 systems allow lowered splitting of composites over multiple params // 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 (deepCheck)
{ {
if ((mInstSize >= 4) && (mInstSize <= maxInstSize))
if ((mInstSize >= 4) && (mInstSize <= 16))
{ {
BfTypeCode types[4] = { BfTypeCode_None }; BfTypeCode types[8] = { BfTypeCode_None };
std::function<void(BfType*, int)> _CheckType = [&](BfType* type, int offset) std::function<void(BfType*, int)> _CheckType = [&](BfType* type, int offset)
{ {
@ -1883,12 +1887,14 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
} }
} }
else else
types[offset / 4] = BfTypeCode_Object; {
types[offset / 4] = BfTypeCode_Object;
}
} }
else if (type->IsPrimitiveType()) else if (type->IsPrimitiveType())
{ {
auto primType = (BfPrimitiveType*)type; auto primType = (BfPrimitiveType*)type;
types[offset / 4] = primType->mTypeDef->mTypeCode; types[offset / 4] = primType->mTypeDef->mTypeCode;
} }
else if (type->IsSizedArray()) else if (type->IsSizedArray())
{ {
@ -1902,7 +1908,87 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
bool handled = false; 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; bool hasFloat = false;
for (int type = 0; type < 4; type++) for (int type = 0; type < 4; type++)