blob: ef8661baf5726e1dccd0085bf5405425f731d508 [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 */
Kenneth Graunkeacf88f22010-07-07 12:08:23 -0700152 unsigned c0_inc = op0_scalar ? 0 : 1;
153 unsigned c1_inc = op1_scalar ? 0 : 1;
Eric Anholt570dc0d2010-07-07 09:07:09 -0700154 unsigned components;
155 if (op1_scalar || !op[1]) {
156 components = op[0]->type->components();
157 } else {
158 components = op[1]->type->components();
159 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700160
Eric Anholta576f9d2010-03-31 16:25:12 -1000161 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000162 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700163 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700164 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700165 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000166 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700167
168 case ir_unop_f2i:
169 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700170 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700171 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700172 }
173 break;
174 case ir_unop_i2f:
175 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
176 op[0]->type->base_type == GLSL_TYPE_INT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700177 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Eric Anholtaf186412010-04-06 10:53:57 -0700178 if (op[0]->type->base_type == GLSL_TYPE_INT)
Ian Romanick4daaab62010-06-11 16:08:47 -0700179 data.f[c] = op[0]->value.i[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700180 else
Ian Romanick4daaab62010-06-11 16:08:47 -0700181 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700182 }
183 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700184 case ir_unop_b2f:
185 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700186 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700187 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700188 }
189 break;
190 case ir_unop_f2b:
191 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700192 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700193 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700194 }
195 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700196 case ir_unop_b2i:
197 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700198 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700199 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700200 }
201 break;
202 case ir_unop_i2b:
203 assert(op[0]->type->is_integer());
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700204 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700205 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700206 }
207 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700208
Kenneth Graunke323d9092010-07-08 23:21:36 -0700209 case ir_unop_trunc:
210 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
211 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
212 data.f[c] = truncf(op[0]->value.f[c]);
213 }
214 break;
215
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700216 case ir_unop_ceil:
217 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
218 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
219 data.f[c] = ceilf(op[0]->value.f[c]);
220 }
221 break;
222
Kenneth Graunke07472042010-07-08 23:23:23 -0700223 case ir_unop_floor:
224 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
225 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
226 data.f[c] = floorf(op[0]->value.f[c]);
227 }
228 break;
229
Eric Anholtd925c912010-07-01 10:37:11 -0700230 case ir_unop_fract:
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700231 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Eric Anholtd925c912010-07-01 10:37:11 -0700232 switch (ir->type->base_type) {
233 case GLSL_TYPE_UINT:
234 data.u[c] = 0;
235 break;
236 case GLSL_TYPE_INT:
237 data.i[c] = 0;
238 break;
239 case GLSL_TYPE_FLOAT:
240 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
241 break;
242 default:
243 assert(0);
244 }
245 }
246 break;
247
Kenneth Graunke908afd12010-07-08 23:28:50 -0700248 case ir_unop_sin:
249 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
250 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
251 data.f[c] = sinf(op[0]->value.f[c]);
252 }
253 break;
254
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700255 case ir_unop_cos:
256 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
257 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
258 data.f[c] = cosf(op[0]->value.f[c]);
259 }
260 break;
261
Eric Anholt43ad37a2010-05-12 14:42:21 -0700262 case ir_unop_neg:
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:
Ian Romanick4daaab62010-06-11 16:08:47 -0700266 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700267 break;
268 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700269 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700270 break;
271 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700272 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700273 break;
274 default:
275 assert(0);
276 }
277 }
278 break;
279
280 case ir_unop_abs:
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700281 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700282 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700283 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700284 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700285 break;
286 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700287 data.i[c] = op[0]->value.i[c];
288 if (data.i[c] < 0)
289 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700290 break;
291 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700292 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700293 break;
294 default:
295 assert(0);
296 }
297 }
298 break;
299
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700300 case ir_unop_sign:
301 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
302 switch (ir->type->base_type) {
303 case GLSL_TYPE_UINT:
304 data.u[c] = op[0]->value.i[c] > 0;
305 break;
306 case GLSL_TYPE_INT:
307 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
308 break;
309 case GLSL_TYPE_FLOAT:
310 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
311 break;
312 default:
313 assert(0);
314 }
315 }
316 break;
317
Eric Anholt43ad37a2010-05-12 14:42:21 -0700318 case ir_unop_rcp:
319 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700320 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700321 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700322 case GLSL_TYPE_UINT:
323 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700324 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700325 break;
326 case GLSL_TYPE_INT:
327 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700328 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700329 break;
330 case GLSL_TYPE_FLOAT:
331 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700332 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700333 break;
334 default:
335 assert(0);
336 }
337 }
338 break;
339
340 case ir_unop_rsq:
341 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700342 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700343 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700344 }
345 break;
346
347 case ir_unop_sqrt:
348 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700349 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700350 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700351 }
352 break;
353
354 case ir_unop_exp:
355 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700356 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700357 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700358 }
359 break;
360
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700361 case ir_unop_exp2:
362 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
363 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
364 data.f[c] = exp2f(op[0]->value.f[c]);
365 }
366 break;
367
Eric Anholt43ad37a2010-05-12 14:42:21 -0700368 case ir_unop_log:
369 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700370 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700371 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700372 }
373 break;
374
Kenneth Graunkecb639292010-07-08 23:18:09 -0700375 case ir_unop_log2:
376 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
377 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
378 data.f[c] = log2f(op[0]->value.f[c]);
379 }
380 break;
381
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700382 case ir_unop_dFdx:
383 case ir_unop_dFdy:
384 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700385 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700386 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700387 }
388 break;
389
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700390 case ir_binop_dot:
391 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
392 data.f[0] = 0;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700393 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700394 switch (ir->operands[0]->type->base_type) {
395 case GLSL_TYPE_UINT:
396 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
397 break;
398 case GLSL_TYPE_INT:
399 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
400 break;
401 case GLSL_TYPE_FLOAT:
402 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
403 break;
404 default:
405 assert(0);
406 }
407 }
408
409 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000410 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700411 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
412 for (unsigned c = 0, c0 = 0, c1 = 0;
413 c < components;
414 c0 += c0_inc, c1 += c1_inc, c++) {
415
416 switch (ir->operands[0]->type->base_type) {
417 case GLSL_TYPE_UINT:
418 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
419 break;
420 case GLSL_TYPE_INT:
421 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
422 break;
423 case GLSL_TYPE_FLOAT:
424 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
425 break;
426 default:
427 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000428 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700429 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700430
Eric Anholtd251b922010-04-01 18:35:42 -1000431 break;
432 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700433 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
434 for (unsigned c = 0, c0 = 0, c1 = 0;
435 c < components;
436 c0 += c0_inc, c1 += c1_inc, c++) {
437
438 switch (ir->operands[0]->type->base_type) {
439 case GLSL_TYPE_UINT:
440 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
441 break;
442 case GLSL_TYPE_INT:
443 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
444 break;
445 case GLSL_TYPE_FLOAT:
446 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
447 break;
448 default:
449 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000450 }
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700451 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700452
Eric Anholtd251b922010-04-01 18:35:42 -1000453 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000454 case ir_binop_mul:
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700455 /* Check for equal types, or unequal types involving scalars */
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700456 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
457 || op0_scalar || op1_scalar) {
458 for (unsigned c = 0, c0 = 0, c1 = 0;
459 c < components;
460 c0 += c0_inc, c1 += c1_inc, c++) {
461
Eric Anholtd98da972010-04-01 18:25:11 -1000462 switch (ir->operands[0]->type->base_type) {
463 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700464 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000465 break;
466 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700467 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000468 break;
469 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700470 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000471 break;
472 default:
473 assert(0);
474 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000475 }
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700476 } else {
477 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
478
479 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
480 * matrix can be a GLSL vector, either N or P can be 1.
481 *
482 * For vec*mat, the vector is treated as a row vector. This
483 * means the vector is a 1-row x M-column matrix.
484 *
485 * For mat*vec, the vector is treated as a column vector. Since
486 * matrix_columns is 1 for vectors, this just works.
487 */
488 const unsigned n = op[0]->type->is_vector()
489 ? 1 : op[0]->type->vector_elements;
490 const unsigned m = op[1]->type->vector_elements;
491 const unsigned p = op[1]->type->matrix_columns;
492 for (unsigned j = 0; j < p; j++) {
493 for (unsigned i = 0; i < n; i++) {
494 for (unsigned k = 0; k < m; k++) {
495 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
496 }
497 }
498 }
499 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700500
Eric Anholta576f9d2010-03-31 16:25:12 -1000501 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000502 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700503 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
504 for (unsigned c = 0, c0 = 0, c1 = 0;
505 c < components;
506 c0 += c0_inc, c1 += c1_inc, c++) {
507
508 switch (ir->operands[0]->type->base_type) {
509 case GLSL_TYPE_UINT:
510 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
511 break;
512 case GLSL_TYPE_INT:
513 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
514 break;
515 case GLSL_TYPE_FLOAT:
516 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
517 break;
518 default:
519 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000520 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700521 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700522
Eric Anholtd251b922010-04-01 18:35:42 -1000523 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000524 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700525 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700526 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700527 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000528 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000529 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700530 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700531 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700532 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000533 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000534 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700535 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700536 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700537 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000538 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700539
540 case ir_binop_less:
Eric Anholt85171c22010-04-06 09:55:45 -0700541 switch (ir->operands[0]->type->base_type) {
542 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700543 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700544 break;
545 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700546 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700547 break;
548 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700549 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700550 break;
551 default:
552 assert(0);
553 }
554 break;
555 case ir_binop_greater:
Eric Anholt85171c22010-04-06 09:55:45 -0700556 switch (ir->operands[0]->type->base_type) {
557 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700558 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700559 break;
560 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700561 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700562 break;
563 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700564 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700565 break;
566 default:
567 assert(0);
568 }
569 break;
570 case ir_binop_lequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700571 switch (ir->operands[0]->type->base_type) {
572 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700573 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700574 break;
575 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700576 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700577 break;
578 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700579 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700580 break;
581 default:
582 assert(0);
583 }
584 break;
585 case ir_binop_gequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700586 switch (ir->operands[0]->type->base_type) {
587 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700588 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700589 break;
590 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700591 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700592 break;
593 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700594 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700595 break;
596 default:
597 assert(0);
598 }
599 break;
600
Eric Anholtec1949e2010-04-06 10:02:27 -0700601 case ir_binop_equal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700602 data.b[0] = true;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700603 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick083d75a2010-06-11 16:20:43 -0700604 switch (ir->operands[0]->type->base_type) {
605 case GLSL_TYPE_UINT:
606 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
607 break;
608 case GLSL_TYPE_INT:
609 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
610 break;
611 case GLSL_TYPE_FLOAT:
612 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
613 break;
614 case GLSL_TYPE_BOOL:
615 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
616 break;
617 default:
618 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700619 }
620 }
621 break;
622 case ir_binop_nequal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700623 data.b[0] = false;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700624 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick083d75a2010-06-11 16:20:43 -0700625 switch (ir->operands[0]->type->base_type) {
626 case GLSL_TYPE_UINT:
627 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
628 break;
629 case GLSL_TYPE_INT:
630 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
631 break;
632 case GLSL_TYPE_FLOAT:
633 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
634 break;
635 case GLSL_TYPE_BOOL:
636 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
637 break;
638 default:
639 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700640 }
641 }
642 break;
643
Eric Anholta576f9d2010-03-31 16:25:12 -1000644 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700645 /* FINISHME: Should handle all expression types. */
646 return;
Eric Anholta576f9d2010-03-31 16:25:12 -1000647 }
Eric Anholtd98da972010-04-01 18:25:11 -1000648
Eric Anholt6b01b502010-06-24 15:18:39 -0700649 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700650 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700651}
652
653
654void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700655ir_constant_visitor::visit(ir_texture *ir)
656{
657 // FINISHME: Do stuff with texture lookups
658 (void) ir;
659 value = NULL;
660}
661
662
663void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700664ir_constant_visitor::visit(ir_swizzle *ir)
665{
Ian Romanickc2ba6192010-06-11 12:30:28 -0700666 ir_constant *v = ir->val->constant_expression_value();
667
668 this->value = NULL;
669
670 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700671 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700672
673 const unsigned swiz_idx[4] = {
674 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
675 };
676
677 for (unsigned i = 0; i < ir->mask.num_components; i++) {
678 switch (v->type->base_type) {
679 case GLSL_TYPE_UINT:
680 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
681 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
682 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
683 default: assert(!"Should not get here."); break;
684 }
685 }
686
Eric Anholt6b01b502010-06-24 15:18:39 -0700687 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700688 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700689 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700690}
691
692
693void
Ian Romanickc7b10462010-05-19 13:20:12 +0200694ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700695{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700696 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700697
Ian Romanickc7b10462010-05-19 13:20:12 +0200698 ir_variable *var = ir->variable_referenced();
699 if (var && var->constant_value)
Ian Romanickca088cc2010-07-06 17:41:02 -0700700 value = var->constant_value->clone(NULL);
Ian Romanickc7b10462010-05-19 13:20:12 +0200701}
702
703
704void
705ir_constant_visitor::visit(ir_dereference_array *ir)
706{
Carl Worth1660a292010-06-23 18:11:51 -0700707 void *ctx = talloc_parent(ir);
Ian Romanick9b92af92010-06-11 12:20:12 -0700708 ir_constant *array = ir->array->constant_expression_value();
709 ir_constant *idx = ir->array_index->constant_expression_value();
710
711 this->value = NULL;
712
713 if ((array != NULL) && (idx != NULL)) {
714 if (array->type->is_matrix()) {
715 /* Array access of a matrix results in a vector.
716 */
717 const unsigned column = idx->value.u[0];
718
719 const glsl_type *const column_type = array->type->column_type();
720
721 /* Offset in the constant matrix to the first element of the column
722 * to be extracted.
723 */
724 const unsigned mat_idx = column * column_type->vector_elements;
725
Ian Romanick0bb70a32010-06-11 15:49:49 -0700726 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700727
728 switch (column_type->base_type) {
729 case GLSL_TYPE_UINT:
730 case GLSL_TYPE_INT:
731 for (unsigned i = 0; i < column_type->vector_elements; i++)
732 data.u[i] = array->value.u[mat_idx + i];
733
734 break;
735
736 case GLSL_TYPE_FLOAT:
737 for (unsigned i = 0; i < column_type->vector_elements; i++)
738 data.f[i] = array->value.f[mat_idx + i];
739
740 break;
741
742 default:
743 assert(!"Should not get here.");
744 break;
745 }
746
Carl Worth1660a292010-06-23 18:11:51 -0700747 this->value = new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700748 } else if (array->type->is_vector()) {
749 const unsigned component = idx->value.u[0];
750
Carl Worth1660a292010-06-23 18:11:51 -0700751 this->value = new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700752 } else {
753 /* FINISHME: Handle access of constant arrays. */
754 }
755 }
Ian Romanickc7b10462010-05-19 13:20:12 +0200756}
757
758
759void
760ir_constant_visitor::visit(ir_dereference_record *ir)
761{
Ian Romanick253dede2010-06-09 17:30:19 -0700762 ir_constant *v = ir->record->constant_expression_value();
763
764 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700765}
766
767
768void
769ir_constant_visitor::visit(ir_assignment *ir)
770{
771 (void) ir;
772 value = NULL;
773}
774
775
776void
777ir_constant_visitor::visit(ir_constant *ir)
778{
779 value = ir;
780}
781
782
783void
784ir_constant_visitor::visit(ir_call *ir)
785{
786 (void) ir;
787 value = NULL;
788}
789
790
791void
792ir_constant_visitor::visit(ir_return *ir)
793{
794 (void) ir;
795 value = NULL;
796}
797
798
799void
Kenneth Graunke16efab12010-06-30 10:47:34 -0700800ir_constant_visitor::visit(ir_discard *ir)
801{
802 (void) ir;
803 value = NULL;
804}
805
806
807void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700808ir_constant_visitor::visit(ir_if *ir)
809{
810 (void) ir;
811 value = NULL;
812}
Ian Romanickfad607a2010-04-05 16:16:07 -0700813
814
815void
816ir_constant_visitor::visit(ir_loop *ir)
817{
818 (void) ir;
819 value = NULL;
820}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700821
822
823void
824ir_constant_visitor::visit(ir_loop_jump *ir)
825{
826 (void) ir;
827 value = NULL;
828}