diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Basic/Targets.cpp | 13 | ||||
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 37 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 1 |
3 files changed, 48 insertions, 3 deletions
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 4fdbc24477..a71e8b0ca3 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -1458,6 +1458,8 @@ static const char *DescriptionStringSI = "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; class R600TargetInfo : public TargetInfo { + static const Builtin::Info BuiltinInfo[]; + /// \brief The GPU profiles supported by the R600 target. enum GPUKind { GK_NONE, @@ -1504,11 +1506,10 @@ public: void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const override { - Records = nullptr; - NumRecords = 0; + Records = BuiltinInfo; + NumRecords = clang::R600::LastTSBuiltin - Builtin::FirstTSBuiltin; } - void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { Builder.defineMacro("__R600__"); @@ -1584,6 +1585,12 @@ public: } }; +const Builtin::Info R600TargetInfo::BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, +#include "clang/Basic/BuiltinsR600.def" +}; + } // end anonymous namespace namespace { diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 608e9d9a16..5bc03f3b94 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -1689,6 +1689,8 @@ Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, case llvm::Triple::ppc64: case llvm::Triple::ppc64le: return EmitPPCBuiltinExpr(BuiltinID, E); + case llvm::Triple::r600: + return EmitR600BuiltinExpr(BuiltinID, E); default: return nullptr; } @@ -5922,3 +5924,38 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, } } } + +Value *CodeGenFunction::EmitR600BuiltinExpr(unsigned BuiltinID, + const CallExpr *E) { + switch (BuiltinID) { + case R600::BI__builtin_amdgpu_div_scale: + case R600::BI__builtin_amdgpu_div_scalef: { + // Translate from the intrinsics's struct return to the builtin's out + // argument. + + std::pair<llvm::Value *, unsigned> FlagOutPtr + = EmitPointerWithAlignment(E->getArg(3)); + + llvm::Value *X = EmitScalarExpr(E->getArg(0)); + llvm::Value *Y = EmitScalarExpr(E->getArg(1)); + llvm::Value *Z = EmitScalarExpr(E->getArg(2)); + + llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::AMDGPU_div_scale, + X->getType()); + + llvm::Value *Tmp = Builder.CreateCall3(Callee, X, Y, Z); + + llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0); + llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1); + + llvm::Type *RealFlagType + = FlagOutPtr.first->getType()->getPointerElementType(); + + llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType); + llvm::StoreInst *FlagStore = Builder.CreateStore(FlagExt, FlagOutPtr.first); + FlagStore->setAlignment(FlagOutPtr.second); + return Result; + } default: + return nullptr; + } +} diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 1ce89642ff..e859a54118 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2249,6 +2249,7 @@ public: llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops); llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E); + llvm::Value *EmitR600BuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E); llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E); |