blob: 548217cddd969ee7c9cc8b8cfaf4053d645bfd27 [file] [log] [blame]
Ian Romanick1cf43a42010-03-30 16:56:50 -07001/*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24/**
25 * \file ir_constant_expression.cpp
26 * Evaluate and process constant valued expressions
27 *
28 * In GLSL, constant valued expressions are used in several places. These
29 * must be processed and evaluated very early in the compilation process.
30 *
31 * * Sizes of arrays
32 * * Initializers for uniforms
33 * * Initializers for \c const variables
34 */
35
Eric Anholt43ad37a2010-05-12 14:42:21 -070036#include <math.h>
Ian Romanick1cf43a42010-03-30 16:56:50 -070037#include "ir.h"
38#include "ir_visitor.h"
Eric Anholta576f9d2010-03-31 16:25:12 -100039#include "glsl_types.h"
Ian Romanick1cf43a42010-03-30 16:56:50 -070040
41/**
42 * Visitor class for evaluating constant expressions
43 */
44class ir_constant_visitor : public ir_visitor {
45public:
46 ir_constant_visitor()
47 : value(NULL)
48 {
49 /* empty */
50 }
51
52 virtual ~ir_constant_visitor()
53 {
54 /* empty */
55 }
56
57 /**
58 * \name Visit methods
59 *
60 * As typical for the visitor pattern, there must be one \c visit method for
61 * each concrete subclass of \c ir_instruction. Virtual base classes within
62 * the hierarchy should not have \c visit methods.
63 */
64 /*@{*/
65 virtual void visit(ir_variable *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070066 virtual void visit(ir_function_signature *);
67 virtual void visit(ir_function *);
68 virtual void visit(ir_expression *);
Kenneth Graunke26d74cd2010-05-26 17:42:03 -070069 virtual void visit(ir_texture *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070070 virtual void visit(ir_swizzle *);
Ian Romanickc7b10462010-05-19 13:20:12 +020071 virtual void visit(ir_dereference_variable *);
72 virtual void visit(ir_dereference_array *);
73 virtual void visit(ir_dereference_record *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070074 virtual void visit(ir_assignment *);
75 virtual void visit(ir_constant *);
76 virtual void visit(ir_call *);
77 virtual void visit(ir_return *);
Kenneth Graunke16efab12010-06-30 10:47:34 -070078 virtual void visit(ir_discard *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070079 virtual void visit(ir_if *);
Ian Romanickfad607a2010-04-05 16:16:07 -070080 virtual void visit(ir_loop *);
Ian Romanickf8e31e02010-04-05 16:28:15 -070081 virtual void visit(ir_loop_jump *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070082 /*@}*/
83
84 /**
85 * Value of the constant expression.
86 *
87 * \note
88 * This field will be \c NULL if the expression is not constant valued.
89 */
90 /* FINIHSME: This cannot hold values for constant arrays or structures. */
91 ir_constant *value;
92};
93
94
95ir_constant *
96ir_instruction::constant_expression_value()
97{
98 ir_constant_visitor visitor;
99
100 this->accept(& visitor);
101 return visitor.value;
102}
103
104
105void
106ir_constant_visitor::visit(ir_variable *ir)
107{
108 (void) ir;
109 value = NULL;
110}
111
112
113void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700114ir_constant_visitor::visit(ir_function_signature *ir)
115{
116 (void) ir;
117 value = NULL;
118}
119
120
121void
122ir_constant_visitor::visit(ir_function *ir)
123{
124 (void) ir;
125 value = NULL;
126}
127
Ian Romanick1cf43a42010-03-30 16:56:50 -0700128void
129ir_constant_visitor::visit(ir_expression *ir)
130{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700131 value = NULL;
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 Anholtd925c912010-07-01 10:37:11 -0700190 case ir_unop_fract:
191 for (c = 0; c < ir->operands[0]->type->components(); c++) {
192 switch (ir->type->base_type) {
193 case GLSL_TYPE_UINT:
194 data.u[c] = 0;
195 break;
196 case GLSL_TYPE_INT:
197 data.i[c] = 0;
198 break;
199 case GLSL_TYPE_FLOAT:
200 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
201 break;
202 default:
203 assert(0);
204 }
205 }
206 break;
207
Eric Anholt43ad37a2010-05-12 14:42:21 -0700208 case ir_unop_neg:
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];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700216 break;
217 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700218 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700219 break;
220 default:
221 assert(0);
222 }
223 }
224 break;
225
226 case ir_unop_abs:
227 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700228 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700229 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700230 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700231 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700232 break;
233 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700234 data.i[c] = op[0]->value.i[c];
235 if (data.i[c] < 0)
236 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700237 break;
238 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700239 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700240 break;
241 default:
242 assert(0);
243 }
244 }
245 break;
246
247 case ir_unop_rcp:
248 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700249 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700250 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700251 case GLSL_TYPE_UINT:
252 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700253 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700254 break;
255 case GLSL_TYPE_INT:
256 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700257 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700258 break;
259 case GLSL_TYPE_FLOAT:
260 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700261 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700262 break;
263 default:
264 assert(0);
265 }
266 }
267 break;
268
269 case ir_unop_rsq:
270 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700271 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700272 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700273 }
274 break;
275
276 case ir_unop_sqrt:
277 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700278 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700279 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700280 }
281 break;
282
283 case ir_unop_exp:
284 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700285 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700286 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700287 }
288 break;
289
290 case ir_unop_log:
291 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700292 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700293 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700294 }
295 break;
296
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700297 case ir_unop_dFdx:
298 case ir_unop_dFdy:
299 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700300 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700301 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700302 }
303 break;
304
Eric Anholtd251b922010-04-01 18:35:42 -1000305 case ir_binop_add:
306 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000307 for (c = 0; c < ir->operands[0]->type->components(); c++) {
308 switch (ir->operands[0]->type->base_type) {
309 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700310 data.u[c] = op[0]->value.u[c] + op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000311 break;
312 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700313 data.i[c] = op[0]->value.i[c] + op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000314 break;
315 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700316 data.f[c] = op[0]->value.f[c] + op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000317 break;
318 default:
319 assert(0);
320 }
321 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700322 } else
323 /* FINISHME: Support operations with non-equal types. */
324 return;
325
Eric Anholtd251b922010-04-01 18:35:42 -1000326 break;
327 case ir_binop_sub:
328 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000329 for (c = 0; c < ir->operands[0]->type->components(); c++) {
330 switch (ir->operands[0]->type->base_type) {
331 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700332 data.u[c] = op[0]->value.u[c] - op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000333 break;
334 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700335 data.i[c] = op[0]->value.i[c] - op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000336 break;
337 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700338 data.f[c] = op[0]->value.f[c] - op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000339 break;
340 default:
341 assert(0);
342 }
343 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700344 } else
345 /* FINISHME: Support operations with non-equal types. */
346 return;
347
Eric Anholtd251b922010-04-01 18:35:42 -1000348 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000349 case ir_binop_mul:
Eric Anholtd98da972010-04-01 18:25:11 -1000350 if (ir->operands[0]->type == ir->operands[1]->type &&
351 !ir->operands[0]->type->is_matrix()) {
Eric Anholtd98da972010-04-01 18:25:11 -1000352 for (c = 0; c < ir->operands[0]->type->components(); c++) {
353 switch (ir->operands[0]->type->base_type) {
354 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700355 data.u[c] = op[0]->value.u[c] * op[1]->value.u[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000356 break;
357 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700358 data.i[c] = op[0]->value.i[c] * op[1]->value.i[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000359 break;
360 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700361 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000362 break;
363 default:
364 assert(0);
365 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000366 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700367 } else
368 /* FINISHME: Support operations with non-equal types. */
369 return;
370
Eric Anholta576f9d2010-03-31 16:25:12 -1000371 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000372 case ir_binop_div:
373 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000374 for (c = 0; c < ir->operands[0]->type->components(); c++) {
375 switch (ir->operands[0]->type->base_type) {
376 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700377 data.u[c] = op[0]->value.u[c] / op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000378 break;
379 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700380 data.i[c] = op[0]->value.i[c] / op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000381 break;
382 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700383 data.f[c] = op[0]->value.f[c] / op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000384 break;
385 default:
386 assert(0);
387 }
388 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700389 } else
390 /* FINISHME: Support operations with non-equal types. */
391 return;
392
Eric Anholtd251b922010-04-01 18:35:42 -1000393 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000394 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700395 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000396 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700397 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000398 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000399 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700400 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd251b922010-04-01 18:35:42 -1000401 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700402 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000403 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000404 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700405 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000406 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700407 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000408 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700409
410 case ir_binop_less:
Eric Anholt85171c22010-04-06 09:55:45 -0700411 switch (ir->operands[0]->type->base_type) {
412 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700413 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700414 break;
415 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700416 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700417 break;
418 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700419 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700420 break;
421 default:
422 assert(0);
423 }
424 break;
425 case ir_binop_greater:
Eric Anholt85171c22010-04-06 09:55:45 -0700426 switch (ir->operands[0]->type->base_type) {
427 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700428 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700429 break;
430 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700431 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700432 break;
433 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700434 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700435 break;
436 default:
437 assert(0);
438 }
439 break;
440 case ir_binop_lequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700441 switch (ir->operands[0]->type->base_type) {
442 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700443 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700444 break;
445 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700446 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700447 break;
448 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700449 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700450 break;
451 default:
452 assert(0);
453 }
454 break;
455 case ir_binop_gequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700456 switch (ir->operands[0]->type->base_type) {
457 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700458 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700459 break;
460 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700461 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700462 break;
463 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700464 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700465 break;
466 default:
467 assert(0);
468 }
469 break;
470
Eric Anholtec1949e2010-04-06 10:02:27 -0700471 case ir_binop_equal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700472 data.b[0] = true;
473 for (c = 0; c < ir->operands[0]->type->components(); c++) {
474 switch (ir->operands[0]->type->base_type) {
475 case GLSL_TYPE_UINT:
476 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
477 break;
478 case GLSL_TYPE_INT:
479 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
480 break;
481 case GLSL_TYPE_FLOAT:
482 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
483 break;
484 case GLSL_TYPE_BOOL:
485 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
486 break;
487 default:
488 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700489 }
490 }
491 break;
492 case ir_binop_nequal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700493 data.b[0] = false;
494 for (c = 0; c < ir->operands[0]->type->components(); c++) {
495 switch (ir->operands[0]->type->base_type) {
496 case GLSL_TYPE_UINT:
497 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
498 break;
499 case GLSL_TYPE_INT:
500 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
501 break;
502 case GLSL_TYPE_FLOAT:
503 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
504 break;
505 case GLSL_TYPE_BOOL:
506 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
507 break;
508 default:
509 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700510 }
511 }
512 break;
513
Eric Anholta576f9d2010-03-31 16:25:12 -1000514 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700515 /* FINISHME: Should handle all expression types. */
516 return;
Eric Anholta576f9d2010-03-31 16:25:12 -1000517 }
Eric Anholtd98da972010-04-01 18:25:11 -1000518
Eric Anholt6b01b502010-06-24 15:18:39 -0700519 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700520 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700521}
522
523
524void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700525ir_constant_visitor::visit(ir_texture *ir)
526{
527 // FINISHME: Do stuff with texture lookups
528 (void) ir;
529 value = NULL;
530}
531
532
533void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700534ir_constant_visitor::visit(ir_swizzle *ir)
535{
Ian Romanickc2ba6192010-06-11 12:30:28 -0700536 ir_constant *v = ir->val->constant_expression_value();
537
538 this->value = NULL;
539
540 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700541 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700542
543 const unsigned swiz_idx[4] = {
544 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
545 };
546
547 for (unsigned i = 0; i < ir->mask.num_components; i++) {
548 switch (v->type->base_type) {
549 case GLSL_TYPE_UINT:
550 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
551 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
552 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
553 default: assert(!"Should not get here."); break;
554 }
555 }
556
Eric Anholt6b01b502010-06-24 15:18:39 -0700557 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700558 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700559 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700560}
561
562
563void
Ian Romanickc7b10462010-05-19 13:20:12 +0200564ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700565{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700566 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700567
Ian Romanickc7b10462010-05-19 13:20:12 +0200568 ir_variable *var = ir->variable_referenced();
569 if (var && var->constant_value)
Eric Anholt4b6fd392010-06-23 11:37:12 -0700570 value = (ir_constant *)var->constant_value->clone(NULL);
Ian Romanickc7b10462010-05-19 13:20:12 +0200571}
572
573
574void
575ir_constant_visitor::visit(ir_dereference_array *ir)
576{
Carl Worth1660a292010-06-23 18:11:51 -0700577 void *ctx = talloc_parent(ir);
Ian Romanick9b92af92010-06-11 12:20:12 -0700578 ir_constant *array = ir->array->constant_expression_value();
579 ir_constant *idx = ir->array_index->constant_expression_value();
580
581 this->value = NULL;
582
583 if ((array != NULL) && (idx != NULL)) {
584 if (array->type->is_matrix()) {
585 /* Array access of a matrix results in a vector.
586 */
587 const unsigned column = idx->value.u[0];
588
589 const glsl_type *const column_type = array->type->column_type();
590
591 /* Offset in the constant matrix to the first element of the column
592 * to be extracted.
593 */
594 const unsigned mat_idx = column * column_type->vector_elements;
595
Ian Romanick0bb70a32010-06-11 15:49:49 -0700596 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700597
598 switch (column_type->base_type) {
599 case GLSL_TYPE_UINT:
600 case GLSL_TYPE_INT:
601 for (unsigned i = 0; i < column_type->vector_elements; i++)
602 data.u[i] = array->value.u[mat_idx + i];
603
604 break;
605
606 case GLSL_TYPE_FLOAT:
607 for (unsigned i = 0; i < column_type->vector_elements; i++)
608 data.f[i] = array->value.f[mat_idx + i];
609
610 break;
611
612 default:
613 assert(!"Should not get here.");
614 break;
615 }
616
Carl Worth1660a292010-06-23 18:11:51 -0700617 this->value = new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700618 } else if (array->type->is_vector()) {
619 const unsigned component = idx->value.u[0];
620
Carl Worth1660a292010-06-23 18:11:51 -0700621 this->value = new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700622 } else {
623 /* FINISHME: Handle access of constant arrays. */
624 }
625 }
Ian Romanickc7b10462010-05-19 13:20:12 +0200626}
627
628
629void
630ir_constant_visitor::visit(ir_dereference_record *ir)
631{
Ian Romanick253dede2010-06-09 17:30:19 -0700632 ir_constant *v = ir->record->constant_expression_value();
633
634 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700635}
636
637
638void
639ir_constant_visitor::visit(ir_assignment *ir)
640{
641 (void) ir;
642 value = NULL;
643}
644
645
646void
647ir_constant_visitor::visit(ir_constant *ir)
648{
649 value = ir;
650}
651
652
653void
654ir_constant_visitor::visit(ir_call *ir)
655{
656 (void) ir;
657 value = NULL;
658}
659
660
661void
662ir_constant_visitor::visit(ir_return *ir)
663{
664 (void) ir;
665 value = NULL;
666}
667
668
669void
Kenneth Graunke16efab12010-06-30 10:47:34 -0700670ir_constant_visitor::visit(ir_discard *ir)
671{
672 (void) ir;
673 value = NULL;
674}
675
676
677void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700678ir_constant_visitor::visit(ir_if *ir)
679{
680 (void) ir;
681 value = NULL;
682}
Ian Romanickfad607a2010-04-05 16:16:07 -0700683
684
685void
686ir_constant_visitor::visit(ir_loop *ir)
687{
688 (void) ir;
689 value = NULL;
690}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700691
692
693void
694ir_constant_visitor::visit(ir_loop_jump *ir)
695{
696 (void) ir;
697 value = NULL;
698}