blob: acfbb8645972609ce59af47d554f1579592f1938 [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:
Kenneth Graunke46d6b8d2010-07-20 13:01:56 -070090 assert(op[0]->type->base_type == GLSL_TYPE_INT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -070091 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke46d6b8d2010-07-20 13:01:56 -070092 data.f[c] = op[0]->value.i[c];
93 }
94 break;
95 case ir_unop_u2f:
96 assert(op[0]->type->base_type == GLSL_TYPE_UINT);
97 for (unsigned c = 0; c < op[0]->type->components(); c++) {
98 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -070099 }
100 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700101 case ir_unop_b2f:
102 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700103 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700104 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700105 }
106 break;
107 case ir_unop_f2b:
108 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700109 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700110 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700111 }
112 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700113 case ir_unop_b2i:
114 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700115 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700116 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700117 }
118 break;
119 case ir_unop_i2b:
120 assert(op[0]->type->is_integer());
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700121 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700122 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700123 }
124 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700125
Kenneth Graunke323d9092010-07-08 23:21:36 -0700126 case ir_unop_trunc:
127 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700128 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke323d9092010-07-08 23:21:36 -0700129 data.f[c] = truncf(op[0]->value.f[c]);
130 }
131 break;
132
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700133 case ir_unop_ceil:
134 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700135 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700136 data.f[c] = ceilf(op[0]->value.f[c]);
137 }
138 break;
139
Kenneth Graunke07472042010-07-08 23:23:23 -0700140 case ir_unop_floor:
141 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700142 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke07472042010-07-08 23:23:23 -0700143 data.f[c] = floorf(op[0]->value.f[c]);
144 }
145 break;
146
Eric Anholtd925c912010-07-01 10:37:11 -0700147 case ir_unop_fract:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700148 for (unsigned c = 0; c < op[0]->type->components(); c++) {
149 switch (this->type->base_type) {
Eric Anholtd925c912010-07-01 10:37:11 -0700150 case GLSL_TYPE_UINT:
151 data.u[c] = 0;
152 break;
153 case GLSL_TYPE_INT:
154 data.i[c] = 0;
155 break;
156 case GLSL_TYPE_FLOAT:
157 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
158 break;
159 default:
160 assert(0);
161 }
162 }
163 break;
164
Kenneth Graunke908afd12010-07-08 23:28:50 -0700165 case ir_unop_sin:
166 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700167 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke908afd12010-07-08 23:28:50 -0700168 data.f[c] = sinf(op[0]->value.f[c]);
169 }
170 break;
171
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700172 case ir_unop_cos:
173 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700174 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700175 data.f[c] = cosf(op[0]->value.f[c]);
176 }
177 break;
178
Eric Anholt43ad37a2010-05-12 14:42:21 -0700179 case ir_unop_neg:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700180 for (unsigned c = 0; c < op[0]->type->components(); c++) {
181 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700182 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700183 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700184 break;
185 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700186 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700187 break;
188 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700189 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700190 break;
191 default:
192 assert(0);
193 }
194 }
195 break;
196
197 case ir_unop_abs:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700198 for (unsigned c = 0; c < op[0]->type->components(); c++) {
199 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700200 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700201 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700202 break;
203 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700204 data.i[c] = op[0]->value.i[c];
205 if (data.i[c] < 0)
206 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700207 break;
208 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700209 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700210 break;
211 default:
212 assert(0);
213 }
214 }
215 break;
216
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700217 case ir_unop_sign:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700218 for (unsigned c = 0; c < op[0]->type->components(); c++) {
219 switch (this->type->base_type) {
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700220 case GLSL_TYPE_UINT:
221 data.u[c] = op[0]->value.i[c] > 0;
222 break;
223 case GLSL_TYPE_INT:
224 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
225 break;
226 case GLSL_TYPE_FLOAT:
227 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
228 break;
229 default:
230 assert(0);
231 }
232 }
233 break;
234
Eric Anholt43ad37a2010-05-12 14:42:21 -0700235 case ir_unop_rcp:
236 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700237 for (unsigned c = 0; c < op[0]->type->components(); c++) {
238 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700239 case GLSL_TYPE_UINT:
240 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700241 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700242 break;
243 case GLSL_TYPE_INT:
244 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700245 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700246 break;
247 case GLSL_TYPE_FLOAT:
248 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700249 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700250 break;
251 default:
252 assert(0);
253 }
254 }
255 break;
256
257 case ir_unop_rsq:
258 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700259 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700260 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700261 }
262 break;
263
264 case ir_unop_sqrt:
265 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700266 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700267 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700268 }
269 break;
270
271 case ir_unop_exp:
272 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700273 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700274 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700275 }
276 break;
277
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700278 case ir_unop_exp2:
279 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700280 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700281 data.f[c] = exp2f(op[0]->value.f[c]);
282 }
283 break;
284
Eric Anholt43ad37a2010-05-12 14:42:21 -0700285 case ir_unop_log:
286 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700287 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700288 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700289 }
290 break;
291
Kenneth Graunkecb639292010-07-08 23:18:09 -0700292 case ir_unop_log2:
293 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700294 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkecb639292010-07-08 23:18:09 -0700295 data.f[c] = log2f(op[0]->value.f[c]);
296 }
297 break;
298
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700299 case ir_unop_dFdx:
300 case ir_unop_dFdy:
301 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700302 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700303 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700304 }
305 break;
306
Kenneth Graunke891a0642010-07-08 23:35:09 -0700307 case ir_binop_pow:
308 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700309 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke891a0642010-07-08 23:35:09 -0700310 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
311 }
312 break;
313
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700314 case ir_binop_dot:
315 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
316 data.f[0] = 0;
Kenneth Graunkef14e5962010-07-06 16:26:11 -0700317 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700318 switch (op[0]->type->base_type) {
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700319 case GLSL_TYPE_UINT:
320 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
321 break;
322 case GLSL_TYPE_INT:
323 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
324 break;
325 case GLSL_TYPE_FLOAT:
326 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
327 break;
328 default:
329 assert(0);
330 }
331 }
332
333 break;
Kenneth Graunke79fed372010-07-09 11:53:56 -0700334 case ir_binop_min:
335 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
336 for (unsigned c = 0, c0 = 0, c1 = 0;
337 c < components;
338 c0 += c0_inc, c1 += c1_inc, c++) {
339
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700340 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700341 case GLSL_TYPE_UINT:
342 data.u[c] = min(op[0]->value.u[c0], op[1]->value.u[c1]);
343 break;
344 case GLSL_TYPE_INT:
345 data.i[c] = min(op[0]->value.i[c0], op[1]->value.i[c1]);
346 break;
347 case GLSL_TYPE_FLOAT:
348 data.f[c] = min(op[0]->value.f[c0], op[1]->value.f[c1]);
349 break;
350 default:
351 assert(0);
352 }
353 }
354
355 break;
356 case ir_binop_max:
357 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
358 for (unsigned c = 0, c0 = 0, c1 = 0;
359 c < components;
360 c0 += c0_inc, c1 += c1_inc, c++) {
361
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700362 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700363 case GLSL_TYPE_UINT:
364 data.u[c] = max(op[0]->value.u[c0], op[1]->value.u[c1]);
365 break;
366 case GLSL_TYPE_INT:
367 data.i[c] = max(op[0]->value.i[c0], op[1]->value.i[c1]);
368 break;
369 case GLSL_TYPE_FLOAT:
370 data.f[c] = max(op[0]->value.f[c0], op[1]->value.f[c1]);
371 break;
372 default:
373 assert(0);
374 }
375 }
Kenneth Graunke79fed372010-07-09 11:53:56 -0700376 break;
Eric Anholt9be7f632010-07-13 15:37:57 -0700377
378 case ir_binop_cross:
379 assert(op[0]->type == glsl_type::vec3_type);
380 assert(op[1]->type == glsl_type::vec3_type);
381 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
382 op[1]->value.f[1] * op[0]->value.f[2]);
383 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
384 op[1]->value.f[2] * op[0]->value.f[0]);
385 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
386 op[1]->value.f[0] * op[0]->value.f[1]);
387 break;
388
Eric Anholtd251b922010-04-01 18:35:42 -1000389 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700390 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
391 for (unsigned c = 0, c0 = 0, c1 = 0;
392 c < components;
393 c0 += c0_inc, c1 += c1_inc, c++) {
394
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700395 switch (op[0]->type->base_type) {
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700396 case GLSL_TYPE_UINT:
397 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
398 break;
399 case GLSL_TYPE_INT:
400 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
401 break;
402 case GLSL_TYPE_FLOAT:
403 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
404 break;
405 default:
406 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000407 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700408 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700409
Eric Anholtd251b922010-04-01 18:35:42 -1000410 break;
411 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700412 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
413 for (unsigned c = 0, c0 = 0, c1 = 0;
414 c < components;
415 c0 += c0_inc, c1 += c1_inc, c++) {
416
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700417 switch (op[0]->type->base_type) {
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700418 case GLSL_TYPE_UINT:
419 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
420 break;
421 case GLSL_TYPE_INT:
422 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
423 break;
424 case GLSL_TYPE_FLOAT:
425 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
426 break;
427 default:
428 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000429 }
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700430 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700431
Eric Anholtd251b922010-04-01 18:35:42 -1000432 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000433 case ir_binop_mul:
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700434 /* Check for equal types, or unequal types involving scalars */
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700435 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
436 || op0_scalar || op1_scalar) {
437 for (unsigned c = 0, c0 = 0, c1 = 0;
438 c < components;
439 c0 += c0_inc, c1 += c1_inc, c++) {
440
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700441 switch (op[0]->type->base_type) {
Eric Anholtd98da972010-04-01 18:25:11 -1000442 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700443 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000444 break;
445 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700446 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000447 break;
448 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700449 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000450 break;
451 default:
452 assert(0);
453 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000454 }
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700455 } else {
456 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
457
458 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
459 * matrix can be a GLSL vector, either N or P can be 1.
460 *
461 * For vec*mat, the vector is treated as a row vector. This
462 * means the vector is a 1-row x M-column matrix.
463 *
464 * For mat*vec, the vector is treated as a column vector. Since
465 * matrix_columns is 1 for vectors, this just works.
466 */
467 const unsigned n = op[0]->type->is_vector()
468 ? 1 : op[0]->type->vector_elements;
469 const unsigned m = op[1]->type->vector_elements;
470 const unsigned p = op[1]->type->matrix_columns;
471 for (unsigned j = 0; j < p; j++) {
472 for (unsigned i = 0; i < n; i++) {
473 for (unsigned k = 0; k < m; k++) {
474 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
475 }
476 }
477 }
478 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700479
Eric Anholta576f9d2010-03-31 16:25:12 -1000480 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000481 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700482 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
483 for (unsigned c = 0, c0 = 0, c1 = 0;
484 c < components;
485 c0 += c0_inc, c1 += c1_inc, c++) {
486
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700487 switch (op[0]->type->base_type) {
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700488 case GLSL_TYPE_UINT:
489 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
490 break;
491 case GLSL_TYPE_INT:
492 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
493 break;
494 case GLSL_TYPE_FLOAT:
495 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
496 break;
497 default:
498 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000499 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700500 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700501
Eric Anholtd251b922010-04-01 18:35:42 -1000502 break;
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700503 case ir_binop_mod:
504 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
505 for (unsigned c = 0, c0 = 0, c1 = 0;
506 c < components;
507 c0 += c0_inc, c1 += c1_inc, c++) {
508
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700509 switch (op[0]->type->base_type) {
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700510 case GLSL_TYPE_UINT:
511 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
512 break;
513 case GLSL_TYPE_INT:
514 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
515 break;
516 case GLSL_TYPE_FLOAT:
517 /* We don't use fmod because it rounds toward zero; GLSL specifies
518 * the use of floor.
519 */
520 data.f[c] = (op[0]->value.f[c0] - op[1]->value.f[c1])
521 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
522 break;
523 default:
524 assert(0);
525 }
526 }
527
528 break;
529
Eric Anholta576f9d2010-03-31 16:25:12 -1000530 case ir_binop_logic_and:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700531 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700532 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700533 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000534 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000535 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700536 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700537 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700538 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000539 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000540 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700541 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700542 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700543 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000544 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700545
546 case ir_binop_less:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700547 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700548 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700549 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700550 break;
551 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700552 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700553 break;
554 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700555 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700556 break;
557 default:
558 assert(0);
559 }
560 break;
561 case ir_binop_greater:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700562 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700563 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700564 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700565 break;
566 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700567 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700568 break;
569 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700570 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700571 break;
572 default:
573 assert(0);
574 }
575 break;
576 case ir_binop_lequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700577 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700578 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700579 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700580 break;
581 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700582 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700583 break;
584 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700585 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700586 break;
587 default:
588 assert(0);
589 }
590 break;
591 case ir_binop_gequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700592 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700593 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700594 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700595 break;
596 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700597 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700598 break;
599 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700600 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700601 break;
602 default:
603 assert(0);
604 }
605 break;
606
Eric Anholtec1949e2010-04-06 10:02:27 -0700607 case ir_binop_equal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700608 data.b[0] = op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700609 break;
610 case ir_binop_nequal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700611 data.b[0] = !op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700612 break;
613
Eric Anholta576f9d2010-03-31 16:25:12 -1000614 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700615 /* FINISHME: Should handle all expression types. */
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700616 return NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000617 }
Eric Anholtd98da972010-04-01 18:25:11 -1000618
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700619 void *ctx = talloc_parent(this);
620 return new(ctx) ir_constant(this->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700621}
622
623
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700624ir_constant *
625ir_texture::constant_expression_value()
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700626{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700627 /* texture lookups aren't constant expressions */
628 return NULL;
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700629}
630
631
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700632ir_constant *
633ir_swizzle::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700634{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700635 ir_constant *v = this->val->constant_expression_value();
Ian Romanickc2ba6192010-06-11 12:30:28 -0700636
Ian Romanickc2ba6192010-06-11 12:30:28 -0700637 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700638 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700639
640 const unsigned swiz_idx[4] = {
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700641 this->mask.x, this->mask.y, this->mask.z, this->mask.w
Ian Romanickc2ba6192010-06-11 12:30:28 -0700642 };
643
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700644 for (unsigned i = 0; i < this->mask.num_components; i++) {
Ian Romanickc2ba6192010-06-11 12:30:28 -0700645 switch (v->type->base_type) {
646 case GLSL_TYPE_UINT:
647 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
648 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
649 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
650 default: assert(!"Should not get here."); break;
651 }
652 }
653
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700654 void *ctx = talloc_parent(this);
655 return new(ctx) ir_constant(this->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700656 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700657 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700658}
659
660
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700661ir_constant *
662ir_dereference_variable::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700663{
Kenneth Graunkee4768ee2010-07-15 10:27:53 -0700664 return var->constant_value ? var->constant_value->clone(NULL) : NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200665}
666
667
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700668ir_constant *
669ir_dereference_array::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200670{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700671 void *ctx = talloc_parent(this);
672 ir_constant *array = this->array->constant_expression_value();
673 ir_constant *idx = this->array_index->constant_expression_value();
Ian Romanick9b92af92010-06-11 12:20:12 -0700674
Ian Romanick9b92af92010-06-11 12:20:12 -0700675 if ((array != NULL) && (idx != NULL)) {
676 if (array->type->is_matrix()) {
677 /* Array access of a matrix results in a vector.
678 */
679 const unsigned column = idx->value.u[0];
680
681 const glsl_type *const column_type = array->type->column_type();
682
683 /* Offset in the constant matrix to the first element of the column
684 * to be extracted.
685 */
686 const unsigned mat_idx = column * column_type->vector_elements;
687
Ian Romanick0bb70a32010-06-11 15:49:49 -0700688 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700689
690 switch (column_type->base_type) {
691 case GLSL_TYPE_UINT:
692 case GLSL_TYPE_INT:
693 for (unsigned i = 0; i < column_type->vector_elements; i++)
694 data.u[i] = array->value.u[mat_idx + i];
695
696 break;
697
698 case GLSL_TYPE_FLOAT:
699 for (unsigned i = 0; i < column_type->vector_elements; i++)
700 data.f[i] = array->value.f[mat_idx + i];
701
702 break;
703
704 default:
705 assert(!"Should not get here.");
706 break;
707 }
708
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700709 return new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700710 } else if (array->type->is_vector()) {
711 const unsigned component = idx->value.u[0];
712
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700713 return new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700714 } else {
715 /* FINISHME: Handle access of constant arrays. */
716 }
717 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700718 return NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200719}
720
721
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700722ir_constant *
723ir_dereference_record::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200724{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700725 ir_constant *v = this->record->constant_expression_value();
Ian Romanick253dede2010-06-09 17:30:19 -0700726
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700727 return (v != NULL) ? v->get_record_field(this->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700728}
729
730
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700731ir_constant *
732ir_assignment::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700733{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700734 /* FINISHME: Handle CEs involving assignment (return RHS) */
735 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700736}
737
738
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700739ir_constant *
740ir_constant::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700741{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700742 return this;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700743}
744
745
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700746ir_constant *
747ir_call::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700748{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700749 /* FINISHME: Handle CEs involving builtin function calls. */
750 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700751}
752