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,49 @@ // 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 (HasC) + Builder.defineMacro("__riscv_compressed"); + + // TODO: Define __riscv_flen, __riscv_fdiv and __riscv_fsqrt after + // F and D code gen upstream. + + // TODO: Define __riscv_atomic after A code gen upstream. +} + +bool RISCVTargetInfo::hasFeature(StringRef Feature) const { + return llvm::StringSwitch(Feature) + .Case("m", HasM) + .Case("a", HasA) + .Case("f", HasF) + .Case("d", HasD) + .Case("c", HasC) + .Default(false); +} + +/// handleTargetFeatures - 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/Preprocessor/riscv-target-features.c =================================================================== --- /dev/null +++ test/Preprocessor/riscv-target-features.c @@ -0,0 +1,17 @@ +// RUN: %clang -target riscv32-unknown-linux-gnu -x c -E -dM %s -o - | FileCheck %s +// RUN: %clang -target riscv64-unknown-linux-gnu -x c -E -dM %s -o - | FileCheck %s + +// CHECK-NOT: __riscv_div +// CHECK-NOT: __riscv_mul +// CHECK-NOT: __riscv_muldiv +// CHECK-NOT: __riscv_compressed + +// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32im -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-M-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64im -x c -E -dM %s -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=rv32ic -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-C-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ic -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-C-EXT %s +// CHECK-C-EXT: __riscv_compressed 1