//===------ CGBuiltin.h - Emit LLVM Code for builtins ---------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILTIN_H #define LLVM_CLANG_LIB_CODEGEN_CGBUILTIN_H #include "CodeGenFunction.h" // Many of MSVC builtins are on x64, ARM and AArch64; to avoid repeating code, // we handle them here. enum class clang::CodeGen::CodeGenFunction::MSVCIntrin { _BitScanForward, _BitScanReverse, _InterlockedAnd, _InterlockedCompareExchange, _InterlockedDecrement, _InterlockedExchange, _InterlockedExchangeAdd, _InterlockedExchangeSub, _InterlockedIncrement, _InterlockedOr, _InterlockedXor, _InterlockedExchangeAdd_acq, _InterlockedExchangeAdd_rel, _InterlockedExchangeAdd_nf, _InterlockedExchange_acq, _InterlockedExchange_rel, _InterlockedExchange_nf, _InterlockedCompareExchange_acq, _InterlockedCompareExchange_rel, _InterlockedCompareExchange_nf, _InterlockedCompareExchange128, _InterlockedCompareExchange128_acq, _InterlockedCompareExchange128_rel, _InterlockedCompareExchange128_nf, _InterlockedOr_acq, _InterlockedOr_rel, _InterlockedOr_nf, _InterlockedXor_acq, _InterlockedXor_rel, _InterlockedXor_nf, _InterlockedAnd_acq, _InterlockedAnd_rel, _InterlockedAnd_nf, _InterlockedIncrement_acq, _InterlockedIncrement_rel, _InterlockedIncrement_nf, _InterlockedDecrement_acq, _InterlockedDecrement_rel, _InterlockedDecrement_nf, __fastfail, }; // Emit a simple intrinsic that has N scalar arguments and a return type // matching the argument type. It is assumed that only the first argument is // overloaded. template llvm::Value *emitBuiltinWithOneOverloadedType(clang::CodeGen::CodeGenFunction &CGF, const clang::CallExpr *E, unsigned IntrinsicID, llvm::StringRef Name = "") { static_assert(N, "expect non-empty argument"); clang::SmallVector Args; for (unsigned I = 0; I < N; ++I) Args.push_back(CGF.EmitScalarExpr(E->getArg(I))); llvm::Function *F = CGF.CGM.getIntrinsic(IntrinsicID, Args[0]->getType()); return CGF.Builder.CreateCall(F, Args, Name); } llvm::Value *emitUnaryMaybeConstrainedFPBuiltin(clang::CodeGen::CodeGenFunction &CGF, const clang::CallExpr *E, unsigned IntrinsicID, unsigned ConstrainedIntrinsicID); llvm::Value *EmitToInt(clang::CodeGen::CodeGenFunction &CGF, llvm::Value *V, clang::QualType T, llvm::IntegerType *IntType); llvm::Value *EmitFromInt(clang::CodeGen::CodeGenFunction &CGF, llvm::Value *V, clang::QualType T, llvm::Type *ResultType); clang::CodeGen::Address CheckAtomicAlignment(clang::CodeGen::CodeGenFunction &CGF, const clang::CallExpr *E); llvm::Value *MakeBinaryAtomicValue(clang::CodeGen::CodeGenFunction &CGF, llvm::AtomicRMWInst::BinOp Kind, const clang::CallExpr *E, llvm::AtomicOrdering Ordering = llvm::AtomicOrdering::SequentiallyConsistent); llvm::Value *EmitOverflowIntrinsic(clang::CodeGen::CodeGenFunction &CGF, const llvm::Intrinsic::ID IntrinsicID, llvm::Value *X, llvm::Value *Y, llvm::Value *&Carry); llvm::Value *MakeAtomicCmpXchgValue(clang::CodeGen::CodeGenFunction &CGF, const clang::CallExpr *E, bool ReturnBool); #endif