summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorNemanja Ivanovic <nemanja.i.ibm@gmail.com>2015-07-05 06:40:52 +0000
committerNemanja Ivanovic <nemanja.i.ibm@gmail.com>2015-07-05 06:40:52 +0000
commit1c7ad715ecb5cda240fdaf5f595e268673d07d5d (patch)
tree2d90d1a4b9d56159e0abb290babcaa42b282020f /clang/lib/CodeGen
parentd358b8f80d50df6ded99fc03c35452c19ad36c3d (diff)
downloadbcm5719-llvm-1c7ad715ecb5cda240fdaf5f595e268673d07d5d.tar.gz
bcm5719-llvm-1c7ad715ecb5cda240fdaf5f595e268673d07d5d.zip
Add missing builtins to altivec.h for ABI compliance (vol. 2)
This patch corresponds to review: http://reviews.llvm.org/D10875 The bulk of the second round of additions to altivec.h. The following interfaces were added: vector double vec_floor(vector double) vector double vec_madd(vector double, vector double, vector double) vector float vec_msub(vector float, vector float, vector float) vector double vec_msub(vector double, vector double, vector double) vector float vec_mul(vector float, vector float) vector double vec_mul(vector double, vector double) vector float vec_nmadd(vector float, vector float, vector float) vector double vec_nmadd(vector double, vector double, vector double) vector double vec_nmsub(vector double, vector double, vector double) vector double vec_nor(vector double, vector double) vector double vec_or(vector double, vector double) vector float vec_rint(vector float) vector double vec_rint(vector double) vector float vec_nearbyint(vector float) vector double vec_nearbyint(vector double) vector float vec_sqrt(vector float) vector double vec_sqrt(vector double) vector double vec_rsqrte(vector double) vector double vec_sel(vector double, vector double, vector unsigned long long) vector double vec_sel(vector double, vector double, vector unsigned long long) vector double vec_sub(vector double, vector double) vector double vec_trunc(vector double) vector double vec_xor(vector double, vector double) vector double vec_xor(vector double, vector bool long long) vector double vec_xor(vector bool long long, vector double) New VSX paths for the following interfaces: vector float vec_madd(vector float, vector float, vector float) vector float vec_nmsub(vector float, vector float, vector float) vector float vec_rsqrte(vector float) vector float vec_trunc(vector float) vector float vec_floor(vector float) llvm-svn: 241399
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp71
1 files changed, 70 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 2ec909b9aac..68302041041 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -6633,14 +6633,83 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
llvm::Function *F = CGM.getIntrinsic(ID);
return Builder.CreateCall(F, Ops, "");
}
+ // Square root
+ case PPC::BI__builtin_vsx_xvsqrtsp:
+ case PPC::BI__builtin_vsx_xvsqrtdp: {
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *X = EmitScalarExpr(E->getArg(0));
+ ID = Intrinsic::sqrt;
+ llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
+ return Builder.CreateCall(F, X);
+ }
+ // Rounding/truncation
case PPC::BI__builtin_vsx_xvrspip:
case PPC::BI__builtin_vsx_xvrdpip:
+ case PPC::BI__builtin_vsx_xvrdpim:
+ case PPC::BI__builtin_vsx_xvrspim:
+ case PPC::BI__builtin_vsx_xvrdpi:
+ case PPC::BI__builtin_vsx_xvrspi:
+ case PPC::BI__builtin_vsx_xvrdpic:
+ case PPC::BI__builtin_vsx_xvrspic:
+ case PPC::BI__builtin_vsx_xvrdpiz:
+ case PPC::BI__builtin_vsx_xvrspiz: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *X = EmitScalarExpr(E->getArg(0));
- ID = Intrinsic::ceil;
+ if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim ||
+ BuiltinID == PPC::BI__builtin_vsx_xvrspim)
+ ID = Intrinsic::floor;
+ else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi ||
+ BuiltinID == PPC::BI__builtin_vsx_xvrspi)
+ ID = Intrinsic::round;
+ else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic ||
+ BuiltinID == PPC::BI__builtin_vsx_xvrspic)
+ ID = Intrinsic::nearbyint;
+ else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip ||
+ BuiltinID == PPC::BI__builtin_vsx_xvrspip)
+ ID = Intrinsic::ceil;
+ else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz ||
+ BuiltinID == PPC::BI__builtin_vsx_xvrspiz)
+ ID = Intrinsic::trunc;
llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
return Builder.CreateCall(F, X);
}
+ // FMA variations
+ case PPC::BI__builtin_vsx_xvmaddadp:
+ case PPC::BI__builtin_vsx_xvmaddasp:
+ case PPC::BI__builtin_vsx_xvnmaddadp:
+ case PPC::BI__builtin_vsx_xvnmaddasp:
+ case PPC::BI__builtin_vsx_xvmsubadp:
+ case PPC::BI__builtin_vsx_xvmsubasp:
+ case PPC::BI__builtin_vsx_xvnmsubadp:
+ case PPC::BI__builtin_vsx_xvnmsubasp: {
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *X = EmitScalarExpr(E->getArg(0));
+ Value *Y = EmitScalarExpr(E->getArg(1));
+ Value *Z = EmitScalarExpr(E->getArg(2));
+ Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
+ llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
+ switch (BuiltinID) {
+ case PPC::BI__builtin_vsx_xvmaddadp:
+ case PPC::BI__builtin_vsx_xvmaddasp:
+ return Builder.CreateCall(F, {X, Y, Z});
+ case PPC::BI__builtin_vsx_xvnmaddadp:
+ case PPC::BI__builtin_vsx_xvnmaddasp:
+ return Builder.CreateFSub(Zero,
+ Builder.CreateCall(F, {X, Y, Z}), "sub");
+ case PPC::BI__builtin_vsx_xvmsubadp:
+ case PPC::BI__builtin_vsx_xvmsubasp:
+ return Builder.CreateCall(F,
+ {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
+ case PPC::BI__builtin_vsx_xvnmsubadp:
+ case PPC::BI__builtin_vsx_xvnmsubasp:
+ Value *FsubRes =
+ Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
+ return Builder.CreateFSub(Zero, FsubRes, "sub");
+ }
+ llvm_unreachable("Unknown FMA operation");
+ return nullptr; // Suppress no-return warning
+ }
+ }
}
// Emit an intrinsic that has 1 float or double.
OpenPOWER on IntegriCloud