blob: b960e428f24137748783c5f5fd8c86d507dda856 [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
Andrei Volykhina5527072017-03-22 16:46:30 +0300201bool TConstantUnion::operator==(const TYuvCscStandardEXT s) const
202{
203 return s == yuvCscStandardEXTConst;
204}
205
Jamie Madill47cb73a2016-09-09 11:41:44 -0400206bool TConstantUnion::operator==(const TConstantUnion &constant) const
207{
208 if (constant.type != type)
209 return false;
210
211 switch (type)
212 {
213 case EbtInt:
214 return constant.iConst == iConst;
215 case EbtUInt:
216 return constant.uConst == uConst;
217 case EbtFloat:
218 return constant.fConst == fConst;
219 case EbtBool:
220 return constant.bConst == bConst;
Andrei Volykhina5527072017-03-22 16:46:30 +0300221 case EbtYuvCscStandardEXT:
222 return constant.yuvCscStandardEXTConst == yuvCscStandardEXTConst;
Jamie Madill47cb73a2016-09-09 11:41:44 -0400223 default:
224 return false;
225 }
226}
227
228bool TConstantUnion::operator!=(const int i) const
229{
230 return !operator==(i);
231}
232
233bool TConstantUnion::operator!=(const unsigned int u) const
234{
235 return !operator==(u);
236}
237
238bool TConstantUnion::operator!=(const float f) const
239{
240 return !operator==(f);
241}
242
243bool TConstantUnion::operator!=(const bool b) const
244{
245 return !operator==(b);
246}
247
Andrei Volykhina5527072017-03-22 16:46:30 +0300248bool TConstantUnion::operator!=(const TYuvCscStandardEXT s) const
249{
250 return !operator==(s);
251}
252
Jamie Madill47cb73a2016-09-09 11:41:44 -0400253bool TConstantUnion::operator!=(const TConstantUnion &constant) const
254{
255 return !operator==(constant);
256}
257
258bool TConstantUnion::operator>(const TConstantUnion &constant) const
259{
260 ASSERT(type == constant.type);
261 switch (type)
262 {
263 case EbtInt:
264 return iConst > constant.iConst;
265 case EbtUInt:
266 return uConst > constant.uConst;
267 case EbtFloat:
268 return fConst > constant.fConst;
269 default:
270 return false; // Invalid operation, handled at semantic analysis
271 }
272}
273
274bool TConstantUnion::operator<(const TConstantUnion &constant) const
275{
276 ASSERT(type == constant.type);
277 switch (type)
278 {
279 case EbtInt:
280 return iConst < constant.iConst;
281 case EbtUInt:
282 return uConst < constant.uConst;
283 case EbtFloat:
284 return fConst < constant.fConst;
285 default:
286 return false; // Invalid operation, handled at semantic analysis
287 }
288}
289
290// static
291TConstantUnion TConstantUnion::add(const TConstantUnion &lhs,
292 const TConstantUnion &rhs,
Jamie Madill5db69f52016-09-15 12:47:32 -0400293 TDiagnostics *diag,
294 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400295{
296 TConstantUnion returnValue;
297 ASSERT(lhs.type == rhs.type);
298 switch (lhs.type)
299 {
300 case EbtInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100301 returnValue.setIConst(gl::WrappingSum<int>(lhs.iConst, rhs.iConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400302 break;
303 case EbtUInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100304 returnValue.setUConst(gl::WrappingSum<unsigned int>(lhs.uConst, rhs.uConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400305 break;
306 case EbtFloat:
Olli Etuaho2d736652016-11-30 10:37:49 +0000307 returnValue.setFConst(CheckedSum(lhs.fConst, rhs.fConst, diag, line));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400308 break;
309 default:
310 UNREACHABLE();
311 }
312
313 return returnValue;
314}
315
316// static
317TConstantUnion TConstantUnion::sub(const TConstantUnion &lhs,
318 const TConstantUnion &rhs,
Jamie Madill5db69f52016-09-15 12:47:32 -0400319 TDiagnostics *diag,
320 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400321{
322 TConstantUnion returnValue;
323 ASSERT(lhs.type == rhs.type);
324 switch (lhs.type)
325 {
326 case EbtInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100327 returnValue.setIConst(gl::WrappingDiff<int>(lhs.iConst, rhs.iConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400328 break;
329 case EbtUInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100330 returnValue.setUConst(gl::WrappingDiff<unsigned int>(lhs.uConst, rhs.uConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400331 break;
332 case EbtFloat:
Olli Etuaho2d736652016-11-30 10:37:49 +0000333 returnValue.setFConst(CheckedDiff(lhs.fConst, rhs.fConst, diag, line));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400334 break;
335 default:
336 UNREACHABLE();
337 }
338
339 return returnValue;
340}
341
342// static
343TConstantUnion TConstantUnion::mul(const TConstantUnion &lhs,
344 const TConstantUnion &rhs,
Jamie Madill5db69f52016-09-15 12:47:32 -0400345 TDiagnostics *diag,
346 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400347{
348 TConstantUnion returnValue;
349 ASSERT(lhs.type == rhs.type);
350 switch (lhs.type)
351 {
352 case EbtInt:
Olli Etuaho7f9a55f2016-10-03 14:32:08 +0100353 returnValue.setIConst(gl::WrappingMul(lhs.iConst, rhs.iConst));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400354 break;
355 case EbtUInt:
Olli Etuaho1be4d492016-09-27 11:15:38 +0100356 // Unsigned integer math in C++ is defined to be done in modulo 2^n, so we rely on that
357 // to implement wrapping multiplication.
358 returnValue.setUConst(lhs.uConst * rhs.uConst);
Jamie Madill47cb73a2016-09-09 11:41:44 -0400359 break;
360 case EbtFloat:
Olli Etuaho2d736652016-11-30 10:37:49 +0000361 returnValue.setFConst(CheckedMul(lhs.fConst, rhs.fConst, diag, line));
Jamie Madill47cb73a2016-09-09 11:41:44 -0400362 break;
363 default:
364 UNREACHABLE();
365 }
366
367 return returnValue;
368}
369
370TConstantUnion TConstantUnion::operator%(const TConstantUnion &constant) const
371{
372 TConstantUnion returnValue;
373 ASSERT(type == constant.type);
374 switch (type)
375 {
376 case EbtInt:
377 returnValue.setIConst(iConst % constant.iConst);
378 break;
379 case EbtUInt:
380 returnValue.setUConst(uConst % constant.uConst);
381 break;
382 default:
383 UNREACHABLE();
384 }
385
386 return returnValue;
387}
388
Jamie Madill596018c2016-09-21 12:57:03 -0400389// static
390TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs,
391 const TConstantUnion &rhs,
392 TDiagnostics *diag,
393 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400394{
395 TConstantUnion returnValue;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100396 ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
397 ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
Olli Etuaho7e735e42017-01-12 15:42:01 +0000398 if (!IsValidShiftOffset(rhs))
Olli Etuaho2cacb772016-09-26 08:50:40 +0100399 {
Olli Etuaho7e735e42017-01-12 15:42:01 +0000400 diag->warning(line, "Undefined shift (operand out of range)", ">>");
Olli Etuaho2cacb772016-09-26 08:50:40 +0100401 switch (lhs.type)
402 {
403 case EbtInt:
404 returnValue.setIConst(0);
405 break;
406 case EbtUInt:
407 returnValue.setUConst(0u);
408 break;
409 default:
410 UNREACHABLE();
411 }
412 return returnValue;
413 }
414
Jamie Madill596018c2016-09-21 12:57:03 -0400415 switch (lhs.type)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400416 {
417 case EbtInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100418 {
419 unsigned int shiftOffset = 0;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100420 switch (rhs.type)
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400421 {
Olli Etuaho2cacb772016-09-26 08:50:40 +0100422 case EbtInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100423 shiftOffset = static_cast<unsigned int>(rhs.iConst);
Olli Etuaho2cacb772016-09-26 08:50:40 +0100424 break;
425 case EbtUInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100426 shiftOffset = rhs.uConst;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100427 break;
428 default:
429 UNREACHABLE();
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400430 }
Olli Etuaho43103542016-10-10 12:28:13 +0100431 if (shiftOffset > 0)
432 {
433 // ESSL 3.00.6 section 5.9: "If E1 is a signed integer, the right-shift will extend
434 // the sign bit." In C++ shifting negative integers is undefined, so we implement
435 // extending the sign bit manually.
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500436 int lhsSafe = lhs.iConst;
Olli Etuaho55644212016-11-08 11:07:34 +0000437 if (lhsSafe == std::numeric_limits<int>::min())
Olli Etuaho43103542016-10-10 12:28:13 +0100438 {
Olli Etuaho55644212016-11-08 11:07:34 +0000439 // The min integer needs special treatment because only bit it has set is the
440 // sign bit, which we clear later to implement safe right shift of negative
441 // numbers.
442 lhsSafe = -0x40000000;
443 --shiftOffset;
Olli Etuaho43103542016-10-10 12:28:13 +0100444 }
Olli Etuaho55644212016-11-08 11:07:34 +0000445 if (shiftOffset > 0)
Olli Etuaho43103542016-10-10 12:28:13 +0100446 {
Olli Etuaho55644212016-11-08 11:07:34 +0000447 bool extendSignBit = false;
448 if (lhsSafe < 0)
449 {
450 extendSignBit = true;
451 // Clear the sign bit so that bitshift right is defined in C++.
452 lhsSafe &= 0x7fffffff;
453 ASSERT(lhsSafe > 0);
454 }
455 returnValue.setIConst(lhsSafe >> shiftOffset);
456
457 // Manually fill in the extended sign bit if necessary.
458 if (extendSignBit)
459 {
460 int extendedSignBit = static_cast<int>(0xffffffffu << (31 - shiftOffset));
461 returnValue.setIConst(returnValue.getIConst() | extendedSignBit);
462 }
463 }
464 else
465 {
466 returnValue.setIConst(lhsSafe);
Olli Etuaho43103542016-10-10 12:28:13 +0100467 }
468 }
469 else
470 {
Olli Etuaho55644212016-11-08 11:07:34 +0000471 returnValue.setIConst(lhs.iConst);
Olli Etuaho43103542016-10-10 12:28:13 +0100472 }
473 break;
474 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400475 case EbtUInt:
Olli Etuaho2cacb772016-09-26 08:50:40 +0100476 switch (rhs.type)
477 {
478 case EbtInt:
479 returnValue.setUConst(lhs.uConst >> rhs.iConst);
480 break;
481 case EbtUInt:
482 returnValue.setUConst(lhs.uConst >> rhs.uConst);
483 break;
484 default:
485 UNREACHABLE();
486 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400487 break;
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400488
Jamie Madill47cb73a2016-09-09 11:41:44 -0400489 default:
490 UNREACHABLE();
491 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400492 return returnValue;
493}
494
Jamie Madill596018c2016-09-21 12:57:03 -0400495// static
496TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs,
497 const TConstantUnion &rhs,
498 TDiagnostics *diag,
499 const TSourceLoc &line)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400500{
501 TConstantUnion returnValue;
Olli Etuaho2cacb772016-09-26 08:50:40 +0100502 ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
503 ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
Olli Etuaho7e735e42017-01-12 15:42:01 +0000504 if (!IsValidShiftOffset(rhs))
Olli Etuaho2cacb772016-09-26 08:50:40 +0100505 {
Olli Etuaho7e735e42017-01-12 15:42:01 +0000506 diag->warning(line, "Undefined shift (operand out of range)", "<<");
Olli Etuaho2cacb772016-09-26 08:50:40 +0100507 switch (lhs.type)
508 {
509 case EbtInt:
510 returnValue.setIConst(0);
511 break;
512 case EbtUInt:
513 returnValue.setUConst(0u);
514 break;
515 default:
516 UNREACHABLE();
517 }
518 return returnValue;
519 }
520
Jamie Madill596018c2016-09-21 12:57:03 -0400521 switch (lhs.type)
Jamie Madill47cb73a2016-09-09 11:41:44 -0400522 {
523 case EbtInt:
Olli Etuaho2cacb772016-09-26 08:50:40 +0100524 switch (rhs.type)
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400525 {
Olli Etuaho43103542016-10-10 12:28:13 +0100526 // Cast to unsigned integer before shifting, since ESSL 3.00.6 section 5.9 says that
527 // lhs is "interpreted as a bit pattern". This also avoids the possibility of signed
528 // integer overflow or undefined shift of a negative integer.
Olli Etuaho2cacb772016-09-26 08:50:40 +0100529 case EbtInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100530 returnValue.setIConst(
531 static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.iConst));
Olli Etuaho2cacb772016-09-26 08:50:40 +0100532 break;
533 case EbtUInt:
Olli Etuaho43103542016-10-10 12:28:13 +0100534 returnValue.setIConst(
535 static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.uConst));
Olli Etuaho2cacb772016-09-26 08:50:40 +0100536 break;
537 default:
538 UNREACHABLE();
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400539 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400540 break;
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400541
Jamie Madill47cb73a2016-09-09 11:41:44 -0400542 case EbtUInt:
Olli Etuaho2cacb772016-09-26 08:50:40 +0100543 switch (rhs.type)
544 {
545 case EbtInt:
546 returnValue.setUConst(lhs.uConst << rhs.iConst);
547 break;
548 case EbtUInt:
549 returnValue.setUConst(lhs.uConst << rhs.uConst);
550 break;
551 default:
552 UNREACHABLE();
553 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400554 break;
Jamie Madill44ebf6b2016-09-22 13:00:02 -0400555
Jamie Madill47cb73a2016-09-09 11:41:44 -0400556 default:
557 UNREACHABLE();
558 }
Jamie Madill47cb73a2016-09-09 11:41:44 -0400559 return returnValue;
560}
561
562TConstantUnion TConstantUnion::operator&(const TConstantUnion &constant) const
563{
564 TConstantUnion returnValue;
565 ASSERT(constant.type == EbtInt || constant.type == EbtUInt);
566 switch (type)
567 {
568 case EbtInt:
569 returnValue.setIConst(iConst & constant.iConst);
570 break;
571 case EbtUInt:
572 returnValue.setUConst(uConst & constant.uConst);
573 break;
574 default:
575 UNREACHABLE();
576 }
577
578 return returnValue;
579}
580
581TConstantUnion TConstantUnion::operator|(const TConstantUnion &constant) const
582{
583 TConstantUnion returnValue;
584 ASSERT(type == constant.type);
585 switch (type)
586 {
587 case EbtInt:
588 returnValue.setIConst(iConst | constant.iConst);
589 break;
590 case EbtUInt:
591 returnValue.setUConst(uConst | constant.uConst);
592 break;
593 default:
594 UNREACHABLE();
595 }
596
597 return returnValue;
598}
599
600TConstantUnion TConstantUnion::operator^(const TConstantUnion &constant) const
601{
602 TConstantUnion returnValue;
603 ASSERT(type == constant.type);
604 switch (type)
605 {
606 case EbtInt:
607 returnValue.setIConst(iConst ^ constant.iConst);
608 break;
609 case EbtUInt:
610 returnValue.setUConst(uConst ^ constant.uConst);
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}
634
635TConstantUnion TConstantUnion::operator||(const TConstantUnion &constant) const
636{
637 TConstantUnion returnValue;
638 ASSERT(type == constant.type);
639 switch (type)
640 {
641 case EbtBool:
642 returnValue.setBConst(bConst || constant.bConst);
643 break;
644 default:
645 UNREACHABLE();
646 }
647
648 return returnValue;
649}
Jamie Madill45bcc782016-11-07 13:58:48 -0500650
651} // namespace sh