diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp | 59 |
1 files changed, 49 insertions, 10 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp index 7a0c8da50248..14bebaf3c1cb 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp @@ -164,9 +164,8 @@ static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) { } // The prototype is something that takes and returns whatever V's type is. - std::vector<const llvm::Type*> Args; - Args.push_back(V->getType()); - llvm::FunctionType *FT = llvm::FunctionType::get(V->getType(), Args, false); + llvm::FunctionType *FT = llvm::FunctionType::get(V->getType(), V->getType(), + false); llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(FT, FnName); return CGF.Builder.CreateCall(Fn, V, "abs"); @@ -1186,6 +1185,41 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, Ops.begin(), Ops.end()); } + if (BuiltinID == ARM::BI__builtin_arm_ldrexd) { + Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); + + Value *LdPtr = EmitScalarExpr(E->getArg(0)); + Value *Val = Builder.CreateCall(F, LdPtr, "ldrexd"); + + Value *Val0 = Builder.CreateExtractValue(Val, 1); + Value *Val1 = Builder.CreateExtractValue(Val, 0); + Val0 = Builder.CreateZExt(Val0, Int64Ty); + Val1 = Builder.CreateZExt(Val1, Int64Ty); + + Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); + Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); + return Builder.CreateOr(Val, Val1); + } + + if (BuiltinID == ARM::BI__builtin_arm_strexd) { + Function *F = CGM.getIntrinsic(Intrinsic::arm_strexd); + llvm::Type *STy = llvm::StructType::get(getLLVMContext(), Int32Ty, Int32Ty, + NULL); + + Value *One = llvm::ConstantInt::get(Int32Ty, 1); + Value *Tmp = Builder.CreateAlloca(Int64Ty, One, "tmp"); + Value *Val = EmitScalarExpr(E->getArg(0)); + Builder.CreateStore(Val, Tmp); + + Value *LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); + Val = Builder.CreateLoad(LdPtr); + + Value *Arg0 = Builder.CreateExtractValue(Val, 0); + Value *Arg1 = Builder.CreateExtractValue(Val, 1); + Value *StPtr = EmitScalarExpr(E->getArg(1)); + return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "strexd"); + } + llvm::SmallVector<Value*, 4> Ops; for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) Ops.push_back(EmitScalarExpr(E->getArg(i))); @@ -2143,16 +2177,21 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. return llvm::Constant::getNullValue(ConvertType(E->getType())); } - case X86::BI__builtin_ia32_loaddqu: { - const llvm::Type *VecTy = ConvertType(E->getType()); - const llvm::Type *IntTy = llvm::IntegerType::get(getLLVMContext(), 128); + case X86::BI__builtin_ia32_movntps: + case X86::BI__builtin_ia32_movntpd: + case X86::BI__builtin_ia32_movntdq: + case X86::BI__builtin_ia32_movnti: { + llvm::MDNode *Node = llvm::MDNode::get(getLLVMContext(), + Builder.getInt32(1)); + // Convert the type of the pointer to a pointer to the stored type. Value *BC = Builder.CreateBitCast(Ops[0], - llvm::PointerType::getUnqual(IntTy), + llvm::PointerType::getUnqual(Ops[1]->getType()), "cast"); - LoadInst *LI = Builder.CreateLoad(BC); - LI->setAlignment(1); // Unaligned load. - return Builder.CreateBitCast(LI, VecTy, "loadu.cast"); + StoreInst *SI = Builder.CreateStore(Ops[1], BC); + SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); + SI->setAlignment(16); + return SI; } // 3DNow! case X86::BI__builtin_ia32_pavgusb: |