blob: 5bb592079a967cfda5788ca704fd007012b099a7 [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 Anholt160d0922010-04-01 18:07:08 -1000135
Eric Anholtd98da972010-04-01 18:25:11 -1000136 for (operand = 0; operand < ir->get_num_operands(); operand++) {
137 op[operand] = ir->operands[operand]->constant_expression_value();
138 if (!op[operand])
Eric Anholt160d0922010-04-01 18:07:08 -1000139 return;
140 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000141
142 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000143 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700144 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000145 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700146 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000147 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700148
149 case ir_unop_f2i:
150 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholtaf186412010-04-06 10:53:57 -0700151 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700152 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700153 }
154 break;
155 case ir_unop_i2f:
156 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
157 op[0]->type->base_type == GLSL_TYPE_INT);
Eric Anholtaf186412010-04-06 10:53:57 -0700158 for (c = 0; c < ir->operands[0]->type->components(); c++) {
159 if (op[0]->type->base_type == GLSL_TYPE_INT)
Ian Romanick4daaab62010-06-11 16:08:47 -0700160 data.f[c] = op[0]->value.i[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700161 else
Ian Romanick4daaab62010-06-11 16:08:47 -0700162 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700163 }
164 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700165 case ir_unop_b2f:
166 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700167 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700168 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700169 }
170 break;
171 case ir_unop_f2b:
172 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700173 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700174 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700175 }
176 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700177 case ir_unop_b2i:
178 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700179 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700180 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700181 }
182 break;
183 case ir_unop_i2b:
184 assert(op[0]->type->is_integer());
Ian Romanick39d6dd32010-06-11 13:46:30 -0700185 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700186 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700187 }
188 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700189
Eric Anholt43ad37a2010-05-12 14:42:21 -0700190 case ir_unop_neg:
Eric Anholt43ad37a2010-05-12 14:42:21 -0700191 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700192 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700193 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700194 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700195 break;
196 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700197 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700198 break;
199 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700200 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700201 break;
202 default:
203 assert(0);
204 }
205 }
206 break;
207
208 case ir_unop_abs:
209 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700210 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700211 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700212 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700213 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700214 break;
215 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700216 data.i[c] = op[0]->value.i[c];
217 if (data.i[c] < 0)
218 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700219 break;
220 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700221 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700222 break;
223 default:
224 assert(0);
225 }
226 }
227 break;
228
229 case ir_unop_rcp:
230 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700231 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700232 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700233 case GLSL_TYPE_UINT:
234 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700235 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700236 break;
237 case GLSL_TYPE_INT:
238 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700239 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700240 break;
241 case GLSL_TYPE_FLOAT:
242 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700243 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700244 break;
245 default:
246 assert(0);
247 }
248 }
249 break;
250
251 case ir_unop_rsq:
252 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700253 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700254 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700255 }
256 break;
257
258 case ir_unop_sqrt:
259 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700260 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700261 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700262 }
263 break;
264
265 case ir_unop_exp:
266 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700267 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700268 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700269 }
270 break;
271
272 case ir_unop_log:
273 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700274 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700275 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700276 }
277 break;
278
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700279 case ir_unop_dFdx:
280 case ir_unop_dFdy:
281 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700282 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700283 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700284 }
285 break;
286
Eric Anholtd251b922010-04-01 18:35:42 -1000287 case ir_binop_add:
288 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000289 for (c = 0; c < ir->operands[0]->type->components(); c++) {
290 switch (ir->operands[0]->type->base_type) {
291 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700292 data.u[c] = op[0]->value.u[c] + op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000293 break;
294 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700295 data.i[c] = op[0]->value.i[c] + op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000296 break;
297 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700298 data.f[c] = op[0]->value.f[c] + op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000299 break;
300 default:
301 assert(0);
302 }
303 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700304 } else
305 /* FINISHME: Support operations with non-equal types. */
306 return;
307
Eric Anholtd251b922010-04-01 18:35:42 -1000308 break;
309 case ir_binop_sub:
310 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000311 for (c = 0; c < ir->operands[0]->type->components(); c++) {
312 switch (ir->operands[0]->type->base_type) {
313 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700314 data.u[c] = op[0]->value.u[c] - op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000315 break;
316 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700317 data.i[c] = op[0]->value.i[c] - op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000318 break;
319 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700320 data.f[c] = op[0]->value.f[c] - op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000321 break;
322 default:
323 assert(0);
324 }
325 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700326 } else
327 /* FINISHME: Support operations with non-equal types. */
328 return;
329
Eric Anholtd251b922010-04-01 18:35:42 -1000330 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000331 case ir_binop_mul:
Eric Anholtd98da972010-04-01 18:25:11 -1000332 if (ir->operands[0]->type == ir->operands[1]->type &&
333 !ir->operands[0]->type->is_matrix()) {
Eric Anholtd98da972010-04-01 18:25:11 -1000334 for (c = 0; c < ir->operands[0]->type->components(); c++) {
335 switch (ir->operands[0]->type->base_type) {
336 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700337 data.u[c] = op[0]->value.u[c] * op[1]->value.u[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000338 break;
339 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700340 data.i[c] = op[0]->value.i[c] * op[1]->value.i[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000341 break;
342 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700343 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000344 break;
345 default:
346 assert(0);
347 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000348 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700349 } else
350 /* FINISHME: Support operations with non-equal types. */
351 return;
352
Eric Anholta576f9d2010-03-31 16:25:12 -1000353 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000354 case ir_binop_div:
355 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000356 for (c = 0; c < ir->operands[0]->type->components(); c++) {
357 switch (ir->operands[0]->type->base_type) {
358 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700359 data.u[c] = op[0]->value.u[c] / op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000360 break;
361 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700362 data.i[c] = op[0]->value.i[c] / op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000363 break;
364 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700365 data.f[c] = op[0]->value.f[c] / op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000366 break;
367 default:
368 assert(0);
369 }
370 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700371 } else
372 /* FINISHME: Support operations with non-equal types. */
373 return;
374
Eric Anholtd251b922010-04-01 18:35:42 -1000375 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000376 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700377 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000378 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700379 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000380 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000381 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700382 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd251b922010-04-01 18:35:42 -1000383 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700384 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000385 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000386 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700387 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000388 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700389 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000390 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700391
392 case ir_binop_less:
Eric Anholt85171c22010-04-06 09:55:45 -0700393 switch (ir->operands[0]->type->base_type) {
394 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700395 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700396 break;
397 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700398 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700399 break;
400 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700401 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700402 break;
403 default:
404 assert(0);
405 }
406 break;
407 case ir_binop_greater:
Eric Anholt85171c22010-04-06 09:55:45 -0700408 switch (ir->operands[0]->type->base_type) {
409 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700410 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700411 break;
412 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700413 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700414 break;
415 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700416 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700417 break;
418 default:
419 assert(0);
420 }
421 break;
422 case ir_binop_lequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700423 switch (ir->operands[0]->type->base_type) {
424 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700425 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700426 break;
427 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700428 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700429 break;
430 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700431 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700432 break;
433 default:
434 assert(0);
435 }
436 break;
437 case ir_binop_gequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700438 switch (ir->operands[0]->type->base_type) {
439 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700440 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700441 break;
442 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700443 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700444 break;
445 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700446 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700447 break;
448 default:
449 assert(0);
450 }
451 break;
452
Eric Anholtec1949e2010-04-06 10:02:27 -0700453 case ir_binop_equal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700454 data.b[0] = true;
455 for (c = 0; c < ir->operands[0]->type->components(); c++) {
456 switch (ir->operands[0]->type->base_type) {
457 case GLSL_TYPE_UINT:
458 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
459 break;
460 case GLSL_TYPE_INT:
461 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
462 break;
463 case GLSL_TYPE_FLOAT:
464 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
465 break;
466 case GLSL_TYPE_BOOL:
467 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
468 break;
469 default:
470 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700471 }
472 }
473 break;
474 case ir_binop_nequal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700475 data.b[0] = false;
476 for (c = 0; c < ir->operands[0]->type->components(); c++) {
477 switch (ir->operands[0]->type->base_type) {
478 case GLSL_TYPE_UINT:
479 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
480 break;
481 case GLSL_TYPE_INT:
482 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
483 break;
484 case GLSL_TYPE_FLOAT:
485 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
486 break;
487 case GLSL_TYPE_BOOL:
488 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
489 break;
490 default:
491 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700492 }
493 }
494 break;
495
Eric Anholta576f9d2010-03-31 16:25:12 -1000496 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700497 /* FINISHME: Should handle all expression types. */
498 return;
Eric Anholta576f9d2010-03-31 16:25:12 -1000499 }
Eric Anholtd98da972010-04-01 18:25:11 -1000500
Ian Romanickf8b88be2010-06-11 16:23:52 -0700501 this->value = new ir_constant(ir->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700502}
503
504
505void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700506ir_constant_visitor::visit(ir_texture *ir)
507{
508 // FINISHME: Do stuff with texture lookups
509 (void) ir;
510 value = NULL;
511}
512
513
514void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700515ir_constant_visitor::visit(ir_swizzle *ir)
516{
Ian Romanickc2ba6192010-06-11 12:30:28 -0700517 ir_constant *v = ir->val->constant_expression_value();
518
519 this->value = NULL;
520
521 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700522 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700523
524 const unsigned swiz_idx[4] = {
525 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
526 };
527
528 for (unsigned i = 0; i < ir->mask.num_components; i++) {
529 switch (v->type->base_type) {
530 case GLSL_TYPE_UINT:
531 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
532 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
533 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
534 default: assert(!"Should not get here."); break;
535 }
536 }
537
538 this->value = new ir_constant(ir->type, &data);
539 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700540}
541
542
543void
Ian Romanickc7b10462010-05-19 13:20:12 +0200544ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700545{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700546 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700547
Ian Romanickc7b10462010-05-19 13:20:12 +0200548 ir_variable *var = ir->variable_referenced();
549 if (var && var->constant_value)
Ian Romanickd4b33ed2010-06-09 17:19:10 -0700550 value = var->constant_value->clone();
Ian Romanickc7b10462010-05-19 13:20:12 +0200551}
552
553
554void
555ir_constant_visitor::visit(ir_dereference_array *ir)
556{
Ian Romanick9b92af92010-06-11 12:20:12 -0700557 ir_constant *array = ir->array->constant_expression_value();
558 ir_constant *idx = ir->array_index->constant_expression_value();
559
560 this->value = NULL;
561
562 if ((array != NULL) && (idx != NULL)) {
563 if (array->type->is_matrix()) {
564 /* Array access of a matrix results in a vector.
565 */
566 const unsigned column = idx->value.u[0];
567
568 const glsl_type *const column_type = array->type->column_type();
569
570 /* Offset in the constant matrix to the first element of the column
571 * to be extracted.
572 */
573 const unsigned mat_idx = column * column_type->vector_elements;
574
Ian Romanick0bb70a32010-06-11 15:49:49 -0700575 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700576
577 switch (column_type->base_type) {
578 case GLSL_TYPE_UINT:
579 case GLSL_TYPE_INT:
580 for (unsigned i = 0; i < column_type->vector_elements; i++)
581 data.u[i] = array->value.u[mat_idx + i];
582
583 break;
584
585 case GLSL_TYPE_FLOAT:
586 for (unsigned i = 0; i < column_type->vector_elements; i++)
587 data.f[i] = array->value.f[mat_idx + i];
588
589 break;
590
591 default:
592 assert(!"Should not get here.");
593 break;
594 }
595
596 this->value = new ir_constant(column_type, &data);
597 } else if (array->type->is_vector()) {
598 const unsigned component = idx->value.u[0];
599
600 this->value = new ir_constant(array, component);
601 } else {
602 /* FINISHME: Handle access of constant arrays. */
603 }
604 }
Ian Romanickc7b10462010-05-19 13:20:12 +0200605}
606
607
608void
609ir_constant_visitor::visit(ir_dereference_record *ir)
610{
Ian Romanick253dede2010-06-09 17:30:19 -0700611 ir_constant *v = ir->record->constant_expression_value();
612
613 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700614}
615
616
617void
618ir_constant_visitor::visit(ir_assignment *ir)
619{
620 (void) ir;
621 value = NULL;
622}
623
624
625void
626ir_constant_visitor::visit(ir_constant *ir)
627{
628 value = ir;
629}
630
631
632void
633ir_constant_visitor::visit(ir_call *ir)
634{
635 (void) ir;
636 value = NULL;
637}
638
639
640void
641ir_constant_visitor::visit(ir_return *ir)
642{
643 (void) ir;
644 value = NULL;
645}
646
647
648void
649ir_constant_visitor::visit(ir_if *ir)
650{
651 (void) ir;
652 value = NULL;
653}
Ian Romanickfad607a2010-04-05 16:16:07 -0700654
655
656void
657ir_constant_visitor::visit(ir_loop *ir)
658{
659 (void) ir;
660 value = NULL;
661}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700662
663
664void
665ir_constant_visitor::visit(ir_loop_jump *ir)
666{
667 (void) ir;
668 value = NULL;
669}