diff options
author | Joey Gouly <joey.gouly@arm.com> | 2013-09-18 10:07:09 +0000 |
---|---|---|
committer | Joey Gouly <joey.gouly@arm.com> | 2013-09-18 10:07:09 +0000 |
commit | 1e8637b259a3243efeb8966c349f02eda79ffb1a (patch) | |
tree | ffb1f7eb5d30085cc8a63b0f1977d002245e4196 /clang/lib/CodeGen | |
parent | 93183ee78c5850cc475f537ca14dd0a83c009bbf (diff) | |
download | bcm5719-llvm-1e8637b259a3243efeb8966c349f02eda79ffb1a.tar.gz bcm5719-llvm-1e8637b259a3243efeb8966c349f02eda79ffb1a.zip |
[ARMv8] Add builtins for CRC instructions.
Patch by Bradley Smith!
llvm-svn: 190931
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index e6cfe64471e..4b4c8f481cb 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2153,6 +2153,49 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, return Builder.CreateCall(F); } + // CRC32 + Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; + switch (BuiltinID) { + case ARM::BI__builtin_arm_crc32b: + CRCIntrinsicID = Intrinsic::arm_crc32b; break; + case ARM::BI__builtin_arm_crc32cb: + CRCIntrinsicID = Intrinsic::arm_crc32cb; break; + case ARM::BI__builtin_arm_crc32h: + CRCIntrinsicID = Intrinsic::arm_crc32h; break; + case ARM::BI__builtin_arm_crc32ch: + CRCIntrinsicID = Intrinsic::arm_crc32ch; break; + case ARM::BI__builtin_arm_crc32w: + case ARM::BI__builtin_arm_crc32d: + CRCIntrinsicID = Intrinsic::arm_crc32w; break; + case ARM::BI__builtin_arm_crc32cw: + case ARM::BI__builtin_arm_crc32cd: + CRCIntrinsicID = Intrinsic::arm_crc32cw; break; + } + + if (CRCIntrinsicID != Intrinsic::not_intrinsic) { + Value *Arg0 = EmitScalarExpr(E->getArg(0)); + Value *Arg1 = EmitScalarExpr(E->getArg(1)); + + // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w + // intrinsics, hence we need different codegen for these cases. + if (BuiltinID == ARM::BI__builtin_arm_crc32d || + BuiltinID == ARM::BI__builtin_arm_crc32cd) { + Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); + Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty); + Value *Arg1b = Builder.CreateLShr(Arg1, C1); + Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty); + + Function *F = CGM.getIntrinsic(CRCIntrinsicID); + Value *Res = Builder.CreateCall2(F, Arg0, Arg1a); + return Builder.CreateCall2(F, Res, Arg1b); + } else { + Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty); + + Function *F = CGM.getIntrinsic(CRCIntrinsicID); + return Builder.CreateCall2(F, Arg0, Arg1); + } + } + SmallVector<Value*, 4> Ops; llvm::Value *Align = 0; for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { |