diff --git a/driver/main.cpp b/driver/main.cpp index 25280e3388..9e7f2b8e75 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -618,21 +618,22 @@ void fixupUClibcEnv() /// Also defines D_HardFloat or D_SoftFloat depending if FPU should be used void registerPredefinedFloatABI(const char *soft, const char *hard, const char *softfp = nullptr) { - // Use target floating point unit instead of s/w float routines - // FIXME: This is a semantic change! - bool useFPU = gTargetMachine->Options.FloatABIType == llvm::FloatABI::Hard; - VersionCondition::addPredefinedGlobalIdent(useFPU ? "D_HardFloat" - : "D_SoftFloat"); - - if (gTargetMachine->Options.FloatABIType == llvm::FloatABI::Soft) { - VersionCondition::addPredefinedGlobalIdent(useFPU && softfp ? softfp - : soft); - } else if (gTargetMachine->Options.FloatABIType == llvm::FloatABI::Hard) { - assert(useFPU && "Should be using the FPU if using float-abi=hard"); + switch (floatABI) { + case FloatABI::Soft: + VersionCondition::addPredefinedGlobalIdent(soft); + break; + case FloatABI::SoftFP: + VersionCondition::addPredefinedGlobalIdent(softfp ? softfp : soft); + break; + case FloatABI::Hard: VersionCondition::addPredefinedGlobalIdent(hard); - } else { - assert(0 && "FloatABIType neither Soft or Hard"); + break; + default: + llvm_unreachable("Unknown float ABI"); } + + VersionCondition::addPredefinedGlobalIdent( + floatABI == FloatABI::Soft ? "D_SoftFloat" : "D_HardFloat"); } /// Registers the predefined versions specific to the current target triple @@ -997,6 +998,7 @@ int cppmain(int argc, char **argv) { // check and fix environment for uClibc fixupUClibcEnv(); + // create target machine and finalize floatABI gTargetMachine = createTargetMachine( mTargetTriple, arch, opts::getCPUStr(), opts::getFeaturesStr(), bitness, floatABI, relocModel, opts::getCodeModel(), codeGenOptLevel(), diff --git a/driver/targetmachine.cpp b/driver/targetmachine.cpp index 25949deb45..5bcdf9b72a 100644 --- a/driver/targetmachine.cpp +++ b/driver/targetmachine.cpp @@ -345,7 +345,7 @@ llvm::TargetMachine * createTargetMachine(const std::string targetTriple, const std::string arch, std::string cpu, const std::string featuresString, const ExplicitBitness::Type bitness, - FloatABI::Type floatABI, + FloatABI::Type &floatABI, #if LDC_LLVM_VER >= 309 llvm::Optional relocModel, #else @@ -468,20 +468,19 @@ createTargetMachine(const std::string targetTriple, const std::string arch, targetOptions.MCOptions.DwarfVersion = 3; #endif - auto ldcFloatABI = floatABI; - if (ldcFloatABI == FloatABI::Default) { + if (floatABI == FloatABI::Default) { switch (triple.getArch()) { default: // X86, ... - ldcFloatABI = FloatABI::Hard; + floatABI = FloatABI::Hard; break; case llvm::Triple::arm: case llvm::Triple::thumb: - ldcFloatABI = getARMFloatABI(triple, getLLVMArchSuffixForARM(cpu)); + floatABI = getARMFloatABI(triple, getLLVMArchSuffixForARM(cpu)); break; } } - switch (ldcFloatABI) { + switch (floatABI) { default: llvm_unreachable("Floating point ABI type unknown."); case FloatABI::Soft: diff --git a/driver/targetmachine.h b/driver/targetmachine.h index 2de1d77778..e4835a89c9 100644 --- a/driver/targetmachine.h +++ b/driver/targetmachine.h @@ -50,13 +50,14 @@ ComputeBackend::Type getComputeTargetType(llvm::Module*); /** * Creates an LLVM TargetMachine suitable for the given (usually command-line) * parameters and the host platform defaults. + * Also finalizes floatABI if it's set to FloatABI::Default. * * Does not depend on any global state. */ llvm::TargetMachine * createTargetMachine(std::string targetTriple, std::string arch, std::string cpu, std::string featuresString, ExplicitBitness::Type bitness, - FloatABI::Type floatABI, + FloatABI::Type &floatABI, #if LDC_LLVM_VER >= 309 llvm::Optional relocModel, #else diff --git a/gen/dcompute/targetCUDA.cpp b/gen/dcompute/targetCUDA.cpp index efb8606eb2..e94fab8d6d 100644 --- a/gen/dcompute/targetCUDA.cpp +++ b/gen/dcompute/targetCUDA.cpp @@ -35,10 +35,11 @@ public: const bool is64 = global.params.is64bit; auto tripleString = is64 ? "nvptx64-nvidia-cuda" : "nvptx-nvidia-cuda"; + auto floatABI = ::FloatABI::Hard; targetMachine = createTargetMachine( tripleString, is64 ? "nvptx64" : "nvptx", "sm_" + ldc::to_string(tversion / 10), {}, - is64 ? ExplicitBitness::M64 : ExplicitBitness::M32, ::FloatABI::Hard, + is64 ? ExplicitBitness::M64 : ExplicitBitness::M32, floatABI, llvm::Reloc::Static, llvm::CodeModel::Medium, codeGenOptLevel(), false); _ir = new IRState("dcomputeTargetCUDA", ctx); diff --git a/tests/driver/float_abi.d b/tests/driver/float_abi.d new file mode 100644 index 0000000000..b910ffa5cd --- /dev/null +++ b/tests/driver/float_abi.d @@ -0,0 +1,35 @@ +// REQUIRES: target_ARM + +// RUN: %ldc -c -o- %s -mtriple=armv7-linux-android -float-abi=soft -d-version=SOFT +// RUN: %ldc -c -o- %s -mtriple=armv7-linux-android -float-abi=softfp -d-version=SOFTFP +// RUN: %ldc -c -o- %s -mtriple=armv7-linux-gnueabihf -d-version=HARD + +version (SOFT) +{ + version (ARM_SoftFloat) {} else static assert(0); + version (ARM_SoftFP) static assert(0); + version (ARM_HardFloat) static assert(0); + + version (D_SoftFloat) {} else static assert(0); + version (D_HardFloat) static assert(0); +} +else version (SOFTFP) +{ + version (ARM_SoftFloat) static assert(0); + version (ARM_SoftFP) {} else static assert(0); + version (ARM_HardFloat) static assert(0); + + version (D_SoftFloat) static assert(0); + version (D_HardFloat) {} else static assert(0); +} +else version (HARD) +{ + version (ARM_SoftFloat) static assert(0); + version (ARM_SoftFP) static assert(0); + version (ARM_HardFloat) {} else static assert(0); + + version (D_SoftFloat) static assert(0); + version (D_HardFloat) {} else static assert(0); +} +else + static assert(0);