blob: bc1261b0b95d6f2d1e8e51d33334540ab80cb794 [file] [log] [blame]
Ian Romanick1cf43a42010-03-30 16:56:50 -07001/*
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
Eric Anholt43ad37a2010-05-12 14:42:21 -070036#include <math.h>
Kenneth Graunkef9149152010-07-21 21:56:13 -070037#include "main/macros.h"
Ian Romanick1cf43a42010-03-30 16:56:50 -070038#include "ir.h"
39#include "ir_visitor.h"
Eric Anholta576f9d2010-03-31 16:25:12 -100040#include "glsl_types.h"
Ian Romanick1cf43a42010-03-30 16:56:50 -070041
Ian Romanick1cf43a42010-03-30 16:56:50 -070042ir_constant *
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -070043ir_expression::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -070044{
Kenneth Graunke6bc432e2010-07-02 17:12:23 -070045 ir_constant *op[2] = { NULL, NULL };
Ian Romanick4daaab62010-06-11 16:08:47 -070046 ir_constant_data data;
Eric Anholt160d0922010-04-01 18:07:08 -100047
Kenneth Graunkec63a1db2010-07-05 22:33:35 -070048 memset(&data, 0, sizeof(data));
49
Kenneth Graunke98f32a12010-07-15 10:20:51 -070050 for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
51 op[operand] = this->operands[operand]->constant_expression_value();
Eric Anholtd98da972010-04-01 18:25:11 -100052 if (!op[operand])
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -070053 return NULL;
Eric Anholt160d0922010-04-01 18:07:08 -100054 }
Eric Anholta576f9d2010-03-31 16:25:12 -100055
Kenneth Graunke6fc983b2010-07-06 02:39:57 -070056 if (op[1] != NULL)
57 assert(op[0]->type->base_type == op[1]->type->base_type);
58
Kenneth Graunkee74dcd72010-07-06 02:48:16 -070059 bool op0_scalar = op[0]->type->is_scalar();
60 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
61
62 /* When iterating over a vector or matrix's components, we want to increase
63 * the loop counter. However, for scalars, we want to stay at 0.
64 */
Kenneth Graunkeacf88f22010-07-07 12:08:23 -070065 unsigned c0_inc = op0_scalar ? 0 : 1;
66 unsigned c1_inc = op1_scalar ? 0 : 1;
Eric Anholt570dc0d2010-07-07 09:07:09 -070067 unsigned components;
68 if (op1_scalar || !op[1]) {
69 components = op[0]->type->components();
70 } else {
71 components = op[1]->type->components();
72 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -070073
Kenneth Graunke9a6d40f2010-07-20 03:08:32 -070074 void *ctx = talloc_parent(this);
75
76 /* Handle array operations here, rather than below. */
77 if (op[0]->type->is_array()) {
78 assert(op[1] != NULL && op[1]->type->is_array());
79 switch (this->operation) {
80 case ir_binop_equal:
81 return new(ctx) ir_constant(op[0]->has_value(op[1]));
82 case ir_binop_nequal:
83 return new(ctx) ir_constant(!op[0]->has_value(op[1]));
84 default:
85 break;
86 }
87 return NULL;
88 }
89
Kenneth Graunke98f32a12010-07-15 10:20:51 -070090 switch (this->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -100091 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -070092 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -070093 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -070094 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -100095 break;
Eric Anholtaf186412010-04-06 10:53:57 -070096
97 case ir_unop_f2i:
98 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -070099 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700100 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700101 }
102 break;
103 case ir_unop_i2f:
Kenneth Graunke46d6b8d2010-07-20 13:01:56 -0700104 assert(op[0]->type->base_type == GLSL_TYPE_INT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700105 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke46d6b8d2010-07-20 13:01:56 -0700106 data.f[c] = op[0]->value.i[c];
107 }
108 break;
109 case ir_unop_u2f:
110 assert(op[0]->type->base_type == GLSL_TYPE_UINT);
111 for (unsigned c = 0; c < op[0]->type->components(); c++) {
112 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700113 }
114 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700115 case ir_unop_b2f:
116 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700117 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700118 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700119 }
120 break;
121 case ir_unop_f2b:
122 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700123 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700124 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700125 }
126 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700127 case ir_unop_b2i:
128 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700129 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700130 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700131 }
132 break;
133 case ir_unop_i2b:
134 assert(op[0]->type->is_integer());
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700135 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700136 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700137 }
138 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700139
Kenneth Graunke323d9092010-07-08 23:21:36 -0700140 case ir_unop_trunc:
141 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700142 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke323d9092010-07-08 23:21:36 -0700143 data.f[c] = truncf(op[0]->value.f[c]);
144 }
145 break;
146
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700147 case ir_unop_ceil:
148 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700149 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700150 data.f[c] = ceilf(op[0]->value.f[c]);
151 }
152 break;
153
Kenneth Graunke07472042010-07-08 23:23:23 -0700154 case ir_unop_floor:
155 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700156 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke07472042010-07-08 23:23:23 -0700157 data.f[c] = floorf(op[0]->value.f[c]);
158 }
159 break;
160
Eric Anholtd925c912010-07-01 10:37:11 -0700161 case ir_unop_fract:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700162 for (unsigned c = 0; c < op[0]->type->components(); c++) {
163 switch (this->type->base_type) {
Eric Anholtd925c912010-07-01 10:37:11 -0700164 case GLSL_TYPE_UINT:
165 data.u[c] = 0;
166 break;
167 case GLSL_TYPE_INT:
168 data.i[c] = 0;
169 break;
170 case GLSL_TYPE_FLOAT:
171 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
172 break;
173 default:
174 assert(0);
175 }
176 }
177 break;
178
Kenneth Graunke908afd12010-07-08 23:28:50 -0700179 case ir_unop_sin:
180 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700181 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke908afd12010-07-08 23:28:50 -0700182 data.f[c] = sinf(op[0]->value.f[c]);
183 }
184 break;
185
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700186 case ir_unop_cos:
187 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700188 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700189 data.f[c] = cosf(op[0]->value.f[c]);
190 }
191 break;
192
Eric Anholt43ad37a2010-05-12 14:42:21 -0700193 case ir_unop_neg:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700194 for (unsigned c = 0; c < op[0]->type->components(); c++) {
195 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700196 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700197 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700198 break;
199 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700200 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700201 break;
202 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700203 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700204 break;
205 default:
206 assert(0);
207 }
208 }
209 break;
210
211 case ir_unop_abs:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700212 for (unsigned c = 0; c < op[0]->type->components(); c++) {
213 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700214 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700215 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700216 break;
217 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700218 data.i[c] = op[0]->value.i[c];
219 if (data.i[c] < 0)
220 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700221 break;
222 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700223 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700224 break;
225 default:
226 assert(0);
227 }
228 }
229 break;
230
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700231 case ir_unop_sign:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700232 for (unsigned c = 0; c < op[0]->type->components(); c++) {
233 switch (this->type->base_type) {
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700234 case GLSL_TYPE_UINT:
235 data.u[c] = op[0]->value.i[c] > 0;
236 break;
237 case GLSL_TYPE_INT:
238 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
239 break;
240 case GLSL_TYPE_FLOAT:
241 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
242 break;
243 default:
244 assert(0);
245 }
246 }
247 break;
248
Eric Anholt43ad37a2010-05-12 14:42:21 -0700249 case ir_unop_rcp:
250 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700251 for (unsigned c = 0; c < op[0]->type->components(); c++) {
252 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700253 case GLSL_TYPE_UINT:
254 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700255 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700256 break;
257 case GLSL_TYPE_INT:
258 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700259 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700260 break;
261 case GLSL_TYPE_FLOAT:
262 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700263 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700264 break;
265 default:
266 assert(0);
267 }
268 }
269 break;
270
271 case ir_unop_rsq:
272 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700273 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700274 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700275 }
276 break;
277
278 case ir_unop_sqrt:
279 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700280 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700281 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700282 }
283 break;
284
285 case ir_unop_exp:
286 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700287 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700288 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700289 }
290 break;
291
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700292 case ir_unop_exp2:
293 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700294 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700295 data.f[c] = exp2f(op[0]->value.f[c]);
296 }
297 break;
298
Eric Anholt43ad37a2010-05-12 14:42:21 -0700299 case ir_unop_log:
300 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700301 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700302 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700303 }
304 break;
305
Kenneth Graunkecb639292010-07-08 23:18:09 -0700306 case ir_unop_log2:
307 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700308 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkecb639292010-07-08 23:18:09 -0700309 data.f[c] = log2f(op[0]->value.f[c]);
310 }
311 break;
312
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700313 case ir_unop_dFdx:
314 case ir_unop_dFdy:
315 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700316 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700317 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700318 }
319 break;
320
Kenneth Graunke891a0642010-07-08 23:35:09 -0700321 case ir_binop_pow:
322 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700323 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke891a0642010-07-08 23:35:09 -0700324 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
325 }
326 break;
327
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700328 case ir_binop_dot:
329 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
330 data.f[0] = 0;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700331 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700332 switch (op[0]->type->base_type) {
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700333 case GLSL_TYPE_UINT:
334 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
335 break;
336 case GLSL_TYPE_INT:
337 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
338 break;
339 case GLSL_TYPE_FLOAT:
340 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
341 break;
342 default:
343 assert(0);
344 }
345 }
346
347 break;
Kenneth Graunke79fed372010-07-09 11:53:56 -0700348 case ir_binop_min:
349 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
350 for (unsigned c = 0, c0 = 0, c1 = 0;
351 c < components;
352 c0 += c0_inc, c1 += c1_inc, c++) {
353
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700354 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700355 case GLSL_TYPE_UINT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700356 data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700357 break;
358 case GLSL_TYPE_INT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700359 data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700360 break;
361 case GLSL_TYPE_FLOAT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700362 data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700363 break;
364 default:
365 assert(0);
366 }
367 }
368
369 break;
370 case ir_binop_max:
371 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
372 for (unsigned c = 0, c0 = 0, c1 = 0;
373 c < components;
374 c0 += c0_inc, c1 += c1_inc, c++) {
375
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700376 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700377 case GLSL_TYPE_UINT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700378 data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700379 break;
380 case GLSL_TYPE_INT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700381 data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700382 break;
383 case GLSL_TYPE_FLOAT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700384 data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700385 break;
386 default:
387 assert(0);
388 }
389 }
Kenneth Graunke79fed372010-07-09 11:53:56 -0700390 break;
Eric Anholt9be7f632010-07-13 15:37:57 -0700391
392 case ir_binop_cross:
393 assert(op[0]->type == glsl_type::vec3_type);
394 assert(op[1]->type == glsl_type::vec3_type);
395 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
396 op[1]->value.f[1] * op[0]->value.f[2]);
397 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
398 op[1]->value.f[2] * op[0]->value.f[0]);
399 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
400 op[1]->value.f[0] * op[0]->value.f[1]);
401 break;
402
Eric Anholtd251b922010-04-01 18:35:42 -1000403 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700404 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
405 for (unsigned c = 0, c0 = 0, c1 = 0;
406 c < components;
407 c0 += c0_inc, c1 += c1_inc, c++) {
408
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700409 switch (op[0]->type->base_type) {
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700410 case GLSL_TYPE_UINT:
411 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
412 break;
413 case GLSL_TYPE_INT:
414 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
415 break;
416 case GLSL_TYPE_FLOAT:
417 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
418 break;
419 default:
420 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000421 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700422 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700423
Eric Anholtd251b922010-04-01 18:35:42 -1000424 break;
425 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700426 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
427 for (unsigned c = 0, c0 = 0, c1 = 0;
428 c < components;
429 c0 += c0_inc, c1 += c1_inc, c++) {
430
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700431 switch (op[0]->type->base_type) {
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700432 case GLSL_TYPE_UINT:
433 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
434 break;
435 case GLSL_TYPE_INT:
436 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
437 break;
438 case GLSL_TYPE_FLOAT:
439 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
440 break;
441 default:
442 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000443 }
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700444 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700445
Eric Anholtd251b922010-04-01 18:35:42 -1000446 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000447 case ir_binop_mul:
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700448 /* Check for equal types, or unequal types involving scalars */
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700449 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
450 || op0_scalar || op1_scalar) {
451 for (unsigned c = 0, c0 = 0, c1 = 0;
452 c < components;
453 c0 += c0_inc, c1 += c1_inc, c++) {
454
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700455 switch (op[0]->type->base_type) {
Eric Anholtd98da972010-04-01 18:25:11 -1000456 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700457 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000458 break;
459 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700460 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000461 break;
462 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700463 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000464 break;
465 default:
466 assert(0);
467 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000468 }
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700469 } else {
470 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
471
472 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
473 * matrix can be a GLSL vector, either N or P can be 1.
474 *
475 * For vec*mat, the vector is treated as a row vector. This
476 * means the vector is a 1-row x M-column matrix.
477 *
478 * For mat*vec, the vector is treated as a column vector. Since
479 * matrix_columns is 1 for vectors, this just works.
480 */
481 const unsigned n = op[0]->type->is_vector()
482 ? 1 : op[0]->type->vector_elements;
483 const unsigned m = op[1]->type->vector_elements;
484 const unsigned p = op[1]->type->matrix_columns;
485 for (unsigned j = 0; j < p; j++) {
486 for (unsigned i = 0; i < n; i++) {
487 for (unsigned k = 0; k < m; k++) {
488 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
489 }
490 }
491 }
492 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700493
Eric Anholta576f9d2010-03-31 16:25:12 -1000494 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000495 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700496 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
497 for (unsigned c = 0, c0 = 0, c1 = 0;
498 c < components;
499 c0 += c0_inc, c1 += c1_inc, c++) {
500
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700501 switch (op[0]->type->base_type) {
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700502 case GLSL_TYPE_UINT:
503 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
504 break;
505 case GLSL_TYPE_INT:
506 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
507 break;
508 case GLSL_TYPE_FLOAT:
509 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
510 break;
511 default:
512 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000513 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700514 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700515
Eric Anholtd251b922010-04-01 18:35:42 -1000516 break;
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700517 case ir_binop_mod:
518 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
519 for (unsigned c = 0, c0 = 0, c1 = 0;
520 c < components;
521 c0 += c0_inc, c1 += c1_inc, c++) {
522
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700523 switch (op[0]->type->base_type) {
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700524 case GLSL_TYPE_UINT:
525 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
526 break;
527 case GLSL_TYPE_INT:
528 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
529 break;
530 case GLSL_TYPE_FLOAT:
531 /* We don't use fmod because it rounds toward zero; GLSL specifies
532 * the use of floor.
533 */
Kenneth Graunke3e882ec2010-07-22 17:44:34 -0700534 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700535 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
536 break;
537 default:
538 assert(0);
539 }
540 }
541
542 break;
543
Eric Anholta576f9d2010-03-31 16:25:12 -1000544 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700545 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700546 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700547 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000548 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000549 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700550 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700551 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700552 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000553 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000554 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700555 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700556 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700557 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000558 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700559
560 case ir_binop_less:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700561 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700562 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700563 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700564 break;
565 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700566 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700567 break;
568 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700569 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700570 break;
571 default:
572 assert(0);
573 }
574 break;
575 case ir_binop_greater:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700576 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700577 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700578 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700579 break;
580 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700581 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700582 break;
583 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700584 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700585 break;
586 default:
587 assert(0);
588 }
589 break;
590 case ir_binop_lequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700591 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700592 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700593 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700594 break;
595 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700596 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700597 break;
598 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700599 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700600 break;
601 default:
602 assert(0);
603 }
604 break;
605 case ir_binop_gequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700606 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700607 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700608 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700609 break;
610 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700611 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700612 break;
613 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700614 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700615 break;
616 default:
617 assert(0);
618 }
619 break;
620
Eric Anholtec1949e2010-04-06 10:02:27 -0700621 case ir_binop_equal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700622 data.b[0] = op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700623 break;
624 case ir_binop_nequal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700625 data.b[0] = !op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700626 break;
627
Eric Anholta576f9d2010-03-31 16:25:12 -1000628 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700629 /* FINISHME: Should handle all expression types. */
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700630 return NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000631 }
Eric Anholtd98da972010-04-01 18:25:11 -1000632
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700633 return new(ctx) ir_constant(this->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700634}
635
636
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700637ir_constant *
638ir_texture::constant_expression_value()
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700639{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700640 /* texture lookups aren't constant expressions */
641 return NULL;
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700642}
643
644
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700645ir_constant *
646ir_swizzle::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700647{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700648 ir_constant *v = this->val->constant_expression_value();
Ian Romanickc2ba6192010-06-11 12:30:28 -0700649
Ian Romanickc2ba6192010-06-11 12:30:28 -0700650 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700651 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700652
653 const unsigned swiz_idx[4] = {
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700654 this->mask.x, this->mask.y, this->mask.z, this->mask.w
Ian Romanickc2ba6192010-06-11 12:30:28 -0700655 };
656
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700657 for (unsigned i = 0; i < this->mask.num_components; i++) {
Ian Romanickc2ba6192010-06-11 12:30:28 -0700658 switch (v->type->base_type) {
659 case GLSL_TYPE_UINT:
660 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
661 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
662 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
663 default: assert(!"Should not get here."); break;
664 }
665 }
666
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700667 void *ctx = talloc_parent(this);
668 return new(ctx) ir_constant(this->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700669 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700670 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700671}
672
673
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700674ir_constant *
675ir_dereference_variable::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700676{
Eric Anholt54f583a2010-07-27 12:10:50 -0700677 /* This may occur during compile and var->type is glsl_type::error_type */
678 if (!var)
679 return NULL;
680
Kenneth Graunkee4768ee2010-07-15 10:27:53 -0700681 return var->constant_value ? var->constant_value->clone(NULL) : NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200682}
683
684
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700685ir_constant *
686ir_dereference_array::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200687{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700688 void *ctx = talloc_parent(this);
689 ir_constant *array = this->array->constant_expression_value();
690 ir_constant *idx = this->array_index->constant_expression_value();
Ian Romanick9b92af92010-06-11 12:20:12 -0700691
Ian Romanick9b92af92010-06-11 12:20:12 -0700692 if ((array != NULL) && (idx != NULL)) {
693 if (array->type->is_matrix()) {
694 /* Array access of a matrix results in a vector.
695 */
696 const unsigned column = idx->value.u[0];
697
698 const glsl_type *const column_type = array->type->column_type();
699
700 /* Offset in the constant matrix to the first element of the column
701 * to be extracted.
702 */
703 const unsigned mat_idx = column * column_type->vector_elements;
704
Ian Romanick0bb70a32010-06-11 15:49:49 -0700705 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700706
707 switch (column_type->base_type) {
708 case GLSL_TYPE_UINT:
709 case GLSL_TYPE_INT:
710 for (unsigned i = 0; i < column_type->vector_elements; i++)
711 data.u[i] = array->value.u[mat_idx + i];
712
713 break;
714
715 case GLSL_TYPE_FLOAT:
716 for (unsigned i = 0; i < column_type->vector_elements; i++)
717 data.f[i] = array->value.f[mat_idx + i];
718
719 break;
720
721 default:
722 assert(!"Should not get here.");
723 break;
724 }
725
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700726 return new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700727 } else if (array->type->is_vector()) {
728 const unsigned component = idx->value.u[0];
729
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700730 return new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700731 } else {
Kenneth Graunkea096fa72010-07-20 01:31:29 -0700732 const unsigned index = idx->value.u[0];
733 return array->get_array_element(index)->clone(NULL);
Ian Romanick9b92af92010-06-11 12:20:12 -0700734 }
735 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700736 return NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200737}
738
739
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700740ir_constant *
741ir_dereference_record::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200742{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700743 ir_constant *v = this->record->constant_expression_value();
Ian Romanick253dede2010-06-09 17:30:19 -0700744
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700745 return (v != NULL) ? v->get_record_field(this->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700746}
747
748
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700749ir_constant *
750ir_assignment::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700751{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700752 /* FINISHME: Handle CEs involving assignment (return RHS) */
753 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700754}
755
756
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700757ir_constant *
758ir_constant::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700759{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700760 return this;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700761}
762
763
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700764ir_constant *
765ir_call::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700766{
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700767 if (this->type == glsl_type::error_type)
768 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700769
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700770 /* From the GLSL 1.20 spec, page 23:
771 * "Function calls to user-defined functions (non-built-in functions)
772 * cannot be used to form constant expressions."
773 */
774 if (!this->callee->is_built_in)
775 return NULL;
776
777 unsigned num_parameters = 0;
778
779 /* Check if all parameters are constant */
780 ir_constant *op[3];
781 foreach_list(n, &this->actual_parameters) {
782 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
783 if (constant == NULL)
784 return NULL;
785
786 op[num_parameters] = constant;
787
788 assert(num_parameters < 3);
789 num_parameters++;
790 }
791
792 /* Individual cases below can either:
793 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
794 * - Fill "data" with appopriate constant data
795 * - Return an ir_constant directly.
796 */
797 void *mem_ctx = talloc_parent(this);
798 ir_expression *expr = NULL;
799
800 ir_constant_data data;
801 memset(&data, 0, sizeof(data));
802
803 const char *callee = this->callee_name();
804 if (strcmp(callee, "abs") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700805 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700806 } else if (strcmp(callee, "all") == 0) {
Kenneth Graunkeaca7e952010-07-21 17:34:32 -0700807 assert(op[0]->type->is_boolean());
808 for (unsigned c = 0; c < op[0]->type->components(); c++) {
809 if (!op[0]->value.b[c])
810 return new(mem_ctx) ir_constant(false);
811 }
812 return new(mem_ctx) ir_constant(true);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700813 } else if (strcmp(callee, "any") == 0) {
Kenneth Graunked6792a72010-07-21 17:35:52 -0700814 assert(op[0]->type->is_boolean());
815 for (unsigned c = 0; c < op[0]->type->components(); c++) {
816 if (op[0]->value.b[c])
817 return new(mem_ctx) ir_constant(true);
818 }
819 return new(mem_ctx) ir_constant(false);
Kenneth Graunkef6ea9df2010-07-21 17:39:47 -0700820 } else if (strcmp(callee, "acos") == 0) {
821 assert(op[0]->type->is_float());
822 for (unsigned c = 0; c < op[0]->type->components(); c++)
823 data.f[c] = acosf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700824 } else if (strcmp(callee, "asin") == 0) {
Kenneth Graunke3b6c29b2010-07-21 17:38:38 -0700825 assert(op[0]->type->is_float());
826 for (unsigned c = 0; c < op[0]->type->components(); c++)
827 data.f[c] = asinf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700828 } else if (strcmp(callee, "atan") == 0) {
Kenneth Graunke13f87582010-07-21 17:42:23 -0700829 assert(op[0]->type->is_float());
830 if (num_parameters == 2) {
831 assert(op[1]->type->is_float());
832 for (unsigned c = 0; c < op[0]->type->components(); c++)
833 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
834 } else {
835 for (unsigned c = 0; c < op[0]->type->components(); c++)
836 data.f[c] = atanf(op[0]->value.f[c]);
837 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700838 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
Kenneth Graunke38cb1b22010-07-21 16:57:10 -0700839 return ir_constant::zero(mem_ctx, this->type);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700840 } else if (strcmp(callee, "ceil") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700841 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700842 } else if (strcmp(callee, "clamp") == 0) {
843 return NULL; /* FINISHME: implement this */
844 } else if (strcmp(callee, "cos") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700845 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700846 } else if (strcmp(callee, "cosh") == 0) {
Kenneth Graunkeba417832010-07-21 17:47:55 -0700847 assert(op[0]->type->is_float());
848 for (unsigned c = 0; c < op[0]->type->components(); c++)
849 data.f[c] = coshf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700850 } else if (strcmp(callee, "cross") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700851 expr = new(mem_ctx) ir_expression(ir_binop_cross, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700852 } else if (strcmp(callee, "degrees") == 0) {
853 return NULL; /* FINISHME: implement this */
854 } else if (strcmp(callee, "distance") == 0) {
855 return NULL; /* FINISHME: implement this */
856 } else if (strcmp(callee, "dot") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700857 expr = new(mem_ctx) ir_expression(ir_binop_dot, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700858 } else if (strcmp(callee, "equal") == 0) {
859 return NULL; /* FINISHME: implement this */
860 } else if (strcmp(callee, "exp") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700861 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700862 } else if (strcmp(callee, "exp2") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700863 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700864 } else if (strcmp(callee, "faceforward") == 0) {
865 return NULL; /* FINISHME: implement this */
866 } else if (strcmp(callee, "floor") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700867 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700868 } else if (strcmp(callee, "fract") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700869 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700870 } else if (strcmp(callee, "fwidth") == 0) {
Kenneth Graunke38cb1b22010-07-21 16:57:10 -0700871 return ir_constant::zero(mem_ctx, this->type);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700872 } else if (strcmp(callee, "greaterThan") == 0) {
873 return NULL; /* FINISHME: implement this */
874 } else if (strcmp(callee, "greaterThanEqual") == 0) {
875 return NULL; /* FINISHME: implement this */
876 } else if (strcmp(callee, "inversesqrt") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700877 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700878 } else if (strcmp(callee, "length") == 0) {
879 return NULL; /* FINISHME: implement this */
880 } else if (strcmp(callee, "lessThan") == 0) {
881 return NULL; /* FINISHME: implement this */
882 } else if (strcmp(callee, "lessThanEqual") == 0) {
883 return NULL; /* FINISHME: implement this */
884 } else if (strcmp(callee, "log") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700885 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700886 } else if (strcmp(callee, "log2") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700887 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700888 } else if (strcmp(callee, "matrixCompMult") == 0) {
889 return NULL; /* FINISHME: implement this */
890 } else if (strcmp(callee, "max") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700891 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700892 } else if (strcmp(callee, "min") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700893 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700894 } else if (strcmp(callee, "mix") == 0) {
895 return NULL; /* FINISHME: implement this */
896 } else if (strcmp(callee, "mod") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700897 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700898 } else if (strcmp(callee, "normalize") == 0) {
899 return NULL; /* FINISHME: implement this */
900 } else if (strcmp(callee, "not") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700901 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700902 } else if (strcmp(callee, "notEqual") == 0) {
903 return NULL; /* FINISHME: implement this */
904 } else if (strcmp(callee, "outerProduct") == 0) {
905 return NULL; /* FINISHME: implement this */
906 } else if (strcmp(callee, "pow") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700907 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700908 } else if (strcmp(callee, "radians") == 0) {
Kenneth Graunke0afe3492010-07-21 17:58:03 -0700909 assert(op[0]->type->is_float());
910 for (unsigned c = 0; c < op[0]->type->components(); c++)
911 data.f[c] = M_PI/180.0 * op[0]->value.f[c];
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700912 } else if (strcmp(callee, "reflect") == 0) {
913 return NULL; /* FINISHME: implement this */
914 } else if (strcmp(callee, "refract") == 0) {
915 return NULL; /* FINISHME: implement this */
916 } else if (strcmp(callee, "sign") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700917 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700918 } else if (strcmp(callee, "sin") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700919 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700920 } else if (strcmp(callee, "sinh") == 0) {
Kenneth Graunke5d551da2010-07-21 17:49:56 -0700921 assert(op[0]->type->is_float());
922 for (unsigned c = 0; c < op[0]->type->components(); c++)
923 data.f[c] = sinhf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700924 } else if (strcmp(callee, "smoothstep") == 0) {
925 return NULL; /* FINISHME: implement this */
926 } else if (strcmp(callee, "sqrt") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700927 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700928 } else if (strcmp(callee, "step") == 0) {
929 return NULL; /* FINISHME: implement this */
930 } else if (strcmp(callee, "tan") == 0) {
Kenneth Graunke9c9f8b22010-07-21 17:50:50 -0700931 assert(op[0]->type->is_float());
932 for (unsigned c = 0; c < op[0]->type->components(); c++)
933 data.f[c] = tanf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700934 } else if (strcmp(callee, "tanh") == 0) {
Kenneth Graunke20970f72010-07-21 17:51:23 -0700935 assert(op[0]->type->is_float());
936 for (unsigned c = 0; c < op[0]->type->components(); c++)
937 data.f[c] = tanhf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700938 } else if (strcmp(callee, "transpose") == 0) {
939 return NULL; /* FINISHME: implement this */
940 } else {
941 /* Unsupported builtin - some are not allowed in constant expressions. */
942 return NULL;
943 }
944
945 if (expr != NULL)
946 return expr->constant_expression_value();
947
948 return new(mem_ctx) ir_constant(this->type, &data);
949}