diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -24,10 +24,14 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { protected: std::string ABI; + bool HasFeatureD; + bool HasFeatureF; public: LoongArchTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { + HasFeatureD = false; + HasFeatureF = false; LongDoubleWidth = 128; LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); @@ -58,6 +62,9 @@ std::string convertConstraint(const char *&Constraint) const override; bool hasBitIntType() const override { return true; } + + bool handleTargetFeatures(std::vector &Features, + DiagnosticsEngine &Diags) override; }; class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -127,10 +127,47 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__loongarch__"); - // TODO: Define more macros. + Builder.defineMacro("__loongarch_grlen", Twine(getRegisterWidth())); + + if (HasFeatureD) + Builder.defineMacro("__loongarch_frlen", "64"); + else if (HasFeatureF) + Builder.defineMacro("__loongarch_frlen", "32"); + else + Builder.defineMacro("__loongarch_frlen", "0"); + + // TODO: define __loongarch_arch and __loongarch_tune. + + StringRef ABI = getABI(); + if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s") + Builder.defineMacro("__loongarch_lp64"); + + if (ABI == "lp64d" || ABI == "ilp32d") { + Builder.defineMacro("__loongarch_hard_float"); + Builder.defineMacro("__loongarch_double_float"); + } else if (ABI == "lp64f" || ABI == "ilp32f") { + Builder.defineMacro("__loongarch_hard_float"); + Builder.defineMacro("__loongarch_single_float"); + } else if (ABI == "lp64s" || ABI == "ilp32s") { + Builder.defineMacro("__loongarch_soft_float"); + } } ArrayRef LoongArchTargetInfo::getTargetBuiltins() const { // TODO: To be implemented in future. return {}; } + +bool LoongArchTargetInfo::handleTargetFeatures( + std::vector &Features, DiagnosticsEngine &Diags) { + for (const auto &Feature : Features) { + if (Feature == "+d" || Feature == "+f") { + // "d" implies "f". + HasFeatureF = true; + if (Feature == "+d") { + HasFeatureD = true; + } + } + } + return true; +} diff --git a/clang/test/Preprocessor/init-loongarch.c b/clang/test/Preprocessor/init-loongarch.c --- a/clang/test/Preprocessor/init-loongarch.c +++ b/clang/test/Preprocessor/init-loongarch.c @@ -639,3 +639,83 @@ // LA64-LINUX: #define __unix__ 1 // LA64-LINUX: #define linux 1 // LA64-LINUX: #define unix 1 + + +/// Check various macros prefixed with "__loongarch_" in different cases. +/// "__loongarch__"" is not listed here as it has been checked above. + +// RUN: %clang --target=loongarch32 -mdouble-float -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA32-DOUBLE %s +// RUN: %clang --target=loongarch32 -mfpu=64 -mabi=ilp32d -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA32-DOUBLE %s +// LA32-DOUBLE: __loongarch_double_float 1 +// LA32-DOUBLE: __loongarch_frlen 64 +// LA32-DOUBLE: __loongarch_grlen 32 +// LA32-DOUBLE: __loongarch_hard_float 1 +// LA32-DOUBLE-NOT: __loongarch_lp64 +// LA32-DOUBLE-NOT: __loongarch_single_float +// LA32-DOUBLE-NOT: __loongarch_soft_float + +// RUN: %clang --target=loongarch32 -msingle-float -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA32-SINGLE %s +// RUN: %clang --target=loongarch32 -mfpu=32 -mabi=ilp32f -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA32-SINGLE %s +// LA32-SINGLE-NOT: __loongarch_double_float +// LA32-SINGLE: __loongarch_frlen 32 +// LA32-SINGLE: __loongarch_grlen 32 +// LA32-SINGLE: __loongarch_hard_float 1 +// LA32-SINGLE-NOT: __loongarch_lp64 +// LA32-SINGLE: __loongarch_single_float 1 +// LA32-SINGLE-NOT: __loongarch_soft_float + +// RUN: %clang --target=loongarch32 -msoft-float -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA32-SOFT %s +// RUN: %clang --target=loongarch32 -mfpu=0 -mabi=ilp32s -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA32-SOFT %s +// RUN: %clang --target=loongarch32 -mfpu=none -mabi=ilp32s -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA32-SOFT %s +// LA32-SOFT-NOT: __loongarch_double_float +// LA32-SOFT: __loongarch_frlen 0 +// LA32-SOFT: __loongarch_grlen 32 +// LA32-SOFT-NOT: __loongarch_hard_float +// LA32-SOFT-NOT: __loongarch_lp64 +// LA32-SOFT-NOT: __loongarch_single_float +// LA32-SOFT: __loongarch_soft_float 1 + +// RUN: %clang --target=loongarch64 -mdouble-float -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA64-DOUBLE %s +// RUN: %clang --target=loongarch64 -mfpu=64 -mabi=lp64d -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA64-DOUBLE %s +// LA64-DOUBLE: __loongarch_double_float 1 +// LA64-DOUBLE: __loongarch_frlen 64 +// LA64-DOUBLE: __loongarch_grlen 64 +// LA64-DOUBLE: __loongarch_hard_float 1 +// LA64-DOUBLE: __loongarch_lp64 1 +// LA64-DOUBLE-NOT: __loongarch_single_float +// LA64-DOUBLE-NOT: __loongarch_soft_float + +// RUN: %clang --target=loongarch64 -msingle-float -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA64-SINGLE %s +// RUN: %clang --target=loongarch64 -mfpu=32 -mabi=lp64f -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA64-SINGLE %s +// LA64-SINGLE-NOT: __loongarch_double_float +// LA64-SINGLE: __loongarch_frlen 32 +// LA64-SINGLE: __loongarch_grlen 64 +// LA64-SINGLE: __loongarch_hard_float 1 +// LA64-SINGLE: __loongarch_lp64 1 +// LA64-SINGLE: __loongarch_single_float 1 +// LA64-SINGLE-NOT: __loongarch_soft_float + +// RUN: %clang --target=loongarch64 -msoft-float -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA64-SOFT %s +// RUN: %clang --target=loongarch64 -mfpu=0 -mabi=lp64s -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA64-SOFT %s +// RUN: %clang --target=loongarch64 -mfpu=none -mabi=lp64s -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=LA64-SOFT %s +// LA64-SOFT-NOT: __loongarch_double_float +// LA64-SOFT: __loongarch_frlen 0 +// LA64-SOFT: __loongarch_grlen 64 +// LA64-SOFT-NOT: __loongarch_hard_float +// LA64-SOFT: __loongarch_lp64 1 +// LA64-SOFT-NOT: __loongarch_single_float +// LA64-SOFT: __loongarch_soft_float 1