blob: 539a375adc4f8b53a986057559c1945f38d08f65 [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 Etuaho2d736652016-11-30 10:37:49 +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 {
28 diag->warning(line, "Constant folded addition overflowed to infinity", "+", "");
29 }
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 Etuaho2d736652016-11-30 10:37:49 +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 {
42 diag->warning(line, "Constant folded subtraction overflowed to infinity", "-", "");
43 }
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 Etuaho2d736652016-11-30 10:37:49 +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 {
56 diag->warning(line, "Constant folded multiplication overflowed to infinity", "*", "");
57 }
58 return result;
Jamie Madill5db69f52016-09-15 12:47:32 -040059}
60
61} // anonymous namespace
62
Jamie Madill47cb73a2016-09-09 11:41:44 -040063TConstantUnion::TConstantUnion()
64{
65 iConst = 0;
66 type = EbtVoid;
67}
68
69bool TConstantUnion::cast(TBasicType newType, const TConstantUnion &constant)
70{
71 switch (newType)
72 {
73 case EbtFloat:
74 switch (constant.type)
75 {
76 case EbtInt:
77 setFConst(static_cast<float>(constant.getIConst()));
78 break;
79 case EbtUInt:
80 setFConst(static_cast<float>(constant.getUConst()));
81 break;
82 case EbtBool:
83 setFConst(static_cast<float>(constant.getBConst()));
84 break;
85 case EbtFloat:
86 setFConst(static_cast<float>(constant.getFConst()));
87 break;
88 default:
89 return false;
90 }
91 break;
92 case EbtInt:
93 switch (constant.type)
94 {
95 case EbtInt:
96 setIConst(static_cast<int>(constant.getIConst()));
97 break;
98 case EbtUInt:
99 setIConst(static_cast<int>(constant.getUConst()));
100 break;
101 case EbtBool:
102 setIConst(static_cast<int>(constant.getBConst()));
103 break;
104 case EbtFloat:
105 setIConst(static_cast<int>(constant.getFConst()));
106 break;
107 default:
108 return false;
109 }
110 break;
111 case EbtUInt:
112 switch (constant.type)
113 {
114 case EbtInt:
115 setUConst(static_cast<unsigned int>(constant.getIConst()));
116 break;
117 case EbtUInt:
118 setUConst(static_cast<unsigned int>(constant.getUConst()));
119 break;
120 case EbtBool:
121 setUConst(static_cast<unsigned int>(constant.getBConst()));
122 break;
123 case EbtFloat:
124 setUConst(static_cast<unsigned int>(constant.getFConst()));
125 break;
126 default:
127 return false;
128 }
129 break;
130 case EbtBool:
131 switch (constant.type)
132 {
133 case EbtInt:
134 setBConst(constant.getIConst() != 0);
135 break;
136 case EbtUInt:
137 setBConst(constant.getUConst() != 0);
138 break;
139 case EbtBool:
140 setBConst(constant.getBConst());
141 break;
142 case EbtFloat:
143 setBConst(constant.getFConst() != 0.0f);
144 break;
145 default:
146 return false;
147 }
148 break;
149 case EbtStruct: // Struct fields don't get cast
150 switch (constant.type)
151 {
152 case EbtInt:
153 setIConst(constant.getIConst());
154 break;
155 case EbtUInt:
156 setUConst(constant.getUConst());
157 break;
158 case EbtBool:
159 setBConst(constant.getBConst());
160 break;
161 case EbtFloat:
162 setFConst(constant.getFConst());
163 break;
164 default:
165 return false;
166 }
167 break;
168 default:
169 return false;
170 }
171
172 return true;
173}
174
175bool TConstantUnion::operator==(const int i) const
176{
177 return i == iConst;
178}
179
180bool TConstantUnion::operator==(const unsigned int u) const
181{
182 return u == uConst;
183}
184
185bool TConstantUnion::operator==(const float f) const
186{
187 return f == fConst;
188}
189
190bool TConstantUnion::operator==(const bool b) const
191{
192 return b == bConst;
193}
194
195bool TConstantUnion::operator==(const TConstantUnion &constant) const
196{
197 if (constant.type != type)
198 return false;
199
200 switch (type)
201 {
202 case EbtInt:
203 return constant.iConst == iConst;
204 case EbtUInt:
205 return constant.uConst == uConst;
206 case EbtFloat:
207 return constant.fConst == fConst;
208 case EbtBool:
209 return constant.bConst == bConst;
210 default:
211 return false;
212 }
213}
214
215bool TConstantUnion::operator!=(const int i) const
216{
217 return !operator==(i);
218}
219
220bool TConstantUnion::operator!=(const unsigned int u) const
221{
222 return !operator==(u);
223}
224
225bool TConstantUnion::operator!=(const float f) const
226{
227 return !operator==(f);
228}
229
230bool TConstantUnion::operator!=(const bool b) const
231{
232 return !operator==(b);
233}
234
235bool TConstantUnion::operator!=(const TConstantUnion &constant) const
236{
237 return !operator==(constant);
238}
239
240bool TConstantUnion::operator>(const TConstantUnion &constant) const
241{
242 ASSERT(type == constant.type);
243 switch (type)
244 {
245 case EbtInt:
246 return iConst > constant.iConst;
247 case EbtUInt:
248 return uConst > constant.uConst;
249 case EbtFloat:
250 return fConst > constant.fConst;
251 default:
252 return false; // Invalid operation, handled at semantic analysis
253 }
254}
255
256bool TConstantUnion::operator<(const TConstantUnion &constant) const
257{
258 ASSERT(type == constant.type);
259 switch (type)
260 {
261 case EbtInt:
262 return iConst < constant.iConst;
263 case EbtUInt:
264 return uConst < constant.uConst;
265 case EbtFloat:
266 return fConst < constant.fConst;
267 default:
268 return false; // Invalid operation, handled at semantic analysis
269 }
270}
271
272// static
273TConstantUnion TConstantUnion::add(const TConstantUnion &lhs,
274 const TConstantUnion &rhs,
Jamie Madill5db69f52016-09-15 12:47:32 -0400275 TDiagnostics *diag,
276 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400277{
278 TConstantUnion returnValue;
279 ASSERT(lhs.type == rhs.type);
280 switch (lhs.type)
281 {
282 case EbtInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100283 returnValue.setIConst(gl::WrappingSum<int>(lhs.iConst, rhs.iConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400284 break;
285 case EbtUInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100286 returnValue.setUConst(gl::WrappingSum<unsigned int>(lhs.uConst, rhs.uConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400287 break;
288 case EbtFloat:
Olli Etuaho2d736652016-11-30 10:37:49 +0000289 returnValue.setFConst(CheckedSum(lhs.fConst, rhs.fConst, diag, line));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400290 break;
291 default:
292 UNREACHABLE();
293 }
294
295 return returnValue;
296}
297
298// static
299TConstantUnion TConstantUnion::sub(const TConstantUnion &lhs,
300 const TConstantUnion &rhs,
Jamie Madill5db69f52016-09-15 12:47:32 -0400301 TDiagnostics *diag,
302 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400303{
304 TConstantUnion returnValue;
305 ASSERT(lhs.type == rhs.type);
306 switch (lhs.type)
307 {
308 case EbtInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100309 returnValue.setIConst(gl::WrappingDiff<int>(lhs.iConst, rhs.iConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400310 break;
311 case EbtUInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100312 returnValue.setUConst(gl::WrappingDiff<unsigned int>(lhs.uConst, rhs.uConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400313 break;
314 case EbtFloat:
Olli Etuaho2d736652016-11-30 10:37:49 +0000315 returnValue.setFConst(CheckedDiff(lhs.fConst, rhs.fConst, diag, line));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400316 break;
317 default:
318 UNREACHABLE();
319 }
320
321 return returnValue;
322}
323
324// static
325TConstantUnion TConstantUnion::mul(const TConstantUnion &lhs,
326 const TConstantUnion &rhs,
Jamie Madill5db69f52016-09-15 12:47:32 -0400327 TDiagnostics *diag,
328 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400329{
330 TConstantUnion returnValue;
331 ASSERT(lhs.type == rhs.type);
332 switch (lhs.type)
333 {
334 case EbtInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100335 returnValue.setIConst(gl::WrappingMul(lhs.iConst, rhs.iConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400336 break;
337 case EbtUInt:
Olli Etuaho1be4d492016-09-27 11:15:38 +0100338 // Unsigned integer math in C++ is defined to be done in modulo 2^n, so we rely on that
339 // to implement wrapping multiplication.
340 returnValue.setUConst(lhs.uConst * rhs.uConst);
Jamie Madill47cb73a2016-09-09 11:41:44 -0400341 break;
342 case EbtFloat:
Olli Etuaho2d736652016-11-30 10:37:49 +0000343 returnValue.setFConst(CheckedMul(lhs.fConst, rhs.fConst, diag, line));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400344 break;
345 default:
346 UNREACHABLE();
347 }
348
349 return returnValue;
350}
351
352TConstantUnion TConstantUnion::operator%(const TConstantUnion &constant) const
353{
354 TConstantUnion returnValue;
355 ASSERT(type == constant.type);
356 switch (type)
357 {
358 case EbtInt:
359 returnValue.setIConst(iConst % constant.iConst);
360 break;
361 case EbtUInt:
362 returnValue.setUConst(uConst % constant.uConst);
363 break;
364 default:
365 UNREACHABLE();
366 }
367
368 return returnValue;
369}
370
Jamie Madill596018c2016-09-21 12:57:03 -0400371// static
372TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs,
373 const TConstantUnion &rhs,
374 TDiagnostics *diag,
375 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400376{
377 TConstantUnion returnValue;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100378 ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
379 ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
Olli Etuaho43103542016-10-10 12:28:13 +0100380 if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) ||
381 (rhs.type == EbtUInt && rhs.uConst > 31u))
Olli Etuaho2cacb772016-09-26 08:50:40 +0100382 {
383 diag->error(line, "Undefined shift (operand out of range)", ">>", "");
384 switch (lhs.type)
385 {
386 case EbtInt:
387 returnValue.setIConst(0);
388 break;
389 case EbtUInt:
390 returnValue.setUConst(0u);
391 break;
392 default:
393 UNREACHABLE();
394 }
395 return returnValue;
396 }
397
Jamie Madill596018c2016-09-21 12:57:03 -0400398 switch (lhs.type)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400399 {
400 case EbtInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100401 {
402 unsigned int shiftOffset = 0;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100403 switch (rhs.type)
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400404 {
Olli Etuaho2cacb772016-09-26 08:50:40 +0100405 case EbtInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100406 shiftOffset = static_cast<unsigned int>(rhs.iConst);
Olli Etuaho2cacb772016-09-26 08:50:40 +0100407 break;
408 case EbtUInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100409 shiftOffset = rhs.uConst;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100410 break;
411 default:
412 UNREACHABLE();
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400413 }
Olli Etuaho43103542016-10-10 12:28:13 +0100414 if (shiftOffset > 0)
415 {
416 // ESSL 3.00.6 section 5.9: "If E1 is a signed integer, the right-shift will extend
417 // the sign bit." In C++ shifting negative integers is undefined, so we implement
418 // extending the sign bit manually.
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500419 int lhsSafe = lhs.iConst;
Olli Etuaho55644212016-11-08 11:07:34 +0000420 if (lhsSafe == std::numeric_limits<int>::min())
Olli Etuaho43103542016-10-10 12:28:13 +0100421 {
Olli Etuaho55644212016-11-08 11:07:34 +0000422 // The min integer needs special treatment because only bit it has set is the
423 // sign bit, which we clear later to implement safe right shift of negative
424 // numbers.
425 lhsSafe = -0x40000000;
426 --shiftOffset;
Olli Etuaho43103542016-10-10 12:28:13 +0100427 }
Olli Etuaho55644212016-11-08 11:07:34 +0000428 if (shiftOffset > 0)
Olli Etuaho43103542016-10-10 12:28:13 +0100429 {
Olli Etuaho55644212016-11-08 11:07:34 +0000430 bool extendSignBit = false;
431 if (lhsSafe < 0)
432 {
433 extendSignBit = true;
434 // Clear the sign bit so that bitshift right is defined in C++.
435 lhsSafe &= 0x7fffffff;
436 ASSERT(lhsSafe > 0);
437 }
438 returnValue.setIConst(lhsSafe >> shiftOffset);
439
440 // Manually fill in the extended sign bit if necessary.
441 if (extendSignBit)
442 {
443 int extendedSignBit = static_cast<int>(0xffffffffu << (31 - shiftOffset));
444 returnValue.setIConst(returnValue.getIConst() | extendedSignBit);
445 }
446 }
447 else
448 {
449 returnValue.setIConst(lhsSafe);
Olli Etuaho43103542016-10-10 12:28:13 +0100450 }
451 }
452 else
453 {
Olli Etuaho55644212016-11-08 11:07:34 +0000454 returnValue.setIConst(lhs.iConst);
Olli Etuaho43103542016-10-10 12:28:13 +0100455 }
456 break;
457 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400458 case EbtUInt:
Olli Etuaho2cacb772016-09-26 08:50:40 +0100459 switch (rhs.type)
460 {
461 case EbtInt:
462 returnValue.setUConst(lhs.uConst >> rhs.iConst);
463 break;
464 case EbtUInt:
465 returnValue.setUConst(lhs.uConst >> rhs.uConst);
466 break;
467 default:
468 UNREACHABLE();
469 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400470 break;
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400471
Jamie Madill47cb73a2016-09-09 11:41:44 -0400472 default:
473 UNREACHABLE();
474 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400475 return returnValue;
476}
477
Jamie Madill596018c2016-09-21 12:57:03 -0400478// static
479TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs,
480 const TConstantUnion &rhs,
481 TDiagnostics *diag,
482 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400483{
484 TConstantUnion returnValue;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100485 ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
486 ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
Olli Etuaho43103542016-10-10 12:28:13 +0100487 if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) ||
488 (rhs.type == EbtUInt && rhs.uConst > 31u))
Olli Etuaho2cacb772016-09-26 08:50:40 +0100489 {
490 diag->error(line, "Undefined shift (operand out of range)", "<<", "");
491 switch (lhs.type)
492 {
493 case EbtInt:
494 returnValue.setIConst(0);
495 break;
496 case EbtUInt:
497 returnValue.setUConst(0u);
498 break;
499 default:
500 UNREACHABLE();
501 }
502 return returnValue;
503 }
504
Jamie Madill596018c2016-09-21 12:57:03 -0400505 switch (lhs.type)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400506 {
507 case EbtInt:
Olli Etuaho2cacb772016-09-26 08:50:40 +0100508 switch (rhs.type)
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400509 {
Olli Etuaho43103542016-10-10 12:28:13 +0100510 // Cast to unsigned integer before shifting, since ESSL 3.00.6 section 5.9 says that
511 // lhs is "interpreted as a bit pattern". This also avoids the possibility of signed
512 // integer overflow or undefined shift of a negative integer.
Olli Etuaho2cacb772016-09-26 08:50:40 +0100513 case EbtInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100514 returnValue.setIConst(
515 static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.iConst));
Olli Etuaho2cacb772016-09-26 08:50:40 +0100516 break;
517 case EbtUInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100518 returnValue.setIConst(
519 static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.uConst));
Olli Etuaho2cacb772016-09-26 08:50:40 +0100520 break;
521 default:
522 UNREACHABLE();
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400523 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400524 break;
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400525
Jamie Madill47cb73a2016-09-09 11:41:44 -0400526 case EbtUInt:
Olli Etuaho2cacb772016-09-26 08:50:40 +0100527 switch (rhs.type)
528 {
529 case EbtInt:
530 returnValue.setUConst(lhs.uConst << rhs.iConst);
531 break;
532 case EbtUInt:
533 returnValue.setUConst(lhs.uConst << rhs.uConst);
534 break;
535 default:
536 UNREACHABLE();
537 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400538 break;
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400539
Jamie Madill47cb73a2016-09-09 11:41:44 -0400540 default:
541 UNREACHABLE();
542 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400543 return returnValue;
544}
545
546TConstantUnion TConstantUnion::operator&(const TConstantUnion &constant) const
547{
548 TConstantUnion returnValue;
549 ASSERT(constant.type == EbtInt || constant.type == EbtUInt);
550 switch (type)
551 {
552 case EbtInt:
553 returnValue.setIConst(iConst & constant.iConst);
554 break;
555 case EbtUInt:
556 returnValue.setUConst(uConst & constant.uConst);
557 break;
558 default:
559 UNREACHABLE();
560 }
561
562 return returnValue;
563}
564
565TConstantUnion TConstantUnion::operator|(const TConstantUnion &constant) const
566{
567 TConstantUnion returnValue;
568 ASSERT(type == constant.type);
569 switch (type)
570 {
571 case EbtInt:
572 returnValue.setIConst(iConst | constant.iConst);
573 break;
574 case EbtUInt:
575 returnValue.setUConst(uConst | constant.uConst);
576 break;
577 default:
578 UNREACHABLE();
579 }
580
581 return returnValue;
582}
583
584TConstantUnion TConstantUnion::operator^(const TConstantUnion &constant) const
585{
586 TConstantUnion returnValue;
587 ASSERT(type == constant.type);
588 switch (type)
589 {
590 case EbtInt:
591 returnValue.setIConst(iConst ^ constant.iConst);
592 break;
593 case EbtUInt:
594 returnValue.setUConst(uConst ^ constant.uConst);
595 break;
596 default:
597 UNREACHABLE();
598 }
599
600 return returnValue;
601}
602
603TConstantUnion TConstantUnion::operator&&(const TConstantUnion &constant) const
604{
605 TConstantUnion returnValue;
606 ASSERT(type == constant.type);
607 switch (type)
608 {
609 case EbtBool:
610 returnValue.setBConst(bConst && constant.bConst);
611 break;
612 default:
613 UNREACHABLE();
614 }
615
616 return returnValue;
617}
618
619TConstantUnion TConstantUnion::operator||(const TConstantUnion &constant) const
620{
621 TConstantUnion returnValue;
622 ASSERT(type == constant.type);
623 switch (type)
624 {
625 case EbtBool:
626 returnValue.setBConst(bConst || constant.bConst);
627 break;
628 default:
629 UNREACHABLE();
630 }
631
632 return returnValue;
633}
Jamie Madill45bcc782016-11-07 13:58:48 -0500634
635} // namespace sh