1 | //===------ CGBuiltin.h - Emit LLVM Code for builtins ---------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILTIN_H |
10 | #define LLVM_CLANG_LIB_CODEGEN_CGBUILTIN_H |
11 | |
12 | #include "CodeGenFunction.h" |
13 | |
14 | // Many of MSVC builtins are on x64, ARM and AArch64; to avoid repeating code, |
15 | // we handle them here. |
16 | enum class clang::CodeGen::CodeGenFunction::MSVCIntrin { |
17 | _BitScanForward, |
18 | _BitScanReverse, |
19 | _InterlockedAnd, |
20 | _InterlockedCompareExchange, |
21 | _InterlockedDecrement, |
22 | _InterlockedExchange, |
23 | _InterlockedExchangeAdd, |
24 | _InterlockedExchangeSub, |
25 | _InterlockedIncrement, |
26 | _InterlockedOr, |
27 | _InterlockedXor, |
28 | _InterlockedExchangeAdd_acq, |
29 | _InterlockedExchangeAdd_rel, |
30 | _InterlockedExchangeAdd_nf, |
31 | _InterlockedExchange_acq, |
32 | _InterlockedExchange_rel, |
33 | _InterlockedExchange_nf, |
34 | _InterlockedCompareExchange_acq, |
35 | _InterlockedCompareExchange_rel, |
36 | _InterlockedCompareExchange_nf, |
37 | _InterlockedCompareExchange128, |
38 | _InterlockedCompareExchange128_acq, |
39 | _InterlockedCompareExchange128_rel, |
40 | _InterlockedCompareExchange128_nf, |
41 | _InterlockedOr_acq, |
42 | _InterlockedOr_rel, |
43 | _InterlockedOr_nf, |
44 | _InterlockedXor_acq, |
45 | _InterlockedXor_rel, |
46 | _InterlockedXor_nf, |
47 | _InterlockedAnd_acq, |
48 | _InterlockedAnd_rel, |
49 | _InterlockedAnd_nf, |
50 | _InterlockedIncrement_acq, |
51 | _InterlockedIncrement_rel, |
52 | _InterlockedIncrement_nf, |
53 | _InterlockedDecrement_acq, |
54 | _InterlockedDecrement_rel, |
55 | _InterlockedDecrement_nf, |
56 | __fastfail, |
57 | }; |
58 | |
59 | // Emit a simple intrinsic that has N scalar arguments and a return type |
60 | // matching the argument type. It is assumed that only the first argument is |
61 | // overloaded. |
62 | template <unsigned N> |
63 | llvm::Value *emitBuiltinWithOneOverloadedType(clang::CodeGen::CodeGenFunction &CGF, |
64 | const clang::CallExpr *E, |
65 | unsigned IntrinsicID, |
66 | llvm::StringRef Name = "" ) { |
67 | static_assert(N, "expect non-empty argument" ); |
68 | clang::SmallVector<llvm::Value *, N> Args; |
69 | for (unsigned I = 0; I < N; ++I) |
70 | Args.push_back(CGF.EmitScalarExpr(E: E->getArg(Arg: I))); |
71 | llvm::Function *F = CGF.CGM.getIntrinsic(IID: IntrinsicID, Tys: Args[0]->getType()); |
72 | return CGF.Builder.CreateCall(F, Args, Name); |
73 | } |
74 | |
75 | llvm::Value *emitUnaryMaybeConstrainedFPBuiltin(clang::CodeGen::CodeGenFunction &CGF, |
76 | const clang::CallExpr *E, |
77 | unsigned IntrinsicID, |
78 | unsigned ConstrainedIntrinsicID); |
79 | |
80 | llvm::Value *EmitToInt(clang::CodeGen::CodeGenFunction &CGF, llvm::Value *V, |
81 | clang::QualType T, llvm::IntegerType *IntType); |
82 | |
83 | llvm::Value *EmitFromInt(clang::CodeGen::CodeGenFunction &CGF, llvm::Value *V, |
84 | clang::QualType T, llvm::Type *ResultType); |
85 | |
86 | clang::CodeGen::Address CheckAtomicAlignment(clang::CodeGen::CodeGenFunction &CGF, |
87 | const clang::CallExpr *E); |
88 | |
89 | llvm::Value *MakeBinaryAtomicValue(clang::CodeGen::CodeGenFunction &CGF, |
90 | llvm::AtomicRMWInst::BinOp Kind, |
91 | const clang::CallExpr *E, |
92 | llvm::AtomicOrdering Ordering = |
93 | llvm::AtomicOrdering::SequentiallyConsistent); |
94 | |
95 | llvm::Value *EmitOverflowIntrinsic(clang::CodeGen::CodeGenFunction &CGF, |
96 | const llvm::Intrinsic::ID IntrinsicID, |
97 | llvm::Value *X, |
98 | llvm::Value *Y, |
99 | llvm::Value *&Carry); |
100 | |
101 | llvm::Value *MakeAtomicCmpXchgValue(clang::CodeGen::CodeGenFunction &CGF, |
102 | const clang::CallExpr *E, |
103 | bool ReturnBool); |
104 | |
105 | #endif |
106 | |