From: Bruno Cardoso Lopes Date: Sat, 28 May 2011 04:11:33 +0000 (+0000) Subject: Add support for ARM ldrexd/strexd builtins X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=26c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267;p=clang Add support for ARM ldrexd/strexd builtins git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132249 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def index 10cefbbdb6..888e529111 100644 --- a/include/clang/Basic/BuiltinsARM.def +++ b/include/clang/Basic/BuiltinsARM.def @@ -24,6 +24,10 @@ BUILTIN(__builtin_arm_qsub, "iii", "nc") BUILTIN(__builtin_arm_ssat, "iiUi", "nc") BUILTIN(__builtin_arm_usat, "UiUiUi", "nc") +// Store and load exclusive doubleword +BUILTIN(__builtin_arm_ldrexd, "LLUiv*", "") +BUILTIN(__builtin_arm_strexd, "iLLUiv*", "") + // VFP BUILTIN(__builtin_arm_get_fpscr, "Ui", "nc") BUILTIN(__builtin_arm_set_fpscr, "vUi", "nc") 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 Ops; for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) Ops.push_back(EmitScalarExpr(E->getArg(i)));