Index: lib/Basic/Targets/RISCV.h =================================================================== --- lib/Basic/Targets/RISCV.h +++ lib/Basic/Targets/RISCV.h @@ -26,10 +26,16 @@ class RISCVTargetInfo : public TargetInfo { protected: std::string ABI; + bool HasM; + bool HasA; + bool HasF; + bool HasD; + bool HasC; public: RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &) - : TargetInfo(Triple) { + : TargetInfo(Triple), HasM(false), HasA(false), HasF(false), + HasD(false), HasC(false) { TLSSupported = false; LongDoubleWidth = 128; LongDoubleAlign = 128; @@ -59,6 +65,11 @@ TargetInfo::ConstraintInfo &Info) const override { return false; } + + bool hasFeature(StringRef Feature) const override; + + bool handleTargetFeatures(std::vector &Features, + DiagnosticsEngine &Diags) override; }; class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { public: Index: lib/Basic/Targets/RISCV.cpp =================================================================== --- lib/Basic/Targets/RISCV.cpp +++ lib/Basic/Targets/RISCV.cpp @@ -49,4 +49,60 @@ // TODO: modify when more code models and ABIs are supported. Builder.defineMacro("__riscv_cmodel_medlow"); Builder.defineMacro("__riscv_float_abi_soft"); + + if (HasM) { + Builder.defineMacro("__riscv_mul"); + Builder.defineMacro("__riscv_div"); + Builder.defineMacro("__riscv_muldiv"); + } + + if (HasA) + Builder.defineMacro("__riscv_atomic"); + + if (HasD) + Builder.defineMacro("__riscv_flen", "64"); + else if (HasF) + Builder.defineMacro("__riscv_flen", "32"); + + if (HasF || HasD) { + Builder.defineMacro("__riscv_fdiv"); + Builder.defineMacro("__riscv_fsqrt"); + } + + if (HasC) + Builder.defineMacro("__riscv_compressed"); +} + +/// Return true if has this feature, need to sync with handleTargetFeatures. +bool RISCVTargetInfo::hasFeature(StringRef Feature) const { + bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64; + return llvm::StringSwitch(Feature) + .Case("riscv", true) + .Case("riscv32", !Is64Bit) + .Case("riscv64", Is64Bit) + .Case("m", HasM) + .Case("a", HasA) + .Case("f", HasF) + .Case("d", HasD) + .Case("c", HasC) + .Default(false); +} + +/// Perform initialization based on the user configured set of features. +bool RISCVTargetInfo::handleTargetFeatures(std::vector &Features, + DiagnosticsEngine &Diags) { + for (const auto &Feature : Features) { + if (Feature == "+m") + HasM = true; + else if (Feature == "+a") + HasA = true; + else if (Feature == "+f") + HasF = true; + else if (Feature == "+d") + HasD = true; + else if (Feature == "+c") + HasC = true; + } + + return true; } Index: test/Modules/Inputs/module.map =================================================================== --- test/Modules/Inputs/module.map +++ test/Modules/Inputs/module.map @@ -380,6 +380,11 @@ module x86_32 { requires x86_32 } module x86_64 { requires x86_64 } } + module riscv { + requires riscv + module riscv32 { requires riscv32 } + module riscv64 { requires riscv64 } + } } module DebugSubmodules { Index: test/Modules/target-features.m =================================================================== --- test/Modules/target-features.m +++ test/Modules/target-features.m @@ -1,6 +1,7 @@ // REQUIRES: x86-registered-target // REQUIRES: arm-registered-target // REQUIRES: aarch64-registered-target +// REQUIRES: riscv-registered-target // RUN: rm -rf %t @@ -17,6 +18,10 @@ // RUN: FileCheck %s -check-prefix=X86_32 < %t.x86_32 // RUN: not %clang_cc1 -triple x86_64-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s 2> %t.x86_64 // RUN: FileCheck %s -check-prefix=X86_64 < %t.x86_64 +// RUN: not %clang_cc1 -triple riscv32-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s 2> %t.riscv32 +// RUN: FileCheck %s -check-prefix=RISCV32 < %t.riscv32 +// RUN: not %clang_cc1 -triple riscv64-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s 2> %t.riscv64 +// RUN: FileCheck %s -check-prefix=RISCV64 < %t.riscv64 #ifndef SANITY_CHECK @import TargetFeatures; @@ -24,16 +29,22 @@ // AARCH64-NOT: module 'TargetFeatures' requires // X86_32-NOT: module 'TargetFeatures' requires // X86_64-NOT: module 'TargetFeatures' requires +// RISCV32-NOT: module 'TargetFeatures' requires +// RISCV64-NOT: module 'TargetFeatures' requires @import TargetFeatures.arm; // AARCH32-NOT: module 'TargetFeatures.arm' requires // AARCH64-NOT: module 'TargetFeatures.arm' requires // X86_32: module 'TargetFeatures.arm' requires feature 'arm' // X86_64: module 'TargetFeatures.arm' requires feature 'arm' +// RISCV32: module 'TargetFeatures.arm' requires +// RISCV64: module 'TargetFeatures.arm' requires @import TargetFeatures.arm.aarch32; // AARCH32-NOT: module 'TargetFeatures.arm.aarch32' requires // AARCH64: module 'TargetFeatures.arm.aarch32' requires feature 'aarch32' // X86_32: module 'TargetFeatures.arm.aarch32' requires feature // X86_64: module 'TargetFeatures.arm.aarch32' requires feature +// RISCV32: module 'TargetFeatures.arm.aarch32' requires feature +// RISCV64: module 'TargetFeatures.arm.aarch32' requires feature #endif @import TargetFeatures.arm.aarch64; @@ -41,6 +52,8 @@ // AARCH64-NOT: module 'TargetFeatures.arm.aarch64' requires // X86_32: module 'TargetFeatures.arm.aarch64' requires feature // X86_64: module 'TargetFeatures.arm.aarch64' requires feature +// RISCV32: module 'TargetFeatures.arm.aarch64' requires feature +// RISCV64: module 'TargetFeatures.arm.aarch64' requires feature #ifndef SANITY_CHECK @import TargetFeatures.x86; @@ -48,14 +61,41 @@ // AARCH64: module 'TargetFeatures.x86' requires feature 'x86' // X86_32-NOT: module 'TargetFeatures.x86' requires // X86_64-NOT: module 'TargetFeatures.x86' requires +// RISCV32: module 'TargetFeatures.x86' requires feature 'x86' +// RISCV64: module 'TargetFeatures.x86' requires feature 'x86' @import TargetFeatures.x86.x86_32; // AARCH32: module 'TargetFeatures.x86.x86_32' requires feature // AARCH64: module 'TargetFeatures.x86.x86_32' requires feature // X86_32-NOT: module 'TargetFeatures.x86.x86_32' requires // X86_64: module 'TargetFeatures.x86.x86_32' requires feature 'x86_32' +// RISCV32: module 'TargetFeatures.x86.x86_32' requires feature +// RISCV64: module 'TargetFeatures.x86.x86_32' requires feature @import TargetFeatures.x86.x86_64; // AARCH32: module 'TargetFeatures.x86.x86_64' requires feature // AARCH64: module 'TargetFeatures.x86.x86_64' requires feature // X86_32: module 'TargetFeatures.x86.x86_64' requires feature 'x86_64' // X86_64-NOT: module 'TargetFeatures.x86.x86_64' requires +// RISCV32: module 'TargetFeatures.x86.x86_64' requires feature +// RISCV64: module 'TargetFeatures.x86.x86_64' requires feature +@import TargetFeatures.riscv; +// AARCH32: module 'TargetFeatures.riscv' requires feature +// AARCH64: module 'TargetFeatures.riscv' requires feature +// X86_32: module 'TargetFeatures.riscv' requires feature +// X86_64: module 'TargetFeatures.riscv' requires feature +// RISCV32-NOT: module 'TargetFeatures.riscv' requires feature +// RISCV64-NOT: module 'TargetFeatures.riscv' requires feature +@import TargetFeatures.riscv.riscv32; +// AARCH32: module 'TargetFeatures.riscv.riscv32' requires feature +// AARCH64: module 'TargetFeatures.riscv.riscv32' requires feature +// X86_32: module 'TargetFeatures.riscv.riscv32' requires feature +// X86_64: module 'TargetFeatures.riscv.riscv32' requires feature +// RISCV32-NOT: module 'TargetFeatures.riscv.riscv32' requires feature +// RISCV64: module 'TargetFeatures.riscv.riscv32' requires feature 'riscv32' +@import TargetFeatures.riscv.riscv64; +// AARCH32: module 'TargetFeatures.riscv.riscv64' requires feature +// AARCH64: module 'TargetFeatures.riscv.riscv64' requires feature +// X86_32: module 'TargetFeatures.riscv.riscv64' requires feature +// X86_64: module 'TargetFeatures.riscv.riscv64' requires feature +// RISCV32: module 'TargetFeatures.riscv.riscv64' requires feature 'riscv64' +// RISCV64-NOT: module 'TargetFeatures.riscv.riscv64' requires feature #endif Index: test/Preprocessor/riscv-target-features.c =================================================================== --- /dev/null +++ test/Preprocessor/riscv-target-features.c @@ -0,0 +1,49 @@ +// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32i -x c -E -dM %s \ +// RUN: -o - | FileCheck %s +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64i -x c -E -dM %s \ +// RUN: -o - | FileCheck %s + +// CHECK-NOT: __riscv_div +// CHECK-NOT: __riscv_mul +// CHECK-NOT: __riscv_muldiv +// CHECK-NOT: __riscv_compressed +// CHECK-NOT: __riscv_flen +// CHECK-NOT: __riscv_fdiv +// CHECK-NOT: __riscv_fsqrt +// CHECK-NOT: __riscv_atomic + +// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32im -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-M-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64im -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-M-EXT %s +// CHECK-M-EXT: __riscv_div 1 +// CHECK-M-EXT: __riscv_mul 1 +// CHECK-M-EXT: __riscv_muldiv 1 + +// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32ia -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-A-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ia -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-A-EXT %s +// CHECK-A-EXT: __riscv_atomic 1 + +// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32if -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-F-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64if -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-F-EXT %s +// CHECK-F-EXT: __riscv_fdiv 1 +// CHECK-F-EXT: __riscv_flen 32 +// CHECK-F-EXT: __riscv_fsqrt 1 + +// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32ifd -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-D-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ifd -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-D-EXT %s +// CHECK-D-EXT: __riscv_fdiv 1 +// CHECK-D-EXT: __riscv_flen 64 +// CHECK-D-EXT: __riscv_fsqrt 1 + +// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32ic -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-C-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ic -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-C-EXT %s +// CHECK-C-EXT: __riscv_compressed 1