1 /****************************************************************************
2 * Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * @file builder_misc.h
24 *
25 * @brief miscellaneous builder functions
26 *
27 * Notes:
28 *
29 ******************************************************************************/
30 #pragma once
31
32 Constant* C(bool i);
33 Constant* C(char i);
34 Constant* C(uint8_t i);
35 Constant* C(int i);
36 Constant* C(int64_t i);
37 Constant* C(uint64_t i);
38 Constant* C(uint16_t i);
39 Constant* C(uint32_t i);
40 Constant* C(float i);
41
42 template <typename Ty>
C(const std::initializer_list<Ty> & constList)43 Constant* C(const std::initializer_list<Ty>& constList)
44 {
45 std::vector<Constant*> vConsts;
46 for (auto i : constList)
47 {
48 vConsts.push_back(C((Ty)i));
49 }
50 return ConstantVector::get(vConsts);
51 }
52
53 template <typename Ty>
C(const std::vector<Ty> & constList)54 Constant* C(const std::vector<Ty>& constList)
55 {
56 std::vector<Constant*> vConsts;
57 for (auto i : constList)
58 {
59 vConsts.push_back(C((Ty)i));
60 }
61 return ConstantVector::get(vConsts);
62 }
63
64 template <typename Ty>
CA(LLVMContext & ctx,ArrayRef<Ty> constList)65 Constant* CA(LLVMContext& ctx, ArrayRef<Ty> constList)
66 {
67 return ConstantDataArray::get(ctx, constList);
68 }
69
70 template <typename Ty>
CInc(uint32_t base,uint32_t count)71 Constant* CInc(uint32_t base, uint32_t count)
72 {
73 std::vector<Constant*> vConsts;
74
75 for (uint32_t i = 0; i < count; i++)
76 {
77 vConsts.push_back(C((Ty)base));
78 base++;
79 }
80 return ConstantVector::get(vConsts);
81 }
82
83 Constant* PRED(bool pred);
84
85 Value* VIMMED1(uint64_t i);
86 Value* VIMMED1_16(uint64_t i);
87
88 Value* VIMMED1(int i);
89 Value* VIMMED1_16(int i);
90
91 Value* VIMMED1(uint32_t i);
92 Value* VIMMED1_16(uint32_t i);
93
94 Value* VIMMED1(float i);
95 Value* VIMMED1_16(float i);
96
97 Value* VIMMED1(bool i);
98 Value* VIMMED1_16(bool i);
99
100 Value* VUNDEF(Type* t);
101
102 Value* VUNDEF_F();
103 Value* VUNDEF_F_16();
104
105 Value* VUNDEF_I();
106 Value* VUNDEF_I_16();
107
108 Value* VUNDEF(Type* ty, uint32_t size);
109
110 Value* VUNDEF_IPTR();
111
112 Value* VBROADCAST(Value* src, const llvm::Twine& name = "");
113 Value* VBROADCAST_16(Value* src);
114
115 Value* VRCP(Value* va, const llvm::Twine& name = "");
116 Value* VPLANEPS(Value* vA, Value* vB, Value* vC, Value*& vX, Value*& vY);
117
118 uint32_t IMMED(Value* i);
119 int32_t S_IMMED(Value* i);
120
121 CallInst* CALL(Value* Callee, const std::initializer_list<Value*>& args, const llvm::Twine& name = "");
CALL(Value * Callee)122 CallInst* CALL(Value* Callee)
123 {
124 #if LLVM_VERSION_MAJOR >= 11
125 // Not a great idea - we loose type info (Function) calling CALL
126 // and then we recast it here. Good for now, but needs to be
127 // more clean - optimally just always CALL a Function
128 return CALLA(FunctionCallee(cast<Function>(Callee)));
129 #else
130 return CALLA(Callee);
131 #endif
132 }
133 CallInst* CALL(Value* Callee, Value* arg);
134 CallInst* CALL2(Value* Callee, Value* arg1, Value* arg2);
135 CallInst* CALL3(Value* Callee, Value* arg1, Value* arg2, Value* arg3);
136
137 Value* MASK(Value* vmask);
138 Value* MASK_16(Value* vmask);
139
140 Value* VMASK(Value* mask);
141 Value* VMASK_16(Value* mask);
142
143 Value* VMOVMSK(Value* mask);
144
145 //////////////////////////////////////////////////////////////////////////
146 /// @brief Float / Fixed-point conversions
147 //////////////////////////////////////////////////////////////////////////
148 // Signed
149 Value* VCVT_F32_FIXED_SI(Value* vFloat,
150 uint32_t numIntBits,
151 uint32_t numFracBits,
152 const llvm::Twine& name = "");
153 Value* VCVT_FIXED_SI_F32(Value* vFixed,
154 uint32_t numIntBits,
155 uint32_t numFracBits,
156 const llvm::Twine& name = "");
157 // Unsigned
158 Value* VCVT_F32_FIXED_UI(Value* vFloat,
159 uint32_t numIntBits,
160 uint32_t numFracBits,
161 const llvm::Twine& name = "");
162 Value* VCVT_FIXED_UI_F32(Value* vFixed,
163 uint32_t numIntBits,
164 uint32_t numFracBits,
165 const llvm::Twine& name = "");
166
167 //////////////////////////////////////////////////////////////////////////
168 /// @brief functions that build IR to call x86 intrinsics directly, or
169 /// emulate them with other instructions if not available on the host
170 //////////////////////////////////////////////////////////////////////////
171
172 Value* EXTRACT_16(Value* x, uint32_t imm);
173 Value* JOIN_16(Value* a, Value* b);
174
175 Value* PSHUFB(Value* a, Value* b);
176 Value* PMOVSXBD(Value* a);
177 Value* PMOVSXWD(Value* a);
178 Value* CVTPH2PS(Value* a, const llvm::Twine& name = "");
179 Value* CVTPS2PH(Value* a, Value* rounding);
180 Value* PMAXSD(Value* a, Value* b);
181 Value* PMINSD(Value* a, Value* b);
182 Value* PMAXUD(Value* a, Value* b);
183 Value* PMINUD(Value* a, Value* b);
184 Value* VABSPS(Value* a);
185 Value* FMADDPS(Value* a, Value* b, Value* c);
186
187 Value* ICLAMP(Value* src, Value* low, Value* high, const llvm::Twine& name = "");
188 Value* FCLAMP(Value* src, Value* low, Value* high);
189 Value* FCLAMP(Value* src, float low, float high);
190
191 CallInst* PRINT(const std::string& printStr);
192 CallInst* PRINT(const std::string& printStr, const std::initializer_list<Value*>& printArgs);
193
194 Value* VPOPCNT(Value* a);
195
INT3()196 Value* INT3()
197 {
198 return DEBUGTRAP();
199 }
200
201
202 Value* VEXTRACTI128(Value* a, Constant* imm8);
203 Value* VINSERTI128(Value* a, Value* b, Constant* imm8);
204
205 // rdtsc buckets macros
206 void RDTSC_START(Value* pBucketMgr, Value* pId);
207 void RDTSC_STOP(Value* pBucketMgr, Value* pId);
208
209 Value* CreateEntryAlloca(Function* pFunc, Type* pType);
210 Value* CreateEntryAlloca(Function* pFunc, Type* pType, Value* pArraySize);
211
212 uint32_t GetTypeSize(Type* pType);
213