xref: /aosp_15_r20/external/swiftshader/src/Reactor/SIMD.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2022 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "SIMD.hpp"
16*03ce13f7SAndroid Build Coastguard Worker 
17*03ce13f7SAndroid Build Coastguard Worker #include "Assert.hpp"
18*03ce13f7SAndroid Build Coastguard Worker #include "Debug.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "Print.hpp"
20*03ce13f7SAndroid Build Coastguard Worker 
21*03ce13f7SAndroid Build Coastguard Worker #include <cmath>
22*03ce13f7SAndroid Build Coastguard Worker 
23*03ce13f7SAndroid Build Coastguard Worker namespace rr {
24*03ce13f7SAndroid Build Coastguard Worker 
Int()25*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int()
26*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
27*03ce13f7SAndroid Build Coastguard Worker {
28*03ce13f7SAndroid Build Coastguard Worker }
29*03ce13f7SAndroid Build Coastguard Worker 
Int(RValue<SIMD::Float> cast)30*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(RValue<SIMD::Float> cast)
31*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
32*03ce13f7SAndroid Build Coastguard Worker {
33*03ce13f7SAndroid Build Coastguard Worker 	Value *xyzw = Nucleus::createFPToSI(cast.value(), SIMD::Int::type());
34*03ce13f7SAndroid Build Coastguard Worker 
35*03ce13f7SAndroid Build Coastguard Worker 	storeValue(xyzw);
36*03ce13f7SAndroid Build Coastguard Worker }
37*03ce13f7SAndroid Build Coastguard Worker 
Int(int broadcast)38*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(int broadcast)
39*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
40*03ce13f7SAndroid Build Coastguard Worker {
41*03ce13f7SAndroid Build Coastguard Worker 	std::vector<int64_t> constantVector = { broadcast };
42*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
43*03ce13f7SAndroid Build Coastguard Worker }
44*03ce13f7SAndroid Build Coastguard Worker 
Int(int x,int y,int z,int w)45*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(int x, int y, int z, int w)
46*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
47*03ce13f7SAndroid Build Coastguard Worker {
48*03ce13f7SAndroid Build Coastguard Worker 	std::vector<int64_t> constantVector = { x, y, z, w };
49*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
50*03ce13f7SAndroid Build Coastguard Worker }
51*03ce13f7SAndroid Build Coastguard Worker 
Int(std::vector<int> v)52*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(std::vector<int> v)
53*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
54*03ce13f7SAndroid Build Coastguard Worker {
55*03ce13f7SAndroid Build Coastguard Worker 	std::vector<int64_t> constantVector;
56*03ce13f7SAndroid Build Coastguard Worker 	for(int i : v) { constantVector.push_back(i); }
57*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
58*03ce13f7SAndroid Build Coastguard Worker }
59*03ce13f7SAndroid Build Coastguard Worker 
Int(std::function<int (int)> LaneValueProducer)60*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(std::function<int(int)> LaneValueProducer)
61*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
62*03ce13f7SAndroid Build Coastguard Worker {
63*03ce13f7SAndroid Build Coastguard Worker 	std::vector<int64_t> constantVector;
64*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 0; i < SIMD::Width; i++) { constantVector.push_back(LaneValueProducer(i)); }
65*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
66*03ce13f7SAndroid Build Coastguard Worker }
67*03ce13f7SAndroid Build Coastguard Worker 
Int(RValue<SIMD::Int> rhs)68*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(RValue<SIMD::Int> rhs)
69*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
70*03ce13f7SAndroid Build Coastguard Worker {
71*03ce13f7SAndroid Build Coastguard Worker 	store(rhs);
72*03ce13f7SAndroid Build Coastguard Worker }
73*03ce13f7SAndroid Build Coastguard Worker 
Int(const SIMD::Int & rhs)74*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(const SIMD::Int &rhs)
75*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
76*03ce13f7SAndroid Build Coastguard Worker {
77*03ce13f7SAndroid Build Coastguard Worker 	store(rhs.load());
78*03ce13f7SAndroid Build Coastguard Worker }
79*03ce13f7SAndroid Build Coastguard Worker 
Int(const Reference<SIMD::Int> & rhs)80*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(const Reference<SIMD::Int> &rhs)
81*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
82*03ce13f7SAndroid Build Coastguard Worker {
83*03ce13f7SAndroid Build Coastguard Worker 	store(rhs.load());
84*03ce13f7SAndroid Build Coastguard Worker }
85*03ce13f7SAndroid Build Coastguard Worker 
Int(RValue<SIMD::UInt> rhs)86*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(RValue<SIMD::UInt> rhs)
87*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
88*03ce13f7SAndroid Build Coastguard Worker {
89*03ce13f7SAndroid Build Coastguard Worker 	storeValue(rhs.value());
90*03ce13f7SAndroid Build Coastguard Worker }
91*03ce13f7SAndroid Build Coastguard Worker 
Int(const SIMD::UInt & rhs)92*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(const SIMD::UInt &rhs)
93*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
94*03ce13f7SAndroid Build Coastguard Worker {
95*03ce13f7SAndroid Build Coastguard Worker 	storeValue(rhs.loadValue());
96*03ce13f7SAndroid Build Coastguard Worker }
97*03ce13f7SAndroid Build Coastguard Worker 
Int(const Reference<SIMD::UInt> & rhs)98*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(const Reference<SIMD::UInt> &rhs)
99*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
100*03ce13f7SAndroid Build Coastguard Worker {
101*03ce13f7SAndroid Build Coastguard Worker 	storeValue(rhs.loadValue());
102*03ce13f7SAndroid Build Coastguard Worker }
103*03ce13f7SAndroid Build Coastguard Worker 
Int(const scalar::Int & rhs)104*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(const scalar::Int &rhs)
105*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
106*03ce13f7SAndroid Build Coastguard Worker {
107*03ce13f7SAndroid Build Coastguard Worker 	*this = RValue<scalar::Int>(rhs.loadValue());
108*03ce13f7SAndroid Build Coastguard Worker }
109*03ce13f7SAndroid Build Coastguard Worker 
Int(const Reference<scalar::Int> & rhs)110*03ce13f7SAndroid Build Coastguard Worker SIMD::Int::Int(const Reference<scalar::Int> &rhs)
111*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
112*03ce13f7SAndroid Build Coastguard Worker {
113*03ce13f7SAndroid Build Coastguard Worker 	*this = RValue<scalar::Int>(rhs.loadValue());
114*03ce13f7SAndroid Build Coastguard Worker }
115*03ce13f7SAndroid Build Coastguard Worker 
operator =(int x)116*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> SIMD::Int::operator=(int x)
117*03ce13f7SAndroid Build Coastguard Worker {
118*03ce13f7SAndroid Build Coastguard Worker 	return *this = SIMD::Int(x);
119*03ce13f7SAndroid Build Coastguard Worker }
120*03ce13f7SAndroid Build Coastguard Worker 
operator =(RValue<SIMD::Int> rhs)121*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> SIMD::Int::operator=(RValue<SIMD::Int> rhs)
122*03ce13f7SAndroid Build Coastguard Worker {
123*03ce13f7SAndroid Build Coastguard Worker 	return store(rhs);
124*03ce13f7SAndroid Build Coastguard Worker }
125*03ce13f7SAndroid Build Coastguard Worker 
operator =(const SIMD::Int & rhs)126*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> SIMD::Int::operator=(const SIMD::Int &rhs)
127*03ce13f7SAndroid Build Coastguard Worker {
128*03ce13f7SAndroid Build Coastguard Worker 	return store(rhs.load());
129*03ce13f7SAndroid Build Coastguard Worker }
130*03ce13f7SAndroid Build Coastguard Worker 
operator =(const Reference<SIMD::Int> & rhs)131*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> SIMD::Int::operator=(const Reference<SIMD::Int> &rhs)
132*03ce13f7SAndroid Build Coastguard Worker {
133*03ce13f7SAndroid Build Coastguard Worker 	return store(rhs.load());
134*03ce13f7SAndroid Build Coastguard Worker }
135*03ce13f7SAndroid Build Coastguard Worker 
operator +(RValue<SIMD::Int> lhs,RValue<SIMD::Int> rhs)136*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator+(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
137*03ce13f7SAndroid Build Coastguard Worker {
138*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createAdd(lhs.value(), rhs.value()));
139*03ce13f7SAndroid Build Coastguard Worker }
140*03ce13f7SAndroid Build Coastguard Worker 
operator -(RValue<SIMD::Int> lhs,RValue<SIMD::Int> rhs)141*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator-(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
142*03ce13f7SAndroid Build Coastguard Worker {
143*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createSub(lhs.value(), rhs.value()));
144*03ce13f7SAndroid Build Coastguard Worker }
145*03ce13f7SAndroid Build Coastguard Worker 
operator *(RValue<SIMD::Int> lhs,RValue<SIMD::Int> rhs)146*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator*(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
147*03ce13f7SAndroid Build Coastguard Worker {
148*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createMul(lhs.value(), rhs.value()));
149*03ce13f7SAndroid Build Coastguard Worker }
150*03ce13f7SAndroid Build Coastguard Worker 
operator /(RValue<SIMD::Int> lhs,RValue<SIMD::Int> rhs)151*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator/(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
152*03ce13f7SAndroid Build Coastguard Worker {
153*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createSDiv(lhs.value(), rhs.value()));
154*03ce13f7SAndroid Build Coastguard Worker }
155*03ce13f7SAndroid Build Coastguard Worker 
operator %(RValue<SIMD::Int> lhs,RValue<SIMD::Int> rhs)156*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator%(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
157*03ce13f7SAndroid Build Coastguard Worker {
158*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createSRem(lhs.value(), rhs.value()));
159*03ce13f7SAndroid Build Coastguard Worker }
160*03ce13f7SAndroid Build Coastguard Worker 
operator &(RValue<SIMD::Int> lhs,RValue<SIMD::Int> rhs)161*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator&(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
162*03ce13f7SAndroid Build Coastguard Worker {
163*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createAnd(lhs.value(), rhs.value()));
164*03ce13f7SAndroid Build Coastguard Worker }
165*03ce13f7SAndroid Build Coastguard Worker 
operator |(RValue<SIMD::Int> lhs,RValue<SIMD::Int> rhs)166*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator|(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
167*03ce13f7SAndroid Build Coastguard Worker {
168*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createOr(lhs.value(), rhs.value()));
169*03ce13f7SAndroid Build Coastguard Worker }
170*03ce13f7SAndroid Build Coastguard Worker 
operator ^(RValue<SIMD::Int> lhs,RValue<SIMD::Int> rhs)171*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator^(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
172*03ce13f7SAndroid Build Coastguard Worker {
173*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createXor(lhs.value(), rhs.value()));
174*03ce13f7SAndroid Build Coastguard Worker }
175*03ce13f7SAndroid Build Coastguard Worker 
operator <<(RValue<SIMD::Int> lhs,RValue<SIMD::Int> rhs)176*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator<<(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
177*03ce13f7SAndroid Build Coastguard Worker {
178*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createShl(lhs.value(), rhs.value()));
179*03ce13f7SAndroid Build Coastguard Worker }
180*03ce13f7SAndroid Build Coastguard Worker 
operator >>(RValue<SIMD::Int> lhs,RValue<SIMD::Int> rhs)181*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator>>(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
182*03ce13f7SAndroid Build Coastguard Worker {
183*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createAShr(lhs.value(), rhs.value()));
184*03ce13f7SAndroid Build Coastguard Worker }
185*03ce13f7SAndroid Build Coastguard Worker 
operator +=(SIMD::Int & lhs,RValue<SIMD::Int> rhs)186*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator+=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
187*03ce13f7SAndroid Build Coastguard Worker {
188*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs + rhs;
189*03ce13f7SAndroid Build Coastguard Worker }
190*03ce13f7SAndroid Build Coastguard Worker 
operator -=(SIMD::Int & lhs,RValue<SIMD::Int> rhs)191*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator-=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
192*03ce13f7SAndroid Build Coastguard Worker {
193*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs - rhs;
194*03ce13f7SAndroid Build Coastguard Worker }
195*03ce13f7SAndroid Build Coastguard Worker 
operator *=(SIMD::Int & lhs,RValue<SIMD::Int> rhs)196*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator*=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
197*03ce13f7SAndroid Build Coastguard Worker {
198*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs * rhs;
199*03ce13f7SAndroid Build Coastguard Worker }
200*03ce13f7SAndroid Build Coastguard Worker 
201*03ce13f7SAndroid Build Coastguard Worker //	RValue<SIMD::Int> operator/=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
202*03ce13f7SAndroid Build Coastguard Worker //	{
203*03ce13f7SAndroid Build Coastguard Worker //		return lhs = lhs / rhs;
204*03ce13f7SAndroid Build Coastguard Worker //	}
205*03ce13f7SAndroid Build Coastguard Worker 
206*03ce13f7SAndroid Build Coastguard Worker //	RValue<SIMD::Int> operator%=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
207*03ce13f7SAndroid Build Coastguard Worker //	{
208*03ce13f7SAndroid Build Coastguard Worker //		return lhs = lhs % rhs;
209*03ce13f7SAndroid Build Coastguard Worker //	}
210*03ce13f7SAndroid Build Coastguard Worker 
operator &=(SIMD::Int & lhs,RValue<SIMD::Int> rhs)211*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator&=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
212*03ce13f7SAndroid Build Coastguard Worker {
213*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs & rhs;
214*03ce13f7SAndroid Build Coastguard Worker }
215*03ce13f7SAndroid Build Coastguard Worker 
operator |=(SIMD::Int & lhs,RValue<SIMD::Int> rhs)216*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator|=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
217*03ce13f7SAndroid Build Coastguard Worker {
218*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs | rhs;
219*03ce13f7SAndroid Build Coastguard Worker }
220*03ce13f7SAndroid Build Coastguard Worker 
operator ^=(SIMD::Int & lhs,RValue<SIMD::Int> rhs)221*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator^=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
222*03ce13f7SAndroid Build Coastguard Worker {
223*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs ^ rhs;
224*03ce13f7SAndroid Build Coastguard Worker }
225*03ce13f7SAndroid Build Coastguard Worker 
operator <<=(SIMD::Int & lhs,unsigned char rhs)226*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator<<=(SIMD::Int &lhs, unsigned char rhs)
227*03ce13f7SAndroid Build Coastguard Worker {
228*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs << rhs;
229*03ce13f7SAndroid Build Coastguard Worker }
230*03ce13f7SAndroid Build Coastguard Worker 
operator >>=(SIMD::Int & lhs,unsigned char rhs)231*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator>>=(SIMD::Int &lhs, unsigned char rhs)
232*03ce13f7SAndroid Build Coastguard Worker {
233*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs >> rhs;
234*03ce13f7SAndroid Build Coastguard Worker }
235*03ce13f7SAndroid Build Coastguard Worker 
operator +(RValue<SIMD::Int> val)236*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator+(RValue<SIMD::Int> val)
237*03ce13f7SAndroid Build Coastguard Worker {
238*03ce13f7SAndroid Build Coastguard Worker 	return val;
239*03ce13f7SAndroid Build Coastguard Worker }
240*03ce13f7SAndroid Build Coastguard Worker 
operator -(RValue<SIMD::Int> val)241*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator-(RValue<SIMD::Int> val)
242*03ce13f7SAndroid Build Coastguard Worker {
243*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createNeg(val.value()));
244*03ce13f7SAndroid Build Coastguard Worker }
245*03ce13f7SAndroid Build Coastguard Worker 
operator ~(RValue<SIMD::Int> val)246*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> operator~(RValue<SIMD::Int> val)
247*03ce13f7SAndroid Build Coastguard Worker {
248*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createNot(val.value()));
249*03ce13f7SAndroid Build Coastguard Worker }
250*03ce13f7SAndroid Build Coastguard Worker 
Extract(RValue<SIMD::Int> x,int i)251*03ce13f7SAndroid Build Coastguard Worker RValue<scalar::Int> Extract(RValue<SIMD::Int> x, int i)
252*03ce13f7SAndroid Build Coastguard Worker {
253*03ce13f7SAndroid Build Coastguard Worker 	return RValue<scalar::Int>(Nucleus::createExtractElement(x.value(), scalar::Int::type(), i));
254*03ce13f7SAndroid Build Coastguard Worker }
255*03ce13f7SAndroid Build Coastguard Worker 
Insert(RValue<SIMD::Int> x,RValue<scalar::Int> element,int i)256*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> Insert(RValue<SIMD::Int> x, RValue<scalar::Int> element, int i)
257*03ce13f7SAndroid Build Coastguard Worker {
258*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Int>(Nucleus::createInsertElement(x.value(), element.value(), i));
259*03ce13f7SAndroid Build Coastguard Worker }
260*03ce13f7SAndroid Build Coastguard Worker 
UInt()261*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt()
262*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
263*03ce13f7SAndroid Build Coastguard Worker {
264*03ce13f7SAndroid Build Coastguard Worker }
265*03ce13f7SAndroid Build Coastguard Worker 
UInt(int broadcast)266*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(int broadcast)
267*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
268*03ce13f7SAndroid Build Coastguard Worker {
269*03ce13f7SAndroid Build Coastguard Worker 	std::vector<int64_t> constantVector = { broadcast };
270*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
271*03ce13f7SAndroid Build Coastguard Worker }
272*03ce13f7SAndroid Build Coastguard Worker 
UInt(int x,int y,int z,int w)273*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(int x, int y, int z, int w)
274*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
275*03ce13f7SAndroid Build Coastguard Worker {
276*03ce13f7SAndroid Build Coastguard Worker 	std::vector<int64_t> constantVector = { x, y, z, w };
277*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
278*03ce13f7SAndroid Build Coastguard Worker }
279*03ce13f7SAndroid Build Coastguard Worker 
UInt(std::vector<int> v)280*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(std::vector<int> v)
281*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
282*03ce13f7SAndroid Build Coastguard Worker {
283*03ce13f7SAndroid Build Coastguard Worker 	std::vector<int64_t> constantVector;
284*03ce13f7SAndroid Build Coastguard Worker 	for(int i : v) { constantVector.push_back(i); }
285*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
286*03ce13f7SAndroid Build Coastguard Worker }
287*03ce13f7SAndroid Build Coastguard Worker 
UInt(std::function<int (int)> LaneValueProducer)288*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(std::function<int(int)> LaneValueProducer)
289*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
290*03ce13f7SAndroid Build Coastguard Worker {
291*03ce13f7SAndroid Build Coastguard Worker 	std::vector<int64_t> constantVector;
292*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 0; i < SIMD::Width; i++) { constantVector.push_back(LaneValueProducer(i)); }
293*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
294*03ce13f7SAndroid Build Coastguard Worker }
295*03ce13f7SAndroid Build Coastguard Worker 
UInt(RValue<SIMD::UInt> rhs)296*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(RValue<SIMD::UInt> rhs)
297*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
298*03ce13f7SAndroid Build Coastguard Worker {
299*03ce13f7SAndroid Build Coastguard Worker 	store(rhs);
300*03ce13f7SAndroid Build Coastguard Worker }
301*03ce13f7SAndroid Build Coastguard Worker 
UInt(const SIMD::UInt & rhs)302*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(const SIMD::UInt &rhs)
303*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
304*03ce13f7SAndroid Build Coastguard Worker {
305*03ce13f7SAndroid Build Coastguard Worker 	store(rhs.load());
306*03ce13f7SAndroid Build Coastguard Worker }
307*03ce13f7SAndroid Build Coastguard Worker 
UInt(const Reference<SIMD::UInt> & rhs)308*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(const Reference<SIMD::UInt> &rhs)
309*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
310*03ce13f7SAndroid Build Coastguard Worker {
311*03ce13f7SAndroid Build Coastguard Worker 	store(rhs.load());
312*03ce13f7SAndroid Build Coastguard Worker }
313*03ce13f7SAndroid Build Coastguard Worker 
UInt(RValue<SIMD::Int> rhs)314*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(RValue<SIMD::Int> rhs)
315*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
316*03ce13f7SAndroid Build Coastguard Worker {
317*03ce13f7SAndroid Build Coastguard Worker 	storeValue(rhs.value());
318*03ce13f7SAndroid Build Coastguard Worker }
319*03ce13f7SAndroid Build Coastguard Worker 
UInt(const SIMD::Int & rhs)320*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(const SIMD::Int &rhs)
321*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
322*03ce13f7SAndroid Build Coastguard Worker {
323*03ce13f7SAndroid Build Coastguard Worker 	storeValue(rhs.loadValue());
324*03ce13f7SAndroid Build Coastguard Worker }
325*03ce13f7SAndroid Build Coastguard Worker 
UInt(const Reference<SIMD::Int> & rhs)326*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(const Reference<SIMD::Int> &rhs)
327*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
328*03ce13f7SAndroid Build Coastguard Worker {
329*03ce13f7SAndroid Build Coastguard Worker 	storeValue(rhs.loadValue());
330*03ce13f7SAndroid Build Coastguard Worker }
331*03ce13f7SAndroid Build Coastguard Worker 
UInt(const scalar::UInt & rhs)332*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(const scalar::UInt &rhs)
333*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
334*03ce13f7SAndroid Build Coastguard Worker {
335*03ce13f7SAndroid Build Coastguard Worker 	*this = RValue<scalar::UInt>(rhs.loadValue());
336*03ce13f7SAndroid Build Coastguard Worker }
337*03ce13f7SAndroid Build Coastguard Worker 
UInt(const Reference<scalar::UInt> & rhs)338*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt::UInt(const Reference<scalar::UInt> &rhs)
339*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
340*03ce13f7SAndroid Build Coastguard Worker {
341*03ce13f7SAndroid Build Coastguard Worker 	*this = RValue<scalar::UInt>(rhs.loadValue());
342*03ce13f7SAndroid Build Coastguard Worker }
343*03ce13f7SAndroid Build Coastguard Worker 
operator =(RValue<SIMD::UInt> rhs)344*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> SIMD::UInt::operator=(RValue<SIMD::UInt> rhs)
345*03ce13f7SAndroid Build Coastguard Worker {
346*03ce13f7SAndroid Build Coastguard Worker 	return store(rhs);
347*03ce13f7SAndroid Build Coastguard Worker }
348*03ce13f7SAndroid Build Coastguard Worker 
operator =(const SIMD::UInt & rhs)349*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> SIMD::UInt::operator=(const SIMD::UInt &rhs)
350*03ce13f7SAndroid Build Coastguard Worker {
351*03ce13f7SAndroid Build Coastguard Worker 	return store(rhs.load());
352*03ce13f7SAndroid Build Coastguard Worker }
353*03ce13f7SAndroid Build Coastguard Worker 
operator =(const Reference<SIMD::UInt> & rhs)354*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> SIMD::UInt::operator=(const Reference<SIMD::UInt> &rhs)
355*03ce13f7SAndroid Build Coastguard Worker {
356*03ce13f7SAndroid Build Coastguard Worker 	return store(rhs.load());
357*03ce13f7SAndroid Build Coastguard Worker }
358*03ce13f7SAndroid Build Coastguard Worker 
operator +(RValue<SIMD::UInt> lhs,RValue<SIMD::UInt> rhs)359*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator+(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
360*03ce13f7SAndroid Build Coastguard Worker {
361*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createAdd(lhs.value(), rhs.value()));
362*03ce13f7SAndroid Build Coastguard Worker }
363*03ce13f7SAndroid Build Coastguard Worker 
operator -(RValue<SIMD::UInt> lhs,RValue<SIMD::UInt> rhs)364*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator-(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
365*03ce13f7SAndroid Build Coastguard Worker {
366*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createSub(lhs.value(), rhs.value()));
367*03ce13f7SAndroid Build Coastguard Worker }
368*03ce13f7SAndroid Build Coastguard Worker 
operator *(RValue<SIMD::UInt> lhs,RValue<SIMD::UInt> rhs)369*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator*(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
370*03ce13f7SAndroid Build Coastguard Worker {
371*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createMul(lhs.value(), rhs.value()));
372*03ce13f7SAndroid Build Coastguard Worker }
373*03ce13f7SAndroid Build Coastguard Worker 
operator /(RValue<SIMD::UInt> lhs,RValue<SIMD::UInt> rhs)374*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator/(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
375*03ce13f7SAndroid Build Coastguard Worker {
376*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createUDiv(lhs.value(), rhs.value()));
377*03ce13f7SAndroid Build Coastguard Worker }
378*03ce13f7SAndroid Build Coastguard Worker 
operator %(RValue<SIMD::UInt> lhs,RValue<SIMD::UInt> rhs)379*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator%(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
380*03ce13f7SAndroid Build Coastguard Worker {
381*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createURem(lhs.value(), rhs.value()));
382*03ce13f7SAndroid Build Coastguard Worker }
383*03ce13f7SAndroid Build Coastguard Worker 
operator &(RValue<SIMD::UInt> lhs,RValue<SIMD::UInt> rhs)384*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator&(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
385*03ce13f7SAndroid Build Coastguard Worker {
386*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createAnd(lhs.value(), rhs.value()));
387*03ce13f7SAndroid Build Coastguard Worker }
388*03ce13f7SAndroid Build Coastguard Worker 
operator |(RValue<SIMD::UInt> lhs,RValue<SIMD::UInt> rhs)389*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator|(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
390*03ce13f7SAndroid Build Coastguard Worker {
391*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createOr(lhs.value(), rhs.value()));
392*03ce13f7SAndroid Build Coastguard Worker }
393*03ce13f7SAndroid Build Coastguard Worker 
operator ^(RValue<SIMD::UInt> lhs,RValue<SIMD::UInt> rhs)394*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator^(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
395*03ce13f7SAndroid Build Coastguard Worker {
396*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createXor(lhs.value(), rhs.value()));
397*03ce13f7SAndroid Build Coastguard Worker }
398*03ce13f7SAndroid Build Coastguard Worker 
operator <<(RValue<SIMD::UInt> lhs,RValue<SIMD::UInt> rhs)399*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator<<(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
400*03ce13f7SAndroid Build Coastguard Worker {
401*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createShl(lhs.value(), rhs.value()));
402*03ce13f7SAndroid Build Coastguard Worker }
403*03ce13f7SAndroid Build Coastguard Worker 
operator >>(RValue<SIMD::UInt> lhs,RValue<SIMD::UInt> rhs)404*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator>>(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
405*03ce13f7SAndroid Build Coastguard Worker {
406*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createLShr(lhs.value(), rhs.value()));
407*03ce13f7SAndroid Build Coastguard Worker }
408*03ce13f7SAndroid Build Coastguard Worker 
operator +=(SIMD::UInt & lhs,RValue<SIMD::UInt> rhs)409*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator+=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
410*03ce13f7SAndroid Build Coastguard Worker {
411*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs + rhs;
412*03ce13f7SAndroid Build Coastguard Worker }
413*03ce13f7SAndroid Build Coastguard Worker 
operator -=(SIMD::UInt & lhs,RValue<SIMD::UInt> rhs)414*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator-=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
415*03ce13f7SAndroid Build Coastguard Worker {
416*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs - rhs;
417*03ce13f7SAndroid Build Coastguard Worker }
418*03ce13f7SAndroid Build Coastguard Worker 
operator *=(SIMD::UInt & lhs,RValue<SIMD::UInt> rhs)419*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator*=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
420*03ce13f7SAndroid Build Coastguard Worker {
421*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs * rhs;
422*03ce13f7SAndroid Build Coastguard Worker }
423*03ce13f7SAndroid Build Coastguard Worker 
424*03ce13f7SAndroid Build Coastguard Worker //	RValue<SIMD::UInt> operator/=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
425*03ce13f7SAndroid Build Coastguard Worker //	{
426*03ce13f7SAndroid Build Coastguard Worker //		return lhs = lhs / rhs;
427*03ce13f7SAndroid Build Coastguard Worker //	}
428*03ce13f7SAndroid Build Coastguard Worker 
429*03ce13f7SAndroid Build Coastguard Worker //	RValue<SIMD::UInt> operator%=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
430*03ce13f7SAndroid Build Coastguard Worker //	{
431*03ce13f7SAndroid Build Coastguard Worker //		return lhs = lhs % rhs;
432*03ce13f7SAndroid Build Coastguard Worker //	}
433*03ce13f7SAndroid Build Coastguard Worker 
operator &=(SIMD::UInt & lhs,RValue<SIMD::UInt> rhs)434*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator&=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
435*03ce13f7SAndroid Build Coastguard Worker {
436*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs & rhs;
437*03ce13f7SAndroid Build Coastguard Worker }
438*03ce13f7SAndroid Build Coastguard Worker 
operator |=(SIMD::UInt & lhs,RValue<SIMD::UInt> rhs)439*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator|=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
440*03ce13f7SAndroid Build Coastguard Worker {
441*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs | rhs;
442*03ce13f7SAndroid Build Coastguard Worker }
443*03ce13f7SAndroid Build Coastguard Worker 
operator ^=(SIMD::UInt & lhs,RValue<SIMD::UInt> rhs)444*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator^=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
445*03ce13f7SAndroid Build Coastguard Worker {
446*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs ^ rhs;
447*03ce13f7SAndroid Build Coastguard Worker }
448*03ce13f7SAndroid Build Coastguard Worker 
operator <<=(SIMD::UInt & lhs,unsigned char rhs)449*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator<<=(SIMD::UInt &lhs, unsigned char rhs)
450*03ce13f7SAndroid Build Coastguard Worker {
451*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs << rhs;
452*03ce13f7SAndroid Build Coastguard Worker }
453*03ce13f7SAndroid Build Coastguard Worker 
operator >>=(SIMD::UInt & lhs,unsigned char rhs)454*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator>>=(SIMD::UInt &lhs, unsigned char rhs)
455*03ce13f7SAndroid Build Coastguard Worker {
456*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs >> rhs;
457*03ce13f7SAndroid Build Coastguard Worker }
458*03ce13f7SAndroid Build Coastguard Worker 
operator +(RValue<SIMD::UInt> val)459*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator+(RValue<SIMD::UInt> val)
460*03ce13f7SAndroid Build Coastguard Worker {
461*03ce13f7SAndroid Build Coastguard Worker 	return val;
462*03ce13f7SAndroid Build Coastguard Worker }
463*03ce13f7SAndroid Build Coastguard Worker 
operator -(RValue<SIMD::UInt> val)464*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator-(RValue<SIMD::UInt> val)
465*03ce13f7SAndroid Build Coastguard Worker {
466*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createNeg(val.value()));
467*03ce13f7SAndroid Build Coastguard Worker }
468*03ce13f7SAndroid Build Coastguard Worker 
operator ~(RValue<SIMD::UInt> val)469*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> operator~(RValue<SIMD::UInt> val)
470*03ce13f7SAndroid Build Coastguard Worker {
471*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createNot(val.value()));
472*03ce13f7SAndroid Build Coastguard Worker }
473*03ce13f7SAndroid Build Coastguard Worker 
Extract(RValue<SIMD::UInt> x,int i)474*03ce13f7SAndroid Build Coastguard Worker RValue<scalar::UInt> Extract(RValue<SIMD::UInt> x, int i)
475*03ce13f7SAndroid Build Coastguard Worker {
476*03ce13f7SAndroid Build Coastguard Worker 	return RValue<scalar::UInt>(Nucleus::createExtractElement(x.value(), scalar::Int::type(), i));
477*03ce13f7SAndroid Build Coastguard Worker }
478*03ce13f7SAndroid Build Coastguard Worker 
Insert(RValue<SIMD::UInt> x,RValue<scalar::UInt> element,int i)479*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> Insert(RValue<SIMD::UInt> x, RValue<scalar::UInt> element, int i)
480*03ce13f7SAndroid Build Coastguard Worker {
481*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::UInt>(Nucleus::createInsertElement(x.value(), element.value(), i));
482*03ce13f7SAndroid Build Coastguard Worker }
483*03ce13f7SAndroid Build Coastguard Worker 
Float(RValue<SIMD::Int> cast)484*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(RValue<SIMD::Int> cast)
485*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
486*03ce13f7SAndroid Build Coastguard Worker {
487*03ce13f7SAndroid Build Coastguard Worker 	Value *xyzw = Nucleus::createSIToFP(cast.value(), SIMD::Float::type());
488*03ce13f7SAndroid Build Coastguard Worker 
489*03ce13f7SAndroid Build Coastguard Worker 	storeValue(xyzw);
490*03ce13f7SAndroid Build Coastguard Worker }
491*03ce13f7SAndroid Build Coastguard Worker 
Float(RValue<SIMD::UInt> cast)492*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(RValue<SIMD::UInt> cast)
493*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
494*03ce13f7SAndroid Build Coastguard Worker {
495*03ce13f7SAndroid Build Coastguard Worker 	RValue<SIMD::Float> result = SIMD::Float(SIMD::Int(cast & SIMD::UInt(0x7FFFFFFF))) +
496*03ce13f7SAndroid Build Coastguard Worker 	                             As<SIMD::Float>((As<SIMD::Int>(cast) >> 31) & As<SIMD::Int>(SIMD::Float(0x80000000u)));
497*03ce13f7SAndroid Build Coastguard Worker 
498*03ce13f7SAndroid Build Coastguard Worker 	storeValue(result.value());
499*03ce13f7SAndroid Build Coastguard Worker }
500*03ce13f7SAndroid Build Coastguard Worker 
Float()501*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float()
502*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
503*03ce13f7SAndroid Build Coastguard Worker {
504*03ce13f7SAndroid Build Coastguard Worker }
505*03ce13f7SAndroid Build Coastguard Worker 
Float(float broadcast)506*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(float broadcast)
507*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
508*03ce13f7SAndroid Build Coastguard Worker {
509*03ce13f7SAndroid Build Coastguard Worker 	// See rr::Float(float) constructor for the rationale behind this assert.
510*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(std::isfinite(broadcast));
511*03ce13f7SAndroid Build Coastguard Worker 
512*03ce13f7SAndroid Build Coastguard Worker 	std::vector<double> constantVector = { broadcast };
513*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
514*03ce13f7SAndroid Build Coastguard Worker }
515*03ce13f7SAndroid Build Coastguard Worker 
Float(float x,float y,float z,float w)516*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(float x, float y, float z, float w)
517*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
518*03ce13f7SAndroid Build Coastguard Worker {
519*03ce13f7SAndroid Build Coastguard Worker 	std::vector<double> constantVector = { x, y, z, w };
520*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
521*03ce13f7SAndroid Build Coastguard Worker }
522*03ce13f7SAndroid Build Coastguard Worker 
Float(std::vector<float> v)523*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(std::vector<float> v)
524*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
525*03ce13f7SAndroid Build Coastguard Worker {
526*03ce13f7SAndroid Build Coastguard Worker 	std::vector<double> constantVector;
527*03ce13f7SAndroid Build Coastguard Worker 	for(int f : v) { constantVector.push_back(f); }
528*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
529*03ce13f7SAndroid Build Coastguard Worker }
530*03ce13f7SAndroid Build Coastguard Worker 
Float(std::function<float (int)> LaneValueProducer)531*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(std::function<float(int)> LaneValueProducer)
532*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
533*03ce13f7SAndroid Build Coastguard Worker {
534*03ce13f7SAndroid Build Coastguard Worker 	std::vector<double> constantVector;
535*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 0; i < SIMD::Width; i++) { constantVector.push_back(LaneValueProducer(i)); }
536*03ce13f7SAndroid Build Coastguard Worker 	storeValue(Nucleus::createConstantVector(constantVector, type()));
537*03ce13f7SAndroid Build Coastguard Worker }
538*03ce13f7SAndroid Build Coastguard Worker 
infinity()539*03ce13f7SAndroid Build Coastguard Worker SIMD::Float SIMD::Float::infinity()
540*03ce13f7SAndroid Build Coastguard Worker {
541*03ce13f7SAndroid Build Coastguard Worker 	SIMD::Float result;
542*03ce13f7SAndroid Build Coastguard Worker 
543*03ce13f7SAndroid Build Coastguard Worker 	constexpr double inf = std::numeric_limits<double>::infinity();
544*03ce13f7SAndroid Build Coastguard Worker 	std::vector<double> constantVector = { inf };
545*03ce13f7SAndroid Build Coastguard Worker 	result.storeValue(Nucleus::createConstantVector(constantVector, type()));
546*03ce13f7SAndroid Build Coastguard Worker 
547*03ce13f7SAndroid Build Coastguard Worker 	return result;
548*03ce13f7SAndroid Build Coastguard Worker }
549*03ce13f7SAndroid Build Coastguard Worker 
Float(RValue<SIMD::Float> rhs)550*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(RValue<SIMD::Float> rhs)
551*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
552*03ce13f7SAndroid Build Coastguard Worker {
553*03ce13f7SAndroid Build Coastguard Worker 	store(rhs);
554*03ce13f7SAndroid Build Coastguard Worker }
555*03ce13f7SAndroid Build Coastguard Worker 
Float(const SIMD::Float & rhs)556*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(const SIMD::Float &rhs)
557*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
558*03ce13f7SAndroid Build Coastguard Worker {
559*03ce13f7SAndroid Build Coastguard Worker 	store(rhs.load());
560*03ce13f7SAndroid Build Coastguard Worker }
561*03ce13f7SAndroid Build Coastguard Worker 
Float(const Reference<SIMD::Float> & rhs)562*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(const Reference<SIMD::Float> &rhs)
563*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
564*03ce13f7SAndroid Build Coastguard Worker {
565*03ce13f7SAndroid Build Coastguard Worker 	store(rhs.load());
566*03ce13f7SAndroid Build Coastguard Worker }
567*03ce13f7SAndroid Build Coastguard Worker 
Float(const scalar::Float & rhs)568*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(const scalar::Float &rhs)
569*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
570*03ce13f7SAndroid Build Coastguard Worker {
571*03ce13f7SAndroid Build Coastguard Worker 	*this = RValue<scalar::Float>(rhs.loadValue());
572*03ce13f7SAndroid Build Coastguard Worker }
573*03ce13f7SAndroid Build Coastguard Worker 
Float(const Reference<scalar::Float> & rhs)574*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(const Reference<scalar::Float> &rhs)
575*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
576*03ce13f7SAndroid Build Coastguard Worker {
577*03ce13f7SAndroid Build Coastguard Worker 	*this = RValue<scalar::Float>(rhs.loadValue());
578*03ce13f7SAndroid Build Coastguard Worker }
579*03ce13f7SAndroid Build Coastguard Worker 
Float(RValue<packed::Float4> rhs)580*03ce13f7SAndroid Build Coastguard Worker SIMD::Float::Float(RValue<packed::Float4> rhs)
581*03ce13f7SAndroid Build Coastguard Worker     : XYZW(this)
582*03ce13f7SAndroid Build Coastguard Worker {
583*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
584*03ce13f7SAndroid Build Coastguard Worker 	*this = Insert128(*this, rhs, 0);
585*03ce13f7SAndroid Build Coastguard Worker }
586*03ce13f7SAndroid Build Coastguard Worker 
operator =(RValue<packed::Float4> rhs)587*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> SIMD::Float::operator=(RValue<packed::Float4> rhs)
588*03ce13f7SAndroid Build Coastguard Worker {
589*03ce13f7SAndroid Build Coastguard Worker 	return *this = SIMD::Float(rhs);
590*03ce13f7SAndroid Build Coastguard Worker }
591*03ce13f7SAndroid Build Coastguard Worker 
operator =(float x)592*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> SIMD::Float::operator=(float x)
593*03ce13f7SAndroid Build Coastguard Worker {
594*03ce13f7SAndroid Build Coastguard Worker 	return *this = SIMD::Float(x);
595*03ce13f7SAndroid Build Coastguard Worker }
596*03ce13f7SAndroid Build Coastguard Worker 
operator =(RValue<SIMD::Float> rhs)597*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> SIMD::Float::operator=(RValue<SIMD::Float> rhs)
598*03ce13f7SAndroid Build Coastguard Worker {
599*03ce13f7SAndroid Build Coastguard Worker 	return store(rhs);
600*03ce13f7SAndroid Build Coastguard Worker }
601*03ce13f7SAndroid Build Coastguard Worker 
operator =(const SIMD::Float & rhs)602*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> SIMD::Float::operator=(const SIMD::Float &rhs)
603*03ce13f7SAndroid Build Coastguard Worker {
604*03ce13f7SAndroid Build Coastguard Worker 	return store(rhs.load());
605*03ce13f7SAndroid Build Coastguard Worker }
606*03ce13f7SAndroid Build Coastguard Worker 
operator =(const Reference<SIMD::Float> & rhs)607*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> SIMD::Float::operator=(const Reference<SIMD::Float> &rhs)
608*03ce13f7SAndroid Build Coastguard Worker {
609*03ce13f7SAndroid Build Coastguard Worker 	return store(rhs.load());
610*03ce13f7SAndroid Build Coastguard Worker }
611*03ce13f7SAndroid Build Coastguard Worker 
operator =(RValue<scalar::Float> rhs)612*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> SIMD::Float::operator=(RValue<scalar::Float> rhs)
613*03ce13f7SAndroid Build Coastguard Worker {
614*03ce13f7SAndroid Build Coastguard Worker 	return *this = SIMD::Float(rhs);
615*03ce13f7SAndroid Build Coastguard Worker }
616*03ce13f7SAndroid Build Coastguard Worker 
operator =(const scalar::Float & rhs)617*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> SIMD::Float::operator=(const scalar::Float &rhs)
618*03ce13f7SAndroid Build Coastguard Worker {
619*03ce13f7SAndroid Build Coastguard Worker 	return *this = SIMD::Float(rhs);
620*03ce13f7SAndroid Build Coastguard Worker }
621*03ce13f7SAndroid Build Coastguard Worker 
operator =(const Reference<scalar::Float> & rhs)622*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> SIMD::Float::operator=(const Reference<scalar::Float> &rhs)
623*03ce13f7SAndroid Build Coastguard Worker {
624*03ce13f7SAndroid Build Coastguard Worker 	return *this = SIMD::Float(rhs);
625*03ce13f7SAndroid Build Coastguard Worker }
626*03ce13f7SAndroid Build Coastguard Worker 
operator +(RValue<SIMD::Float> lhs,RValue<SIMD::Float> rhs)627*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator+(RValue<SIMD::Float> lhs, RValue<SIMD::Float> rhs)
628*03ce13f7SAndroid Build Coastguard Worker {
629*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Float>(Nucleus::createFAdd(lhs.value(), rhs.value()));
630*03ce13f7SAndroid Build Coastguard Worker }
631*03ce13f7SAndroid Build Coastguard Worker 
operator -(RValue<SIMD::Float> lhs,RValue<SIMD::Float> rhs)632*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator-(RValue<SIMD::Float> lhs, RValue<SIMD::Float> rhs)
633*03ce13f7SAndroid Build Coastguard Worker {
634*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Float>(Nucleus::createFSub(lhs.value(), rhs.value()));
635*03ce13f7SAndroid Build Coastguard Worker }
636*03ce13f7SAndroid Build Coastguard Worker 
operator *(RValue<SIMD::Float> lhs,RValue<SIMD::Float> rhs)637*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator*(RValue<SIMD::Float> lhs, RValue<SIMD::Float> rhs)
638*03ce13f7SAndroid Build Coastguard Worker {
639*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Float>(Nucleus::createFMul(lhs.value(), rhs.value()));
640*03ce13f7SAndroid Build Coastguard Worker }
641*03ce13f7SAndroid Build Coastguard Worker 
operator /(RValue<SIMD::Float> lhs,RValue<SIMD::Float> rhs)642*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator/(RValue<SIMD::Float> lhs, RValue<SIMD::Float> rhs)
643*03ce13f7SAndroid Build Coastguard Worker {
644*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Float>(Nucleus::createFDiv(lhs.value(), rhs.value()));
645*03ce13f7SAndroid Build Coastguard Worker }
646*03ce13f7SAndroid Build Coastguard Worker 
operator +=(SIMD::Float & lhs,RValue<SIMD::Float> rhs)647*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator+=(SIMD::Float &lhs, RValue<SIMD::Float> rhs)
648*03ce13f7SAndroid Build Coastguard Worker {
649*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs + rhs;
650*03ce13f7SAndroid Build Coastguard Worker }
651*03ce13f7SAndroid Build Coastguard Worker 
operator -=(SIMD::Float & lhs,RValue<SIMD::Float> rhs)652*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator-=(SIMD::Float &lhs, RValue<SIMD::Float> rhs)
653*03ce13f7SAndroid Build Coastguard Worker {
654*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs - rhs;
655*03ce13f7SAndroid Build Coastguard Worker }
656*03ce13f7SAndroid Build Coastguard Worker 
operator *=(SIMD::Float & lhs,RValue<SIMD::Float> rhs)657*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator*=(SIMD::Float &lhs, RValue<SIMD::Float> rhs)
658*03ce13f7SAndroid Build Coastguard Worker {
659*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs * rhs;
660*03ce13f7SAndroid Build Coastguard Worker }
661*03ce13f7SAndroid Build Coastguard Worker 
operator /=(SIMD::Float & lhs,RValue<SIMD::Float> rhs)662*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator/=(SIMD::Float &lhs, RValue<SIMD::Float> rhs)
663*03ce13f7SAndroid Build Coastguard Worker {
664*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs / rhs;
665*03ce13f7SAndroid Build Coastguard Worker }
666*03ce13f7SAndroid Build Coastguard Worker 
operator %=(SIMD::Float & lhs,RValue<SIMD::Float> rhs)667*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator%=(SIMD::Float &lhs, RValue<SIMD::Float> rhs)
668*03ce13f7SAndroid Build Coastguard Worker {
669*03ce13f7SAndroid Build Coastguard Worker 	return lhs = lhs % rhs;
670*03ce13f7SAndroid Build Coastguard Worker }
671*03ce13f7SAndroid Build Coastguard Worker 
operator +(RValue<SIMD::Float> val)672*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator+(RValue<SIMD::Float> val)
673*03ce13f7SAndroid Build Coastguard Worker {
674*03ce13f7SAndroid Build Coastguard Worker 	return val;
675*03ce13f7SAndroid Build Coastguard Worker }
676*03ce13f7SAndroid Build Coastguard Worker 
operator -(RValue<SIMD::Float> val)677*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> operator-(RValue<SIMD::Float> val)
678*03ce13f7SAndroid Build Coastguard Worker {
679*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Float>(Nucleus::createFNeg(val.value()));
680*03ce13f7SAndroid Build Coastguard Worker }
681*03ce13f7SAndroid Build Coastguard Worker 
Rcp(RValue<SIMD::Float> x,bool relaxedPrecision,bool exactAtPow2)682*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Rcp(RValue<SIMD::Float> x, bool relaxedPrecision, bool exactAtPow2)
683*03ce13f7SAndroid Build Coastguard Worker {
684*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
685*03ce13f7SAndroid Build Coastguard Worker 	return SIMD::Float(Rcp(Extract128(x, 0), relaxedPrecision, exactAtPow2));
686*03ce13f7SAndroid Build Coastguard Worker }
687*03ce13f7SAndroid Build Coastguard Worker 
RcpSqrt(RValue<SIMD::Float> x,bool relaxedPrecision)688*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> RcpSqrt(RValue<SIMD::Float> x, bool relaxedPrecision)
689*03ce13f7SAndroid Build Coastguard Worker {
690*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
691*03ce13f7SAndroid Build Coastguard Worker 	return SIMD::Float(RcpSqrt(Extract128(x, 0), relaxedPrecision));
692*03ce13f7SAndroid Build Coastguard Worker }
693*03ce13f7SAndroid Build Coastguard Worker 
Insert(RValue<SIMD::Float> x,RValue<scalar::Float> element,int i)694*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Insert(RValue<SIMD::Float> x, RValue<scalar::Float> element, int i)
695*03ce13f7SAndroid Build Coastguard Worker {
696*03ce13f7SAndroid Build Coastguard Worker 	return RValue<SIMD::Float>(Nucleus::createInsertElement(x.value(), element.value(), i));
697*03ce13f7SAndroid Build Coastguard Worker }
698*03ce13f7SAndroid Build Coastguard Worker 
Extract(RValue<SIMD::Float> x,int i)699*03ce13f7SAndroid Build Coastguard Worker RValue<scalar::Float> Extract(RValue<SIMD::Float> x, int i)
700*03ce13f7SAndroid Build Coastguard Worker {
701*03ce13f7SAndroid Build Coastguard Worker 	return RValue<scalar::Float>(Nucleus::createExtractElement(x.value(), scalar::Float::type(), i));
702*03ce13f7SAndroid Build Coastguard Worker }
703*03ce13f7SAndroid Build Coastguard Worker 
IsInf(RValue<SIMD::Float> x)704*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> IsInf(RValue<SIMD::Float> x)
705*03ce13f7SAndroid Build Coastguard Worker {
706*03ce13f7SAndroid Build Coastguard Worker 	return CmpEQ(As<SIMD::Int>(x) & SIMD::Int(0x7FFFFFFF), SIMD::Int(0x7F800000));
707*03ce13f7SAndroid Build Coastguard Worker }
708*03ce13f7SAndroid Build Coastguard Worker 
IsNan(RValue<SIMD::Float> x)709*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> IsNan(RValue<SIMD::Float> x)
710*03ce13f7SAndroid Build Coastguard Worker {
711*03ce13f7SAndroid Build Coastguard Worker 	return ~CmpEQ(x, x);
712*03ce13f7SAndroid Build Coastguard Worker }
713*03ce13f7SAndroid Build Coastguard Worker 
Sin(RValue<SIMD::Float> x)714*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Sin(RValue<SIMD::Float> x)
715*03ce13f7SAndroid Build Coastguard Worker {
716*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(sinf, x);
717*03ce13f7SAndroid Build Coastguard Worker }
718*03ce13f7SAndroid Build Coastguard Worker 
Cos(RValue<SIMD::Float> x)719*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Cos(RValue<SIMD::Float> x)
720*03ce13f7SAndroid Build Coastguard Worker {
721*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(cosf, x);
722*03ce13f7SAndroid Build Coastguard Worker }
723*03ce13f7SAndroid Build Coastguard Worker 
Tan(RValue<SIMD::Float> x)724*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Tan(RValue<SIMD::Float> x)
725*03ce13f7SAndroid Build Coastguard Worker {
726*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(tanf, x);
727*03ce13f7SAndroid Build Coastguard Worker }
728*03ce13f7SAndroid Build Coastguard Worker 
Asin(RValue<SIMD::Float> x)729*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Asin(RValue<SIMD::Float> x)
730*03ce13f7SAndroid Build Coastguard Worker {
731*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(asinf, x);
732*03ce13f7SAndroid Build Coastguard Worker }
733*03ce13f7SAndroid Build Coastguard Worker 
Acos(RValue<SIMD::Float> x)734*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Acos(RValue<SIMD::Float> x)
735*03ce13f7SAndroid Build Coastguard Worker {
736*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(acosf, x);
737*03ce13f7SAndroid Build Coastguard Worker }
738*03ce13f7SAndroid Build Coastguard Worker 
Atan(RValue<SIMD::Float> x)739*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Atan(RValue<SIMD::Float> x)
740*03ce13f7SAndroid Build Coastguard Worker {
741*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(atanf, x);
742*03ce13f7SAndroid Build Coastguard Worker }
743*03ce13f7SAndroid Build Coastguard Worker 
Sinh(RValue<SIMD::Float> x)744*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Sinh(RValue<SIMD::Float> x)
745*03ce13f7SAndroid Build Coastguard Worker {
746*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(sinhf, x);
747*03ce13f7SAndroid Build Coastguard Worker }
748*03ce13f7SAndroid Build Coastguard Worker 
Cosh(RValue<SIMD::Float> x)749*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Cosh(RValue<SIMD::Float> x)
750*03ce13f7SAndroid Build Coastguard Worker {
751*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(coshf, x);
752*03ce13f7SAndroid Build Coastguard Worker }
753*03ce13f7SAndroid Build Coastguard Worker 
Tanh(RValue<SIMD::Float> x)754*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Tanh(RValue<SIMD::Float> x)
755*03ce13f7SAndroid Build Coastguard Worker {
756*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(tanhf, x);
757*03ce13f7SAndroid Build Coastguard Worker }
758*03ce13f7SAndroid Build Coastguard Worker 
Asinh(RValue<SIMD::Float> x)759*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Asinh(RValue<SIMD::Float> x)
760*03ce13f7SAndroid Build Coastguard Worker {
761*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(asinhf, x);
762*03ce13f7SAndroid Build Coastguard Worker }
763*03ce13f7SAndroid Build Coastguard Worker 
Acosh(RValue<SIMD::Float> x)764*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Acosh(RValue<SIMD::Float> x)
765*03ce13f7SAndroid Build Coastguard Worker {
766*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(acoshf, x);
767*03ce13f7SAndroid Build Coastguard Worker }
768*03ce13f7SAndroid Build Coastguard Worker 
Atanh(RValue<SIMD::Float> x)769*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Atanh(RValue<SIMD::Float> x)
770*03ce13f7SAndroid Build Coastguard Worker {
771*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(atanhf, x);
772*03ce13f7SAndroid Build Coastguard Worker }
773*03ce13f7SAndroid Build Coastguard Worker 
Atan2(RValue<SIMD::Float> x,RValue<SIMD::Float> y)774*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Atan2(RValue<SIMD::Float> x, RValue<SIMD::Float> y)
775*03ce13f7SAndroid Build Coastguard Worker {
776*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(atan2f, x, y);
777*03ce13f7SAndroid Build Coastguard Worker }
778*03ce13f7SAndroid Build Coastguard Worker 
Pow(RValue<SIMD::Float> x,RValue<SIMD::Float> y)779*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Pow(RValue<SIMD::Float> x, RValue<SIMD::Float> y)
780*03ce13f7SAndroid Build Coastguard Worker {
781*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(powf, x, y);
782*03ce13f7SAndroid Build Coastguard Worker }
783*03ce13f7SAndroid Build Coastguard Worker 
Exp(RValue<SIMD::Float> x)784*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Exp(RValue<SIMD::Float> x)
785*03ce13f7SAndroid Build Coastguard Worker {
786*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(expf, x);
787*03ce13f7SAndroid Build Coastguard Worker }
788*03ce13f7SAndroid Build Coastguard Worker 
Log(RValue<SIMD::Float> x)789*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Log(RValue<SIMD::Float> x)
790*03ce13f7SAndroid Build Coastguard Worker {
791*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(logf, x);
792*03ce13f7SAndroid Build Coastguard Worker }
793*03ce13f7SAndroid Build Coastguard Worker 
Exp2(RValue<SIMD::Float> x)794*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Exp2(RValue<SIMD::Float> x)
795*03ce13f7SAndroid Build Coastguard Worker {
796*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(exp2f, x);
797*03ce13f7SAndroid Build Coastguard Worker }
798*03ce13f7SAndroid Build Coastguard Worker 
Log2(RValue<SIMD::Float> x)799*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Log2(RValue<SIMD::Float> x)
800*03ce13f7SAndroid Build Coastguard Worker {
801*03ce13f7SAndroid Build Coastguard Worker 	return ScalarizeCall(log2f, x);
802*03ce13f7SAndroid Build Coastguard Worker }
803*03ce13f7SAndroid Build Coastguard Worker 
SignMask(RValue<SIMD::Int> x)804*03ce13f7SAndroid Build Coastguard Worker RValue<Int> SignMask(RValue<SIMD::Int> x)
805*03ce13f7SAndroid Build Coastguard Worker {
806*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
807*03ce13f7SAndroid Build Coastguard Worker 	return SignMask(Extract128(x, 0));
808*03ce13f7SAndroid Build Coastguard Worker }
809*03ce13f7SAndroid Build Coastguard Worker 
Ctlz(RValue<SIMD::UInt> x,bool isZeroUndef)810*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> Ctlz(RValue<SIMD::UInt> x, bool isZeroUndef)
811*03ce13f7SAndroid Build Coastguard Worker {
812*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
813*03ce13f7SAndroid Build Coastguard Worker 	SIMD::UInt result;
814*03ce13f7SAndroid Build Coastguard Worker 	return Insert128(result, Ctlz(Extract128(x, 0), isZeroUndef), 0);
815*03ce13f7SAndroid Build Coastguard Worker }
816*03ce13f7SAndroid Build Coastguard Worker 
Cttz(RValue<SIMD::UInt> x,bool isZeroUndef)817*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> Cttz(RValue<SIMD::UInt> x, bool isZeroUndef)
818*03ce13f7SAndroid Build Coastguard Worker {
819*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
820*03ce13f7SAndroid Build Coastguard Worker 	SIMD::UInt result;
821*03ce13f7SAndroid Build Coastguard Worker 	return Insert128(result, Cttz(Extract128(x, 0), isZeroUndef), 0);
822*03ce13f7SAndroid Build Coastguard Worker }
823*03ce13f7SAndroid Build Coastguard Worker 
MulHigh(RValue<SIMD::Int> x,RValue<SIMD::Int> y)824*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> MulHigh(RValue<SIMD::Int> x, RValue<SIMD::Int> y)
825*03ce13f7SAndroid Build Coastguard Worker {
826*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
827*03ce13f7SAndroid Build Coastguard Worker 	SIMD::Int result;
828*03ce13f7SAndroid Build Coastguard Worker 	return Insert128(result, MulHigh(Extract128(x, 0), Extract128(y, 0)), 0);
829*03ce13f7SAndroid Build Coastguard Worker }
830*03ce13f7SAndroid Build Coastguard Worker 
MulHigh(RValue<SIMD::UInt> x,RValue<SIMD::UInt> y)831*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> MulHigh(RValue<SIMD::UInt> x, RValue<SIMD::UInt> y)
832*03ce13f7SAndroid Build Coastguard Worker {
833*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
834*03ce13f7SAndroid Build Coastguard Worker 	SIMD::UInt result;
835*03ce13f7SAndroid Build Coastguard Worker 	return Insert128(result, MulHigh(Extract128(x, 0), Extract128(y, 0)), 0);
836*03ce13f7SAndroid Build Coastguard Worker }
837*03ce13f7SAndroid Build Coastguard Worker 
AnyTrue(const RValue<SIMD::Int> & bools)838*03ce13f7SAndroid Build Coastguard Worker RValue<Bool> AnyTrue(const RValue<SIMD::Int> &bools)
839*03ce13f7SAndroid Build Coastguard Worker {
840*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
841*03ce13f7SAndroid Build Coastguard Worker 	return AnyTrue(Extract128(bools, 0));
842*03ce13f7SAndroid Build Coastguard Worker }
843*03ce13f7SAndroid Build Coastguard Worker 
AnyFalse(const RValue<SIMD::Int> & bools)844*03ce13f7SAndroid Build Coastguard Worker RValue<Bool> AnyFalse(const RValue<SIMD::Int> &bools)
845*03ce13f7SAndroid Build Coastguard Worker {
846*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
847*03ce13f7SAndroid Build Coastguard Worker 	return AnyFalse(Extract128(bools, 0));
848*03ce13f7SAndroid Build Coastguard Worker }
849*03ce13f7SAndroid Build Coastguard Worker 
Divergent(const RValue<SIMD::Int> & ints)850*03ce13f7SAndroid Build Coastguard Worker RValue<Bool> Divergent(const RValue<SIMD::Int> &ints)
851*03ce13f7SAndroid Build Coastguard Worker {
852*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
853*03ce13f7SAndroid Build Coastguard Worker 	return Divergent(Extract128(ints, 0));
854*03ce13f7SAndroid Build Coastguard Worker }
855*03ce13f7SAndroid Build Coastguard Worker 
Swizzle(RValue<SIMD::Int> x,uint16_t select)856*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> Swizzle(RValue<SIMD::Int> x, uint16_t select)
857*03ce13f7SAndroid Build Coastguard Worker {
858*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
859*03ce13f7SAndroid Build Coastguard Worker 	SIMD::Int result;
860*03ce13f7SAndroid Build Coastguard Worker 	return Insert128(result, Swizzle(Extract128(x, 0), select), 0);
861*03ce13f7SAndroid Build Coastguard Worker }
862*03ce13f7SAndroid Build Coastguard Worker 
Swizzle(RValue<SIMD::UInt> x,uint16_t select)863*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> Swizzle(RValue<SIMD::UInt> x, uint16_t select)
864*03ce13f7SAndroid Build Coastguard Worker {
865*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
866*03ce13f7SAndroid Build Coastguard Worker 	SIMD::UInt result;
867*03ce13f7SAndroid Build Coastguard Worker 	return Insert128(result, Swizzle(Extract128(x, 0), select), 0);
868*03ce13f7SAndroid Build Coastguard Worker }
869*03ce13f7SAndroid Build Coastguard Worker 
Swizzle(RValue<SIMD::Float> x,uint16_t select)870*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Swizzle(RValue<SIMD::Float> x, uint16_t select)
871*03ce13f7SAndroid Build Coastguard Worker {
872*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
873*03ce13f7SAndroid Build Coastguard Worker 	SIMD::Float result;
874*03ce13f7SAndroid Build Coastguard Worker 	return Insert128(result, Swizzle(Extract128(x, 0), select), 0);
875*03ce13f7SAndroid Build Coastguard Worker }
876*03ce13f7SAndroid Build Coastguard Worker 
Shuffle(RValue<SIMD::Int> x,RValue<SIMD::Int> y,uint16_t select)877*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> Shuffle(RValue<SIMD::Int> x, RValue<SIMD::Int> y, uint16_t select)
878*03ce13f7SAndroid Build Coastguard Worker {
879*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
880*03ce13f7SAndroid Build Coastguard Worker 	SIMD::Int result;
881*03ce13f7SAndroid Build Coastguard Worker 	return Insert128(result, Shuffle(Extract128(x, 0), Extract128(y, 0), select), 0);
882*03ce13f7SAndroid Build Coastguard Worker }
883*03ce13f7SAndroid Build Coastguard Worker 
Shuffle(RValue<SIMD::UInt> x,RValue<SIMD::UInt> y,uint16_t select)884*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::UInt> Shuffle(RValue<SIMD::UInt> x, RValue<SIMD::UInt> y, uint16_t select)
885*03ce13f7SAndroid Build Coastguard Worker {
886*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
887*03ce13f7SAndroid Build Coastguard Worker 	SIMD::UInt result;
888*03ce13f7SAndroid Build Coastguard Worker 	return Insert128(result, Shuffle(Extract128(x, 0), Extract128(y, 0), select), 0);
889*03ce13f7SAndroid Build Coastguard Worker }
890*03ce13f7SAndroid Build Coastguard Worker 
Shuffle(RValue<SIMD::Float> x,RValue<SIMD::Float> y,uint16_t select)891*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Float> Shuffle(RValue<SIMD::Float> x, RValue<SIMD::Float> y, uint16_t select)
892*03ce13f7SAndroid Build Coastguard Worker {
893*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(SIMD::Width == 4);
894*03ce13f7SAndroid Build Coastguard Worker 	SIMD::Float result;
895*03ce13f7SAndroid Build Coastguard Worker 	return Insert128(result, Shuffle(Extract128(x, 0), Extract128(y, 0), select), 0);
896*03ce13f7SAndroid Build Coastguard Worker }
897*03ce13f7SAndroid Build Coastguard Worker 
Pointer(scalar::Pointer<Byte> base,rr::Int limit)898*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer::Pointer(scalar::Pointer<Byte> base, rr::Int limit)
899*03ce13f7SAndroid Build Coastguard Worker     : base(base)
900*03ce13f7SAndroid Build Coastguard Worker     , dynamicLimit(limit)
901*03ce13f7SAndroid Build Coastguard Worker     , staticLimit(0)
902*03ce13f7SAndroid Build Coastguard Worker     , dynamicOffsets(0)
903*03ce13f7SAndroid Build Coastguard Worker     , staticOffsets(SIMD::Width)
904*03ce13f7SAndroid Build Coastguard Worker     , hasDynamicLimit(true)
905*03ce13f7SAndroid Build Coastguard Worker     , hasDynamicOffsets(false)
906*03ce13f7SAndroid Build Coastguard Worker     , isBasePlusOffset(true)
907*03ce13f7SAndroid Build Coastguard Worker {}
908*03ce13f7SAndroid Build Coastguard Worker 
Pointer(scalar::Pointer<Byte> base,unsigned int limit)909*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer::Pointer(scalar::Pointer<Byte> base, unsigned int limit)
910*03ce13f7SAndroid Build Coastguard Worker     : base(base)
911*03ce13f7SAndroid Build Coastguard Worker     , dynamicLimit(0)
912*03ce13f7SAndroid Build Coastguard Worker     , staticLimit(limit)
913*03ce13f7SAndroid Build Coastguard Worker     , dynamicOffsets(0)
914*03ce13f7SAndroid Build Coastguard Worker     , staticOffsets(SIMD::Width)
915*03ce13f7SAndroid Build Coastguard Worker     , hasDynamicLimit(false)
916*03ce13f7SAndroid Build Coastguard Worker     , hasDynamicOffsets(false)
917*03ce13f7SAndroid Build Coastguard Worker     , isBasePlusOffset(true)
918*03ce13f7SAndroid Build Coastguard Worker {}
919*03ce13f7SAndroid Build Coastguard Worker 
Pointer(scalar::Pointer<Byte> base,rr::Int limit,SIMD::Int offset)920*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer::Pointer(scalar::Pointer<Byte> base, rr::Int limit, SIMD::Int offset)
921*03ce13f7SAndroid Build Coastguard Worker     : base(base)
922*03ce13f7SAndroid Build Coastguard Worker     , dynamicLimit(limit)
923*03ce13f7SAndroid Build Coastguard Worker     , staticLimit(0)
924*03ce13f7SAndroid Build Coastguard Worker     , dynamicOffsets(offset)
925*03ce13f7SAndroid Build Coastguard Worker     , staticOffsets(SIMD::Width)
926*03ce13f7SAndroid Build Coastguard Worker     , hasDynamicLimit(true)
927*03ce13f7SAndroid Build Coastguard Worker     , hasDynamicOffsets(true)
928*03ce13f7SAndroid Build Coastguard Worker     , isBasePlusOffset(true)
929*03ce13f7SAndroid Build Coastguard Worker {}
930*03ce13f7SAndroid Build Coastguard Worker 
Pointer(scalar::Pointer<Byte> base,unsigned int limit,SIMD::Int offset)931*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer::Pointer(scalar::Pointer<Byte> base, unsigned int limit, SIMD::Int offset)
932*03ce13f7SAndroid Build Coastguard Worker     : base(base)
933*03ce13f7SAndroid Build Coastguard Worker     , dynamicLimit(0)
934*03ce13f7SAndroid Build Coastguard Worker     , staticLimit(limit)
935*03ce13f7SAndroid Build Coastguard Worker     , dynamicOffsets(offset)
936*03ce13f7SAndroid Build Coastguard Worker     , staticOffsets(SIMD::Width)
937*03ce13f7SAndroid Build Coastguard Worker     , hasDynamicLimit(false)
938*03ce13f7SAndroid Build Coastguard Worker     , hasDynamicOffsets(true)
939*03ce13f7SAndroid Build Coastguard Worker     , isBasePlusOffset(true)
940*03ce13f7SAndroid Build Coastguard Worker {}
941*03ce13f7SAndroid Build Coastguard Worker 
Pointer(std::vector<scalar::Pointer<Byte>> pointers)942*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer::Pointer(std::vector<scalar::Pointer<Byte>> pointers)
943*03ce13f7SAndroid Build Coastguard Worker     : pointers(pointers)
944*03ce13f7SAndroid Build Coastguard Worker     , isBasePlusOffset(false)
945*03ce13f7SAndroid Build Coastguard Worker {}
946*03ce13f7SAndroid Build Coastguard Worker 
Pointer(SIMD::UInt cast)947*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer::Pointer(SIMD::UInt cast)
948*03ce13f7SAndroid Build Coastguard Worker     : pointers(SIMD::Width)
949*03ce13f7SAndroid Build Coastguard Worker     , isBasePlusOffset(false)
950*03ce13f7SAndroid Build Coastguard Worker {
951*03ce13f7SAndroid Build Coastguard Worker 	assert(sizeof(void *) == 4);
952*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 0; i < SIMD::Width; i++)
953*03ce13f7SAndroid Build Coastguard Worker 	{
954*03ce13f7SAndroid Build Coastguard Worker 		pointers[i] = As<rr::Pointer<Byte>>(Extract(cast, i));
955*03ce13f7SAndroid Build Coastguard Worker 	}
956*03ce13f7SAndroid Build Coastguard Worker }
957*03ce13f7SAndroid Build Coastguard Worker 
Pointer(SIMD::UInt castLow,SIMD::UInt castHigh)958*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer::Pointer(SIMD::UInt castLow, SIMD::UInt castHigh)
959*03ce13f7SAndroid Build Coastguard Worker     : pointers(SIMD::Width)
960*03ce13f7SAndroid Build Coastguard Worker     , isBasePlusOffset(false)
961*03ce13f7SAndroid Build Coastguard Worker {
962*03ce13f7SAndroid Build Coastguard Worker 	assert(sizeof(void *) == 8);
963*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 0; i < SIMD::Width; i++)
964*03ce13f7SAndroid Build Coastguard Worker 	{
965*03ce13f7SAndroid Build Coastguard Worker 		UInt2 address;
966*03ce13f7SAndroid Build Coastguard Worker 		address = Insert(address, Extract(castLow, i), 0);
967*03ce13f7SAndroid Build Coastguard Worker 		address = Insert(address, Extract(castHigh, i), 1);
968*03ce13f7SAndroid Build Coastguard Worker 		pointers[i] = As<rr::Pointer<Byte>>(address);
969*03ce13f7SAndroid Build Coastguard Worker 	}
970*03ce13f7SAndroid Build Coastguard Worker }
971*03ce13f7SAndroid Build Coastguard Worker 
operator +=(SIMD::Int i)972*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer &SIMD::Pointer::operator+=(SIMD::Int i)
973*03ce13f7SAndroid Build Coastguard Worker {
974*03ce13f7SAndroid Build Coastguard Worker 	if(isBasePlusOffset)
975*03ce13f7SAndroid Build Coastguard Worker 	{
976*03ce13f7SAndroid Build Coastguard Worker 		dynamicOffsets += i;
977*03ce13f7SAndroid Build Coastguard Worker 		hasDynamicOffsets = true;
978*03ce13f7SAndroid Build Coastguard Worker 	}
979*03ce13f7SAndroid Build Coastguard Worker 	else
980*03ce13f7SAndroid Build Coastguard Worker 	{
981*03ce13f7SAndroid Build Coastguard Worker 		for(int el = 0; el < SIMD::Width; el++) { pointers[el] += Extract(i, el); }
982*03ce13f7SAndroid Build Coastguard Worker 	}
983*03ce13f7SAndroid Build Coastguard Worker 	return *this;
984*03ce13f7SAndroid Build Coastguard Worker }
985*03ce13f7SAndroid Build Coastguard Worker 
operator +(SIMD::Int i)986*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer SIMD::Pointer::operator+(SIMD::Int i)
987*03ce13f7SAndroid Build Coastguard Worker {
988*03ce13f7SAndroid Build Coastguard Worker 	SIMD::Pointer p = *this;
989*03ce13f7SAndroid Build Coastguard Worker 	p += i;
990*03ce13f7SAndroid Build Coastguard Worker 	return p;
991*03ce13f7SAndroid Build Coastguard Worker }
992*03ce13f7SAndroid Build Coastguard Worker 
operator +=(int i)993*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer &SIMD::Pointer::operator+=(int i)
994*03ce13f7SAndroid Build Coastguard Worker {
995*03ce13f7SAndroid Build Coastguard Worker 	if(isBasePlusOffset)
996*03ce13f7SAndroid Build Coastguard Worker 	{
997*03ce13f7SAndroid Build Coastguard Worker 		for(int el = 0; el < SIMD::Width; el++) { staticOffsets[el] += i; }
998*03ce13f7SAndroid Build Coastguard Worker 	}
999*03ce13f7SAndroid Build Coastguard Worker 	else
1000*03ce13f7SAndroid Build Coastguard Worker 	{
1001*03ce13f7SAndroid Build Coastguard Worker 		for(int el = 0; el < SIMD::Width; el++) { pointers[el] += i; }
1002*03ce13f7SAndroid Build Coastguard Worker 	}
1003*03ce13f7SAndroid Build Coastguard Worker 	return *this;
1004*03ce13f7SAndroid Build Coastguard Worker }
1005*03ce13f7SAndroid Build Coastguard Worker 
operator +(int i)1006*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer SIMD::Pointer::operator+(int i)
1007*03ce13f7SAndroid Build Coastguard Worker {
1008*03ce13f7SAndroid Build Coastguard Worker 	SIMD::Pointer p = *this;
1009*03ce13f7SAndroid Build Coastguard Worker 	p += i;
1010*03ce13f7SAndroid Build Coastguard Worker 	return p;
1011*03ce13f7SAndroid Build Coastguard Worker }
1012*03ce13f7SAndroid Build Coastguard Worker 
offsets() const1013*03ce13f7SAndroid Build Coastguard Worker SIMD::Int SIMD::Pointer::offsets() const
1014*03ce13f7SAndroid Build Coastguard Worker {
1015*03ce13f7SAndroid Build Coastguard Worker 	ASSERT_MSG(isBasePlusOffset, "No offsets for this type of pointer");
1016*03ce13f7SAndroid Build Coastguard Worker 	return dynamicOffsets + SIMD::Int(staticOffsets);
1017*03ce13f7SAndroid Build Coastguard Worker }
1018*03ce13f7SAndroid Build Coastguard Worker 
isInBounds(unsigned int accessSize,OutOfBoundsBehavior robustness) const1019*03ce13f7SAndroid Build Coastguard Worker SIMD::Int SIMD::Pointer::isInBounds(unsigned int accessSize, OutOfBoundsBehavior robustness) const
1020*03ce13f7SAndroid Build Coastguard Worker {
1021*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(accessSize > 0);
1022*03ce13f7SAndroid Build Coastguard Worker 
1023*03ce13f7SAndroid Build Coastguard Worker 	if(isStaticallyInBounds(accessSize, robustness))
1024*03ce13f7SAndroid Build Coastguard Worker 	{
1025*03ce13f7SAndroid Build Coastguard Worker 		return SIMD::Int(0xFFFFFFFF);
1026*03ce13f7SAndroid Build Coastguard Worker 	}
1027*03ce13f7SAndroid Build Coastguard Worker 
1028*03ce13f7SAndroid Build Coastguard Worker 	if(!hasDynamicOffsets && !hasDynamicLimit)
1029*03ce13f7SAndroid Build Coastguard Worker 	{
1030*03ce13f7SAndroid Build Coastguard Worker 		ASSERT(SIMD::Width == 4);
1031*03ce13f7SAndroid Build Coastguard Worker 		// Common fast paths.
1032*03ce13f7SAndroid Build Coastguard Worker 		return SIMD::Int(
1033*03ce13f7SAndroid Build Coastguard Worker 		    (staticOffsets[0] + accessSize - 1 < staticLimit) ? 0xFFFFFFFF : 0,
1034*03ce13f7SAndroid Build Coastguard Worker 		    (staticOffsets[1] + accessSize - 1 < staticLimit) ? 0xFFFFFFFF : 0,
1035*03ce13f7SAndroid Build Coastguard Worker 		    (staticOffsets[2] + accessSize - 1 < staticLimit) ? 0xFFFFFFFF : 0,
1036*03ce13f7SAndroid Build Coastguard Worker 		    (staticOffsets[3] + accessSize - 1 < staticLimit) ? 0xFFFFFFFF : 0);
1037*03ce13f7SAndroid Build Coastguard Worker 	}
1038*03ce13f7SAndroid Build Coastguard Worker 
1039*03ce13f7SAndroid Build Coastguard Worker 	return CmpGE(offsets(), 0) & CmpLT(offsets() + SIMD::Int(accessSize - 1), limit());
1040*03ce13f7SAndroid Build Coastguard Worker }
1041*03ce13f7SAndroid Build Coastguard Worker 
isStaticallyInBounds(unsigned int accessSize,OutOfBoundsBehavior robustness) const1042*03ce13f7SAndroid Build Coastguard Worker bool SIMD::Pointer::isStaticallyInBounds(unsigned int accessSize, OutOfBoundsBehavior robustness) const
1043*03ce13f7SAndroid Build Coastguard Worker {
1044*03ce13f7SAndroid Build Coastguard Worker 	if(hasDynamicOffsets)
1045*03ce13f7SAndroid Build Coastguard Worker 	{
1046*03ce13f7SAndroid Build Coastguard Worker 		return false;
1047*03ce13f7SAndroid Build Coastguard Worker 	}
1048*03ce13f7SAndroid Build Coastguard Worker 
1049*03ce13f7SAndroid Build Coastguard Worker 	if(hasDynamicLimit)
1050*03ce13f7SAndroid Build Coastguard Worker 	{
1051*03ce13f7SAndroid Build Coastguard Worker 		if(hasStaticEqualOffsets() || hasStaticSequentialOffsets(accessSize))
1052*03ce13f7SAndroid Build Coastguard Worker 		{
1053*03ce13f7SAndroid Build Coastguard Worker 			switch(robustness)
1054*03ce13f7SAndroid Build Coastguard Worker 			{
1055*03ce13f7SAndroid Build Coastguard Worker 			case OutOfBoundsBehavior::UndefinedBehavior:
1056*03ce13f7SAndroid Build Coastguard Worker 				// With this robustness setting the application/compiler guarantees in-bounds accesses on active lanes,
1057*03ce13f7SAndroid Build Coastguard Worker 				// but since it can't know in advance which branches are taken this must be true even for inactives lanes.
1058*03ce13f7SAndroid Build Coastguard Worker 				return true;
1059*03ce13f7SAndroid Build Coastguard Worker 			case OutOfBoundsBehavior::Nullify:
1060*03ce13f7SAndroid Build Coastguard Worker 			case OutOfBoundsBehavior::RobustBufferAccess:
1061*03ce13f7SAndroid Build Coastguard Worker 			case OutOfBoundsBehavior::UndefinedValue:
1062*03ce13f7SAndroid Build Coastguard Worker 				return false;
1063*03ce13f7SAndroid Build Coastguard Worker 			}
1064*03ce13f7SAndroid Build Coastguard Worker 		}
1065*03ce13f7SAndroid Build Coastguard Worker 	}
1066*03ce13f7SAndroid Build Coastguard Worker 
1067*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 0; i < SIMD::Width; i++)
1068*03ce13f7SAndroid Build Coastguard Worker 	{
1069*03ce13f7SAndroid Build Coastguard Worker 		if(staticOffsets[i] + accessSize - 1 >= staticLimit)
1070*03ce13f7SAndroid Build Coastguard Worker 		{
1071*03ce13f7SAndroid Build Coastguard Worker 			return false;
1072*03ce13f7SAndroid Build Coastguard Worker 		}
1073*03ce13f7SAndroid Build Coastguard Worker 	}
1074*03ce13f7SAndroid Build Coastguard Worker 
1075*03ce13f7SAndroid Build Coastguard Worker 	return true;
1076*03ce13f7SAndroid Build Coastguard Worker }
1077*03ce13f7SAndroid Build Coastguard Worker 
limit() const1078*03ce13f7SAndroid Build Coastguard Worker SIMD::Int SIMD::Pointer::limit() const
1079*03ce13f7SAndroid Build Coastguard Worker {
1080*03ce13f7SAndroid Build Coastguard Worker 	return dynamicLimit + staticLimit;
1081*03ce13f7SAndroid Build Coastguard Worker }
1082*03ce13f7SAndroid Build Coastguard Worker 
1083*03ce13f7SAndroid Build Coastguard Worker // Returns true if all offsets are compile-time static and sequential
1084*03ce13f7SAndroid Build Coastguard Worker // (N+0*step, N+1*step, N+2*step, N+3*step)
hasStaticSequentialOffsets(unsigned int step) const1085*03ce13f7SAndroid Build Coastguard Worker bool SIMD::Pointer::hasStaticSequentialOffsets(unsigned int step) const
1086*03ce13f7SAndroid Build Coastguard Worker {
1087*03ce13f7SAndroid Build Coastguard Worker 	ASSERT_MSG(isBasePlusOffset, "No offsets for this type of pointer");
1088*03ce13f7SAndroid Build Coastguard Worker 	if(hasDynamicOffsets)
1089*03ce13f7SAndroid Build Coastguard Worker 	{
1090*03ce13f7SAndroid Build Coastguard Worker 		return false;
1091*03ce13f7SAndroid Build Coastguard Worker 	}
1092*03ce13f7SAndroid Build Coastguard Worker 
1093*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 1; i < SIMD::Width; i++)
1094*03ce13f7SAndroid Build Coastguard Worker 	{
1095*03ce13f7SAndroid Build Coastguard Worker 		if(staticOffsets[i - 1] + int32_t(step) != staticOffsets[i])
1096*03ce13f7SAndroid Build Coastguard Worker 		{
1097*03ce13f7SAndroid Build Coastguard Worker 			return false;
1098*03ce13f7SAndroid Build Coastguard Worker 		}
1099*03ce13f7SAndroid Build Coastguard Worker 	}
1100*03ce13f7SAndroid Build Coastguard Worker 
1101*03ce13f7SAndroid Build Coastguard Worker 	return true;
1102*03ce13f7SAndroid Build Coastguard Worker }
1103*03ce13f7SAndroid Build Coastguard Worker 
1104*03ce13f7SAndroid Build Coastguard Worker // Returns true if all offsets are compile-time static and equal
1105*03ce13f7SAndroid Build Coastguard Worker // (N, N, N, N)
hasStaticEqualOffsets() const1106*03ce13f7SAndroid Build Coastguard Worker bool SIMD::Pointer::hasStaticEqualOffsets() const
1107*03ce13f7SAndroid Build Coastguard Worker {
1108*03ce13f7SAndroid Build Coastguard Worker 	ASSERT_MSG(isBasePlusOffset, "No offsets for this type of pointer");
1109*03ce13f7SAndroid Build Coastguard Worker 	if(hasDynamicOffsets)
1110*03ce13f7SAndroid Build Coastguard Worker 	{
1111*03ce13f7SAndroid Build Coastguard Worker 		return false;
1112*03ce13f7SAndroid Build Coastguard Worker 	}
1113*03ce13f7SAndroid Build Coastguard Worker 
1114*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 1; i < SIMD::Width; i++)
1115*03ce13f7SAndroid Build Coastguard Worker 	{
1116*03ce13f7SAndroid Build Coastguard Worker 		if(staticOffsets[0] != staticOffsets[i])
1117*03ce13f7SAndroid Build Coastguard Worker 		{
1118*03ce13f7SAndroid Build Coastguard Worker 			return false;
1119*03ce13f7SAndroid Build Coastguard Worker 		}
1120*03ce13f7SAndroid Build Coastguard Worker 	}
1121*03ce13f7SAndroid Build Coastguard Worker 
1122*03ce13f7SAndroid Build Coastguard Worker 	return true;
1123*03ce13f7SAndroid Build Coastguard Worker }
1124*03ce13f7SAndroid Build Coastguard Worker 
getUniformPointer() const1125*03ce13f7SAndroid Build Coastguard Worker scalar::Pointer<Byte> SIMD::Pointer::getUniformPointer() const
1126*03ce13f7SAndroid Build Coastguard Worker {
1127*03ce13f7SAndroid Build Coastguard Worker #ifndef NDEBUG
1128*03ce13f7SAndroid Build Coastguard Worker 	if(isBasePlusOffset)
1129*03ce13f7SAndroid Build Coastguard Worker 	{
1130*03ce13f7SAndroid Build Coastguard Worker 		SIMD::Int uniform = offsets();
1131*03ce13f7SAndroid Build Coastguard Worker 		scalar::Int x = Extract(uniform, 0);
1132*03ce13f7SAndroid Build Coastguard Worker 
1133*03ce13f7SAndroid Build Coastguard Worker 		for(int i = 1; i < SIMD::Width; i++)
1134*03ce13f7SAndroid Build Coastguard Worker 		{
1135*03ce13f7SAndroid Build Coastguard Worker 			Assert(x == Extract(uniform, i));
1136*03ce13f7SAndroid Build Coastguard Worker 		}
1137*03ce13f7SAndroid Build Coastguard Worker 	}
1138*03ce13f7SAndroid Build Coastguard Worker 	else
1139*03ce13f7SAndroid Build Coastguard Worker 	{
1140*03ce13f7SAndroid Build Coastguard Worker 		for(int i = 1; i < SIMD::Width; i++)
1141*03ce13f7SAndroid Build Coastguard Worker 		{
1142*03ce13f7SAndroid Build Coastguard Worker 			Assert(pointers[0] == pointers[i]);
1143*03ce13f7SAndroid Build Coastguard Worker 		}
1144*03ce13f7SAndroid Build Coastguard Worker 	}
1145*03ce13f7SAndroid Build Coastguard Worker #endif
1146*03ce13f7SAndroid Build Coastguard Worker 
1147*03ce13f7SAndroid Build Coastguard Worker 	return getPointerForLane(0);
1148*03ce13f7SAndroid Build Coastguard Worker }
1149*03ce13f7SAndroid Build Coastguard Worker 
getPointerForLane(int lane) const1150*03ce13f7SAndroid Build Coastguard Worker scalar::Pointer<Byte> SIMD::Pointer::getPointerForLane(int lane) const
1151*03ce13f7SAndroid Build Coastguard Worker {
1152*03ce13f7SAndroid Build Coastguard Worker 	if(isBasePlusOffset)
1153*03ce13f7SAndroid Build Coastguard Worker 	{
1154*03ce13f7SAndroid Build Coastguard Worker 		return base + Extract(offsets(), lane);
1155*03ce13f7SAndroid Build Coastguard Worker 	}
1156*03ce13f7SAndroid Build Coastguard Worker 	else
1157*03ce13f7SAndroid Build Coastguard Worker 	{
1158*03ce13f7SAndroid Build Coastguard Worker 		return pointers[lane];
1159*03ce13f7SAndroid Build Coastguard Worker 	}
1160*03ce13f7SAndroid Build Coastguard Worker }
1161*03ce13f7SAndroid Build Coastguard Worker 
castTo(SIMD::UInt & bits) const1162*03ce13f7SAndroid Build Coastguard Worker void SIMD::Pointer::castTo(SIMD::UInt &bits) const
1163*03ce13f7SAndroid Build Coastguard Worker {
1164*03ce13f7SAndroid Build Coastguard Worker 	assert(sizeof(void *) == 4);
1165*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 0; i < SIMD::Width; i++)
1166*03ce13f7SAndroid Build Coastguard Worker 	{
1167*03ce13f7SAndroid Build Coastguard Worker 		bits = Insert(bits, As<scalar::UInt>(pointers[i]), i);
1168*03ce13f7SAndroid Build Coastguard Worker 	}
1169*03ce13f7SAndroid Build Coastguard Worker }
1170*03ce13f7SAndroid Build Coastguard Worker 
castTo(SIMD::UInt & lowerBits,SIMD::UInt & upperBits) const1171*03ce13f7SAndroid Build Coastguard Worker void SIMD::Pointer::castTo(SIMD::UInt &lowerBits, SIMD::UInt &upperBits) const
1172*03ce13f7SAndroid Build Coastguard Worker {
1173*03ce13f7SAndroid Build Coastguard Worker 	assert(sizeof(void *) == 8);
1174*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 0; i < SIMD::Width; i++)
1175*03ce13f7SAndroid Build Coastguard Worker 	{
1176*03ce13f7SAndroid Build Coastguard Worker 		UInt2 address = As<UInt2>(pointers[i]);
1177*03ce13f7SAndroid Build Coastguard Worker 		lowerBits = Insert(lowerBits, Extract(address, 0), i);
1178*03ce13f7SAndroid Build Coastguard Worker 		upperBits = Insert(upperBits, Extract(address, 1), i);
1179*03ce13f7SAndroid Build Coastguard Worker 	}
1180*03ce13f7SAndroid Build Coastguard Worker }
1181*03ce13f7SAndroid Build Coastguard Worker 
IfThenElse(SIMD::Int condition,const SIMD::Pointer & lhs,const SIMD::Pointer & rhs)1182*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer SIMD::Pointer::IfThenElse(SIMD::Int condition, const SIMD::Pointer &lhs, const SIMD::Pointer &rhs)
1183*03ce13f7SAndroid Build Coastguard Worker {
1184*03ce13f7SAndroid Build Coastguard Worker 	std::vector<scalar::Pointer<Byte>> pointers(SIMD::Width);
1185*03ce13f7SAndroid Build Coastguard Worker 	for(int i = 0; i < SIMD::Width; i++)
1186*03ce13f7SAndroid Build Coastguard Worker 	{
1187*03ce13f7SAndroid Build Coastguard Worker 		If(Extract(condition, i) != 0)
1188*03ce13f7SAndroid Build Coastguard Worker 		{
1189*03ce13f7SAndroid Build Coastguard Worker 			pointers[i] = lhs.getPointerForLane(i);
1190*03ce13f7SAndroid Build Coastguard Worker 		}
1191*03ce13f7SAndroid Build Coastguard Worker 		Else
1192*03ce13f7SAndroid Build Coastguard Worker 		{
1193*03ce13f7SAndroid Build Coastguard Worker 			pointers[i] = rhs.getPointerForLane(i);
1194*03ce13f7SAndroid Build Coastguard Worker 		}
1195*03ce13f7SAndroid Build Coastguard Worker 	}
1196*03ce13f7SAndroid Build Coastguard Worker 
1197*03ce13f7SAndroid Build Coastguard Worker 	return { pointers };
1198*03ce13f7SAndroid Build Coastguard Worker }
1199*03ce13f7SAndroid Build Coastguard Worker 
1200*03ce13f7SAndroid Build Coastguard Worker #ifdef ENABLE_RR_PRINT
getPrintValues() const1201*03ce13f7SAndroid Build Coastguard Worker std::vector<rr::Value *> SIMD::Pointer::getPrintValues() const
1202*03ce13f7SAndroid Build Coastguard Worker {
1203*03ce13f7SAndroid Build Coastguard Worker 	if(isBasePlusOffset)
1204*03ce13f7SAndroid Build Coastguard Worker 	{
1205*03ce13f7SAndroid Build Coastguard Worker 		return PrintValue::vals(base, offsets());
1206*03ce13f7SAndroid Build Coastguard Worker 	}
1207*03ce13f7SAndroid Build Coastguard Worker 	else
1208*03ce13f7SAndroid Build Coastguard Worker 	{
1209*03ce13f7SAndroid Build Coastguard Worker 		std::vector<Value *> vals;
1210*03ce13f7SAndroid Build Coastguard Worker 		for(int i = 0; i < SIMD::Width; i++)
1211*03ce13f7SAndroid Build Coastguard Worker 		{
1212*03ce13f7SAndroid Build Coastguard Worker 			vals.push_back(RValue<scalar::Pointer<Byte>>(pointers[i]).value());
1213*03ce13f7SAndroid Build Coastguard Worker 		}
1214*03ce13f7SAndroid Build Coastguard Worker 		return vals;
1215*03ce13f7SAndroid Build Coastguard Worker 	}
1216*03ce13f7SAndroid Build Coastguard Worker }
1217*03ce13f7SAndroid Build Coastguard Worker #endif
1218*03ce13f7SAndroid Build Coastguard Worker 
1219*03ce13f7SAndroid Build Coastguard Worker }  // namespace rr
1220