blob: 11c810bc484237ea284fc2431f6e4827e6071caa [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 };
Ian Romanick4daaab62010-06-11 16:08:47 -0700133 ir_constant_data data;
Eric Anholt160d0922010-04-01 18:07:08 -1000134
Kenneth Graunkec63a1db2010-07-05 22:33:35 -0700135 memset(&data, 0, sizeof(data));
136
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700137 for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) {
Eric Anholtd98da972010-04-01 18:25:11 -1000138 op[operand] = ir->operands[operand]->constant_expression_value();
139 if (!op[operand])
Eric Anholt160d0922010-04-01 18:07:08 -1000140 return;
141 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000142
Kenneth Graunke6fc983b2010-07-06 02:39:57 -0700143 if (op[1] != NULL)
144 assert(op[0]->type->base_type == op[1]->type->base_type);
145
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700146 bool op0_scalar = op[0]->type->is_scalar();
147 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
148
149 /* When iterating over a vector or matrix's components, we want to increase
150 * the loop counter. However, for scalars, we want to stay at 0.
151 */
152 unsigned c0_inc = op0_scalar ? 1 : 0;
153 unsigned c1_inc = op1_scalar ? 1 : 0;
154 unsigned components = op[op1_scalar ? 0 : 1]->type->components();
155
Eric Anholta576f9d2010-03-31 16:25:12 -1000156 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000157 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700158 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700159 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700160 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000161 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700162
163 case ir_unop_f2i:
164 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700165 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700166 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700167 }
168 break;
169 case ir_unop_i2f:
170 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
171 op[0]->type->base_type == GLSL_TYPE_INT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700172 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Eric Anholtaf186412010-04-06 10:53:57 -0700173 if (op[0]->type->base_type == GLSL_TYPE_INT)
Ian Romanick4daaab62010-06-11 16:08:47 -0700174 data.f[c] = op[0]->value.i[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700175 else
Ian Romanick4daaab62010-06-11 16:08:47 -0700176 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700177 }
178 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700179 case ir_unop_b2f:
180 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700181 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700182 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700183 }
184 break;
185 case ir_unop_f2b:
186 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700187 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700188 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700189 }
190 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700191 case ir_unop_b2i:
192 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700193 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700194 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700195 }
196 break;
197 case ir_unop_i2b:
198 assert(op[0]->type->is_integer());
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700199 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700200 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700201 }
202 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700203
Eric Anholtd925c912010-07-01 10:37:11 -0700204 case ir_unop_fract:
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700205 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Eric Anholtd925c912010-07-01 10:37:11 -0700206 switch (ir->type->base_type) {
207 case GLSL_TYPE_UINT:
208 data.u[c] = 0;
209 break;
210 case GLSL_TYPE_INT:
211 data.i[c] = 0;
212 break;
213 case GLSL_TYPE_FLOAT:
214 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
215 break;
216 default:
217 assert(0);
218 }
219 }
220 break;
221
Eric Anholt43ad37a2010-05-12 14:42:21 -0700222 case ir_unop_neg:
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700223 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700224 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700225 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700226 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700227 break;
228 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700229 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700230 break;
231 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700232 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700233 break;
234 default:
235 assert(0);
236 }
237 }
238 break;
239
240 case ir_unop_abs:
241 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700242 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700243 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700244 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700245 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700246 break;
247 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700248 data.i[c] = op[0]->value.i[c];
249 if (data.i[c] < 0)
250 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700251 break;
252 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700253 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700254 break;
255 default:
256 assert(0);
257 }
258 }
259 break;
260
261 case ir_unop_rcp:
262 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700263 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700264 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700265 case GLSL_TYPE_UINT:
266 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700267 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700268 break;
269 case GLSL_TYPE_INT:
270 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700271 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700272 break;
273 case GLSL_TYPE_FLOAT:
274 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700275 data.f[c] = 1.0 / 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_rsq:
284 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700285 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700286 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700287 }
288 break;
289
290 case ir_unop_sqrt:
291 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700292 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700293 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700294 }
295 break;
296
297 case ir_unop_exp:
298 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700299 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700300 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700301 }
302 break;
303
304 case ir_unop_log:
305 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700306 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700307 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700308 }
309 break;
310
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700311 case ir_unop_dFdx:
312 case ir_unop_dFdy:
313 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700314 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700315 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700316 }
317 break;
318
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700319 case ir_binop_dot:
320 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
321 data.f[0] = 0;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700322 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700323 switch (ir->operands[0]->type->base_type) {
324 case GLSL_TYPE_UINT:
325 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
326 break;
327 case GLSL_TYPE_INT:
328 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
329 break;
330 case GLSL_TYPE_FLOAT:
331 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
332 break;
333 default:
334 assert(0);
335 }
336 }
337
338 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000339 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700340 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
341 for (unsigned c = 0, c0 = 0, c1 = 0;
342 c < components;
343 c0 += c0_inc, c1 += c1_inc, c++) {
344
345 switch (ir->operands[0]->type->base_type) {
346 case GLSL_TYPE_UINT:
347 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
348 break;
349 case GLSL_TYPE_INT:
350 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
351 break;
352 case GLSL_TYPE_FLOAT:
353 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
354 break;
355 default:
356 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000357 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700358 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700359
Eric Anholtd251b922010-04-01 18:35:42 -1000360 break;
361 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700362 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
363 for (unsigned c = 0, c0 = 0, c1 = 0;
364 c < components;
365 c0 += c0_inc, c1 += c1_inc, c++) {
366
367 switch (ir->operands[0]->type->base_type) {
368 case GLSL_TYPE_UINT:
369 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
370 break;
371 case GLSL_TYPE_INT:
372 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
373 break;
374 case GLSL_TYPE_FLOAT:
375 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
376 break;
377 default:
378 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000379 }
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700380 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700381
Eric Anholtd251b922010-04-01 18:35:42 -1000382 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000383 case ir_binop_mul:
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700384 /* Check for equal types, or unequal types involving scalars */
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700385 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
386 || op0_scalar || op1_scalar) {
387 for (unsigned c = 0, c0 = 0, c1 = 0;
388 c < components;
389 c0 += c0_inc, c1 += c1_inc, c++) {
390
Eric Anholtd98da972010-04-01 18:25:11 -1000391 switch (ir->operands[0]->type->base_type) {
392 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700393 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000394 break;
395 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700396 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000397 break;
398 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700399 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000400 break;
401 default:
402 assert(0);
403 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000404 }
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700405 } else {
406 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
407
408 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
409 * matrix can be a GLSL vector, either N or P can be 1.
410 *
411 * For vec*mat, the vector is treated as a row vector. This
412 * means the vector is a 1-row x M-column matrix.
413 *
414 * For mat*vec, the vector is treated as a column vector. Since
415 * matrix_columns is 1 for vectors, this just works.
416 */
417 const unsigned n = op[0]->type->is_vector()
418 ? 1 : op[0]->type->vector_elements;
419 const unsigned m = op[1]->type->vector_elements;
420 const unsigned p = op[1]->type->matrix_columns;
421 for (unsigned j = 0; j < p; j++) {
422 for (unsigned i = 0; i < n; i++) {
423 for (unsigned k = 0; k < m; k++) {
424 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
425 }
426 }
427 }
428 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700429
Eric Anholta576f9d2010-03-31 16:25:12 -1000430 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000431 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700432 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
433 for (unsigned c = 0, c0 = 0, c1 = 0;
434 c < components;
435 c0 += c0_inc, c1 += c1_inc, c++) {
436
437 switch (ir->operands[0]->type->base_type) {
438 case GLSL_TYPE_UINT:
439 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
440 break;
441 case GLSL_TYPE_INT:
442 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
443 break;
444 case GLSL_TYPE_FLOAT:
445 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
446 break;
447 default:
448 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000449 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700450 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700451
Eric Anholtd251b922010-04-01 18:35:42 -1000452 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000453 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700454 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700455 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700456 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000457 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000458 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700459 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700460 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700461 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000462 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000463 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700464 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700465 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700466 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000467 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700468
469 case ir_binop_less:
Eric Anholt85171c22010-04-06 09:55:45 -0700470 switch (ir->operands[0]->type->base_type) {
471 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700472 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700473 break;
474 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700475 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700476 break;
477 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700478 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700479 break;
480 default:
481 assert(0);
482 }
483 break;
484 case ir_binop_greater:
Eric Anholt85171c22010-04-06 09:55:45 -0700485 switch (ir->operands[0]->type->base_type) {
486 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700487 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700488 break;
489 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700490 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700491 break;
492 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700493 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700494 break;
495 default:
496 assert(0);
497 }
498 break;
499 case ir_binop_lequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700500 switch (ir->operands[0]->type->base_type) {
501 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700502 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700503 break;
504 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700505 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700506 break;
507 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700508 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700509 break;
510 default:
511 assert(0);
512 }
513 break;
514 case ir_binop_gequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700515 switch (ir->operands[0]->type->base_type) {
516 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700517 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700518 break;
519 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700520 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700521 break;
522 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700523 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700524 break;
525 default:
526 assert(0);
527 }
528 break;
529
Eric Anholtec1949e2010-04-06 10:02:27 -0700530 case ir_binop_equal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700531 data.b[0] = true;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700532 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick083d75a2010-06-11 16:20:43 -0700533 switch (ir->operands[0]->type->base_type) {
534 case GLSL_TYPE_UINT:
535 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
536 break;
537 case GLSL_TYPE_INT:
538 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
539 break;
540 case GLSL_TYPE_FLOAT:
541 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
542 break;
543 case GLSL_TYPE_BOOL:
544 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
545 break;
546 default:
547 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700548 }
549 }
550 break;
551 case ir_binop_nequal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700552 data.b[0] = false;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700553 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick083d75a2010-06-11 16:20:43 -0700554 switch (ir->operands[0]->type->base_type) {
555 case GLSL_TYPE_UINT:
556 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
557 break;
558 case GLSL_TYPE_INT:
559 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
560 break;
561 case GLSL_TYPE_FLOAT:
562 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
563 break;
564 case GLSL_TYPE_BOOL:
565 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
566 break;
567 default:
568 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700569 }
570 }
571 break;
572
Eric Anholta576f9d2010-03-31 16:25:12 -1000573 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700574 /* FINISHME: Should handle all expression types. */
575 return;
Eric Anholta576f9d2010-03-31 16:25:12 -1000576 }
Eric Anholtd98da972010-04-01 18:25:11 -1000577
Eric Anholt6b01b502010-06-24 15:18:39 -0700578 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700579 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700580}
581
582
583void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700584ir_constant_visitor::visit(ir_texture *ir)
585{
586 // FINISHME: Do stuff with texture lookups
587 (void) ir;
588 value = NULL;
589}
590
591
592void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700593ir_constant_visitor::visit(ir_swizzle *ir)
594{
Ian Romanickc2ba6192010-06-11 12:30:28 -0700595 ir_constant *v = ir->val->constant_expression_value();
596
597 this->value = NULL;
598
599 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700600 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700601
602 const unsigned swiz_idx[4] = {
603 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
604 };
605
606 for (unsigned i = 0; i < ir->mask.num_components; i++) {
607 switch (v->type->base_type) {
608 case GLSL_TYPE_UINT:
609 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
610 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
611 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
612 default: assert(!"Should not get here."); break;
613 }
614 }
615
Eric Anholt6b01b502010-06-24 15:18:39 -0700616 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700617 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700618 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700619}
620
621
622void
Ian Romanickc7b10462010-05-19 13:20:12 +0200623ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700624{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700625 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700626
Ian Romanickc7b10462010-05-19 13:20:12 +0200627 ir_variable *var = ir->variable_referenced();
628 if (var && var->constant_value)
Eric Anholt4b6fd392010-06-23 11:37:12 -0700629 value = (ir_constant *)var->constant_value->clone(NULL);
Ian Romanickc7b10462010-05-19 13:20:12 +0200630}
631
632
633void
634ir_constant_visitor::visit(ir_dereference_array *ir)
635{
Carl Worth1660a292010-06-23 18:11:51 -0700636 void *ctx = talloc_parent(ir);
Ian Romanick9b92af92010-06-11 12:20:12 -0700637 ir_constant *array = ir->array->constant_expression_value();
638 ir_constant *idx = ir->array_index->constant_expression_value();
639
640 this->value = NULL;
641
642 if ((array != NULL) && (idx != NULL)) {
643 if (array->type->is_matrix()) {
644 /* Array access of a matrix results in a vector.
645 */
646 const unsigned column = idx->value.u[0];
647
648 const glsl_type *const column_type = array->type->column_type();
649
650 /* Offset in the constant matrix to the first element of the column
651 * to be extracted.
652 */
653 const unsigned mat_idx = column * column_type->vector_elements;
654
Ian Romanick0bb70a32010-06-11 15:49:49 -0700655 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700656
657 switch (column_type->base_type) {
658 case GLSL_TYPE_UINT:
659 case GLSL_TYPE_INT:
660 for (unsigned i = 0; i < column_type->vector_elements; i++)
661 data.u[i] = array->value.u[mat_idx + i];
662
663 break;
664
665 case GLSL_TYPE_FLOAT:
666 for (unsigned i = 0; i < column_type->vector_elements; i++)
667 data.f[i] = array->value.f[mat_idx + i];
668
669 break;
670
671 default:
672 assert(!"Should not get here.");
673 break;
674 }
675
Carl Worth1660a292010-06-23 18:11:51 -0700676 this->value = new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700677 } else if (array->type->is_vector()) {
678 const unsigned component = idx->value.u[0];
679
Carl Worth1660a292010-06-23 18:11:51 -0700680 this->value = new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700681 } else {
682 /* FINISHME: Handle access of constant arrays. */
683 }
684 }
Ian Romanickc7b10462010-05-19 13:20:12 +0200685}
686
687
688void
689ir_constant_visitor::visit(ir_dereference_record *ir)
690{
Ian Romanick253dede2010-06-09 17:30:19 -0700691 ir_constant *v = ir->record->constant_expression_value();
692
693 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700694}
695
696
697void
698ir_constant_visitor::visit(ir_assignment *ir)
699{
700 (void) ir;
701 value = NULL;
702}
703
704
705void
706ir_constant_visitor::visit(ir_constant *ir)
707{
708 value = ir;
709}
710
711
712void
713ir_constant_visitor::visit(ir_call *ir)
714{
715 (void) ir;
716 value = NULL;
717}
718
719
720void
721ir_constant_visitor::visit(ir_return *ir)
722{
723 (void) ir;
724 value = NULL;
725}
726
727
728void
Kenneth Graunke16efab12010-06-30 10:47:34 -0700729ir_constant_visitor::visit(ir_discard *ir)
730{
731 (void) ir;
732 value = NULL;
733}
734
735
736void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700737ir_constant_visitor::visit(ir_if *ir)
738{
739 (void) ir;
740 value = NULL;
741}
Ian Romanickfad607a2010-04-05 16:16:07 -0700742
743
744void
745ir_constant_visitor::visit(ir_loop *ir)
746{
747 (void) ir;
748 value = NULL;
749}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700750
751
752void
753ir_constant_visitor::visit(ir_loop_jump *ir)
754{
755 (void) ir;
756 value = NULL;
757}