blob: 076fdfda75fa2bbbb501a62afe9723d1b962cf7e [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
36#define NULL 0
37#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 *);
69 virtual void visit(ir_swizzle *);
Ian Romanickc7b10462010-05-19 13:20:12 +020070 virtual void visit(ir_dereference_variable *);
71 virtual void visit(ir_dereference_array *);
72 virtual void visit(ir_dereference_record *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070073 virtual void visit(ir_assignment *);
74 virtual void visit(ir_constant *);
75 virtual void visit(ir_call *);
76 virtual void visit(ir_return *);
77 virtual void visit(ir_if *);
Ian Romanickfad607a2010-04-05 16:16:07 -070078 virtual void visit(ir_loop *);
Ian Romanickf8e31e02010-04-05 16:28:15 -070079 virtual void visit(ir_loop_jump *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070080 /*@}*/
81
82 /**
83 * Value of the constant expression.
84 *
85 * \note
86 * This field will be \c NULL if the expression is not constant valued.
87 */
88 /* FINIHSME: This cannot hold values for constant arrays or structures. */
89 ir_constant *value;
90};
91
92
93ir_constant *
94ir_instruction::constant_expression_value()
95{
96 ir_constant_visitor visitor;
97
98 this->accept(& visitor);
99 return visitor.value;
100}
101
102
103void
104ir_constant_visitor::visit(ir_variable *ir)
105{
106 (void) ir;
107 value = NULL;
108}
109
110
111void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700112ir_constant_visitor::visit(ir_function_signature *ir)
113{
114 (void) ir;
115 value = NULL;
116}
117
118
119void
120ir_constant_visitor::visit(ir_function *ir)
121{
122 (void) ir;
123 value = NULL;
124}
125
Ian Romanick1cf43a42010-03-30 16:56:50 -0700126void
127ir_constant_visitor::visit(ir_expression *ir)
128{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700129 value = NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000130 ir_constant *op[2];
Eric Anholtd98da972010-04-01 18:25:11 -1000131 unsigned int operand, c;
132 unsigned u[16];
133 int i[16];
134 float f[16];
135 bool b[16];
136 const glsl_type *type = NULL;
Eric Anholt160d0922010-04-01 18:07:08 -1000137
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
144 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000145 case ir_unop_logic_not:
Eric Anholtd98da972010-04-01 18:25:11 -1000146 type = ir->operands[0]->type;
147 assert(type->base_type == GLSL_TYPE_BOOL);
148 for (c = 0; c < ir->operands[0]->type->components(); c++)
149 b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000150 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700151
152 case ir_unop_f2i:
153 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
154 type = ir->type;
155 for (c = 0; c < ir->operands[0]->type->components(); c++) {
156 i[c] = op[0]->value.f[c];
157 }
158 break;
159 case ir_unop_i2f:
160 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
161 op[0]->type->base_type == GLSL_TYPE_INT);
162 type = ir->type;
163 for (c = 0; c < ir->operands[0]->type->components(); c++) {
164 if (op[0]->type->base_type == GLSL_TYPE_INT)
165 f[c] = op[0]->value.i[c];
166 else
167 f[c] = op[0]->value.u[c];
168 }
169 break;
170
Eric Anholtd251b922010-04-01 18:35:42 -1000171 case ir_binop_add:
172 if (ir->operands[0]->type == ir->operands[1]->type) {
173 type = ir->operands[0]->type;
174 for (c = 0; c < ir->operands[0]->type->components(); c++) {
175 switch (ir->operands[0]->type->base_type) {
176 case GLSL_TYPE_UINT:
177 u[c] = op[0]->value.u[c] + op[1]->value.u[c];
178 break;
179 case GLSL_TYPE_INT:
180 i[c] = op[0]->value.i[c] + op[1]->value.i[c];
181 break;
182 case GLSL_TYPE_FLOAT:
183 f[c] = op[0]->value.f[c] + op[1]->value.f[c];
184 break;
185 default:
186 assert(0);
187 }
188 }
189 }
190 break;
191 case ir_binop_sub:
192 if (ir->operands[0]->type == ir->operands[1]->type) {
193 type = ir->operands[0]->type;
194 for (c = 0; c < ir->operands[0]->type->components(); c++) {
195 switch (ir->operands[0]->type->base_type) {
196 case GLSL_TYPE_UINT:
197 u[c] = op[0]->value.u[c] - op[1]->value.u[c];
198 break;
199 case GLSL_TYPE_INT:
200 i[c] = op[0]->value.i[c] - op[1]->value.i[c];
201 break;
202 case GLSL_TYPE_FLOAT:
203 f[c] = op[0]->value.f[c] - op[1]->value.f[c];
204 break;
205 default:
206 assert(0);
207 }
208 }
209 }
210 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000211 case ir_binop_mul:
Eric Anholtd98da972010-04-01 18:25:11 -1000212 if (ir->operands[0]->type == ir->operands[1]->type &&
213 !ir->operands[0]->type->is_matrix()) {
214 type = ir->operands[0]->type;
215 for (c = 0; c < ir->operands[0]->type->components(); c++) {
216 switch (ir->operands[0]->type->base_type) {
217 case GLSL_TYPE_UINT:
218 u[c] = op[0]->value.u[c] * op[1]->value.u[c];
219 break;
220 case GLSL_TYPE_INT:
221 i[c] = op[0]->value.i[c] * op[1]->value.i[c];
222 break;
223 case GLSL_TYPE_FLOAT:
224 f[c] = op[0]->value.f[c] * op[1]->value.f[c];
225 break;
226 default:
227 assert(0);
228 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000229 }
230 }
231 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000232 case ir_binop_div:
233 if (ir->operands[0]->type == ir->operands[1]->type) {
234 type = ir->operands[0]->type;
235 for (c = 0; c < ir->operands[0]->type->components(); c++) {
236 switch (ir->operands[0]->type->base_type) {
237 case GLSL_TYPE_UINT:
238 u[c] = op[0]->value.u[c] / op[1]->value.u[c];
239 break;
240 case GLSL_TYPE_INT:
241 i[c] = op[0]->value.i[c] / op[1]->value.i[c];
242 break;
243 case GLSL_TYPE_FLOAT:
244 f[c] = op[0]->value.f[c] / op[1]->value.f[c];
245 break;
246 default:
247 assert(0);
248 }
249 }
250 }
251 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000252 case ir_binop_logic_and:
Eric Anholtd98da972010-04-01 18:25:11 -1000253 type = ir->operands[0]->type;
254 assert(type->base_type == GLSL_TYPE_BOOL);
255 for (c = 0; c < ir->operands[0]->type->components(); c++)
256 b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000257 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000258 case ir_binop_logic_xor:
259 type = ir->operands[0]->type;
260 assert(type->base_type == GLSL_TYPE_BOOL);
261 for (c = 0; c < ir->operands[0]->type->components(); c++)
262 b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
263 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000264 case ir_binop_logic_or:
Eric Anholtd98da972010-04-01 18:25:11 -1000265 type = ir->operands[0]->type;
266 assert(type->base_type == GLSL_TYPE_BOOL);
267 for (c = 0; c < ir->operands[0]->type->components(); c++)
268 b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000269 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700270
271 case ir_binop_less:
272 type = glsl_type::bool_type;
273 switch (ir->operands[0]->type->base_type) {
274 case GLSL_TYPE_UINT:
275 b[0] = op[0]->value.u[0] < op[1]->value.u[0];
276 break;
277 case GLSL_TYPE_INT:
278 b[0] = op[0]->value.i[0] < op[1]->value.i[0];
279 break;
280 case GLSL_TYPE_FLOAT:
281 b[0] = op[0]->value.f[0] < op[1]->value.f[0];
282 break;
283 default:
284 assert(0);
285 }
286 break;
287 case ir_binop_greater:
288 type = glsl_type::bool_type;
289 switch (ir->operands[0]->type->base_type) {
290 case GLSL_TYPE_UINT:
291 b[0] = op[0]->value.u[0] > op[1]->value.u[0];
292 break;
293 case GLSL_TYPE_INT:
294 b[0] = op[0]->value.i[0] > op[1]->value.i[0];
295 break;
296 case GLSL_TYPE_FLOAT:
297 b[0] = op[0]->value.f[0] > op[1]->value.f[0];
298 break;
299 default:
300 assert(0);
301 }
302 break;
303 case ir_binop_lequal:
304 type = glsl_type::bool_type;
305 switch (ir->operands[0]->type->base_type) {
306 case GLSL_TYPE_UINT:
307 b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
308 break;
309 case GLSL_TYPE_INT:
310 b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
311 break;
312 case GLSL_TYPE_FLOAT:
313 b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
314 break;
315 default:
316 assert(0);
317 }
318 break;
319 case ir_binop_gequal:
320 type = glsl_type::bool_type;
321 switch (ir->operands[0]->type->base_type) {
322 case GLSL_TYPE_UINT:
323 b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
324 break;
325 case GLSL_TYPE_INT:
326 b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
327 break;
328 case GLSL_TYPE_FLOAT:
329 b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
330 break;
331 default:
332 assert(0);
333 }
334 break;
335
Eric Anholtec1949e2010-04-06 10:02:27 -0700336 case ir_binop_equal:
337 if (ir->operands[0]->type == ir->operands[1]->type) {
338 type = glsl_type::bool_type;
339 b[0] = true;
340 for (c = 0; c < ir->operands[0]->type->components(); c++) {
341 switch (ir->operands[0]->type->base_type) {
342 case GLSL_TYPE_UINT:
343 b[0] = b[0] && op[0]->value.u[c] == op[1]->value.u[c];
344 break;
345 case GLSL_TYPE_INT:
346 b[0] = b[0] && op[0]->value.i[c] == op[1]->value.i[c];
347 break;
348 case GLSL_TYPE_FLOAT:
349 b[0] = b[0] && op[0]->value.f[c] == op[1]->value.f[c];
350 break;
Ian Romanick77cce642010-04-07 16:48:42 -0700351 case GLSL_TYPE_BOOL:
352 b[0] = b[0] && op[0]->value.b[c] == op[1]->value.b[c];
353 break;
Eric Anholtec1949e2010-04-06 10:02:27 -0700354 default:
355 assert(0);
356 }
357 }
358 }
359 break;
360 case ir_binop_nequal:
361 if (ir->operands[0]->type == ir->operands[1]->type) {
362 type = glsl_type::bool_type;
363 b[0] = false;
364 for (c = 0; c < ir->operands[0]->type->components(); c++) {
365 switch (ir->operands[0]->type->base_type) {
366 case GLSL_TYPE_UINT:
367 b[0] = b[0] || op[0]->value.u[c] != op[1]->value.u[c];
368 break;
369 case GLSL_TYPE_INT:
370 b[0] = b[0] || op[0]->value.i[c] != op[1]->value.i[c];
371 break;
372 case GLSL_TYPE_FLOAT:
373 b[0] = b[0] || op[0]->value.f[c] != op[1]->value.f[c];
374 break;
Ian Romanick77cce642010-04-07 16:48:42 -0700375 case GLSL_TYPE_BOOL:
376 b[0] = b[0] || op[0]->value.b[c] != op[1]->value.b[c];
377 break;
Eric Anholtec1949e2010-04-06 10:02:27 -0700378 default:
379 assert(0);
380 }
381 }
382 }
383 break;
384
Eric Anholta576f9d2010-03-31 16:25:12 -1000385 default:
386 break;
387 }
Eric Anholtd98da972010-04-01 18:25:11 -1000388
389 if (type) {
390 switch (type->base_type) {
391 case GLSL_TYPE_UINT:
392 value = new ir_constant(type, u);
393 break;
394 case GLSL_TYPE_INT:
395 value = new ir_constant(type, i);
396 break;
397 case GLSL_TYPE_FLOAT:
398 value = new ir_constant(type, f);
399 break;
400 case GLSL_TYPE_BOOL:
401 value = new ir_constant(type, b);
402 break;
403 }
404 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700405}
406
407
408void
409ir_constant_visitor::visit(ir_swizzle *ir)
410{
411 (void) ir;
412 value = NULL;
413}
414
415
416void
Ian Romanickc7b10462010-05-19 13:20:12 +0200417ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700418{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700419 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700420
Ian Romanickc7b10462010-05-19 13:20:12 +0200421 ir_variable *var = ir->variable_referenced();
422 if (var && var->constant_value)
423 value = new ir_constant(ir->type, &var->constant_value->value);
424}
425
426
427void
428ir_constant_visitor::visit(ir_dereference_array *ir)
429{
430 value = NULL;
431 /* FINISHME: Other dereference modes. */
432}
433
434
435void
436ir_constant_visitor::visit(ir_dereference_record *ir)
437{
438 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700439 /* FINISHME: Other dereference modes. */
Ian Romanick1cf43a42010-03-30 16:56:50 -0700440}
441
442
443void
444ir_constant_visitor::visit(ir_assignment *ir)
445{
446 (void) ir;
447 value = NULL;
448}
449
450
451void
452ir_constant_visitor::visit(ir_constant *ir)
453{
454 value = ir;
455}
456
457
458void
459ir_constant_visitor::visit(ir_call *ir)
460{
461 (void) ir;
462 value = NULL;
463}
464
465
466void
467ir_constant_visitor::visit(ir_return *ir)
468{
469 (void) ir;
470 value = NULL;
471}
472
473
474void
475ir_constant_visitor::visit(ir_if *ir)
476{
477 (void) ir;
478 value = NULL;
479}
Ian Romanickfad607a2010-04-05 16:16:07 -0700480
481
482void
483ir_constant_visitor::visit(ir_loop *ir)
484{
485 (void) ir;
486 value = NULL;
487}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700488
489
490void
491ir_constant_visitor::visit(ir_loop_jump *ir)
492{
493 (void) ir;
494 value = NULL;
495}