blob: 610d9479a941438891da9b511c60d18aa6efd663 [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;
Kenneth Graunke6bc432e2010-07-02 17:12:23 -0700132 ir_constant *op[2] = { NULL, NULL };
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
Kenneth Graunkec63a1db2010-07-05 22:33:35 -0700136 memset(&data, 0, sizeof(data));
137
Eric Anholtd98da972010-04-01 18:25:11 -1000138 for (operand = 0; operand < ir->get_num_operands(); operand++) {
139 op[operand] = ir->operands[operand]->constant_expression_value();
140 if (!op[operand])
Eric Anholt160d0922010-04-01 18:07:08 -1000141 return;
142 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000143
Kenneth Graunke6fc983b2010-07-06 02:39:57 -0700144 if (op[1] != NULL)
145 assert(op[0]->type->base_type == op[1]->type->base_type);
146
Eric Anholta576f9d2010-03-31 16:25:12 -1000147 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000148 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700149 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000150 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700151 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000152 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700153
154 case ir_unop_f2i:
155 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholtaf186412010-04-06 10:53:57 -0700156 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700157 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700158 }
159 break;
160 case ir_unop_i2f:
161 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
162 op[0]->type->base_type == GLSL_TYPE_INT);
Eric Anholtaf186412010-04-06 10:53:57 -0700163 for (c = 0; c < ir->operands[0]->type->components(); c++) {
164 if (op[0]->type->base_type == GLSL_TYPE_INT)
Ian Romanick4daaab62010-06-11 16:08:47 -0700165 data.f[c] = op[0]->value.i[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700166 else
Ian Romanick4daaab62010-06-11 16:08:47 -0700167 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700168 }
169 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700170 case ir_unop_b2f:
171 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
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.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);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700178 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700179 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700180 }
181 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700182 case ir_unop_b2i:
183 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
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.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700186 }
187 break;
188 case ir_unop_i2b:
189 assert(op[0]->type->is_integer());
Ian Romanick39d6dd32010-06-11 13:46:30 -0700190 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700191 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700192 }
193 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700194
Eric Anholtd925c912010-07-01 10:37:11 -0700195 case ir_unop_fract:
196 for (c = 0; c < ir->operands[0]->type->components(); c++) {
197 switch (ir->type->base_type) {
198 case GLSL_TYPE_UINT:
199 data.u[c] = 0;
200 break;
201 case GLSL_TYPE_INT:
202 data.i[c] = 0;
203 break;
204 case GLSL_TYPE_FLOAT:
205 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
206 break;
207 default:
208 assert(0);
209 }
210 }
211 break;
212
Eric Anholt43ad37a2010-05-12 14:42:21 -0700213 case ir_unop_neg:
Eric Anholt43ad37a2010-05-12 14:42:21 -0700214 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700215 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700216 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700217 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700218 break;
219 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700220 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700221 break;
222 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700223 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700224 break;
225 default:
226 assert(0);
227 }
228 }
229 break;
230
231 case ir_unop_abs:
232 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700233 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700234 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700235 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700236 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700237 break;
238 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700239 data.i[c] = op[0]->value.i[c];
240 if (data.i[c] < 0)
241 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700242 break;
243 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700244 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700245 break;
246 default:
247 assert(0);
248 }
249 }
250 break;
251
252 case ir_unop_rcp:
253 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700254 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700255 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700256 case GLSL_TYPE_UINT:
257 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700258 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700259 break;
260 case GLSL_TYPE_INT:
261 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700262 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700263 break;
264 case GLSL_TYPE_FLOAT:
265 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700266 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700267 break;
268 default:
269 assert(0);
270 }
271 }
272 break;
273
274 case ir_unop_rsq:
275 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700276 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700277 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700278 }
279 break;
280
281 case ir_unop_sqrt:
282 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700283 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700284 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700285 }
286 break;
287
288 case ir_unop_exp:
289 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700290 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700291 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700292 }
293 break;
294
295 case ir_unop_log:
296 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700297 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700298 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700299 }
300 break;
301
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700302 case ir_unop_dFdx:
303 case ir_unop_dFdy:
304 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700305 for (c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700306 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700307 }
308 break;
309
Eric Anholtd251b922010-04-01 18:35:42 -1000310 case ir_binop_add:
311 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000312 for (c = 0; c < ir->operands[0]->type->components(); c++) {
313 switch (ir->operands[0]->type->base_type) {
314 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700315 data.u[c] = op[0]->value.u[c] + op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000316 break;
317 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700318 data.i[c] = op[0]->value.i[c] + op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000319 break;
320 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700321 data.f[c] = op[0]->value.f[c] + op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000322 break;
323 default:
324 assert(0);
325 }
326 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700327 } else
328 /* FINISHME: Support operations with non-equal types. */
329 return;
330
Eric Anholtd251b922010-04-01 18:35:42 -1000331 break;
332 case ir_binop_sub:
333 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -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 Anholtd251b922010-04-01 18:35:42 -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 Anholtd251b922010-04-01 18:35:42 -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 Anholtd251b922010-04-01 18:35:42 -1000344 break;
345 default:
346 assert(0);
347 }
348 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700349 } else
350 /* FINISHME: Support operations with non-equal types. */
351 return;
352
Eric Anholtd251b922010-04-01 18:35:42 -1000353 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000354 case ir_binop_mul:
Eric Anholtd98da972010-04-01 18:25:11 -1000355 if (ir->operands[0]->type == ir->operands[1]->type &&
356 !ir->operands[0]->type->is_matrix()) {
Eric Anholtd98da972010-04-01 18:25:11 -1000357 for (c = 0; c < ir->operands[0]->type->components(); c++) {
358 switch (ir->operands[0]->type->base_type) {
359 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700360 data.u[c] = op[0]->value.u[c] * op[1]->value.u[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000361 break;
362 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700363 data.i[c] = op[0]->value.i[c] * op[1]->value.i[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000364 break;
365 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700366 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
Eric Anholtd98da972010-04-01 18:25:11 -1000367 break;
368 default:
369 assert(0);
370 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000371 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700372 } else
373 /* FINISHME: Support operations with non-equal types. */
374 return;
375
Eric Anholta576f9d2010-03-31 16:25:12 -1000376 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000377 case ir_binop_div:
378 if (ir->operands[0]->type == ir->operands[1]->type) {
Eric Anholtd251b922010-04-01 18:35:42 -1000379 for (c = 0; c < ir->operands[0]->type->components(); c++) {
380 switch (ir->operands[0]->type->base_type) {
381 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700382 data.u[c] = op[0]->value.u[c] / op[1]->value.u[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000383 break;
384 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700385 data.i[c] = op[0]->value.i[c] / op[1]->value.i[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000386 break;
387 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700388 data.f[c] = op[0]->value.f[c] / op[1]->value.f[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000389 break;
390 default:
391 assert(0);
392 }
393 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700394 } else
395 /* FINISHME: Support operations with non-equal types. */
396 return;
397
Eric Anholtd251b922010-04-01 18:35:42 -1000398 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000399 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700400 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -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 Anholta576f9d2010-03-31 16:25:12 -1000403 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000404 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700405 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd251b922010-04-01 18:35:42 -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 Anholtd251b922010-04-01 18:35:42 -1000408 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000409 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700410 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Eric Anholtd98da972010-04-01 18:25:11 -1000411 for (c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700412 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000413 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700414
415 case ir_binop_less:
Eric Anholt85171c22010-04-06 09:55:45 -0700416 switch (ir->operands[0]->type->base_type) {
417 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700418 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700419 break;
420 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700421 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700422 break;
423 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700424 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700425 break;
426 default:
427 assert(0);
428 }
429 break;
430 case ir_binop_greater:
Eric Anholt85171c22010-04-06 09:55:45 -0700431 switch (ir->operands[0]->type->base_type) {
432 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700433 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700434 break;
435 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700436 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700437 break;
438 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700439 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700440 break;
441 default:
442 assert(0);
443 }
444 break;
445 case ir_binop_lequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700446 switch (ir->operands[0]->type->base_type) {
447 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700448 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700449 break;
450 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700451 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700452 break;
453 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700454 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700455 break;
456 default:
457 assert(0);
458 }
459 break;
460 case ir_binop_gequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700461 switch (ir->operands[0]->type->base_type) {
462 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700463 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700464 break;
465 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700466 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700467 break;
468 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700469 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700470 break;
471 default:
472 assert(0);
473 }
474 break;
475
Eric Anholtec1949e2010-04-06 10:02:27 -0700476 case ir_binop_equal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700477 data.b[0] = true;
478 for (c = 0; c < ir->operands[0]->type->components(); c++) {
479 switch (ir->operands[0]->type->base_type) {
480 case GLSL_TYPE_UINT:
481 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
482 break;
483 case GLSL_TYPE_INT:
484 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
485 break;
486 case GLSL_TYPE_FLOAT:
487 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
488 break;
489 case GLSL_TYPE_BOOL:
490 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
491 break;
492 default:
493 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700494 }
495 }
496 break;
497 case ir_binop_nequal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700498 data.b[0] = false;
499 for (c = 0; c < ir->operands[0]->type->components(); c++) {
500 switch (ir->operands[0]->type->base_type) {
501 case GLSL_TYPE_UINT:
502 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
503 break;
504 case GLSL_TYPE_INT:
505 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
506 break;
507 case GLSL_TYPE_FLOAT:
508 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
509 break;
510 case GLSL_TYPE_BOOL:
511 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
512 break;
513 default:
514 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700515 }
516 }
517 break;
518
Eric Anholta576f9d2010-03-31 16:25:12 -1000519 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700520 /* FINISHME: Should handle all expression types. */
521 return;
Eric Anholta576f9d2010-03-31 16:25:12 -1000522 }
Eric Anholtd98da972010-04-01 18:25:11 -1000523
Eric Anholt6b01b502010-06-24 15:18:39 -0700524 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700525 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700526}
527
528
529void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700530ir_constant_visitor::visit(ir_texture *ir)
531{
532 // FINISHME: Do stuff with texture lookups
533 (void) ir;
534 value = NULL;
535}
536
537
538void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700539ir_constant_visitor::visit(ir_swizzle *ir)
540{
Ian Romanickc2ba6192010-06-11 12:30:28 -0700541 ir_constant *v = ir->val->constant_expression_value();
542
543 this->value = NULL;
544
545 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700546 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700547
548 const unsigned swiz_idx[4] = {
549 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
550 };
551
552 for (unsigned i = 0; i < ir->mask.num_components; i++) {
553 switch (v->type->base_type) {
554 case GLSL_TYPE_UINT:
555 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
556 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
557 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
558 default: assert(!"Should not get here."); break;
559 }
560 }
561
Eric Anholt6b01b502010-06-24 15:18:39 -0700562 void *ctx = talloc_parent(ir);
Carl Worth1660a292010-06-23 18:11:51 -0700563 this->value = new(ctx) ir_constant(ir->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700564 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700565}
566
567
568void
Ian Romanickc7b10462010-05-19 13:20:12 +0200569ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700570{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700571 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700572
Ian Romanickc7b10462010-05-19 13:20:12 +0200573 ir_variable *var = ir->variable_referenced();
574 if (var && var->constant_value)
Eric Anholt4b6fd392010-06-23 11:37:12 -0700575 value = (ir_constant *)var->constant_value->clone(NULL);
Ian Romanickc7b10462010-05-19 13:20:12 +0200576}
577
578
579void
580ir_constant_visitor::visit(ir_dereference_array *ir)
581{
Carl Worth1660a292010-06-23 18:11:51 -0700582 void *ctx = talloc_parent(ir);
Ian Romanick9b92af92010-06-11 12:20:12 -0700583 ir_constant *array = ir->array->constant_expression_value();
584 ir_constant *idx = ir->array_index->constant_expression_value();
585
586 this->value = NULL;
587
588 if ((array != NULL) && (idx != NULL)) {
589 if (array->type->is_matrix()) {
590 /* Array access of a matrix results in a vector.
591 */
592 const unsigned column = idx->value.u[0];
593
594 const glsl_type *const column_type = array->type->column_type();
595
596 /* Offset in the constant matrix to the first element of the column
597 * to be extracted.
598 */
599 const unsigned mat_idx = column * column_type->vector_elements;
600
Ian Romanick0bb70a32010-06-11 15:49:49 -0700601 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700602
603 switch (column_type->base_type) {
604 case GLSL_TYPE_UINT:
605 case GLSL_TYPE_INT:
606 for (unsigned i = 0; i < column_type->vector_elements; i++)
607 data.u[i] = array->value.u[mat_idx + i];
608
609 break;
610
611 case GLSL_TYPE_FLOAT:
612 for (unsigned i = 0; i < column_type->vector_elements; i++)
613 data.f[i] = array->value.f[mat_idx + i];
614
615 break;
616
617 default:
618 assert(!"Should not get here.");
619 break;
620 }
621
Carl Worth1660a292010-06-23 18:11:51 -0700622 this->value = new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700623 } else if (array->type->is_vector()) {
624 const unsigned component = idx->value.u[0];
625
Carl Worth1660a292010-06-23 18:11:51 -0700626 this->value = new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700627 } else {
628 /* FINISHME: Handle access of constant arrays. */
629 }
630 }
Ian Romanickc7b10462010-05-19 13:20:12 +0200631}
632
633
634void
635ir_constant_visitor::visit(ir_dereference_record *ir)
636{
Ian Romanick253dede2010-06-09 17:30:19 -0700637 ir_constant *v = ir->record->constant_expression_value();
638
639 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700640}
641
642
643void
644ir_constant_visitor::visit(ir_assignment *ir)
645{
646 (void) ir;
647 value = NULL;
648}
649
650
651void
652ir_constant_visitor::visit(ir_constant *ir)
653{
654 value = ir;
655}
656
657
658void
659ir_constant_visitor::visit(ir_call *ir)
660{
661 (void) ir;
662 value = NULL;
663}
664
665
666void
667ir_constant_visitor::visit(ir_return *ir)
668{
669 (void) ir;
670 value = NULL;
671}
672
673
674void
Kenneth Graunke16efab12010-06-30 10:47:34 -0700675ir_constant_visitor::visit(ir_discard *ir)
676{
677 (void) ir;
678 value = NULL;
679}
680
681
682void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700683ir_constant_visitor::visit(ir_if *ir)
684{
685 (void) ir;
686 value = NULL;
687}
Ian Romanickfad607a2010-04-05 16:16:07 -0700688
689
690void
691ir_constant_visitor::visit(ir_loop *ir)
692{
693 (void) ir;
694 value = NULL;
695}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700696
697
698void
699ir_constant_visitor::visit(ir_loop_jump *ir)
700{
701 (void) ir;
702 value = NULL;
703}