blob: ca834978f471bfd6287618640fea2b4a93b57828 [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 -070044/**
45 * Visitor class for evaluating constant expressions
46 */
47class ir_constant_visitor : public ir_visitor {
48public:
49 ir_constant_visitor()
50 : value(NULL)
51 {
52 /* empty */
53 }
54
55 virtual ~ir_constant_visitor()
56 {
57 /* empty */
58 }
59
60 /**
61 * \name Visit methods
62 *
63 * As typical for the visitor pattern, there must be one \c visit method for
64 * each concrete subclass of \c ir_instruction. Virtual base classes within
65 * the hierarchy should not have \c visit methods.
66 */
67 /*@{*/
68 virtual void visit(ir_variable *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070069 virtual void visit(ir_function_signature *);
70 virtual void visit(ir_function *);
71 virtual void visit(ir_expression *);
Kenneth Graunke26d74cd2010-05-26 17:42:03 -070072 virtual void visit(ir_texture *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070073 virtual void visit(ir_swizzle *);
Ian Romanickc7b10462010-05-19 13:20:12 +020074 virtual void visit(ir_dereference_variable *);
75 virtual void visit(ir_dereference_array *);
76 virtual void visit(ir_dereference_record *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070077 virtual void visit(ir_assignment *);
78 virtual void visit(ir_constant *);
79 virtual void visit(ir_call *);
80 virtual void visit(ir_return *);
Kenneth Graunke16efab12010-06-30 10:47:34 -070081 virtual void visit(ir_discard *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070082 virtual void visit(ir_if *);
Ian Romanickfad607a2010-04-05 16:16:07 -070083 virtual void visit(ir_loop *);
Ian Romanickf8e31e02010-04-05 16:28:15 -070084 virtual void visit(ir_loop_jump *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070085 /*@}*/
86
87 /**
88 * Value of the constant expression.
89 *
90 * \note
91 * This field will be \c NULL if the expression is not constant valued.
92 */
93 /* FINIHSME: This cannot hold values for constant arrays or structures. */
94 ir_constant *value;
95};
96
97
98ir_constant *
99ir_instruction::constant_expression_value()
100{
101 ir_constant_visitor visitor;
102
103 this->accept(& visitor);
104 return visitor.value;
105}
106
107
108void
109ir_constant_visitor::visit(ir_variable *ir)
110{
111 (void) ir;
112 value = NULL;
113}
114
115
116void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700117ir_constant_visitor::visit(ir_function_signature *ir)
118{
119 (void) ir;
120 value = NULL;
121}
122
123
124void
125ir_constant_visitor::visit(ir_function *ir)
126{
127 (void) ir;
128 value = NULL;
129}
130
Ian Romanick1cf43a42010-03-30 16:56:50 -0700131void
132ir_constant_visitor::visit(ir_expression *ir)
133{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700134 value = NULL;
Kenneth Graunke6bc432e2010-07-02 17:12:23 -0700135 ir_constant *op[2] = { NULL, NULL };
Ian Romanick4daaab62010-06-11 16:08:47 -0700136 ir_constant_data data;
Eric Anholt160d0922010-04-01 18:07:08 -1000137
Kenneth Graunkec63a1db2010-07-05 22:33:35 -0700138 memset(&data, 0, sizeof(data));
139
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700140 for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) {
Eric Anholtd98da972010-04-01 18:25:11 -1000141 op[operand] = ir->operands[operand]->constant_expression_value();
142 if (!op[operand])
Eric Anholt160d0922010-04-01 18:07:08 -1000143 return;
144 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000145
Kenneth Graunke6fc983b2010-07-06 02:39:57 -0700146 if (op[1] != NULL)
147 assert(op[0]->type->base_type == op[1]->type->base_type);
148
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700149 bool op0_scalar = op[0]->type->is_scalar();
150 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
151
152 /* When iterating over a vector or matrix's components, we want to increase
153 * the loop counter. However, for scalars, we want to stay at 0.
154 */
Kenneth Graunkeacf88f22010-07-07 12:08:23 -0700155 unsigned c0_inc = op0_scalar ? 0 : 1;
156 unsigned c1_inc = op1_scalar ? 0 : 1;
Eric Anholt570dc0d2010-07-07 09:07:09 -0700157 unsigned components;
158 if (op1_scalar || !op[1]) {
159 components = op[0]->type->components();
160 } else {
161 components = op[1]->type->components();
162 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700163
Eric Anholta576f9d2010-03-31 16:25:12 -1000164 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000165 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700166 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700167 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700168 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000169 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700170
171 case ir_unop_f2i:
172 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700173 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700174 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700175 }
176 break;
177 case ir_unop_i2f:
178 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
179 op[0]->type->base_type == GLSL_TYPE_INT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700180 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Eric Anholtaf186412010-04-06 10:53:57 -0700181 if (op[0]->type->base_type == GLSL_TYPE_INT)
Ian Romanick4daaab62010-06-11 16:08:47 -0700182 data.f[c] = op[0]->value.i[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700183 else
Ian Romanick4daaab62010-06-11 16:08:47 -0700184 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700185 }
186 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700187 case ir_unop_b2f:
188 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700189 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700190 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700191 }
192 break;
193 case ir_unop_f2b:
194 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700195 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700196 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700197 }
198 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700199 case ir_unop_b2i:
200 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700201 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700202 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700203 }
204 break;
205 case ir_unop_i2b:
206 assert(op[0]->type->is_integer());
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700207 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700208 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700209 }
210 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700211
Kenneth Graunke323d9092010-07-08 23:21:36 -0700212 case ir_unop_trunc:
213 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
214 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
215 data.f[c] = truncf(op[0]->value.f[c]);
216 }
217 break;
218
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700219 case ir_unop_ceil:
220 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
221 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
222 data.f[c] = ceilf(op[0]->value.f[c]);
223 }
224 break;
225
Kenneth Graunke07472042010-07-08 23:23:23 -0700226 case ir_unop_floor:
227 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
228 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
229 data.f[c] = floorf(op[0]->value.f[c]);
230 }
231 break;
232
Eric Anholtd925c912010-07-01 10:37:11 -0700233 case ir_unop_fract:
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700234 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Eric Anholtd925c912010-07-01 10:37:11 -0700235 switch (ir->type->base_type) {
236 case GLSL_TYPE_UINT:
237 data.u[c] = 0;
238 break;
239 case GLSL_TYPE_INT:
240 data.i[c] = 0;
241 break;
242 case GLSL_TYPE_FLOAT:
243 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
244 break;
245 default:
246 assert(0);
247 }
248 }
249 break;
250
Kenneth Graunke908afd12010-07-08 23:28:50 -0700251 case ir_unop_sin:
252 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
253 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
254 data.f[c] = sinf(op[0]->value.f[c]);
255 }
256 break;
257
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700258 case ir_unop_cos:
259 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
260 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
261 data.f[c] = cosf(op[0]->value.f[c]);
262 }
263 break;
264
Eric Anholt43ad37a2010-05-12 14:42:21 -0700265 case ir_unop_neg:
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700266 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700267 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700268 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700269 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700270 break;
271 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700272 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700273 break;
274 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700275 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700276 break;
277 default:
278 assert(0);
279 }
280 }
281 break;
282
283 case ir_unop_abs:
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700284 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700285 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700286 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700287 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700288 break;
289 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700290 data.i[c] = op[0]->value.i[c];
291 if (data.i[c] < 0)
292 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700293 break;
294 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700295 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700296 break;
297 default:
298 assert(0);
299 }
300 }
301 break;
302
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700303 case ir_unop_sign:
304 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
305 switch (ir->type->base_type) {
306 case GLSL_TYPE_UINT:
307 data.u[c] = op[0]->value.i[c] > 0;
308 break;
309 case GLSL_TYPE_INT:
310 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
311 break;
312 case GLSL_TYPE_FLOAT:
313 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
314 break;
315 default:
316 assert(0);
317 }
318 }
319 break;
320
Eric Anholt43ad37a2010-05-12 14:42:21 -0700321 case ir_unop_rcp:
322 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700323 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700324 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700325 case GLSL_TYPE_UINT:
326 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700327 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700328 break;
329 case GLSL_TYPE_INT:
330 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700331 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700332 break;
333 case GLSL_TYPE_FLOAT:
334 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700335 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700336 break;
337 default:
338 assert(0);
339 }
340 }
341 break;
342
343 case ir_unop_rsq:
344 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700345 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700346 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700347 }
348 break;
349
350 case ir_unop_sqrt:
351 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700352 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700353 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700354 }
355 break;
356
357 case ir_unop_exp:
358 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700359 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700360 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700361 }
362 break;
363
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700364 case ir_unop_exp2:
365 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
366 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
367 data.f[c] = exp2f(op[0]->value.f[c]);
368 }
369 break;
370
Eric Anholt43ad37a2010-05-12 14:42:21 -0700371 case ir_unop_log:
372 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700373 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700374 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700375 }
376 break;
377
Kenneth Graunkecb639292010-07-08 23:18:09 -0700378 case ir_unop_log2:
379 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
380 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
381 data.f[c] = log2f(op[0]->value.f[c]);
382 }
383 break;
384
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700385 case ir_unop_dFdx:
386 case ir_unop_dFdy:
387 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700388 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700389 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700390 }
391 break;
392
Kenneth Graunke891a0642010-07-08 23:35:09 -0700393 case ir_binop_pow:
394 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
395 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
396 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
397 }
398 break;
399
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700400 case ir_binop_dot:
401 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
402 data.f[0] = 0;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700403 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700404 switch (ir->operands[0]->type->base_type) {
405 case GLSL_TYPE_UINT:
406 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
407 break;
408 case GLSL_TYPE_INT:
409 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
410 break;
411 case GLSL_TYPE_FLOAT:
412 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
413 break;
414 default:
415 assert(0);
416 }
417 }
418
419 break;
Kenneth Graunke79fed372010-07-09 11:53:56 -0700420 case ir_binop_min:
421 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
422 for (unsigned c = 0, c0 = 0, c1 = 0;
423 c < components;
424 c0 += c0_inc, c1 += c1_inc, c++) {
425
426 switch (ir->operands[0]->type->base_type) {
427 case GLSL_TYPE_UINT:
428 data.u[c] = min(op[0]->value.u[c0], op[1]->value.u[c1]);
429 break;
430 case GLSL_TYPE_INT:
431 data.i[c] = min(op[0]->value.i[c0], op[1]->value.i[c1]);
432 break;
433 case GLSL_TYPE_FLOAT:
434 data.f[c] = min(op[0]->value.f[c0], op[1]->value.f[c1]);
435 break;
436 default:
437 assert(0);
438 }
439 }
440
441 break;
442 case ir_binop_max:
443 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
444 for (unsigned c = 0, c0 = 0, c1 = 0;
445 c < components;
446 c0 += c0_inc, c1 += c1_inc, c++) {
447
448 switch (ir->operands[0]->type->base_type) {
449 case GLSL_TYPE_UINT:
450 data.u[c] = max(op[0]->value.u[c0], op[1]->value.u[c1]);
451 break;
452 case GLSL_TYPE_INT:
453 data.i[c] = max(op[0]->value.i[c0], op[1]->value.i[c1]);
454 break;
455 case GLSL_TYPE_FLOAT:
456 data.f[c] = max(op[0]->value.f[c0], op[1]->value.f[c1]);
457 break;
458 default:
459 assert(0);
460 }
461 }
Kenneth Graunke79fed372010-07-09 11:53:56 -0700462 break;
Eric Anholt9be7f632010-07-13 15:37:57 -0700463
464 case ir_binop_cross:
465 assert(op[0]->type == glsl_type::vec3_type);
466 assert(op[1]->type == glsl_type::vec3_type);
467 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
468 op[1]->value.f[1] * op[0]->value.f[2]);
469 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
470 op[1]->value.f[2] * op[0]->value.f[0]);
471 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
472 op[1]->value.f[0] * op[0]->value.f[1]);
473 break;
474
Eric Anholtd251b922010-04-01 18:35:42 -1000475 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700476 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
477 for (unsigned c = 0, c0 = 0, c1 = 0;
478 c < components;
479 c0 += c0_inc, c1 += c1_inc, c++) {
480
481 switch (ir->operands[0]->type->base_type) {
482 case GLSL_TYPE_UINT:
483 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
484 break;
485 case GLSL_TYPE_INT:
486 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
487 break;
488 case GLSL_TYPE_FLOAT:
489 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
490 break;
491 default:
492 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000493 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700494 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700495
Eric Anholtd251b922010-04-01 18:35:42 -1000496 break;
497 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -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
503 switch (ir->operands[0]->type->base_type) {
504 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 Graunke97b44f02010-07-06 02:53:29 -0700516 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700517
Eric Anholtd251b922010-04-01 18:35:42 -1000518 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000519 case ir_binop_mul:
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700520 /* Check for equal types, or unequal types involving scalars */
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700521 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
522 || op0_scalar || op1_scalar) {
523 for (unsigned c = 0, c0 = 0, c1 = 0;
524 c < components;
525 c0 += c0_inc, c1 += c1_inc, c++) {
526
Eric Anholtd98da972010-04-01 18:25:11 -1000527 switch (ir->operands[0]->type->base_type) {
528 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700529 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000530 break;
531 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700532 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000533 break;
534 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700535 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000536 break;
537 default:
538 assert(0);
539 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000540 }
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700541 } else {
542 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
543
544 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
545 * matrix can be a GLSL vector, either N or P can be 1.
546 *
547 * For vec*mat, the vector is treated as a row vector. This
548 * means the vector is a 1-row x M-column matrix.
549 *
550 * For mat*vec, the vector is treated as a column vector. Since
551 * matrix_columns is 1 for vectors, this just works.
552 */
553 const unsigned n = op[0]->type->is_vector()
554 ? 1 : op[0]->type->vector_elements;
555 const unsigned m = op[1]->type->vector_elements;
556 const unsigned p = op[1]->type->matrix_columns;
557 for (unsigned j = 0; j < p; j++) {
558 for (unsigned i = 0; i < n; i++) {
559 for (unsigned k = 0; k < m; k++) {
560 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
561 }
562 }
563 }
564 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700565
Eric Anholta576f9d2010-03-31 16:25:12 -1000566 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000567 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700568 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
569 for (unsigned c = 0, c0 = 0, c1 = 0;
570 c < components;
571 c0 += c0_inc, c1 += c1_inc, c++) {
572
573 switch (ir->operands[0]->type->base_type) {
574 case GLSL_TYPE_UINT:
575 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
576 break;
577 case GLSL_TYPE_INT:
578 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
579 break;
580 case GLSL_TYPE_FLOAT:
581 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
582 break;
583 default:
584 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000585 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700586 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700587
Eric Anholtd251b922010-04-01 18:35:42 -1000588 break;
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700589 case ir_binop_mod:
590 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
591 for (unsigned c = 0, c0 = 0, c1 = 0;
592 c < components;
593 c0 += c0_inc, c1 += c1_inc, c++) {
594
595 switch (ir->operands[0]->type->base_type) {
596 case GLSL_TYPE_UINT:
597 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
598 break;
599 case GLSL_TYPE_INT:
600 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
601 break;
602 case GLSL_TYPE_FLOAT:
603 /* We don't use fmod because it rounds toward zero; GLSL specifies
604 * the use of floor.
605 */
606 data.f[c] = (op[0]->value.f[c0] - op[1]->value.f[c1])
607 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
608 break;
609 default:
610 assert(0);
611 }
612 }
613
614 break;
615
Eric Anholta576f9d2010-03-31 16:25:12 -1000616 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700617 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700618 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700619 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000620 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000621 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700622 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700623 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700624 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000625 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000626 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700627 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700628 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700629 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000630 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700631
632 case ir_binop_less:
Eric Anholt85171c22010-04-06 09:55:45 -0700633 switch (ir->operands[0]->type->base_type) {
634 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700635 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700636 break;
637 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700638 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700639 break;
640 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700641 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700642 break;
643 default:
644 assert(0);
645 }
646 break;
647 case ir_binop_greater:
Eric Anholt85171c22010-04-06 09:55:45 -0700648 switch (ir->operands[0]->type->base_type) {
649 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700650 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700651 break;
652 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700653 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700654 break;
655 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700656 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700657 break;
658 default:
659 assert(0);
660 }
661 break;
662 case ir_binop_lequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700663 switch (ir->operands[0]->type->base_type) {
664 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700665 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700666 break;
667 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700668 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700669 break;
670 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700671 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700672 break;
673 default:
674 assert(0);
675 }
676 break;
677 case ir_binop_gequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700678 switch (ir->operands[0]->type->base_type) {
679 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700680 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700681 break;
682 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700683 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700684 break;
685 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700686 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700687 break;
688 default:
689 assert(0);
690 }
691 break;
692
Eric Anholtec1949e2010-04-06 10:02:27 -0700693 case ir_binop_equal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700694 data.b[0] = true;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700695 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick083d75a2010-06-11 16:20:43 -0700696 switch (ir->operands[0]->type->base_type) {
697 case GLSL_TYPE_UINT:
698 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
699 break;
700 case GLSL_TYPE_INT:
701 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
702 break;
703 case GLSL_TYPE_FLOAT:
704 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
705 break;
706 case GLSL_TYPE_BOOL:
707 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
708 break;
709 default:
710 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700711 }
712 }
713 break;
714 case ir_binop_nequal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700715 data.b[0] = false;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700716 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick083d75a2010-06-11 16:20:43 -0700717 switch (ir->operands[0]->type->base_type) {
718 case GLSL_TYPE_UINT:
719 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
720 break;
721 case GLSL_TYPE_INT:
722 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
723 break;
724 case GLSL_TYPE_FLOAT:
725 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
726 break;
727 case GLSL_TYPE_BOOL:
728 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
729 break;
730 default:
731 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700732 }
733 }
734 break;
735
Eric Anholta576f9d2010-03-31 16:25:12 -1000736 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700737 /* FINISHME: Should handle all expression types. */
738 return;
Eric Anholta576f9d2010-03-31 16:25:12 -1000739 }
Eric Anholtd98da972010-04-01 18:25:11 -1000740
Eric Anholt6b01b502010-06-24 15:18:39 -0700741 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700742 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700743}
744
745
746void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700747ir_constant_visitor::visit(ir_texture *ir)
748{
749 // FINISHME: Do stuff with texture lookups
750 (void) ir;
751 value = NULL;
752}
753
754
755void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700756ir_constant_visitor::visit(ir_swizzle *ir)
757{
Ian Romanickc2ba6192010-06-11 12:30:28 -0700758 ir_constant *v = ir->val->constant_expression_value();
759
760 this->value = NULL;
761
762 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700763 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700764
765 const unsigned swiz_idx[4] = {
766 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
767 };
768
769 for (unsigned i = 0; i < ir->mask.num_components; i++) {
770 switch (v->type->base_type) {
771 case GLSL_TYPE_UINT:
772 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
773 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
774 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
775 default: assert(!"Should not get here."); break;
776 }
777 }
778
Eric Anholt6b01b502010-06-24 15:18:39 -0700779 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700780 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700781 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700782}
783
784
785void
Ian Romanickc7b10462010-05-19 13:20:12 +0200786ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700787{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700788 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700789
Ian Romanickc7b10462010-05-19 13:20:12 +0200790 ir_variable *var = ir->variable_referenced();
791 if (var && var->constant_value)
Ian Romanickca088cc2010-07-06 17:41:02 -0700792 value = var->constant_value->clone(NULL);
Ian Romanickc7b10462010-05-19 13:20:12 +0200793}
794
795
796void
797ir_constant_visitor::visit(ir_dereference_array *ir)
798{
Carl Worth1660a292010-06-23 18:11:51 -0700799 void *ctx = talloc_parent(ir);
Ian Romanick9b92af92010-06-11 12:20:12 -0700800 ir_constant *array = ir->array->constant_expression_value();
801 ir_constant *idx = ir->array_index->constant_expression_value();
802
803 this->value = NULL;
804
805 if ((array != NULL) && (idx != NULL)) {
806 if (array->type->is_matrix()) {
807 /* Array access of a matrix results in a vector.
808 */
809 const unsigned column = idx->value.u[0];
810
811 const glsl_type *const column_type = array->type->column_type();
812
813 /* Offset in the constant matrix to the first element of the column
814 * to be extracted.
815 */
816 const unsigned mat_idx = column * column_type->vector_elements;
817
Ian Romanick0bb70a32010-06-11 15:49:49 -0700818 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700819
820 switch (column_type->base_type) {
821 case GLSL_TYPE_UINT:
822 case GLSL_TYPE_INT:
823 for (unsigned i = 0; i < column_type->vector_elements; i++)
824 data.u[i] = array->value.u[mat_idx + i];
825
826 break;
827
828 case GLSL_TYPE_FLOAT:
829 for (unsigned i = 0; i < column_type->vector_elements; i++)
830 data.f[i] = array->value.f[mat_idx + i];
831
832 break;
833
834 default:
835 assert(!"Should not get here.");
836 break;
837 }
838
Carl Worth1660a292010-06-23 18:11:51 -0700839 this->value = new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700840 } else if (array->type->is_vector()) {
841 const unsigned component = idx->value.u[0];
842
Carl Worth1660a292010-06-23 18:11:51 -0700843 this->value = new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700844 } else {
845 /* FINISHME: Handle access of constant arrays. */
846 }
847 }
Ian Romanickc7b10462010-05-19 13:20:12 +0200848}
849
850
851void
852ir_constant_visitor::visit(ir_dereference_record *ir)
853{
Ian Romanick253dede2010-06-09 17:30:19 -0700854 ir_constant *v = ir->record->constant_expression_value();
855
856 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700857}
858
859
860void
861ir_constant_visitor::visit(ir_assignment *ir)
862{
863 (void) ir;
864 value = NULL;
865}
866
867
868void
869ir_constant_visitor::visit(ir_constant *ir)
870{
871 value = ir;
872}
873
874
875void
876ir_constant_visitor::visit(ir_call *ir)
877{
878 (void) ir;
879 value = NULL;
880}
881
882
883void
884ir_constant_visitor::visit(ir_return *ir)
885{
886 (void) ir;
887 value = NULL;
888}
889
890
891void
Kenneth Graunke16efab12010-06-30 10:47:34 -0700892ir_constant_visitor::visit(ir_discard *ir)
893{
894 (void) ir;
895 value = NULL;
896}
897
898
899void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700900ir_constant_visitor::visit(ir_if *ir)
901{
902 (void) ir;
903 value = NULL;
904}
Ian Romanickfad607a2010-04-05 16:16:07 -0700905
906
907void
908ir_constant_visitor::visit(ir_loop *ir)
909{
910 (void) ir;
911 value = NULL;
912}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700913
914
915void
916ir_constant_visitor::visit(ir_loop_jump *ir)
917{
918 (void) ir;
919 value = NULL;
920}