1 /****************************************************************************
2 * Copyright (C) 2014-2015 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_misc.h
25 * @brief miscellaneous builder functions
29 ******************************************************************************/
34 Constant
*C(uint8_t i
);
36 Constant
*C(int64_t i
);
37 Constant
*C(uint16_t i
);
38 Constant
*C(uint32_t i
);
42 Constant
*C(const std::initializer_list
<Ty
> &constList
)
44 std::vector
<Constant
*> vConsts
;
45 for(auto i
: constList
) {
47 vConsts
.push_back(C((Ty
)i
));
49 return ConstantVector::get(vConsts
);
52 Constant
*PRED(bool pred
);
53 Value
*VIMMED1(int i
);
54 Value
*VIMMED1(uint32_t i
);
55 Value
*VIMMED1(float i
);
56 Value
*VIMMED1(bool i
);
57 #if USE_SIMD16_BUILDER
58 Value
*VIMMED2_1(int i
);
59 Value
*VIMMED2_1(uint32_t i
);
60 Value
*VIMMED2_1(float i
);
61 Value
*VIMMED2_1(bool i
);
63 Value
*VUNDEF(Type
* t
);
66 #if USE_SIMD16_BUILDER
70 Value
*VUNDEF(Type
* ty
, uint32_t size
);
72 Value
*VBROADCAST(Value
*src
);
73 #if USE_SIMD16_BUILDER
74 Value
*VBROADCAST2(Value
*src
);
76 Value
*VRCP(Value
*va
);
77 Value
*VPLANEPS(Value
* vA
, Value
* vB
, Value
* vC
, Value
* &vX
, Value
* &vY
);
79 uint32_t IMMED(Value
* i
);
80 int32_t S_IMMED(Value
* i
);
82 Value
*GEP(Value
* ptr
, const std::initializer_list
<Value
*> &indexList
);
83 Value
*GEP(Value
* ptr
, const std::initializer_list
<uint32_t> &indexList
);
84 Value
*IN_BOUNDS_GEP(Value
* ptr
, const std::initializer_list
<Value
*> &indexList
);
85 Value
*IN_BOUNDS_GEP(Value
* ptr
, const std::initializer_list
<uint32_t> &indexList
);
87 CallInst
*CALL(Value
*Callee
, const std::initializer_list
<Value
*> &args
);
88 CallInst
*CALL(Value
*Callee
) { return CALLA(Callee
); }
89 CallInst
*CALL(Value
*Callee
, Value
* arg
);
90 CallInst
*CALL2(Value
*Callee
, Value
* arg1
, Value
* arg2
);
91 CallInst
*CALL3(Value
*Callee
, Value
* arg1
, Value
* arg2
, Value
* arg3
);
93 LoadInst
*LOAD(Value
*BasePtr
, const std::initializer_list
<uint32_t> &offset
, const llvm::Twine
& name
= "");
94 LoadInst
*LOADV(Value
*BasePtr
, const std::initializer_list
<Value
*> &offset
, const llvm::Twine
& name
= "");
95 StoreInst
*STORE(Value
*Val
, Value
*BasePtr
, const std::initializer_list
<uint32_t> &offset
);
96 StoreInst
*STOREV(Value
*Val
, Value
*BasePtr
, const std::initializer_list
<Value
*> &offset
);
98 Value
*VCMPPS_EQ(Value
* a
, Value
* b
) { return VCMPPS(a
, b
, C((uint8_t)_CMP_EQ_OQ
)); }
99 Value
*VCMPPS_LT(Value
* a
, Value
* b
) { return VCMPPS(a
, b
, C((uint8_t)_CMP_LT_OQ
)); }
100 Value
*VCMPPS_LE(Value
* a
, Value
* b
) { return VCMPPS(a
, b
, C((uint8_t)_CMP_LE_OQ
)); }
101 Value
*VCMPPS_ISNAN(Value
* a
, Value
* b
) { return VCMPPS(a
, b
, C((uint8_t)_CMP_UNORD_Q
)); }
102 Value
*VCMPPS_NEQ(Value
* a
, Value
* b
) { return VCMPPS(a
, b
, C((uint8_t)_CMP_NEQ_OQ
)); }
103 Value
*VCMPPS_GE(Value
* a
, Value
* b
) { return VCMPPS(a
, b
, C((uint8_t)_CMP_GE_OQ
)); }
104 Value
*VCMPPS_GT(Value
* a
, Value
* b
) { return VCMPPS(a
, b
, C((uint8_t)_CMP_GT_OQ
)); }
105 Value
*VCMPPS_NOTNAN(Value
* a
, Value
* b
){ return VCMPPS(a
, b
, C((uint8_t)_CMP_ORD_Q
)); }
107 Value
*MASK(Value
*vmask
);
108 Value
*VMASK(Value
*mask
);
109 #if USE_SIMD16_BUILDER
110 Value
*MASK2(Value
*vmask
);
111 Value
*VMASK2(Value
*mask
);
114 //////////////////////////////////////////////////////////////////////////
115 /// @brief functions that build IR to call x86 intrinsics directly, or
116 /// emulate them with other instructions if not available on the host
117 //////////////////////////////////////////////////////////////////////////
119 #if USE_SIMD16_BUILDER
120 Value
*EXTRACT2_F(Value
*a2
, uint32_t imm
);
121 Value
*EXTRACT2_I(Value
*a2
, uint32_t imm
);
122 Value
*INSERT2_F(Value
*a2
, Value
*b
, uint32_t imm
);
123 Value
*INSERT2_I(Value
*a2
, Value
*b
, uint32_t imm
);
126 Value
*MASKLOADD(Value
* src
, Value
* mask
);
128 void Gather4(const SWR_FORMAT format
, Value
* pSrcBase
, Value
* byteOffsets
,
129 Value
* mask
, Value
* vGatherComponents
[], bool bPackedOutput
);
131 Value
*GATHERPS(Value
*src
, Value
*pBase
, Value
*indices
, Value
*mask
, uint8_t scale
= 1);
132 #if USE_SIMD16_BUILDER
133 Value
*GATHERPS_16(Value
*src
, Value
*pBase
, Value
*indices
, Value
*mask
, uint8_t scale
= 1);
135 void GATHER4PS(const SWR_FORMAT_INFO
&info
, Value
* pSrcBase
, Value
* byteOffsets
,
136 Value
* mask
, Value
* vGatherComponents
[], bool bPackedOutput
);
138 Value
*GATHERDD(Value
* src
, Value
* pBase
, Value
* indices
, Value
* mask
, uint8_t scale
= 1);
139 void GATHER4DD(const SWR_FORMAT_INFO
&info
, Value
* pSrcBase
, Value
* byteOffsets
,
140 Value
* mask
, Value
* vGatherComponents
[], bool bPackedOutput
);
142 Value
*GATHERPD(Value
* src
, Value
* pBase
, Value
* indices
, Value
* mask
, uint8_t scale
= 1);
144 #if USE_SIMD16_BUILDER
145 Value
*PSRLI(Value
*a
, Value
*imm
);
146 Value
*PSRLI_16(Value
*a
, Value
*imm
);
149 void SCATTERPS(Value
* pDst
, Value
* vSrc
, Value
* vOffsets
, Value
* vMask
);
151 void Shuffle8bpcGather4(const SWR_FORMAT_INFO
&info
, Value
* vGatherInput
, Value
* vGatherOutput
[], bool bPackedOutput
);
152 void Shuffle16bpcGather4(const SWR_FORMAT_INFO
&info
, Value
* vGatherInput
[], Value
* vGatherOutput
[], bool bPackedOutput
);
154 Value
*PSHUFB(Value
* a
, Value
* b
);
155 Value
*PMOVSXBD(Value
* a
);
156 Value
*PMOVSXWD(Value
* a
);
157 Value
*PERMD(Value
* a
, Value
* idx
);
158 Value
*PERMPS(Value
* a
, Value
* idx
);
159 Value
*CVTPH2PS(Value
* a
);
160 Value
*CVTPS2PH(Value
* a
, Value
* rounding
);
161 Value
*PMAXSD(Value
* a
, Value
* b
);
162 Value
*PMINSD(Value
* a
, Value
* b
);
163 Value
*VABSPS(Value
* a
);
164 Value
*FMADDPS(Value
* a
, Value
* b
, Value
* c
);
166 // LLVM removed VPCMPGTD x86 intrinsic. This emulates that behavior
167 Value
*VPCMPGTD(Value
* a
, Value
* b
)
169 Value
* vIndexMask
= ICMP_UGT(a
,b
);
171 // need to set the high bit for x86 intrinsic masks
172 return S_EXT(vIndexMask
,VectorType::get(mInt32Ty
,JM()->mVWidth
));
175 Value
*ICLAMP(Value
* src
, Value
* low
, Value
* high
);
176 Value
*FCLAMP(Value
* src
, Value
* low
, Value
* high
);
177 Value
*FCLAMP(Value
* src
, float low
, float high
);
179 CallInst
*PRINT(const std::string
&printStr
);
180 CallInst
*PRINT(const std::string
&printStr
,const std::initializer_list
<Value
*> &printArgs
);
182 void STACKRESTORE(Value
* pSaved
);
184 Value
* POPCNT(Value
* a
);
187 Value
* INT3() { return DEBUGTRAP(); }
190 Value
*VEXTRACTI128(Value
* a
, Constant
* imm8
);
191 Value
*VINSERTI128(Value
* a
, Value
* b
, Constant
* imm8
);
193 // rdtsc buckets macros
194 void RDTSC_START(Value
* pBucketMgr
, Value
* pId
);
195 void RDTSC_STOP(Value
* pBucketMgr
, Value
* pId
);
197 Value
* CreateEntryAlloca(Function
* pFunc
, Type
* pType
);
198 Value
* CreateEntryAlloca(Function
* pFunc
, Type
* pType
, Value
* pArraySize
);
200 // Static stack allocations for scatter operations
201 Value
* pScatterStackSrc
{ nullptr };
202 Value
* pScatterStackOffsets
{ nullptr };
205 uint32_t GetTypeSize(Type
* pType
);