diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-05-28 04:11:33 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-05-28 04:11:33 +0000 |
commit | 26c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267 (patch) | |
tree | d2aa93721a4453ba8124dd1713ee1591adb47cdb /lib/CodeGen | |
parent | 469244a322dd5d35cee1d02d70a2edbc12ac5ce7 (diff) |
Add support for ARM ldrexd/strexd builtins
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132249 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 9d6c20f12f..2f4104da93 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -1186,6 +1186,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))); |