blob: 5bef17c7554eedfec5dd8b1ba45a4f7295bc139b [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>
Ian Romanick1cf43a42010-03-30 16:56:50 -070037#include "ir.h"
38#include "ir_visitor.h"
Eric Anholta576f9d2010-03-31 16:25:12 -100039#include "glsl_types.h"
Ian Romanick1cf43a42010-03-30 16:56:50 -070040
Kenneth Graunke79fed372010-07-09 11:53:56 -070041#define min(x,y) (x) < (y) ? (x) : (y)
42#define max(x,y) (x) > (y) ? (x) : (y)
43
Ian Romanick1cf43a42010-03-30 16:56:50 -070044ir_constant *
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -070045ir_expression::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -070046{
Kenneth Graunke6bc432e2010-07-02 17:12:23 -070047 ir_constant *op[2] = { NULL, NULL };
Ian Romanick4daaab62010-06-11 16:08:47 -070048 ir_constant_data data;
Eric Anholt160d0922010-04-01 18:07:08 -100049
Kenneth Graunkec63a1db2010-07-05 22:33:35 -070050 memset(&data, 0, sizeof(data));
51
Kenneth Graunke98f32a12010-07-15 10:20:51 -070052 for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
53 op[operand] = this->operands[operand]->constant_expression_value();
Eric Anholtd98da972010-04-01 18:25:11 -100054 if (!op[operand])
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -070055 return NULL;
Eric Anholt160d0922010-04-01 18:07:08 -100056 }
Eric Anholta576f9d2010-03-31 16:25:12 -100057
Kenneth Graunke6fc983b2010-07-06 02:39:57 -070058 if (op[1] != NULL)
59 assert(op[0]->type->base_type == op[1]->type->base_type);
60
Kenneth Graunkee74dcd72010-07-06 02:48:16 -070061 bool op0_scalar = op[0]->type->is_scalar();
62 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
63
64 /* When iterating over a vector or matrix's components, we want to increase
65 * the loop counter. However, for scalars, we want to stay at 0.
66 */
Kenneth Graunkeacf88f22010-07-07 12:08:23 -070067 unsigned c0_inc = op0_scalar ? 0 : 1;
68 unsigned c1_inc = op1_scalar ? 0 : 1;
Eric Anholt570dc0d2010-07-07 09:07:09 -070069 unsigned components;
70 if (op1_scalar || !op[1]) {
71 components = op[0]->type->components();
72 } else {
73 components = op[1]->type->components();
74 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -070075
Kenneth Graunke9a6d40f2010-07-20 03:08:32 -070076 void *ctx = talloc_parent(this);
77
78 /* Handle array operations here, rather than below. */
79 if (op[0]->type->is_array()) {
80 assert(op[1] != NULL && op[1]->type->is_array());
81 switch (this->operation) {
82 case ir_binop_equal:
83 return new(ctx) ir_constant(op[0]->has_value(op[1]));
84 case ir_binop_nequal:
85 return new(ctx) ir_constant(!op[0]->has_value(op[1]));
86 default:
87 break;
88 }
89 return NULL;
90 }
91
Kenneth Graunke98f32a12010-07-15 10:20:51 -070092 switch (this->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -100093 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -070094 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -070095 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -070096 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -100097 break;
Eric Anholtaf186412010-04-06 10:53:57 -070098
99 case ir_unop_f2i:
100 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700101 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700102 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700103 }
104 break;
105 case ir_unop_i2f:
Kenneth Graunke46d6b8d2010-07-20 13:01:56 -0700106 assert(op[0]->type->base_type == GLSL_TYPE_INT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700107 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke46d6b8d2010-07-20 13:01:56 -0700108 data.f[c] = op[0]->value.i[c];
109 }
110 break;
111 case ir_unop_u2f:
112 assert(op[0]->type->base_type == GLSL_TYPE_UINT);
113 for (unsigned c = 0; c < op[0]->type->components(); c++) {
114 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700115 }
116 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700117 case ir_unop_b2f:
118 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700119 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700120 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700121 }
122 break;
123 case ir_unop_f2b:
124 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700125 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700126 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700127 }
128 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700129 case ir_unop_b2i:
130 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700131 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700132 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700133 }
134 break;
135 case ir_unop_i2b:
136 assert(op[0]->type->is_integer());
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700137 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700138 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700139 }
140 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700141
Kenneth Graunke323d9092010-07-08 23:21:36 -0700142 case ir_unop_trunc:
143 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700144 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke323d9092010-07-08 23:21:36 -0700145 data.f[c] = truncf(op[0]->value.f[c]);
146 }
147 break;
148
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700149 case ir_unop_ceil:
150 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700151 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700152 data.f[c] = ceilf(op[0]->value.f[c]);
153 }
154 break;
155
Kenneth Graunke07472042010-07-08 23:23:23 -0700156 case ir_unop_floor:
157 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700158 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke07472042010-07-08 23:23:23 -0700159 data.f[c] = floorf(op[0]->value.f[c]);
160 }
161 break;
162
Eric Anholtd925c912010-07-01 10:37:11 -0700163 case ir_unop_fract:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700164 for (unsigned c = 0; c < op[0]->type->components(); c++) {
165 switch (this->type->base_type) {
Eric Anholtd925c912010-07-01 10:37:11 -0700166 case GLSL_TYPE_UINT:
167 data.u[c] = 0;
168 break;
169 case GLSL_TYPE_INT:
170 data.i[c] = 0;
171 break;
172 case GLSL_TYPE_FLOAT:
173 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
174 break;
175 default:
176 assert(0);
177 }
178 }
179 break;
180
Kenneth Graunke908afd12010-07-08 23:28:50 -0700181 case ir_unop_sin:
182 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700183 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke908afd12010-07-08 23:28:50 -0700184 data.f[c] = sinf(op[0]->value.f[c]);
185 }
186 break;
187
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700188 case ir_unop_cos:
189 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700190 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700191 data.f[c] = cosf(op[0]->value.f[c]);
192 }
193 break;
194
Eric Anholt43ad37a2010-05-12 14:42:21 -0700195 case ir_unop_neg:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700196 for (unsigned c = 0; c < op[0]->type->components(); c++) {
197 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700198 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700199 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700200 break;
201 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700202 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700203 break;
204 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700205 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700206 break;
207 default:
208 assert(0);
209 }
210 }
211 break;
212
213 case ir_unop_abs:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700214 for (unsigned c = 0; c < op[0]->type->components(); c++) {
215 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700216 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700217 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700218 break;
219 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700220 data.i[c] = op[0]->value.i[c];
221 if (data.i[c] < 0)
222 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700223 break;
224 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700225 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700226 break;
227 default:
228 assert(0);
229 }
230 }
231 break;
232
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700233 case ir_unop_sign:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700234 for (unsigned c = 0; c < op[0]->type->components(); c++) {
235 switch (this->type->base_type) {
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700236 case GLSL_TYPE_UINT:
237 data.u[c] = op[0]->value.i[c] > 0;
238 break;
239 case GLSL_TYPE_INT:
240 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
241 break;
242 case GLSL_TYPE_FLOAT:
243 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
244 break;
245 default:
246 assert(0);
247 }
248 }
249 break;
250
Eric Anholt43ad37a2010-05-12 14:42:21 -0700251 case ir_unop_rcp:
252 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700253 for (unsigned c = 0; c < op[0]->type->components(); c++) {
254 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700255 case GLSL_TYPE_UINT:
256 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700257 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700258 break;
259 case GLSL_TYPE_INT:
260 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700261 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700262 break;
263 case GLSL_TYPE_FLOAT:
264 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700265 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700266 break;
267 default:
268 assert(0);
269 }
270 }
271 break;
272
273 case ir_unop_rsq:
274 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700275 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700276 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700277 }
278 break;
279
280 case ir_unop_sqrt:
281 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700282 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700283 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700284 }
285 break;
286
287 case ir_unop_exp:
288 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700289 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700290 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700291 }
292 break;
293
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700294 case ir_unop_exp2:
295 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700296 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700297 data.f[c] = exp2f(op[0]->value.f[c]);
298 }
299 break;
300
Eric Anholt43ad37a2010-05-12 14:42:21 -0700301 case ir_unop_log:
302 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700303 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700304 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700305 }
306 break;
307
Kenneth Graunkecb639292010-07-08 23:18:09 -0700308 case ir_unop_log2:
309 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700310 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkecb639292010-07-08 23:18:09 -0700311 data.f[c] = log2f(op[0]->value.f[c]);
312 }
313 break;
314
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700315 case ir_unop_dFdx:
316 case ir_unop_dFdy:
317 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700318 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700319 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700320 }
321 break;
322
Kenneth Graunke891a0642010-07-08 23:35:09 -0700323 case ir_binop_pow:
324 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700325 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke891a0642010-07-08 23:35:09 -0700326 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
327 }
328 break;
329
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700330 case ir_binop_dot:
331 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
332 data.f[0] = 0;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700333 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700334 switch (op[0]->type->base_type) {
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700335 case GLSL_TYPE_UINT:
336 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
337 break;
338 case GLSL_TYPE_INT:
339 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
340 break;
341 case GLSL_TYPE_FLOAT:
342 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
343 break;
344 default:
345 assert(0);
346 }
347 }
348
349 break;
Kenneth Graunke79fed372010-07-09 11:53:56 -0700350 case ir_binop_min:
351 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
352 for (unsigned c = 0, c0 = 0, c1 = 0;
353 c < components;
354 c0 += c0_inc, c1 += c1_inc, c++) {
355
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700356 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700357 case GLSL_TYPE_UINT:
358 data.u[c] = min(op[0]->value.u[c0], op[1]->value.u[c1]);
359 break;
360 case GLSL_TYPE_INT:
361 data.i[c] = min(op[0]->value.i[c0], op[1]->value.i[c1]);
362 break;
363 case GLSL_TYPE_FLOAT:
364 data.f[c] = min(op[0]->value.f[c0], op[1]->value.f[c1]);
365 break;
366 default:
367 assert(0);
368 }
369 }
370
371 break;
372 case ir_binop_max:
373 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
374 for (unsigned c = 0, c0 = 0, c1 = 0;
375 c < components;
376 c0 += c0_inc, c1 += c1_inc, c++) {
377
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700378 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700379 case GLSL_TYPE_UINT:
380 data.u[c] = max(op[0]->value.u[c0], op[1]->value.u[c1]);
381 break;
382 case GLSL_TYPE_INT:
383 data.i[c] = max(op[0]->value.i[c0], op[1]->value.i[c1]);
384 break;
385 case GLSL_TYPE_FLOAT:
386 data.f[c] = max(op[0]->value.f[c0], op[1]->value.f[c1]);
387 break;
388 default:
389 assert(0);
390 }
391 }
Kenneth Graunke79fed372010-07-09 11:53:56 -0700392 break;
Eric Anholt9be7f632010-07-13 15:37:57 -0700393
394 case ir_binop_cross:
395 assert(op[0]->type == glsl_type::vec3_type);
396 assert(op[1]->type == glsl_type::vec3_type);
397 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
398 op[1]->value.f[1] * op[0]->value.f[2]);
399 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
400 op[1]->value.f[2] * op[0]->value.f[0]);
401 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
402 op[1]->value.f[0] * op[0]->value.f[1]);
403 break;
404
Eric Anholtd251b922010-04-01 18:35:42 -1000405 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700406 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
407 for (unsigned c = 0, c0 = 0, c1 = 0;
408 c < components;
409 c0 += c0_inc, c1 += c1_inc, c++) {
410
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700411 switch (op[0]->type->base_type) {
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700412 case GLSL_TYPE_UINT:
413 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
414 break;
415 case GLSL_TYPE_INT:
416 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
417 break;
418 case GLSL_TYPE_FLOAT:
419 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
420 break;
421 default:
422 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000423 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700424 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700425
Eric Anholtd251b922010-04-01 18:35:42 -1000426 break;
427 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700428 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
429 for (unsigned c = 0, c0 = 0, c1 = 0;
430 c < components;
431 c0 += c0_inc, c1 += c1_inc, c++) {
432
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700433 switch (op[0]->type->base_type) {
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700434 case GLSL_TYPE_UINT:
435 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
436 break;
437 case GLSL_TYPE_INT:
438 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
439 break;
440 case GLSL_TYPE_FLOAT:
441 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
442 break;
443 default:
444 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000445 }
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700446 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700447
Eric Anholtd251b922010-04-01 18:35:42 -1000448 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000449 case ir_binop_mul:
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700450 /* Check for equal types, or unequal types involving scalars */
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700451 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
452 || op0_scalar || op1_scalar) {
453 for (unsigned c = 0, c0 = 0, c1 = 0;
454 c < components;
455 c0 += c0_inc, c1 += c1_inc, c++) {
456
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700457 switch (op[0]->type->base_type) {
Eric Anholtd98da972010-04-01 18:25:11 -1000458 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700459 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000460 break;
461 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700462 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000463 break;
464 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700465 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000466 break;
467 default:
468 assert(0);
469 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000470 }
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700471 } else {
472 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
473
474 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
475 * matrix can be a GLSL vector, either N or P can be 1.
476 *
477 * For vec*mat, the vector is treated as a row vector. This
478 * means the vector is a 1-row x M-column matrix.
479 *
480 * For mat*vec, the vector is treated as a column vector. Since
481 * matrix_columns is 1 for vectors, this just works.
482 */
483 const unsigned n = op[0]->type->is_vector()
484 ? 1 : op[0]->type->vector_elements;
485 const unsigned m = op[1]->type->vector_elements;
486 const unsigned p = op[1]->type->matrix_columns;
487 for (unsigned j = 0; j < p; j++) {
488 for (unsigned i = 0; i < n; i++) {
489 for (unsigned k = 0; k < m; k++) {
490 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
491 }
492 }
493 }
494 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700495
Eric Anholta576f9d2010-03-31 16:25:12 -1000496 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000497 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700498 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
499 for (unsigned c = 0, c0 = 0, c1 = 0;
500 c < components;
501 c0 += c0_inc, c1 += c1_inc, c++) {
502
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700503 switch (op[0]->type->base_type) {
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700504 case GLSL_TYPE_UINT:
505 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
506 break;
507 case GLSL_TYPE_INT:
508 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
509 break;
510 case GLSL_TYPE_FLOAT:
511 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
512 break;
513 default:
514 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000515 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700516 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700517
Eric Anholtd251b922010-04-01 18:35:42 -1000518 break;
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700519 case ir_binop_mod:
520 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
521 for (unsigned c = 0, c0 = 0, c1 = 0;
522 c < components;
523 c0 += c0_inc, c1 += c1_inc, c++) {
524
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700525 switch (op[0]->type->base_type) {
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700526 case GLSL_TYPE_UINT:
527 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
528 break;
529 case GLSL_TYPE_INT:
530 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
531 break;
532 case GLSL_TYPE_FLOAT:
533 /* We don't use fmod because it rounds toward zero; GLSL specifies
534 * the use of floor.
535 */
536 data.f[c] = (op[0]->value.f[c0] - op[1]->value.f[c1])
537 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
538 break;
539 default:
540 assert(0);
541 }
542 }
543
544 break;
545
Eric Anholta576f9d2010-03-31 16:25:12 -1000546 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700547 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700548 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700549 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000550 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000551 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700552 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700553 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700554 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000555 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000556 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700557 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700558 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700559 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000560 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700561
562 case ir_binop_less:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700563 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700564 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700565 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700566 break;
567 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700568 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700569 break;
570 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700571 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700572 break;
573 default:
574 assert(0);
575 }
576 break;
577 case ir_binop_greater:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700578 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700579 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700580 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700581 break;
582 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700583 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700584 break;
585 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700586 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700587 break;
588 default:
589 assert(0);
590 }
591 break;
592 case ir_binop_lequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700593 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700594 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700595 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700596 break;
597 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700598 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700599 break;
600 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700601 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700602 break;
603 default:
604 assert(0);
605 }
606 break;
607 case ir_binop_gequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700608 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700609 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700610 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700611 break;
612 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700613 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700614 break;
615 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700616 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700617 break;
618 default:
619 assert(0);
620 }
621 break;
622
Eric Anholtec1949e2010-04-06 10:02:27 -0700623 case ir_binop_equal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700624 data.b[0] = op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700625 break;
626 case ir_binop_nequal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700627 data.b[0] = !op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700628 break;
629
Eric Anholta576f9d2010-03-31 16:25:12 -1000630 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700631 /* FINISHME: Should handle all expression types. */
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700632 return NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000633 }
Eric Anholtd98da972010-04-01 18:25:11 -1000634
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700635 return new(ctx) ir_constant(this->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700636}
637
638
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700639ir_constant *
640ir_texture::constant_expression_value()
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700641{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700642 /* texture lookups aren't constant expressions */
643 return NULL;
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700644}
645
646
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700647ir_constant *
648ir_swizzle::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700649{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700650 ir_constant *v = this->val->constant_expression_value();
Ian Romanickc2ba6192010-06-11 12:30:28 -0700651
Ian Romanickc2ba6192010-06-11 12:30:28 -0700652 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700653 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700654
655 const unsigned swiz_idx[4] = {
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700656 this->mask.x, this->mask.y, this->mask.z, this->mask.w
Ian Romanickc2ba6192010-06-11 12:30:28 -0700657 };
658
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700659 for (unsigned i = 0; i < this->mask.num_components; i++) {
Ian Romanickc2ba6192010-06-11 12:30:28 -0700660 switch (v->type->base_type) {
661 case GLSL_TYPE_UINT:
662 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
663 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
664 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
665 default: assert(!"Should not get here."); break;
666 }
667 }
668
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700669 void *ctx = talloc_parent(this);
670 return new(ctx) ir_constant(this->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700671 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700672 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700673}
674
675
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700676ir_constant *
677ir_dereference_variable::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700678{
Kenneth Graunkee4768ee2010-07-15 10:27:53 -0700679 return var->constant_value ? var->constant_value->clone(NULL) : NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200680}
681
682
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700683ir_constant *
684ir_dereference_array::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200685{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700686 void *ctx = talloc_parent(this);
687 ir_constant *array = this->array->constant_expression_value();
688 ir_constant *idx = this->array_index->constant_expression_value();
Ian Romanick9b92af92010-06-11 12:20:12 -0700689
Ian Romanick9b92af92010-06-11 12:20:12 -0700690 if ((array != NULL) && (idx != NULL)) {
691 if (array->type->is_matrix()) {
692 /* Array access of a matrix results in a vector.
693 */
694 const unsigned column = idx->value.u[0];
695
696 const glsl_type *const column_type = array->type->column_type();
697
698 /* Offset in the constant matrix to the first element of the column
699 * to be extracted.
700 */
701 const unsigned mat_idx = column * column_type->vector_elements;
702
Ian Romanick0bb70a32010-06-11 15:49:49 -0700703 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700704
705 switch (column_type->base_type) {
706 case GLSL_TYPE_UINT:
707 case GLSL_TYPE_INT:
708 for (unsigned i = 0; i < column_type->vector_elements; i++)
709 data.u[i] = array->value.u[mat_idx + i];
710
711 break;
712
713 case GLSL_TYPE_FLOAT:
714 for (unsigned i = 0; i < column_type->vector_elements; i++)
715 data.f[i] = array->value.f[mat_idx + i];
716
717 break;
718
719 default:
720 assert(!"Should not get here.");
721 break;
722 }
723
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700724 return new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700725 } else if (array->type->is_vector()) {
726 const unsigned component = idx->value.u[0];
727
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700728 return new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700729 } else {
Kenneth Graunkea096fa72010-07-20 01:31:29 -0700730 const unsigned index = idx->value.u[0];
731 return array->get_array_element(index)->clone(NULL);
Ian Romanick9b92af92010-06-11 12:20:12 -0700732 }
733 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700734 return NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200735}
736
737
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700738ir_constant *
739ir_dereference_record::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200740{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700741 ir_constant *v = this->record->constant_expression_value();
Ian Romanick253dede2010-06-09 17:30:19 -0700742
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700743 return (v != NULL) ? v->get_record_field(this->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700744}
745
746
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700747ir_constant *
748ir_assignment::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700749{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700750 /* FINISHME: Handle CEs involving assignment (return RHS) */
751 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700752}
753
754
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700755ir_constant *
756ir_constant::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700757{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700758 return this;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700759}
760
761
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700762ir_constant *
763ir_call::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700764{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700765 /* FINISHME: Handle CEs involving builtin function calls. */
766 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700767}
768