6ecd96978dd8f99fc83bafff680384a714f7afe1
1 /****************************************************************************
2 * Copyright (C) 2014-2018 Intel Corporation. All Rights Reserved.
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:
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
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
23 * @file builder_gfx_mem.cpp
25 * @brief Definition of the gfx mem builder
29 ******************************************************************************/
30 #include "jit_pch.hpp"
32 #include "common/rdtsc_buckets.h"
33 #include "builder_gfx_mem.h"
40 BuilderGfxMem::BuilderGfxMem(JitManager
* pJitMgr
) :
43 mpTranslationFuncTy
= nullptr;
44 mpfnTranslateGfxAddress
= nullptr;
45 mpParamSimDC
= nullptr;
49 void BuilderGfxMem::NotifyPrivateContextSet()
53 void BuilderGfxMem::AssertGFXMemoryParams(Value
* ptr
, Builder::JIT_MEM_CLIENT usage
)
55 SWR_ASSERT(!(ptr
->getType() == mInt64Ty
&& usage
== MEM_CLIENT_INTERNAL
), "Internal memory should not be gfxptr_t.");
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
)
70 // address may be coming in as 64bit int now so get the pointer
71 if (pBase
->getType() == mInt64Ty
)
73 pBase
= INT_TO_PTR(pBase
, PointerType::get(mInt8Ty
, 0));
76 vGather
= Builder::GATHERPS(vSrc
, pBase
, vIndices
, vMask
, scale
);
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
)
90 Value
* vGather
= VIMMED1(0.0f
);
93 // address may be coming in as 64bit int now so get the pointer
94 if (pBase
->getType() == mInt64Ty
)
96 pBase
= INT_TO_PTR(pBase
, PointerType::get(mInt8Ty
, 0));
99 vGather
= Builder::GATHERDD(vSrc
, pBase
, vIndices
, vMask
, scale
);
104 Value
* BuilderGfxMem::OFFSET_TO_NEXT_COMPONENT(Value
* base
, Constant
*offset
)
106 return ADD(base
, offset
);
109 Value
*BuilderGfxMem::GEP(Value
*Ptr
, Value
*Idx
, Type
*Ty
, const Twine
&Name
)
111 Ptr
= TranslationHelper(Ptr
, Ty
);
112 return Builder::GEP(Ptr
, Idx
, nullptr, Name
);
115 Value
*BuilderGfxMem::GEP(Type
*Ty
, Value
*Ptr
, Value
*Idx
, const Twine
&Name
)
117 Ptr
= TranslationHelper(Ptr
, Ty
);
118 return Builder::GEP(Ty
, Ptr
, Idx
, Name
);
121 Value
*BuilderGfxMem::GEP(Value
* Ptr
, const std::initializer_list
<Value
*> &indexList
, Type
*Ty
)
123 Ptr
= TranslationHelper(Ptr
, Ty
);
124 return Builder::GEP(Ptr
, indexList
);
127 Value
*BuilderGfxMem::GEP(Value
* Ptr
, const std::initializer_list
<uint32_t> &indexList
, Type
*Ty
)
129 Ptr
= TranslationHelper(Ptr
, Ty
);
130 return Builder::GEP(Ptr
, indexList
);
133 Value
* BuilderGfxMem::TranslationHelper(Value
*Ptr
, Type
*Ty
)
135 SWR_ASSERT(!(Ptr
->getType() == mInt64Ty
&& Ty
== nullptr), "Access of GFX pointers must have non-null type specified.");
138 // address may be coming in as 64bit int now so get the pointer
139 if (Ptr
->getType() == mInt64Ty
)
141 Ptr
= INT_TO_PTR(Ptr
, Ty
);
147 LoadInst
* BuilderGfxMem::LOAD(Value
*Ptr
, const char *Name
, Type
*Ty
, JIT_MEM_CLIENT usage
)
149 AssertGFXMemoryParams(Ptr
, usage
);
151 Ptr
= TranslationHelper(Ptr
, Ty
);
152 return Builder::LOAD(Ptr
, Name
);
155 LoadInst
* BuilderGfxMem::LOAD(Value
*Ptr
, const Twine
&Name
, Type
*Ty
, JIT_MEM_CLIENT usage
)
157 AssertGFXMemoryParams(Ptr
, usage
);
159 Ptr
= TranslationHelper(Ptr
, Ty
);
160 return Builder::LOAD(Ptr
, Name
);
163 LoadInst
* BuilderGfxMem::LOAD(Type
*Ty
, Value
*Ptr
, const Twine
&Name
, JIT_MEM_CLIENT usage
)
165 AssertGFXMemoryParams(Ptr
, usage
);
167 Ptr
= TranslationHelper(Ptr
, Ty
);
168 return Builder::LOAD(Ty
, Ptr
, Name
);
171 LoadInst
* BuilderGfxMem::LOAD(Value
*Ptr
, bool isVolatile
, const Twine
&Name
, Type
*Ty
, JIT_MEM_CLIENT usage
)
173 AssertGFXMemoryParams(Ptr
, usage
);
175 Ptr
= TranslationHelper(Ptr
, Ty
);
176 return Builder::LOAD(Ptr
, isVolatile
, Name
);
179 LoadInst
*BuilderGfxMem::LOAD(Value
*BasePtr
, const std::initializer_list
<uint32_t> &offset
, const llvm::Twine
& name
, Type
*Ty
, JIT_MEM_CLIENT usage
)
181 AssertGFXMemoryParams(BasePtr
, usage
);
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
);
191 CallInst
* BuilderGfxMem::MASKED_LOAD(Value
*Ptr
, unsigned Align
, Value
*Mask
, Value
*PassThru
, const Twine
&Name
, Type
*Ty
, JIT_MEM_CLIENT usage
)
193 AssertGFXMemoryParams(Ptr
, usage
);
195 Ptr
= TranslationHelper(Ptr
, Ty
);
196 return Builder::MASKED_LOAD(Ptr
, Align
, Mask
, PassThru
, Name
, Ty
, usage
);
199 Value
* BuilderGfxMem::TranslateGfxAddress(Value
* xpGfxAddress
)
201 return INT_TO_PTR(xpGfxAddress
, PointerType::get(mInt8Ty
, 0));