blob: 3a3d994302e729a5649d891d3ba289c7b3de2ee9 [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
Eric Anholt43ad37a2010-05-12 14:42:21 -070037#include <math.h>
Ian Romanick1cf43a42010-03-30 16:56:50 -070038#include "ir.h"
39#include "ir_visitor.h"
Eric Anholta576f9d2010-03-31 16:25:12 -100040#include "glsl_types.h"
Ian Romanick1cf43a42010-03-30 16:56:50 -070041
42/**
43 * Visitor class for evaluating constant expressions
44 */
45class ir_constant_visitor : public ir_visitor {
46public:
47 ir_constant_visitor()
48 : value(NULL)
49 {
50 /* empty */
51 }
52
53 virtual ~ir_constant_visitor()
54 {
55 /* empty */
56 }
57
58 /**
59 * \name Visit methods
60 *
61 * As typical for the visitor pattern, there must be one \c visit method for
62 * each concrete subclass of \c ir_instruction. Virtual base classes within
63 * the hierarchy should not have \c visit methods.
64 */
65 /*@{*/
66 virtual void visit(ir_variable *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070067 virtual void visit(ir_function_signature *);
68 virtual void visit(ir_function *);
69 virtual void visit(ir_expression *);
Kenneth Graunke26d74cd2010-05-26 17:42:03 -070070 virtual void visit(ir_texture *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070071 virtual void visit(ir_swizzle *);
Ian Romanickc7b10462010-05-19 13:20:12 +020072 virtual void visit(ir_dereference_variable *);
73 virtual void visit(ir_dereference_array *);
74 virtual void visit(ir_dereference_record *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070075 virtual void visit(ir_assignment *);
76 virtual void visit(ir_constant *);
77 virtual void visit(ir_call *);
78 virtual void visit(ir_return *);
79 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;
Eric Anholta576f9d2010-03-31 16:25:12 -1000132 ir_constant *op[2];
Eric Anholtd98da972010-04-01 18:25:11 -1000133 unsigned int operand, c;
Ian Romanick4daaab62010-06-11 16:08:47 -0700134 ir_constant_data data;
Eric Anholtd98da972010-04-01 18:25:11 -1000135 const glsl_type *type = NULL;
Eric Anholt160d0922010-04-01 18:07:08 -1000136
Eric Anholtd98da972010-04-01 18:25:11 -1000137 for (operand = 0; operand < ir->get_num_operands(); operand++) {
138 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
143 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000144 case ir_unop_logic_not:
Eric Anholtd98da972010-04-01 18:25:11 -1000145 type = ir->operands[0]->type;
146 assert(type->base_type == GLSL_TYPE_BOOL);
147 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700148 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000149 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700150
151 case ir_unop_f2i:
152 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
153 type = ir->type;
154 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700155 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700156 }
157 break;
158 case ir_unop_i2f:
159 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
160 op[0]->type->base_type == GLSL_TYPE_INT);
161 type = ir->type;
162 for (c = 0; c < ir->operands[0]->type->components(); c++) {
163 if (op[0]->type->base_type == GLSL_TYPE_INT)
Ian Romanick4daaab62010-06-11 16:08:47 -0700164 data.f[c] = op[0]->value.i[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700165 else
Ian Romanick4daaab62010-06-11 16:08:47 -0700166 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700167 }
168 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700169 case ir_unop_b2f:
170 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
171 type = ir->type;
172 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700173 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700174 }
175 break;
176 case ir_unop_f2b:
177 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
178 type = ir->type;
179 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700180 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700181 }
182 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700183 case ir_unop_b2i:
184 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
185 type = ir->type;
186 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700187 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700188 }
189 break;
190 case ir_unop_i2b:
191 assert(op[0]->type->is_integer());
192 type = ir->type;
193 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700194 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700195 }
196 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700197
Eric Anholt43ad37a2010-05-12 14:42:21 -0700198 case ir_unop_neg:
199 type = ir->type;
200 for (c = 0; c < ir->operands[0]->type->components(); c++) {
201 switch (type->base_type) {
202 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700203 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700204 break;
205 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700206 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700207 break;
208 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700209 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700210 break;
211 default:
212 assert(0);
213 }
214 }
215 break;
216
217 case ir_unop_abs:
218 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
219 type = ir->type;
220 for (c = 0; c < ir->operands[0]->type->components(); c++) {
221 switch (type->base_type) {
222 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700223 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700224 break;
225 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700226 data.i[c] = op[0]->value.i[c];
227 if (data.i[c] < 0)
228 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700229 break;
230 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700231 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700232 break;
233 default:
234 assert(0);
235 }
236 }
237 break;
238
239 case ir_unop_rcp:
240 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
241 type = ir->type;
242 for (c = 0; c < ir->operands[0]->type->components(); c++) {
243 switch (type->base_type) {
244 case GLSL_TYPE_UINT:
245 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700246 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700247 break;
248 case GLSL_TYPE_INT:
249 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700250 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700251 break;
252 case GLSL_TYPE_FLOAT:
253 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700254 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700255 break;
256 default:
257 assert(0);
258 }
259 }
260 break;
261
262 case ir_unop_rsq:
263 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
264 type = ir->type;
265 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700266 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700267 }
268 break;
269
270 case ir_unop_sqrt:
271 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
272 type = ir->type;
273 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700274 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700275 }
276 break;
277
278 case ir_unop_exp:
279 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
280 type = ir->type;
281 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700282 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700283 }
284 break;
285
286 case ir_unop_log:
287 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
288 type = ir->type;
289 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700290 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700291 }
292 break;
293
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700294 case ir_unop_dFdx:
295 case ir_unop_dFdy:
296 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
297 type = ir->type;
298 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700299 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700300 }
301 break;
302
Eric Anholtd251b922010-04-01 18:35:42 -1000303 case ir_binop_add:
304 if (ir->operands[0]->type == ir->operands[1]->type) {
305 type = ir->operands[0]->type;
306 for (c = 0; c < ir->operands[0]->type->components(); c++) {
307 switch (ir->operands[0]->type->base_type) {
308 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700309 data.u[c] = op[0]->value.u[c] + op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000310 break;
311 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700312 data.i[c] = op[0]->value.i[c] + op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000313 break;
314 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700315 data.f[c] = op[0]->value.f[c] + op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000316 break;
317 default:
318 assert(0);
319 }
320 }
321 }
322 break;
323 case ir_binop_sub:
324 if (ir->operands[0]->type == ir->operands[1]->type) {
325 type = ir->operands[0]->type;
326 for (c = 0; c < ir->operands[0]->type->components(); c++) {
327 switch (ir->operands[0]->type->base_type) {
328 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700329 data.u[c] = op[0]->value.u[c] - op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000330 break;
331 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700332 data.i[c] = op[0]->value.i[c] - op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000333 break;
334 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700335 data.f[c] = op[0]->value.f[c] - op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000336 break;
337 default:
338 assert(0);
339 }
340 }
341 }
342 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000343 case ir_binop_mul:
Eric Anholtd98da972010-04-01 18:25:11 -1000344 if (ir->operands[0]->type == ir->operands[1]->type &&
345 !ir->operands[0]->type->is_matrix()) {
346 type = ir->operands[0]->type;
347 for (c = 0; c < ir->operands[0]->type->components(); c++) {
348 switch (ir->operands[0]->type->base_type) {
349 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700350 data.u[c] = op[0]->value.u[c] * op[1]->value.u[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000351 break;
352 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700353 data.i[c] = op[0]->value.i[c] * op[1]->value.i[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000354 break;
355 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700356 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000357 break;
358 default:
359 assert(0);
360 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000361 }
362 }
363 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000364 case ir_binop_div:
365 if (ir->operands[0]->type == ir->operands[1]->type) {
366 type = ir->operands[0]->type;
367 for (c = 0; c < ir->operands[0]->type->components(); c++) {
368 switch (ir->operands[0]->type->base_type) {
369 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700370 data.u[c] = op[0]->value.u[c] / op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000371 break;
372 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700373 data.i[c] = op[0]->value.i[c] / op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000374 break;
375 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700376 data.f[c] = op[0]->value.f[c] / op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000377 break;
378 default:
379 assert(0);
380 }
381 }
382 }
383 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000384 case ir_binop_logic_and:
Eric Anholtd98da972010-04-01 18:25:11 -1000385 type = ir->operands[0]->type;
386 assert(type->base_type == GLSL_TYPE_BOOL);
387 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 Anholtd251b922010-04-01 18:35:42 -1000390 case ir_binop_logic_xor:
391 type = ir->operands[0]->type;
392 assert(type->base_type == GLSL_TYPE_BOOL);
393 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700394 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000395 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000396 case ir_binop_logic_or:
Eric Anholtd98da972010-04-01 18:25:11 -1000397 type = ir->operands[0]->type;
398 assert(type->base_type == GLSL_TYPE_BOOL);
399 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700400 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000401 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700402
403 case ir_binop_less:
404 type = glsl_type::bool_type;
405 switch (ir->operands[0]->type->base_type) {
406 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700407 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700408 break;
409 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700410 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700411 break;
412 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700413 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700414 break;
415 default:
416 assert(0);
417 }
418 break;
419 case ir_binop_greater:
420 type = glsl_type::bool_type;
421 switch (ir->operands[0]->type->base_type) {
422 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700423 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700424 break;
425 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700426 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700427 break;
428 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700429 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700430 break;
431 default:
432 assert(0);
433 }
434 break;
435 case ir_binop_lequal:
436 type = glsl_type::bool_type;
437 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 case ir_binop_gequal:
452 type = glsl_type::bool_type;
453 switch (ir->operands[0]->type->base_type) {
454 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700455 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700456 break;
457 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700458 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700459 break;
460 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700461 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700462 break;
463 default:
464 assert(0);
465 }
466 break;
467
Eric Anholtec1949e2010-04-06 10:02:27 -0700468 case ir_binop_equal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700469 type = glsl_type::bool_type;
470 data.b[0] = true;
471 for (c = 0; c < ir->operands[0]->type->components(); c++) {
472 switch (ir->operands[0]->type->base_type) {
473 case GLSL_TYPE_UINT:
474 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
475 break;
476 case GLSL_TYPE_INT:
477 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
478 break;
479 case GLSL_TYPE_FLOAT:
480 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
481 break;
482 case GLSL_TYPE_BOOL:
483 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
484 break;
485 default:
486 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700487 }
488 }
489 break;
490 case ir_binop_nequal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700491 type = glsl_type::bool_type;
492 data.b[0] = false;
493 for (c = 0; c < ir->operands[0]->type->components(); c++) {
494 switch (ir->operands[0]->type->base_type) {
495 case GLSL_TYPE_UINT:
496 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
497 break;
498 case GLSL_TYPE_INT:
499 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
500 break;
501 case GLSL_TYPE_FLOAT:
502 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
503 break;
504 case GLSL_TYPE_BOOL:
505 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
506 break;
507 default:
508 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700509 }
510 }
511 break;
512
Eric Anholta576f9d2010-03-31 16:25:12 -1000513 default:
514 break;
515 }
Eric Anholtd98da972010-04-01 18:25:11 -1000516
517 if (type) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700518 this->value = new ir_constant(type, &data);
Eric Anholtd98da972010-04-01 18:25:11 -1000519 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700520}
521
522
523void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700524ir_constant_visitor::visit(ir_texture *ir)
525{
526 // FINISHME: Do stuff with texture lookups
527 (void) ir;
528 value = NULL;
529}
530
531
532void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700533ir_constant_visitor::visit(ir_swizzle *ir)
534{
Ian Romanickc2ba6192010-06-11 12:30:28 -0700535 ir_constant *v = ir->val->constant_expression_value();
536
537 this->value = NULL;
538
539 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700540 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700541
542 const unsigned swiz_idx[4] = {
543 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
544 };
545
546 for (unsigned i = 0; i < ir->mask.num_components; i++) {
547 switch (v->type->base_type) {
548 case GLSL_TYPE_UINT:
549 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
550 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
551 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
552 default: assert(!"Should not get here."); break;
553 }
554 }
555
556 this->value = new ir_constant(ir->type, &data);
557 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700558}
559
560
561void
Ian Romanickc7b10462010-05-19 13:20:12 +0200562ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700563{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700564 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700565
Ian Romanickc7b10462010-05-19 13:20:12 +0200566 ir_variable *var = ir->variable_referenced();
567 if (var && var->constant_value)
Ian Romanickd4b33ed2010-06-09 17:19:10 -0700568 value = var->constant_value->clone();
Ian Romanickc7b10462010-05-19 13:20:12 +0200569}
570
571
572void
573ir_constant_visitor::visit(ir_dereference_array *ir)
574{
Ian Romanick9b92af92010-06-11 12:20:12 -0700575 ir_constant *array = ir->array->constant_expression_value();
576 ir_constant *idx = ir->array_index->constant_expression_value();
577
578 this->value = NULL;
579
580 if ((array != NULL) && (idx != NULL)) {
581 if (array->type->is_matrix()) {
582 /* Array access of a matrix results in a vector.
583 */
584 const unsigned column = idx->value.u[0];
585
586 const glsl_type *const column_type = array->type->column_type();
587
588 /* Offset in the constant matrix to the first element of the column
589 * to be extracted.
590 */
591 const unsigned mat_idx = column * column_type->vector_elements;
592
Ian Romanick0bb70a32010-06-11 15:49:49 -0700593 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700594
595 switch (column_type->base_type) {
596 case GLSL_TYPE_UINT:
597 case GLSL_TYPE_INT:
598 for (unsigned i = 0; i < column_type->vector_elements; i++)
599 data.u[i] = array->value.u[mat_idx + i];
600
601 break;
602
603 case GLSL_TYPE_FLOAT:
604 for (unsigned i = 0; i < column_type->vector_elements; i++)
605 data.f[i] = array->value.f[mat_idx + i];
606
607 break;
608
609 default:
610 assert(!"Should not get here.");
611 break;
612 }
613
614 this->value = new ir_constant(column_type, &data);
615 } else if (array->type->is_vector()) {
616 const unsigned component = idx->value.u[0];
617
618 this->value = new ir_constant(array, component);
619 } else {
620 /* FINISHME: Handle access of constant arrays. */
621 }
622 }
Ian Romanickc7b10462010-05-19 13:20:12 +0200623}
624
625
626void
627ir_constant_visitor::visit(ir_dereference_record *ir)
628{
Ian Romanick253dede2010-06-09 17:30:19 -0700629 ir_constant *v = ir->record->constant_expression_value();
630
631 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700632}
633
634
635void
636ir_constant_visitor::visit(ir_assignment *ir)
637{
638 (void) ir;
639 value = NULL;
640}
641
642
643void
644ir_constant_visitor::visit(ir_constant *ir)
645{
646 value = ir;
647}
648
649
650void
651ir_constant_visitor::visit(ir_call *ir)
652{
653 (void) ir;
654 value = NULL;
655}
656
657
658void
659ir_constant_visitor::visit(ir_return *ir)
660{
661 (void) ir;
662 value = NULL;
663}
664
665
666void
667ir_constant_visitor::visit(ir_if *ir)
668{
669 (void) ir;
670 value = NULL;
671}
Ian Romanickfad607a2010-04-05 16:16:07 -0700672
673
674void
675ir_constant_visitor::visit(ir_loop *ir)
676{
677 (void) ir;
678 value = NULL;
679}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700680
681
682void
683ir_constant_visitor::visit(ir_loop_jump *ir)
684{
685 (void) ir;
686 value = NULL;
687}