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
32public:
33enum 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
43protected:
44virtual Value* OFFSET_TO_NEXT_COMPONENT(Value* base, Constant* offset);
45void           AssertMemoryUsageParams(Value* ptr, MEM_CLIENT usage);
46
47public:
48virtual Value* GEP(Value* Ptr, Value* Idx, Type* Ty = nullptr, bool isReadOnly = true, const Twine& Name = "");
49virtual Value* GEP(Type* Ty, Value* Ptr, Value* Idx, const Twine& Name = "");
50virtual Value* GEP(Value* ptr, const std::initializer_list<Value*>& indexList, Type* Ty = nullptr);
51virtual Value*
52GEP(Value* ptr, const std::initializer_list<uint32_t>& indexList, Type* Ty = nullptr);
53
54Value* GEPA(Value* Ptr, ArrayRef<Value*> IdxList, const Twine& Name = "");
55Value* GEPA(Type* Ty, Value* Ptr, ArrayRef<Value*> IdxList, const Twine& Name = "");
56
57Value* IN_BOUNDS_GEP(Value* ptr, const std::initializer_list<Value*>& indexList);
58Value* IN_BOUNDS_GEP(Value* ptr, const std::initializer_list<uint32_t>& indexList);
59
60virtual LoadInst*
61                  LOAD(Value* Ptr, const char* Name, Type* Ty = nullptr, MEM_CLIENT usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
62virtual LoadInst* LOAD(Value*         Ptr,
63                       const Twine&   Name  = "",
64                       Type*          Ty    = nullptr,
65                       MEM_CLIENT usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
66virtual LoadInst*
67                  LOAD(Type* Ty, Value* Ptr, const Twine& Name = "", MEM_CLIENT usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
68virtual LoadInst* LOAD(Value*         Ptr,
69                       bool           isVolatile,
70                       const Twine&   Name  = "",
71                       Type*          Ty    = nullptr,
72                       MEM_CLIENT     usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
73virtual 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
79virtual 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
90virtual 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
95virtual 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
97virtual 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
102LoadInst*  LOADV(Value* BasePtr, const std::initializer_list<Value*>& offset, const llvm::Twine& name = "");
103StoreInst* STOREV(Value* Val, Value* BasePtr, const std::initializer_list<Value*>& offset);
104
105Value* MEM_ADD(Value*                                 i32Incr,
106               Value*                                 basePtr,
107               const std::initializer_list<uint32_t>& indices,
108               const llvm::Twine&                     name = "");
109
110void 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
118virtual 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
125void 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
133virtual 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
140void 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
148Value* GATHERPD(Value* src, Value* pBase, Value* indices, Value* mask, uint8_t scale = 1);
149
150Value* GATHER_PTR(Value* pVecSrcPtr, Value* pVecMask, Value* pVecPassthru);
151void SCATTER_PTR(Value* pVecDstPtr, Value* pVecSrc, Value* pVecMask);
152
153virtual void SCATTERPS(Value*         pDst,
154                       Value*         vSrc,
155                       Value*         vOffsets,
156                       Value*         vMask,
157                       MEM_CLIENT     usage = MEM_CLIENT::MEM_CLIENT_INTERNAL);
158
159void Shuffle8bpcGather4(const SWR_FORMAT_INFO& info,
160                        Value*                 vGatherInput,
161                        Value*                 vGatherOutput[],
162                        bool                   bPackedOutput);
163void Shuffle16bpcGather4(const SWR_FORMAT_INFO& info,
164                         Value*                 vGatherInput[],
165                         Value*                 vGatherOutput[],
166                         bool                   bPackedOutput);
167
168// Static stack allocations for scatter operations
169Value* pScatterStackSrc{nullptr};
170Value* pScatterStackOffsets{nullptr};
171