blob: e9f04998209fd49cf4676e1225421aa0e02e2e8b [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 *);
78 virtual void visit(ir_if *);
Ian Romanickfad607a2010-04-05 16:16:07 -070079 virtual void visit(ir_loop *);
Ian Romanickf8e31e02010-04-05 16:28:15 -070080 virtual void visit(ir_loop_jump *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070081 /*@}*/
82
83 /**
84 * Value of the constant expression.
85 *
86 * \note
87 * This field will be \c NULL if the expression is not constant valued.
88 */
89 /* FINIHSME: This cannot hold values for constant arrays or structures. */
90 ir_constant *value;
91};
92
93
94ir_constant *
95ir_instruction::constant_expression_value()
96{
97 ir_constant_visitor visitor;
98
99 this->accept(& visitor);
100 return visitor.value;
101}
102
103
104void
105ir_constant_visitor::visit(ir_variable *ir)
106{
107 (void) ir;
108 value = NULL;
109}
110
111
112void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700113ir_constant_visitor::visit(ir_function_signature *ir)
114{
115 (void) ir;
116 value = NULL;
117}
118
119
120void
121ir_constant_visitor::visit(ir_function *ir)
122{
123 (void) ir;
124 value = NULL;
125}
126
Ian Romanick1cf43a42010-03-30 16:56:50 -0700127void
128ir_constant_visitor::visit(ir_expression *ir)
129{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700130 value = NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000131 ir_constant *op[2];
Eric Anholtd98da972010-04-01 18:25:11 -1000132 unsigned int operand, c;
Ian Romanick4daaab62010-06-11 16:08:47 -0700133 ir_constant_data data;
Eric Anholt160d0922010-04-01 18:07:08 -1000134
Eric Anholtd98da972010-04-01 18:25:11 -1000135 for (operand = 0; operand < ir->get_num_operands(); operand++) {
136 op[operand] = ir->operands[operand]->constant_expression_value();
137 if (!op[operand])
Eric Anholt160d0922010-04-01 18:07:08 -1000138 return;
139 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000140
141 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000142 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700143 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000144 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700145 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000146 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700147
148 case ir_unop_f2i:
149 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholtaf186412010-04-06 10:53:57 -0700150 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700151 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700152 }
153 break;
154 case ir_unop_i2f:
155 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
156 op[0]->type->base_type == GLSL_TYPE_INT);
Eric Anholtaf186412010-04-06 10:53:57 -0700157 for (c = 0; c < ir->operands[0]->type->components(); c++) {
158 if (op[0]->type->base_type == GLSL_TYPE_INT)
Ian Romanick4daaab62010-06-11 16:08:47 -0700159 data.f[c] = op[0]->value.i[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700160 else
Ian Romanick4daaab62010-06-11 16:08:47 -0700161 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700162 }
163 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700164 case ir_unop_b2f:
165 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700166 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700167 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700168 }
169 break;
170 case ir_unop_f2b:
171 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700172 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700173 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700174 }
175 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700176 case ir_unop_b2i:
177 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700178 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700179 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700180 }
181 break;
182 case ir_unop_i2b:
183 assert(op[0]->type->is_integer());
Ian Romanick39d6dd32010-06-11 13:46:30 -0700184 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700185 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700186 }
187 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700188
Eric Anholt43ad37a2010-05-12 14:42:21 -0700189 case ir_unop_neg:
Eric Anholt43ad37a2010-05-12 14:42:21 -0700190 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700191 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700192 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700193 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700194 break;
195 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700196 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700197 break;
198 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700199 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700200 break;
201 default:
202 assert(0);
203 }
204 }
205 break;
206
207 case ir_unop_abs:
208 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700209 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700210 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700211 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700212 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700213 break;
214 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700215 data.i[c] = op[0]->value.i[c];
216 if (data.i[c] < 0)
217 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700218 break;
219 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700220 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700221 break;
222 default:
223 assert(0);
224 }
225 }
226 break;
227
228 case ir_unop_rcp:
229 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700230 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700231 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700232 case GLSL_TYPE_UINT:
233 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700234 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700235 break;
236 case GLSL_TYPE_INT:
237 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700238 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700239 break;
240 case GLSL_TYPE_FLOAT:
241 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700242 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700243 break;
244 default:
245 assert(0);
246 }
247 }
248 break;
249
250 case ir_unop_rsq:
251 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700252 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700253 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700254 }
255 break;
256
257 case ir_unop_sqrt:
258 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700259 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700260 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700261 }
262 break;
263
264 case ir_unop_exp:
265 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700266 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700267 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700268 }
269 break;
270
271 case ir_unop_log:
272 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700273 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700274 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700275 }
276 break;
277
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700278 case ir_unop_dFdx:
279 case ir_unop_dFdy:
280 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700281 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700282 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700283 }
284 break;
285
Eric Anholtd251b922010-04-01 18:35:42 -1000286 case ir_binop_add:
287 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000288 for (c = 0; c < ir->operands[0]->type->components(); c++) {
289 switch (ir->operands[0]->type->base_type) {
290 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700291 data.u[c] = op[0]->value.u[c] + op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000292 break;
293 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700294 data.i[c] = op[0]->value.i[c] + op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000295 break;
296 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700297 data.f[c] = op[0]->value.f[c] + op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000298 break;
299 default:
300 assert(0);
301 }
302 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700303 } else
304 /* FINISHME: Support operations with non-equal types. */
305 return;
306
Eric Anholtd251b922010-04-01 18:35:42 -1000307 break;
308 case ir_binop_sub:
309 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000310 for (c = 0; c < ir->operands[0]->type->components(); c++) {
311 switch (ir->operands[0]->type->base_type) {
312 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700313 data.u[c] = op[0]->value.u[c] - op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000314 break;
315 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700316 data.i[c] = op[0]->value.i[c] - op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000317 break;
318 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700319 data.f[c] = op[0]->value.f[c] - op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000320 break;
321 default:
322 assert(0);
323 }
324 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700325 } else
326 /* FINISHME: Support operations with non-equal types. */
327 return;
328
Eric Anholtd251b922010-04-01 18:35:42 -1000329 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000330 case ir_binop_mul:
Eric Anholtd98da972010-04-01 18:25:11 -1000331 if (ir->operands[0]->type == ir->operands[1]->type &&
332 !ir->operands[0]->type->is_matrix()) {
Eric Anholtd98da972010-04-01 18:25:11 -1000333 for (c = 0; c < ir->operands[0]->type->components(); c++) {
334 switch (ir->operands[0]->type->base_type) {
335 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700336 data.u[c] = op[0]->value.u[c] * op[1]->value.u[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000337 break;
338 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700339 data.i[c] = op[0]->value.i[c] * op[1]->value.i[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000340 break;
341 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700342 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000343 break;
344 default:
345 assert(0);
346 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000347 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700348 } else
349 /* FINISHME: Support operations with non-equal types. */
350 return;
351
Eric Anholta576f9d2010-03-31 16:25:12 -1000352 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000353 case ir_binop_div:
354 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000355 for (c = 0; c < ir->operands[0]->type->components(); c++) {
356 switch (ir->operands[0]->type->base_type) {
357 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700358 data.u[c] = op[0]->value.u[c] / op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000359 break;
360 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700361 data.i[c] = op[0]->value.i[c] / op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000362 break;
363 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700364 data.f[c] = op[0]->value.f[c] / op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000365 break;
366 default:
367 assert(0);
368 }
369 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700370 } else
371 /* FINISHME: Support operations with non-equal types. */
372 return;
373
Eric Anholtd251b922010-04-01 18:35:42 -1000374 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000375 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700376 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000377 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700378 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000379 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000380 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700381 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd251b922010-04-01 18:35:42 -1000382 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700383 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000384 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000385 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700386 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000387 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700388 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000389 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700390
391 case ir_binop_less:
Eric Anholt85171c22010-04-06 09:55:45 -0700392 switch (ir->operands[0]->type->base_type) {
393 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700394 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700395 break;
396 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700397 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700398 break;
399 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700400 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700401 break;
402 default:
403 assert(0);
404 }
405 break;
406 case ir_binop_greater:
Eric Anholt85171c22010-04-06 09:55:45 -0700407 switch (ir->operands[0]->type->base_type) {
408 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700409 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700410 break;
411 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700412 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700413 break;
414 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700415 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700416 break;
417 default:
418 assert(0);
419 }
420 break;
421 case ir_binop_lequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700422 switch (ir->operands[0]->type->base_type) {
423 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700424 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700425 break;
426 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700427 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700428 break;
429 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700430 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700431 break;
432 default:
433 assert(0);
434 }
435 break;
436 case ir_binop_gequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700437 switch (ir->operands[0]->type->base_type) {
438 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700439 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700440 break;
441 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700442 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700443 break;
444 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700445 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700446 break;
447 default:
448 assert(0);
449 }
450 break;
451
Eric Anholtec1949e2010-04-06 10:02:27 -0700452 case ir_binop_equal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700453 data.b[0] = true;
454 for (c = 0; c < ir->operands[0]->type->components(); c++) {
455 switch (ir->operands[0]->type->base_type) {
456 case GLSL_TYPE_UINT:
457 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
458 break;
459 case GLSL_TYPE_INT:
460 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
461 break;
462 case GLSL_TYPE_FLOAT:
463 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
464 break;
465 case GLSL_TYPE_BOOL:
466 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
467 break;
468 default:
469 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700470 }
471 }
472 break;
473 case ir_binop_nequal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700474 data.b[0] = false;
475 for (c = 0; c < ir->operands[0]->type->components(); c++) {
476 switch (ir->operands[0]->type->base_type) {
477 case GLSL_TYPE_UINT:
478 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
479 break;
480 case GLSL_TYPE_INT:
481 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
482 break;
483 case GLSL_TYPE_FLOAT:
484 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
485 break;
486 case GLSL_TYPE_BOOL:
487 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
488 break;
489 default:
490 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700491 }
492 }
493 break;
494
Eric Anholta576f9d2010-03-31 16:25:12 -1000495 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700496 /* FINISHME: Should handle all expression types. */
497 return;
Eric Anholta576f9d2010-03-31 16:25:12 -1000498 }
Eric Anholtd98da972010-04-01 18:25:11 -1000499
Ian Romanickf8b88be2010-06-11 16:23:52 -0700500 this->value = new ir_constant(ir->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700501}
502
503
504void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700505ir_constant_visitor::visit(ir_texture *ir)
506{
507 // FINISHME: Do stuff with texture lookups
508 (void) ir;
509 value = NULL;
510}
511
512
513void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700514ir_constant_visitor::visit(ir_swizzle *ir)
515{
Ian Romanickc2ba6192010-06-11 12:30:28 -0700516 ir_constant *v = ir->val->constant_expression_value();
517
518 this->value = NULL;
519
520 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700521 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700522
523 const unsigned swiz_idx[4] = {
524 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
525 };
526
527 for (unsigned i = 0; i < ir->mask.num_components; i++) {
528 switch (v->type->base_type) {
529 case GLSL_TYPE_UINT:
530 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
531 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
532 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
533 default: assert(!"Should not get here."); break;
534 }
535 }
536
537 this->value = new ir_constant(ir->type, &data);
538 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700539}
540
541
542void
Ian Romanickc7b10462010-05-19 13:20:12 +0200543ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700544{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700545 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700546
Ian Romanickc7b10462010-05-19 13:20:12 +0200547 ir_variable *var = ir->variable_referenced();
548 if (var && var->constant_value)
Ian Romanickd4b33ed2010-06-09 17:19:10 -0700549 value = var->constant_value->clone();
Ian Romanickc7b10462010-05-19 13:20:12 +0200550}
551
552
553void
554ir_constant_visitor::visit(ir_dereference_array *ir)
555{
Ian Romanick9b92af92010-06-11 12:20:12 -0700556 ir_constant *array = ir->array->constant_expression_value();
557 ir_constant *idx = ir->array_index->constant_expression_value();
558
559 this->value = NULL;
560
561 if ((array != NULL) && (idx != NULL)) {
562 if (array->type->is_matrix()) {
563 /* Array access of a matrix results in a vector.
564 */
565 const unsigned column = idx->value.u[0];
566
567 const glsl_type *const column_type = array->type->column_type();
568
569 /* Offset in the constant matrix to the first element of the column
570 * to be extracted.
571 */
572 const unsigned mat_idx = column * column_type->vector_elements;
573
Ian Romanick0bb70a32010-06-11 15:49:49 -0700574 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700575
576 switch (column_type->base_type) {
577 case GLSL_TYPE_UINT:
578 case GLSL_TYPE_INT:
579 for (unsigned i = 0; i < column_type->vector_elements; i++)
580 data.u[i] = array->value.u[mat_idx + i];
581
582 break;
583
584 case GLSL_TYPE_FLOAT:
585 for (unsigned i = 0; i < column_type->vector_elements; i++)
586 data.f[i] = array->value.f[mat_idx + i];
587
588 break;
589
590 default:
591 assert(!"Should not get here.");
592 break;
593 }
594
595 this->value = new ir_constant(column_type, &data);
596 } else if (array->type->is_vector()) {
597 const unsigned component = idx->value.u[0];
598
599 this->value = new ir_constant(array, component);
600 } else {
601 /* FINISHME: Handle access of constant arrays. */
602 }
603 }
Ian Romanickc7b10462010-05-19 13:20:12 +0200604}
605
606
607void
608ir_constant_visitor::visit(ir_dereference_record *ir)
609{
Ian Romanick253dede2010-06-09 17:30:19 -0700610 ir_constant *v = ir->record->constant_expression_value();
611
612 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700613}
614
615
616void
617ir_constant_visitor::visit(ir_assignment *ir)
618{
619 (void) ir;
620 value = NULL;
621}
622
623
624void
625ir_constant_visitor::visit(ir_constant *ir)
626{
627 value = ir;
628}
629
630
631void
632ir_constant_visitor::visit(ir_call *ir)
633{
634 (void) ir;
635 value = NULL;
636}
637
638
639void
640ir_constant_visitor::visit(ir_return *ir)
641{
642 (void) ir;
643 value = NULL;
644}
645
646
647void
648ir_constant_visitor::visit(ir_if *ir)
649{
650 (void) ir;
651 value = NULL;
652}
Ian Romanickfad607a2010-04-05 16:16:07 -0700653
654
655void
656ir_constant_visitor::visit(ir_loop *ir)
657{
658 (void) ir;
659 value = NULL;
660}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700661
662
663void
664ir_constant_visitor::visit(ir_loop_jump *ir)
665{
666 (void) ir;
667 value = NULL;
668}