summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAlbert Gutowski <agutowski@google.com>2016-09-08 22:32:19 +0000
committerAlbert Gutowski <agutowski@google.com>2016-09-08 22:32:19 +0000
commitb6a11acb533132bd1da786c73962ed8307b50ff7 (patch)
tree11bda798f5d3210955fe9c3e60a25db1f022148f /clang/lib
parentdec394935fb1415315d21b6de10ab0f1ea1772fe (diff)
downloadbcm5719-llvm-b6a11acb533132bd1da786c73962ed8307b50ff7.tar.gz
bcm5719-llvm-b6a11acb533132bd1da786c73962ed8307b50ff7.zip
Implement MS _rot intrinsics
Reviewers: thakis, Prazek, compnerd, rnk Subscribers: majnemer, cfe-commits Differential Revision: https://reviews.llvm.org/D24311 llvm-svn: 280997
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp52
-rw-r--r--clang/lib/Headers/intrin.h55
2 files changed, 52 insertions, 55 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index c06fcf73f37..d74f06cbc5c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -696,6 +696,58 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
"cast");
return RValue::get(Result);
}
+ case Builtin::BI_rotr8:
+ case Builtin::BI_rotr16:
+ case Builtin::BI_rotr:
+ case Builtin::BI_lrotr:
+ case Builtin::BI_rotr64: {
+ Value *Val = EmitScalarExpr(E->getArg(0));
+ Value *Shift = EmitScalarExpr(E->getArg(1));
+
+ llvm::Type *ArgType = Val->getType();
+ Shift = Builder.CreateIntCast(Shift, ArgType, false);
+ unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
+ Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth);
+ Value *ArgZero = llvm::Constant::getNullValue(ArgType);
+
+ Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
+ Shift = Builder.CreateAnd(Shift, Mask);
+ Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift);
+
+ Value *RightShifted = Builder.CreateLShr(Val, Shift);
+ Value *LeftShifted = Builder.CreateShl(Val, LeftShift);
+ Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted);
+
+ Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero);
+ Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated);
+ return RValue::get(Result);
+ }
+ case Builtin::BI_rotl8:
+ case Builtin::BI_rotl16:
+ case Builtin::BI_rotl:
+ case Builtin::BI_lrotl:
+ case Builtin::BI_rotl64: {
+ Value *Val = EmitScalarExpr(E->getArg(0));
+ Value *Shift = EmitScalarExpr(E->getArg(1));
+
+ llvm::Type *ArgType = Val->getType();
+ Shift = Builder.CreateIntCast(Shift, ArgType, false);
+ unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
+ Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth);
+ Value *ArgZero = llvm::Constant::getNullValue(ArgType);
+
+ Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
+ Shift = Builder.CreateAnd(Shift, Mask);
+ Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift);
+
+ Value *LeftShifted = Builder.CreateShl(Val, Shift);
+ Value *RightShifted = Builder.CreateLShr(Val, RightShift);
+ Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted);
+
+ Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero);
+ Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated);
+ return RValue::get(Result);
+ }
case Builtin::BI__builtin_unpredictable: {
// Always return the argument of __builtin_unpredictable. LLVM does not
// handle this builtin. Metadata for this builtin should be added directly
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index d68fdfc7a39..fed869beabe 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -447,61 +447,6 @@ __emulu(unsigned int __in1, unsigned int __in2) {
return (unsigned __int64)__in1 * (unsigned __int64)__in2;
}
/*----------------------------------------------------------------------------*\
-|* Bit Twiddling
-\*----------------------------------------------------------------------------*/
-static __inline__ unsigned char __DEFAULT_FN_ATTRS
-_rotl8(unsigned char _Value, unsigned char _Shift) {
- _Shift &= 0x7;
- return _Shift ? (_Value << _Shift) | (_Value >> (8 - _Shift)) : _Value;
-}
-static __inline__ unsigned char __DEFAULT_FN_ATTRS
-_rotr8(unsigned char _Value, unsigned char _Shift) {
- _Shift &= 0x7;
- return _Shift ? (_Value >> _Shift) | (_Value << (8 - _Shift)) : _Value;
-}
-static __inline__ unsigned short __DEFAULT_FN_ATTRS
-_rotl16(unsigned short _Value, unsigned char _Shift) {
- _Shift &= 0xf;
- return _Shift ? (_Value << _Shift) | (_Value >> (16 - _Shift)) : _Value;
-}
-static __inline__ unsigned short __DEFAULT_FN_ATTRS
-_rotr16(unsigned short _Value, unsigned char _Shift) {
- _Shift &= 0xf;
- return _Shift ? (_Value >> _Shift) | (_Value << (16 - _Shift)) : _Value;
-}
-static __inline__ unsigned int __DEFAULT_FN_ATTRS
-_rotl(unsigned int _Value, int _Shift) {
- _Shift &= 0x1f;
- return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value;
-}
-static __inline__ unsigned int __DEFAULT_FN_ATTRS
-_rotr(unsigned int _Value, int _Shift) {
- _Shift &= 0x1f;
- return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value;
-}
-static __inline__ unsigned long __DEFAULT_FN_ATTRS
-_lrotl(unsigned long _Value, int _Shift) {
- _Shift &= 0x1f;
- return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value;
-}
-static __inline__ unsigned long __DEFAULT_FN_ATTRS
-_lrotr(unsigned long _Value, int _Shift) {
- _Shift &= 0x1f;
- return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value;
-}
-static
-__inline__ unsigned __int64 __DEFAULT_FN_ATTRS
-_rotl64(unsigned __int64 _Value, int _Shift) {
- _Shift &= 0x3f;
- return _Shift ? (_Value << _Shift) | (_Value >> (64 - _Shift)) : _Value;
-}
-static
-__inline__ unsigned __int64 __DEFAULT_FN_ATTRS
-_rotr64(unsigned __int64 _Value, int _Shift) {
- _Shift &= 0x3f;
- return _Shift ? (_Value >> _Shift) | (_Value << (64 - _Shift)) : _Value;
-}
-/*----------------------------------------------------------------------------*\
|* Bit Counting and Testing
\*----------------------------------------------------------------------------*/
static __inline__ unsigned char __DEFAULT_FN_ATTRS
OpenPOWER on IntegriCloud