• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef _CONSTANT_UNION_INCLUDED_
16 #define _CONSTANT_UNION_INCLUDED_
17 
18 #ifndef __ANDROID__
19 #include <assert.h>
20 #else
21 #include "../../Common/DebugAndroid.hpp"
22 #endif
23 
24 class ConstantUnion {
25 public:
26 	POOL_ALLOCATOR_NEW_DELETE();
ConstantUnion()27 	ConstantUnion()
28 	{
29 		iConst = 0;
30 		type = EbtVoid;
31 	}
32 
cast(TBasicType newType,const ConstantUnion & constant)33 	bool cast(TBasicType newType, const ConstantUnion &constant)
34 	{
35 		switch (newType)
36 		{
37 		case EbtFloat:
38 			switch (constant.type)
39 			{
40 			case EbtInt:   setFConst(static_cast<float>(constant.getIConst())); break;
41 			case EbtUInt:  setFConst(static_cast<float>(constant.getUConst())); break;
42 			case EbtBool:  setFConst(static_cast<float>(constant.getBConst())); break;
43 			case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break;
44 			default:       return false;
45 			}
46 			break;
47 		case EbtInt:
48 			switch (constant.type)
49 			{
50 			case EbtInt:   setIConst(static_cast<int>(constant.getIConst())); break;
51 			case EbtUInt:  setIConst(static_cast<int>(constant.getUConst())); break;
52 			case EbtBool:  setIConst(static_cast<int>(constant.getBConst())); break;
53 			case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break;
54 			default:       return false;
55 			}
56 			break;
57 		case EbtUInt:
58 			switch (constant.type)
59 			{
60 			case EbtInt:   setUConst(static_cast<unsigned int>(constant.getIConst())); break;
61 			case EbtUInt:  setUConst(static_cast<unsigned int>(constant.getUConst())); break;
62 			case EbtBool:  setUConst(static_cast<unsigned int>(constant.getBConst())); break;
63 			case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break;
64 			default:       return false;
65 			}
66 			break;
67 		case EbtBool:
68 			switch (constant.type)
69 			{
70 			case EbtInt:   setBConst(constant.getIConst() != 0);    break;
71 			case EbtUInt:  setBConst(constant.getUConst() != 0);    break;
72 			case EbtBool:  setBConst(constant.getBConst());         break;
73 			case EbtFloat: setBConst(constant.getFConst() != 0.0f); break;
74 			default:       return false;
75 			}
76 			break;
77 		case EbtStruct:    // Struct fields don't get cast
78 			switch (constant.type)
79 			{
80 			case EbtInt:   setIConst(constant.getIConst()); break;
81 			case EbtUInt:  setUConst(constant.getUConst()); break;
82 			case EbtBool:  setBConst(constant.getBConst()); break;
83 			case EbtFloat: setFConst(constant.getFConst()); break;
84 			default:       return false;
85 			}
86 			break;
87 		default:
88 			return false;
89 		}
90 
91 		return true;
92 	}
93 
setIConst(int i)94 	void setIConst(int i) {iConst = i; type = EbtInt; }
setUConst(unsigned int u)95 	void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
setFConst(float f)96 	void setFConst(float f) {fConst = f; type = EbtFloat; }
setBConst(bool b)97 	void setBConst(bool b) {bConst = b; type = EbtBool; }
98 
getIConst()99 	int getIConst() const { return iConst; }
getUConst()100 	unsigned int getUConst() const { return uConst; }
getFConst()101 	float getFConst() const { return fConst; }
getBConst()102 	bool getBConst() const { return bConst; }
103 
getAsFloat()104 	float getAsFloat() const
105 	{
106 		const int FFFFFFFFh = 0xFFFFFFFF;
107 
108 		switch(type)
109 		{
110 		case EbtInt:   return reinterpret_cast<const float&>(iConst);
111 		case EbtUInt:  return reinterpret_cast<const float&>(uConst);
112 		case EbtFloat: return fConst;
113 		case EbtBool:  return (bConst == true) ? reinterpret_cast<const float&>(FFFFFFFFh) : 0;
114 		default:       return 0;
115 		}
116 	}
117 
118 	bool operator==(const int i) const
119 	{
120 		return i == iConst;
121 	}
122 
123 	bool operator==(const unsigned int u) const
124 	{
125 		return u == uConst;
126 	}
127 
128 	bool operator==(const float f) const
129 	{
130 		return f == fConst;
131 	}
132 
133 	bool operator==(const bool b) const
134 	{
135 		return b == bConst;
136 	}
137 
138 	bool operator==(const ConstantUnion& constant) const
139 	{
140 		if (constant.type != type)
141 			return false;
142 
143 		switch (type) {
144 		case EbtInt:
145 			return constant.iConst == iConst;
146 		case EbtUInt:
147 			return constant.uConst == uConst;
148 		case EbtFloat:
149 			return constant.fConst == fConst;
150 		case EbtBool:
151 			return constant.bConst == bConst;
152 		default:
153 			return false;
154 		}
155 	}
156 
157 	bool operator!=(const int i) const
158 	{
159 		return !operator==(i);
160 	}
161 
162 	bool operator!=(const unsigned int u) const
163 	{
164 		return !operator==(u);
165 	}
166 
167 	bool operator!=(const float f) const
168 	{
169 		return !operator==(f);
170 	}
171 
172 	bool operator!=(const bool b) const
173 	{
174 		return !operator==(b);
175 	}
176 
177 	bool operator!=(const ConstantUnion& constant) const
178 	{
179 		return !operator==(constant);
180 	}
181 
182 	bool operator>(const ConstantUnion& constant) const
183 	{
184 		assert(type == constant.type);
185 		switch (type) {
186 		case EbtInt:
187 			return iConst > constant.iConst;
188 		case EbtUInt:
189 			return uConst > constant.uConst;
190 		case EbtFloat:
191 			return fConst > constant.fConst;
192 		default:
193 			return false;   // Invalid operation, handled at semantic analysis
194 		}
195 	}
196 
197 	bool operator<(const ConstantUnion& constant) const
198 	{
199 		assert(type == constant.type);
200 		switch (type) {
201 		case EbtInt:
202 			return iConst < constant.iConst;
203 		case EbtUInt:
204 			return uConst < constant.uConst;
205 		case EbtFloat:
206 			return fConst < constant.fConst;
207 		default:
208 			return false;   // Invalid operation, handled at semantic analysis
209 		}
210 	}
211 
212 	bool operator<=(const ConstantUnion& constant) const
213 	{
214 		assert(type == constant.type);
215 		switch (type) {
216 		case EbtInt:
217 			return iConst <= constant.iConst;
218 		case EbtUInt:
219 			return uConst <= constant.uConst;
220 		case EbtFloat:
221 			return fConst <= constant.fConst;
222 		default:
223 			return false;   // Invalid operation, handled at semantic analysis
224 		}
225 	}
226 
227 	bool operator>=(const ConstantUnion& constant) const
228 	{
229 		assert(type == constant.type);
230 		switch (type) {
231 		case EbtInt:
232 			return iConst >= constant.iConst;
233 		case EbtUInt:
234 			return uConst >= constant.uConst;
235 		case EbtFloat:
236 			return fConst >= constant.fConst;
237 		default:
238 			return false;   // Invalid operation, handled at semantic analysis
239 		}
240 	}
241 
242 	ConstantUnion operator+(const ConstantUnion& constant) const
243 	{
244 		ConstantUnion returnValue;
245 		assert(type == constant.type);
246 		switch (type) {
247 		case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
248 		case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break;
249 		case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
250 		default: assert(false && "Default missing");
251 		}
252 
253 		return returnValue;
254 	}
255 
256 	ConstantUnion operator-(const ConstantUnion& constant) const
257 	{
258 		ConstantUnion returnValue;
259 		assert(type == constant.type);
260 		switch (type) {
261 		case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
262 		case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break;
263 		case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
264 		default: assert(false && "Default missing");
265 		}
266 
267 		return returnValue;
268 	}
269 
270 	ConstantUnion operator*(const ConstantUnion& constant) const
271 	{
272 		ConstantUnion returnValue;
273 		assert(type == constant.type);
274 		switch (type) {
275 		case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
276 		case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break;
277 		case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break;
278 		default: assert(false && "Default missing");
279 		}
280 
281 		return returnValue;
282 	}
283 
284 	ConstantUnion operator%(const ConstantUnion& constant) const
285 	{
286 		ConstantUnion returnValue;
287 		assert(type == constant.type);
288 		switch (type) {
289 		case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
290 		case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break;
291 		default:     assert(false && "Default missing");
292 		}
293 
294 		return returnValue;
295 	}
296 
297 	ConstantUnion operator>>(const ConstantUnion& constant) const
298 	{
299 		ConstantUnion returnValue;
300 		assert(type == constant.type);
301 		switch (type) {
302 		case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
303 		case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break;
304 		default:     assert(false && "Default missing");
305 		}
306 
307 		return returnValue;
308 	}
309 
310 	ConstantUnion operator<<(const ConstantUnion& constant) const
311 	{
312 		ConstantUnion returnValue;
313 		// The signedness of the second parameter might be different, but we
314 		// don't care, since the result is undefined if the second parameter is
315 		// negative, and aliasing should not be a problem with unions.
316 		assert(constant.type == EbtInt || constant.type == EbtUInt);
317 		switch (type) {
318 		case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
319 		case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break;
320 		default:     assert(false && "Default missing");
321 		}
322 
323 		return returnValue;
324 	}
325 
326 	ConstantUnion operator&(const ConstantUnion& constant) const
327 	{
328 		ConstantUnion returnValue;
329 		assert(constant.type == EbtInt || constant.type == EbtUInt);
330 		switch (type) {
331 		case EbtInt:  returnValue.setIConst(iConst & constant.iConst); break;
332 		case EbtUInt:  returnValue.setUConst(uConst & constant.uConst); break;
333 		default:     assert(false && "Default missing");
334 		}
335 
336 		return returnValue;
337 	}
338 
339 	ConstantUnion operator|(const ConstantUnion& constant) const
340 	{
341 		ConstantUnion returnValue;
342 		assert(type == constant.type);
343 		switch (type) {
344 		case EbtInt:  returnValue.setIConst(iConst | constant.iConst); break;
345 		case EbtUInt:  returnValue.setUConst(uConst | constant.uConst); break;
346 		default:     assert(false && "Default missing");
347 		}
348 
349 		return returnValue;
350 	}
351 
352 	ConstantUnion operator^(const ConstantUnion& constant) const
353 	{
354 		ConstantUnion returnValue;
355 		assert(type == constant.type);
356 		switch (type) {
357 		case EbtInt:  returnValue.setIConst(iConst ^ constant.iConst); break;
358 		case EbtUInt:  returnValue.setUConst(uConst ^ constant.uConst); break;
359 		default:     assert(false && "Default missing");
360 		}
361 
362 		return returnValue;
363 	}
364 
365 	ConstantUnion operator&&(const ConstantUnion& constant) const
366 	{
367 		ConstantUnion returnValue;
368 		assert(type == constant.type);
369 		switch (type) {
370 		case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
371 		default:     assert(false && "Default missing");
372 		}
373 
374 		return returnValue;
375 	}
376 
377 	ConstantUnion operator||(const ConstantUnion& constant) const
378 	{
379 		ConstantUnion returnValue;
380 		assert(type == constant.type);
381 		switch (type) {
382 		case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
383 		default:     assert(false && "Default missing");
384 		}
385 
386 		return returnValue;
387 	}
388 
getType()389 	TBasicType getType() const { return type; }
390 private:
391 
392 	union  {
393 		int iConst;  // used for ivec, scalar ints
394 		unsigned int uConst; // used for uvec, scalar uints
395 		bool bConst; // used for bvec, scalar bools
396 		float fConst;   // used for vec, mat, scalar floats
397 	} ;
398 
399 	TBasicType type;
400 };
401 
402 #endif // _CONSTANT_UNION_INCLUDED_
403