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