summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f5ce8fba8c6..35597fe4a0b 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -26,6 +26,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Intrinsics.h"
+#include <sstream>
using namespace clang;
using namespace CodeGen;
@@ -6370,6 +6371,7 @@ 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:
@@ -6399,6 +6401,89 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
llvm::Function *F = CGM.getIntrinsic(ID);
return Builder.CreateCall(F, Ops, "");
}
+
+ // HTM builtins
+ case PPC::BI__builtin_tbegin:
+ case PPC::BI__builtin_tend:
+ case PPC::BI__builtin_tsr: {
+ unsigned int MaxValue;
+ // The HTM instructions only accept one argument and with limited range.
+ ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]);
+ assert(CI);
+ switch (BuiltinID) {
+ case PPC::BI__builtin_tbegin:
+ ID = Intrinsic::ppc_tbegin;
+ MaxValue = 1;
+ break;
+ case PPC::BI__builtin_tend:
+ ID = Intrinsic::ppc_tend;
+ MaxValue = 1;
+ break;
+ case PPC::BI__builtin_tsr:
+ ID = Intrinsic::ppc_tsr;
+ MaxValue = 7;
+ break;
+ }
+ if (CI->getZExtValue() > MaxValue) {
+ std::stringstream ss;
+ ss << "argument out of range (should be 0 or " << MaxValue << ")";
+ CGM.Error(E->getArg(0)->getExprLoc(), ss.str());
+ return llvm::UndefValue::get(Ops[0]->getType());
+ }
+
+ llvm::Function *F = CGM.getIntrinsic(ID);
+ return Builder.CreateCall(F, Ops, "");
+ }
+ case PPC::BI__builtin_tabortdc:
+ case PPC::BI__builtin_tabortwc: {
+ // For wd and dc variant of tabort first argument must be a 5-bit constant
+ // integer
+ ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]);
+ assert(CI);
+ if (CI->getZExtValue() > 31) {
+ CGM.ErrorUnsupported(E->getArg(0), "argument out of range (should be 0-31)");
+ return llvm::UndefValue::get(Ops[0]->getType());
+ }
+ switch (BuiltinID) {
+ case PPC::BI__builtin_tabortdc:
+ ID = Intrinsic::ppc_tabortdc;
+ break;
+ case PPC::BI__builtin_tabortwc:
+ ID = Intrinsic::ppc_tabortwc;
+ break;
+ }
+ llvm::Function *F = CGM.getIntrinsic(ID);
+ return Builder.CreateCall(F, Ops, "");
+ }
+ case PPC::BI__builtin_tabortdci:
+ case PPC::BI__builtin_tabortwci: {
+ // For wd and dc variant of tabort first and third argument must be a
+ // 5-bit constant integer
+ ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]);
+ assert(CI);
+ if (CI->getZExtValue() > 31) {
+ CGM.ErrorUnsupported(E->getArg(0), "argument out of range (should be 0-31)");
+ return llvm::UndefValue::get(Ops[0]->getType());
+ }
+ CI = dyn_cast<ConstantInt>(Ops[2]);
+ assert(CI);
+ if (CI->getZExtValue() > 31) {
+ CGM.ErrorUnsupported(E->getArg(2), "argument out of range (should be 0-31)");
+ return llvm::UndefValue::get(Ops[2]->getType());
+ }
+ switch (BuiltinID) {
+ default: llvm_unreachable("Unsupported htm intrinsic!");
+ case PPC::BI__builtin_tabortdci:
+ ID = Intrinsic::ppc_tabortdci;
+ break;
+ case PPC::BI__builtin_tabortwci:
+ ID = Intrinsic::ppc_tabortwci;
+ break;
+ }
+ llvm::Function *F = CGM.getIntrinsic(ID);
+ return Builder.CreateCall(F, Ops, "");
+ }
+
}
}
OpenPOWER on IntegriCloud