blob: 0a924246da1d3d224e28978a48b11be9f32fdf91 [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>
Kenneth Graunkef9149152010-07-21 21:56:13 -070037#include "main/macros.h"
Ian Romanick1cf43a42010-03-30 16:56:50 -070038#include "ir.h"
39#include "ir_visitor.h"
Eric Anholta576f9d2010-03-31 16:25:12 -100040#include "glsl_types.h"
Ian Romanick1cf43a42010-03-30 16:56:50 -070041
Kenneth Graunkeffcec132010-07-21 20:09:21 -070042static float
43dot(ir_constant *op0, ir_constant *op1)
44{
45 assert(op0->type->is_float() && op1->type->is_float());
46
47 float result = 0;
48 for (unsigned c = 0; c < op0->type->components(); c++)
49 result += op0->value.f[c] * op1->value.f[c];
50
51 return result;
52}
53
Ian Romanick1cf43a42010-03-30 16:56:50 -070054ir_constant *
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -070055ir_expression::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -070056{
Kenneth Graunke6bc432e2010-07-02 17:12:23 -070057 ir_constant *op[2] = { NULL, NULL };
Ian Romanick4daaab62010-06-11 16:08:47 -070058 ir_constant_data data;
Eric Anholt160d0922010-04-01 18:07:08 -100059
Kenneth Graunkec63a1db2010-07-05 22:33:35 -070060 memset(&data, 0, sizeof(data));
61
Kenneth Graunke98f32a12010-07-15 10:20:51 -070062 for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
63 op[operand] = this->operands[operand]->constant_expression_value();
Eric Anholtd98da972010-04-01 18:25:11 -100064 if (!op[operand])
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -070065 return NULL;
Eric Anholt160d0922010-04-01 18:07:08 -100066 }
Eric Anholta576f9d2010-03-31 16:25:12 -100067
Kenneth Graunke6fc983b2010-07-06 02:39:57 -070068 if (op[1] != NULL)
69 assert(op[0]->type->base_type == op[1]->type->base_type);
70
Kenneth Graunkee74dcd72010-07-06 02:48:16 -070071 bool op0_scalar = op[0]->type->is_scalar();
72 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
73
74 /* When iterating over a vector or matrix's components, we want to increase
75 * the loop counter. However, for scalars, we want to stay at 0.
76 */
Kenneth Graunkeacf88f22010-07-07 12:08:23 -070077 unsigned c0_inc = op0_scalar ? 0 : 1;
78 unsigned c1_inc = op1_scalar ? 0 : 1;
Eric Anholt570dc0d2010-07-07 09:07:09 -070079 unsigned components;
80 if (op1_scalar || !op[1]) {
81 components = op[0]->type->components();
82 } else {
83 components = op[1]->type->components();
84 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -070085
Kenneth Graunke9a6d40f2010-07-20 03:08:32 -070086 void *ctx = talloc_parent(this);
87
88 /* Handle array operations here, rather than below. */
89 if (op[0]->type->is_array()) {
90 assert(op[1] != NULL && op[1]->type->is_array());
91 switch (this->operation) {
92 case ir_binop_equal:
93 return new(ctx) ir_constant(op[0]->has_value(op[1]));
94 case ir_binop_nequal:
95 return new(ctx) ir_constant(!op[0]->has_value(op[1]));
96 default:
97 break;
98 }
99 return NULL;
100 }
101
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700102 switch (this->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000103 case ir_unop_logic_not:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700104 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700105 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700106 data.b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000107 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700108
109 case ir_unop_f2i:
110 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700111 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700112 data.i[c] = op[0]->value.f[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700113 }
114 break;
115 case ir_unop_i2f:
Kenneth Graunke46d6b8d2010-07-20 13:01:56 -0700116 assert(op[0]->type->base_type == GLSL_TYPE_INT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700117 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke46d6b8d2010-07-20 13:01:56 -0700118 data.f[c] = op[0]->value.i[c];
119 }
120 break;
121 case ir_unop_u2f:
122 assert(op[0]->type->base_type == GLSL_TYPE_UINT);
123 for (unsigned c = 0; c < op[0]->type->components(); c++) {
124 data.f[c] = op[0]->value.u[c];
Eric Anholtaf186412010-04-06 10:53:57 -0700125 }
126 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700127 case ir_unop_b2f:
128 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700129 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700130 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700131 }
132 break;
133 case ir_unop_f2b:
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++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700136 data.b[c] = bool(op[0]->value.f[c]);
Ian Romanick7dc2b712010-06-07 15:10:14 -0700137 }
138 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700139 case ir_unop_b2i:
140 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700141 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700142 data.u[c] = op[0]->value.b[c] ? 1 : 0;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700143 }
144 break;
145 case ir_unop_i2b:
146 assert(op[0]->type->is_integer());
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700147 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700148 data.b[c] = bool(op[0]->value.u[c]);
Ian Romanick39d6dd32010-06-11 13:46:30 -0700149 }
150 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700151
Kenneth Graunke323d9092010-07-08 23:21:36 -0700152 case ir_unop_trunc:
153 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700154 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke323d9092010-07-08 23:21:36 -0700155 data.f[c] = truncf(op[0]->value.f[c]);
156 }
157 break;
158
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700159 case ir_unop_ceil:
160 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700161 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkec1ee30a2010-07-08 23:22:36 -0700162 data.f[c] = ceilf(op[0]->value.f[c]);
163 }
164 break;
165
Kenneth Graunke07472042010-07-08 23:23:23 -0700166 case ir_unop_floor:
167 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700168 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke07472042010-07-08 23:23:23 -0700169 data.f[c] = floorf(op[0]->value.f[c]);
170 }
171 break;
172
Eric Anholtd925c912010-07-01 10:37:11 -0700173 case ir_unop_fract:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700174 for (unsigned c = 0; c < op[0]->type->components(); c++) {
175 switch (this->type->base_type) {
Eric Anholtd925c912010-07-01 10:37:11 -0700176 case GLSL_TYPE_UINT:
177 data.u[c] = 0;
178 break;
179 case GLSL_TYPE_INT:
180 data.i[c] = 0;
181 break;
182 case GLSL_TYPE_FLOAT:
183 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
184 break;
185 default:
186 assert(0);
187 }
188 }
189 break;
190
Kenneth Graunke908afd12010-07-08 23:28:50 -0700191 case ir_unop_sin:
192 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700193 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke908afd12010-07-08 23:28:50 -0700194 data.f[c] = sinf(op[0]->value.f[c]);
195 }
196 break;
197
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700198 case ir_unop_cos:
199 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700200 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke3fab3762010-07-08 23:29:37 -0700201 data.f[c] = cosf(op[0]->value.f[c]);
202 }
203 break;
204
Eric Anholt43ad37a2010-05-12 14:42:21 -0700205 case ir_unop_neg:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700206 for (unsigned c = 0; c < op[0]->type->components(); c++) {
207 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700208 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700209 data.u[c] = -op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700210 break;
211 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700212 data.i[c] = -op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700213 break;
214 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700215 data.f[c] = -op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700216 break;
217 default:
218 assert(0);
219 }
220 }
221 break;
222
223 case ir_unop_abs:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700224 for (unsigned c = 0; c < op[0]->type->components(); c++) {
225 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700226 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700227 data.u[c] = op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700228 break;
229 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700230 data.i[c] = op[0]->value.i[c];
231 if (data.i[c] < 0)
232 data.i[c] = -data.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700233 break;
234 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700235 data.f[c] = fabs(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700236 break;
237 default:
238 assert(0);
239 }
240 }
241 break;
242
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700243 case ir_unop_sign:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700244 for (unsigned c = 0; c < op[0]->type->components(); c++) {
245 switch (this->type->base_type) {
Kenneth Graunke14b7b262010-07-08 23:11:14 -0700246 case GLSL_TYPE_UINT:
247 data.u[c] = op[0]->value.i[c] > 0;
248 break;
249 case GLSL_TYPE_INT:
250 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
251 break;
252 case GLSL_TYPE_FLOAT:
253 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
254 break;
255 default:
256 assert(0);
257 }
258 }
259 break;
260
Eric Anholt43ad37a2010-05-12 14:42:21 -0700261 case ir_unop_rcp:
262 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700263 for (unsigned c = 0; c < op[0]->type->components(); c++) {
264 switch (this->type->base_type) {
Eric Anholt43ad37a2010-05-12 14:42:21 -0700265 case GLSL_TYPE_UINT:
266 if (op[0]->value.u[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700267 data.u[c] = 1 / op[0]->value.u[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700268 break;
269 case GLSL_TYPE_INT:
270 if (op[0]->value.i[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700271 data.i[c] = 1 / op[0]->value.i[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700272 break;
273 case GLSL_TYPE_FLOAT:
274 if (op[0]->value.f[c] != 0.0)
Ian Romanick4daaab62010-06-11 16:08:47 -0700275 data.f[c] = 1.0 / op[0]->value.f[c];
Eric Anholt43ad37a2010-05-12 14:42:21 -0700276 break;
277 default:
278 assert(0);
279 }
280 }
281 break;
282
283 case ir_unop_rsq:
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] = 1.0 / sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700287 }
288 break;
289
290 case ir_unop_sqrt:
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++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700293 data.f[c] = sqrtf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700294 }
295 break;
296
297 case ir_unop_exp:
298 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700299 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700300 data.f[c] = expf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700301 }
302 break;
303
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700304 case ir_unop_exp2:
305 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700306 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkeaca01ed2010-07-08 23:14:32 -0700307 data.f[c] = exp2f(op[0]->value.f[c]);
308 }
309 break;
310
Eric Anholt43ad37a2010-05-12 14:42:21 -0700311 case ir_unop_log:
312 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700313 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700314 data.f[c] = logf(op[0]->value.f[c]);
Eric Anholt43ad37a2010-05-12 14:42:21 -0700315 }
316 break;
317
Kenneth Graunkecb639292010-07-08 23:18:09 -0700318 case ir_unop_log2:
319 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700320 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunkecb639292010-07-08 23:18:09 -0700321 data.f[c] = log2f(op[0]->value.f[c]);
322 }
323 break;
324
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700325 case ir_unop_dFdx:
326 case ir_unop_dFdy:
327 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700328 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Ian Romanick4daaab62010-06-11 16:08:47 -0700329 data.f[c] = 0.0;
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700330 }
331 break;
332
Kenneth Graunke891a0642010-07-08 23:35:09 -0700333 case ir_binop_pow:
334 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700335 for (unsigned c = 0; c < op[0]->type->components(); c++) {
Kenneth Graunke891a0642010-07-08 23:35:09 -0700336 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
337 }
338 break;
339
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700340 case ir_binop_dot:
Kenneth Graunkeffcec132010-07-21 20:09:21 -0700341 data.f[0] = dot(op[0], op[1]);
Kenneth Graunke3f4a0b82010-07-05 21:15:32 -0700342 break;
Kenneth Graunkeffcec132010-07-21 20:09:21 -0700343
Kenneth Graunke79fed372010-07-09 11:53:56 -0700344 case ir_binop_min:
345 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
346 for (unsigned c = 0, c0 = 0, c1 = 0;
347 c < components;
348 c0 += c0_inc, c1 += c1_inc, c++) {
349
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700350 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700351 case GLSL_TYPE_UINT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700352 data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700353 break;
354 case GLSL_TYPE_INT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700355 data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700356 break;
357 case GLSL_TYPE_FLOAT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700358 data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700359 break;
360 default:
361 assert(0);
362 }
363 }
364
365 break;
366 case ir_binop_max:
367 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
368 for (unsigned c = 0, c0 = 0, c1 = 0;
369 c < components;
370 c0 += c0_inc, c1 += c1_inc, c++) {
371
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700372 switch (op[0]->type->base_type) {
Kenneth Graunke79fed372010-07-09 11:53:56 -0700373 case GLSL_TYPE_UINT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700374 data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700375 break;
376 case GLSL_TYPE_INT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700377 data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700378 break;
379 case GLSL_TYPE_FLOAT:
Kenneth Graunkef9149152010-07-21 21:56:13 -0700380 data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
Kenneth Graunke79fed372010-07-09 11:53:56 -0700381 break;
382 default:
383 assert(0);
384 }
385 }
Kenneth Graunke79fed372010-07-09 11:53:56 -0700386 break;
Eric Anholt9be7f632010-07-13 15:37:57 -0700387
388 case ir_binop_cross:
389 assert(op[0]->type == glsl_type::vec3_type);
390 assert(op[1]->type == glsl_type::vec3_type);
391 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
392 op[1]->value.f[1] * op[0]->value.f[2]);
393 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
394 op[1]->value.f[2] * op[0]->value.f[0]);
395 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
396 op[1]->value.f[0] * op[0]->value.f[1]);
397 break;
398
Eric Anholtd251b922010-04-01 18:35:42 -1000399 case ir_binop_add:
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700400 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
401 for (unsigned c = 0, c0 = 0, c1 = 0;
402 c < components;
403 c0 += c0_inc, c1 += c1_inc, c++) {
404
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700405 switch (op[0]->type->base_type) {
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700406 case GLSL_TYPE_UINT:
407 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
408 break;
409 case GLSL_TYPE_INT:
410 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
411 break;
412 case GLSL_TYPE_FLOAT:
413 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
414 break;
415 default:
416 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000417 }
Kenneth Graunkee74dcd72010-07-06 02:48:16 -0700418 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700419
Eric Anholtd251b922010-04-01 18:35:42 -1000420 break;
421 case ir_binop_sub:
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700422 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
423 for (unsigned c = 0, c0 = 0, c1 = 0;
424 c < components;
425 c0 += c0_inc, c1 += c1_inc, c++) {
426
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700427 switch (op[0]->type->base_type) {
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700428 case GLSL_TYPE_UINT:
429 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
430 break;
431 case GLSL_TYPE_INT:
432 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
433 break;
434 case GLSL_TYPE_FLOAT:
435 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
436 break;
437 default:
438 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000439 }
Kenneth Graunke97b44f02010-07-06 02:53:29 -0700440 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700441
Eric Anholtd251b922010-04-01 18:35:42 -1000442 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000443 case ir_binop_mul:
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700444 /* Check for equal types, or unequal types involving scalars */
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700445 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
446 || op0_scalar || op1_scalar) {
447 for (unsigned c = 0, c0 = 0, c1 = 0;
448 c < components;
449 c0 += c0_inc, c1 += c1_inc, c++) {
450
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700451 switch (op[0]->type->base_type) {
Eric Anholtd98da972010-04-01 18:25:11 -1000452 case GLSL_TYPE_UINT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700453 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000454 break;
455 case GLSL_TYPE_INT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700456 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000457 break;
458 case GLSL_TYPE_FLOAT:
Kenneth Graunke37b3f9d2010-07-06 03:01:15 -0700459 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
Eric Anholtd98da972010-04-01 18:25:11 -1000460 break;
461 default:
462 assert(0);
463 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000464 }
Kenneth Graunkecf80a4d2010-07-05 23:19:56 -0700465 } else {
466 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
467
468 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
469 * matrix can be a GLSL vector, either N or P can be 1.
470 *
471 * For vec*mat, the vector is treated as a row vector. This
472 * means the vector is a 1-row x M-column matrix.
473 *
474 * For mat*vec, the vector is treated as a column vector. Since
475 * matrix_columns is 1 for vectors, this just works.
476 */
477 const unsigned n = op[0]->type->is_vector()
478 ? 1 : op[0]->type->vector_elements;
479 const unsigned m = op[1]->type->vector_elements;
480 const unsigned p = op[1]->type->matrix_columns;
481 for (unsigned j = 0; j < p; j++) {
482 for (unsigned i = 0; i < n; i++) {
483 for (unsigned k = 0; k < m; k++) {
484 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
485 }
486 }
487 }
488 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700489
Eric Anholta576f9d2010-03-31 16:25:12 -1000490 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000491 case ir_binop_div:
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700492 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
493 for (unsigned c = 0, c0 = 0, c1 = 0;
494 c < components;
495 c0 += c0_inc, c1 += c1_inc, c++) {
496
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700497 switch (op[0]->type->base_type) {
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700498 case GLSL_TYPE_UINT:
499 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
500 break;
501 case GLSL_TYPE_INT:
502 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
503 break;
504 case GLSL_TYPE_FLOAT:
505 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
506 break;
507 default:
508 assert(0);
Eric Anholtd251b922010-04-01 18:35:42 -1000509 }
Kenneth Graunkedad35eb2010-07-06 02:56:36 -0700510 }
Ian Romanickf8b88be2010-06-11 16:23:52 -0700511
Eric Anholtd251b922010-04-01 18:35:42 -1000512 break;
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700513 case ir_binop_mod:
514 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
515 for (unsigned c = 0, c0 = 0, c1 = 0;
516 c < components;
517 c0 += c0_inc, c1 += c1_inc, c++) {
518
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700519 switch (op[0]->type->base_type) {
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700520 case GLSL_TYPE_UINT:
521 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
522 break;
523 case GLSL_TYPE_INT:
524 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
525 break;
526 case GLSL_TYPE_FLOAT:
527 /* We don't use fmod because it rounds toward zero; GLSL specifies
528 * the use of floor.
529 */
Kenneth Graunke3e882ec2010-07-22 17:44:34 -0700530 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
Kenneth Graunkece5ae5f2010-07-14 11:28:40 -0700531 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
532 break;
533 default:
534 assert(0);
535 }
536 }
537
538 break;
539
Eric Anholta576f9d2010-03-31 16:25:12 -1000540 case ir_binop_logic_and:
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 Anholtd251b922010-04-01 18:35:42 -1000545 case ir_binop_logic_xor:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700546 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700547 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700548 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
Eric Anholtd251b922010-04-01 18:35:42 -1000549 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000550 case ir_binop_logic_or:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700551 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700552 for (unsigned c = 0; c < op[0]->type->components(); c++)
Ian Romanick4daaab62010-06-11 16:08:47 -0700553 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000554 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700555
556 case ir_binop_less:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700557 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700558 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700559 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700560 break;
561 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700562 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700563 break;
564 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700565 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700566 break;
567 default:
568 assert(0);
569 }
570 break;
571 case ir_binop_greater:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700572 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700573 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700574 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700575 break;
576 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700577 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700578 break;
579 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700580 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700581 break;
582 default:
583 assert(0);
584 }
585 break;
586 case ir_binop_lequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700587 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700588 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700589 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700590 break;
591 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700592 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700593 break;
594 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700595 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700596 break;
597 default:
598 assert(0);
599 }
600 break;
601 case ir_binop_gequal:
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700602 switch (op[0]->type->base_type) {
Eric Anholt85171c22010-04-06 09:55:45 -0700603 case GLSL_TYPE_UINT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700604 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700605 break;
606 case GLSL_TYPE_INT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700607 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700608 break;
609 case GLSL_TYPE_FLOAT:
Ian Romanick4daaab62010-06-11 16:08:47 -0700610 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
Eric Anholt85171c22010-04-06 09:55:45 -0700611 break;
612 default:
613 assert(0);
614 }
615 break;
616
Eric Anholtec1949e2010-04-06 10:02:27 -0700617 case ir_binop_equal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700618 data.b[0] = op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700619 break;
620 case ir_binop_nequal:
Kenneth Graunke3163f872010-07-20 03:01:54 -0700621 data.b[0] = !op[0]->has_value(op[1]);
Eric Anholtec1949e2010-04-06 10:02:27 -0700622 break;
623
Eric Anholta576f9d2010-03-31 16:25:12 -1000624 default:
Ian Romanickf8b88be2010-06-11 16:23:52 -0700625 /* FINISHME: Should handle all expression types. */
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700626 return NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000627 }
Eric Anholtd98da972010-04-01 18:25:11 -1000628
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700629 return new(ctx) ir_constant(this->type, &data);
Ian Romanick1cf43a42010-03-30 16:56:50 -0700630}
631
632
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700633ir_constant *
634ir_texture::constant_expression_value()
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700635{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700636 /* texture lookups aren't constant expressions */
637 return NULL;
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700638}
639
640
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700641ir_constant *
642ir_swizzle::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700643{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700644 ir_constant *v = this->val->constant_expression_value();
Ian Romanickc2ba6192010-06-11 12:30:28 -0700645
Ian Romanickc2ba6192010-06-11 12:30:28 -0700646 if (v != NULL) {
Ian Romanick0bb70a32010-06-11 15:49:49 -0700647 ir_constant_data data;
Ian Romanickc2ba6192010-06-11 12:30:28 -0700648
649 const unsigned swiz_idx[4] = {
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700650 this->mask.x, this->mask.y, this->mask.z, this->mask.w
Ian Romanickc2ba6192010-06-11 12:30:28 -0700651 };
652
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700653 for (unsigned i = 0; i < this->mask.num_components; i++) {
Ian Romanickc2ba6192010-06-11 12:30:28 -0700654 switch (v->type->base_type) {
655 case GLSL_TYPE_UINT:
656 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
657 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
658 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
659 default: assert(!"Should not get here."); break;
660 }
661 }
662
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700663 void *ctx = talloc_parent(this);
664 return new(ctx) ir_constant(this->type, &data);
Ian Romanickc2ba6192010-06-11 12:30:28 -0700665 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700666 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700667}
668
669
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700670ir_constant *
671ir_dereference_variable::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700672{
Eric Anholt54f583a2010-07-27 12:10:50 -0700673 /* This may occur during compile and var->type is glsl_type::error_type */
674 if (!var)
675 return NULL;
676
Eric Anholt5704ed22010-08-02 15:31:28 -0700677 /* The constant_value of a uniform variable is its initializer,
678 * not the lifetime constant value of the uniform.
679 */
680 if (var->mode == ir_var_uniform)
681 return NULL;
682
Eric Anholt8273bd42010-08-04 12:34:56 -0700683 if (!var->constant_value)
684 return NULL;
685
686 return var->constant_value->clone(talloc_parent(var), NULL);
Ian Romanickc7b10462010-05-19 13:20:12 +0200687}
688
689
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700690ir_constant *
691ir_dereference_array::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200692{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700693 ir_constant *array = this->array->constant_expression_value();
694 ir_constant *idx = this->array_index->constant_expression_value();
Ian Romanick9b92af92010-06-11 12:20:12 -0700695
Ian Romanick9b92af92010-06-11 12:20:12 -0700696 if ((array != NULL) && (idx != NULL)) {
Eric Anholt952d0f82010-08-04 12:57:58 -0700697 void *ctx = talloc_parent(this);
Ian Romanick9b92af92010-06-11 12:20:12 -0700698 if (array->type->is_matrix()) {
699 /* Array access of a matrix results in a vector.
700 */
701 const unsigned column = idx->value.u[0];
702
703 const glsl_type *const column_type = array->type->column_type();
704
705 /* Offset in the constant matrix to the first element of the column
706 * to be extracted.
707 */
708 const unsigned mat_idx = column * column_type->vector_elements;
709
Ian Romanick0bb70a32010-06-11 15:49:49 -0700710 ir_constant_data data;
Ian Romanick9b92af92010-06-11 12:20:12 -0700711
712 switch (column_type->base_type) {
713 case GLSL_TYPE_UINT:
714 case GLSL_TYPE_INT:
715 for (unsigned i = 0; i < column_type->vector_elements; i++)
716 data.u[i] = array->value.u[mat_idx + i];
717
718 break;
719
720 case GLSL_TYPE_FLOAT:
721 for (unsigned i = 0; i < column_type->vector_elements; i++)
722 data.f[i] = array->value.f[mat_idx + i];
723
724 break;
725
726 default:
727 assert(!"Should not get here.");
728 break;
729 }
730
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700731 return new(ctx) ir_constant(column_type, &data);
Ian Romanick9b92af92010-06-11 12:20:12 -0700732 } else if (array->type->is_vector()) {
733 const unsigned component = idx->value.u[0];
734
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700735 return new(ctx) ir_constant(array, component);
Ian Romanick9b92af92010-06-11 12:20:12 -0700736 } else {
Kenneth Graunkea096fa72010-07-20 01:31:29 -0700737 const unsigned index = idx->value.u[0];
Eric Anholt8273bd42010-08-04 12:34:56 -0700738 return array->get_array_element(index)->clone(ctx, NULL);
Ian Romanick9b92af92010-06-11 12:20:12 -0700739 }
740 }
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700741 return NULL;
Ian Romanickc7b10462010-05-19 13:20:12 +0200742}
743
744
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700745ir_constant *
746ir_dereference_record::constant_expression_value()
Ian Romanickc7b10462010-05-19 13:20:12 +0200747{
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700748 ir_constant *v = this->record->constant_expression_value();
Ian Romanick253dede2010-06-09 17:30:19 -0700749
Kenneth Graunke98f32a12010-07-15 10:20:51 -0700750 return (v != NULL) ? v->get_record_field(this->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700751}
752
753
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700754ir_constant *
755ir_assignment::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700756{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700757 /* FINISHME: Handle CEs involving assignment (return RHS) */
758 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700759}
760
761
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700762ir_constant *
763ir_constant::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700764{
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700765 return this;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700766}
767
768
Kenneth Graunkefb2ffd22010-07-15 10:09:09 -0700769ir_constant *
770ir_call::constant_expression_value()
Ian Romanick1cf43a42010-03-30 16:56:50 -0700771{
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700772 if (this->type == glsl_type::error_type)
773 return NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700774
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700775 /* From the GLSL 1.20 spec, page 23:
776 * "Function calls to user-defined functions (non-built-in functions)
777 * cannot be used to form constant expressions."
778 */
779 if (!this->callee->is_built_in)
780 return NULL;
781
782 unsigned num_parameters = 0;
783
784 /* Check if all parameters are constant */
785 ir_constant *op[3];
786 foreach_list(n, &this->actual_parameters) {
787 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
788 if (constant == NULL)
789 return NULL;
790
791 op[num_parameters] = constant;
792
793 assert(num_parameters < 3);
794 num_parameters++;
795 }
796
797 /* Individual cases below can either:
798 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
799 * - Fill "data" with appopriate constant data
800 * - Return an ir_constant directly.
801 */
802 void *mem_ctx = talloc_parent(this);
803 ir_expression *expr = NULL;
804
805 ir_constant_data data;
806 memset(&data, 0, sizeof(data));
807
808 const char *callee = this->callee_name();
809 if (strcmp(callee, "abs") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700810 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700811 } else if (strcmp(callee, "all") == 0) {
Kenneth Graunkeaca7e952010-07-21 17:34:32 -0700812 assert(op[0]->type->is_boolean());
813 for (unsigned c = 0; c < op[0]->type->components(); c++) {
814 if (!op[0]->value.b[c])
815 return new(mem_ctx) ir_constant(false);
816 }
817 return new(mem_ctx) ir_constant(true);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700818 } else if (strcmp(callee, "any") == 0) {
Kenneth Graunked6792a72010-07-21 17:35:52 -0700819 assert(op[0]->type->is_boolean());
820 for (unsigned c = 0; c < op[0]->type->components(); c++) {
821 if (op[0]->value.b[c])
822 return new(mem_ctx) ir_constant(true);
823 }
824 return new(mem_ctx) ir_constant(false);
Kenneth Graunkef6ea9df2010-07-21 17:39:47 -0700825 } else if (strcmp(callee, "acos") == 0) {
826 assert(op[0]->type->is_float());
827 for (unsigned c = 0; c < op[0]->type->components(); c++)
828 data.f[c] = acosf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700829 } else if (strcmp(callee, "asin") == 0) {
Kenneth Graunke3b6c29b2010-07-21 17:38:38 -0700830 assert(op[0]->type->is_float());
831 for (unsigned c = 0; c < op[0]->type->components(); c++)
832 data.f[c] = asinf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700833 } else if (strcmp(callee, "atan") == 0) {
Kenneth Graunke13f87582010-07-21 17:42:23 -0700834 assert(op[0]->type->is_float());
835 if (num_parameters == 2) {
836 assert(op[1]->type->is_float());
837 for (unsigned c = 0; c < op[0]->type->components(); c++)
838 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
839 } else {
840 for (unsigned c = 0; c < op[0]->type->components(); c++)
841 data.f[c] = atanf(op[0]->value.f[c]);
842 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700843 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
Kenneth Graunke38cb1b22010-07-21 16:57:10 -0700844 return ir_constant::zero(mem_ctx, this->type);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700845 } else if (strcmp(callee, "ceil") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700846 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700847 } else if (strcmp(callee, "clamp") == 0) {
Kenneth Graunkea4ca1cf2010-07-21 22:23:17 -0700848 assert(num_parameters == 3);
849 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
850 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
851 for (unsigned c = 0, c1 = 0, c2 = 0;
852 c < op[0]->type->components();
853 c1 += c1_inc, c2 += c2_inc, c++) {
854
855 switch (op[0]->type->base_type) {
856 case GLSL_TYPE_UINT:
857 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
858 op[2]->value.u[c2]);
859 break;
860 case GLSL_TYPE_INT:
861 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
Eric Anholtc8babd52010-08-02 17:49:01 -0700862 op[2]->value.i[c2]);
Kenneth Graunkea4ca1cf2010-07-21 22:23:17 -0700863 break;
864 case GLSL_TYPE_FLOAT:
865 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
866 op[2]->value.f[c2]);
867 break;
868 default:
869 assert(!"Should not get here.");
870 }
871 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700872 } else if (strcmp(callee, "cos") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700873 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700874 } else if (strcmp(callee, "cosh") == 0) {
Kenneth Graunkeba417832010-07-21 17:47:55 -0700875 assert(op[0]->type->is_float());
876 for (unsigned c = 0; c < op[0]->type->components(); c++)
877 data.f[c] = coshf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700878 } else if (strcmp(callee, "cross") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700879 expr = new(mem_ctx) ir_expression(ir_binop_cross, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700880 } else if (strcmp(callee, "degrees") == 0) {
Kenneth Graunke7bcaa382010-07-21 17:59:00 -0700881 assert(op[0]->type->is_float());
882 for (unsigned c = 0; c < op[0]->type->components(); c++)
883 data.f[c] = 180.0/M_PI * op[0]->value.f[c];
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700884 } else if (strcmp(callee, "distance") == 0) {
Kenneth Graunke2eaf3162010-07-21 18:01:22 -0700885 assert(op[0]->type->is_float() && op[1]->type->is_float());
886 float length_squared = 0.0;
887 for (unsigned c = 0; c < op[0]->type->components(); c++) {
888 float t = op[0]->value.f[c] - op[1]->value.f[c];
889 length_squared += t * t;
890 }
891 return new(mem_ctx) ir_constant(sqrtf(length_squared));
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700892 } else if (strcmp(callee, "dot") == 0) {
Kenneth Graunkea7650af2010-07-21 20:12:43 -0700893 return new(mem_ctx) ir_constant(dot(op[0], op[1]));
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700894 } else if (strcmp(callee, "equal") == 0) {
Kenneth Graunke0b6ef6e2010-07-21 18:04:22 -0700895 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
896 for (unsigned c = 0; c < op[0]->type->components(); c++) {
897 switch (op[0]->type->base_type) {
898 case GLSL_TYPE_UINT:
899 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
900 break;
901 case GLSL_TYPE_INT:
902 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
903 break;
904 case GLSL_TYPE_FLOAT:
905 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
906 break;
907 default:
908 assert(!"Should not get here.");
909 }
910 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700911 } else if (strcmp(callee, "exp") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700912 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700913 } else if (strcmp(callee, "exp2") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700914 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700915 } else if (strcmp(callee, "faceforward") == 0) {
Kenneth Graunke3d5c2f02010-07-21 21:46:16 -0700916 if (dot(op[2], op[1]) < 0)
917 return op[0];
918 for (unsigned c = 0; c < op[0]->type->components(); c++)
919 data.f[c] = -op[0]->value.f[c];
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700920 } else if (strcmp(callee, "floor") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700921 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700922 } else if (strcmp(callee, "fract") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700923 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700924 } else if (strcmp(callee, "fwidth") == 0) {
Kenneth Graunke38cb1b22010-07-21 16:57:10 -0700925 return ir_constant::zero(mem_ctx, this->type);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700926 } else if (strcmp(callee, "greaterThan") == 0) {
Kenneth Graunke7f042b92010-07-21 18:07:43 -0700927 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
928 for (unsigned c = 0; c < op[0]->type->components(); c++) {
929 switch (op[0]->type->base_type) {
930 case GLSL_TYPE_UINT:
931 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
932 break;
933 case GLSL_TYPE_INT:
934 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
935 break;
936 case GLSL_TYPE_FLOAT:
937 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
938 break;
939 default:
940 assert(!"Should not get here.");
941 }
942 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700943 } else if (strcmp(callee, "greaterThanEqual") == 0) {
Kenneth Graunke55782732010-07-21 18:08:05 -0700944 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
945 for (unsigned c = 0; c < op[0]->type->components(); c++) {
946 switch (op[0]->type->base_type) {
947 case GLSL_TYPE_UINT:
948 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
949 break;
950 case GLSL_TYPE_INT:
951 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
952 break;
953 case GLSL_TYPE_FLOAT:
954 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
955 break;
956 default:
957 assert(!"Should not get here.");
958 }
959 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700960 } else if (strcmp(callee, "inversesqrt") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700961 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700962 } else if (strcmp(callee, "length") == 0) {
Kenneth Graunke5489ad02010-07-21 18:26:00 -0700963 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700964 } else if (strcmp(callee, "lessThan") == 0) {
Kenneth Graunke6d897f02010-07-21 18:06:18 -0700965 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
966 for (unsigned c = 0; c < op[0]->type->components(); c++) {
967 switch (op[0]->type->base_type) {
968 case GLSL_TYPE_UINT:
969 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
970 break;
971 case GLSL_TYPE_INT:
972 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
973 break;
974 case GLSL_TYPE_FLOAT:
975 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
976 break;
977 default:
978 assert(!"Should not get here.");
979 }
980 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700981 } else if (strcmp(callee, "lessThanEqual") == 0) {
Kenneth Graunke319f4942010-07-21 18:07:09 -0700982 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
983 for (unsigned c = 0; c < op[0]->type->components(); c++) {
984 switch (op[0]->type->base_type) {
985 case GLSL_TYPE_UINT:
986 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
987 break;
988 case GLSL_TYPE_INT:
989 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
990 break;
991 case GLSL_TYPE_FLOAT:
992 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
993 break;
994 default:
995 assert(!"Should not get here.");
996 }
997 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -0700998 } else if (strcmp(callee, "log") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -0700999 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001000 } else if (strcmp(callee, "log2") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001001 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001002 } else if (strcmp(callee, "matrixCompMult") == 0) {
Kenneth Graunke8fe5f302010-07-21 20:03:55 -07001003 assert(op[0]->type->is_float() && op[1]->type->is_float());
1004 for (unsigned c = 0; c < op[0]->type->components(); c++)
1005 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001006 } else if (strcmp(callee, "max") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001007 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001008 } else if (strcmp(callee, "min") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001009 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001010 } else if (strcmp(callee, "mix") == 0) {
Kenneth Graunke5d255e22010-07-23 12:36:50 -07001011 assert(op[0]->type->is_float() && op[1]->type->is_float());
1012 if (op[2]->type->is_float()) {
1013 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1014 unsigned components = op[0]->type->components();
1015 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
1016 data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
1017 op[1]->value.f[c] * op[2]->value.f[c2];
1018 }
1019 } else {
1020 assert(op[2]->type->is_boolean());
1021 for (unsigned c = 0; c < op[0]->type->components(); c++)
1022 data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
1023 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001024 } else if (strcmp(callee, "mod") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001025 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001026 } else if (strcmp(callee, "normalize") == 0) {
Kenneth Graunke53f306d2010-07-21 20:19:32 -07001027 assert(op[0]->type->is_float());
1028 float length = sqrtf(dot(op[0], op[0]));
1029
1030 if (length == 0)
1031 return ir_constant::zero(mem_ctx, this->type);
1032
1033 for (unsigned c = 0; c < op[0]->type->components(); c++)
1034 data.f[c] = op[0]->value.f[c] / length;
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001035 } else if (strcmp(callee, "not") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001036 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001037 } else if (strcmp(callee, "notEqual") == 0) {
Kenneth Graunke48a69ba2010-07-21 18:05:36 -07001038 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1039 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1040 switch (op[0]->type->base_type) {
1041 case GLSL_TYPE_UINT:
1042 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
1043 break;
1044 case GLSL_TYPE_INT:
1045 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1046 break;
1047 case GLSL_TYPE_FLOAT:
1048 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1049 break;
1050 default:
1051 assert(!"Should not get here.");
1052 }
1053 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001054 } else if (strcmp(callee, "outerProduct") == 0) {
Kenneth Graunke7ddee6a2010-07-23 13:24:09 -07001055 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
1056 const unsigned m = op[0]->type->vector_elements;
1057 const unsigned n = op[1]->type->vector_elements;
1058 for (unsigned j = 0; j < n; j++) {
1059 for (unsigned i = 0; i < m; i++) {
1060 data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
1061 }
1062 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001063 } else if (strcmp(callee, "pow") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001064 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001065 } else if (strcmp(callee, "radians") == 0) {
Kenneth Graunke0afe3492010-07-21 17:58:03 -07001066 assert(op[0]->type->is_float());
1067 for (unsigned c = 0; c < op[0]->type->components(); c++)
1068 data.f[c] = M_PI/180.0 * op[0]->value.f[c];
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001069 } else if (strcmp(callee, "reflect") == 0) {
Kenneth Graunked60b2b02010-07-21 20:24:29 -07001070 assert(op[0]->type->is_float());
1071 float dot_NI = dot(op[1], op[0]);
1072 for (unsigned c = 0; c < op[0]->type->components(); c++)
1073 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001074 } else if (strcmp(callee, "refract") == 0) {
Kenneth Graunke04b36432010-07-21 20:33:42 -07001075 const float eta = op[2]->value.f[0];
1076 const float dot_NI = dot(op[1], op[0]);
1077 const float k = 1.0 - eta * eta * (1.0 - dot_NI * dot_NI);
1078 if (k < 0.0) {
1079 return ir_constant::zero(mem_ctx, this->type);
1080 } else {
1081 for (unsigned c = 0; c < type->components(); c++) {
1082 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
1083 * op[1]->value.f[c];
1084 }
1085 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001086 } else if (strcmp(callee, "sign") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001087 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001088 } else if (strcmp(callee, "sin") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001089 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001090 } else if (strcmp(callee, "sinh") == 0) {
Kenneth Graunke5d551da2010-07-21 17:49:56 -07001091 assert(op[0]->type->is_float());
1092 for (unsigned c = 0; c < op[0]->type->components(); c++)
1093 data.f[c] = sinhf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001094 } else if (strcmp(callee, "smoothstep") == 0) {
Kenneth Graunke546f3a22010-07-21 22:37:50 -07001095 assert(num_parameters == 3);
1096 assert(op[1]->type == op[0]->type);
1097 unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
1098 for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
1099 const float edge0 = op[0]->value.f[e];
1100 const float edge1 = op[1]->value.f[e];
1101 if (edge0 == edge1) {
1102 data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
1103 } else {
1104 const float numerator = op[2]->value.f[c] - edge0;
1105 const float denominator = edge1 - edge0;
1106 const float t = CLAMP(numerator/denominator, 0, 1);
1107 data.f[c] = t * t * (3 - 2 * t);
1108 }
1109 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001110 } else if (strcmp(callee, "sqrt") == 0) {
Kenneth Graunke8b1680a2010-07-21 16:57:53 -07001111 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001112 } else if (strcmp(callee, "step") == 0) {
Kenneth Graunkeff58b7c2010-07-21 21:53:40 -07001113 assert(op[0]->type->is_float() && op[1]->type->is_float());
1114 /* op[0] (edge) may be either a scalar or a vector */
1115 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
1116 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
1117 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0 : 1.0;
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001118 } else if (strcmp(callee, "tan") == 0) {
Kenneth Graunke9c9f8b22010-07-21 17:50:50 -07001119 assert(op[0]->type->is_float());
1120 for (unsigned c = 0; c < op[0]->type->components(); c++)
1121 data.f[c] = tanf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001122 } else if (strcmp(callee, "tanh") == 0) {
Kenneth Graunke20970f72010-07-21 17:51:23 -07001123 assert(op[0]->type->is_float());
1124 for (unsigned c = 0; c < op[0]->type->components(); c++)
1125 data.f[c] = tanhf(op[0]->value.f[c]);
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001126 } else if (strcmp(callee, "transpose") == 0) {
Kenneth Graunkeb09ae5d2010-07-22 15:34:49 -07001127 assert(op[0]->type->is_matrix());
1128 const unsigned n = op[0]->type->vector_elements;
1129 const unsigned m = op[0]->type->matrix_columns;
1130 for (unsigned j = 0; j < m; j++) {
1131 for (unsigned i = 0; i < n; i++) {
1132 data.f[m*i+j] += op[0]->value.f[i+n*j];
1133 }
1134 }
Kenneth Graunkebafd89f2010-07-21 16:55:46 -07001135 } else {
1136 /* Unsupported builtin - some are not allowed in constant expressions. */
1137 return NULL;
1138 }
1139
1140 if (expr != NULL)
1141 return expr->constant_expression_value();
1142
1143 return new(mem_ctx) ir_constant(this->type, &data);
1144}