6ecd96978dd8f99fc83bafff680384a714f7afe1
[mesa.git] / src / gallium / drivers / swr / rasterizer / jitter / builder_gfx_mem.cpp
1 /****************************************************************************
2 * Copyright (C) 2014-2018 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_gfx_mem.cpp
24 *
25 * @brief Definition of the gfx mem builder
26 *
27 * Notes:
28 *
29 ******************************************************************************/
30 #include "jit_pch.hpp"
31 #include "builder.h"
32 #include "common/rdtsc_buckets.h"
33 #include "builder_gfx_mem.h"
34
35
36 namespace SwrJit
37 {
38 using namespace llvm;
39
40 BuilderGfxMem::BuilderGfxMem(JitManager* pJitMgr) :
41 Builder(pJitMgr)
42 {
43 mpTranslationFuncTy = nullptr;
44 mpfnTranslateGfxAddress = nullptr;
45 mpParamSimDC = nullptr;
46
47 }
48
49 void BuilderGfxMem::NotifyPrivateContextSet()
50 {
51 }
52
53 void BuilderGfxMem::AssertGFXMemoryParams(Value* ptr, Builder::JIT_MEM_CLIENT usage)
54 {
55 SWR_ASSERT(!(ptr->getType() == mInt64Ty && usage == MEM_CLIENT_INTERNAL), "Internal memory should not be gfxptr_t.");
56 }
57
58 //////////////////////////////////////////////////////////////////////////
59 /// @brief Generate a masked gather operation in LLVM IR. If not
60 /// supported on the underlying platform, emulate it with loads
61 /// @param vSrc - SIMD wide value that will be loaded if mask is invalid
62 /// @param pBase - Int8* base VB address pointer value
63 /// @param vIndices - SIMD wide value of VB byte offsets
64 /// @param vMask - SIMD wide mask that controls whether to access memory or the src values
65 /// @param scale - value to scale indices by
66 Value *BuilderGfxMem::GATHERPS(Value *vSrc, Value *pBase, Value *vIndices, Value *vMask, uint8_t scale, JIT_MEM_CLIENT usage)
67 {
68 Value *vGather;
69
70 // address may be coming in as 64bit int now so get the pointer
71 if (pBase->getType() == mInt64Ty)
72 {
73 pBase = INT_TO_PTR(pBase, PointerType::get(mInt8Ty, 0));
74 }
75
76 vGather = Builder::GATHERPS(vSrc, pBase, vIndices, vMask, scale);
77 return vGather;
78 }
79
80 //////////////////////////////////////////////////////////////////////////
81 /// @brief Generate a masked gather operation in LLVM IR. If not
82 /// supported on the underlying platform, emulate it with loads
83 /// @param vSrc - SIMD wide value that will be loaded if mask is invalid
84 /// @param pBase - Int8* base VB address pointer value
85 /// @param vIndices - SIMD wide value of VB byte offsets
86 /// @param vMask - SIMD wide mask that controls whether to access memory or the src values
87 /// @param scale - value to scale indices by
88 Value *BuilderGfxMem::GATHERDD(Value* vSrc, Value* pBase, Value* vIndices, Value* vMask, uint8_t scale, JIT_MEM_CLIENT usage)
89 {
90 Value* vGather = VIMMED1(0.0f);
91
92
93 // address may be coming in as 64bit int now so get the pointer
94 if (pBase->getType() == mInt64Ty)
95 {
96 pBase = INT_TO_PTR(pBase, PointerType::get(mInt8Ty, 0));
97 }
98
99 vGather = Builder::GATHERDD(vSrc, pBase, vIndices, vMask, scale);
100 return vGather;
101 }
102
103
104 Value* BuilderGfxMem::OFFSET_TO_NEXT_COMPONENT(Value* base, Constant *offset)
105 {
106 return ADD(base, offset);
107 }
108
109 Value *BuilderGfxMem::GEP(Value *Ptr, Value *Idx, Type *Ty, const Twine &Name)
110 {
111 Ptr = TranslationHelper(Ptr, Ty);
112 return Builder::GEP(Ptr, Idx, nullptr, Name);
113 }
114
115 Value *BuilderGfxMem::GEP(Type *Ty, Value *Ptr, Value *Idx, const Twine &Name)
116 {
117 Ptr = TranslationHelper(Ptr, Ty);
118 return Builder::GEP(Ty, Ptr, Idx, Name);
119 }
120
121 Value *BuilderGfxMem::GEP(Value* Ptr, const std::initializer_list<Value*> &indexList, Type *Ty)
122 {
123 Ptr = TranslationHelper(Ptr, Ty);
124 return Builder::GEP(Ptr, indexList);
125 }
126
127 Value *BuilderGfxMem::GEP(Value* Ptr, const std::initializer_list<uint32_t> &indexList, Type *Ty)
128 {
129 Ptr = TranslationHelper(Ptr, Ty);
130 return Builder::GEP(Ptr, indexList);
131 }
132
133 Value* BuilderGfxMem::TranslationHelper(Value *Ptr, Type *Ty)
134 {
135 SWR_ASSERT(!(Ptr->getType() == mInt64Ty && Ty == nullptr), "Access of GFX pointers must have non-null type specified.");
136
137
138 // address may be coming in as 64bit int now so get the pointer
139 if (Ptr->getType() == mInt64Ty)
140 {
141 Ptr = INT_TO_PTR(Ptr, Ty);
142 }
143
144 return Ptr;
145 }
146
147 LoadInst* BuilderGfxMem::LOAD(Value *Ptr, const char *Name, Type *Ty, JIT_MEM_CLIENT usage)
148 {
149 AssertGFXMemoryParams(Ptr, usage);
150
151 Ptr = TranslationHelper(Ptr, Ty);
152 return Builder::LOAD(Ptr, Name);
153 }
154
155 LoadInst* BuilderGfxMem::LOAD(Value *Ptr, const Twine &Name, Type *Ty, JIT_MEM_CLIENT usage)
156 {
157 AssertGFXMemoryParams(Ptr, usage);
158
159 Ptr = TranslationHelper(Ptr, Ty);
160 return Builder::LOAD(Ptr, Name);
161 }
162
163 LoadInst* BuilderGfxMem::LOAD(Type *Ty, Value *Ptr, const Twine &Name, JIT_MEM_CLIENT usage)
164 {
165 AssertGFXMemoryParams(Ptr, usage);
166
167 Ptr = TranslationHelper(Ptr, Ty);
168 return Builder::LOAD(Ty, Ptr, Name);
169 }
170
171 LoadInst* BuilderGfxMem::LOAD(Value *Ptr, bool isVolatile, const Twine &Name, Type *Ty, JIT_MEM_CLIENT usage)
172 {
173 AssertGFXMemoryParams(Ptr, usage);
174
175 Ptr = TranslationHelper(Ptr, Ty);
176 return Builder::LOAD(Ptr, isVolatile, Name);
177 }
178
179 LoadInst *BuilderGfxMem::LOAD(Value *BasePtr, const std::initializer_list<uint32_t> &offset, const llvm::Twine& name, Type *Ty, JIT_MEM_CLIENT usage)
180 {
181 AssertGFXMemoryParams(BasePtr, usage);
182
183 // This call is just a pass through to the base class.
184 // It needs to be here to compile due to the combination of virtual overrides and signature overloads.
185 // It doesn't do anything meaningful because the implementation in the base class is going to call
186 // another version of LOAD inside itself where the actual per offset translation will take place
187 // and we can't just translate the BasePtr once, each address needs individual translation.
188 return Builder::LOAD(BasePtr, offset, name, Ty, usage);
189 }
190
191 CallInst* BuilderGfxMem::MASKED_LOAD(Value *Ptr, unsigned Align, Value *Mask, Value *PassThru, const Twine &Name, Type *Ty, JIT_MEM_CLIENT usage)
192 {
193 AssertGFXMemoryParams(Ptr, usage);
194
195 Ptr = TranslationHelper(Ptr, Ty);
196 return Builder::MASKED_LOAD(Ptr, Align, Mask, PassThru, Name, Ty, usage);
197 }
198
199 Value* BuilderGfxMem::TranslateGfxAddress(Value* xpGfxAddress)
200 {
201 return INT_TO_PTR(xpGfxAddress, PointerType::get(mInt8Ty, 0));
202 }
203 }