blob: e3e717a14e6f6e3c6a60554fdecfd0e574d44fa8 [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
Kenneth Graunke79fed372010-07-09 11:53:56 -070041#define min(x,y) (x) < (y) ? (x) : (y)
42#define max(x,y) (x) > (y) ? (x) : (y)
43
Ian Romanick1cf43a42010-03-30 16:56:50 -070044ir_constant *
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -070045ir_expression::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -070046{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -070047 ir_expression *ir = this;
Kenneth Graunke6bc432e2010-07-02 17:12:23 -070048 ir_constant *op[2] = { NULL, NULL };
Ian Romanick4daaab62010-06-11 16:08:47 -070049 ir_constant_data data;
Eric Anholt160d0922010-04-01 18:07:08 -100050
Kenneth Graunkec63a1db2010-07-05 22:33:35 -070051 memset(&data, 0, sizeof(data));
52
Kenneth Graunkef14e5962010-07-06 16:26:11 -070053 for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) {
Eric Anholtd98da972010-04-01 18:25:11 -100054 op[operand] = ir->operands[operand]->constant_expression_value();
55 if (!op[operand])
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -070056 return NULL;
Eric Anholt160d0922010-04-01 18:07:08 -100057 }
Eric Anholta576f9d2010-03-31 16:25:12 -100058
Kenneth Graunke6fc983b2010-07-06 02:39:57 -070059 if (op[1] != NULL)
60 assert(op[0]->type->base_type == op[1]->type->base_type);
61
Kenneth Graunkee74dcd72010-07-06 02:48:16 -070062 bool op0_scalar = op[0]->type->is_scalar();
63 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
64
65 /* When iterating over a vector or matrix's components, we want to increase
66 * the loop counter. However, for scalars, we want to stay at 0.
67 */
Kenneth Graunkeacf88f22010-07-07 12:08:23 -070068 unsigned c0_inc = op0_scalar ? 0 : 1;
69 unsigned c1_inc = op1_scalar ? 0 : 1;
Eric Anholt570dc0d2010-07-07 09:07:09 -070070 unsigned components;
71 if (op1_scalar || !op[1]) {
72 components = op[0]->type->components();
73 } else {
74 components = op[1]->type->components();
75 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -070076
Eric Anholta576f9d2010-03-31 16:25:12 -100077 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -100078 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -070079 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -070080 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -070081 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -100082 break;
Eric Anholtaf186412010-04-06 10:53:57 -070083
84 case ir_unop_f2i:
85 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -070086 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -070087 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -070088 }
89 break;
90 case ir_unop_i2f:
91 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
92 op[0]->type->base_type == GLSL_TYPE_INT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -070093 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Eric Anholtaf186412010-04-06 10:53:57 -070094 if (op[0]->type->base_type == GLSL_TYPE_INT)
Ian Romanick4daaab62010-06-11 16:08:47 -070095 data.f[c] = op[0]->value.i[c];
Eric Anholtaf186412010-04-06 10:53:57 -070096 else
Ian Romanick4daaab62010-06-11 16:08:47 -070097 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -070098 }
99 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700100 case ir_unop_b2f:
101 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700102 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700103 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700104 }
105 break;
106 case ir_unop_f2b:
107 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700108 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700109 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700110 }
111 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700112 case ir_unop_b2i:
113 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700114 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700115 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700116 }
117 break;
118 case ir_unop_i2b:
119 assert(op[0]->type->is_integer());
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700120 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700121 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700122 }
123 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700124
Kenneth Graunke323d9092010-07-08 23:21:36 -0700125 case ir_unop_trunc:
126 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
127 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
128 data.f[c] = truncf(op[0]->value.f[c]);
129 }
130 break;
131
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700132 case ir_unop_ceil:
133 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
134 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
135 data.f[c] = ceilf(op[0]->value.f[c]);
136 }
137 break;
138
Kenneth Graunke07472042010-07-08 23:23:23 -0700139 case ir_unop_floor:
140 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
141 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
142 data.f[c] = floorf(op[0]->value.f[c]);
143 }
144 break;
145
Eric Anholtd925c912010-07-01 10:37:11 -0700146 case ir_unop_fract:
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700147 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Eric Anholtd925c912010-07-01 10:37:11 -0700148 switch (ir->type->base_type) {
149 case GLSL_TYPE_UINT:
150 data.u[c] = 0;
151 break;
152 case GLSL_TYPE_INT:
153 data.i[c] = 0;
154 break;
155 case GLSL_TYPE_FLOAT:
156 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
157 break;
158 default:
159 assert(0);
160 }
161 }
162 break;
163
Kenneth Graunke908afd12010-07-08 23:28:50 -0700164 case ir_unop_sin:
165 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
166 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
167 data.f[c] = sinf(op[0]->value.f[c]);
168 }
169 break;
170
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700171 case ir_unop_cos:
172 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
173 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
174 data.f[c] = cosf(op[0]->value.f[c]);
175 }
176 break;
177
Eric Anholt43ad37a2010-05-12 14:42:21 -0700178 case ir_unop_neg:
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700179 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700180 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700181 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700182 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700183 break;
184 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700185 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700186 break;
187 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700188 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700189 break;
190 default:
191 assert(0);
192 }
193 }
194 break;
195
196 case ir_unop_abs:
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700197 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700198 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700199 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700200 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700201 break;
202 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700203 data.i[c] = op[0]->value.i[c];
204 if (data.i[c] < 0)
205 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700206 break;
207 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700208 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700209 break;
210 default:
211 assert(0);
212 }
213 }
214 break;
215
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700216 case ir_unop_sign:
217 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
218 switch (ir->type->base_type) {
219 case GLSL_TYPE_UINT:
220 data.u[c] = op[0]->value.i[c] > 0;
221 break;
222 case GLSL_TYPE_INT:
223 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
224 break;
225 case GLSL_TYPE_FLOAT:
226 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
227 break;
228 default:
229 assert(0);
230 }
231 }
232 break;
233
Eric Anholt43ad37a2010-05-12 14:42:21 -0700234 case ir_unop_rcp:
235 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700236 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanickf8b88be2010-06-11 16:23:52 -0700237 switch (ir->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700238 case GLSL_TYPE_UINT:
239 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700240 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700241 break;
242 case GLSL_TYPE_INT:
243 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700244 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700245 break;
246 case GLSL_TYPE_FLOAT:
247 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700248 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700249 break;
250 default:
251 assert(0);
252 }
253 }
254 break;
255
256 case ir_unop_rsq:
257 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700258 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700259 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700260 }
261 break;
262
263 case ir_unop_sqrt:
264 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700265 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700266 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700267 }
268 break;
269
270 case ir_unop_exp:
271 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700272 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700273 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700274 }
275 break;
276
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700277 case ir_unop_exp2:
278 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
279 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
280 data.f[c] = exp2f(op[0]->value.f[c]);
281 }
282 break;
283
Eric Anholt43ad37a2010-05-12 14:42:21 -0700284 case ir_unop_log:
285 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700286 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700287 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700288 }
289 break;
290
Kenneth Graunkecb639292010-07-08 23:18:09 -0700291 case ir_unop_log2:
292 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
293 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
294 data.f[c] = log2f(op[0]->value.f[c]);
295 }
296 break;
297
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700298 case ir_unop_dFdx:
299 case ir_unop_dFdy:
300 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700301 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700302 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700303 }
304 break;
305
Kenneth Graunke891a0642010-07-08 23:35:09 -0700306 case ir_binop_pow:
307 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
308 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
309 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
310 }
311 break;
312
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700313 case ir_binop_dot:
314 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
315 data.f[0] = 0;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700316 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700317 switch (ir->operands[0]->type->base_type) {
318 case GLSL_TYPE_UINT:
319 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
320 break;
321 case GLSL_TYPE_INT:
322 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
323 break;
324 case GLSL_TYPE_FLOAT:
325 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
326 break;
327 default:
328 assert(0);
329 }
330 }
331
332 break;
Kenneth Graunke79fed372010-07-09 11:53:56 -0700333 case ir_binop_min:
334 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
335 for (unsigned c = 0, c0 = 0, c1 = 0;
336 c < components;
337 c0 += c0_inc, c1 += c1_inc, c++) {
338
339 switch (ir->operands[0]->type->base_type) {
340 case GLSL_TYPE_UINT:
341 data.u[c] = min(op[0]->value.u[c0], op[1]->value.u[c1]);
342 break;
343 case GLSL_TYPE_INT:
344 data.i[c] = min(op[0]->value.i[c0], op[1]->value.i[c1]);
345 break;
346 case GLSL_TYPE_FLOAT:
347 data.f[c] = min(op[0]->value.f[c0], op[1]->value.f[c1]);
348 break;
349 default:
350 assert(0);
351 }
352 }
353
354 break;
355 case ir_binop_max:
356 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
357 for (unsigned c = 0, c0 = 0, c1 = 0;
358 c < components;
359 c0 += c0_inc, c1 += c1_inc, c++) {
360
361 switch (ir->operands[0]->type->base_type) {
362 case GLSL_TYPE_UINT:
363 data.u[c] = max(op[0]->value.u[c0], op[1]->value.u[c1]);
364 break;
365 case GLSL_TYPE_INT:
366 data.i[c] = max(op[0]->value.i[c0], op[1]->value.i[c1]);
367 break;
368 case GLSL_TYPE_FLOAT:
369 data.f[c] = max(op[0]->value.f[c0], op[1]->value.f[c1]);
370 break;
371 default:
372 assert(0);
373 }
374 }
Kenneth Graunke79fed372010-07-09 11:53:56 -0700375 break;
Eric Anholt9be7f632010-07-13 15:37:57 -0700376
377 case ir_binop_cross:
378 assert(op[0]->type == glsl_type::vec3_type);
379 assert(op[1]->type == glsl_type::vec3_type);
380 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
381 op[1]->value.f[1] * op[0]->value.f[2]);
382 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
383 op[1]->value.f[2] * op[0]->value.f[0]);
384 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
385 op[1]->value.f[0] * op[0]->value.f[1]);
386 break;
387
Eric Anholtd251b922010-04-01 18:35:42 -1000388 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700389 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
390 for (unsigned c = 0, c0 = 0, c1 = 0;
391 c < components;
392 c0 += c0_inc, c1 += c1_inc, c++) {
393
394 switch (ir->operands[0]->type->base_type) {
395 case GLSL_TYPE_UINT:
396 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
397 break;
398 case GLSL_TYPE_INT:
399 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
400 break;
401 case GLSL_TYPE_FLOAT:
402 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
403 break;
404 default:
405 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000406 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700407 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700408
Eric Anholtd251b922010-04-01 18:35:42 -1000409 break;
410 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700411 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
412 for (unsigned c = 0, c0 = 0, c1 = 0;
413 c < components;
414 c0 += c0_inc, c1 += c1_inc, c++) {
415
416 switch (ir->operands[0]->type->base_type) {
417 case GLSL_TYPE_UINT:
418 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
419 break;
420 case GLSL_TYPE_INT:
421 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
422 break;
423 case GLSL_TYPE_FLOAT:
424 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
425 break;
426 default:
427 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000428 }
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700429 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700430
Eric Anholtd251b922010-04-01 18:35:42 -1000431 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000432 case ir_binop_mul:
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700433 /* Check for equal types, or unequal types involving scalars */
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700434 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
435 || op0_scalar || op1_scalar) {
436 for (unsigned c = 0, c0 = 0, c1 = 0;
437 c < components;
438 c0 += c0_inc, c1 += c1_inc, c++) {
439
Eric Anholtd98da972010-04-01 18:25:11 -1000440 switch (ir->operands[0]->type->base_type) {
441 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700442 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000443 break;
444 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700445 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000446 break;
447 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700448 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000449 break;
450 default:
451 assert(0);
452 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000453 }
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700454 } else {
455 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
456
457 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
458 * matrix can be a GLSL vector, either N or P can be 1.
459 *
460 * For vec*mat, the vector is treated as a row vector. This
461 * means the vector is a 1-row x M-column matrix.
462 *
463 * For mat*vec, the vector is treated as a column vector. Since
464 * matrix_columns is 1 for vectors, this just works.
465 */
466 const unsigned n = op[0]->type->is_vector()
467 ? 1 : op[0]->type->vector_elements;
468 const unsigned m = op[1]->type->vector_elements;
469 const unsigned p = op[1]->type->matrix_columns;
470 for (unsigned j = 0; j < p; j++) {
471 for (unsigned i = 0; i < n; i++) {
472 for (unsigned k = 0; k < m; k++) {
473 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
474 }
475 }
476 }
477 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700478
Eric Anholta576f9d2010-03-31 16:25:12 -1000479 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000480 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700481 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
482 for (unsigned c = 0, c0 = 0, c1 = 0;
483 c < components;
484 c0 += c0_inc, c1 += c1_inc, c++) {
485
486 switch (ir->operands[0]->type->base_type) {
487 case GLSL_TYPE_UINT:
488 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
489 break;
490 case GLSL_TYPE_INT:
491 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
492 break;
493 case GLSL_TYPE_FLOAT:
494 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
495 break;
496 default:
497 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000498 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700499 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700500
Eric Anholtd251b922010-04-01 18:35:42 -1000501 break;
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700502 case ir_binop_mod:
503 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
504 for (unsigned c = 0, c0 = 0, c1 = 0;
505 c < components;
506 c0 += c0_inc, c1 += c1_inc, c++) {
507
508 switch (ir->operands[0]->type->base_type) {
509 case GLSL_TYPE_UINT:
510 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
511 break;
512 case GLSL_TYPE_INT:
513 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
514 break;
515 case GLSL_TYPE_FLOAT:
516 /* We don't use fmod because it rounds toward zero; GLSL specifies
517 * the use of floor.
518 */
519 data.f[c] = (op[0]->value.f[c0] - op[1]->value.f[c1])
520 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
521 break;
522 default:
523 assert(0);
524 }
525 }
526
527 break;
528
Eric Anholta576f9d2010-03-31 16:25:12 -1000529 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700530 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700531 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700532 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000533 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000534 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700535 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700536 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700537 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000538 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000539 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700540 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700541 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700542 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000543 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700544
545 case ir_binop_less:
Eric Anholt85171c22010-04-06 09:55:45 -0700546 switch (ir->operands[0]->type->base_type) {
547 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700548 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700549 break;
550 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700551 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700552 break;
553 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700554 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700555 break;
556 default:
557 assert(0);
558 }
559 break;
560 case ir_binop_greater:
Eric Anholt85171c22010-04-06 09:55:45 -0700561 switch (ir->operands[0]->type->base_type) {
562 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700563 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700564 break;
565 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700566 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700567 break;
568 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700569 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700570 break;
571 default:
572 assert(0);
573 }
574 break;
575 case ir_binop_lequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700576 switch (ir->operands[0]->type->base_type) {
577 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700578 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700579 break;
580 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700581 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700582 break;
583 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700584 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700585 break;
586 default:
587 assert(0);
588 }
589 break;
590 case ir_binop_gequal:
Eric Anholt85171c22010-04-06 09:55:45 -0700591 switch (ir->operands[0]->type->base_type) {
592 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700593 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700594 break;
595 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700596 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700597 break;
598 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700599 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700600 break;
601 default:
602 assert(0);
603 }
604 break;
605
Eric Anholtec1949e2010-04-06 10:02:27 -0700606 case ir_binop_equal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700607 data.b[0] = true;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700608 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick083d75a2010-06-11 16:20:43 -0700609 switch (ir->operands[0]->type->base_type) {
610 case GLSL_TYPE_UINT:
611 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
612 break;
613 case GLSL_TYPE_INT:
614 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
615 break;
616 case GLSL_TYPE_FLOAT:
617 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
618 break;
619 case GLSL_TYPE_BOOL:
620 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
621 break;
622 default:
623 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700624 }
625 }
626 break;
627 case ir_binop_nequal:
Ian Romanick083d75a2010-06-11 16:20:43 -0700628 data.b[0] = false;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700629 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
Ian Romanick083d75a2010-06-11 16:20:43 -0700630 switch (ir->operands[0]->type->base_type) {
631 case GLSL_TYPE_UINT:
632 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
633 break;
634 case GLSL_TYPE_INT:
635 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
636 break;
637 case GLSL_TYPE_FLOAT:
638 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
639 break;
640 case GLSL_TYPE_BOOL:
641 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
642 break;
643 default:
644 assert(0);
Eric Anholtec1949e2010-04-06 10:02:27 -0700645 }
646 }
647 break;
648
Eric Anholta576f9d2010-03-31 16:25:12 -1000649 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700650 /* FINISHME: Should handle all expression types. */
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700651 return NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000652 }
Eric Anholtd98da972010-04-01 18:25:11 -1000653
Eric Anholt6b01b502010-06-24 15:18:39 -0700654 void *ctx = talloc_parent(ir);
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700655 return new(ctx) ir_constant(ir->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700656}
657
658
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700659ir_constant *
660ir_texture::constant_expression_value()
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700661{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700662 /* texture lookups aren't constant expressions */
663 return NULL;
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700664}
665
666
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700667ir_constant *
668ir_swizzle::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700669{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700670 ir_swizzle *ir = this;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700671 ir_constant *v = ir->val->constant_expression_value();
672
Ian Romanickc2ba6192010-06-11 12:30:28 -0700673 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700674 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700675
676 const unsigned swiz_idx[4] = {
677 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
678 };
679
680 for (unsigned i = 0; i < ir->mask.num_components; i++) {
681 switch (v->type->base_type) {
682 case GLSL_TYPE_UINT:
683 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
684 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
685 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
686 default: assert(!"Should not get here."); break;
687 }
688 }
689
Eric Anholt6b01b502010-06-24 15:18:39 -0700690 void *ctx = talloc_parent(ir);
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700691 return new(ctx) ir_constant(ir->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700692 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700693 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700694}
695
696
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700697ir_constant *
698ir_dereference_variable::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700699{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700700 ir_variable *var = this->variable_referenced();
Ian Romanickc7b10462010-05-19 13:20:12 +0200701 if (var && var->constant_value)
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700702 return var->constant_value->clone(NULL);
703 return NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200704}
705
706
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700707ir_constant *
708ir_dereference_array::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200709{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700710 ir_dereference_array *ir = this;
Carl Worth1660a292010-06-23 18:11:51 -0700711 void *ctx = talloc_parent(ir);
Ian Romanick9b92af92010-06-11 12:20:12 -0700712 ir_constant *array = ir->array->constant_expression_value();
713 ir_constant *idx = ir->array_index->constant_expression_value();
714
Ian Romanick9b92af92010-06-11 12:20:12 -0700715 if ((array != NULL) && (idx != NULL)) {
716 if (array->type->is_matrix()) {
717 /* Array access of a matrix results in a vector.
718 */
719 const unsigned column = idx->value.u[0];
720
721 const glsl_type *const column_type = array->type->column_type();
722
723 /* Offset in the constant matrix to the first element of the column
724 * to be extracted.
725 */
726 const unsigned mat_idx = column * column_type->vector_elements;
727
Ian Romanick0bb70a32010-06-11 15:49:49 -0700728 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700729
730 switch (column_type->base_type) {
731 case GLSL_TYPE_UINT:
732 case GLSL_TYPE_INT:
733 for (unsigned i = 0; i < column_type->vector_elements; i++)
734 data.u[i] = array->value.u[mat_idx + i];
735
736 break;
737
738 case GLSL_TYPE_FLOAT:
739 for (unsigned i = 0; i < column_type->vector_elements; i++)
740 data.f[i] = array->value.f[mat_idx + i];
741
742 break;
743
744 default:
745 assert(!"Should not get here.");
746 break;
747 }
748
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700749 return new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700750 } else if (array->type->is_vector()) {
751 const unsigned component = idx->value.u[0];
752
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700753 return new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700754 } else {
755 /* FINISHME: Handle access of constant arrays. */
756 }
757 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700758 return NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200759}
760
761
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700762ir_constant *
763ir_dereference_record::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200764{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700765 ir_dereference_record *ir = this;
Ian Romanick253dede2010-06-09 17:30:19 -0700766 ir_constant *v = ir->record->constant_expression_value();
767
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700768 return (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700769}
770
771
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700772ir_constant *
773ir_assignment::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700774{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700775 /* FINISHME: Handle CEs involving assignment (return RHS) */
776 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700777}
778
779
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700780ir_constant *
781ir_constant::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700782{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700783 return this;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700784}
785
786
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700787ir_constant *
788ir_call::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700789{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700790 /* FINISHME: Handle CEs involving builtin function calls. */
791 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700792}
793