diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 77 |
1 files changed, 40 insertions, 37 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index abcd1d45969..5b8a272d589 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1647,6 +1647,46 @@ 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 = ArgType->getIntegerBitWidth(); + Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); + + Value *RightShiftAmt = Builder.CreateAnd(Shift, Mask); + Value *RightShifted = Builder.CreateLShr(Val, RightShiftAmt); + Value *LeftShiftAmt = Builder.CreateAnd(Builder.CreateNeg(Shift), Mask); + Value *LeftShifted = Builder.CreateShl(Val, LeftShiftAmt); + Value *Result = Builder.CreateOr(LeftShifted, RightShifted); + 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 = ArgType->getIntegerBitWidth(); + Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); + + Value *LeftShiftAmt = Builder.CreateAnd(Shift, Mask); + Value *LeftShifted = Builder.CreateShl(Val, LeftShiftAmt); + Value *RightShiftAmt = Builder.CreateAnd(Builder.CreateNeg(Shift), Mask); + Value *RightShifted = Builder.CreateLShr(Val, RightShiftAmt); + Value *Result = Builder.CreateOr(LeftShifted, RightShifted); + 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 @@ -1701,43 +1741,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, case Builtin::BI__builtin_bitreverse64: { return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bitreverse)); } - case Builtin::BI__builtin_rotateleft8: - case Builtin::BI__builtin_rotateleft16: - case Builtin::BI__builtin_rotateleft32: - case Builtin::BI__builtin_rotateleft64: - case Builtin::BI_rotl8: // Microsoft variants of rotate left - case Builtin::BI_rotl16: - case Builtin::BI_rotl: - case Builtin::BI_lrotl: - case Builtin::BI_rotl64: { - llvm::Value *Src = EmitScalarExpr(E->getArg(0)); - llvm::Value *ShiftAmt = EmitScalarExpr(E->getArg(1)); - // The builtin's shift arg may have a different type than the source arg and - // result, but the LLVM intrinsic uses the same type for all values. - llvm::Type *Ty = Src->getType(); - ShiftAmt = Builder.CreateIntCast(ShiftAmt, Ty, false); - Value *F = CGM.getIntrinsic(Intrinsic::fshl, Ty); - return RValue::get(Builder.CreateCall(F, { Src, Src, ShiftAmt })); - } - case Builtin::BI__builtin_rotateright8: - case Builtin::BI__builtin_rotateright16: - case Builtin::BI__builtin_rotateright32: - case Builtin::BI__builtin_rotateright64: - case Builtin::BI_rotr8: // Microsoft variants of rotate right - case Builtin::BI_rotr16: - case Builtin::BI_rotr: - case Builtin::BI_lrotr: - case Builtin::BI_rotr64: { - llvm::Value *Src = EmitScalarExpr(E->getArg(0)); - llvm::Value *ShiftAmt = EmitScalarExpr(E->getArg(1)); - // The builtin's shift arg may have a different type than the source arg and - // result, but the LLVM intrinsic uses the same type for all values. - llvm::Type *Ty = Src->getType(); - ShiftAmt = Builder.CreateIntCast(ShiftAmt, Ty, false); - Value *F = CGM.getIntrinsic(Intrinsic::fshr, Ty); - return RValue::get(Builder.CreateCall(F, { Src, Src, ShiftAmt })); - } - case Builtin::BI__builtin_object_size: { unsigned Type = E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue(); |