Home | History | Annotate | Download | only in compiler
      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();
     27 	ConstantUnion()
     28 	{
     29 		iConst = 0;
     30 		type = EbtVoid;
     31 	}
     32 
     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 
     94 	void setIConst(int i) {iConst = i; type = EbtInt; }
     95 	void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
     96 	void setFConst(float f) {fConst = f; type = EbtFloat; }
     97 	void setBConst(bool b) {bConst = b; type = EbtBool; }
     98 
     99 	int getIConst() const { return iConst; }
    100 	unsigned int getUConst() const { return uConst; }
    101 	float getFConst() const { return fConst; }
    102 	bool getBConst() const { return bConst; }
    103 
    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 
    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