blob: b0333dbebb75db120e9de9317f40235730b7f469 [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 Graunke6bc432e2010-07-02 17:12:23 -070047 ir_constant *op[2] = { NULL, NULL };
Ian Romanick4daaab62010-06-11 16:08:47 -070048 ir_constant_data data;
Eric Anholt160d0922010-04-01 18:07:08 -100049
Kenneth Graunkec63a1db2010-07-05 22:33:35 -070050 memset(&data, 0, sizeof(data));
51
Kenneth Graunke98f32a12010-07-15 10:20:51 -070052 for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
53 op[operand] = this->operands[operand]->constant_expression_value();
Eric Anholtd98da972010-04-01 18:25:11 -100054 if (!op[operand])
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -070055 return NULL;
Eric Anholt160d0922010-04-01 18:07:08 -100056 }
Eric Anholta576f9d2010-03-31 16:25:12 -100057
Kenneth Graunke6fc983b2010-07-06 02:39:57 -070058 if (op[1] != NULL)
59 assert(op[0]->type->base_type == op[1]->type->base_type);
60
Kenneth Graunkee74dcd72010-07-06 02:48:16 -070061 bool op0_scalar = op[0]->type->is_scalar();
62 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
63
64 /* When iterating over a vector or matrix's components, we want to increase
65 * the loop counter. However, for scalars, we want to stay at 0.
66 */
Kenneth Graunkeacf88f22010-07-07 12:08:23 -070067 unsigned c0_inc = op0_scalar ? 0 : 1;
68 unsigned c1_inc = op1_scalar ? 0 : 1;
Eric Anholt570dc0d2010-07-07 09:07:09 -070069 unsigned components;
70 if (op1_scalar || !op[1]) {
71 components = op[0]->type->components();
72 } else {
73 components = op[1]->type->components();
74 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -070075
Kenneth Graunke98f32a12010-07-15 10:20:51 -070076 switch (this->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -100077 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -070078 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -070079 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -070080 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -100081 break;
Eric Anholtaf186412010-04-06 10:53:57 -070082
83 case ir_unop_f2i:
84 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -070085 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -070086 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -070087 }
88 break;
89 case ir_unop_i2f:
90 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
91 op[0]->type->base_type == GLSL_TYPE_INT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -070092 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Eric Anholtaf186412010-04-06 10:53:57 -070093 if (op[0]->type->base_type == GLSL_TYPE_INT)
Ian Romanick4daaab62010-06-11 16:08:47 -070094 data.f[c] = op[0]->value.i[c];
Eric Anholtaf186412010-04-06 10:53:57 -070095 else
Ian Romanick4daaab62010-06-11 16:08:47 -070096 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -070097 }
98 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -070099 case ir_unop_b2f:
100 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700101 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700102 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700103 }
104 break;
105 case ir_unop_f2b:
106 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700107 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700108 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700109 }
110 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700111 case ir_unop_b2i:
112 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700113 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700114 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700115 }
116 break;
117 case ir_unop_i2b:
118 assert(op[0]->type->is_integer());
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700119 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700120 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700121 }
122 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700123
Kenneth Graunke323d9092010-07-08 23:21:36 -0700124 case ir_unop_trunc:
125 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700126 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke323d9092010-07-08 23:21:36 -0700127 data.f[c] = truncf(op[0]->value.f[c]);
128 }
129 break;
130
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700131 case ir_unop_ceil:
132 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700133 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700134 data.f[c] = ceilf(op[0]->value.f[c]);
135 }
136 break;
137
Kenneth Graunke07472042010-07-08 23:23:23 -0700138 case ir_unop_floor:
139 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700140 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke07472042010-07-08 23:23:23 -0700141 data.f[c] = floorf(op[0]->value.f[c]);
142 }
143 break;
144
Eric Anholtd925c912010-07-01 10:37:11 -0700145 case ir_unop_fract:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700146 for (unsigned c = 0; c < op[0]->type->components(); c++) {
147 switch (this->type->base_type) {
Eric Anholtd925c912010-07-01 10:37:11 -0700148 case GLSL_TYPE_UINT:
149 data.u[c] = 0;
150 break;
151 case GLSL_TYPE_INT:
152 data.i[c] = 0;
153 break;
154 case GLSL_TYPE_FLOAT:
155 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
156 break;
157 default:
158 assert(0);
159 }
160 }
161 break;
162
Kenneth Graunke908afd12010-07-08 23:28:50 -0700163 case ir_unop_sin:
164 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700165 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke908afd12010-07-08 23:28:50 -0700166 data.f[c] = sinf(op[0]->value.f[c]);
167 }
168 break;
169
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700170 case ir_unop_cos:
171 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700172 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700173 data.f[c] = cosf(op[0]->value.f[c]);
174 }
175 break;
176
Eric Anholt43ad37a2010-05-12 14:42:21 -0700177 case ir_unop_neg:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700178 for (unsigned c = 0; c < op[0]->type->components(); c++) {
179 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700180 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700181 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700182 break;
183 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700184 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700185 break;
186 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700187 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700188 break;
189 default:
190 assert(0);
191 }
192 }
193 break;
194
195 case ir_unop_abs:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700196 for (unsigned c = 0; c < op[0]->type->components(); c++) {
197 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700198 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700199 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700200 break;
201 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700202 data.i[c] = op[0]->value.i[c];
203 if (data.i[c] < 0)
204 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700205 break;
206 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700207 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700208 break;
209 default:
210 assert(0);
211 }
212 }
213 break;
214
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700215 case ir_unop_sign:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700216 for (unsigned c = 0; c < op[0]->type->components(); c++) {
217 switch (this->type->base_type) {
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700218 case GLSL_TYPE_UINT:
219 data.u[c] = op[0]->value.i[c] > 0;
220 break;
221 case GLSL_TYPE_INT:
222 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
223 break;
224 case GLSL_TYPE_FLOAT:
225 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
226 break;
227 default:
228 assert(0);
229 }
230 }
231 break;
232
Eric Anholt43ad37a2010-05-12 14:42:21 -0700233 case ir_unop_rcp:
234 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700235 for (unsigned c = 0; c < op[0]->type->components(); c++) {
236 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700237 case GLSL_TYPE_UINT:
238 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700239 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700240 break;
241 case GLSL_TYPE_INT:
242 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700243 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700244 break;
245 case GLSL_TYPE_FLOAT:
246 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700247 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700248 break;
249 default:
250 assert(0);
251 }
252 }
253 break;
254
255 case ir_unop_rsq:
256 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700257 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700258 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700259 }
260 break;
261
262 case ir_unop_sqrt:
263 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700264 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700265 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700266 }
267 break;
268
269 case ir_unop_exp:
270 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700271 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700272 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700273 }
274 break;
275
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700276 case ir_unop_exp2:
277 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700278 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700279 data.f[c] = exp2f(op[0]->value.f[c]);
280 }
281 break;
282
Eric Anholt43ad37a2010-05-12 14:42:21 -0700283 case ir_unop_log:
284 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700285 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700286 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700287 }
288 break;
289
Kenneth Graunkecb639292010-07-08 23:18:09 -0700290 case ir_unop_log2:
291 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700292 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkecb639292010-07-08 23:18:09 -0700293 data.f[c] = log2f(op[0]->value.f[c]);
294 }
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 Graunke98f32a12010-07-15 10:20:51 -0700300 for (unsigned c = 0; c < op[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
Kenneth Graunke891a0642010-07-08 23:35:09 -0700305 case ir_binop_pow:
306 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700307 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke891a0642010-07-08 23:35:09 -0700308 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
309 }
310 break;
311
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700312 case ir_binop_dot:
313 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
314 data.f[0] = 0;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700315 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700316 switch (op[0]->type->base_type) {
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700317 case GLSL_TYPE_UINT:
318 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
319 break;
320 case GLSL_TYPE_INT:
321 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
322 break;
323 case GLSL_TYPE_FLOAT:
324 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
325 break;
326 default:
327 assert(0);
328 }
329 }
330
331 break;
Kenneth Graunke79fed372010-07-09 11:53:56 -0700332 case ir_binop_min:
333 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
334 for (unsigned c = 0, c0 = 0, c1 = 0;
335 c < components;
336 c0 += c0_inc, c1 += c1_inc, c++) {
337
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700338 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700339 case GLSL_TYPE_UINT:
340 data.u[c] = min(op[0]->value.u[c0], op[1]->value.u[c1]);
341 break;
342 case GLSL_TYPE_INT:
343 data.i[c] = min(op[0]->value.i[c0], op[1]->value.i[c1]);
344 break;
345 case GLSL_TYPE_FLOAT:
346 data.f[c] = min(op[0]->value.f[c0], op[1]->value.f[c1]);
347 break;
348 default:
349 assert(0);
350 }
351 }
352
353 break;
354 case ir_binop_max:
355 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
356 for (unsigned c = 0, c0 = 0, c1 = 0;
357 c < components;
358 c0 += c0_inc, c1 += c1_inc, c++) {
359
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700360 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700361 case GLSL_TYPE_UINT:
362 data.u[c] = max(op[0]->value.u[c0], op[1]->value.u[c1]);
363 break;
364 case GLSL_TYPE_INT:
365 data.i[c] = max(op[0]->value.i[c0], op[1]->value.i[c1]);
366 break;
367 case GLSL_TYPE_FLOAT:
368 data.f[c] = max(op[0]->value.f[c0], op[1]->value.f[c1]);
369 break;
370 default:
371 assert(0);
372 }
373 }
Kenneth Graunke79fed372010-07-09 11:53:56 -0700374 break;
Eric Anholt9be7f632010-07-13 15:37:57 -0700375
376 case ir_binop_cross:
377 assert(op[0]->type == glsl_type::vec3_type);
378 assert(op[1]->type == glsl_type::vec3_type);
379 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
380 op[1]->value.f[1] * op[0]->value.f[2]);
381 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
382 op[1]->value.f[2] * op[0]->value.f[0]);
383 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
384 op[1]->value.f[0] * op[0]->value.f[1]);
385 break;
386
Eric Anholtd251b922010-04-01 18:35:42 -1000387 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700388 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
389 for (unsigned c = 0, c0 = 0, c1 = 0;
390 c < components;
391 c0 += c0_inc, c1 += c1_inc, c++) {
392
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700393 switch (op[0]->type->base_type) {
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700394 case GLSL_TYPE_UINT:
395 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
396 break;
397 case GLSL_TYPE_INT:
398 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
399 break;
400 case GLSL_TYPE_FLOAT:
401 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
402 break;
403 default:
404 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000405 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700406 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700407
Eric Anholtd251b922010-04-01 18:35:42 -1000408 break;
409 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700410 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
411 for (unsigned c = 0, c0 = 0, c1 = 0;
412 c < components;
413 c0 += c0_inc, c1 += c1_inc, c++) {
414
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700415 switch (op[0]->type->base_type) {
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700416 case GLSL_TYPE_UINT:
417 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
418 break;
419 case GLSL_TYPE_INT:
420 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
421 break;
422 case GLSL_TYPE_FLOAT:
423 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
424 break;
425 default:
426 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000427 }
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700428 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700429
Eric Anholtd251b922010-04-01 18:35:42 -1000430 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000431 case ir_binop_mul:
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700432 /* Check for equal types, or unequal types involving scalars */
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700433 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
434 || op0_scalar || op1_scalar) {
435 for (unsigned c = 0, c0 = 0, c1 = 0;
436 c < components;
437 c0 += c0_inc, c1 += c1_inc, c++) {
438
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700439 switch (op[0]->type->base_type) {
Eric Anholtd98da972010-04-01 18:25:11 -1000440 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700441 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000442 break;
443 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700444 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000445 break;
446 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700447 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000448 break;
449 default:
450 assert(0);
451 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000452 }
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700453 } else {
454 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
455
456 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
457 * matrix can be a GLSL vector, either N or P can be 1.
458 *
459 * For vec*mat, the vector is treated as a row vector. This
460 * means the vector is a 1-row x M-column matrix.
461 *
462 * For mat*vec, the vector is treated as a column vector. Since
463 * matrix_columns is 1 for vectors, this just works.
464 */
465 const unsigned n = op[0]->type->is_vector()
466 ? 1 : op[0]->type->vector_elements;
467 const unsigned m = op[1]->type->vector_elements;
468 const unsigned p = op[1]->type->matrix_columns;
469 for (unsigned j = 0; j < p; j++) {
470 for (unsigned i = 0; i < n; i++) {
471 for (unsigned k = 0; k < m; k++) {
472 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
473 }
474 }
475 }
476 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700477
Eric Anholta576f9d2010-03-31 16:25:12 -1000478 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000479 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700480 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
481 for (unsigned c = 0, c0 = 0, c1 = 0;
482 c < components;
483 c0 += c0_inc, c1 += c1_inc, c++) {
484
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700485 switch (op[0]->type->base_type) {
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700486 case GLSL_TYPE_UINT:
487 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
488 break;
489 case GLSL_TYPE_INT:
490 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
491 break;
492 case GLSL_TYPE_FLOAT:
493 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
494 break;
495 default:
496 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000497 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700498 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700499
Eric Anholtd251b922010-04-01 18:35:42 -1000500 break;
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700501 case ir_binop_mod:
502 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
503 for (unsigned c = 0, c0 = 0, c1 = 0;
504 c < components;
505 c0 += c0_inc, c1 += c1_inc, c++) {
506
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700507 switch (op[0]->type->base_type) {
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700508 case GLSL_TYPE_UINT:
509 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
510 break;
511 case GLSL_TYPE_INT:
512 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
513 break;
514 case GLSL_TYPE_FLOAT:
515 /* We don't use fmod because it rounds toward zero; GLSL specifies
516 * the use of floor.
517 */
518 data.f[c] = (op[0]->value.f[c0] - op[1]->value.f[c1])
519 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
520 break;
521 default:
522 assert(0);
523 }
524 }
525
526 break;
527
Eric Anholta576f9d2010-03-31 16:25:12 -1000528 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700529 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700530 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700531 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000532 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000533 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700534 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700535 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700536 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000537 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000538 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700539 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700540 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700541 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000542 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700543
544 case ir_binop_less:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700545 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700546 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700547 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700548 break;
549 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700550 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700551 break;
552 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700553 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700554 break;
555 default:
556 assert(0);
557 }
558 break;
559 case ir_binop_greater:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700560 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700561 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700562 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700563 break;
564 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700565 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700566 break;
567 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700568 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700569 break;
570 default:
571 assert(0);
572 }
573 break;
574 case ir_binop_lequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700575 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700576 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700577 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700578 break;
579 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700580 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700581 break;
582 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700583 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700584 break;
585 default:
586 assert(0);
587 }
588 break;
589 case ir_binop_gequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700590 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700591 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700592 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700593 break;
594 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700595 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700596 break;
597 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700598 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700599 break;
600 default:
601 assert(0);
602 }
603 break;
604
Eric Anholtec1949e2010-04-06 10:02:27 -0700605 case ir_binop_equal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700606 data.b[0] = op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700607 break;
608 case ir_binop_nequal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700609 data.b[0] = !op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700610 break;
611
Eric Anholta576f9d2010-03-31 16:25:12 -1000612 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700613 /* FINISHME: Should handle all expression types. */
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700614 return NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000615 }
Eric Anholtd98da972010-04-01 18:25:11 -1000616
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700617 void *ctx = talloc_parent(this);
618 return new(ctx) ir_constant(this->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700619}
620
621
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700622ir_constant *
623ir_texture::constant_expression_value()
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700624{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700625 /* texture lookups aren't constant expressions */
626 return NULL;
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700627}
628
629
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700630ir_constant *
631ir_swizzle::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700632{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700633 ir_constant *v = this->val->constant_expression_value();
Ian Romanickc2ba6192010-06-11 12:30:28 -0700634
Ian Romanickc2ba6192010-06-11 12:30:28 -0700635 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700636 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700637
638 const unsigned swiz_idx[4] = {
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700639 this->mask.x, this->mask.y, this->mask.z, this->mask.w
Ian Romanickc2ba6192010-06-11 12:30:28 -0700640 };
641
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700642 for (unsigned i = 0; i < this->mask.num_components; i++) {
Ian Romanickc2ba6192010-06-11 12:30:28 -0700643 switch (v->type->base_type) {
644 case GLSL_TYPE_UINT:
645 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
646 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
647 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
648 default: assert(!"Should not get here."); break;
649 }
650 }
651
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700652 void *ctx = talloc_parent(this);
653 return new(ctx) ir_constant(this->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700654 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700655 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700656}
657
658
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700659ir_constant *
660ir_dereference_variable::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700661{
Kenneth Graunkee4768ee2010-07-15 10:27:53 -0700662 return var->constant_value ? var->constant_value->clone(NULL) : NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200663}
664
665
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700666ir_constant *
667ir_dereference_array::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200668{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700669 void *ctx = talloc_parent(this);
670 ir_constant *array = this->array->constant_expression_value();
671 ir_constant *idx = this->array_index->constant_expression_value();
Ian Romanick9b92af92010-06-11 12:20:12 -0700672
Ian Romanick9b92af92010-06-11 12:20:12 -0700673 if ((array != NULL) && (idx != NULL)) {
674 if (array->type->is_matrix()) {
675 /* Array access of a matrix results in a vector.
676 */
677 const unsigned column = idx->value.u[0];
678
679 const glsl_type *const column_type = array->type->column_type();
680
681 /* Offset in the constant matrix to the first element of the column
682 * to be extracted.
683 */
684 const unsigned mat_idx = column * column_type->vector_elements;
685
Ian Romanick0bb70a32010-06-11 15:49:49 -0700686 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700687
688 switch (column_type->base_type) {
689 case GLSL_TYPE_UINT:
690 case GLSL_TYPE_INT:
691 for (unsigned i = 0; i < column_type->vector_elements; i++)
692 data.u[i] = array->value.u[mat_idx + i];
693
694 break;
695
696 case GLSL_TYPE_FLOAT:
697 for (unsigned i = 0; i < column_type->vector_elements; i++)
698 data.f[i] = array->value.f[mat_idx + i];
699
700 break;
701
702 default:
703 assert(!"Should not get here.");
704 break;
705 }
706
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700707 return new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700708 } else if (array->type->is_vector()) {
709 const unsigned component = idx->value.u[0];
710
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700711 return new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700712 } else {
713 /* FINISHME: Handle access of constant arrays. */
714 }
715 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700716 return NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200717}
718
719
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700720ir_constant *
721ir_dereference_record::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200722{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700723 ir_constant *v = this->record->constant_expression_value();
Ian Romanick253dede2010-06-09 17:30:19 -0700724
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700725 return (v != NULL) ? v->get_record_field(this->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700726}
727
728
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700729ir_constant *
730ir_assignment::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700731{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700732 /* FINISHME: Handle CEs involving assignment (return RHS) */
733 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700734}
735
736
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700737ir_constant *
738ir_constant::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700739{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700740 return this;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700741}
742
743
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700744ir_constant *
745ir_call::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700746{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700747 /* FINISHME: Handle CEs involving builtin function calls. */
748 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700749}
750