blob: 799bd4a60b7b1bae3261c6533b920e8a6dce5e15 [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());
Kenneth Graunke4b1d77e2010-07-21 18:18:16 -0700330 assert(op[0]->type->is_float() && op[1]->type->is_float());
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700331 data.f[0] = 0;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700332 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke4b1d77e2010-07-21 18:18:16 -0700333 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700334 }
335
336 break;
Kenneth Graunke79fed372010-07-09 11:53:56 -0700337 case ir_binop_min:
338 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
339 for (unsigned c = 0, c0 = 0, c1 = 0;
340 c < components;
341 c0 += c0_inc, c1 += c1_inc, c++) {
342
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700343 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700344 case GLSL_TYPE_UINT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700345 data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700346 break;
347 case GLSL_TYPE_INT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700348 data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700349 break;
350 case GLSL_TYPE_FLOAT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700351 data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700352 break;
353 default:
354 assert(0);
355 }
356 }
357
358 break;
359 case ir_binop_max:
360 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
361 for (unsigned c = 0, c0 = 0, c1 = 0;
362 c < components;
363 c0 += c0_inc, c1 += c1_inc, c++) {
364
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700365 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700366 case GLSL_TYPE_UINT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700367 data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700368 break;
369 case GLSL_TYPE_INT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700370 data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700371 break;
372 case GLSL_TYPE_FLOAT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700373 data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700374 break;
375 default:
376 assert(0);
377 }
378 }
Kenneth Graunke79fed372010-07-09 11:53:56 -0700379 break;
Eric Anholt9be7f632010-07-13 15:37:57 -0700380
381 case ir_binop_cross:
382 assert(op[0]->type == glsl_type::vec3_type);
383 assert(op[1]->type == glsl_type::vec3_type);
384 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
385 op[1]->value.f[1] * op[0]->value.f[2]);
386 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
387 op[1]->value.f[2] * op[0]->value.f[0]);
388 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
389 op[1]->value.f[0] * op[0]->value.f[1]);
390 break;
391
Eric Anholtd251b922010-04-01 18:35:42 -1000392 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700393 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
394 for (unsigned c = 0, c0 = 0, c1 = 0;
395 c < components;
396 c0 += c0_inc, c1 += c1_inc, c++) {
397
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700398 switch (op[0]->type->base_type) {
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700399 case GLSL_TYPE_UINT:
400 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
401 break;
402 case GLSL_TYPE_INT:
403 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
404 break;
405 case GLSL_TYPE_FLOAT:
406 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
407 break;
408 default:
409 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000410 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700411 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700412
Eric Anholtd251b922010-04-01 18:35:42 -1000413 break;
414 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700415 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
416 for (unsigned c = 0, c0 = 0, c1 = 0;
417 c < components;
418 c0 += c0_inc, c1 += c1_inc, c++) {
419
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700420 switch (op[0]->type->base_type) {
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700421 case GLSL_TYPE_UINT:
422 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
423 break;
424 case GLSL_TYPE_INT:
425 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
426 break;
427 case GLSL_TYPE_FLOAT:
428 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
429 break;
430 default:
431 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000432 }
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700433 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700434
Eric Anholtd251b922010-04-01 18:35:42 -1000435 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000436 case ir_binop_mul:
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700437 /* Check for equal types, or unequal types involving scalars */
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700438 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
439 || op0_scalar || op1_scalar) {
440 for (unsigned c = 0, c0 = 0, c1 = 0;
441 c < components;
442 c0 += c0_inc, c1 += c1_inc, c++) {
443
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700444 switch (op[0]->type->base_type) {
Eric Anholtd98da972010-04-01 18:25:11 -1000445 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700446 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000447 break;
448 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700449 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000450 break;
451 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700452 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000453 break;
454 default:
455 assert(0);
456 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000457 }
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700458 } else {
459 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
460
461 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
462 * matrix can be a GLSL vector, either N or P can be 1.
463 *
464 * For vec*mat, the vector is treated as a row vector. This
465 * means the vector is a 1-row x M-column matrix.
466 *
467 * For mat*vec, the vector is treated as a column vector. Since
468 * matrix_columns is 1 for vectors, this just works.
469 */
470 const unsigned n = op[0]->type->is_vector()
471 ? 1 : op[0]->type->vector_elements;
472 const unsigned m = op[1]->type->vector_elements;
473 const unsigned p = op[1]->type->matrix_columns;
474 for (unsigned j = 0; j < p; j++) {
475 for (unsigned i = 0; i < n; i++) {
476 for (unsigned k = 0; k < m; k++) {
477 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
478 }
479 }
480 }
481 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700482
Eric Anholta576f9d2010-03-31 16:25:12 -1000483 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000484 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700485 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
486 for (unsigned c = 0, c0 = 0, c1 = 0;
487 c < components;
488 c0 += c0_inc, c1 += c1_inc, c++) {
489
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700490 switch (op[0]->type->base_type) {
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700491 case GLSL_TYPE_UINT:
492 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
493 break;
494 case GLSL_TYPE_INT:
495 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
496 break;
497 case GLSL_TYPE_FLOAT:
498 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
499 break;
500 default:
501 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000502 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700503 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700504
Eric Anholtd251b922010-04-01 18:35:42 -1000505 break;
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700506 case ir_binop_mod:
507 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
508 for (unsigned c = 0, c0 = 0, c1 = 0;
509 c < components;
510 c0 += c0_inc, c1 += c1_inc, c++) {
511
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700512 switch (op[0]->type->base_type) {
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700513 case GLSL_TYPE_UINT:
514 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
515 break;
516 case GLSL_TYPE_INT:
517 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
518 break;
519 case GLSL_TYPE_FLOAT:
520 /* We don't use fmod because it rounds toward zero; GLSL specifies
521 * the use of floor.
522 */
Kenneth Graunke3e882ec2010-07-22 17:44:34 -0700523 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700524 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
525 break;
526 default:
527 assert(0);
528 }
529 }
530
531 break;
532
Eric Anholta576f9d2010-03-31 16:25:12 -1000533 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700534 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700535 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700536 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000537 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000538 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700539 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700540 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700541 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000542 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000543 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700544 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700545 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700546 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000547 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700548
549 case ir_binop_less:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700550 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700551 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700552 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700553 break;
554 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700555 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700556 break;
557 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700558 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700559 break;
560 default:
561 assert(0);
562 }
563 break;
564 case ir_binop_greater:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700565 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700566 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700567 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700568 break;
569 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700570 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700571 break;
572 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700573 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700574 break;
575 default:
576 assert(0);
577 }
578 break;
579 case ir_binop_lequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700580 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700581 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700582 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700583 break;
584 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700585 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700586 break;
587 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700588 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700589 break;
590 default:
591 assert(0);
592 }
593 break;
594 case ir_binop_gequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700595 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700596 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700597 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700598 break;
599 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700600 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700601 break;
602 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700603 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700604 break;
605 default:
606 assert(0);
607 }
608 break;
609
Eric Anholtec1949e2010-04-06 10:02:27 -0700610 case ir_binop_equal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700611 data.b[0] = op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700612 break;
613 case ir_binop_nequal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700614 data.b[0] = !op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700615 break;
616
Eric Anholta576f9d2010-03-31 16:25:12 -1000617 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700618 /* FINISHME: Should handle all expression types. */
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700619 return NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000620 }
Eric Anholtd98da972010-04-01 18:25:11 -1000621
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700622 return new(ctx) ir_constant(this->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700623}
624
625
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700626ir_constant *
627ir_texture::constant_expression_value()
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700628{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700629 /* texture lookups aren't constant expressions */
630 return NULL;
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700631}
632
633
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700634ir_constant *
635ir_swizzle::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700636{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700637 ir_constant *v = this->val->constant_expression_value();
Ian Romanickc2ba6192010-06-11 12:30:28 -0700638
Ian Romanickc2ba6192010-06-11 12:30:28 -0700639 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700640 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700641
642 const unsigned swiz_idx[4] = {
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700643 this->mask.x, this->mask.y, this->mask.z, this->mask.w
Ian Romanickc2ba6192010-06-11 12:30:28 -0700644 };
645
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700646 for (unsigned i = 0; i < this->mask.num_components; i++) {
Ian Romanickc2ba6192010-06-11 12:30:28 -0700647 switch (v->type->base_type) {
648 case GLSL_TYPE_UINT:
649 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
650 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
651 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
652 default: assert(!"Should not get here."); break;
653 }
654 }
655
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700656 void *ctx = talloc_parent(this);
657 return new(ctx) ir_constant(this->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700658 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700659 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700660}
661
662
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700663ir_constant *
664ir_dereference_variable::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700665{
Eric Anholt54f583a2010-07-27 12:10:50 -0700666 /* This may occur during compile and var->type is glsl_type::error_type */
667 if (!var)
668 return NULL;
669
Kenneth Graunkee4768ee2010-07-15 10:27:53 -0700670 return var->constant_value ? var->constant_value->clone(NULL) : NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200671}
672
673
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700674ir_constant *
675ir_dereference_array::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200676{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700677 void *ctx = talloc_parent(this);
678 ir_constant *array = this->array->constant_expression_value();
679 ir_constant *idx = this->array_index->constant_expression_value();
Ian Romanick9b92af92010-06-11 12:20:12 -0700680
Ian Romanick9b92af92010-06-11 12:20:12 -0700681 if ((array != NULL) && (idx != NULL)) {
682 if (array->type->is_matrix()) {
683 /* Array access of a matrix results in a vector.
684 */
685 const unsigned column = idx->value.u[0];
686
687 const glsl_type *const column_type = array->type->column_type();
688
689 /* Offset in the constant matrix to the first element of the column
690 * to be extracted.
691 */
692 const unsigned mat_idx = column * column_type->vector_elements;
693
Ian Romanick0bb70a32010-06-11 15:49:49 -0700694 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700695
696 switch (column_type->base_type) {
697 case GLSL_TYPE_UINT:
698 case GLSL_TYPE_INT:
699 for (unsigned i = 0; i < column_type->vector_elements; i++)
700 data.u[i] = array->value.u[mat_idx + i];
701
702 break;
703
704 case GLSL_TYPE_FLOAT:
705 for (unsigned i = 0; i < column_type->vector_elements; i++)
706 data.f[i] = array->value.f[mat_idx + i];
707
708 break;
709
710 default:
711 assert(!"Should not get here.");
712 break;
713 }
714
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700715 return new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700716 } else if (array->type->is_vector()) {
717 const unsigned component = idx->value.u[0];
718
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700719 return new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700720 } else {
Kenneth Graunkea096fa72010-07-20 01:31:29 -0700721 const unsigned index = idx->value.u[0];
722 return array->get_array_element(index)->clone(NULL);
Ian Romanick9b92af92010-06-11 12:20:12 -0700723 }
724 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700725 return NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200726}
727
728
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700729ir_constant *
730ir_dereference_record::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200731{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700732 ir_constant *v = this->record->constant_expression_value();
Ian Romanick253dede2010-06-09 17:30:19 -0700733
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700734 return (v != NULL) ? v->get_record_field(this->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700735}
736
737
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700738ir_constant *
739ir_assignment::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700740{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700741 /* FINISHME: Handle CEs involving assignment (return RHS) */
742 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700743}
744
745
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700746ir_constant *
747ir_constant::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700748{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700749 return this;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700750}
751
752
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700753ir_constant *
754ir_call::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700755{
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700756 if (this->type == glsl_type::error_type)
757 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700758
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700759 /* From the GLSL 1.20 spec, page 23:
760 * "Function calls to user-defined functions (non-built-in functions)
761 * cannot be used to form constant expressions."
762 */
763 if (!this->callee->is_built_in)
764 return NULL;
765
766 unsigned num_parameters = 0;
767
768 /* Check if all parameters are constant */
769 ir_constant *op[3];
770 foreach_list(n, &this->actual_parameters) {
771 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
772 if (constant == NULL)
773 return NULL;
774
775 op[num_parameters] = constant;
776
777 assert(num_parameters < 3);
778 num_parameters++;
779 }
780
781 /* Individual cases below can either:
782 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
783 * - Fill "data" with appopriate constant data
784 * - Return an ir_constant directly.
785 */
786 void *mem_ctx = talloc_parent(this);
787 ir_expression *expr = NULL;
788
789 ir_constant_data data;
790 memset(&data, 0, sizeof(data));
791
792 const char *callee = this->callee_name();
793 if (strcmp(callee, "abs") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700794 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700795 } else if (strcmp(callee, "all") == 0) {
Kenneth Graunkeaca7e952010-07-21 17:34:32 -0700796 assert(op[0]->type->is_boolean());
797 for (unsigned c = 0; c < op[0]->type->components(); c++) {
798 if (!op[0]->value.b[c])
799 return new(mem_ctx) ir_constant(false);
800 }
801 return new(mem_ctx) ir_constant(true);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700802 } else if (strcmp(callee, "any") == 0) {
Kenneth Graunked6792a72010-07-21 17:35:52 -0700803 assert(op[0]->type->is_boolean());
804 for (unsigned c = 0; c < op[0]->type->components(); c++) {
805 if (op[0]->value.b[c])
806 return new(mem_ctx) ir_constant(true);
807 }
808 return new(mem_ctx) ir_constant(false);
Kenneth Graunkef6ea9df2010-07-21 17:39:47 -0700809 } else if (strcmp(callee, "acos") == 0) {
810 assert(op[0]->type->is_float());
811 for (unsigned c = 0; c < op[0]->type->components(); c++)
812 data.f[c] = acosf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700813 } else if (strcmp(callee, "asin") == 0) {
Kenneth Graunke3b6c29b2010-07-21 17:38:38 -0700814 assert(op[0]->type->is_float());
815 for (unsigned c = 0; c < op[0]->type->components(); c++)
816 data.f[c] = asinf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700817 } else if (strcmp(callee, "atan") == 0) {
Kenneth Graunke13f87582010-07-21 17:42:23 -0700818 assert(op[0]->type->is_float());
819 if (num_parameters == 2) {
820 assert(op[1]->type->is_float());
821 for (unsigned c = 0; c < op[0]->type->components(); c++)
822 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
823 } else {
824 for (unsigned c = 0; c < op[0]->type->components(); c++)
825 data.f[c] = atanf(op[0]->value.f[c]);
826 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700827 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
Kenneth Graunke38cb1b22010-07-21 16:57:10 -0700828 return ir_constant::zero(mem_ctx, this->type);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700829 } else if (strcmp(callee, "ceil") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700830 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700831 } else if (strcmp(callee, "clamp") == 0) {
832 return NULL; /* FINISHME: implement this */
833 } else if (strcmp(callee, "cos") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700834 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700835 } else if (strcmp(callee, "cosh") == 0) {
Kenneth Graunkeba417832010-07-21 17:47:55 -0700836 assert(op[0]->type->is_float());
837 for (unsigned c = 0; c < op[0]->type->components(); c++)
838 data.f[c] = coshf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700839 } else if (strcmp(callee, "cross") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700840 expr = new(mem_ctx) ir_expression(ir_binop_cross, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700841 } else if (strcmp(callee, "degrees") == 0) {
Kenneth Graunke7bcaa382010-07-21 17:59:00 -0700842 assert(op[0]->type->is_float());
843 for (unsigned c = 0; c < op[0]->type->components(); c++)
844 data.f[c] = 180.0/M_PI * op[0]->value.f[c];
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700845 } else if (strcmp(callee, "distance") == 0) {
Kenneth Graunke2eaf3162010-07-21 18:01:22 -0700846 assert(op[0]->type->is_float() && op[1]->type->is_float());
847 float length_squared = 0.0;
848 for (unsigned c = 0; c < op[0]->type->components(); c++) {
849 float t = op[0]->value.f[c] - op[1]->value.f[c];
850 length_squared += t * t;
851 }
852 return new(mem_ctx) ir_constant(sqrtf(length_squared));
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700853 } else if (strcmp(callee, "dot") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700854 expr = new(mem_ctx) ir_expression(ir_binop_dot, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700855 } else if (strcmp(callee, "equal") == 0) {
Kenneth Graunke0b6ef6e2010-07-21 18:04:22 -0700856 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
857 for (unsigned c = 0; c < op[0]->type->components(); c++) {
858 switch (op[0]->type->base_type) {
859 case GLSL_TYPE_UINT:
860 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
861 break;
862 case GLSL_TYPE_INT:
863 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
864 break;
865 case GLSL_TYPE_FLOAT:
866 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
867 break;
868 default:
869 assert(!"Should not get here.");
870 }
871 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700872 } else if (strcmp(callee, "exp") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700873 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700874 } else if (strcmp(callee, "exp2") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700875 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700876 } else if (strcmp(callee, "faceforward") == 0) {
877 return NULL; /* FINISHME: implement this */
878 } else if (strcmp(callee, "floor") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700879 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700880 } else if (strcmp(callee, "fract") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700881 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700882 } else if (strcmp(callee, "fwidth") == 0) {
Kenneth Graunke38cb1b22010-07-21 16:57:10 -0700883 return ir_constant::zero(mem_ctx, this->type);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700884 } else if (strcmp(callee, "greaterThan") == 0) {
Kenneth Graunke7f042b92010-07-21 18:07:43 -0700885 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
886 for (unsigned c = 0; c < op[0]->type->components(); c++) {
887 switch (op[0]->type->base_type) {
888 case GLSL_TYPE_UINT:
889 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
890 break;
891 case GLSL_TYPE_INT:
892 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
893 break;
894 case GLSL_TYPE_FLOAT:
895 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
896 break;
897 default:
898 assert(!"Should not get here.");
899 }
900 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700901 } else if (strcmp(callee, "greaterThanEqual") == 0) {
Kenneth Graunke55782732010-07-21 18:08:05 -0700902 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
903 for (unsigned c = 0; c < op[0]->type->components(); c++) {
904 switch (op[0]->type->base_type) {
905 case GLSL_TYPE_UINT:
906 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
907 break;
908 case GLSL_TYPE_INT:
909 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
910 break;
911 case GLSL_TYPE_FLOAT:
912 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
913 break;
914 default:
915 assert(!"Should not get here.");
916 }
917 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700918 } else if (strcmp(callee, "inversesqrt") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700919 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700920 } else if (strcmp(callee, "length") == 0) {
921 return NULL; /* FINISHME: implement this */
922 } else if (strcmp(callee, "lessThan") == 0) {
Kenneth Graunke6d897f02010-07-21 18:06:18 -0700923 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
924 for (unsigned c = 0; c < op[0]->type->components(); c++) {
925 switch (op[0]->type->base_type) {
926 case GLSL_TYPE_UINT:
927 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
928 break;
929 case GLSL_TYPE_INT:
930 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
931 break;
932 case GLSL_TYPE_FLOAT:
933 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
934 break;
935 default:
936 assert(!"Should not get here.");
937 }
938 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700939 } else if (strcmp(callee, "lessThanEqual") == 0) {
Kenneth Graunke319f4942010-07-21 18:07:09 -0700940 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
941 for (unsigned c = 0; c < op[0]->type->components(); c++) {
942 switch (op[0]->type->base_type) {
943 case GLSL_TYPE_UINT:
944 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
945 break;
946 case GLSL_TYPE_INT:
947 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
948 break;
949 case GLSL_TYPE_FLOAT:
950 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
951 break;
952 default:
953 assert(!"Should not get here.");
954 }
955 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700956 } else if (strcmp(callee, "log") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700957 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700958 } else if (strcmp(callee, "log2") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700959 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700960 } else if (strcmp(callee, "matrixCompMult") == 0) {
961 return NULL; /* FINISHME: implement this */
962 } else if (strcmp(callee, "max") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700963 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700964 } else if (strcmp(callee, "min") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700965 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700966 } else if (strcmp(callee, "mix") == 0) {
967 return NULL; /* FINISHME: implement this */
968 } else if (strcmp(callee, "mod") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700969 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700970 } else if (strcmp(callee, "normalize") == 0) {
971 return NULL; /* FINISHME: implement this */
972 } else if (strcmp(callee, "not") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700973 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700974 } else if (strcmp(callee, "notEqual") == 0) {
Kenneth Graunke48a69ba2010-07-21 18:05:36 -0700975 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
976 for (unsigned c = 0; c < op[0]->type->components(); c++) {
977 switch (op[0]->type->base_type) {
978 case GLSL_TYPE_UINT:
979 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
980 break;
981 case GLSL_TYPE_INT:
982 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
983 break;
984 case GLSL_TYPE_FLOAT:
985 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
986 break;
987 default:
988 assert(!"Should not get here.");
989 }
990 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700991 } else if (strcmp(callee, "outerProduct") == 0) {
992 return NULL; /* FINISHME: implement this */
993 } else if (strcmp(callee, "pow") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700994 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700995 } else if (strcmp(callee, "radians") == 0) {
Kenneth Graunke0afe3492010-07-21 17:58:03 -0700996 assert(op[0]->type->is_float());
997 for (unsigned c = 0; c < op[0]->type->components(); c++)
998 data.f[c] = M_PI/180.0 * op[0]->value.f[c];
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700999 } else if (strcmp(callee, "reflect") == 0) {
1000 return NULL; /* FINISHME: implement this */
1001 } else if (strcmp(callee, "refract") == 0) {
1002 return NULL; /* FINISHME: implement this */
1003 } else if (strcmp(callee, "sign") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001004 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001005 } else if (strcmp(callee, "sin") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001006 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001007 } else if (strcmp(callee, "sinh") == 0) {
Kenneth Graunke5d551da2010-07-21 17:49:56 -07001008 assert(op[0]->type->is_float());
1009 for (unsigned c = 0; c < op[0]->type->components(); c++)
1010 data.f[c] = sinhf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001011 } else if (strcmp(callee, "smoothstep") == 0) {
1012 return NULL; /* FINISHME: implement this */
1013 } else if (strcmp(callee, "sqrt") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001014 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001015 } else if (strcmp(callee, "step") == 0) {
1016 return NULL; /* FINISHME: implement this */
1017 } else if (strcmp(callee, "tan") == 0) {
Kenneth Graunke9c9f8b22010-07-21 17:50:50 -07001018 assert(op[0]->type->is_float());
1019 for (unsigned c = 0; c < op[0]->type->components(); c++)
1020 data.f[c] = tanf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001021 } else if (strcmp(callee, "tanh") == 0) {
Kenneth Graunke20970f72010-07-21 17:51:23 -07001022 assert(op[0]->type->is_float());
1023 for (unsigned c = 0; c < op[0]->type->components(); c++)
1024 data.f[c] = tanhf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001025 } else if (strcmp(callee, "transpose") == 0) {
1026 return NULL; /* FINISHME: implement this */
1027 } else {
1028 /* Unsupported builtin - some are not allowed in constant expressions. */
1029 return NULL;
1030 }
1031
1032 if (expr != NULL)
1033 return expr->constant_expression_value();
1034
1035 return new(mem_ctx) ir_constant(this->type, &data);
1036}