1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #ifndef _BUILTINSFRONTEND_H_
10 #define _BUILTINSFRONTEND_H_
11 
12 #include "common/LLVMWarningsPush.hpp"
13 #include <llvm/IR/Module.h>
14 #include <llvm/IR/LLVMContext.h>
15 #include <llvm/IR/Constants.h>
16 #include <llvm/IR/Intrinsics.h>
17 #include <llvm/Support/MemoryBuffer.h>
18 #include <llvm/Support/SourceMgr.h>
19 #include <llvm/AsmParser/Parser.h>
20 #include "common/LLVMWarningsPop.hpp"
21 #include "Compiler/CodeGenPublicEnums.h"
22 #include "inc/common/Compiler/API/SurfaceFormats.h"
23 #include "inc/common/igfxfmid.h"
24 #include "common/IGCIRBuilder.h"
25 #include "../common/EmUtils.h"
26 
27 struct genplatform
28 {
29 private:
30     const PLATFORM* m_platformInfo;
31 public:
genplatformgenplatform32     genplatform(const PLATFORM* platform) { m_platformInfo = platform; }
genplatformgenplatform33     genplatform() {}
GetPlatformFamilygenplatform34     GFXCORE_FAMILY GetPlatformFamily() const { return m_platformInfo->eRenderCoreFamily; }
hasHDCSupportForTypedReadsgenplatform35     bool hasHDCSupportForTypedReads() const { return m_platformInfo->eRenderCoreFamily >= IGFX_GEN10_CORE; }
36     bool hasHDCSupportForTypedReadsUnormSnormToFloatConversion() const;
37 };
38 
hasHDCSupportForTypedReadsUnormSnormToFloatConversion() const39 inline bool genplatform::hasHDCSupportForTypedReadsUnormSnormToFloatConversion() const
40 {
41     return m_platformInfo->eRenderCoreFamily >= IGFX_GEN10_CORE;
42 }
43 
44 
45 class SampleParamsFromCube
46 {
47 public:
48     llvm::Value* float_xcube;
49     llvm::Value* float_ycube;
50     llvm::Value* float_aicube;
51     llvm::Value* float_address_3;
52     llvm::Value* int32_textureIdx;
53     llvm::Value* int32_sampler;
54     llvm::Value* offsetU;
55     llvm::Value* offsetV;
56     llvm::Value* offsetR;
57 
get_float_xcube()58     llvm::Value* get_float_xcube() { return float_xcube; }
get_float_ycube()59     llvm::Value* get_float_ycube() { return float_ycube; }
get_float_aicube()60     llvm::Value* get_float_aicube() { return float_aicube; }
get_float_address_3()61     llvm::Value* get_float_address_3() { return float_address_3; }
get_int32_textureIdx()62     llvm::Value* get_int32_textureIdx() { return int32_textureIdx; }
get_int32_sampler()63     llvm::Value* get_int32_sampler() { return int32_sampler; }
get_offsetU()64     llvm::Value* get_offsetU() { return offsetU; }
get_offsetV()65     llvm::Value* get_offsetV() { return offsetV; }
get_offsetR()66     llvm::Value* get_offsetR() { return offsetR; }
67 
operator =(const SampleParamsFromCube & CUBE_params)68     void operator=(const SampleParamsFromCube &CUBE_params)
69     {
70         float_xcube = CUBE_params.float_xcube;
71         float_ycube = CUBE_params.float_ycube;
72         float_aicube = CUBE_params.float_aicube;
73         float_address_3 = CUBE_params.float_address_3;
74         int32_textureIdx = CUBE_params.int32_textureIdx;
75         int32_sampler = CUBE_params.int32_sampler;
76         offsetU = CUBE_params.offsetU;
77         offsetV = CUBE_params.offsetV;
78         offsetR = CUBE_params.offsetR;
79     }
80 };
81 
82 
83 
84 class SampleD_DC_FromCubeParams
85 {
86 public:
87     llvm::Value* float_src_u;
88     llvm::Value* dxu;
89     llvm::Value* dyu;
90     llvm::Value* float_src_v;
91     llvm::Value* dxv;
92     llvm::Value* dyv;
93     llvm::Value* float_src_r;
94     llvm::Value* dxr;
95     llvm::Value* dyr;
96     llvm::Value* float_src_ai;
97     llvm::Value* int32_textureIdx;
98     llvm::Value* int32_sampler;
99     llvm::Value* int32_offsetU;
100     llvm::Value* int32_offsetV;
101     llvm::Value* int32_offsetW;
102 
get_float_src_u()103     llvm::Value* get_float_src_u() { return float_src_u; }
get_dxu()104     llvm::Value* get_dxu() { return dxu; }
get_dyu()105     llvm::Value* get_dyu() { return dyu; }
get_float_src_v()106     llvm::Value* get_float_src_v() { return float_src_v; }
get_dxv()107     llvm::Value* get_dxv() { return dxv; }
get_dyv()108     llvm::Value* get_dyv() { return dyv; }
get_float_src_r()109     llvm::Value* get_float_src_r() { return float_src_r; }
get_dxr()110     llvm::Value* get_dxr() { return dxr; }
get_dyr()111     llvm::Value* get_dyr() { return dyr; }
get_float_src_ai()112     llvm::Value* get_float_src_ai() { return float_src_ai; }
get_int32_textureIdx()113     llvm::Value* get_int32_textureIdx() { return int32_textureIdx; }
get_int32_sampler()114     llvm::Value* get_int32_sampler() { return int32_sampler; }
get_int32_offsetU()115     llvm::Value* get_int32_offsetU() { return int32_offsetU; }
get_int32_offsetV()116     llvm::Value* get_int32_offsetV() { return int32_offsetV; }
get_int32_offsetW()117     llvm::Value* get_int32_offsetW() { return int32_offsetW; }
118 
operator =(const SampleD_DC_FromCubeParams & D_DC_CUBE_params)119     void operator=(const SampleD_DC_FromCubeParams &D_DC_CUBE_params)
120     {
121         float_src_u = D_DC_CUBE_params.float_src_u;
122         dxu = D_DC_CUBE_params.dxu;
123         dyu = D_DC_CUBE_params.dyu;
124         float_src_v = D_DC_CUBE_params.float_src_v;
125         dxv = D_DC_CUBE_params.dxv;
126         dyv = D_DC_CUBE_params.dyv;
127         float_src_r = D_DC_CUBE_params.float_src_r;
128         dxr = D_DC_CUBE_params.dxr;
129         dyr = D_DC_CUBE_params.dyr;
130         float_src_ai = D_DC_CUBE_params.float_src_ai;
131         int32_textureIdx = D_DC_CUBE_params.int32_textureIdx;
132         int32_sampler = D_DC_CUBE_params.int32_sampler;
133         int32_offsetU = D_DC_CUBE_params.int32_offsetU;
134         int32_offsetV = D_DC_CUBE_params.int32_offsetV;
135         int32_offsetW = D_DC_CUBE_params.int32_offsetW;
136     }
137 };
138 
139 
140 template<bool preserveNames = true, typename T = llvm::ConstantFolder,
141     typename InserterTyDef() = llvm::IRBuilderDefaultInserter>
142 class LLVM3DBuilder : public llvm::IGCIRBuilder<T, InserterTyDef()>
143 {
144 public:
LLVM3DBuilder(llvm::LLVMContext & pCtx,const PLATFORM & pPlatform)145     LLVM3DBuilder(llvm::LLVMContext &pCtx, const PLATFORM &pPlatform)
146         : llvm::IGCIRBuilder<T, InserterTyDef()>(pCtx),
147         m_Platform(new genplatform(&pPlatform))
148     {
149             Init();
150     }
151 
~LLVM3DBuilder()152     ~LLVM3DBuilder()
153     {
154         if (m_Platform)
155         {
156             delete m_Platform;
157             m_Platform = NULL;
158         }
159     }
160 
161     static unsigned EncodeASForGFXResource(
162         const llvm::Value& bufIdx,
163         IGC::BufferType bufType,
164         unsigned uniqueIndAS);
165 
166     llvm::Value* CreateFAbs(llvm::Value* V);
167     llvm::Value* CreateFSat(llvm::Value* V);
168     llvm::Value* CreateSqrt(llvm::Value* V);
169     llvm::Value* CreateDiscard(llvm::Value* V);
170     llvm::Value* CreateFLog(llvm::Value* V);
171     llvm::Value* CreateFExp(llvm::Value* V);
172     llvm::Value* CreateFloor(llvm::Value* V);
173     llvm::Value* CreateCeil(llvm::Value* V);
174     llvm::Value* CreateRoundZ(llvm::Value* V);
175     llvm::Value* CreateRoundNE(llvm::Value* V);
176     llvm::Value* CreateFPow(llvm::Value *LHS, llvm::Value *RHS);
177     llvm::Value* CreateFMax(llvm::Value *LHS, llvm::Value *RHS);
178     llvm::Value* CreateFMin(llvm::Value *LHS, llvm::Value *RHS);
179     llvm::Value* CreateIMulH(llvm::Value* LHS, llvm::Value* RHS);
180     llvm::Value* CreateUMulH(llvm::Value* LHS, llvm::Value* RHS);
181     llvm::Value* CreateDeriveRTX(llvm::Value* V);
182     llvm::Value* CreateDeriveRTX_Fine(llvm::Value* V);
183     llvm::Value* CreateDeriveRTY(llvm::Value* V);
184     llvm::Value* CreateDeriveRTY_Fine(llvm::Value* V);
185     llvm::Value* CreateSin(llvm::Value* V);
186     llvm::Value* CreateCos(llvm::Value* V);
187     llvm::Value* CreateIsNan(llvm::Value *V);
188     llvm::Value* CreateCtpop(llvm::Value* V);
189     llvm::Value* CreateFrc(llvm::Value* V);
190 
191     llvm::Value* CreateCPSRqstCoarseSize(
192                     llvm::Value* pSrcVal);
193     llvm::Value* CreateCPSActualCoarseSize(
194                     llvm::Value* pSrcVal);
195 
196     llvm::Value* getHalf(float f);
197     llvm::Value* getFloat(float f);
198     llvm::Value* getDouble(double d);
199     llvm::Value* CreatePow(llvm::Value* src0, llvm::Value* src1);
200 
201     llvm::Value* Create_MAD_Scalar(
202         llvm::Value* float_src0,
203         llvm::Value* float_src1,
204         llvm::Value* float_src2);
205 
206     llvm::Value* Create_resinfo(
207         llvm::Value* int32_src_s_mip,
208         llvm::Value* int32_textureIdx);
209 
210     llvm::Value* Create_resinfoptr_msaa(
211         llvm::Value* srcBuffer,
212         llvm::Value* float_src_s_mip);
213 
214     llvm::Value* CreateReadSurfaceInfo(llvm::Value* resource, llvm::Value* mimap);
215 
216     llvm::Value* Create_typedwrite(
217         llvm::Value* dstBuffer,
218         llvm::Value* srcAddressU,
219         llvm::Value* srcAddressV,
220         llvm::Value* srcAddressW,
221         llvm::Value* lod,
222         llvm::Value* float_X,
223         llvm::Value* float_Y,
224         llvm::Value* float_Z,
225         llvm::Value* float_W);
226 
227     llvm::Value* Create_typedread(
228         llvm::Value* dstBuffer,
229         llvm::Value* srcAddressU,
230         llvm::Value* srcAddressV,
231         llvm::Value* srcAddressW,
232         llvm::Value* lod);
233 
234     llvm::Value* Create_typedread_msaa2D(
235         llvm::Value* srcBuffer,
236         llvm::Value* sampleIdx,
237         llvm::Value* srcAddressU,
238         llvm::Value* srcAddressV,
239         llvm::Value* lod);
240 
241     llvm::Value* Create_typedread_msaa2DArray(
242         llvm::Value* srcBuffer,
243         llvm::Value* sampleIdx,
244         llvm::Value* srcAddressU,
245         llvm::Value* srcAddressV,
246         llvm::Value* srcAddressR,
247         llvm::Value* lod);
248 
249     llvm::Value* Create_typedwrite_msaa2D(
250         llvm::Value* dstBuffer,
251         llvm::Value* sampleIdx,
252         llvm::Value* srcAddressU,
253         llvm::Value* srcAddressV,
254         llvm::Value* float_X,
255         llvm::Value* float_Y,
256         llvm::Value* float_Z,
257         llvm::Value* float_W);
258 
259     llvm::Value* Create_typedwrite_msaa2DArray(
260         llvm::Value* dstBuffer,
261         llvm::Value* sampleIdx,
262         llvm::Value* srcAddressU,
263         llvm::Value* srcAddressV,
264         llvm::Value* srcAddressR,
265         llvm::Value* float_X,
266         llvm::Value* float_Y,
267         llvm::Value* float_Z,
268         llvm::Value* float_W);
269 
270     llvm::Value* Create_dwordatomictypedMsaa2D(
271         llvm::Value* dstBuffer,
272         llvm::Value* sampleIdx,
273         llvm::Value* srcAddressU,
274         llvm::Value* srcAddressV,
275         llvm::Value* src,
276         llvm::Value* instType);
277 
278     llvm::Value* Create_dwordatomictypedMsaa2DArray(
279         llvm::Value* dstBuffer,
280         llvm::Value* sampleIdx,
281         llvm::Value* srcAddressU,
282         llvm::Value* srcAddressV,
283         llvm::Value* srcAddressR,
284         llvm::Value* src,
285         llvm::Value* instType);
286 
287     llvm::Value* Create_cmpxchgatomictypedMsaa2D(
288         llvm::Value* dstBuffer,
289         llvm::Value* sampleIdx,
290         llvm::Value* srcAddressU,
291         llvm::Value* srcAddressV,
292         llvm::Value* src0,
293         llvm::Value* src1);
294 
295     llvm::Value* Create_cmpxchgatomictypedMsaa2DArray(
296         llvm::Value* dstBuffer,
297         llvm::Value* sampleIdx,
298         llvm::Value* srcAddressU,
299         llvm::Value* srcAddressV,
300         llvm::Value* srcAddressR,
301         llvm::Value* src0,
302         llvm::Value* src1);
303 
304     llvm::Value* Create_StatelessAtomic(
305         llvm::Value* ptr,
306         llvm::Value* data,
307         IGC::AtomicOp opcode);
308 
309     llvm::Value* Create_InidrectAtomic(
310         llvm::Value* resource,
311         llvm::Value* offset,
312         llvm::Value* data,
313         IGC::AtomicOp opcode);
314 
315     llvm::Value* Create_StatelessAtomicCmpXChg(
316         llvm::Value* ptr,
317         llvm::Value* data0,
318         llvm::Value* data1);
319 
320     llvm::Value* Create_InidrectAtomicCmpXChg(
321         llvm::Value* resource,
322         llvm::Value* offset,
323         llvm::Value* data0,
324         llvm::Value* data1);
325 
326     llvm::Value* Create_TypedAtomic(
327         llvm::Value* resource,
328         llvm::Value* addressU,
329         llvm::Value* addressV,
330         llvm::Value* addressR,
331         llvm::Value* data,
332         IGC::AtomicOp opcode);
333 
334     llvm::Value* Create_TypedAtomicCmpXChg(
335         llvm::Value* resource,
336         llvm::Value* addressU,
337         llvm::Value* addressV,
338         llvm::Value* addressR,
339         llvm::Value* data0,
340         llvm::Value* data1);
341 
342     llvm::CallInst* Create_SampleInfo(
343         llvm::Value* int32_resourceIdx);
344 
345     llvm::Value* Create_SamplePos(
346         llvm::Value* int32_resourceIdx,
347         llvm::Value* int32_samplerIdx);
348 
349     llvm::Value* Create_SyncThreadGroup();
350     llvm::Value* Create_FlushSampler();
351     llvm::Value* Create_MemoryFence(
352         bool commit,
353         bool flushRWDataCache,
354         bool flushConstantCache,
355         bool flushTextureCache,
356         bool flushInstructionCache,
357         bool globalFence);
358     llvm::Value* Create_GlobalSync();
359 
360     llvm::CallInst* Create_SAMPLE(
361         llvm::Value* coordinate_u,
362         llvm::Value* coordinate_v,
363         llvm::Value* coordinate_r,
364         llvm::Value* coordinate_ai,
365         llvm::Value* ptr_textureIdx,
366         llvm::Value* ptr_sampler,
367         llvm::Value* offsetU,
368         llvm::Value* offsetV,
369         llvm::Value* offsetW,
370         llvm::Value* minlod,
371         bool feedback_enabled = false,
372         llvm::Type* returnType = nullptr);
373 
374     SampleParamsFromCube Prepare_SAMPLE_Cube_ParamsFromUnormalizedCoords(
375         llvm::Value* int32_lod,
376         llvm::Value* int32_textureIdx,
377         llvm::Value* int32_u,
378         llvm::Value* int32_v,
379         llvm::Value* int32_faceid,
380         llvm::Value* int32_cube_array_index,
381         llvm::Value *float_array_6_3,
382         llvm::Value *int32_sampler);
383 
384     SampleParamsFromCube Prepare_SAMPLE_Cube_Params(
385         llvm::Value* float_address_0,
386         llvm::Value* float_address_1,
387         llvm::Value* float_address_2,
388         llvm::Value* float_address_3,
389         llvm::Value* int32_textureIdx,
390         llvm::Value* int32_sampler);
391 
392     llvm::CallInst* Create_SAMPLED(
393         SampleD_DC_FromCubeParams& sampleParams,
394         llvm::Value* minlod = nullptr,
395         bool feedback_enabled = false,
396         llvm::Type* returnType = nullptr);
397 
398     llvm::CallInst* Create_SAMPLED(
399         llvm::Value* float_src1_s_chan0,
400         llvm::Value* float_src1_s_chan1,
401         llvm::Value* float_src1_s_chan2,
402         llvm::Value* float_src2_s_chan0,
403         llvm::Value* float_src2_s_chan1,
404         llvm::Value* float_src2_s_chan2,
405         llvm::Value* float_src3_s_chan0,
406         llvm::Value* float_src3_s_chan1,
407         llvm::Value* float_src3_s_chan2,
408         llvm::Value* float_src1_s_chan3,
409         llvm::Value* int32_textureIdx_356,
410         llvm::Value* int32_sampler_357,
411         llvm::Value* int32_offsetU_358,
412         llvm::Value* int32_offsetV_359,
413         llvm::Value* int32_offsetW_359,
414         llvm::Value* minlod,
415         bool feedback_enabled = false,
416         llvm::Type* returnType = nullptr);
417 
418     llvm::CallInst* Create_SAMPLEDC(
419         llvm::Value* float_ref,
420         llvm::Value* float_src_u,
421         llvm::Value* dxu,
422         llvm::Value* dyu,
423         llvm::Value* float_src_v,
424         llvm::Value* dxv,
425         llvm::Value* dyv,
426         llvm::Value* float_src_r,
427         llvm::Value* dxr,
428         llvm::Value* dyr,
429         llvm::Value* float_src_ai,
430         llvm::Value* int32_textureIdx,
431         llvm::Value* int32_sampler,
432         llvm::Value* int32_offsetU,
433         llvm::Value* int32_offsetV,
434         llvm::Value* int32_offsetW,
435         llvm::Type* returnType = nullptr);
436 
437     SampleD_DC_FromCubeParams Prepare_SAMPLE_D_DC_Cube_Params(SampleD_DC_FromCubeParams& params);
438 
439     SampleD_DC_FromCubeParams Prepare_SAMPLE_D_DC_Cube_Params(
440         llvm::Value* float_src_x,
441         llvm::Value* float_src_y,
442         llvm::Value* float_src_z,
443         llvm::Value* float_src_ai,
444         llvm::Value* dxu,
445         llvm::Value* dyu,
446         llvm::Value* dzu,
447         llvm::Value* dxv,
448         llvm::Value* dyv,
449         llvm::Value* dzv,
450         llvm::Value* int32_textureIdx_356,
451         llvm::Value* int32_sampler_357,
452         llvm::Value* int32_offsetU_358,
453         llvm::Value* int32_offsetV_359,
454         llvm::Value* int32_offsetW_359);
455 
456     llvm::CallInst* Create_SAMPLEB(
457         llvm::Value* float_bias_0,
458         llvm::Value* float_address_0,
459         llvm::Value* float_address_1,
460         llvm::Value* float_address_2,
461         llvm::Value* float_address_3,
462         llvm::Value* int32_textureIdx,
463         llvm::Value* int32_sampler,
464         llvm::Value* int32_offsetU,
465         llvm::Value* int32_offsetV,
466         llvm::Value* int32_offsetW,
467         llvm::Value* minlod,
468         bool feedback_enabled = false,
469         llvm::Type* returnType = nullptr);
470 
471     llvm::CallInst* Create_SAMPLEL(
472         llvm::Value* float_lod_0,
473         llvm::Value* float_address_0,
474         llvm::Value* float_address_1,
475         llvm::Value* float_address_2,
476         llvm::Value* float_address_3,
477         llvm::Value* int32_textureIdx,
478         llvm::Value* int32_sampler,
479         llvm::Value* int32_offsetU,
480         llvm::Value* int32_offsetV,
481         llvm::Value* int32_offsetW,
482         bool feedback_enabled = false,
483         llvm::Type* returnType = nullptr);
484 
485     llvm::CallInst* Create_SAMPLEC(
486         llvm::Value* float_reference_0,
487         llvm::Value* float_address_0,
488         llvm::Value* float_address_1,
489         llvm::Value* float_address_2,
490         llvm::Value* float_address_3,
491         llvm::Value* int32_textureIdx,
492         llvm::Value* int32_sampler,
493         llvm::Value* int32_offsetU,
494         llvm::Value* int32_offsetV,
495         llvm::Value* int32_offsetR,
496         llvm::Value* minlod,
497         bool feedback_enabled = false,
498         llvm::Type* returnType = nullptr);
499 
500     llvm::CallInst* Create_SAMPLELC(
501         llvm::Value* float_reference_0,
502         llvm::Value* float_address_0,
503         llvm::Value* float_address_1,
504         llvm::Value* float_address_2,
505         llvm::Value* float_address_3,
506         llvm::Value* float_lod,
507         llvm::Value* int32_textureIdx,
508         llvm::Value* int32_sampler,
509         llvm::Value* int32_offsetU,
510         llvm::Value* int32_offsetV,
511         llvm::Value* int32_offsetW,
512         llvm::Type* returnType = nullptr);
513 
514     llvm::CallInst* Create_SAMPLEC_LZ(
515         llvm::Value* float_reference_0,
516         llvm::Value* float_address_0,
517         llvm::Value* float_address_1,
518         llvm::Value* float_address_2,
519         llvm::Value* float_address_3,
520         llvm::Value* int32_textureIdx,
521         llvm::Value* int32_sampler,
522         llvm::Value* int32_offsetU,
523         llvm::Value* int32_offsetV,
524         llvm::Value* int32_offsetW,
525         bool feedback_enabled = false,
526         llvm::Type* returnType = nullptr);
527 
528     llvm::CallInst* Create_lod(
529         llvm::Value* float_address_0,
530         llvm::Value* float_address_1,
531         llvm::Value* float_address_2,
532         llvm::Value* float_address_3,
533         llvm::Value* int32_textureIdx_356,
534         llvm::Value* int32_sampler_357,
535         llvm::Type* returnType = nullptr);
536 
537     llvm::CallInst* Create_gather4(
538         llvm::Value* float_address_0,
539         llvm::Value* float_address_1,
540         llvm::Value* float_address_2,
541         llvm::Value* float_address_3,
542         llvm::Value* int32_textureIdx_356,
543         llvm::Value* int32_sampler_357,
544         llvm::Value* int32_offsetU,
545         llvm::Value* int32_offsetV,
546         llvm::Value* int32_offsetW,
547         llvm::Value* int32_srcChannel,
548         bool feedback_enabled = false,
549         llvm::Type* returnType = nullptr);
550 
551     llvm::CallInst* Create_load(
552         llvm::Value* int32_sampleIdxU,
553         llvm::Value* int32_sampleIdxV,
554         llvm::Value* int32_sampleIdxR,
555         llvm::Value* int32_lod,
556         llvm::Value* ptr_textureIdx,
557         llvm::Value* int32_offsetU,
558         llvm::Value* int32_offsetV,
559         llvm::Value* int32_offsetR,
560         bool feedback_enabled = false,
561         llvm::Type* returnType = nullptr);
562 
563     llvm::CallInst* Create_ldms(
564         llvm::Value* int32_srcIdxU,
565         llvm::Value* int32_srcIdxV,
566         llvm::Value* int32_srcIdxR,
567         llvm::Value* int32_sampleIdx,
568         llvm::Value* int32_textureIdx,
569         llvm::Value* int32_offsetU,
570         llvm::Value* int32_offsetV,
571         llvm::Value* int32_offsetR,
572         bool feedback_enabled = false,
573         llvm::Type* returnType = nullptr);
574 
575     llvm::CallInst* Create_gather4C(
576         llvm::Value* float_reference_0,
577         llvm::Value* float_address_0,
578         llvm::Value* float_address_1,
579         llvm::Value* float_address_2,
580         llvm::Value* float_address_3,
581         llvm::Value* int32_textureIdx,
582         llvm::Value* int32_sampler,
583         llvm::Value* int32_offsetU,
584         llvm::Value* int32_offsetV,
585         llvm::Value* int32_srcChannel,
586         bool feedback_enabled = false,
587         llvm::Type* returnType = nullptr);
588 
589     llvm::CallInst* Create_gather4PO(
590         llvm::Value* float_address_0,
591         llvm::Value* float_address_1,
592         llvm::Value* float_address_2,
593         llvm::Value* float_src_offset_0,
594         llvm::Value* float_src_offset_1,
595         llvm::Value* int32_textureIdx,
596         llvm::Value* int32_sampler,
597         llvm::Value* int32_offsetU,
598         llvm::Value* int32_offsetV,
599         llvm::Value* int32_srcChannel,
600         bool feedback_enabled = false,
601         llvm::Type* returnType = nullptr);
602 
603     llvm::CallInst* Create_gather4POC(
604         llvm::Value* float_address_0,
605         llvm::Value* float_address_1,
606         llvm::Value* float_address_2,
607         llvm::Value* int_src_offset_0,
608         llvm::Value* int_src_offset_1,
609         llvm::Value* float_src_reference_0,
610         llvm::Value* int32_textureIdx,
611         llvm::Value* int32_sampler,
612         llvm::Value* int32_offsetU,
613         llvm::Value* int32_offsetV,
614         llvm::Value* int32_srcChannel,
615         bool feedback_enabled = false,
616         llvm::Type* returnType = nullptr);
617 
618     llvm::Value* Create_gather4PositionOffsets(
619         llvm::Value* float_address_0,
620         llvm::Value* float_address_1,
621         llvm::Value* float_address_2,
622         llvm::ArrayRef<llvm::Value *> int_src_offsets,
623         llvm::Value* int32_textureIdx_356,
624         llvm::Value* int32_sampler_357,
625         llvm::Value* int32_offsetU,
626         llvm::Value* int32_offsetV,
627         llvm::Value* int32_srcChannel);
628 
629     llvm::Value* Create_gather4PositionOffsetsC(
630         llvm::Value* float_reference_0,
631         llvm::Value* float_address_0,
632         llvm::Value* float_address_1,
633         llvm::Value* float_address_2,
634         llvm::ArrayRef<llvm::Value *> int_src_offsets,
635         llvm::Value* int32_textureIdx_356,
636         llvm::Value* int32_sampler_357,
637         llvm::Value* int32_offsetU,
638         llvm::Value* int32_offsetV,
639         llvm::Value* int32_srcChannel);
640 
641     llvm::CallInst* Create_SAMPLEBC(
642         llvm::Value* float_ref_value,
643         llvm::Value* bias_value,
644         llvm::Value* address_u,
645         llvm::Value* address_v,
646         llvm::Value* address_r,
647         llvm::Value* address_ai,
648         llvm::Value* int32_textureIdx,
649         llvm::Value* int32_sampler,
650         llvm::Value* int32_offsetU,
651         llvm::Value* int32_offsetV,
652         llvm::Value* int32_offsetW,
653         llvm::Type* returnType = nullptr);
654 
655     llvm::Value* create_indirectLoad(
656         llvm::Value* srcBuffer,
657         llvm::Value* offset,
658         llvm::Value* alignment,
659         llvm::Type* returnType,
660         bool isVolatile = false);
661 
662     llvm::Value* create_indirectStore(
663         llvm::Value* srcBuffer,
664         llvm::Value* offset,
665         llvm::Value* data,
666         bool isVolatile = false);
667 
668     llvm::Value* create_atomicCounterIncrement(llvm::Value* srcBuffer);
669     llvm::Value* create_atomicCounterDecrement(llvm::Value* srcBuffer);
670 
671     llvm::Value* createThreadLocalId(unsigned int dim);
672     llvm::Value* createGroupId(unsigned int dim);
673 
674     llvm::Value* CreateF16TOF32(
675         llvm::Value* f16_src);
676 
677     IGC::SURFACE_FORMAT GetSubstituteImageFormat(
678         const IGC::SURFACE_FORMAT format) const;
679 
680     llvm::Value* CreateImageDataConversion(
681         IGC::SURFACE_FORMAT format,
682         llvm::Value* data);
683 
684     llvm::Value* Create_UBFE(
685         llvm::Value* int32_width,
686         llvm::Value* int32_offset,
687         llvm::Value* int32_source);
688 
689     llvm::Value* Create_IBFE(
690         llvm::Value* int32_width,
691         llvm::Value* int32_offset,
692         llvm::Value* int32_source);
693 
694     llvm::Value* Create_BFI(
695         llvm::Value* int32_width,
696         llvm::Value* int32_offset,
697         llvm::Value* int32_source,
698         llvm::Value* int32_replace);
699 
700     llvm::Value* Create_BFREV(
701         llvm::Value* int32_source);
702 
703     llvm::Value* Create_FirstBitHi(
704         llvm::Value* int32_source);
705 
706     llvm::Value* Create_FirstBitLo(
707         llvm::Value* int32_source);
708 
709     llvm::Value* Create_FirstBitShi(
710         llvm::Value* int32_source);
711 
712     llvm::Value* CreateEvalSampleIndex(
713         llvm::Value* inputIndex,
714         llvm::Value* sampleIndex,
715         llvm::Value* perspective);
716 
717     llvm::Value* CreateEvalSnapped(
718         llvm::Value* inputIndex,
719         llvm::Value* xOffset,
720         llvm::Value* yOffset,
721         llvm::Value* perspective);
722 
723     llvm::Value* CreateSetStream(llvm::Value* StreamId, llvm::Value* emitCount);
724     llvm::Value* CreateEndPrimitive(llvm::Value* emitCount);
725 
726     llvm::Value* CreateControlPointId();
727     llvm::Value* CreatePrimitiveID();
728     llvm::Value* CreateInstanceID();
729     llvm::Value* CreateCoverage();
730     llvm::Value* CreateSampleIndex();
731     llvm::Value* CreateDomainPointInput(unsigned int dimension);
732     llvm::Value* create_inputVecF32(llvm::Value* inputIndex, llvm::Value* interpolationMode);
733     llvm::Value* create_uavSerializeAll();
734     llvm::Value* create_discard(llvm::Value* condition);
735     llvm::Value* create_runtime(llvm::Value* offset);
736     llvm::CallInst* create_countbits(llvm::Value* src);
737     llvm::Value* create_waveBallot(llvm::Value* src);
738     llvm::Value* create_waveInverseBallot(llvm::Value* src);
739     llvm::Value* create_waveshuffleIndex(llvm::Value* src, llvm::Value* index, llvm::Value* helperLaneMode = nullptr);
740     llvm::Value* create_waveAll(llvm::Value* src, llvm::Value* type);
741     llvm::Value* create_wavePrefix(
742         llvm::Value* src, llvm::Value* type, bool inclusive,
743         llvm::Value *Mask = nullptr);
744     llvm::Value* create_wavePrefixBitCount(
745         llvm::Value* src, llvm::Value *Mask = nullptr);
746     llvm::Value* create_waveMatch(llvm::Instruction *inst, llvm::Value *src);
747     llvm::Value* create_waveMultiPrefix(
748         llvm::Instruction *I,
749         llvm::Value *Val,
750         llvm::Value *Mask,
751         IGC::WaveOps OpKind);
752     llvm::Value* create_waveMultiPrefixBitCount(
753         llvm::Instruction *I,
754         llvm::Value *Val,
755         llvm::Value *Mask);
756     llvm::Value* create_quadPrefix(llvm::Value* src, llvm::Value* type, bool inclusive = false);
757     llvm::Value* get32BitLaneID();
758     llvm::Value* getSimdSize();
759     llvm::Value* getFirstLaneID();
760     llvm::Value* readFirstLane(llvm::Value* src);
761 
762     void VectorToScalars(
763         llvm::Value* vector,
764         llvm::Value** outScalars,
765         unsigned maxSize,
766         llvm::Value* initializer = nullptr);
767 
768     llvm::Value* ScalarsToVector(
769         llvm::Value* (&scalars)[4],
770         unsigned vectorElementCnt);
771 
772 private:
773 
774     /// @brief helper structure for keeping image format properties used by image read emulation
775     struct ImageFormatInfo
776     {
777         IGC::SURFACE_FORMAT m_Format; ///< original image format
778         unsigned            m_NumComponents; ///< number of components in the original format, only valid when m_RequiresConversion is true
779         unsigned            m_BPE; ///< number of bits per component in the original format, valid only if all components have the same, only valid when m_RequiresConversion is true
780         bool                m_RequiresConversion; ///< true if conversion is required
781         IGC::SURFACE_FORMAT m_SubstituteFormat; ///< image format programmed in the additional surface state, only valid when m_RequiresConversion is true
782         bool                m_Is128b; ///< true for 128 bit formats, only valid when m_RequiresConversion is true
783     };
784 
785     llvm::Constant* GetSnormFactor(unsigned bits);
786     llvm::Constant* GetUnormFactor(unsigned bits);
787 
788     bool NeedConversionFor128FormatRead(
789         IGC::SURFACE_FORMAT format) const;
790 
791     // these functions are taken from OCL builtins
792     llvm::Value* CreateDFloor(llvm::Value* val);
793     llvm::Value* CreateDTrunc(llvm::Value* val);
794     llvm::Value* CreateDCeil(llvm::Value* val);
795     llvm::Value* CreateDRoundNE(llvm::Value* val);
796 
797 
798     genplatform*         m_Platform;
799 
800     llvm::Function* llvm_GenISA_ubfe() const;
801 
802     llvm::Function* llvm_GenISA_ibfe() const;
803 
804     llvm::Function* llvm_GenISA_bfi() const;
805 
806     llvm::Function* llvm_GenISA_bfrev() const;
807 
808     llvm::Function* llvm_GenISA_firstbitHi() const;
809 
810     llvm::Function* llvm_GenISA_firstbitLo() const;
811 
812     llvm::Function* llvm_GenISA_firstbitShi() const;
813 
814     llvm::Function* llvm_GenISA_ld() const;
815 
816     llvm::Function* llvm_GenISA_ldms() const;
817 
818     llvm::Function* llvm_GenISA_ldmcs() const;
819 
820     llvm::Function* llvm_GenISA_sampleBC_v4f32_f32() const;
821 
822     llvm::ConstantInt* m_int0; // 0
823     llvm::ConstantInt* m_int1; // 1
824     llvm::ConstantInt* m_int2; // 2
825     llvm::ConstantInt* m_int3; // 3
826 
827 
828     llvm::ConstantFP* m_float0; // 0.0f
829     llvm::ConstantFP* m_float1; // 1.0f
830 
831     void Init();
832 };
833 
834 #include "BuiltinsFrontendDefinitions.hpp"
835 
836 
837 #endif
838