diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3247,6 +3247,8 @@ def mno_mma: Flag<["-"], "mno-mma">, Group; def mrop_protect : Flag<["-"], "mrop-protect">, Group; +def mprivileged : Flag<["-"], "mprivileged">, + Group; def maix_struct_return : Flag<["-"], "maix-struct-return">, Group, Flags<[CC1Option]>, HelpText<"Return all structs in memory (PPC32 only)">; diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -60,6 +60,7 @@ bool HasAltivec = false; bool HasMMA = false; bool HasROPProtect = false; + bool HasPrivileged = false; bool HasVSX = false; bool HasP8Vector = false; bool HasP8Crypto = false; diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -68,6 +68,8 @@ HasMMA = true; } else if (Feature == "+rop-protect") { HasROPProtect = true; + } else if (Feature == "+privileged") { + HasPrivileged = true; } // TODO: Finish this list and add an assert that we've handled them // all. @@ -197,6 +199,8 @@ Builder.defineMacro("__MMA__"); if (HasROPProtect) Builder.defineMacro("__ROP_PROTECT__"); + if (HasPrivileged) + Builder.defineMacro("__PRIVILEGED__"); if (HasP10Vector) Builder.defineMacro("__POWER10_VECTOR__"); if (HasPCRelativeMemops) @@ -327,6 +331,8 @@ // ROP Protect is off by default. Features["rop-protect"] = false; + // Privileged instructions are off by default. + Features["privileged"] = false; Features["spe"] = llvm::StringSwitch(CPU) .Case("8548", true) @@ -371,6 +377,12 @@ return false; } + if (!(ArchDefs & ArchDefinePwr8) && + llvm::find(FeaturesVec, "+privileged") != FeaturesVec.end()) { + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mprivileged" << CPU; + return false; + } + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } @@ -410,6 +422,7 @@ .Case("spe", HasSPE) .Case("mma", HasMMA) .Case("rop-protect", HasROPProtect) + .Case("privileged", HasPrivileged) .Default(false); } diff --git a/clang/test/Driver/ppc-mprivileged-support-check.c b/clang/test/Driver/ppc-mprivileged-support-check.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/ppc-mprivileged-support-check.c @@ -0,0 +1,26 @@ +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr10 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power10 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr9 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power9 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr8 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power8 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=HASPRIV + +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr7 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=NOPRIV +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power7 -mprivileged %s 2>&1 | FileCheck %s --check-prefix=NOPRIV + +#ifdef __PRIVILEGED__ +static_assert(false, "Privileged instructions enabled"); +#endif + +// HASPRIV: Privileged instructions enabled +// HASPRIV-NOT: option '-mprivileged' cannot be specified with +// NOPRIV: option '-mprivileged' cannot be specified with + diff --git a/clang/test/Preprocessor/init-ppc64.c b/clang/test/Preprocessor/init-ppc64.c --- a/clang/test/Preprocessor/init-ppc64.c +++ b/clang/test/Preprocessor/init-ppc64.c @@ -567,6 +567,7 @@ // PPCPWR8:#define _ARCH_PWR7 1 // PPCPWR8:#define _ARCH_PWR8 1 // PPCPWR8-NOT:#define __ROP_PROTECT__ 1 +// PPCPWR8-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER8 %s // @@ -585,6 +586,7 @@ // PPCPOWER8:#define _ARCH_PWR7 1 // PPCPOWER8:#define _ARCH_PWR8 1 // PPCPOWER8-NOT:#define __ROP_PROTECT__ 1 +// PPCPOWER8-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr9 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPWR9 %s // @@ -600,6 +602,7 @@ // PPCPWR9:#define _ARCH_PWR7 1 // PPCPWR9:#define _ARCH_PWR9 1 // PPCPWR9-NOT:#define __ROP_PROTECT__ 1 +// PPCPWR9-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER9 %s // @@ -615,6 +618,7 @@ // PPCPOWER9:#define _ARCH_PWR7 1 // PPCPOWER9:#define _ARCH_PWR9 1 // PPCPOWER9-NOT:#define __ROP_PROTECT__ 1 +// PPCPOWER9-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr10 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER10 %s // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER10 %s @@ -635,6 +639,7 @@ // PPCPOWER10:#define __MMA__ 1 // PPCPOWER10:#define __PCREL__ 1 // PPCPOWER10-NOT:#define __ROP_PROTECT__ 1 +// PPCPOWER10-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu future -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCFUTURE %s // @@ -655,6 +660,7 @@ // PPCFUTURE:#define __MMA__ 1 // PPCFUTURE:#define __PCREL__ 1 // PPCFUTURE-NOT:#define __ROP_PROTECT__ 1 +// PPCFUTURE-NOT:#define __PRIVILEGED__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +mma -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-MMA %s // PPC-MMA:#define __MMA__ 1 @@ -664,6 +670,11 @@ // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +rop-protect -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-ROP %s // PPC-ROP:#define __ROP_PROTECT__ 1 // +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +privileged -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-PRIV %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +privileged -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-PRIV %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +privileged -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-PRIV %s +// PPC-PRIV:#define __PRIVILEGED__ 1 +// // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +float128 -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-FLOAT128 %s // PPC-FLOAT128:#define __FLOAT128__ 1 // diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td --- a/llvm/lib/Target/PowerPC/PPC.td +++ b/llvm/lib/Target/PowerPC/PPC.td @@ -256,6 +256,10 @@ SubtargetFeature<"rop-protect", "HasROPProtect", "true", "Add ROP protect">; +def FeaturePrivileged : + SubtargetFeature<"privileged", "HasPrivileged", "true", + "Add privileged instructions">; + def FeaturePredictableSelectIsExpensive : SubtargetFeature<"predictable-select-expensive", "PredictableSelectIsExpensive", diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.h b/llvm/lib/Target/PowerPC/PPCSubtarget.h --- a/llvm/lib/Target/PowerPC/PPCSubtarget.h +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.h @@ -113,6 +113,7 @@ bool HasPCRelativeMemops; bool HasMMA; bool HasROPProtect; + bool HasPrivileged; bool HasFCPSGN; bool HasFSQRT; bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES; @@ -275,6 +276,7 @@ bool hasPCRelativeMemops() const { return HasPCRelativeMemops; } bool hasMMA() const { return HasMMA; } bool hasROPProtect() const { return HasROPProtect; } + bool hasPrivileged() const { return HasPrivileged; } bool pairedVectorMemops() const { return PairedVectorMemops; } bool hasMFOCRF() const { return HasMFOCRF; } bool hasISEL() const { return HasISEL; } diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp --- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp @@ -88,6 +88,7 @@ HasP9Altivec = false; HasMMA = false; HasROPProtect = false; + HasPrivileged = false; HasP10Vector = false; HasPrefixInstrs = false; HasPCRelativeMemops = false; diff --git a/llvm/test/CodeGen/PowerPC/future-check-features.ll b/llvm/test/CodeGen/PowerPC/future-check-features.ll --- a/llvm/test/CodeGen/PowerPC/future-check-features.ll +++ b/llvm/test/CodeGen/PowerPC/future-check-features.ll @@ -1,7 +1,7 @@ -; RUN: llc -mattr=pcrelative-memops,prefix-instrs,paired-vector-memops,mma,rop-protect \ +; RUN: llc -mattr=pcrelative-memops,prefix-instrs,paired-vector-memops,mma,rop-protect,privileged \ ; RUN: -verify-machineinstrs -mtriple=powerpc64le-unknown-unknown \ ; RUN: -ppc-asm-full-reg-names %s -o - 2>&1 | FileCheck %s -; RUN: llc -mattr=pcrelative-memops,prefix-instrs,paired-vector-memops,mma,rop-protect \ +; RUN: llc -mattr=pcrelative-memops,prefix-instrs,paired-vector-memops,mma,rop-protect,privileged \ ; RUN: -verify-machineinstrs -mtriple=powerpc64-unknown-unknown \ ; RUN: -ppc-asm-full-reg-names %s -o - 2>&1 | FileCheck %s