blob: e039504d4e42d431c94d9e0f4229c73035efb25a [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
41/**
42 * Visitor class for evaluating constant expressions
43 */
44class ir_constant_visitor : public ir_visitor {
45public:
46 ir_constant_visitor()
47 : value(NULL)
48 {
49 /* empty */
50 }
51
52 virtual ~ir_constant_visitor()
53 {
54 /* empty */
55 }
56
57 /**
58 * \name Visit methods
59 *
60 * As typical for the visitor pattern, there must be one \c visit method for
61 * each concrete subclass of \c ir_instruction. Virtual base classes within
62 * the hierarchy should not have \c visit methods.
63 */
64 /*@{*/
65 virtual void visit(ir_variable *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070066 virtual void visit(ir_function_signature *);
67 virtual void visit(ir_function *);
68 virtual void visit(ir_expression *);
Kenneth Graunke26d74cd2010-05-26 17:42:03 -070069 virtual void visit(ir_texture *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070070 virtual void visit(ir_swizzle *);
Ian Romanickc7b10462010-05-19 13:20:12 +020071 virtual void visit(ir_dereference_variable *);
72 virtual void visit(ir_dereference_array *);
73 virtual void visit(ir_dereference_record *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070074 virtual void visit(ir_assignment *);
75 virtual void visit(ir_constant *);
76 virtual void visit(ir_call *);
77 virtual void visit(ir_return *);
Kenneth Graunke16efab12010-06-30 10:47:34 -070078 virtual void visit(ir_discard *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070079 virtual void visit(ir_if *);
Ian Romanickfad607a2010-04-05 16:16:07 -070080 virtual void visit(ir_loop *);
Ian Romanickf8e31e02010-04-05 16:28:15 -070081 virtual void visit(ir_loop_jump *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070082 /*@}*/
83
84 /**
85 * Value of the constant expression.
86 *
87 * \note
88 * This field will be \c NULL if the expression is not constant valued.
89 */
90 /* FINIHSME: This cannot hold values for constant arrays or structures. */
91 ir_constant *value;
92};
93
94
95ir_constant *
96ir_instruction::constant_expression_value()
97{
98 ir_constant_visitor visitor;
99
100 this->accept(& visitor);
101 return visitor.value;
102}
103
104
105void
106ir_constant_visitor::visit(ir_variable *ir)
107{
108 (void) ir;
109 value = NULL;
110}
111
112
113void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700114ir_constant_visitor::visit(ir_function_signature *ir)
115{
116 (void) ir;
117 value = NULL;
118}
119
120
121void
122ir_constant_visitor::visit(ir_function *ir)
123{
124 (void) ir;
125 value = NULL;
126}
127
Ian Romanick1cf43a42010-03-30 16:56:50 -0700128void
129ir_constant_visitor::visit(ir_expression *ir)
130{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700131 value = NULL;
Kenneth Graunke6bc432e2010-07-02 17:12:23 -0700132 ir_constant *op[2] = { NULL, NULL };
Eric Anholtd98da972010-04-01 18:25:11 -1000133 unsigned int operand, c;
Ian Romanick4daaab62010-06-11 16:08:47 -0700134 ir_constant_data data;
Eric Anholt160d0922010-04-01 18:07:08 -1000135
Kenneth Graunkec63a1db2010-07-05 22:33:35 -0700136 memset(&data, 0, sizeof(data));
137
Eric Anholtd98da972010-04-01 18:25:11 -1000138 for (operand = 0; operand < ir->get_num_operands(); operand++) {
139 op[operand] = ir->operands[operand]->constant_expression_value();
140 if (!op[operand])
Eric Anholt160d0922010-04-01 18:07:08 -1000141 return;
142 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000143
Kenneth Graunke6fc983b2010-07-06 02:39:57 -0700144 if (op[1] != NULL)
145 assert(op[0]->type->base_type == op[1]->type->base_type);
146
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700147 bool op0_scalar = op[0]->type->is_scalar();
148 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
149
150 /* When iterating over a vector or matrix's components, we want to increase
151 * the loop counter. However, for scalars, we want to stay at 0.
152 */
153 unsigned c0_inc = op0_scalar ? 1 : 0;
154 unsigned c1_inc = op1_scalar ? 1 : 0;
155 unsigned components = op[op1_scalar ? 0 : 1]->type->components();
156
Eric Anholta576f9d2010-03-31 16:25:12 -1000157 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000158 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700159 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000160 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700161 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000162 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700163
164 case ir_unop_f2i:
165 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholtaf186412010-04-06 10:53:57 -0700166 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700167 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700168 }
169 break;
170 case ir_unop_i2f:
171 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
172 op[0]->type->base_type == GLSL_TYPE_INT);
Eric Anholtaf186412010-04-06 10:53:57 -0700173 for (c = 0; c < ir->operands[0]->type->components(); c++) {
174 if (op[0]->type->base_type == GLSL_TYPE_INT)
Ian Romanick4daaab62010-06-11 16:08:47 -0700175 data.f[c] = op[0]->value.i[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700176 else
Ian Romanick4daaab62010-06-11 16:08:47 -0700177 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700178 }
179 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700180 case ir_unop_b2f:
181 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700182 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700183 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700184 }
185 break;
186 case ir_unop_f2b:
187 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700188 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700189 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700190 }
191 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700192 case ir_unop_b2i:
193 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700194 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700195 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700196 }
197 break;
198 case ir_unop_i2b:
199 assert(op[0]->type->is_integer());
Ian Romanick39d6dd32010-06-11 13:46:30 -0700200 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700201 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700202 }
203 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700204
Eric Anholtd925c912010-07-01 10:37:11 -0700205 case ir_unop_fract:
206 for (c = 0; c < ir->operands[0]->type->components(); c++) {
207 switch (ir->type->base_type) {
208 case GLSL_TYPE_UINT:
209 data.u[c] = 0;
210 break;
211 case GLSL_TYPE_INT:
212 data.i[c] = 0;
213 break;
214 case GLSL_TYPE_FLOAT:
215 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
216 break;
217 default:
218 assert(0);
219 }
220 }
221 break;
222
Eric Anholt43ad37a2010-05-12 14:42:21 -0700223 case ir_unop_neg:
Eric Anholt43ad37a2010-05-12 14:42:21 -0700224 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700225 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700226 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700227 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700228 break;
229 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700230 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700231 break;
232 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700233 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700234 break;
235 default:
236 assert(0);
237 }
238 }
239 break;
240
241 case ir_unop_abs:
242 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700243 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700244 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700245 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700246 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700247 break;
248 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700249 data.i[c] = op[0]->value.i[c];
250 if (data.i[c] < 0)
251 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700252 break;
253 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700254 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700255 break;
256 default:
257 assert(0);
258 }
259 }
260 break;
261
262 case ir_unop_rcp:
263 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700264 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700265 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700266 case GLSL_TYPE_UINT:
267 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700268 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700269 break;
270 case GLSL_TYPE_INT:
271 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700272 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700273 break;
274 case GLSL_TYPE_FLOAT:
275 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700276 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700277 break;
278 default:
279 assert(0);
280 }
281 }
282 break;
283
284 case ir_unop_rsq:
285 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700286 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700287 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700288 }
289 break;
290
291 case ir_unop_sqrt:
292 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700293 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700294 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700295 }
296 break;
297
298 case ir_unop_exp:
299 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700300 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700301 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700302 }
303 break;
304
305 case ir_unop_log:
306 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700307 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700308 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700309 }
310 break;
311
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700312 case ir_unop_dFdx:
313 case ir_unop_dFdy:
314 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700315 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700316 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700317 }
318 break;
319
Eric Anholtd251b922010-04-01 18:35:42 -1000320 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700321 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
322 for (unsigned c = 0, c0 = 0, c1 = 0;
323 c < components;
324 c0 += c0_inc, c1 += c1_inc, c++) {
325
326 switch (ir->operands[0]->type->base_type) {
327 case GLSL_TYPE_UINT:
328 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
329 break;
330 case GLSL_TYPE_INT:
331 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
332 break;
333 case GLSL_TYPE_FLOAT:
334 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
335 break;
336 default:
337 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000338 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700339 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700340
Eric Anholtd251b922010-04-01 18:35:42 -1000341 break;
342 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700343 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
344 for (unsigned c = 0, c0 = 0, c1 = 0;
345 c < components;
346 c0 += c0_inc, c1 += c1_inc, c++) {
347
348 switch (ir->operands[0]->type->base_type) {
349 case GLSL_TYPE_UINT:
350 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
351 break;
352 case GLSL_TYPE_INT:
353 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
354 break;
355 case GLSL_TYPE_FLOAT:
356 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
357 break;
358 default:
359 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000360 }
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700361 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700362
Eric Anholtd251b922010-04-01 18:35:42 -1000363 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000364 case ir_binop_mul:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700365 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
366 || op0_scalar || op1_scalar) {
367 for (unsigned c = 0, c0 = 0, c1 = 0;
368 c < components;
369 c0 += c0_inc, c1 += c1_inc, c++) {
370
Eric Anholtd98da972010-04-01 18:25:11 -1000371 switch (ir->operands[0]->type->base_type) {
372 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700373 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000374 break;
375 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700376 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000377 break;
378 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700379 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000380 break;
381 default:
382 assert(0);
383 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000384 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700385 } else
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700386 /* FINISHME: Support vector/matrix and matrix multiplication. */
Ian Romanickf8b88be2010-06-11 16:23:52 -0700387 return;
388
Eric Anholta576f9d2010-03-31 16:25:12 -1000389 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000390 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700391 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
392 for (unsigned c = 0, c0 = 0, c1 = 0;
393 c < components;
394 c0 += c0_inc, c1 += c1_inc, c++) {
395
396 switch (ir->operands[0]->type->base_type) {
397 case GLSL_TYPE_UINT:
398 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
399 break;
400 case GLSL_TYPE_INT:
401 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
402 break;
403 case GLSL_TYPE_FLOAT:
404 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
405 break;
406 default:
407 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000408 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700409 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700410
Eric Anholtd251b922010-04-01 18:35:42 -1000411 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000412 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700413 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000414 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700415 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000416 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000417 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700418 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd251b922010-04-01 18:35:42 -1000419 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700420 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000421 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000422 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700423 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000424 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700425 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000426 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700427
428 case ir_binop_less:
Eric Anholt85171c22010-04-06 09:55:45 -0700429 switch (ir->operands[0]->type->base_type) {
430 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700431 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700432 break;
433 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700434 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700435 break;
436 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700437 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700438 break;
439 default:
440 assert(0);
441 }
442 break;
443 case ir_binop_greater:
Eric Anholt85171c22010-04-06 09:55:45 -0700444 switch (ir->operands[0]->type->base_type) {
445 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700446 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700447 break;
448 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700449 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700450 break;
451 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700452 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700453 break;
454 default:
455 assert(0);
456 }
457 break;
458 case ir_binop_lequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700459 switch (ir->operands[0]->type->base_type) {
460 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700461 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700462 break;
463 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700464 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700465 break;
466 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700467 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700468 break;
469 default:
470 assert(0);
471 }
472 break;
473 case ir_binop_gequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700474 switch (ir->operands[0]->type->base_type) {
475 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700476 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700477 break;
478 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700479 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700480 break;
481 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700482 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700483 break;
484 default:
485 assert(0);
486 }
487 break;
488
Eric Anholtec1949e2010-04-06 10:02:27 -0700489 case ir_binop_equal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700490 data.b[0] = true;
491 for (c = 0; c < ir->operands[0]->type->components(); c++) {
492 switch (ir->operands[0]->type->base_type) {
493 case GLSL_TYPE_UINT:
494 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
495 break;
496 case GLSL_TYPE_INT:
497 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
498 break;
499 case GLSL_TYPE_FLOAT:
500 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
501 break;
502 case GLSL_TYPE_BOOL:
503 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
504 break;
505 default:
506 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700507 }
508 }
509 break;
510 case ir_binop_nequal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700511 data.b[0] = false;
512 for (c = 0; c < ir->operands[0]->type->components(); c++) {
513 switch (ir->operands[0]->type->base_type) {
514 case GLSL_TYPE_UINT:
515 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
516 break;
517 case GLSL_TYPE_INT:
518 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
519 break;
520 case GLSL_TYPE_FLOAT:
521 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
522 break;
523 case GLSL_TYPE_BOOL:
524 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
525 break;
526 default:
527 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700528 }
529 }
530 break;
531
Eric Anholta576f9d2010-03-31 16:25:12 -1000532 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700533 /* FINISHME: Should handle all expression types. */
534 return;
Eric Anholta576f9d2010-03-31 16:25:12 -1000535 }
Eric Anholtd98da972010-04-01 18:25:11 -1000536
Eric Anholt6b01b502010-06-24 15:18:39 -0700537 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700538 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700539}
540
541
542void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700543ir_constant_visitor::visit(ir_texture *ir)
544{
545 // FINISHME: Do stuff with texture lookups
546 (void) ir;
547 value = NULL;
548}
549
550
551void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700552ir_constant_visitor::visit(ir_swizzle *ir)
553{
Ian Romanickc2ba6192010-06-11 12:30:28 -0700554 ir_constant *v = ir->val->constant_expression_value();
555
556 this->value = NULL;
557
558 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700559 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700560
561 const unsigned swiz_idx[4] = {
562 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
563 };
564
565 for (unsigned i = 0; i < ir->mask.num_components; i++) {
566 switch (v->type->base_type) {
567 case GLSL_TYPE_UINT:
568 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
569 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
570 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
571 default: assert(!"Should not get here."); break;
572 }
573 }
574
Eric Anholt6b01b502010-06-24 15:18:39 -0700575 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700576 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700577 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700578}
579
580
581void
Ian Romanickc7b10462010-05-19 13:20:12 +0200582ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700583{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700584 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700585
Ian Romanickc7b10462010-05-19 13:20:12 +0200586 ir_variable *var = ir->variable_referenced();
587 if (var && var->constant_value)
Eric Anholt4b6fd392010-06-23 11:37:12 -0700588 value = (ir_constant *)var->constant_value->clone(NULL);
Ian Romanickc7b10462010-05-19 13:20:12 +0200589}
590
591
592void
593ir_constant_visitor::visit(ir_dereference_array *ir)
594{
Carl Worth1660a292010-06-23 18:11:51 -0700595 void *ctx = talloc_parent(ir);
Ian Romanick9b92af92010-06-11 12:20:12 -0700596 ir_constant *array = ir->array->constant_expression_value();
597 ir_constant *idx = ir->array_index->constant_expression_value();
598
599 this->value = NULL;
600
601 if ((array != NULL) && (idx != NULL)) {
602 if (array->type->is_matrix()) {
603 /* Array access of a matrix results in a vector.
604 */
605 const unsigned column = idx->value.u[0];
606
607 const glsl_type *const column_type = array->type->column_type();
608
609 /* Offset in the constant matrix to the first element of the column
610 * to be extracted.
611 */
612 const unsigned mat_idx = column * column_type->vector_elements;
613
Ian Romanick0bb70a32010-06-11 15:49:49 -0700614 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700615
616 switch (column_type->base_type) {
617 case GLSL_TYPE_UINT:
618 case GLSL_TYPE_INT:
619 for (unsigned i = 0; i < column_type->vector_elements; i++)
620 data.u[i] = array->value.u[mat_idx + i];
621
622 break;
623
624 case GLSL_TYPE_FLOAT:
625 for (unsigned i = 0; i < column_type->vector_elements; i++)
626 data.f[i] = array->value.f[mat_idx + i];
627
628 break;
629
630 default:
631 assert(!"Should not get here.");
632 break;
633 }
634
Carl Worth1660a292010-06-23 18:11:51 -0700635 this->value = new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700636 } else if (array->type->is_vector()) {
637 const unsigned component = idx->value.u[0];
638
Carl Worth1660a292010-06-23 18:11:51 -0700639 this->value = new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700640 } else {
641 /* FINISHME: Handle access of constant arrays. */
642 }
643 }
Ian Romanickc7b10462010-05-19 13:20:12 +0200644}
645
646
647void
648ir_constant_visitor::visit(ir_dereference_record *ir)
649{
Ian Romanick253dede2010-06-09 17:30:19 -0700650 ir_constant *v = ir->record->constant_expression_value();
651
652 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700653}
654
655
656void
657ir_constant_visitor::visit(ir_assignment *ir)
658{
659 (void) ir;
660 value = NULL;
661}
662
663
664void
665ir_constant_visitor::visit(ir_constant *ir)
666{
667 value = ir;
668}
669
670
671void
672ir_constant_visitor::visit(ir_call *ir)
673{
674 (void) ir;
675 value = NULL;
676}
677
678
679void
680ir_constant_visitor::visit(ir_return *ir)
681{
682 (void) ir;
683 value = NULL;
684}
685
686
687void
Kenneth Graunke16efab12010-06-30 10:47:34 -0700688ir_constant_visitor::visit(ir_discard *ir)
689{
690 (void) ir;
691 value = NULL;
692}
693
694
695void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700696ir_constant_visitor::visit(ir_if *ir)
697{
698 (void) ir;
699 value = NULL;
700}
Ian Romanickfad607a2010-04-05 16:16:07 -0700701
702
703void
704ir_constant_visitor::visit(ir_loop *ir)
705{
706 (void) ir;
707 value = NULL;
708}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700709
710
711void
712ir_constant_visitor::visit(ir_loop_jump *ir)
713{
714 (void) ir;
715 value = NULL;
716}