blob: a86d27f3ff33e259017094ec984f3633baa82e5c [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
Nicolas Capens01df23e2014-06-11 10:56:03 -04002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Geoff Lang0a73dd82014-11-19 16:18:08 -05007#ifndef COMPILER_TRANSLATOR_CONSTANTUNION_H_
8#define COMPILER_TRANSLATOR_CONSTANTUNION_H_
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00009
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000010#include <assert.h>
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000011
Jamie Madill6ba6ead2015-05-04 14:21:21 -040012#include "compiler/translator/BaseTypes.h"
13
14class TConstantUnion {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000015public:
Alok Priyadarshi8156b6b2013-09-23 14:56:58 -040016 POOL_ALLOCATOR_NEW_DELETE();
Jamie Madill6ba6ead2015-05-04 14:21:21 -040017 TConstantUnion()
apatrick@chromium.orga1d80592012-01-25 21:52:10 +000018 {
19 iConst = 0;
shannon.woods%transgaming.com@gtempaccount.comc0d0c222013-04-13 03:29:36 +000020 type = EbtVoid;
apatrick@chromium.orga1d80592012-01-25 21:52:10 +000021 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000022
Jamie Madill6ba6ead2015-05-04 14:21:21 -040023 bool cast(TBasicType newType, const TConstantUnion &constant)
Nicolas Capens01df23e2014-06-11 10:56:03 -040024 {
25 switch (newType)
26 {
27 case EbtFloat:
28 switch (constant.type)
29 {
30 case EbtInt: setFConst(static_cast<float>(constant.getIConst())); break;
31 case EbtUInt: setFConst(static_cast<float>(constant.getUConst())); break;
32 case EbtBool: setFConst(static_cast<float>(constant.getBConst())); break;
33 case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break;
34 default: return false;
35 }
36 break;
37 case EbtInt:
38 switch (constant.type)
39 {
40 case EbtInt: setIConst(static_cast<int>(constant.getIConst())); break;
41 case EbtUInt: setIConst(static_cast<int>(constant.getUConst())); break;
42 case EbtBool: setIConst(static_cast<int>(constant.getBConst())); break;
43 case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break;
44 default: return false;
45 }
46 break;
47 case EbtUInt:
48 switch (constant.type)
49 {
50 case EbtInt: setUConst(static_cast<unsigned int>(constant.getIConst())); break;
51 case EbtUInt: setUConst(static_cast<unsigned int>(constant.getUConst())); break;
52 case EbtBool: setUConst(static_cast<unsigned int>(constant.getBConst())); break;
53 case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break;
54 default: return false;
55 }
56 break;
57 case EbtBool:
58 switch (constant.type)
59 {
60 case EbtInt: setBConst(constant.getIConst() != 0); break;
61 case EbtUInt: setBConst(constant.getUConst() != 0); break;
62 case EbtBool: setBConst(constant.getBConst()); break;
63 case EbtFloat: setBConst(constant.getFConst() != 0.0f); break;
64 default: return false;
65 }
66 break;
67 case EbtStruct: // Struct fields don't get cast
68 switch (constant.type)
69 {
70 case EbtInt: setIConst(constant.getIConst()); break;
71 case EbtUInt: setUConst(constant.getUConst()); break;
72 case EbtBool: setBConst(constant.getBConst()); break;
73 case EbtFloat: setFConst(constant.getFConst()); break;
74 default: return false;
75 }
76 break;
77 default:
78 return false;
79 }
80
81 return true;
82 }
83
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000084 void setIConst(int i) {iConst = i; type = EbtInt; }
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +000085 void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000086 void setFConst(float f) {fConst = f; type = EbtFloat; }
87 void setBConst(bool b) {bConst = b; type = EbtBool; }
88
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000089 int getIConst() const { return iConst; }
Nicolas Capensc0f7c612013-06-05 11:46:09 -040090 unsigned int getUConst() const { return uConst; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000091 float getFConst() const { return fConst; }
92 bool getBConst() const { return bConst; }
93
94 bool operator==(const int i) const
95 {
daniel@transgaming.come90a0d52011-02-18 02:52:06 +000096 return i == iConst;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000097 }
98
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +000099 bool operator==(const unsigned int u) const
100 {
101 return u == uConst;
102 }
103
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000104 bool operator==(const float f) const
105 {
daniel@transgaming.come90a0d52011-02-18 02:52:06 +0000106 return f == fConst;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107 }
108
109 bool operator==(const bool b) const
110 {
daniel@transgaming.come90a0d52011-02-18 02:52:06 +0000111 return b == bConst;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000112 }
113
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400114 bool operator==(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000115 {
116 if (constant.type != type)
117 return false;
118
119 switch (type) {
120 case EbtInt:
daniel@transgaming.come90a0d52011-02-18 02:52:06 +0000121 return constant.iConst == iConst;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000122 case EbtUInt:
123 return constant.uConst == uConst;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000124 case EbtFloat:
daniel@transgaming.come90a0d52011-02-18 02:52:06 +0000125 return constant.fConst == fConst;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000126 case EbtBool:
daniel@transgaming.come90a0d52011-02-18 02:52:06 +0000127 return constant.bConst == bConst;
daniel@transgaming.comcd3a1b92011-03-15 18:23:46 +0000128 default:
129 return false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000130 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000131 }
132
133 bool operator!=(const int i) const
134 {
135 return !operator==(i);
136 }
137
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000138 bool operator!=(const unsigned int u) const
139 {
140 return !operator==(u);
141 }
142
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000143 bool operator!=(const float f) const
144 {
145 return !operator==(f);
146 }
147
148 bool operator!=(const bool b) const
149 {
150 return !operator==(b);
151 }
152
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400153 bool operator!=(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000154 {
155 return !operator==(constant);
156 }
157
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400158 bool operator>(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000159 {
160 assert(type == constant.type);
161 switch (type) {
162 case EbtInt:
daniel@transgaming.comb31f35a2011-02-11 13:19:35 +0000163 return iConst > constant.iConst;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000164 case EbtUInt:
165 return uConst > constant.uConst;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000166 case EbtFloat:
daniel@transgaming.comb31f35a2011-02-11 13:19:35 +0000167 return fConst > constant.fConst;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000168 default:
daniel@transgaming.comb31f35a2011-02-11 13:19:35 +0000169 return false; // Invalid operation, handled at semantic analysis
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000170 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000171 }
172
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400173 bool operator<(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000174 {
175 assert(type == constant.type);
176 switch (type) {
177 case EbtInt:
daniel@transgaming.comb31f35a2011-02-11 13:19:35 +0000178 return iConst < constant.iConst;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000179 case EbtUInt:
180 return uConst < constant.uConst;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000181 case EbtFloat:
daniel@transgaming.comb31f35a2011-02-11 13:19:35 +0000182 return fConst < constant.fConst;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000183 default:
daniel@transgaming.comb31f35a2011-02-11 13:19:35 +0000184 return false; // Invalid operation, handled at semantic analysis
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000185 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000186 }
187
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400188 TConstantUnion operator+(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000189 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400190 TConstantUnion returnValue;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000191 assert(type == constant.type);
192 switch (type) {
193 case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000194 case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000195 case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
196 default: assert(false && "Default missing");
197 }
198
199 return returnValue;
200 }
201
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400202 TConstantUnion operator-(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400204 TConstantUnion returnValue;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000205 assert(type == constant.type);
206 switch (type) {
207 case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000208 case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209 case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
210 default: assert(false && "Default missing");
211 }
212
213 return returnValue;
214 }
215
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400216 TConstantUnion operator*(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000217 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400218 TConstantUnion returnValue;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000219 assert(type == constant.type);
220 switch (type) {
221 case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000222 case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223 case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break;
224 default: assert(false && "Default missing");
225 }
226
227 return returnValue;
228 }
229
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400230 TConstantUnion operator%(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000231 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400232 TConstantUnion returnValue;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000233 assert(type == constant.type);
234 switch (type) {
235 case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000236 case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237 default: assert(false && "Default missing");
238 }
239
240 return returnValue;
241 }
242
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400243 TConstantUnion operator>>(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000244 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400245 TConstantUnion returnValue;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000246 assert(type == constant.type);
247 switch (type) {
248 case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000249 case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000250 default: assert(false && "Default missing");
251 }
252
253 return returnValue;
254 }
255
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400256 TConstantUnion operator<<(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000257 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400258 TConstantUnion returnValue;
Olli Etuaho31b5fc62015-01-16 12:13:36 +0200259 // The signedness of the second parameter might be different, but we
260 // don't care, since the result is undefined if the second parameter is
261 // negative, and aliasing should not be a problem with unions.
262 assert(constant.type == EbtInt || constant.type == EbtUInt);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000263 switch (type) {
264 case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000265 case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000266 default: assert(false && "Default missing");
267 }
268
269 return returnValue;
270 }
271
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400272 TConstantUnion operator&(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000273 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400274 TConstantUnion returnValue;
Olli Etuaho31b5fc62015-01-16 12:13:36 +0200275 assert(constant.type == EbtInt || constant.type == EbtUInt);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000276 switch (type) {
277 case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000278 case EbtUInt: returnValue.setUConst(uConst & constant.uConst); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279 default: assert(false && "Default missing");
280 }
281
282 return returnValue;
283 }
284
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400285 TConstantUnion operator|(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000286 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400287 TConstantUnion returnValue;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000288 assert(type == constant.type);
289 switch (type) {
290 case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000291 case EbtUInt: returnValue.setUConst(uConst | constant.uConst); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000292 default: assert(false && "Default missing");
293 }
294
295 return returnValue;
296 }
297
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400298 TConstantUnion operator^(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000299 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400300 TConstantUnion returnValue;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000301 assert(type == constant.type);
302 switch (type) {
303 case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000304 case EbtUInt: returnValue.setUConst(uConst ^ constant.uConst); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000305 default: assert(false && "Default missing");
306 }
307
308 return returnValue;
309 }
310
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400311 TConstantUnion operator&&(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000312 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400313 TConstantUnion returnValue;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000314 assert(type == constant.type);
315 switch (type) {
316 case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
317 default: assert(false && "Default missing");
318 }
319
320 return returnValue;
321 }
322
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400323 TConstantUnion operator||(const TConstantUnion& constant) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000324 {
Jamie Madill6ba6ead2015-05-04 14:21:21 -0400325 TConstantUnion returnValue;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000326 assert(type == constant.type);
327 switch (type) {
328 case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
329 default: assert(false && "Default missing");
330 }
331
332 return returnValue;
333 }
334
alokp@chromium.org76b82082010-03-24 17:59:39 +0000335 TBasicType getType() const { return type; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000336private:
337
338 union {
339 int iConst; // used for ivec, scalar ints
shannonwoods@chromium.org3c9d95a2013-05-30 00:19:46 +0000340 unsigned int uConst; // used for uvec, scalar uints
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000341 bool bConst; // used for bvec, scalar bools
342 float fConst; // used for vec, mat, scalar floats
343 } ;
344
345 TBasicType type;
346};
347
Geoff Lang0a73dd82014-11-19 16:18:08 -0500348#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_