diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/Targets.cpp | 20 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 29 | ||||
-rw-r--r-- | clang/lib/Headers/altivec.h | 127 |
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 */ |