blob: 464c30cab7874ecf632ac992b1b7cb95e9571006 [file] [log] [blame]
Jamie Madill47cb73a2016-09-09 11:41:44 -04001//
2// Copyright 2016 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// ConstantUnion: Constant folding helper class.
7
8#include "compiler/translator/ConstantUnion.h"
9
Olli Etuaho7f9a55f2016-10-03 14:32:08 +010010#include "common/mathutil.h"
Jamie Madill47cb73a2016-09-09 11:41:44 -040011#include "compiler/translator/Diagnostics.h"
12
Jamie Madill45bcc782016-11-07 13:58:48 -050013namespace sh
14{
15
Jamie Madill5db69f52016-09-15 12:47:32 -040016namespace
17{
18
Olli Etuaho2d736652016-11-30 10:37:49 +000019float CheckedSum(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
Jamie Madill5db69f52016-09-15 12:47:32 -040020{
Olli Etuaho2d736652016-11-30 10:37:49 +000021 float result = lhs + rhs;
22 if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
Jamie Madill5db69f52016-09-15 12:47:32 -040023 {
Olli Etuaho4de340a2016-12-16 09:32:03 +000024 diag->warning(line, "Constant folded undefined addition generated NaN", "+");
Jamie Madill5db69f52016-09-15 12:47:32 -040025 }
Olli Etuaho2d736652016-11-30 10:37:49 +000026 else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
27 {
Olli Etuaho4de340a2016-12-16 09:32:03 +000028 diag->warning(line, "Constant folded addition overflowed to infinity", "+");
Olli Etuaho2d736652016-11-30 10:37:49 +000029 }
30 return result;
Jamie Madill5db69f52016-09-15 12:47:32 -040031}
32
Olli Etuaho2d736652016-11-30 10:37:49 +000033float CheckedDiff(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
Jamie Madill5db69f52016-09-15 12:47:32 -040034{
Olli Etuaho2d736652016-11-30 10:37:49 +000035 float result = lhs - rhs;
36 if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
Jamie Madill5db69f52016-09-15 12:47:32 -040037 {
Olli Etuaho4de340a2016-12-16 09:32:03 +000038 diag->warning(line, "Constant folded undefined subtraction generated NaN", "-");
Jamie Madill5db69f52016-09-15 12:47:32 -040039 }
Olli Etuaho2d736652016-11-30 10:37:49 +000040 else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
41 {
Olli Etuaho4de340a2016-12-16 09:32:03 +000042 diag->warning(line, "Constant folded subtraction overflowed to infinity", "-");
Olli Etuaho2d736652016-11-30 10:37:49 +000043 }
44 return result;
Jamie Madill5db69f52016-09-15 12:47:32 -040045}
46
Olli Etuaho2d736652016-11-30 10:37:49 +000047float CheckedMul(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
Jamie Madill5db69f52016-09-15 12:47:32 -040048{
Olli Etuaho2d736652016-11-30 10:37:49 +000049 float result = lhs * rhs;
50 if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
Jamie Madill5db69f52016-09-15 12:47:32 -040051 {
Olli Etuaho4de340a2016-12-16 09:32:03 +000052 diag->warning(line, "Constant folded undefined multiplication generated NaN", "*");
Jamie Madill5db69f52016-09-15 12:47:32 -040053 }
Olli Etuaho2d736652016-11-30 10:37:49 +000054 else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
55 {
Olli Etuaho4de340a2016-12-16 09:32:03 +000056 diag->warning(line, "Constant folded multiplication overflowed to infinity", "*");
Olli Etuaho2d736652016-11-30 10:37:49 +000057 }
58 return result;
Jamie Madill5db69f52016-09-15 12:47:32 -040059}
60
Olli Etuaho7e735e42017-01-12 15:42:01 +000061bool IsValidShiftOffset(const TConstantUnion &rhs)
62{
63 return (rhs.getType() == EbtInt && (rhs.getIConst() >= 0 && rhs.getIConst() <= 31)) ||
64 (rhs.getType() == EbtUInt && rhs.getUConst() <= 31u);
65}
66
Jamie Madill5db69f52016-09-15 12:47:32 -040067} // anonymous namespace
68
Jamie Madill47cb73a2016-09-09 11:41:44 -040069TConstantUnion::TConstantUnion()
70{
71 iConst = 0;
72 type = EbtVoid;
73}
74
75bool TConstantUnion::cast(TBasicType newType, const TConstantUnion &constant)
76{
77 switch (newType)
78 {
79 case EbtFloat:
80 switch (constant.type)
81 {
82 case EbtInt:
83 setFConst(static_cast<float>(constant.getIConst()));
84 break;
85 case EbtUInt:
86 setFConst(static_cast<float>(constant.getUConst()));
87 break;
88 case EbtBool:
89 setFConst(static_cast<float>(constant.getBConst()));
90 break;
91 case EbtFloat:
92 setFConst(static_cast<float>(constant.getFConst()));
93 break;
94 default:
95 return false;
96 }
97 break;
98 case EbtInt:
99 switch (constant.type)
100 {
101 case EbtInt:
102 setIConst(static_cast<int>(constant.getIConst()));
103 break;
104 case EbtUInt:
105 setIConst(static_cast<int>(constant.getUConst()));
106 break;
107 case EbtBool:
108 setIConst(static_cast<int>(constant.getBConst()));
109 break;
110 case EbtFloat:
111 setIConst(static_cast<int>(constant.getFConst()));
112 break;
113 default:
114 return false;
115 }
116 break;
117 case EbtUInt:
118 switch (constant.type)
119 {
120 case EbtInt:
121 setUConst(static_cast<unsigned int>(constant.getIConst()));
122 break;
123 case EbtUInt:
124 setUConst(static_cast<unsigned int>(constant.getUConst()));
125 break;
126 case EbtBool:
127 setUConst(static_cast<unsigned int>(constant.getBConst()));
128 break;
129 case EbtFloat:
130 setUConst(static_cast<unsigned int>(constant.getFConst()));
131 break;
132 default:
133 return false;
134 }
135 break;
136 case EbtBool:
137 switch (constant.type)
138 {
139 case EbtInt:
140 setBConst(constant.getIConst() != 0);
141 break;
142 case EbtUInt:
143 setBConst(constant.getUConst() != 0);
144 break;
145 case EbtBool:
146 setBConst(constant.getBConst());
147 break;
148 case EbtFloat:
149 setBConst(constant.getFConst() != 0.0f);
150 break;
151 default:
152 return false;
153 }
154 break;
155 case EbtStruct: // Struct fields don't get cast
156 switch (constant.type)
157 {
158 case EbtInt:
159 setIConst(constant.getIConst());
160 break;
161 case EbtUInt:
162 setUConst(constant.getUConst());
163 break;
164 case EbtBool:
165 setBConst(constant.getBConst());
166 break;
167 case EbtFloat:
168 setFConst(constant.getFConst());
169 break;
170 default:
171 return false;
172 }
173 break;
174 default:
175 return false;
176 }
177
178 return true;
179}
180
181bool TConstantUnion::operator==(const int i) const
182{
183 return i == iConst;
184}
185
186bool TConstantUnion::operator==(const unsigned int u) const
187{
188 return u == uConst;
189}
190
191bool TConstantUnion::operator==(const float f) const
192{
193 return f == fConst;
194}
195
196bool TConstantUnion::operator==(const bool b) const
197{
198 return b == bConst;
199}
200
201bool TConstantUnion::operator==(const TConstantUnion &constant) const
202{
203 if (constant.type != type)
204 return false;
205
206 switch (type)
207 {
208 case EbtInt:
209 return constant.iConst == iConst;
210 case EbtUInt:
211 return constant.uConst == uConst;
212 case EbtFloat:
213 return constant.fConst == fConst;
214 case EbtBool:
215 return constant.bConst == bConst;
216 default:
217 return false;
218 }
219}
220
221bool TConstantUnion::operator!=(const int i) const
222{
223 return !operator==(i);
224}
225
226bool TConstantUnion::operator!=(const unsigned int u) const
227{
228 return !operator==(u);
229}
230
231bool TConstantUnion::operator!=(const float f) const
232{
233 return !operator==(f);
234}
235
236bool TConstantUnion::operator!=(const bool b) const
237{
238 return !operator==(b);
239}
240
241bool TConstantUnion::operator!=(const TConstantUnion &constant) const
242{
243 return !operator==(constant);
244}
245
246bool TConstantUnion::operator>(const TConstantUnion &constant) const
247{
248 ASSERT(type == constant.type);
249 switch (type)
250 {
251 case EbtInt:
252 return iConst > constant.iConst;
253 case EbtUInt:
254 return uConst > constant.uConst;
255 case EbtFloat:
256 return fConst > constant.fConst;
257 default:
258 return false; // Invalid operation, handled at semantic analysis
259 }
260}
261
262bool TConstantUnion::operator<(const TConstantUnion &constant) const
263{
264 ASSERT(type == constant.type);
265 switch (type)
266 {
267 case EbtInt:
268 return iConst < constant.iConst;
269 case EbtUInt:
270 return uConst < constant.uConst;
271 case EbtFloat:
272 return fConst < constant.fConst;
273 default:
274 return false; // Invalid operation, handled at semantic analysis
275 }
276}
277
278// static
279TConstantUnion TConstantUnion::add(const TConstantUnion &lhs,
280 const TConstantUnion &rhs,
Jamie Madill5db69f52016-09-15 12:47:32 -0400281 TDiagnostics *diag,
282 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400283{
284 TConstantUnion returnValue;
285 ASSERT(lhs.type == rhs.type);
286 switch (lhs.type)
287 {
288 case EbtInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100289 returnValue.setIConst(gl::WrappingSum<int>(lhs.iConst, rhs.iConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400290 break;
291 case EbtUInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100292 returnValue.setUConst(gl::WrappingSum<unsigned int>(lhs.uConst, rhs.uConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400293 break;
294 case EbtFloat:
Olli Etuaho2d736652016-11-30 10:37:49 +0000295 returnValue.setFConst(CheckedSum(lhs.fConst, rhs.fConst, diag, line));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400296 break;
297 default:
298 UNREACHABLE();
299 }
300
301 return returnValue;
302}
303
304// static
305TConstantUnion TConstantUnion::sub(const TConstantUnion &lhs,
306 const TConstantUnion &rhs,
Jamie Madill5db69f52016-09-15 12:47:32 -0400307 TDiagnostics *diag,
308 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400309{
310 TConstantUnion returnValue;
311 ASSERT(lhs.type == rhs.type);
312 switch (lhs.type)
313 {
314 case EbtInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100315 returnValue.setIConst(gl::WrappingDiff<int>(lhs.iConst, rhs.iConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400316 break;
317 case EbtUInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100318 returnValue.setUConst(gl::WrappingDiff<unsigned int>(lhs.uConst, rhs.uConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400319 break;
320 case EbtFloat:
Olli Etuaho2d736652016-11-30 10:37:49 +0000321 returnValue.setFConst(CheckedDiff(lhs.fConst, rhs.fConst, diag, line));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400322 break;
323 default:
324 UNREACHABLE();
325 }
326
327 return returnValue;
328}
329
330// static
331TConstantUnion TConstantUnion::mul(const TConstantUnion &lhs,
332 const TConstantUnion &rhs,
Jamie Madill5db69f52016-09-15 12:47:32 -0400333 TDiagnostics *diag,
334 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400335{
336 TConstantUnion returnValue;
337 ASSERT(lhs.type == rhs.type);
338 switch (lhs.type)
339 {
340 case EbtInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100341 returnValue.setIConst(gl::WrappingMul(lhs.iConst, rhs.iConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400342 break;
343 case EbtUInt:
Olli Etuaho1be4d492016-09-27 11:15:38 +0100344 // Unsigned integer math in C++ is defined to be done in modulo 2^n, so we rely on that
345 // to implement wrapping multiplication.
346 returnValue.setUConst(lhs.uConst * rhs.uConst);
Jamie Madill47cb73a2016-09-09 11:41:44 -0400347 break;
348 case EbtFloat:
Olli Etuaho2d736652016-11-30 10:37:49 +0000349 returnValue.setFConst(CheckedMul(lhs.fConst, rhs.fConst, diag, line));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400350 break;
351 default:
352 UNREACHABLE();
353 }
354
355 return returnValue;
356}
357
358TConstantUnion TConstantUnion::operator%(const TConstantUnion &constant) const
359{
360 TConstantUnion returnValue;
361 ASSERT(type == constant.type);
362 switch (type)
363 {
364 case EbtInt:
365 returnValue.setIConst(iConst % constant.iConst);
366 break;
367 case EbtUInt:
368 returnValue.setUConst(uConst % constant.uConst);
369 break;
370 default:
371 UNREACHABLE();
372 }
373
374 return returnValue;
375}
376
Jamie Madill596018c2016-09-21 12:57:03 -0400377// static
378TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs,
379 const TConstantUnion &rhs,
380 TDiagnostics *diag,
381 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400382{
383 TConstantUnion returnValue;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100384 ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
385 ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
Olli Etuaho7e735e42017-01-12 15:42:01 +0000386 if (!IsValidShiftOffset(rhs))
Olli Etuaho2cacb772016-09-26 08:50:40 +0100387 {
Olli Etuaho7e735e42017-01-12 15:42:01 +0000388 diag->warning(line, "Undefined shift (operand out of range)", ">>");
Olli Etuaho2cacb772016-09-26 08:50:40 +0100389 switch (lhs.type)
390 {
391 case EbtInt:
392 returnValue.setIConst(0);
393 break;
394 case EbtUInt:
395 returnValue.setUConst(0u);
396 break;
397 default:
398 UNREACHABLE();
399 }
400 return returnValue;
401 }
402
Jamie Madill596018c2016-09-21 12:57:03 -0400403 switch (lhs.type)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400404 {
405 case EbtInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100406 {
407 unsigned int shiftOffset = 0;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100408 switch (rhs.type)
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400409 {
Olli Etuaho2cacb772016-09-26 08:50:40 +0100410 case EbtInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100411 shiftOffset = static_cast<unsigned int>(rhs.iConst);
Olli Etuaho2cacb772016-09-26 08:50:40 +0100412 break;
413 case EbtUInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100414 shiftOffset = rhs.uConst;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100415 break;
416 default:
417 UNREACHABLE();
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400418 }
Olli Etuaho43103542016-10-10 12:28:13 +0100419 if (shiftOffset > 0)
420 {
421 // ESSL 3.00.6 section 5.9: "If E1 is a signed integer, the right-shift will extend
422 // the sign bit." In C++ shifting negative integers is undefined, so we implement
423 // extending the sign bit manually.
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500424 int lhsSafe = lhs.iConst;
Olli Etuaho55644212016-11-08 11:07:34 +0000425 if (lhsSafe == std::numeric_limits<int>::min())
Olli Etuaho43103542016-10-10 12:28:13 +0100426 {
Olli Etuaho55644212016-11-08 11:07:34 +0000427 // The min integer needs special treatment because only bit it has set is the
428 // sign bit, which we clear later to implement safe right shift of negative
429 // numbers.
430 lhsSafe = -0x40000000;
431 --shiftOffset;
Olli Etuaho43103542016-10-10 12:28:13 +0100432 }
Olli Etuaho55644212016-11-08 11:07:34 +0000433 if (shiftOffset > 0)
Olli Etuaho43103542016-10-10 12:28:13 +0100434 {
Olli Etuaho55644212016-11-08 11:07:34 +0000435 bool extendSignBit = false;
436 if (lhsSafe < 0)
437 {
438 extendSignBit = true;
439 // Clear the sign bit so that bitshift right is defined in C++.
440 lhsSafe &= 0x7fffffff;
441 ASSERT(lhsSafe > 0);
442 }
443 returnValue.setIConst(lhsSafe >> shiftOffset);
444
445 // Manually fill in the extended sign bit if necessary.
446 if (extendSignBit)
447 {
448 int extendedSignBit = static_cast<int>(0xffffffffu << (31 - shiftOffset));
449 returnValue.setIConst(returnValue.getIConst() | extendedSignBit);
450 }
451 }
452 else
453 {
454 returnValue.setIConst(lhsSafe);
Olli Etuaho43103542016-10-10 12:28:13 +0100455 }
456 }
457 else
458 {
Olli Etuaho55644212016-11-08 11:07:34 +0000459 returnValue.setIConst(lhs.iConst);
Olli Etuaho43103542016-10-10 12:28:13 +0100460 }
461 break;
462 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400463 case EbtUInt:
Olli Etuaho2cacb772016-09-26 08:50:40 +0100464 switch (rhs.type)
465 {
466 case EbtInt:
467 returnValue.setUConst(lhs.uConst >> rhs.iConst);
468 break;
469 case EbtUInt:
470 returnValue.setUConst(lhs.uConst >> rhs.uConst);
471 break;
472 default:
473 UNREACHABLE();
474 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400475 break;
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400476
Jamie Madill47cb73a2016-09-09 11:41:44 -0400477 default:
478 UNREACHABLE();
479 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400480 return returnValue;
481}
482
Jamie Madill596018c2016-09-21 12:57:03 -0400483// static
484TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs,
485 const TConstantUnion &rhs,
486 TDiagnostics *diag,
487 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400488{
489 TConstantUnion returnValue;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100490 ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
491 ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
Olli Etuaho7e735e42017-01-12 15:42:01 +0000492 if (!IsValidShiftOffset(rhs))
Olli Etuaho2cacb772016-09-26 08:50:40 +0100493 {
Olli Etuaho7e735e42017-01-12 15:42:01 +0000494 diag->warning(line, "Undefined shift (operand out of range)", "<<");
Olli Etuaho2cacb772016-09-26 08:50:40 +0100495 switch (lhs.type)
496 {
497 case EbtInt:
498 returnValue.setIConst(0);
499 break;
500 case EbtUInt:
501 returnValue.setUConst(0u);
502 break;
503 default:
504 UNREACHABLE();
505 }
506 return returnValue;
507 }
508
Jamie Madill596018c2016-09-21 12:57:03 -0400509 switch (lhs.type)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400510 {
511 case EbtInt:
Olli Etuaho2cacb772016-09-26 08:50:40 +0100512 switch (rhs.type)
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400513 {
Olli Etuaho43103542016-10-10 12:28:13 +0100514 // Cast to unsigned integer before shifting, since ESSL 3.00.6 section 5.9 says that
515 // lhs is "interpreted as a bit pattern". This also avoids the possibility of signed
516 // integer overflow or undefined shift of a negative integer.
Olli Etuaho2cacb772016-09-26 08:50:40 +0100517 case EbtInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100518 returnValue.setIConst(
519 static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.iConst));
Olli Etuaho2cacb772016-09-26 08:50:40 +0100520 break;
521 case EbtUInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100522 returnValue.setIConst(
523 static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.uConst));
Olli Etuaho2cacb772016-09-26 08:50:40 +0100524 break;
525 default:
526 UNREACHABLE();
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400527 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400528 break;
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400529
Jamie Madill47cb73a2016-09-09 11:41:44 -0400530 case EbtUInt:
Olli Etuaho2cacb772016-09-26 08:50:40 +0100531 switch (rhs.type)
532 {
533 case EbtInt:
534 returnValue.setUConst(lhs.uConst << rhs.iConst);
535 break;
536 case EbtUInt:
537 returnValue.setUConst(lhs.uConst << rhs.uConst);
538 break;
539 default:
540 UNREACHABLE();
541 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400542 break;
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400543
Jamie Madill47cb73a2016-09-09 11:41:44 -0400544 default:
545 UNREACHABLE();
546 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400547 return returnValue;
548}
549
550TConstantUnion TConstantUnion::operator&(const TConstantUnion &constant) const
551{
552 TConstantUnion returnValue;
553 ASSERT(constant.type == EbtInt || constant.type == EbtUInt);
554 switch (type)
555 {
556 case EbtInt:
557 returnValue.setIConst(iConst & constant.iConst);
558 break;
559 case EbtUInt:
560 returnValue.setUConst(uConst & constant.uConst);
561 break;
562 default:
563 UNREACHABLE();
564 }
565
566 return returnValue;
567}
568
569TConstantUnion TConstantUnion::operator|(const TConstantUnion &constant) const
570{
571 TConstantUnion returnValue;
572 ASSERT(type == constant.type);
573 switch (type)
574 {
575 case EbtInt:
576 returnValue.setIConst(iConst | constant.iConst);
577 break;
578 case EbtUInt:
579 returnValue.setUConst(uConst | constant.uConst);
580 break;
581 default:
582 UNREACHABLE();
583 }
584
585 return returnValue;
586}
587
588TConstantUnion TConstantUnion::operator^(const TConstantUnion &constant) const
589{
590 TConstantUnion returnValue;
591 ASSERT(type == constant.type);
592 switch (type)
593 {
594 case EbtInt:
595 returnValue.setIConst(iConst ^ constant.iConst);
596 break;
597 case EbtUInt:
598 returnValue.setUConst(uConst ^ constant.uConst);
599 break;
600 default:
601 UNREACHABLE();
602 }
603
604 return returnValue;
605}
606
607TConstantUnion TConstantUnion::operator&&(const TConstantUnion &constant) const
608{
609 TConstantUnion returnValue;
610 ASSERT(type == constant.type);
611 switch (type)
612 {
613 case EbtBool:
614 returnValue.setBConst(bConst && constant.bConst);
615 break;
616 default:
617 UNREACHABLE();
618 }
619
620 return returnValue;
621}
622
623TConstantUnion TConstantUnion::operator||(const TConstantUnion &constant) const
624{
625 TConstantUnion returnValue;
626 ASSERT(type == constant.type);
627 switch (type)
628 {
629 case EbtBool:
630 returnValue.setBConst(bConst || constant.bConst);
631 break;
632 default:
633 UNREACHABLE();
634 }
635
636 return returnValue;
637}
Jamie Madill45bcc782016-11-07 13:58:48 -0500638
639} // namespace sh