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 public:
33 enum class MEM_CLIENT
34 {
35     MEM_CLIENT_INTERNAL,
36     GFX_MEM_CLIENT_FETCH,
37     GFX_MEM_CLIENT_SAMPLER,
38     GFX_MEM_CLIENT_SHADER,
39     GFX_MEM_CLIENT_STREAMOUT,
40     GFX_MEM_CLIENT_URB
41 };
42 
43 protected:
44 virtual Value* OFFSET_TO_NEXT_COMPONENT(Value* base, Constant* offset);
45 void           AssertMemoryUsageParams(Value* ptr, MEM_CLIENT usage);
46 
47 public:
48 virtual Value* GEP(Value* Ptr, Value* Idx, Type* Ty = nullptr, bool isReadOnly = true, const Twine& Name = "");
49 virtual Value* GEP(Type* Ty, Value* Ptr, Value* Idx, const Twine& Name = "");
50 virtual Value* GEP(Value* ptr, const std::initializer_list<Value*>& indexList, Type* Ty = nullptr);
51 virtual Value*
52 GEP(Value* ptr, const std::initializer_list<uint32_t>& indexList, Type* Ty = nullptr);
53 
54 Value* GEPA(Value* Ptr, ArrayRef<Value*> IdxList, const Twine& Name = "");
55 Value* GEPA(Type* Ty, Value* Ptr, ArrayRef<Value*> IdxList, const Twine& Name = "");
56 
57 Value* IN_BOUNDS_GEP(Value* ptr, const std::initializer_list<Value*>& indexList);
58 Value* IN_BOUNDS_GEP(Value* ptr, const std::initializer_list<uint32_t>& indexList);
59 
60 virtual LoadInst*
61                   LOAD(Value* Ptr, const char* Name, Type* Ty = nullptr, MEM_CLIENT usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
62 virtual LoadInst* LOAD(Value*         Ptr,
63                        const Twine&   Name  = "",
64                        Type*          Ty    = nullptr,
65                        MEM_CLIENT usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
66 virtual LoadInst*
67                   LOAD(Type* Ty, Value* Ptr, const Twine& Name = "", MEM_CLIENT usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
68 virtual LoadInst* LOAD(Value*         Ptr,
69                        bool           isVolatile,
70                        const Twine&   Name  = "",
71                        Type*          Ty    = nullptr,
72                        MEM_CLIENT     usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
73 virtual LoadInst* LOAD(Value*                                 BasePtr,
74                        const std::initializer_list<uint32_t>& offset,
75                        const llvm::Twine&                     Name  = "",
76                        Type*                                  Ty    = nullptr,
77                        MEM_CLIENT                             usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
78 
79 virtual CallInst* MASKED_LOAD(Value*         Ptr,
80                               unsigned       Align,
81                               Value*         Mask,
82                               Value*         PassThru = nullptr,
83                               const Twine&   Name     = "",
84                               Type*          Ty       = nullptr,
85                               MEM_CLIENT usage    = MEM_CLIENT::MEM_CLIENT_INTERNAL)
86 {
87     return IRB()->CreateMaskedLoad(Ptr, AlignType(Align), Mask, PassThru, Name);
88 }
89 
90 virtual StoreInst* STORE(Value *Val, Value *Ptr, bool isVolatile = false, Type* Ty = nullptr, MEM_CLIENT usage = MEM_CLIENT::MEM_CLIENT_INTERNAL)
91 {
92     return IRB()->CreateStore(Val, Ptr, isVolatile);
93 }
94 
95 virtual StoreInst* STORE(Value* Val, Value* BasePtr, const std::initializer_list<uint32_t>& offset, Type* Ty = nullptr, MEM_CLIENT usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
96 
97 virtual CallInst* MASKED_STORE(Value *Val, Value *Ptr, unsigned Align, Value *Mask, Type* Ty = nullptr, MEM_CLIENT usage = MEM_CLIENT::MEM_CLIENT_INTERNAL)
98 {
99     return IRB()->CreateMaskedStore(Val, Ptr, AlignType(Align), Mask);
100 }
101 
102 LoadInst*  LOADV(Value* BasePtr, const std::initializer_list<Value*>& offset, const llvm::Twine& name = "");
103 StoreInst* STOREV(Value* Val, Value* BasePtr, const std::initializer_list<Value*>& offset);
104 
105 Value* MEM_ADD(Value*                                 i32Incr,
106                Value*                                 basePtr,
107                const std::initializer_list<uint32_t>& indices,
108                const llvm::Twine&                     name = "");
109 
110 void Gather4(const SWR_FORMAT format,
111              Value*           pSrcBase,
112              Value*           byteOffsets,
113              Value*           mask,
114              Value*           vGatherComponents[],
115              bool             bPackedOutput,
116              MEM_CLIENT       usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
117 
118 virtual Value* GATHERPS(Value*         src,
119                         Value*         pBase,
120                         Value*         indices,
121                         Value*         mask,
122                         uint8_t        scale = 1,
123                         MEM_CLIENT     usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
124 
125 void GATHER4PS(const SWR_FORMAT_INFO& info,
126                Value*                 pSrcBase,
127                Value*                 byteOffsets,
128                Value*                 mask,
129                Value*                 vGatherComponents[],
130                bool                   bPackedOutput,
131                MEM_CLIENT             usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
132 
133 virtual Value* GATHERDD(Value*         src,
134                         Value*         pBase,
135                         Value*         indices,
136                         Value*         mask,
137                         uint8_t        scale = 1,
138                         MEM_CLIENT     usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
139 
140 void GATHER4DD(const SWR_FORMAT_INFO& info,
141                Value*                 pSrcBase,
142                Value*                 byteOffsets,
143                Value*                 mask,
144                Value*                 vGatherComponents[],
145                bool                   bPackedOutput,
146                MEM_CLIENT             usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
147 
148 Value* GATHERPD(Value* src, Value* pBase, Value* indices, Value* mask, uint8_t scale = 1);
149 
150 Value* GATHER_PTR(Value* pVecSrcPtr, Value* pVecMask, Value* pVecPassthru);
151 void SCATTER_PTR(Value* pVecDstPtr, Value* pVecSrc, Value* pVecMask);
152 
153 virtual void SCATTERPS(Value*         pDst,
154                        Value*         vSrc,
155                        Value*         vOffsets,
156                        Value*         vMask,
157                        MEM_CLIENT     usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
158 
159 void Shuffle8bpcGather4(const SWR_FORMAT_INFO& info,
160                         Value*                 vGatherInput,
161                         Value*                 vGatherOutput[],
162                         bool                   bPackedOutput);
163 void Shuffle16bpcGather4(const SWR_FORMAT_INFO& info,
164                          Value*                 vGatherInput[],
165                          Value*                 vGatherOutput[],
166                          bool                   bPackedOutput);
167 
168 // Static stack allocations for scatter operations
169 Value* pScatterStackSrc{nullptr};
170 Value* pScatterStackOffsets{nullptr};
171