diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 21ec2e17..84815bd9 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -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); diff --git a/IDE/src/Project.bf b/IDE/src/Project.bf index 56922862..207ee5ce 100644 --- a/IDE/src/Project.bf +++ b/IDE/src/Project.bf @@ -879,6 +879,7 @@ namespace IDE case Test; case StaticLib; case DynamicLib; + case Intermediate; case NotSupported; } diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 2be4f74d..6ba9a95a 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -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; } } diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index b70b6ad5..96a55a86 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -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 }; diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index d92a6c8c..b9841eb5 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -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; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index ec8c59a9..960a0cab 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -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 _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++)