summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Targets.cpp20
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp29
-rw-r--r--clang/lib/Headers/altivec.h127
3 files changed, 175 insertions, 1 deletions
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 1d820d36a9a..56b884d4ae6 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -719,13 +719,15 @@ class PPCTargetInfo : public TargetInfo {
// Target cpu features.
bool HasVSX;
bool HasP8Vector;
+ bool HasP8Crypto;
protected:
std::string ABI;
public:
PPCTargetInfo(const llvm::Triple &Triple)
- : TargetInfo(Triple), HasVSX(false), HasP8Vector(false) {
+ : TargetInfo(Triple), HasVSX(false), HasP8Vector(false),
+ HasP8Crypto(false) {
BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
LongDoubleWidth = LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
@@ -986,6 +988,11 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
continue;
}
+ if (Feature == "crypto") {
+ HasP8Crypto = true;
+ continue;
+ }
+
// TODO: Finish this list and add an assert that we've handled them
// all.
}
@@ -1138,6 +1145,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__VSX__");
if (HasP8Vector)
Builder.defineMacro("__POWER8_VECTOR__");
+ if (HasP8Crypto)
+ Builder.defineMacro("__CRYPTO__");
// FIXME: The following are not yet generated here by Clang, but are
// generated by GCC:
@@ -1176,6 +1185,14 @@ void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
.Default(false);
Features["qpx"] = (CPU == "a2q");
+ Features["crypto"] = llvm::StringSwitch<bool>(CPU)
+ .Case("ppc64le", true)
+ .Case("pwr8", true)
+ .Default(false);
+ Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)
+ .Case("ppc64le", true)
+ .Case("pwr8", true)
+ .Default(false);
}
bool PPCTargetInfo::hasFeature(StringRef Feature) const {
@@ -1183,6 +1200,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
.Case("powerpc", true)
.Case("vsx", HasVSX)
.Case("power8-vector", HasP8Vector)
+ .Case("crypto", HasP8Crypto)
.Default(false);
}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 014ea9d9392..eae5f02edbd 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -6349,6 +6349,35 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
llvm::Function *F = CGM.getIntrinsic(ID);
return Builder.CreateCall(F, Ops, "");
}
+ // P8 Crypto builtins
+ case PPC::BI__builtin_altivec_crypto_vshasigmaw:
+ case PPC::BI__builtin_altivec_crypto_vshasigmad:
+ {
+ ConstantInt *CI1 = dyn_cast<ConstantInt>(Ops[1]);
+ ConstantInt *CI2 = dyn_cast<ConstantInt>(Ops[2]);
+ assert(CI1 && CI2);
+ if (CI1->getZExtValue() > 1) {
+ CGM.Error(E->getArg(1)->getExprLoc(),
+ "argument out of range (should be 0-1).");
+ return llvm::UndefValue::get(Ops[0]->getType());
+ }
+ if (CI2->getZExtValue() > 15) {
+ CGM.Error(E->getArg(2)->getExprLoc(),
+ "argument out of range (should be 0-15).");
+ return llvm::UndefValue::get(Ops[0]->getType());
+ }
+ switch (BuiltinID) {
+ default: llvm_unreachable("Unsupported sigma intrinsic!");
+ case PPC::BI__builtin_altivec_crypto_vshasigmaw:
+ ID = Intrinsic::ppc_altivec_crypto_vshasigmaw;
+ break;
+ case PPC::BI__builtin_altivec_crypto_vshasigmad:
+ ID = Intrinsic::ppc_altivec_crypto_vshasigmad;
+ break;
+ }
+ llvm::Function *F = CGM.getIntrinsic(ID);
+ return Builder.CreateCall(F, Ops, "");
+ }
}
}
diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h
index b8a886954b7..48cc44c2ca2 100644
--- a/clang/lib/Headers/altivec.h
+++ b/clang/lib/Headers/altivec.h
@@ -12661,6 +12661,133 @@ vec_any_out(vector float __a, vector float __b)
return __builtin_altivec_vcmpbfp_p(__CR6_EQ_REV, __a, __b);
}
+/* Power 8 Crypto functions
+Note: We diverge from the current GCC implementation with regard
+to cryptography and related functions as follows:
+- Only the SHA and AES instructions and builtins are disabled by -mno-crypto
+- The remaining ones are only available on Power8 and up so
+ require -mpower8-vector
+The justification for this is that export requirements require that
+Category:Vector.Crypto is optional (i.e. compliant hardware may not provide
+support). As a result, we need to be able to turn off support for those.
+The remaining ones (currently controlled by -mcrypto for GCC) still
+need to be provided on compliant hardware even if Vector.Crypto is not
+provided.
+FIXME: the naming convention for the builtins will be adjusted due
+to the inconsistency (__builtin_crypto_ prefix on builtins that cannot be
+removed with -mno-crypto). This is under development.
+*/
+#ifdef __CRYPTO__
+static vector unsigned long long __attribute__((__always_inline__))
+__builtin_crypto_vsbox (vector unsigned long long __a)
+{
+ return __builtin_altivec_crypto_vsbox(__a);
+}
+
+static vector unsigned long long __attribute__((__always_inline__))
+__builtin_crypto_vcipher (vector unsigned long long __a,
+ vector unsigned long long __b)
+{
+ return __builtin_altivec_crypto_vcipher(__a, __b);
+}
+
+static vector unsigned long long __attribute__((__always_inline__))
+__builtin_crypto_vcipherlast (vector unsigned long long __a,
+ vector unsigned long long __b)
+{
+ return __builtin_altivec_crypto_vcipherlast(__a, __b);
+}
+
+static vector unsigned long long __attribute__((__always_inline__))
+__builtin_crypto_vncipher (vector unsigned long long __a,
+ vector unsigned long long __b)
+{
+ return __builtin_altivec_crypto_vncipher(__a, __b);
+}
+
+static vector unsigned long long __attribute__((__always_inline__))
+__builtin_crypto_vncipherlast (vector unsigned long long __a,
+ vector unsigned long long __b)
+{
+ return __builtin_altivec_crypto_vncipherlast(__a, __b);
+}
+
+
+#define __builtin_crypto_vshasigmad __builtin_altivec_crypto_vshasigmad
+#define __builtin_crypto_vshasigmaw __builtin_altivec_crypto_vshasigmaw
+#endif
+
+#ifdef __POWER8_VECTOR__
+static vector unsigned char __ATTRS_o_ai
+__builtin_crypto_vpermxor (vector unsigned char __a,
+ vector unsigned char __b,
+ vector unsigned char __c)
+{
+ return __builtin_altivec_crypto_vpermxor(__a, __b, __c);
+}
+
+static vector unsigned short __ATTRS_o_ai
+__builtin_crypto_vpermxor (vector unsigned short __a,
+ vector unsigned short __b,
+ vector unsigned short __c)
+{
+ return (vector unsigned short)
+ __builtin_altivec_crypto_vpermxor((vector unsigned char) __a,
+ (vector unsigned char) __b,
+ (vector unsigned char) __c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+__builtin_crypto_vpermxor (vector unsigned int __a,
+ vector unsigned int __b,
+ vector unsigned int __c)
+{
+ return (vector unsigned int)
+ __builtin_altivec_crypto_vpermxor((vector unsigned char) __a,
+ (vector unsigned char) __b,
+ (vector unsigned char) __c);
+}
+
+static vector unsigned long long __ATTRS_o_ai
+__builtin_crypto_vpermxor (vector unsigned long long __a,
+ vector unsigned long long __b,
+ vector unsigned long long __c)
+{
+ return (vector unsigned long long)
+ __builtin_altivec_crypto_vpermxor((vector unsigned char) __a,
+ (vector unsigned char) __b,
+ (vector unsigned char) __c);
+}
+
+static vector unsigned char __ATTRS_o_ai
+__builtin_crypto_vpmsumb (vector unsigned char __a,
+ vector unsigned char __b)
+{
+ return __builtin_altivec_crypto_vpmsumb(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+__builtin_crypto_vpmsumb (vector unsigned short __a,
+ vector unsigned short __b)
+{
+ return __builtin_altivec_crypto_vpmsumh(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+__builtin_crypto_vpmsumb (vector unsigned int __a,
+ vector unsigned int __b)
+{
+ return __builtin_altivec_crypto_vpmsumw(__a, __b);
+}
+
+static vector unsigned long long __ATTRS_o_ai
+__builtin_crypto_vpmsumb (vector unsigned long long __a,
+ vector unsigned long long __b)
+{
+ return __builtin_altivec_crypto_vpmsumd(__a, __b);
+}
+#endif
+
#undef __ATTRS_o_ai
#endif /* __ALTIVEC_H */
OpenPOWER on IntegriCloud