ir_constant_expression.cpp revision 344f94bb006188931b09939aafc7cc96609c4f5a
1/*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24/**
25 * \file ir_constant_expression.cpp
26 * Evaluate and process constant valued expressions
27 *
28 * In GLSL, constant valued expressions are used in several places.  These
29 * must be processed and evaluated very early in the compilation process.
30 *
31 *    * Sizes of arrays
32 *    * Initializers for uniforms
33 *    * Initializers for \c const variables
34 */
35
36#include <math.h>
37#include "main/core.h" /* for MAX2, MIN2, CLAMP */
38#include "ir.h"
39#include "ir_visitor.h"
40#include "glsl_types.h"
41
42static float
43dot(ir_constant *op0, ir_constant *op1)
44{
45   assert(op0->type->is_float() && op1->type->is_float());
46
47   float result = 0;
48   for (unsigned c = 0; c < op0->type->components(); c++)
49      result += op0->value.f[c] * op1->value.f[c];
50
51   return result;
52}
53
54ir_constant *
55ir_expression::constant_expression_value()
56{
57   if (this->type->is_error())
58      return NULL;
59
60   ir_constant *op[Elements(this->operands)] = { NULL, };
61   ir_constant_data data;
62
63   memset(&data, 0, sizeof(data));
64
65   for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
66      op[operand] = this->operands[operand]->constant_expression_value();
67      if (!op[operand])
68	 return NULL;
69   }
70
71   if (op[1] != NULL)
72      assert(op[0]->type->base_type == op[1]->type->base_type ||
73	     this->operation == ir_binop_lshift ||
74	     this->operation == ir_binop_rshift);
75
76   bool op0_scalar = op[0]->type->is_scalar();
77   bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
78
79   /* When iterating over a vector or matrix's components, we want to increase
80    * the loop counter.  However, for scalars, we want to stay at 0.
81    */
82   unsigned c0_inc = op0_scalar ? 0 : 1;
83   unsigned c1_inc = op1_scalar ? 0 : 1;
84   unsigned components;
85   if (op1_scalar || !op[1]) {
86      components = op[0]->type->components();
87   } else {
88      components = op[1]->type->components();
89   }
90
91   void *ctx = ralloc_parent(this);
92
93   /* Handle array operations here, rather than below. */
94   if (op[0]->type->is_array()) {
95      assert(op[1] != NULL && op[1]->type->is_array());
96      switch (this->operation) {
97      case ir_binop_all_equal:
98	 return new(ctx) ir_constant(op[0]->has_value(op[1]));
99      case ir_binop_any_nequal:
100	 return new(ctx) ir_constant(!op[0]->has_value(op[1]));
101      default:
102	 break;
103      }
104      return NULL;
105   }
106
107   switch (this->operation) {
108   case ir_unop_bit_not:
109       switch (op[0]->type->base_type) {
110       case GLSL_TYPE_INT:
111           for (unsigned c = 0; c < components; c++)
112               data.i[c] = ~ op[0]->value.i[c];
113           break;
114       case GLSL_TYPE_UINT:
115           for (unsigned c = 0; c < components; c++)
116               data.u[c] = ~ op[0]->value.u[c];
117           break;
118       default:
119           assert(0);
120       }
121       break;
122
123   case ir_unop_logic_not:
124      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
125      for (unsigned c = 0; c < op[0]->type->components(); c++)
126	 data.b[c] = !op[0]->value.b[c];
127      break;
128
129   case ir_unop_f2i:
130      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
131      for (unsigned c = 0; c < op[0]->type->components(); c++) {
132	 data.i[c] = (int) op[0]->value.f[c];
133      }
134      break;
135   case ir_unop_i2f:
136      assert(op[0]->type->base_type == GLSL_TYPE_INT);
137      for (unsigned c = 0; c < op[0]->type->components(); c++) {
138	 data.f[c] = (float) op[0]->value.i[c];
139      }
140      break;
141   case ir_unop_u2f:
142      assert(op[0]->type->base_type == GLSL_TYPE_UINT);
143      for (unsigned c = 0; c < op[0]->type->components(); c++) {
144	 data.f[c] = (float) op[0]->value.u[c];
145      }
146      break;
147   case ir_unop_b2f:
148      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
149      for (unsigned c = 0; c < op[0]->type->components(); c++) {
150	 data.f[c] = op[0]->value.b[c] ? 1.0F : 0.0F;
151      }
152      break;
153   case ir_unop_f2b:
154      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
155      for (unsigned c = 0; c < op[0]->type->components(); c++) {
156	 data.b[c] = op[0]->value.f[c] != 0.0F ? true : false;
157      }
158      break;
159   case ir_unop_b2i:
160      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
161      for (unsigned c = 0; c < op[0]->type->components(); c++) {
162	 data.u[c] = op[0]->value.b[c] ? 1 : 0;
163      }
164      break;
165   case ir_unop_i2b:
166      assert(op[0]->type->is_integer());
167      for (unsigned c = 0; c < op[0]->type->components(); c++) {
168	 data.b[c] = op[0]->value.u[c] ? true : false;
169      }
170      break;
171   case ir_unop_u2i:
172      assert(op[0]->type->base_type == GLSL_TYPE_UINT);
173      for (unsigned c = 0; c < op[0]->type->components(); c++) {
174	 data.i[c] = op[0]->value.u[c];
175      }
176      break;
177   case ir_unop_i2u:
178      assert(op[0]->type->base_type == GLSL_TYPE_INT);
179      for (unsigned c = 0; c < op[0]->type->components(); c++) {
180	 data.u[c] = op[0]->value.i[c];
181      }
182      break;
183   case ir_unop_any:
184      assert(op[0]->type->is_boolean());
185      data.b[0] = false;
186      for (unsigned c = 0; c < op[0]->type->components(); c++) {
187	 if (op[0]->value.b[c])
188	    data.b[0] = true;
189      }
190      break;
191
192   case ir_unop_trunc:
193      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
194      for (unsigned c = 0; c < op[0]->type->components(); c++) {
195	 data.f[c] = truncf(op[0]->value.f[c]);
196      }
197      break;
198
199   case ir_unop_ceil:
200      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
201      for (unsigned c = 0; c < op[0]->type->components(); c++) {
202	 data.f[c] = ceilf(op[0]->value.f[c]);
203      }
204      break;
205
206   case ir_unop_floor:
207      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
208      for (unsigned c = 0; c < op[0]->type->components(); c++) {
209	 data.f[c] = floorf(op[0]->value.f[c]);
210      }
211      break;
212
213   case ir_unop_fract:
214      for (unsigned c = 0; c < op[0]->type->components(); c++) {
215	 switch (this->type->base_type) {
216	 case GLSL_TYPE_UINT:
217	    data.u[c] = 0;
218	    break;
219	 case GLSL_TYPE_INT:
220	    data.i[c] = 0;
221	    break;
222	 case GLSL_TYPE_FLOAT:
223	    data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
224	    break;
225	 default:
226	    assert(0);
227	 }
228      }
229      break;
230
231   case ir_unop_sin:
232   case ir_unop_sin_reduced:
233      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
234      for (unsigned c = 0; c < op[0]->type->components(); c++) {
235	 data.f[c] = sinf(op[0]->value.f[c]);
236      }
237      break;
238
239   case ir_unop_cos:
240   case ir_unop_cos_reduced:
241      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
242      for (unsigned c = 0; c < op[0]->type->components(); c++) {
243	 data.f[c] = cosf(op[0]->value.f[c]);
244      }
245      break;
246
247   case ir_unop_neg:
248      for (unsigned c = 0; c < op[0]->type->components(); c++) {
249	 switch (this->type->base_type) {
250	 case GLSL_TYPE_UINT:
251	    data.u[c] = -((int) op[0]->value.u[c]);
252	    break;
253	 case GLSL_TYPE_INT:
254	    data.i[c] = -op[0]->value.i[c];
255	    break;
256	 case GLSL_TYPE_FLOAT:
257	    data.f[c] = -op[0]->value.f[c];
258	    break;
259	 default:
260	    assert(0);
261	 }
262      }
263      break;
264
265   case ir_unop_abs:
266      for (unsigned c = 0; c < op[0]->type->components(); c++) {
267	 switch (this->type->base_type) {
268	 case GLSL_TYPE_UINT:
269	    data.u[c] = op[0]->value.u[c];
270	    break;
271	 case GLSL_TYPE_INT:
272	    data.i[c] = op[0]->value.i[c];
273	    if (data.i[c] < 0)
274	       data.i[c] = -data.i[c];
275	    break;
276	 case GLSL_TYPE_FLOAT:
277	    data.f[c] = fabs(op[0]->value.f[c]);
278	    break;
279	 default:
280	    assert(0);
281	 }
282      }
283      break;
284
285   case ir_unop_sign:
286      for (unsigned c = 0; c < op[0]->type->components(); c++) {
287	 switch (this->type->base_type) {
288	 case GLSL_TYPE_UINT:
289	    data.u[c] = op[0]->value.i[c] > 0;
290	    break;
291	 case GLSL_TYPE_INT:
292	    data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
293	    break;
294	 case GLSL_TYPE_FLOAT:
295	    data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
296	    break;
297	 default:
298	    assert(0);
299	 }
300      }
301      break;
302
303   case ir_unop_rcp:
304      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
305      for (unsigned c = 0; c < op[0]->type->components(); c++) {
306	 switch (this->type->base_type) {
307	 case GLSL_TYPE_UINT:
308	    if (op[0]->value.u[c] != 0.0)
309	       data.u[c] = 1 / op[0]->value.u[c];
310	    break;
311	 case GLSL_TYPE_INT:
312	    if (op[0]->value.i[c] != 0.0)
313	       data.i[c] = 1 / op[0]->value.i[c];
314	    break;
315	 case GLSL_TYPE_FLOAT:
316	    if (op[0]->value.f[c] != 0.0)
317	       data.f[c] = 1.0F / op[0]->value.f[c];
318	    break;
319	 default:
320	    assert(0);
321	 }
322      }
323      break;
324
325   case ir_unop_rsq:
326      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
327      for (unsigned c = 0; c < op[0]->type->components(); c++) {
328	 data.f[c] = 1.0F / sqrtf(op[0]->value.f[c]);
329      }
330      break;
331
332   case ir_unop_sqrt:
333      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
334      for (unsigned c = 0; c < op[0]->type->components(); c++) {
335	 data.f[c] = sqrtf(op[0]->value.f[c]);
336      }
337      break;
338
339   case ir_unop_exp:
340      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
341      for (unsigned c = 0; c < op[0]->type->components(); c++) {
342	 data.f[c] = expf(op[0]->value.f[c]);
343      }
344      break;
345
346   case ir_unop_exp2:
347      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
348      for (unsigned c = 0; c < op[0]->type->components(); c++) {
349	 data.f[c] = exp2f(op[0]->value.f[c]);
350      }
351      break;
352
353   case ir_unop_log:
354      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
355      for (unsigned c = 0; c < op[0]->type->components(); c++) {
356	 data.f[c] = logf(op[0]->value.f[c]);
357      }
358      break;
359
360   case ir_unop_log2:
361      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
362      for (unsigned c = 0; c < op[0]->type->components(); c++) {
363	 data.f[c] = log2f(op[0]->value.f[c]);
364      }
365      break;
366
367   case ir_unop_dFdx:
368   case ir_unop_dFdy:
369      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
370      for (unsigned c = 0; c < op[0]->type->components(); c++) {
371	 data.f[c] = 0.0;
372      }
373      break;
374
375   case ir_binop_pow:
376      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
377      for (unsigned c = 0; c < op[0]->type->components(); c++) {
378	 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
379      }
380      break;
381
382   case ir_binop_dot:
383      data.f[0] = dot(op[0], op[1]);
384      break;
385
386   case ir_binop_min:
387      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
388      for (unsigned c = 0, c0 = 0, c1 = 0;
389	   c < components;
390	   c0 += c0_inc, c1 += c1_inc, c++) {
391
392	 switch (op[0]->type->base_type) {
393	 case GLSL_TYPE_UINT:
394	    data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
395	    break;
396	 case GLSL_TYPE_INT:
397	    data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
398	    break;
399	 case GLSL_TYPE_FLOAT:
400	    data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
401	    break;
402	 default:
403	    assert(0);
404	 }
405      }
406
407      break;
408   case ir_binop_max:
409      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
410      for (unsigned c = 0, c0 = 0, c1 = 0;
411	   c < components;
412	   c0 += c0_inc, c1 += c1_inc, c++) {
413
414	 switch (op[0]->type->base_type) {
415	 case GLSL_TYPE_UINT:
416	    data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
417	    break;
418	 case GLSL_TYPE_INT:
419	    data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
420	    break;
421	 case GLSL_TYPE_FLOAT:
422	    data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
423	    break;
424	 default:
425	    assert(0);
426	 }
427      }
428      break;
429
430   case ir_binop_add:
431      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
432      for (unsigned c = 0, c0 = 0, c1 = 0;
433	   c < components;
434	   c0 += c0_inc, c1 += c1_inc, c++) {
435
436	 switch (op[0]->type->base_type) {
437	 case GLSL_TYPE_UINT:
438	    data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
439	    break;
440	 case GLSL_TYPE_INT:
441	    data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
442	    break;
443	 case GLSL_TYPE_FLOAT:
444	    data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
445	    break;
446	 default:
447	    assert(0);
448	 }
449      }
450
451      break;
452   case ir_binop_sub:
453      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
454      for (unsigned c = 0, c0 = 0, c1 = 0;
455	   c < components;
456	   c0 += c0_inc, c1 += c1_inc, c++) {
457
458	 switch (op[0]->type->base_type) {
459	 case GLSL_TYPE_UINT:
460	    data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
461	    break;
462	 case GLSL_TYPE_INT:
463	    data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
464	    break;
465	 case GLSL_TYPE_FLOAT:
466	    data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
467	    break;
468	 default:
469	    assert(0);
470	 }
471      }
472
473      break;
474   case ir_binop_mul:
475      /* Check for equal types, or unequal types involving scalars */
476      if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
477	  || op0_scalar || op1_scalar) {
478	 for (unsigned c = 0, c0 = 0, c1 = 0;
479	      c < components;
480	      c0 += c0_inc, c1 += c1_inc, c++) {
481
482	    switch (op[0]->type->base_type) {
483	    case GLSL_TYPE_UINT:
484	       data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
485	       break;
486	    case GLSL_TYPE_INT:
487	       data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
488	       break;
489	    case GLSL_TYPE_FLOAT:
490	       data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
491	       break;
492	    default:
493	       assert(0);
494	    }
495	 }
496      } else {
497	 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
498
499	 /* Multiply an N-by-M matrix with an M-by-P matrix.  Since either
500	  * matrix can be a GLSL vector, either N or P can be 1.
501	  *
502	  * For vec*mat, the vector is treated as a row vector.  This
503	  * means the vector is a 1-row x M-column matrix.
504	  *
505	  * For mat*vec, the vector is treated as a column vector.  Since
506	  * matrix_columns is 1 for vectors, this just works.
507	  */
508	 const unsigned n = op[0]->type->is_vector()
509	    ? 1 : op[0]->type->vector_elements;
510	 const unsigned m = op[1]->type->vector_elements;
511	 const unsigned p = op[1]->type->matrix_columns;
512	 for (unsigned j = 0; j < p; j++) {
513	    for (unsigned i = 0; i < n; i++) {
514	       for (unsigned k = 0; k < m; k++) {
515		  data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
516	       }
517	    }
518	 }
519      }
520
521      break;
522   case ir_binop_div:
523      /* FINISHME: Emit warning when division-by-zero is detected. */
524      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
525      for (unsigned c = 0, c0 = 0, c1 = 0;
526	   c < components;
527	   c0 += c0_inc, c1 += c1_inc, c++) {
528
529	 switch (op[0]->type->base_type) {
530	 case GLSL_TYPE_UINT:
531	    if (op[1]->value.u[c1] == 0) {
532	       data.u[c] = 0;
533	    } else {
534	       data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
535	    }
536	    break;
537	 case GLSL_TYPE_INT:
538	    if (op[1]->value.i[c1] == 0) {
539	       data.i[c] = 0;
540	    } else {
541	       data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
542	    }
543	    break;
544	 case GLSL_TYPE_FLOAT:
545	    data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
546	    break;
547	 default:
548	    assert(0);
549	 }
550      }
551
552      break;
553   case ir_binop_mod:
554      /* FINISHME: Emit warning when division-by-zero is detected. */
555      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
556      for (unsigned c = 0, c0 = 0, c1 = 0;
557	   c < components;
558	   c0 += c0_inc, c1 += c1_inc, c++) {
559
560	 switch (op[0]->type->base_type) {
561	 case GLSL_TYPE_UINT:
562	    if (op[1]->value.u[c1] == 0) {
563	       data.u[c] = 0;
564	    } else {
565	       data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
566	    }
567	    break;
568	 case GLSL_TYPE_INT:
569	    if (op[1]->value.i[c1] == 0) {
570	       data.i[c] = 0;
571	    } else {
572	       data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
573	    }
574	    break;
575	 case GLSL_TYPE_FLOAT:
576	    /* We don't use fmod because it rounds toward zero; GLSL specifies
577	     * the use of floor.
578	     */
579	    data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
580	       * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
581	    break;
582	 default:
583	    assert(0);
584	 }
585      }
586
587      break;
588
589   case ir_binop_logic_and:
590      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
591      for (unsigned c = 0; c < op[0]->type->components(); c++)
592	 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
593      break;
594   case ir_binop_logic_xor:
595      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
596      for (unsigned c = 0; c < op[0]->type->components(); c++)
597	 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
598      break;
599   case ir_binop_logic_or:
600      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
601      for (unsigned c = 0; c < op[0]->type->components(); c++)
602	 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
603      break;
604
605   case ir_binop_less:
606      assert(op[0]->type == op[1]->type);
607      for (unsigned c = 0; c < op[0]->type->components(); c++) {
608	 switch (op[0]->type->base_type) {
609	 case GLSL_TYPE_UINT:
610	    data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
611	    break;
612	 case GLSL_TYPE_INT:
613	    data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
614	    break;
615	 case GLSL_TYPE_FLOAT:
616	    data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
617	    break;
618	 default:
619	    assert(0);
620	 }
621      }
622      break;
623   case ir_binop_greater:
624      assert(op[0]->type == op[1]->type);
625      for (unsigned c = 0; c < op[0]->type->components(); c++) {
626	 switch (op[0]->type->base_type) {
627	 case GLSL_TYPE_UINT:
628	    data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
629	    break;
630	 case GLSL_TYPE_INT:
631	    data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
632	    break;
633	 case GLSL_TYPE_FLOAT:
634	    data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
635	    break;
636	 default:
637	    assert(0);
638	 }
639      }
640      break;
641   case ir_binop_lequal:
642      assert(op[0]->type == op[1]->type);
643      for (unsigned c = 0; c < op[0]->type->components(); c++) {
644	 switch (op[0]->type->base_type) {
645	 case GLSL_TYPE_UINT:
646	    data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
647	    break;
648	 case GLSL_TYPE_INT:
649	    data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
650	    break;
651	 case GLSL_TYPE_FLOAT:
652	    data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
653	    break;
654	 default:
655	    assert(0);
656	 }
657      }
658      break;
659   case ir_binop_gequal:
660      assert(op[0]->type == op[1]->type);
661      for (unsigned c = 0; c < op[0]->type->components(); c++) {
662	 switch (op[0]->type->base_type) {
663	 case GLSL_TYPE_UINT:
664	    data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
665	    break;
666	 case GLSL_TYPE_INT:
667	    data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
668	    break;
669	 case GLSL_TYPE_FLOAT:
670	    data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
671	    break;
672	 default:
673	    assert(0);
674	 }
675      }
676      break;
677   case ir_binop_equal:
678      assert(op[0]->type == op[1]->type);
679      for (unsigned c = 0; c < components; c++) {
680	 switch (op[0]->type->base_type) {
681	 case GLSL_TYPE_UINT:
682	    data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
683	    break;
684	 case GLSL_TYPE_INT:
685	    data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
686	    break;
687	 case GLSL_TYPE_FLOAT:
688	    data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
689	    break;
690	 default:
691	    assert(0);
692	 }
693      }
694      break;
695   case ir_binop_nequal:
696      assert(op[0]->type != op[1]->type);
697      for (unsigned c = 0; c < components; c++) {
698	 switch (op[0]->type->base_type) {
699	 case GLSL_TYPE_UINT:
700	    data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
701	    break;
702	 case GLSL_TYPE_INT:
703	    data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
704	    break;
705	 case GLSL_TYPE_FLOAT:
706	    data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
707	    break;
708	 default:
709	    assert(0);
710	 }
711      }
712      break;
713   case ir_binop_all_equal:
714      data.b[0] = op[0]->has_value(op[1]);
715      break;
716   case ir_binop_any_nequal:
717      data.b[0] = !op[0]->has_value(op[1]);
718      break;
719
720   case ir_binop_lshift:
721      for (unsigned c = 0, c0 = 0, c1 = 0;
722           c < components;
723           c0 += c0_inc, c1 += c1_inc, c++) {
724
725          if (op[0]->type->base_type == GLSL_TYPE_INT &&
726              op[1]->type->base_type == GLSL_TYPE_INT) {
727              data.i[c] = op[0]->value.i[c0] << op[1]->value.i[c1];
728
729          } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
730                     op[1]->type->base_type == GLSL_TYPE_UINT) {
731              data.i[c] = op[0]->value.i[c0] << op[1]->value.u[c1];
732
733          } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
734                     op[1]->type->base_type == GLSL_TYPE_INT) {
735              data.u[c] = op[0]->value.u[c0] << op[1]->value.i[c1];
736
737          } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
738                     op[1]->type->base_type == GLSL_TYPE_UINT) {
739              data.u[c] = op[0]->value.u[c0] << op[1]->value.u[c1];
740          }
741      }
742      break;
743
744   case ir_binop_rshift:
745       for (unsigned c = 0, c0 = 0, c1 = 0;
746            c < components;
747            c0 += c0_inc, c1 += c1_inc, c++) {
748
749           if (op[0]->type->base_type == GLSL_TYPE_INT &&
750               op[1]->type->base_type == GLSL_TYPE_INT) {
751               data.i[c] = op[0]->value.i[c0] >> op[1]->value.i[c1];
752
753           } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
754                      op[1]->type->base_type == GLSL_TYPE_UINT) {
755               data.i[c] = op[0]->value.i[c0] >> op[1]->value.u[c1];
756
757           } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
758                      op[1]->type->base_type == GLSL_TYPE_INT) {
759               data.u[c] = op[0]->value.u[c0] >> op[1]->value.i[c1];
760
761           } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
762                      op[1]->type->base_type == GLSL_TYPE_UINT) {
763               data.u[c] = op[0]->value.u[c0] >> op[1]->value.u[c1];
764           }
765       }
766       break;
767
768   case ir_binop_bit_and:
769      for (unsigned c = 0, c0 = 0, c1 = 0;
770           c < components;
771           c0 += c0_inc, c1 += c1_inc, c++) {
772
773          switch (op[0]->type->base_type) {
774          case GLSL_TYPE_INT:
775              data.i[c] = op[0]->value.i[c0] & op[1]->value.i[c1];
776              break;
777          case GLSL_TYPE_UINT:
778              data.u[c] = op[0]->value.u[c0] & op[1]->value.u[c1];
779              break;
780          default:
781              assert(0);
782          }
783      }
784      break;
785
786   case ir_binop_bit_or:
787      for (unsigned c = 0, c0 = 0, c1 = 0;
788           c < components;
789           c0 += c0_inc, c1 += c1_inc, c++) {
790
791          switch (op[0]->type->base_type) {
792          case GLSL_TYPE_INT:
793              data.i[c] = op[0]->value.i[c0] | op[1]->value.i[c1];
794              break;
795          case GLSL_TYPE_UINT:
796              data.u[c] = op[0]->value.u[c0] | op[1]->value.u[c1];
797              break;
798          default:
799              assert(0);
800          }
801      }
802      break;
803
804   case ir_binop_bit_xor:
805      for (unsigned c = 0, c0 = 0, c1 = 0;
806           c < components;
807           c0 += c0_inc, c1 += c1_inc, c++) {
808
809          switch (op[0]->type->base_type) {
810          case GLSL_TYPE_INT:
811              data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1];
812              break;
813          case GLSL_TYPE_UINT:
814              data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1];
815              break;
816          default:
817              assert(0);
818          }
819      }
820      break;
821
822   case ir_quadop_vector:
823      for (unsigned c = 0; c < this->type->vector_elements; c++) {
824	 switch (this->type->base_type) {
825	 case GLSL_TYPE_INT:
826	    data.i[c] = op[c]->value.i[0];
827	    break;
828	 case GLSL_TYPE_UINT:
829	    data.u[c] = op[c]->value.u[0];
830	    break;
831	 case GLSL_TYPE_FLOAT:
832	    data.f[c] = op[c]->value.f[0];
833	    break;
834	 default:
835	    assert(0);
836	 }
837      }
838      break;
839
840   default:
841      /* FINISHME: Should handle all expression types. */
842      return NULL;
843   }
844
845   return new(ctx) ir_constant(this->type, &data);
846}
847
848
849ir_constant *
850ir_texture::constant_expression_value()
851{
852   /* texture lookups aren't constant expressions */
853   return NULL;
854}
855
856
857ir_constant *
858ir_swizzle::constant_expression_value()
859{
860   ir_constant *v = this->val->constant_expression_value();
861
862   if (v != NULL) {
863      ir_constant_data data = { { 0 } };
864
865      const unsigned swiz_idx[4] = {
866	 this->mask.x, this->mask.y, this->mask.z, this->mask.w
867      };
868
869      for (unsigned i = 0; i < this->mask.num_components; i++) {
870	 switch (v->type->base_type) {
871	 case GLSL_TYPE_UINT:
872	 case GLSL_TYPE_INT:   data.u[i] = v->value.u[swiz_idx[i]]; break;
873	 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
874	 case GLSL_TYPE_BOOL:  data.b[i] = v->value.b[swiz_idx[i]]; break;
875	 default:              assert(!"Should not get here."); break;
876	 }
877      }
878
879      void *ctx = ralloc_parent(this);
880      return new(ctx) ir_constant(this->type, &data);
881   }
882   return NULL;
883}
884
885
886ir_constant *
887ir_dereference_variable::constant_expression_value()
888{
889   /* This may occur during compile and var->type is glsl_type::error_type */
890   if (!var)
891      return NULL;
892
893   /* The constant_value of a uniform variable is its initializer,
894    * not the lifetime constant value of the uniform.
895    */
896   if (var->mode == ir_var_uniform)
897      return NULL;
898
899   if (!var->constant_value)
900      return NULL;
901
902   return var->constant_value->clone(ralloc_parent(var), NULL);
903}
904
905
906ir_constant *
907ir_dereference_array::constant_expression_value()
908{
909   ir_constant *array = this->array->constant_expression_value();
910   ir_constant *idx = this->array_index->constant_expression_value();
911
912   if ((array != NULL) && (idx != NULL)) {
913      void *ctx = ralloc_parent(this);
914      if (array->type->is_matrix()) {
915	 /* Array access of a matrix results in a vector.
916	  */
917	 const unsigned column = idx->value.u[0];
918
919	 const glsl_type *const column_type = array->type->column_type();
920
921	 /* Offset in the constant matrix to the first element of the column
922	  * to be extracted.
923	  */
924	 const unsigned mat_idx = column * column_type->vector_elements;
925
926	 ir_constant_data data = { { 0 } };
927
928	 switch (column_type->base_type) {
929	 case GLSL_TYPE_UINT:
930	 case GLSL_TYPE_INT:
931	    for (unsigned i = 0; i < column_type->vector_elements; i++)
932	       data.u[i] = array->value.u[mat_idx + i];
933
934	    break;
935
936	 case GLSL_TYPE_FLOAT:
937	    for (unsigned i = 0; i < column_type->vector_elements; i++)
938	       data.f[i] = array->value.f[mat_idx + i];
939
940	    break;
941
942	 default:
943	    assert(!"Should not get here.");
944	    break;
945	 }
946
947	 return new(ctx) ir_constant(column_type, &data);
948      } else if (array->type->is_vector()) {
949	 const unsigned component = idx->value.u[0];
950
951	 return new(ctx) ir_constant(array, component);
952      } else {
953	 const unsigned index = idx->value.u[0];
954	 return array->get_array_element(index)->clone(ctx, NULL);
955      }
956   }
957   return NULL;
958}
959
960
961ir_constant *
962ir_dereference_record::constant_expression_value()
963{
964   ir_constant *v = this->record->constant_expression_value();
965
966   return (v != NULL) ? v->get_record_field(this->field) : NULL;
967}
968
969
970ir_constant *
971ir_assignment::constant_expression_value()
972{
973   /* FINISHME: Handle CEs involving assignment (return RHS) */
974   return NULL;
975}
976
977
978ir_constant *
979ir_constant::constant_expression_value()
980{
981   return this;
982}
983
984
985ir_constant *
986ir_call::constant_expression_value()
987{
988   if (this->type == glsl_type::error_type)
989      return NULL;
990
991   /* From the GLSL 1.20 spec, page 23:
992    * "Function calls to user-defined functions (non-built-in functions)
993    *  cannot be used to form constant expressions."
994    */
995   if (!this->callee->is_builtin)
996      return NULL;
997
998   unsigned num_parameters = 0;
999
1000   /* Check if all parameters are constant */
1001   ir_constant *op[3];
1002   foreach_list(n, &this->actual_parameters) {
1003      ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
1004      if (constant == NULL)
1005	 return NULL;
1006
1007      op[num_parameters] = constant;
1008
1009      assert(num_parameters < 3);
1010      num_parameters++;
1011   }
1012
1013   /* Individual cases below can either:
1014    * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
1015    * - Fill "data" with appopriate constant data
1016    * - Return an ir_constant directly.
1017    */
1018   void *mem_ctx = ralloc_parent(this);
1019   ir_expression *expr = NULL;
1020
1021   ir_constant_data data;
1022   memset(&data, 0, sizeof(data));
1023
1024   const char *callee = this->callee_name();
1025   if (strcmp(callee, "abs") == 0) {
1026      expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
1027   } else if (strcmp(callee, "all") == 0) {
1028      assert(op[0]->type->is_boolean());
1029      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1030	 if (!op[0]->value.b[c])
1031	    return new(mem_ctx) ir_constant(false);
1032      }
1033      return new(mem_ctx) ir_constant(true);
1034   } else if (strcmp(callee, "any") == 0) {
1035      assert(op[0]->type->is_boolean());
1036      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1037	 if (op[0]->value.b[c])
1038	    return new(mem_ctx) ir_constant(true);
1039      }
1040      return new(mem_ctx) ir_constant(false);
1041   } else if (strcmp(callee, "acos") == 0) {
1042      assert(op[0]->type->is_float());
1043      for (unsigned c = 0; c < op[0]->type->components(); c++)
1044	 data.f[c] = acosf(op[0]->value.f[c]);
1045   } else if (strcmp(callee, "acosh") == 0) {
1046      assert(op[0]->type->is_float());
1047      for (unsigned c = 0; c < op[0]->type->components(); c++)
1048	 data.f[c] = acoshf(op[0]->value.f[c]);
1049   } else if (strcmp(callee, "asin") == 0) {
1050      assert(op[0]->type->is_float());
1051      for (unsigned c = 0; c < op[0]->type->components(); c++)
1052	 data.f[c] = asinf(op[0]->value.f[c]);
1053   } else if (strcmp(callee, "asinh") == 0) {
1054      assert(op[0]->type->is_float());
1055      for (unsigned c = 0; c < op[0]->type->components(); c++)
1056	 data.f[c] = asinhf(op[0]->value.f[c]);
1057   } else if (strcmp(callee, "atan") == 0) {
1058      assert(op[0]->type->is_float());
1059      if (num_parameters == 2) {
1060	 assert(op[1]->type->is_float());
1061	 for (unsigned c = 0; c < op[0]->type->components(); c++)
1062	    data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
1063      } else {
1064	 for (unsigned c = 0; c < op[0]->type->components(); c++)
1065	    data.f[c] = atanf(op[0]->value.f[c]);
1066      }
1067   } else if (strcmp(callee, "atanh") == 0) {
1068      assert(op[0]->type->is_float());
1069      for (unsigned c = 0; c < op[0]->type->components(); c++)
1070	 data.f[c] = atanhf(op[0]->value.f[c]);
1071   } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
1072      return ir_constant::zero(mem_ctx, this->type);
1073   } else if (strcmp(callee, "ceil") == 0) {
1074      expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
1075   } else if (strcmp(callee, "clamp") == 0) {
1076      assert(num_parameters == 3);
1077      unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
1078      unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1079      for (unsigned c = 0, c1 = 0, c2 = 0;
1080	   c < op[0]->type->components();
1081	   c1 += c1_inc, c2 += c2_inc, c++) {
1082
1083	 switch (op[0]->type->base_type) {
1084	 case GLSL_TYPE_UINT:
1085	    data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
1086			      op[2]->value.u[c2]);
1087	    break;
1088	 case GLSL_TYPE_INT:
1089	    data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
1090			      op[2]->value.i[c2]);
1091	    break;
1092	 case GLSL_TYPE_FLOAT:
1093	    data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
1094			      op[2]->value.f[c2]);
1095	    break;
1096	 default:
1097	    assert(!"Should not get here.");
1098	 }
1099      }
1100   } else if (strcmp(callee, "cos") == 0) {
1101      expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
1102   } else if (strcmp(callee, "cosh") == 0) {
1103      assert(op[0]->type->is_float());
1104      for (unsigned c = 0; c < op[0]->type->components(); c++)
1105	 data.f[c] = coshf(op[0]->value.f[c]);
1106   } else if (strcmp(callee, "cross") == 0) {
1107      assert(op[0]->type == glsl_type::vec3_type);
1108      assert(op[1]->type == glsl_type::vec3_type);
1109      data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
1110		   op[1]->value.f[1] * op[0]->value.f[2]);
1111      data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
1112		   op[1]->value.f[2] * op[0]->value.f[0]);
1113      data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
1114		   op[1]->value.f[0] * op[0]->value.f[1]);
1115   } else if (strcmp(callee, "degrees") == 0) {
1116      assert(op[0]->type->is_float());
1117      for (unsigned c = 0; c < op[0]->type->components(); c++)
1118	 data.f[c] = 180.0F / M_PI * op[0]->value.f[c];
1119   } else if (strcmp(callee, "distance") == 0) {
1120      assert(op[0]->type->is_float() && op[1]->type->is_float());
1121      float length_squared = 0.0;
1122      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1123	 float t = op[0]->value.f[c] - op[1]->value.f[c];
1124	 length_squared += t * t;
1125      }
1126      return new(mem_ctx) ir_constant(sqrtf(length_squared));
1127   } else if (strcmp(callee, "dot") == 0) {
1128      return new(mem_ctx) ir_constant(dot(op[0], op[1]));
1129   } else if (strcmp(callee, "equal") == 0) {
1130      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1131      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1132	 switch (op[0]->type->base_type) {
1133	 case GLSL_TYPE_UINT:
1134	    data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
1135	    break;
1136	 case GLSL_TYPE_INT:
1137	    data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
1138	    break;
1139	 case GLSL_TYPE_FLOAT:
1140	    data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
1141	    break;
1142	 case GLSL_TYPE_BOOL:
1143	    data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
1144	    break;
1145	 default:
1146	    assert(!"Should not get here.");
1147	 }
1148      }
1149   } else if (strcmp(callee, "exp") == 0) {
1150      expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
1151   } else if (strcmp(callee, "exp2") == 0) {
1152      expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
1153   } else if (strcmp(callee, "faceforward") == 0) {
1154      if (dot(op[2], op[1]) < 0)
1155	 return op[0];
1156      for (unsigned c = 0; c < op[0]->type->components(); c++)
1157	 data.f[c] = -op[0]->value.f[c];
1158   } else if (strcmp(callee, "floor") == 0) {
1159      expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
1160   } else if (strcmp(callee, "fract") == 0) {
1161      expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
1162   } else if (strcmp(callee, "fwidth") == 0) {
1163      return ir_constant::zero(mem_ctx, this->type);
1164   } else if (strcmp(callee, "greaterThan") == 0) {
1165      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1166      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1167	 switch (op[0]->type->base_type) {
1168	 case GLSL_TYPE_UINT:
1169	    data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
1170	    break;
1171	 case GLSL_TYPE_INT:
1172	    data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
1173	    break;
1174	 case GLSL_TYPE_FLOAT:
1175	    data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
1176	    break;
1177	 default:
1178	    assert(!"Should not get here.");
1179	 }
1180      }
1181   } else if (strcmp(callee, "greaterThanEqual") == 0) {
1182      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1183      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1184	 switch (op[0]->type->base_type) {
1185	 case GLSL_TYPE_UINT:
1186	    data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
1187	    break;
1188	 case GLSL_TYPE_INT:
1189	    data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
1190	    break;
1191	 case GLSL_TYPE_FLOAT:
1192	    data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
1193	    break;
1194	 default:
1195	    assert(!"Should not get here.");
1196	 }
1197      }
1198   } else if (strcmp(callee, "inversesqrt") == 0) {
1199      expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
1200   } else if (strcmp(callee, "length") == 0) {
1201      return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
1202   } else if (strcmp(callee, "lessThan") == 0) {
1203      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1204      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1205	 switch (op[0]->type->base_type) {
1206	 case GLSL_TYPE_UINT:
1207	    data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
1208	    break;
1209	 case GLSL_TYPE_INT:
1210	    data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
1211	    break;
1212	 case GLSL_TYPE_FLOAT:
1213	    data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
1214	    break;
1215	 default:
1216	    assert(!"Should not get here.");
1217	 }
1218      }
1219   } else if (strcmp(callee, "lessThanEqual") == 0) {
1220      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1221      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1222	 switch (op[0]->type->base_type) {
1223	 case GLSL_TYPE_UINT:
1224	    data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
1225	    break;
1226	 case GLSL_TYPE_INT:
1227	    data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
1228	    break;
1229	 case GLSL_TYPE_FLOAT:
1230	    data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
1231	    break;
1232	 default:
1233	    assert(!"Should not get here.");
1234	 }
1235      }
1236   } else if (strcmp(callee, "log") == 0) {
1237      expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
1238   } else if (strcmp(callee, "log2") == 0) {
1239      expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
1240   } else if (strcmp(callee, "matrixCompMult") == 0) {
1241      assert(op[0]->type->is_float() && op[1]->type->is_float());
1242      for (unsigned c = 0; c < op[0]->type->components(); c++)
1243	 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
1244   } else if (strcmp(callee, "max") == 0) {
1245      expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
1246   } else if (strcmp(callee, "min") == 0) {
1247      expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
1248   } else if (strcmp(callee, "mix") == 0) {
1249      assert(op[0]->type->is_float() && op[1]->type->is_float());
1250      if (op[2]->type->is_float()) {
1251	 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1252	 unsigned components = op[0]->type->components();
1253	 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
1254	    data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
1255			op[1]->value.f[c] * op[2]->value.f[c2];
1256	 }
1257      } else {
1258	 assert(op[2]->type->is_boolean());
1259	 for (unsigned c = 0; c < op[0]->type->components(); c++)
1260	    data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
1261      }
1262   } else if (strcmp(callee, "mod") == 0) {
1263      expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
1264   } else if (strcmp(callee, "normalize") == 0) {
1265      assert(op[0]->type->is_float());
1266      float length = sqrtf(dot(op[0], op[0]));
1267
1268      if (length == 0)
1269	 return ir_constant::zero(mem_ctx, this->type);
1270
1271      for (unsigned c = 0; c < op[0]->type->components(); c++)
1272	 data.f[c] = op[0]->value.f[c] / length;
1273   } else if (strcmp(callee, "not") == 0) {
1274      expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
1275   } else if (strcmp(callee, "notEqual") == 0) {
1276      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1277      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1278	 switch (op[0]->type->base_type) {
1279	 case GLSL_TYPE_UINT:
1280	    data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
1281	    break;
1282	 case GLSL_TYPE_INT:
1283	    data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1284	    break;
1285	 case GLSL_TYPE_FLOAT:
1286	    data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1287	    break;
1288	 case GLSL_TYPE_BOOL:
1289	    data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
1290	    break;
1291	 default:
1292	    assert(!"Should not get here.");
1293	 }
1294      }
1295   } else if (strcmp(callee, "outerProduct") == 0) {
1296      assert(op[0]->type->is_vector() && op[1]->type->is_vector());
1297      const unsigned m = op[0]->type->vector_elements;
1298      const unsigned n = op[1]->type->vector_elements;
1299      for (unsigned j = 0; j < n; j++) {
1300	 for (unsigned i = 0; i < m; i++) {
1301	    data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
1302	 }
1303      }
1304   } else if (strcmp(callee, "pow") == 0) {
1305      expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
1306   } else if (strcmp(callee, "radians") == 0) {
1307      assert(op[0]->type->is_float());
1308      for (unsigned c = 0; c < op[0]->type->components(); c++)
1309	 data.f[c] = M_PI / 180.0F * op[0]->value.f[c];
1310   } else if (strcmp(callee, "reflect") == 0) {
1311      assert(op[0]->type->is_float());
1312      float dot_NI = dot(op[1], op[0]);
1313      for (unsigned c = 0; c < op[0]->type->components(); c++)
1314	 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
1315   } else if (strcmp(callee, "refract") == 0) {
1316      const float eta = op[2]->value.f[0];
1317      const float dot_NI = dot(op[1], op[0]);
1318      const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI);
1319      if (k < 0.0) {
1320	 return ir_constant::zero(mem_ctx, this->type);
1321      } else {
1322	 for (unsigned c = 0; c < type->components(); c++) {
1323	    data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
1324			    * op[1]->value.f[c];
1325	 }
1326      }
1327   } else if (strcmp(callee, "sign") == 0) {
1328      expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
1329   } else if (strcmp(callee, "sin") == 0) {
1330      expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
1331   } else if (strcmp(callee, "sinh") == 0) {
1332      assert(op[0]->type->is_float());
1333      for (unsigned c = 0; c < op[0]->type->components(); c++)
1334	 data.f[c] = sinhf(op[0]->value.f[c]);
1335   } else if (strcmp(callee, "smoothstep") == 0) {
1336      assert(num_parameters == 3);
1337      assert(op[1]->type == op[0]->type);
1338      unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
1339      for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
1340	 const float edge0 = op[0]->value.f[e];
1341	 const float edge1 = op[1]->value.f[e];
1342	 if (edge0 == edge1) {
1343	    data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
1344	 } else {
1345	    const float numerator = op[2]->value.f[c] - edge0;
1346	    const float denominator = edge1 - edge0;
1347	    const float t = CLAMP(numerator/denominator, 0, 1);
1348	    data.f[c] = t * t * (3 - 2 * t);
1349	 }
1350      }
1351   } else if (strcmp(callee, "sqrt") == 0) {
1352      expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
1353   } else if (strcmp(callee, "step") == 0) {
1354      assert(op[0]->type->is_float() && op[1]->type->is_float());
1355      /* op[0] (edge) may be either a scalar or a vector */
1356      const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
1357      for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
1358	 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F;
1359   } else if (strcmp(callee, "tan") == 0) {
1360      assert(op[0]->type->is_float());
1361      for (unsigned c = 0; c < op[0]->type->components(); c++)
1362	 data.f[c] = tanf(op[0]->value.f[c]);
1363   } else if (strcmp(callee, "tanh") == 0) {
1364      assert(op[0]->type->is_float());
1365      for (unsigned c = 0; c < op[0]->type->components(); c++)
1366	 data.f[c] = tanhf(op[0]->value.f[c]);
1367   } else if (strcmp(callee, "transpose") == 0) {
1368      assert(op[0]->type->is_matrix());
1369      const unsigned n = op[0]->type->vector_elements;
1370      const unsigned m = op[0]->type->matrix_columns;
1371      for (unsigned j = 0; j < m; j++) {
1372	 for (unsigned i = 0; i < n; i++) {
1373	    data.f[m*i+j] += op[0]->value.f[i+n*j];
1374	 }
1375      }
1376   } else {
1377      /* Unsupported builtin - some are not allowed in constant expressions. */
1378      return NULL;
1379   }
1380
1381   if (expr != NULL)
1382      return expr->constant_expression_value();
1383
1384   return new(mem_ctx) ir_constant(this->type, &data);
1385}
1386