1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2010 Intel Corporation
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b8e80941Smrg * DEALINGS IN THE SOFTWARE.
22b8e80941Smrg */
23b8e80941Smrg
24b8e80941Smrg/**
25b8e80941Smrg * \file ir_constant_expression.cpp
26b8e80941Smrg * Evaluate and process constant valued expressions
27b8e80941Smrg *
28b8e80941Smrg * In GLSL, constant valued expressions are used in several places.  These
29b8e80941Smrg * must be processed and evaluated very early in the compilation process.
30b8e80941Smrg *
31b8e80941Smrg *    * Sizes of arrays
32b8e80941Smrg *    * Initializers for uniforms
33b8e80941Smrg *    * Initializers for \c const variables
34b8e80941Smrg */
35b8e80941Smrg
36b8e80941Smrg#include <math.h>
37b8e80941Smrg#include "util/rounding.h" /* for _mesa_roundeven */
38b8e80941Smrg#include "util/half_float.h"
39b8e80941Smrg#include "ir.h"
40b8e80941Smrg#include "compiler/glsl_types.h"
41b8e80941Smrg#include "util/hash_table.h"
42b8e80941Smrg#include "util/u_math.h"
43b8e80941Smrg
44b8e80941Smrgstatic float
45b8e80941Smrgdot_f(ir_constant *op0, ir_constant *op1)
46b8e80941Smrg{
47b8e80941Smrg   assert(op0->type->is_float() && op1->type->is_float());
48b8e80941Smrg
49b8e80941Smrg   float result = 0;
50b8e80941Smrg   for (unsigned c = 0; c < op0->type->components(); c++)
51b8e80941Smrg      result += op0->value.f[c] * op1->value.f[c];
52b8e80941Smrg
53b8e80941Smrg   return result;
54b8e80941Smrg}
55b8e80941Smrg
56b8e80941Smrgstatic double
57b8e80941Smrgdot_d(ir_constant *op0, ir_constant *op1)
58b8e80941Smrg{
59b8e80941Smrg   assert(op0->type->is_double() && op1->type->is_double());
60b8e80941Smrg
61b8e80941Smrg   double result = 0;
62b8e80941Smrg   for (unsigned c = 0; c < op0->type->components(); c++)
63b8e80941Smrg      result += op0->value.d[c] * op1->value.d[c];
64b8e80941Smrg
65b8e80941Smrg   return result;
66b8e80941Smrg}
67b8e80941Smrg
68b8e80941Smrg/* This method is the only one supported by gcc.  Unions in particular
69b8e80941Smrg * are iffy, and read-through-converted-pointer is killed by strict
70b8e80941Smrg * aliasing.  OTOH, the compiler sees through the memcpy, so the
71b8e80941Smrg * resulting asm is reasonable.
72b8e80941Smrg */
73b8e80941Smrgstatic float
74b8e80941Smrgbitcast_u2f(unsigned int u)
75b8e80941Smrg{
76b8e80941Smrg   assert(sizeof(float) == sizeof(unsigned int));
77b8e80941Smrg   float f;
78b8e80941Smrg   memcpy(&f, &u, sizeof(f));
79b8e80941Smrg   return f;
80b8e80941Smrg}
81b8e80941Smrg
82b8e80941Smrgstatic unsigned int
83b8e80941Smrgbitcast_f2u(float f)
84b8e80941Smrg{
85b8e80941Smrg   assert(sizeof(float) == sizeof(unsigned int));
86b8e80941Smrg   unsigned int u;
87b8e80941Smrg   memcpy(&u, &f, sizeof(f));
88b8e80941Smrg   return u;
89b8e80941Smrg}
90b8e80941Smrg
91b8e80941Smrgstatic double
92b8e80941Smrgbitcast_u642d(uint64_t u)
93b8e80941Smrg{
94b8e80941Smrg   assert(sizeof(double) == sizeof(uint64_t));
95b8e80941Smrg   double d;
96b8e80941Smrg   memcpy(&d, &u, sizeof(d));
97b8e80941Smrg   return d;
98b8e80941Smrg}
99b8e80941Smrg
100b8e80941Smrgstatic double
101b8e80941Smrgbitcast_i642d(int64_t i)
102b8e80941Smrg{
103b8e80941Smrg   assert(sizeof(double) == sizeof(int64_t));
104b8e80941Smrg   double d;
105b8e80941Smrg   memcpy(&d, &i, sizeof(d));
106b8e80941Smrg   return d;
107b8e80941Smrg}
108b8e80941Smrg
109b8e80941Smrgstatic double
110b8e80941Smrgbitcast_d2u64(double d)
111b8e80941Smrg{
112b8e80941Smrg   assert(sizeof(double) == sizeof(uint64_t));
113b8e80941Smrg   uint64_t u;
114b8e80941Smrg   memcpy(&u, &d, sizeof(d));
115b8e80941Smrg   return u;
116b8e80941Smrg}
117b8e80941Smrg
118b8e80941Smrgstatic double
119b8e80941Smrgbitcast_d2i64(double d)
120b8e80941Smrg{
121b8e80941Smrg   assert(sizeof(double) == sizeof(int64_t));
122b8e80941Smrg   int64_t i;
123b8e80941Smrg   memcpy(&i, &d, sizeof(d));
124b8e80941Smrg   return i;
125b8e80941Smrg}
126b8e80941Smrg
127b8e80941Smrg/**
128b8e80941Smrg * Evaluate one component of a floating-point 4x8 unpacking function.
129b8e80941Smrg */
130b8e80941Smrgtypedef uint8_t
131b8e80941Smrg(*pack_1x8_func_t)(float);
132b8e80941Smrg
133b8e80941Smrg/**
134b8e80941Smrg * Evaluate one component of a floating-point 2x16 unpacking function.
135b8e80941Smrg */
136b8e80941Smrgtypedef uint16_t
137b8e80941Smrg(*pack_1x16_func_t)(float);
138b8e80941Smrg
139b8e80941Smrg/**
140b8e80941Smrg * Evaluate one component of a floating-point 4x8 unpacking function.
141b8e80941Smrg */
142b8e80941Smrgtypedef float
143b8e80941Smrg(*unpack_1x8_func_t)(uint8_t);
144b8e80941Smrg
145b8e80941Smrg/**
146b8e80941Smrg * Evaluate one component of a floating-point 2x16 unpacking function.
147b8e80941Smrg */
148b8e80941Smrgtypedef float
149b8e80941Smrg(*unpack_1x16_func_t)(uint16_t);
150b8e80941Smrg
151b8e80941Smrg/**
152b8e80941Smrg * Evaluate a 2x16 floating-point packing function.
153b8e80941Smrg */
154b8e80941Smrgstatic uint32_t
155b8e80941Smrgpack_2x16(pack_1x16_func_t pack_1x16,
156b8e80941Smrg          float x, float y)
157b8e80941Smrg{
158b8e80941Smrg   /* From section 8.4 of the GLSL ES 3.00 spec:
159b8e80941Smrg    *
160b8e80941Smrg    *    packSnorm2x16
161b8e80941Smrg    *    -------------
162b8e80941Smrg    *    The first component of the vector will be written to the least
163b8e80941Smrg    *    significant bits of the output; the last component will be written to
164b8e80941Smrg    *    the most significant bits.
165b8e80941Smrg    *
166b8e80941Smrg    * The specifications for the other packing functions contain similar
167b8e80941Smrg    * language.
168b8e80941Smrg    */
169b8e80941Smrg   uint32_t u = 0;
170b8e80941Smrg   u |= ((uint32_t) pack_1x16(x) << 0);
171b8e80941Smrg   u |= ((uint32_t) pack_1x16(y) << 16);
172b8e80941Smrg   return u;
173b8e80941Smrg}
174b8e80941Smrg
175b8e80941Smrg/**
176b8e80941Smrg * Evaluate a 4x8 floating-point packing function.
177b8e80941Smrg */
178b8e80941Smrgstatic uint32_t
179b8e80941Smrgpack_4x8(pack_1x8_func_t pack_1x8,
180b8e80941Smrg         float x, float y, float z, float w)
181b8e80941Smrg{
182b8e80941Smrg   /* From section 8.4 of the GLSL 4.30 spec:
183b8e80941Smrg    *
184b8e80941Smrg    *    packSnorm4x8
185b8e80941Smrg    *    ------------
186b8e80941Smrg    *    The first component of the vector will be written to the least
187b8e80941Smrg    *    significant bits of the output; the last component will be written to
188b8e80941Smrg    *    the most significant bits.
189b8e80941Smrg    *
190b8e80941Smrg    * The specifications for the other packing functions contain similar
191b8e80941Smrg    * language.
192b8e80941Smrg    */
193b8e80941Smrg   uint32_t u = 0;
194b8e80941Smrg   u |= ((uint32_t) pack_1x8(x) << 0);
195b8e80941Smrg   u |= ((uint32_t) pack_1x8(y) << 8);
196b8e80941Smrg   u |= ((uint32_t) pack_1x8(z) << 16);
197b8e80941Smrg   u |= ((uint32_t) pack_1x8(w) << 24);
198b8e80941Smrg   return u;
199b8e80941Smrg}
200b8e80941Smrg
201b8e80941Smrg/**
202b8e80941Smrg * Evaluate a 2x16 floating-point unpacking function.
203b8e80941Smrg */
204b8e80941Smrgstatic void
205b8e80941Smrgunpack_2x16(unpack_1x16_func_t unpack_1x16,
206b8e80941Smrg            uint32_t u,
207b8e80941Smrg            float *x, float *y)
208b8e80941Smrg{
209b8e80941Smrg    /* From section 8.4 of the GLSL ES 3.00 spec:
210b8e80941Smrg     *
211b8e80941Smrg     *    unpackSnorm2x16
212b8e80941Smrg     *    ---------------
213b8e80941Smrg     *    The first component of the returned vector will be extracted from
214b8e80941Smrg     *    the least significant bits of the input; the last component will be
215b8e80941Smrg     *    extracted from the most significant bits.
216b8e80941Smrg     *
217b8e80941Smrg     * The specifications for the other unpacking functions contain similar
218b8e80941Smrg     * language.
219b8e80941Smrg     */
220b8e80941Smrg   *x = unpack_1x16((uint16_t) (u & 0xffff));
221b8e80941Smrg   *y = unpack_1x16((uint16_t) (u >> 16));
222b8e80941Smrg}
223b8e80941Smrg
224b8e80941Smrg/**
225b8e80941Smrg * Evaluate a 4x8 floating-point unpacking function.
226b8e80941Smrg */
227b8e80941Smrgstatic void
228b8e80941Smrgunpack_4x8(unpack_1x8_func_t unpack_1x8, uint32_t u,
229b8e80941Smrg           float *x, float *y, float *z, float *w)
230b8e80941Smrg{
231b8e80941Smrg    /* From section 8.4 of the GLSL 4.30 spec:
232b8e80941Smrg     *
233b8e80941Smrg     *    unpackSnorm4x8
234b8e80941Smrg     *    --------------
235b8e80941Smrg     *    The first component of the returned vector will be extracted from
236b8e80941Smrg     *    the least significant bits of the input; the last component will be
237b8e80941Smrg     *    extracted from the most significant bits.
238b8e80941Smrg     *
239b8e80941Smrg     * The specifications for the other unpacking functions contain similar
240b8e80941Smrg     * language.
241b8e80941Smrg     */
242b8e80941Smrg   *x = unpack_1x8((uint8_t) (u & 0xff));
243b8e80941Smrg   *y = unpack_1x8((uint8_t) (u >> 8));
244b8e80941Smrg   *z = unpack_1x8((uint8_t) (u >> 16));
245b8e80941Smrg   *w = unpack_1x8((uint8_t) (u >> 24));
246b8e80941Smrg}
247b8e80941Smrg
248b8e80941Smrg/**
249b8e80941Smrg * Evaluate one component of packSnorm4x8.
250b8e80941Smrg */
251b8e80941Smrgstatic uint8_t
252b8e80941Smrgpack_snorm_1x8(float x)
253b8e80941Smrg{
254b8e80941Smrg    /* From section 8.4 of the GLSL 4.30 spec:
255b8e80941Smrg     *
256b8e80941Smrg     *    packSnorm4x8
257b8e80941Smrg     *    ------------
258b8e80941Smrg     *    The conversion for component c of v to fixed point is done as
259b8e80941Smrg     *    follows:
260b8e80941Smrg     *
261b8e80941Smrg     *      packSnorm4x8: round(clamp(c, -1, +1) * 127.0)
262b8e80941Smrg     */
263b8e80941Smrg   return (uint8_t)
264b8e80941Smrg          _mesa_lroundevenf(CLAMP(x, -1.0f, +1.0f) * 127.0f);
265b8e80941Smrg}
266b8e80941Smrg
267b8e80941Smrg/**
268b8e80941Smrg * Evaluate one component of packSnorm2x16.
269b8e80941Smrg */
270b8e80941Smrgstatic uint16_t
271b8e80941Smrgpack_snorm_1x16(float x)
272b8e80941Smrg{
273b8e80941Smrg    /* From section 8.4 of the GLSL ES 3.00 spec:
274b8e80941Smrg     *
275b8e80941Smrg     *    packSnorm2x16
276b8e80941Smrg     *    -------------
277b8e80941Smrg     *    The conversion for component c of v to fixed point is done as
278b8e80941Smrg     *    follows:
279b8e80941Smrg     *
280b8e80941Smrg     *      packSnorm2x16: round(clamp(c, -1, +1) * 32767.0)
281b8e80941Smrg     */
282b8e80941Smrg   return (uint16_t)
283b8e80941Smrg          _mesa_lroundevenf(CLAMP(x, -1.0f, +1.0f) * 32767.0f);
284b8e80941Smrg}
285b8e80941Smrg
286b8e80941Smrg/**
287b8e80941Smrg * Evaluate one component of unpackSnorm4x8.
288b8e80941Smrg */
289b8e80941Smrgstatic float
290b8e80941Smrgunpack_snorm_1x8(uint8_t u)
291b8e80941Smrg{
292b8e80941Smrg    /* From section 8.4 of the GLSL 4.30 spec:
293b8e80941Smrg     *
294b8e80941Smrg     *    unpackSnorm4x8
295b8e80941Smrg     *    --------------
296b8e80941Smrg     *    The conversion for unpacked fixed-point value f to floating point is
297b8e80941Smrg     *    done as follows:
298b8e80941Smrg     *
299b8e80941Smrg     *       unpackSnorm4x8: clamp(f / 127.0, -1, +1)
300b8e80941Smrg     */
301b8e80941Smrg   return CLAMP((int8_t) u / 127.0f, -1.0f, +1.0f);
302b8e80941Smrg}
303b8e80941Smrg
304b8e80941Smrg/**
305b8e80941Smrg * Evaluate one component of unpackSnorm2x16.
306b8e80941Smrg */
307b8e80941Smrgstatic float
308b8e80941Smrgunpack_snorm_1x16(uint16_t u)
309b8e80941Smrg{
310b8e80941Smrg    /* From section 8.4 of the GLSL ES 3.00 spec:
311b8e80941Smrg     *
312b8e80941Smrg     *    unpackSnorm2x16
313b8e80941Smrg     *    ---------------
314b8e80941Smrg     *    The conversion for unpacked fixed-point value f to floating point is
315b8e80941Smrg     *    done as follows:
316b8e80941Smrg     *
317b8e80941Smrg     *       unpackSnorm2x16: clamp(f / 32767.0, -1, +1)
318b8e80941Smrg     */
319b8e80941Smrg   return CLAMP((int16_t) u / 32767.0f, -1.0f, +1.0f);
320b8e80941Smrg}
321b8e80941Smrg
322b8e80941Smrg/**
323b8e80941Smrg * Evaluate one component packUnorm4x8.
324b8e80941Smrg */
325b8e80941Smrgstatic uint8_t
326b8e80941Smrgpack_unorm_1x8(float x)
327b8e80941Smrg{
328b8e80941Smrg    /* From section 8.4 of the GLSL 4.30 spec:
329b8e80941Smrg     *
330b8e80941Smrg     *    packUnorm4x8
331b8e80941Smrg     *    ------------
332b8e80941Smrg     *    The conversion for component c of v to fixed point is done as
333b8e80941Smrg     *    follows:
334b8e80941Smrg     *
335b8e80941Smrg     *       packUnorm4x8: round(clamp(c, 0, +1) * 255.0)
336b8e80941Smrg     */
337b8e80941Smrg   return (uint8_t) (int) _mesa_roundevenf(CLAMP(x, 0.0f, 1.0f) * 255.0f);
338b8e80941Smrg}
339b8e80941Smrg
340b8e80941Smrg/**
341b8e80941Smrg * Evaluate one component packUnorm2x16.
342b8e80941Smrg */
343b8e80941Smrgstatic uint16_t
344b8e80941Smrgpack_unorm_1x16(float x)
345b8e80941Smrg{
346b8e80941Smrg    /* From section 8.4 of the GLSL ES 3.00 spec:
347b8e80941Smrg     *
348b8e80941Smrg     *    packUnorm2x16
349b8e80941Smrg     *    -------------
350b8e80941Smrg     *    The conversion for component c of v to fixed point is done as
351b8e80941Smrg     *    follows:
352b8e80941Smrg     *
353b8e80941Smrg     *       packUnorm2x16: round(clamp(c, 0, +1) * 65535.0)
354b8e80941Smrg     */
355b8e80941Smrg   return (uint16_t) (int)
356b8e80941Smrg          _mesa_roundevenf(CLAMP(x, 0.0f, 1.0f) * 65535.0f);
357b8e80941Smrg}
358b8e80941Smrg
359b8e80941Smrg/**
360b8e80941Smrg * Evaluate one component of unpackUnorm4x8.
361b8e80941Smrg */
362b8e80941Smrgstatic float
363b8e80941Smrgunpack_unorm_1x8(uint8_t u)
364b8e80941Smrg{
365b8e80941Smrg    /* From section 8.4 of the GLSL 4.30 spec:
366b8e80941Smrg     *
367b8e80941Smrg     *    unpackUnorm4x8
368b8e80941Smrg     *    --------------
369b8e80941Smrg     *    The conversion for unpacked fixed-point value f to floating point is
370b8e80941Smrg     *    done as follows:
371b8e80941Smrg     *
372b8e80941Smrg     *       unpackUnorm4x8: f / 255.0
373b8e80941Smrg     */
374b8e80941Smrg   return (float) u / 255.0f;
375b8e80941Smrg}
376b8e80941Smrg
377b8e80941Smrg/**
378b8e80941Smrg * Evaluate one component of unpackUnorm2x16.
379b8e80941Smrg */
380b8e80941Smrgstatic float
381b8e80941Smrgunpack_unorm_1x16(uint16_t u)
382b8e80941Smrg{
383b8e80941Smrg    /* From section 8.4 of the GLSL ES 3.00 spec:
384b8e80941Smrg     *
385b8e80941Smrg     *    unpackUnorm2x16
386b8e80941Smrg     *    ---------------
387b8e80941Smrg     *    The conversion for unpacked fixed-point value f to floating point is
388b8e80941Smrg     *    done as follows:
389b8e80941Smrg     *
390b8e80941Smrg     *       unpackUnorm2x16: f / 65535.0
391b8e80941Smrg     */
392b8e80941Smrg   return (float) u / 65535.0f;
393b8e80941Smrg}
394b8e80941Smrg
395b8e80941Smrg/**
396b8e80941Smrg * Evaluate one component of packHalf2x16.
397b8e80941Smrg */
398b8e80941Smrgstatic uint16_t
399b8e80941Smrgpack_half_1x16(float x)
400b8e80941Smrg{
401b8e80941Smrg   return _mesa_float_to_half(x);
402b8e80941Smrg}
403b8e80941Smrg
404b8e80941Smrg/**
405b8e80941Smrg * Evaluate one component of unpackHalf2x16.
406b8e80941Smrg */
407b8e80941Smrgstatic float
408b8e80941Smrgunpack_half_1x16(uint16_t u)
409b8e80941Smrg{
410b8e80941Smrg   return _mesa_half_to_float(u);
411b8e80941Smrg}
412b8e80941Smrg
413b8e80941Smrg/**
414b8e80941Smrg * Get the constant that is ultimately referenced by an r-value, in a constant
415b8e80941Smrg * expression evaluation context.
416b8e80941Smrg *
417b8e80941Smrg * The offset is used when the reference is to a specific column of a matrix.
418b8e80941Smrg */
419b8e80941Smrgstatic bool
420b8e80941Smrgconstant_referenced(const ir_dereference *deref,
421b8e80941Smrg                    struct hash_table *variable_context,
422b8e80941Smrg                    ir_constant *&store, int &offset)
423b8e80941Smrg{
424b8e80941Smrg   store = NULL;
425b8e80941Smrg   offset = 0;
426b8e80941Smrg
427b8e80941Smrg   if (variable_context == NULL)
428b8e80941Smrg      return false;
429b8e80941Smrg
430b8e80941Smrg   switch (deref->ir_type) {
431b8e80941Smrg   case ir_type_dereference_array: {
432b8e80941Smrg      const ir_dereference_array *const da =
433b8e80941Smrg         (const ir_dereference_array *) deref;
434b8e80941Smrg
435b8e80941Smrg      ir_constant *const index_c =
436b8e80941Smrg         da->array_index->constant_expression_value(variable_context);
437b8e80941Smrg
438b8e80941Smrg      if (!index_c || !index_c->type->is_scalar() || !index_c->type->is_integer())
439b8e80941Smrg         break;
440b8e80941Smrg
441b8e80941Smrg      const int index = index_c->type->base_type == GLSL_TYPE_INT ?
442b8e80941Smrg         index_c->get_int_component(0) :
443b8e80941Smrg         index_c->get_uint_component(0);
444b8e80941Smrg
445b8e80941Smrg      ir_constant *substore;
446b8e80941Smrg      int suboffset;
447b8e80941Smrg
448b8e80941Smrg      const ir_dereference *const deref = da->array->as_dereference();
449b8e80941Smrg      if (!deref)
450b8e80941Smrg         break;
451b8e80941Smrg
452b8e80941Smrg      if (!constant_referenced(deref, variable_context, substore, suboffset))
453b8e80941Smrg         break;
454b8e80941Smrg
455b8e80941Smrg      const glsl_type *const vt = da->array->type;
456b8e80941Smrg      if (vt->is_array()) {
457b8e80941Smrg         store = substore->get_array_element(index);
458b8e80941Smrg         offset = 0;
459b8e80941Smrg      } else if (vt->is_matrix()) {
460b8e80941Smrg         store = substore;
461b8e80941Smrg         offset = index * vt->vector_elements;
462b8e80941Smrg      } else if (vt->is_vector()) {
463b8e80941Smrg         store = substore;
464b8e80941Smrg         offset = suboffset + index;
465b8e80941Smrg      }
466b8e80941Smrg
467b8e80941Smrg      break;
468b8e80941Smrg   }
469b8e80941Smrg
470b8e80941Smrg   case ir_type_dereference_record: {
471b8e80941Smrg      const ir_dereference_record *const dr =
472b8e80941Smrg         (const ir_dereference_record *) deref;
473b8e80941Smrg
474b8e80941Smrg      const ir_dereference *const deref = dr->record->as_dereference();
475b8e80941Smrg      if (!deref)
476b8e80941Smrg         break;
477b8e80941Smrg
478b8e80941Smrg      ir_constant *substore;
479b8e80941Smrg      int suboffset;
480b8e80941Smrg
481b8e80941Smrg      if (!constant_referenced(deref, variable_context, substore, suboffset))
482b8e80941Smrg         break;
483b8e80941Smrg
484b8e80941Smrg      /* Since we're dropping it on the floor...
485b8e80941Smrg       */
486b8e80941Smrg      assert(suboffset == 0);
487b8e80941Smrg
488b8e80941Smrg      store = substore->get_record_field(dr->field_idx);
489b8e80941Smrg      break;
490b8e80941Smrg   }
491b8e80941Smrg
492b8e80941Smrg   case ir_type_dereference_variable: {
493b8e80941Smrg      const ir_dereference_variable *const dv =
494b8e80941Smrg         (const ir_dereference_variable *) deref;
495b8e80941Smrg
496b8e80941Smrg      hash_entry *entry = _mesa_hash_table_search(variable_context, dv->var);
497b8e80941Smrg      if (entry)
498b8e80941Smrg         store = (ir_constant *) entry->data;
499b8e80941Smrg      break;
500b8e80941Smrg   }
501b8e80941Smrg
502b8e80941Smrg   default:
503b8e80941Smrg      assert(!"Should not get here.");
504b8e80941Smrg      break;
505b8e80941Smrg   }
506b8e80941Smrg
507b8e80941Smrg   return store != NULL;
508b8e80941Smrg}
509b8e80941Smrg
510b8e80941Smrg
511b8e80941Smrgir_constant *
512b8e80941Smrgir_rvalue::constant_expression_value(void *, struct hash_table *)
513b8e80941Smrg{
514b8e80941Smrg   assert(this->type->is_error());
515b8e80941Smrg   return NULL;
516b8e80941Smrg}
517b8e80941Smrg
518b8e80941Smrgstatic uint32_t
519b8e80941Smrgbitfield_reverse(uint32_t v)
520b8e80941Smrg{
521b8e80941Smrg   /* http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious */
522b8e80941Smrg   uint32_t r = v; // r will be reversed bits of v; first get LSB of v
523b8e80941Smrg   int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end
524b8e80941Smrg
525b8e80941Smrg   for (v >>= 1; v; v >>= 1) {
526b8e80941Smrg      r <<= 1;
527b8e80941Smrg      r |= v & 1;
528b8e80941Smrg      s--;
529b8e80941Smrg   }
530b8e80941Smrg   r <<= s; // shift when v's highest bits are zero
531b8e80941Smrg
532b8e80941Smrg   return r;
533b8e80941Smrg}
534b8e80941Smrg
535b8e80941Smrgstatic int
536b8e80941Smrgfind_msb_uint(uint32_t v)
537b8e80941Smrg{
538b8e80941Smrg   int count = 0;
539b8e80941Smrg
540b8e80941Smrg   /* If v == 0, then the loop will terminate when count == 32.  In that case
541b8e80941Smrg    * 31-count will produce the -1 result required by GLSL findMSB().
542b8e80941Smrg    */
543b8e80941Smrg   while (((v & (1u << 31)) == 0) && count != 32) {
544b8e80941Smrg      count++;
545b8e80941Smrg      v <<= 1;
546b8e80941Smrg   }
547b8e80941Smrg
548b8e80941Smrg   return 31 - count;
549b8e80941Smrg}
550b8e80941Smrg
551b8e80941Smrgstatic int
552b8e80941Smrgfind_msb_int(int32_t v)
553b8e80941Smrg{
554b8e80941Smrg   /* If v is signed, findMSB() returns the position of the most significant
555b8e80941Smrg    * zero bit.
556b8e80941Smrg    */
557b8e80941Smrg   return find_msb_uint(v < 0 ? ~v : v);
558b8e80941Smrg}
559b8e80941Smrg
560b8e80941Smrgstatic float
561b8e80941Smrgldexpf_flush_subnormal(float x, int exp)
562b8e80941Smrg{
563b8e80941Smrg   const float result = ldexpf(x, exp);
564b8e80941Smrg
565b8e80941Smrg   /* Flush subnormal values to zero. */
566b8e80941Smrg   return !isnormal(result) ? copysignf(0.0f, x) : result;
567b8e80941Smrg}
568b8e80941Smrg
569b8e80941Smrgstatic double
570b8e80941Smrgldexp_flush_subnormal(double x, int exp)
571b8e80941Smrg{
572b8e80941Smrg   const double result = ldexp(x, exp);
573b8e80941Smrg
574b8e80941Smrg   /* Flush subnormal values to zero. */
575b8e80941Smrg   return !isnormal(result) ? copysign(0.0, x) : result;
576b8e80941Smrg}
577b8e80941Smrg
578b8e80941Smrgstatic uint32_t
579b8e80941Smrgbitfield_extract_uint(uint32_t value, int offset, int bits)
580b8e80941Smrg{
581b8e80941Smrg   if (bits == 0)
582b8e80941Smrg      return 0;
583b8e80941Smrg   else if (offset < 0 || bits < 0)
584b8e80941Smrg      return 0; /* Undefined, per spec. */
585b8e80941Smrg   else if (offset + bits > 32)
586b8e80941Smrg      return 0; /* Undefined, per spec. */
587b8e80941Smrg   else {
588b8e80941Smrg      value <<= 32 - bits - offset;
589b8e80941Smrg      value >>= 32 - bits;
590b8e80941Smrg      return value;
591b8e80941Smrg   }
592b8e80941Smrg}
593b8e80941Smrg
594b8e80941Smrgstatic int32_t
595b8e80941Smrgbitfield_extract_int(int32_t value, int offset, int bits)
596b8e80941Smrg{
597b8e80941Smrg   if (bits == 0)
598b8e80941Smrg      return 0;
599b8e80941Smrg   else if (offset < 0 || bits < 0)
600b8e80941Smrg      return 0; /* Undefined, per spec. */
601b8e80941Smrg   else if (offset + bits > 32)
602b8e80941Smrg      return 0; /* Undefined, per spec. */
603b8e80941Smrg   else {
604b8e80941Smrg      value <<= 32 - bits - offset;
605b8e80941Smrg      value >>= 32 - bits;
606b8e80941Smrg      return value;
607b8e80941Smrg   }
608b8e80941Smrg}
609b8e80941Smrg
610b8e80941Smrgstatic uint32_t
611b8e80941Smrgbitfield_insert(uint32_t base, uint32_t insert, int offset, int bits)
612b8e80941Smrg{
613b8e80941Smrg   if (bits == 0)
614b8e80941Smrg      return base;
615b8e80941Smrg   else if (offset < 0 || bits < 0)
616b8e80941Smrg      return 0; /* Undefined, per spec. */
617b8e80941Smrg   else if (offset + bits > 32)
618b8e80941Smrg      return 0; /* Undefined, per spec. */
619b8e80941Smrg   else {
620b8e80941Smrg      unsigned insert_mask = ((1ull << bits) - 1) << offset;
621b8e80941Smrg
622b8e80941Smrg      insert <<= offset;
623b8e80941Smrg      insert &= insert_mask;
624b8e80941Smrg      base &= ~insert_mask;
625b8e80941Smrg
626b8e80941Smrg      return base | insert;
627b8e80941Smrg   }
628b8e80941Smrg}
629b8e80941Smrg
630b8e80941Smrgir_constant *
631b8e80941Smrgir_expression::constant_expression_value(void *mem_ctx,
632b8e80941Smrg                                         struct hash_table *variable_context)
633b8e80941Smrg{
634b8e80941Smrg   assert(mem_ctx);
635b8e80941Smrg
636b8e80941Smrg   if (this->type->is_error())
637b8e80941Smrg      return NULL;
638b8e80941Smrg
639b8e80941Smrg   ir_constant *op[ARRAY_SIZE(this->operands)] = { NULL, };
640b8e80941Smrg   ir_constant_data data;
641b8e80941Smrg
642b8e80941Smrg   memset(&data, 0, sizeof(data));
643b8e80941Smrg
644b8e80941Smrg   for (unsigned operand = 0; operand < this->num_operands; operand++) {
645b8e80941Smrg      op[operand] =
646b8e80941Smrg         this->operands[operand]->constant_expression_value(mem_ctx,
647b8e80941Smrg                                                            variable_context);
648b8e80941Smrg      if (!op[operand])
649b8e80941Smrg         return NULL;
650b8e80941Smrg   }
651b8e80941Smrg
652b8e80941Smrg   if (op[1] != NULL)
653b8e80941Smrg      switch (this->operation) {
654b8e80941Smrg      case ir_binop_lshift:
655b8e80941Smrg      case ir_binop_rshift:
656b8e80941Smrg      case ir_binop_ldexp:
657b8e80941Smrg      case ir_binop_interpolate_at_offset:
658b8e80941Smrg      case ir_binop_interpolate_at_sample:
659b8e80941Smrg      case ir_binop_vector_extract:
660b8e80941Smrg      case ir_triop_csel:
661b8e80941Smrg      case ir_triop_bitfield_extract:
662b8e80941Smrg         break;
663b8e80941Smrg
664b8e80941Smrg      default:
665b8e80941Smrg         assert(op[0]->type->base_type == op[1]->type->base_type);
666b8e80941Smrg         break;
667b8e80941Smrg      }
668b8e80941Smrg
669b8e80941Smrg   bool op0_scalar = op[0]->type->is_scalar();
670b8e80941Smrg   bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
671b8e80941Smrg
672b8e80941Smrg   /* When iterating over a vector or matrix's components, we want to increase
673b8e80941Smrg    * the loop counter.  However, for scalars, we want to stay at 0.
674b8e80941Smrg    */
675b8e80941Smrg   unsigned c0_inc = op0_scalar ? 0 : 1;
676b8e80941Smrg   unsigned c1_inc = op1_scalar ? 0 : 1;
677b8e80941Smrg   unsigned components;
678b8e80941Smrg   if (op1_scalar || !op[1]) {
679b8e80941Smrg      components = op[0]->type->components();
680b8e80941Smrg   } else {
681b8e80941Smrg      components = op[1]->type->components();
682b8e80941Smrg   }
683b8e80941Smrg
684b8e80941Smrg   /* Handle array operations here, rather than below. */
685b8e80941Smrg   if (op[0]->type->is_array()) {
686b8e80941Smrg      assert(op[1] != NULL && op[1]->type->is_array());
687b8e80941Smrg      switch (this->operation) {
688b8e80941Smrg      case ir_binop_all_equal:
689b8e80941Smrg         return new(mem_ctx) ir_constant(op[0]->has_value(op[1]));
690b8e80941Smrg      case ir_binop_any_nequal:
691b8e80941Smrg         return new(mem_ctx) ir_constant(!op[0]->has_value(op[1]));
692b8e80941Smrg      default:
693b8e80941Smrg         break;
694b8e80941Smrg      }
695b8e80941Smrg      return NULL;
696b8e80941Smrg   }
697b8e80941Smrg
698b8e80941Smrg#include "ir_expression_operation_constant.h"
699b8e80941Smrg
700b8e80941Smrg   return new(mem_ctx) ir_constant(this->type, &data);
701b8e80941Smrg}
702b8e80941Smrg
703b8e80941Smrg
704b8e80941Smrgir_constant *
705b8e80941Smrgir_texture::constant_expression_value(void *, struct hash_table *)
706b8e80941Smrg{
707b8e80941Smrg   /* texture lookups aren't constant expressions */
708b8e80941Smrg   return NULL;
709b8e80941Smrg}
710b8e80941Smrg
711b8e80941Smrg
712b8e80941Smrgir_constant *
713b8e80941Smrgir_swizzle::constant_expression_value(void *mem_ctx,
714b8e80941Smrg                                      struct hash_table *variable_context)
715b8e80941Smrg{
716b8e80941Smrg   assert(mem_ctx);
717b8e80941Smrg
718b8e80941Smrg   ir_constant *v = this->val->constant_expression_value(mem_ctx,
719b8e80941Smrg                                                         variable_context);
720b8e80941Smrg
721b8e80941Smrg   if (v != NULL) {
722b8e80941Smrg      ir_constant_data data = { { 0 } };
723b8e80941Smrg
724b8e80941Smrg      const unsigned swiz_idx[4] = {
725b8e80941Smrg         this->mask.x, this->mask.y, this->mask.z, this->mask.w
726b8e80941Smrg      };
727b8e80941Smrg
728b8e80941Smrg      for (unsigned i = 0; i < this->mask.num_components; i++) {
729b8e80941Smrg         switch (v->type->base_type) {
730b8e80941Smrg         case GLSL_TYPE_UINT:
731b8e80941Smrg         case GLSL_TYPE_INT:   data.u[i] = v->value.u[swiz_idx[i]]; break;
732b8e80941Smrg         case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
733b8e80941Smrg         case GLSL_TYPE_BOOL:  data.b[i] = v->value.b[swiz_idx[i]]; break;
734b8e80941Smrg         case GLSL_TYPE_DOUBLE:data.d[i] = v->value.d[swiz_idx[i]]; break;
735b8e80941Smrg         case GLSL_TYPE_UINT64:data.u64[i] = v->value.u64[swiz_idx[i]]; break;
736b8e80941Smrg         case GLSL_TYPE_INT64: data.i64[i] = v->value.i64[swiz_idx[i]]; break;
737b8e80941Smrg         default:              assert(!"Should not get here."); break;
738b8e80941Smrg         }
739b8e80941Smrg      }
740b8e80941Smrg
741b8e80941Smrg      return new(mem_ctx) ir_constant(this->type, &data);
742b8e80941Smrg   }
743b8e80941Smrg   return NULL;
744b8e80941Smrg}
745b8e80941Smrg
746b8e80941Smrg
747b8e80941Smrgir_constant *
748b8e80941Smrgir_dereference_variable::constant_expression_value(void *mem_ctx,
749b8e80941Smrg                                                   struct hash_table *variable_context)
750b8e80941Smrg{
751b8e80941Smrg   assert(var);
752b8e80941Smrg   assert(mem_ctx);
753b8e80941Smrg
754b8e80941Smrg   /* Give priority to the context hashtable, if it exists */
755b8e80941Smrg   if (variable_context) {
756b8e80941Smrg      hash_entry *entry = _mesa_hash_table_search(variable_context, var);
757b8e80941Smrg
758b8e80941Smrg      if(entry)
759b8e80941Smrg         return (ir_constant *) entry->data;
760b8e80941Smrg   }
761b8e80941Smrg
762b8e80941Smrg   /* The constant_value of a uniform variable is its initializer,
763b8e80941Smrg    * not the lifetime constant value of the uniform.
764b8e80941Smrg    */
765b8e80941Smrg   if (var->data.mode == ir_var_uniform)
766b8e80941Smrg      return NULL;
767b8e80941Smrg
768b8e80941Smrg   if (!var->constant_value)
769b8e80941Smrg      return NULL;
770b8e80941Smrg
771b8e80941Smrg   return var->constant_value->clone(mem_ctx, NULL);
772b8e80941Smrg}
773b8e80941Smrg
774b8e80941Smrg
775b8e80941Smrgir_constant *
776b8e80941Smrgir_dereference_array::constant_expression_value(void *mem_ctx,
777b8e80941Smrg                                                struct hash_table *variable_context)
778b8e80941Smrg{
779b8e80941Smrg   assert(mem_ctx);
780b8e80941Smrg
781b8e80941Smrg   ir_constant *array = this->array->constant_expression_value(mem_ctx, variable_context);
782b8e80941Smrg   ir_constant *idx = this->array_index->constant_expression_value(mem_ctx, variable_context);
783b8e80941Smrg
784b8e80941Smrg   if ((array != NULL) && (idx != NULL)) {
785b8e80941Smrg      if (array->type->is_matrix()) {
786b8e80941Smrg         /* Array access of a matrix results in a vector.
787b8e80941Smrg          */
788b8e80941Smrg         const unsigned column = idx->value.u[0];
789b8e80941Smrg
790b8e80941Smrg         const glsl_type *const column_type = array->type->column_type();
791b8e80941Smrg
792b8e80941Smrg         /* Offset in the constant matrix to the first element of the column
793b8e80941Smrg          * to be extracted.
794b8e80941Smrg          */
795b8e80941Smrg         const unsigned mat_idx = column * column_type->vector_elements;
796b8e80941Smrg
797b8e80941Smrg         ir_constant_data data = { { 0 } };
798b8e80941Smrg
799b8e80941Smrg         switch (column_type->base_type) {
800b8e80941Smrg         case GLSL_TYPE_UINT:
801b8e80941Smrg         case GLSL_TYPE_INT:
802b8e80941Smrg            for (unsigned i = 0; i < column_type->vector_elements; i++)
803b8e80941Smrg               data.u[i] = array->value.u[mat_idx + i];
804b8e80941Smrg
805b8e80941Smrg            break;
806b8e80941Smrg
807b8e80941Smrg         case GLSL_TYPE_FLOAT:
808b8e80941Smrg            for (unsigned i = 0; i < column_type->vector_elements; i++)
809b8e80941Smrg               data.f[i] = array->value.f[mat_idx + i];
810b8e80941Smrg
811b8e80941Smrg            break;
812b8e80941Smrg
813b8e80941Smrg         case GLSL_TYPE_DOUBLE:
814b8e80941Smrg            for (unsigned i = 0; i < column_type->vector_elements; i++)
815b8e80941Smrg               data.d[i] = array->value.d[mat_idx + i];
816b8e80941Smrg
817b8e80941Smrg            break;
818b8e80941Smrg
819b8e80941Smrg         default:
820b8e80941Smrg            assert(!"Should not get here.");
821b8e80941Smrg            break;
822b8e80941Smrg         }
823b8e80941Smrg
824b8e80941Smrg         return new(mem_ctx) ir_constant(column_type, &data);
825b8e80941Smrg      } else if (array->type->is_vector()) {
826b8e80941Smrg         const unsigned component = idx->value.u[0];
827b8e80941Smrg
828b8e80941Smrg         return new(mem_ctx) ir_constant(array, component);
829b8e80941Smrg      } else if (array->type->is_array()) {
830b8e80941Smrg         const unsigned index = idx->value.u[0];
831b8e80941Smrg         return array->get_array_element(index)->clone(mem_ctx, NULL);
832b8e80941Smrg      }
833b8e80941Smrg   }
834b8e80941Smrg   return NULL;
835b8e80941Smrg}
836b8e80941Smrg
837b8e80941Smrg
838b8e80941Smrgir_constant *
839b8e80941Smrgir_dereference_record::constant_expression_value(void *mem_ctx,
840b8e80941Smrg                                                 struct hash_table *)
841b8e80941Smrg{
842b8e80941Smrg   assert(mem_ctx);
843b8e80941Smrg
844b8e80941Smrg   ir_constant *v = this->record->constant_expression_value(mem_ctx);
845b8e80941Smrg
846b8e80941Smrg   return (v != NULL) ? v->get_record_field(this->field_idx) : NULL;
847b8e80941Smrg}
848b8e80941Smrg
849b8e80941Smrg
850b8e80941Smrgir_constant *
851b8e80941Smrgir_assignment::constant_expression_value(void *, struct hash_table *)
852b8e80941Smrg{
853b8e80941Smrg   /* FINISHME: Handle CEs involving assignment (return RHS) */
854b8e80941Smrg   return NULL;
855b8e80941Smrg}
856b8e80941Smrg
857b8e80941Smrg
858b8e80941Smrgir_constant *
859b8e80941Smrgir_constant::constant_expression_value(void *, struct hash_table *)
860b8e80941Smrg{
861b8e80941Smrg   return this;
862b8e80941Smrg}
863b8e80941Smrg
864b8e80941Smrg
865b8e80941Smrgir_constant *
866b8e80941Smrgir_call::constant_expression_value(void *mem_ctx, struct hash_table *variable_context)
867b8e80941Smrg{
868b8e80941Smrg   assert(mem_ctx);
869b8e80941Smrg
870b8e80941Smrg   return this->callee->constant_expression_value(mem_ctx,
871b8e80941Smrg                                                  &this->actual_parameters,
872b8e80941Smrg                                                  variable_context);
873b8e80941Smrg}
874b8e80941Smrg
875b8e80941Smrg
876b8e80941Smrgbool ir_function_signature::constant_expression_evaluate_expression_list(void *mem_ctx,
877b8e80941Smrg                                                                        const struct exec_list &body,
878b8e80941Smrg                                                                         struct hash_table *variable_context,
879b8e80941Smrg                                                                         ir_constant **result)
880b8e80941Smrg{
881b8e80941Smrg   assert(mem_ctx);
882b8e80941Smrg
883b8e80941Smrg   foreach_in_list(ir_instruction, inst, &body) {
884b8e80941Smrg      switch(inst->ir_type) {
885b8e80941Smrg
886b8e80941Smrg         /* (declare () type symbol) */
887b8e80941Smrg      case ir_type_variable: {
888b8e80941Smrg         ir_variable *var = inst->as_variable();
889b8e80941Smrg         _mesa_hash_table_insert(variable_context, var, ir_constant::zero(this, var->type));
890b8e80941Smrg         break;
891b8e80941Smrg      }
892b8e80941Smrg
893b8e80941Smrg         /* (assign [condition] (write-mask) (ref) (value)) */
894b8e80941Smrg      case ir_type_assignment: {
895b8e80941Smrg         ir_assignment *asg = inst->as_assignment();
896b8e80941Smrg         if (asg->condition) {
897b8e80941Smrg            ir_constant *cond =
898b8e80941Smrg               asg->condition->constant_expression_value(mem_ctx,
899b8e80941Smrg                                                         variable_context);
900b8e80941Smrg            if (!cond)
901b8e80941Smrg               return false;
902b8e80941Smrg            if (!cond->get_bool_component(0))
903b8e80941Smrg               break;
904b8e80941Smrg         }
905b8e80941Smrg
906b8e80941Smrg         ir_constant *store = NULL;
907b8e80941Smrg         int offset = 0;
908b8e80941Smrg
909b8e80941Smrg         if (!constant_referenced(asg->lhs, variable_context, store, offset))
910b8e80941Smrg            return false;
911b8e80941Smrg
912b8e80941Smrg         ir_constant *value =
913b8e80941Smrg            asg->rhs->constant_expression_value(mem_ctx, variable_context);
914b8e80941Smrg
915b8e80941Smrg         if (!value)
916b8e80941Smrg            return false;
917b8e80941Smrg
918b8e80941Smrg         store->copy_masked_offset(value, offset, asg->write_mask);
919b8e80941Smrg         break;
920b8e80941Smrg      }
921b8e80941Smrg
922b8e80941Smrg         /* (return (expression)) */
923b8e80941Smrg      case ir_type_return:
924b8e80941Smrg         assert (result);
925b8e80941Smrg         *result =
926b8e80941Smrg            inst->as_return()->value->constant_expression_value(mem_ctx,
927b8e80941Smrg                                                                variable_context);
928b8e80941Smrg         return *result != NULL;
929b8e80941Smrg
930b8e80941Smrg         /* (call name (ref) (params))*/
931b8e80941Smrg      case ir_type_call: {
932b8e80941Smrg         ir_call *call = inst->as_call();
933b8e80941Smrg
934b8e80941Smrg         /* Just say no to void functions in constant expressions.  We
935b8e80941Smrg          * don't need them at that point.
936b8e80941Smrg          */
937b8e80941Smrg
938b8e80941Smrg         if (!call->return_deref)
939b8e80941Smrg            return false;
940b8e80941Smrg
941b8e80941Smrg         ir_constant *store = NULL;
942b8e80941Smrg         int offset = 0;
943b8e80941Smrg
944b8e80941Smrg         if (!constant_referenced(call->return_deref, variable_context,
945b8e80941Smrg                                  store, offset))
946b8e80941Smrg            return false;
947b8e80941Smrg
948b8e80941Smrg         ir_constant *value =
949b8e80941Smrg            call->constant_expression_value(mem_ctx, variable_context);
950b8e80941Smrg
951b8e80941Smrg         if(!value)
952b8e80941Smrg            return false;
953b8e80941Smrg
954b8e80941Smrg         store->copy_offset(value, offset);
955b8e80941Smrg         break;
956b8e80941Smrg      }
957b8e80941Smrg
958b8e80941Smrg         /* (if condition (then-instructions) (else-instructions)) */
959b8e80941Smrg      case ir_type_if: {
960b8e80941Smrg         ir_if *iif = inst->as_if();
961b8e80941Smrg
962b8e80941Smrg         ir_constant *cond =
963b8e80941Smrg            iif->condition->constant_expression_value(mem_ctx,
964b8e80941Smrg                                                      variable_context);
965b8e80941Smrg         if (!cond || !cond->type->is_boolean())
966b8e80941Smrg            return false;
967b8e80941Smrg
968b8e80941Smrg         exec_list &branch = cond->get_bool_component(0) ? iif->then_instructions : iif->else_instructions;
969b8e80941Smrg
970b8e80941Smrg         *result = NULL;
971b8e80941Smrg         if (!constant_expression_evaluate_expression_list(mem_ctx, branch,
972b8e80941Smrg                                                           variable_context,
973b8e80941Smrg                                                           result))
974b8e80941Smrg            return false;
975b8e80941Smrg
976b8e80941Smrg         /* If there was a return in the branch chosen, drop out now. */
977b8e80941Smrg         if (*result)
978b8e80941Smrg            return true;
979b8e80941Smrg
980b8e80941Smrg         break;
981b8e80941Smrg      }
982b8e80941Smrg
983b8e80941Smrg         /* Every other expression type, we drop out. */
984b8e80941Smrg      default:
985b8e80941Smrg         return false;
986b8e80941Smrg      }
987b8e80941Smrg   }
988b8e80941Smrg
989b8e80941Smrg   /* Reaching the end of the block is not an error condition */
990b8e80941Smrg   if (result)
991b8e80941Smrg      *result = NULL;
992b8e80941Smrg
993b8e80941Smrg   return true;
994b8e80941Smrg}
995b8e80941Smrg
996b8e80941Smrgir_constant *
997b8e80941Smrgir_function_signature::constant_expression_value(void *mem_ctx,
998b8e80941Smrg                                                 exec_list *actual_parameters,
999b8e80941Smrg                                                 struct hash_table *variable_context)
1000b8e80941Smrg{
1001b8e80941Smrg   assert(mem_ctx);
1002b8e80941Smrg
1003b8e80941Smrg   const glsl_type *type = this->return_type;
1004b8e80941Smrg   if (type == glsl_type::void_type)
1005b8e80941Smrg      return NULL;
1006b8e80941Smrg
1007b8e80941Smrg   /* From the GLSL 1.20 spec, page 23:
1008b8e80941Smrg    * "Function calls to user-defined functions (non-built-in functions)
1009b8e80941Smrg    *  cannot be used to form constant expressions."
1010b8e80941Smrg    */
1011b8e80941Smrg   if (!this->is_builtin())
1012b8e80941Smrg      return NULL;
1013b8e80941Smrg
1014b8e80941Smrg   /*
1015b8e80941Smrg    * Of the builtin functions, only the texture lookups and the noise
1016b8e80941Smrg    * ones must not be used in constant expressions.  They all include
1017b8e80941Smrg    * specific opcodes so they don't need to be special-cased at this
1018b8e80941Smrg    * point.
1019b8e80941Smrg    */
1020b8e80941Smrg
1021b8e80941Smrg   /* Initialize the table of dereferencable names with the function
1022b8e80941Smrg    * parameters.  Verify their const-ness on the way.
1023b8e80941Smrg    *
1024b8e80941Smrg    * We expect the correctness of the number of parameters to have
1025b8e80941Smrg    * been checked earlier.
1026b8e80941Smrg    */
1027b8e80941Smrg   hash_table *deref_hash = _mesa_pointer_hash_table_create(NULL);
1028b8e80941Smrg
1029b8e80941Smrg   /* If "origin" is non-NULL, then the function body is there.  So we
1030b8e80941Smrg    * have to use the variable objects from the object with the body,
1031b8e80941Smrg    * but the parameter instanciation on the current object.
1032b8e80941Smrg    */
1033b8e80941Smrg   const exec_node *parameter_info = origin ? origin->parameters.get_head_raw() : parameters.get_head_raw();
1034b8e80941Smrg
1035b8e80941Smrg   foreach_in_list(ir_rvalue, n, actual_parameters) {
1036b8e80941Smrg      ir_constant *constant =
1037b8e80941Smrg         n->constant_expression_value(mem_ctx, variable_context);
1038b8e80941Smrg      if (constant == NULL) {
1039b8e80941Smrg         _mesa_hash_table_destroy(deref_hash, NULL);
1040b8e80941Smrg         return NULL;
1041b8e80941Smrg      }
1042b8e80941Smrg
1043b8e80941Smrg
1044b8e80941Smrg      ir_variable *var = (ir_variable *)parameter_info;
1045b8e80941Smrg      _mesa_hash_table_insert(deref_hash, var, constant);
1046b8e80941Smrg
1047b8e80941Smrg      parameter_info = parameter_info->next;
1048b8e80941Smrg   }
1049b8e80941Smrg
1050b8e80941Smrg   ir_constant *result = NULL;
1051b8e80941Smrg
1052b8e80941Smrg   /* Now run the builtin function until something non-constant
1053b8e80941Smrg    * happens or we get the result.
1054b8e80941Smrg    */
1055b8e80941Smrg   if (constant_expression_evaluate_expression_list(mem_ctx, origin ? origin->body : body, deref_hash, &result) &&
1056b8e80941Smrg       result)
1057b8e80941Smrg      result = result->clone(mem_ctx, NULL);
1058b8e80941Smrg
1059b8e80941Smrg   _mesa_hash_table_destroy(deref_hash, NULL);
1060b8e80941Smrg
1061b8e80941Smrg   return result;
1062b8e80941Smrg}
1063