2 * Copyright © 2010 Intel Corporation
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:
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
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.
25 * \file ir_constant_expression.cpp
26 * Evaluate and process constant valued expressions
28 * In GLSL, constant valued expressions are used in several places. These
29 * must be processed and evaluated very early in the compilation process.
32 * * Initializers for uniforms
33 * * Initializers for \c const variables
37 #include "main/core.h" /* for MAX2, MIN2, CLAMP */
39 #include "ir_visitor.h"
40 #include "glsl_types.h"
43 dot(ir_constant
*op0
, ir_constant
*op1
)
45 assert(op0
->type
->is_float() && op1
->type
->is_float());
48 for (unsigned c
= 0; c
< op0
->type
->components(); c
++)
49 result
+= op0
->value
.f
[c
] * op1
->value
.f
[c
];
55 ir_expression::constant_expression_value()
57 if (this->type
->is_error())
60 ir_constant
*op
[2] = { NULL
, NULL
};
61 ir_constant_data data
;
63 memset(&data
, 0, sizeof(data
));
65 for (unsigned operand
= 0; operand
< this->get_num_operands(); operand
++) {
66 op
[operand
] = this->operands
[operand
]->constant_expression_value();
72 assert(op
[0]->type
->base_type
== op
[1]->type
->base_type
);
74 bool op0_scalar
= op
[0]->type
->is_scalar();
75 bool op1_scalar
= op
[1] != NULL
&& op
[1]->type
->is_scalar();
77 /* When iterating over a vector or matrix's components, we want to increase
78 * the loop counter. However, for scalars, we want to stay at 0.
80 unsigned c0_inc
= op0_scalar
? 0 : 1;
81 unsigned c1_inc
= op1_scalar
? 0 : 1;
83 if (op1_scalar
|| !op
[1]) {
84 components
= op
[0]->type
->components();
86 components
= op
[1]->type
->components();
89 void *ctx
= talloc_parent(this);
91 /* Handle array operations here, rather than below. */
92 if (op
[0]->type
->is_array()) {
93 assert(op
[1] != NULL
&& op
[1]->type
->is_array());
94 switch (this->operation
) {
95 case ir_binop_all_equal
:
96 return new(ctx
) ir_constant(op
[0]->has_value(op
[1]));
97 case ir_binop_any_nequal
:
98 return new(ctx
) ir_constant(!op
[0]->has_value(op
[1]));
105 switch (this->operation
) {
106 case ir_unop_bit_not
:
107 switch (op
[0]->type
->base_type
) {
109 for (unsigned c
= 0; c
< components
; c
++)
110 data
.i
[c
] = ~ op
[0]->value
.i
[c
];
113 for (unsigned c
= 0; c
< components
; c
++)
114 data
.u
[c
] = ~ op
[0]->value
.u
[c
];
121 case ir_unop_logic_not
:
122 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
123 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
124 data
.b
[c
] = !op
[0]->value
.b
[c
];
128 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
129 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
130 data
.i
[c
] = op
[0]->value
.f
[c
];
134 assert(op
[0]->type
->base_type
== GLSL_TYPE_INT
);
135 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
136 data
.f
[c
] = op
[0]->value
.i
[c
];
140 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
);
141 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
142 data
.f
[c
] = op
[0]->value
.u
[c
];
146 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
147 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
148 data
.f
[c
] = op
[0]->value
.b
[c
] ? 1.0 : 0.0;
152 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
153 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
154 data
.b
[c
] = bool(op
[0]->value
.f
[c
]);
158 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
159 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
160 data
.u
[c
] = op
[0]->value
.b
[c
] ? 1 : 0;
164 assert(op
[0]->type
->is_integer());
165 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
166 data
.b
[c
] = bool(op
[0]->value
.u
[c
]);
171 assert(op
[0]->type
->is_boolean());
173 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
174 if (op
[0]->value
.b
[c
])
180 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
181 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
182 data
.f
[c
] = truncf(op
[0]->value
.f
[c
]);
187 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
188 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
189 data
.f
[c
] = ceilf(op
[0]->value
.f
[c
]);
194 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
195 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
196 data
.f
[c
] = floorf(op
[0]->value
.f
[c
]);
201 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
202 switch (this->type
->base_type
) {
209 case GLSL_TYPE_FLOAT
:
210 data
.f
[c
] = op
[0]->value
.f
[c
] - floor(op
[0]->value
.f
[c
]);
219 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
220 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
221 data
.f
[c
] = sinf(op
[0]->value
.f
[c
]);
226 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
227 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
228 data
.f
[c
] = cosf(op
[0]->value
.f
[c
]);
233 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
234 switch (this->type
->base_type
) {
236 data
.u
[c
] = -op
[0]->value
.u
[c
];
239 data
.i
[c
] = -op
[0]->value
.i
[c
];
241 case GLSL_TYPE_FLOAT
:
242 data
.f
[c
] = -op
[0]->value
.f
[c
];
251 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
252 switch (this->type
->base_type
) {
254 data
.u
[c
] = op
[0]->value
.u
[c
];
257 data
.i
[c
] = op
[0]->value
.i
[c
];
259 data
.i
[c
] = -data
.i
[c
];
261 case GLSL_TYPE_FLOAT
:
262 data
.f
[c
] = fabs(op
[0]->value
.f
[c
]);
271 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
272 switch (this->type
->base_type
) {
274 data
.u
[c
] = op
[0]->value
.i
[c
] > 0;
277 data
.i
[c
] = (op
[0]->value
.i
[c
] > 0) - (op
[0]->value
.i
[c
] < 0);
279 case GLSL_TYPE_FLOAT
:
280 data
.f
[c
] = float((op
[0]->value
.f
[c
] > 0)-(op
[0]->value
.f
[c
] < 0));
289 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
290 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
291 switch (this->type
->base_type
) {
293 if (op
[0]->value
.u
[c
] != 0.0)
294 data
.u
[c
] = 1 / op
[0]->value
.u
[c
];
297 if (op
[0]->value
.i
[c
] != 0.0)
298 data
.i
[c
] = 1 / op
[0]->value
.i
[c
];
300 case GLSL_TYPE_FLOAT
:
301 if (op
[0]->value
.f
[c
] != 0.0)
302 data
.f
[c
] = 1.0 / op
[0]->value
.f
[c
];
311 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
312 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
313 data
.f
[c
] = 1.0 / sqrtf(op
[0]->value
.f
[c
]);
318 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
319 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
320 data
.f
[c
] = sqrtf(op
[0]->value
.f
[c
]);
325 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
326 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
327 data
.f
[c
] = expf(op
[0]->value
.f
[c
]);
332 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
333 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
334 data
.f
[c
] = exp2f(op
[0]->value
.f
[c
]);
339 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
340 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
341 data
.f
[c
] = logf(op
[0]->value
.f
[c
]);
346 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
347 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
348 data
.f
[c
] = log2f(op
[0]->value
.f
[c
]);
354 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
355 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
361 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
362 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
363 data
.f
[c
] = powf(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
368 data
.f
[0] = dot(op
[0], op
[1]);
372 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
373 for (unsigned c
= 0, c0
= 0, c1
= 0;
375 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
377 switch (op
[0]->type
->base_type
) {
379 data
.u
[c
] = MIN2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
382 data
.i
[c
] = MIN2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
384 case GLSL_TYPE_FLOAT
:
385 data
.f
[c
] = MIN2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
394 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
395 for (unsigned c
= 0, c0
= 0, c1
= 0;
397 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
399 switch (op
[0]->type
->base_type
) {
401 data
.u
[c
] = MAX2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
404 data
.i
[c
] = MAX2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
406 case GLSL_TYPE_FLOAT
:
407 data
.f
[c
] = MAX2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
416 assert(op
[0]->type
== glsl_type::vec3_type
);
417 assert(op
[1]->type
== glsl_type::vec3_type
);
418 data
.f
[0] = (op
[0]->value
.f
[1] * op
[1]->value
.f
[2] -
419 op
[1]->value
.f
[1] * op
[0]->value
.f
[2]);
420 data
.f
[1] = (op
[0]->value
.f
[2] * op
[1]->value
.f
[0] -
421 op
[1]->value
.f
[2] * op
[0]->value
.f
[0]);
422 data
.f
[2] = (op
[0]->value
.f
[0] * op
[1]->value
.f
[1] -
423 op
[1]->value
.f
[0] * op
[0]->value
.f
[1]);
427 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
428 for (unsigned c
= 0, c0
= 0, c1
= 0;
430 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
432 switch (op
[0]->type
->base_type
) {
434 data
.u
[c
] = op
[0]->value
.u
[c0
] + op
[1]->value
.u
[c1
];
437 data
.i
[c
] = op
[0]->value
.i
[c0
] + op
[1]->value
.i
[c1
];
439 case GLSL_TYPE_FLOAT
:
440 data
.f
[c
] = op
[0]->value
.f
[c0
] + op
[1]->value
.f
[c1
];
449 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
450 for (unsigned c
= 0, c0
= 0, c1
= 0;
452 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
454 switch (op
[0]->type
->base_type
) {
456 data
.u
[c
] = op
[0]->value
.u
[c0
] - op
[1]->value
.u
[c1
];
459 data
.i
[c
] = op
[0]->value
.i
[c0
] - op
[1]->value
.i
[c1
];
461 case GLSL_TYPE_FLOAT
:
462 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
];
471 /* Check for equal types, or unequal types involving scalars */
472 if ((op
[0]->type
== op
[1]->type
&& !op
[0]->type
->is_matrix())
473 || op0_scalar
|| op1_scalar
) {
474 for (unsigned c
= 0, c0
= 0, c1
= 0;
476 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
478 switch (op
[0]->type
->base_type
) {
480 data
.u
[c
] = op
[0]->value
.u
[c0
] * op
[1]->value
.u
[c1
];
483 data
.i
[c
] = op
[0]->value
.i
[c0
] * op
[1]->value
.i
[c1
];
485 case GLSL_TYPE_FLOAT
:
486 data
.f
[c
] = op
[0]->value
.f
[c0
] * op
[1]->value
.f
[c1
];
493 assert(op
[0]->type
->is_matrix() || op
[1]->type
->is_matrix());
495 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
496 * matrix can be a GLSL vector, either N or P can be 1.
498 * For vec*mat, the vector is treated as a row vector. This
499 * means the vector is a 1-row x M-column matrix.
501 * For mat*vec, the vector is treated as a column vector. Since
502 * matrix_columns is 1 for vectors, this just works.
504 const unsigned n
= op
[0]->type
->is_vector()
505 ? 1 : op
[0]->type
->vector_elements
;
506 const unsigned m
= op
[1]->type
->vector_elements
;
507 const unsigned p
= op
[1]->type
->matrix_columns
;
508 for (unsigned j
= 0; j
< p
; j
++) {
509 for (unsigned i
= 0; i
< n
; i
++) {
510 for (unsigned k
= 0; k
< m
; k
++) {
511 data
.f
[i
+n
*j
] += op
[0]->value
.f
[i
+n
*k
]*op
[1]->value
.f
[k
+m
*j
];
519 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
520 for (unsigned c
= 0, c0
= 0, c1
= 0;
522 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
524 switch (op
[0]->type
->base_type
) {
526 data
.u
[c
] = op
[0]->value
.u
[c0
] / op
[1]->value
.u
[c1
];
529 data
.i
[c
] = op
[0]->value
.i
[c0
] / op
[1]->value
.i
[c1
];
531 case GLSL_TYPE_FLOAT
:
532 data
.f
[c
] = op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
];
541 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
542 for (unsigned c
= 0, c0
= 0, c1
= 0;
544 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
546 switch (op
[0]->type
->base_type
) {
548 data
.u
[c
] = op
[0]->value
.u
[c0
] % op
[1]->value
.u
[c1
];
551 data
.i
[c
] = op
[0]->value
.i
[c0
] % op
[1]->value
.i
[c1
];
553 case GLSL_TYPE_FLOAT
:
554 /* We don't use fmod because it rounds toward zero; GLSL specifies
557 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
]
558 * floorf(op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
]);
567 case ir_binop_logic_and
:
568 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
569 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
570 data
.b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
572 case ir_binop_logic_xor
:
573 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
574 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
575 data
.b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
577 case ir_binop_logic_or
:
578 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
579 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
580 data
.b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
584 switch (op
[0]->type
->base_type
) {
586 data
.b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
589 data
.b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
591 case GLSL_TYPE_FLOAT
:
592 data
.b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
598 case ir_binop_greater
:
599 switch (op
[0]->type
->base_type
) {
601 data
.b
[0] = op
[0]->value
.u
[0] > op
[1]->value
.u
[0];
604 data
.b
[0] = op
[0]->value
.i
[0] > op
[1]->value
.i
[0];
606 case GLSL_TYPE_FLOAT
:
607 data
.b
[0] = op
[0]->value
.f
[0] > op
[1]->value
.f
[0];
613 case ir_binop_lequal
:
614 switch (op
[0]->type
->base_type
) {
616 data
.b
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
619 data
.b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
621 case GLSL_TYPE_FLOAT
:
622 data
.b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
628 case ir_binop_gequal
:
629 switch (op
[0]->type
->base_type
) {
631 data
.b
[0] = op
[0]->value
.u
[0] >= op
[1]->value
.u
[0];
634 data
.b
[0] = op
[0]->value
.i
[0] >= op
[1]->value
.i
[0];
636 case GLSL_TYPE_FLOAT
:
637 data
.b
[0] = op
[0]->value
.f
[0] >= op
[1]->value
.f
[0];
644 assert(op
[0]->type
== op
[1]->type
);
645 for (unsigned c
= 0; c
< components
; c
++) {
646 switch (op
[0]->type
->base_type
) {
648 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
651 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
653 case GLSL_TYPE_FLOAT
:
654 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
661 case ir_binop_nequal
:
662 assert(op
[0]->type
!= op
[1]->type
);
663 for (unsigned c
= 0; c
< components
; c
++) {
664 switch (op
[0]->type
->base_type
) {
666 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
669 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
671 case GLSL_TYPE_FLOAT
:
672 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
679 case ir_binop_all_equal
:
680 data
.b
[0] = op
[0]->has_value(op
[1]);
682 case ir_binop_any_nequal
:
683 data
.b
[0] = !op
[0]->has_value(op
[1]);
686 case ir_binop_lshift
:
687 for (unsigned c
= 0, c0
= 0, c1
= 0;
689 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
691 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
692 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
693 data
.i
[c
] = op
[0]->value
.i
[c0
] << op
[1]->value
.i
[c1
];
695 } else if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
696 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
697 data
.i
[c
] = op
[0]->value
.i
[c0
] << op
[1]->value
.u
[c1
];
699 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
700 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
701 data
.u
[c
] = op
[0]->value
.u
[c0
] << op
[1]->value
.i
[c1
];
703 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
704 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
705 data
.u
[c
] = op
[0]->value
.u
[c0
] << op
[1]->value
.u
[c1
];
710 case ir_binop_rshift
:
711 for (unsigned c
= 0, c0
= 0, c1
= 0;
713 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
715 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
716 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
717 data
.i
[c
] = op
[0]->value
.i
[c0
] >> op
[1]->value
.i
[c1
];
719 } else if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
720 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
721 data
.i
[c
] = op
[0]->value
.i
[c0
] >> op
[1]->value
.u
[c1
];
723 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
724 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
725 data
.u
[c
] = op
[0]->value
.u
[c0
] >> op
[1]->value
.i
[c1
];
727 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
728 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
729 data
.u
[c
] = op
[0]->value
.u
[c0
] >> op
[1]->value
.u
[c1
];
734 case ir_binop_bit_and
:
735 for (unsigned c
= 0, c0
= 0, c1
= 0;
737 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
739 switch (op
[0]->type
->base_type
) {
741 data
.i
[c
] = op
[0]->value
.i
[c0
] & op
[1]->value
.i
[c1
];
744 data
.u
[c
] = op
[0]->value
.u
[c0
] & op
[1]->value
.u
[c1
];
752 case ir_binop_bit_or
:
753 for (unsigned c
= 0, c0
= 0, c1
= 0;
755 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
757 switch (op
[0]->type
->base_type
) {
759 data
.i
[c
] = op
[0]->value
.i
[c0
] | op
[1]->value
.i
[c1
];
762 data
.u
[c
] = op
[0]->value
.u
[c0
] | op
[1]->value
.u
[c1
];
770 case ir_binop_bit_xor
:
771 for (unsigned c
= 0, c0
= 0, c1
= 0;
773 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
775 switch (op
[0]->type
->base_type
) {
777 data
.i
[c
] = op
[0]->value
.i
[c0
] ^ op
[1]->value
.i
[c1
];
780 data
.u
[c
] = op
[0]->value
.u
[c0
] ^ op
[1]->value
.u
[c1
];
789 /* FINISHME: Should handle all expression types. */
793 return new(ctx
) ir_constant(this->type
, &data
);
798 ir_texture::constant_expression_value()
800 /* texture lookups aren't constant expressions */
806 ir_swizzle::constant_expression_value()
808 ir_constant
*v
= this->val
->constant_expression_value();
811 ir_constant_data data
= { { 0 } };
813 const unsigned swiz_idx
[4] = {
814 this->mask
.x
, this->mask
.y
, this->mask
.z
, this->mask
.w
817 for (unsigned i
= 0; i
< this->mask
.num_components
; i
++) {
818 switch (v
->type
->base_type
) {
820 case GLSL_TYPE_INT
: data
.u
[i
] = v
->value
.u
[swiz_idx
[i
]]; break;
821 case GLSL_TYPE_FLOAT
: data
.f
[i
] = v
->value
.f
[swiz_idx
[i
]]; break;
822 case GLSL_TYPE_BOOL
: data
.b
[i
] = v
->value
.b
[swiz_idx
[i
]]; break;
823 default: assert(!"Should not get here."); break;
827 void *ctx
= talloc_parent(this);
828 return new(ctx
) ir_constant(this->type
, &data
);
835 ir_dereference_variable::constant_expression_value()
837 /* This may occur during compile and var->type is glsl_type::error_type */
841 /* The constant_value of a uniform variable is its initializer,
842 * not the lifetime constant value of the uniform.
844 if (var
->mode
== ir_var_uniform
)
847 if (!var
->constant_value
)
850 return var
->constant_value
->clone(talloc_parent(var
), NULL
);
855 ir_dereference_array::constant_expression_value()
857 ir_constant
*array
= this->array
->constant_expression_value();
858 ir_constant
*idx
= this->array_index
->constant_expression_value();
860 if ((array
!= NULL
) && (idx
!= NULL
)) {
861 void *ctx
= talloc_parent(this);
862 if (array
->type
->is_matrix()) {
863 /* Array access of a matrix results in a vector.
865 const unsigned column
= idx
->value
.u
[0];
867 const glsl_type
*const column_type
= array
->type
->column_type();
869 /* Offset in the constant matrix to the first element of the column
872 const unsigned mat_idx
= column
* column_type
->vector_elements
;
874 ir_constant_data data
= { { 0 } };
876 switch (column_type
->base_type
) {
879 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
880 data
.u
[i
] = array
->value
.u
[mat_idx
+ i
];
884 case GLSL_TYPE_FLOAT
:
885 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
886 data
.f
[i
] = array
->value
.f
[mat_idx
+ i
];
891 assert(!"Should not get here.");
895 return new(ctx
) ir_constant(column_type
, &data
);
896 } else if (array
->type
->is_vector()) {
897 const unsigned component
= idx
->value
.u
[0];
899 return new(ctx
) ir_constant(array
, component
);
901 const unsigned index
= idx
->value
.u
[0];
902 return array
->get_array_element(index
)->clone(ctx
, NULL
);
910 ir_dereference_record::constant_expression_value()
912 ir_constant
*v
= this->record
->constant_expression_value();
914 return (v
!= NULL
) ? v
->get_record_field(this->field
) : NULL
;
919 ir_assignment::constant_expression_value()
921 /* FINISHME: Handle CEs involving assignment (return RHS) */
927 ir_constant::constant_expression_value()
934 ir_call::constant_expression_value()
936 if (this->type
== glsl_type::error_type
)
939 /* From the GLSL 1.20 spec, page 23:
940 * "Function calls to user-defined functions (non-built-in functions)
941 * cannot be used to form constant expressions."
943 if (!this->callee
->is_builtin
)
946 unsigned num_parameters
= 0;
948 /* Check if all parameters are constant */
950 foreach_list(n
, &this->actual_parameters
) {
951 ir_constant
*constant
= ((ir_rvalue
*) n
)->constant_expression_value();
952 if (constant
== NULL
)
955 op
[num_parameters
] = constant
;
957 assert(num_parameters
< 3);
961 /* Individual cases below can either:
962 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
963 * - Fill "data" with appopriate constant data
964 * - Return an ir_constant directly.
966 void *mem_ctx
= talloc_parent(this);
967 ir_expression
*expr
= NULL
;
969 ir_constant_data data
;
970 memset(&data
, 0, sizeof(data
));
972 const char *callee
= this->callee_name();
973 if (strcmp(callee
, "abs") == 0) {
974 expr
= new(mem_ctx
) ir_expression(ir_unop_abs
, type
, op
[0], NULL
);
975 } else if (strcmp(callee
, "all") == 0) {
976 assert(op
[0]->type
->is_boolean());
977 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
978 if (!op
[0]->value
.b
[c
])
979 return new(mem_ctx
) ir_constant(false);
981 return new(mem_ctx
) ir_constant(true);
982 } else if (strcmp(callee
, "any") == 0) {
983 assert(op
[0]->type
->is_boolean());
984 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
985 if (op
[0]->value
.b
[c
])
986 return new(mem_ctx
) ir_constant(true);
988 return new(mem_ctx
) ir_constant(false);
989 } else if (strcmp(callee
, "acos") == 0) {
990 assert(op
[0]->type
->is_float());
991 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
992 data
.f
[c
] = acosf(op
[0]->value
.f
[c
]);
993 } else if (strcmp(callee
, "asin") == 0) {
994 assert(op
[0]->type
->is_float());
995 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
996 data
.f
[c
] = asinf(op
[0]->value
.f
[c
]);
997 } else if (strcmp(callee
, "atan") == 0) {
998 assert(op
[0]->type
->is_float());
999 if (num_parameters
== 2) {
1000 assert(op
[1]->type
->is_float());
1001 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1002 data
.f
[c
] = atan2f(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
1004 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1005 data
.f
[c
] = atanf(op
[0]->value
.f
[c
]);
1007 } else if (strcmp(callee
, "dFdx") == 0 || strcmp(callee
, "dFdy") == 0) {
1008 return ir_constant::zero(mem_ctx
, this->type
);
1009 } else if (strcmp(callee
, "ceil") == 0) {
1010 expr
= new(mem_ctx
) ir_expression(ir_unop_ceil
, type
, op
[0], NULL
);
1011 } else if (strcmp(callee
, "clamp") == 0) {
1012 assert(num_parameters
== 3);
1013 unsigned c1_inc
= op
[1]->type
->is_scalar() ? 0 : 1;
1014 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1015 for (unsigned c
= 0, c1
= 0, c2
= 0;
1016 c
< op
[0]->type
->components();
1017 c1
+= c1_inc
, c2
+= c2_inc
, c
++) {
1019 switch (op
[0]->type
->base_type
) {
1020 case GLSL_TYPE_UINT
:
1021 data
.u
[c
] = CLAMP(op
[0]->value
.u
[c
], op
[1]->value
.u
[c1
],
1022 op
[2]->value
.u
[c2
]);
1025 data
.i
[c
] = CLAMP(op
[0]->value
.i
[c
], op
[1]->value
.i
[c1
],
1026 op
[2]->value
.i
[c2
]);
1028 case GLSL_TYPE_FLOAT
:
1029 data
.f
[c
] = CLAMP(op
[0]->value
.f
[c
], op
[1]->value
.f
[c1
],
1030 op
[2]->value
.f
[c2
]);
1033 assert(!"Should not get here.");
1036 } else if (strcmp(callee
, "cos") == 0) {
1037 expr
= new(mem_ctx
) ir_expression(ir_unop_cos
, type
, op
[0], NULL
);
1038 } else if (strcmp(callee
, "cosh") == 0) {
1039 assert(op
[0]->type
->is_float());
1040 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1041 data
.f
[c
] = coshf(op
[0]->value
.f
[c
]);
1042 } else if (strcmp(callee
, "cross") == 0) {
1043 expr
= new(mem_ctx
) ir_expression(ir_binop_cross
, type
, op
[0], op
[1]);
1044 } else if (strcmp(callee
, "degrees") == 0) {
1045 assert(op
[0]->type
->is_float());
1046 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1047 data
.f
[c
] = 180.0/M_PI
* op
[0]->value
.f
[c
];
1048 } else if (strcmp(callee
, "distance") == 0) {
1049 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1050 float length_squared
= 0.0;
1051 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1052 float t
= op
[0]->value
.f
[c
] - op
[1]->value
.f
[c
];
1053 length_squared
+= t
* t
;
1055 return new(mem_ctx
) ir_constant(sqrtf(length_squared
));
1056 } else if (strcmp(callee
, "dot") == 0) {
1057 return new(mem_ctx
) ir_constant(dot(op
[0], op
[1]));
1058 } else if (strcmp(callee
, "equal") == 0) {
1059 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1060 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1061 switch (op
[0]->type
->base_type
) {
1062 case GLSL_TYPE_UINT
:
1063 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
1066 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
1068 case GLSL_TYPE_FLOAT
:
1069 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
1071 case GLSL_TYPE_BOOL
:
1072 data
.b
[c
] = op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
1075 assert(!"Should not get here.");
1078 } else if (strcmp(callee
, "exp") == 0) {
1079 expr
= new(mem_ctx
) ir_expression(ir_unop_exp
, type
, op
[0], NULL
);
1080 } else if (strcmp(callee
, "exp2") == 0) {
1081 expr
= new(mem_ctx
) ir_expression(ir_unop_exp2
, type
, op
[0], NULL
);
1082 } else if (strcmp(callee
, "faceforward") == 0) {
1083 if (dot(op
[2], op
[1]) < 0)
1085 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1086 data
.f
[c
] = -op
[0]->value
.f
[c
];
1087 } else if (strcmp(callee
, "floor") == 0) {
1088 expr
= new(mem_ctx
) ir_expression(ir_unop_floor
, type
, op
[0], NULL
);
1089 } else if (strcmp(callee
, "fract") == 0) {
1090 expr
= new(mem_ctx
) ir_expression(ir_unop_fract
, type
, op
[0], NULL
);
1091 } else if (strcmp(callee
, "fwidth") == 0) {
1092 return ir_constant::zero(mem_ctx
, this->type
);
1093 } else if (strcmp(callee
, "greaterThan") == 0) {
1094 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1095 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1096 switch (op
[0]->type
->base_type
) {
1097 case GLSL_TYPE_UINT
:
1098 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
1101 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
1103 case GLSL_TYPE_FLOAT
:
1104 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
1107 assert(!"Should not get here.");
1110 } else if (strcmp(callee
, "greaterThanEqual") == 0) {
1111 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1112 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1113 switch (op
[0]->type
->base_type
) {
1114 case GLSL_TYPE_UINT
:
1115 data
.b
[c
] = op
[0]->value
.u
[c
] >= op
[1]->value
.u
[c
];
1118 data
.b
[c
] = op
[0]->value
.i
[c
] >= op
[1]->value
.i
[c
];
1120 case GLSL_TYPE_FLOAT
:
1121 data
.b
[c
] = op
[0]->value
.f
[c
] >= op
[1]->value
.f
[c
];
1124 assert(!"Should not get here.");
1127 } else if (strcmp(callee
, "inversesqrt") == 0) {
1128 expr
= new(mem_ctx
) ir_expression(ir_unop_rsq
, type
, op
[0], NULL
);
1129 } else if (strcmp(callee
, "length") == 0) {
1130 return new(mem_ctx
) ir_constant(sqrtf(dot(op
[0], op
[0])));
1131 } else if (strcmp(callee
, "lessThan") == 0) {
1132 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1133 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1134 switch (op
[0]->type
->base_type
) {
1135 case GLSL_TYPE_UINT
:
1136 data
.b
[c
] = op
[0]->value
.u
[c
] < op
[1]->value
.u
[c
];
1139 data
.b
[c
] = op
[0]->value
.i
[c
] < op
[1]->value
.i
[c
];
1141 case GLSL_TYPE_FLOAT
:
1142 data
.b
[c
] = op
[0]->value
.f
[c
] < op
[1]->value
.f
[c
];
1145 assert(!"Should not get here.");
1148 } else if (strcmp(callee
, "lessThanEqual") == 0) {
1149 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1150 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1151 switch (op
[0]->type
->base_type
) {
1152 case GLSL_TYPE_UINT
:
1153 data
.b
[c
] = op
[0]->value
.u
[c
] <= op
[1]->value
.u
[c
];
1156 data
.b
[c
] = op
[0]->value
.i
[c
] <= op
[1]->value
.i
[c
];
1158 case GLSL_TYPE_FLOAT
:
1159 data
.b
[c
] = op
[0]->value
.f
[c
] <= op
[1]->value
.f
[c
];
1162 assert(!"Should not get here.");
1165 } else if (strcmp(callee
, "log") == 0) {
1166 expr
= new(mem_ctx
) ir_expression(ir_unop_log
, type
, op
[0], NULL
);
1167 } else if (strcmp(callee
, "log2") == 0) {
1168 expr
= new(mem_ctx
) ir_expression(ir_unop_log2
, type
, op
[0], NULL
);
1169 } else if (strcmp(callee
, "matrixCompMult") == 0) {
1170 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1171 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1172 data
.f
[c
] = op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
1173 } else if (strcmp(callee
, "max") == 0) {
1174 expr
= new(mem_ctx
) ir_expression(ir_binop_max
, type
, op
[0], op
[1]);
1175 } else if (strcmp(callee
, "min") == 0) {
1176 expr
= new(mem_ctx
) ir_expression(ir_binop_min
, type
, op
[0], op
[1]);
1177 } else if (strcmp(callee
, "mix") == 0) {
1178 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1179 if (op
[2]->type
->is_float()) {
1180 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1181 unsigned components
= op
[0]->type
->components();
1182 for (unsigned c
= 0, c2
= 0; c
< components
; c2
+= c2_inc
, c
++) {
1183 data
.f
[c
] = op
[0]->value
.f
[c
] * (1 - op
[2]->value
.f
[c2
]) +
1184 op
[1]->value
.f
[c
] * op
[2]->value
.f
[c2
];
1187 assert(op
[2]->type
->is_boolean());
1188 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1189 data
.f
[c
] = op
[op
[2]->value
.b
[c
] ? 1 : 0]->value
.f
[c
];
1191 } else if (strcmp(callee
, "mod") == 0) {
1192 expr
= new(mem_ctx
) ir_expression(ir_binop_mod
, type
, op
[0], op
[1]);
1193 } else if (strcmp(callee
, "normalize") == 0) {
1194 assert(op
[0]->type
->is_float());
1195 float length
= sqrtf(dot(op
[0], op
[0]));
1198 return ir_constant::zero(mem_ctx
, this->type
);
1200 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1201 data
.f
[c
] = op
[0]->value
.f
[c
] / length
;
1202 } else if (strcmp(callee
, "not") == 0) {
1203 expr
= new(mem_ctx
) ir_expression(ir_unop_logic_not
, type
, op
[0], NULL
);
1204 } else if (strcmp(callee
, "notEqual") == 0) {
1205 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1206 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1207 switch (op
[0]->type
->base_type
) {
1208 case GLSL_TYPE_UINT
:
1209 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
1212 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
1214 case GLSL_TYPE_FLOAT
:
1215 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
1217 case GLSL_TYPE_BOOL
:
1218 data
.b
[c
] = op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
1221 assert(!"Should not get here.");
1224 } else if (strcmp(callee
, "outerProduct") == 0) {
1225 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
1226 const unsigned m
= op
[0]->type
->vector_elements
;
1227 const unsigned n
= op
[1]->type
->vector_elements
;
1228 for (unsigned j
= 0; j
< n
; j
++) {
1229 for (unsigned i
= 0; i
< m
; i
++) {
1230 data
.f
[i
+m
*j
] = op
[0]->value
.f
[i
] * op
[1]->value
.f
[j
];
1233 } else if (strcmp(callee
, "pow") == 0) {
1234 expr
= new(mem_ctx
) ir_expression(ir_binop_pow
, type
, op
[0], op
[1]);
1235 } else if (strcmp(callee
, "radians") == 0) {
1236 assert(op
[0]->type
->is_float());
1237 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1238 data
.f
[c
] = M_PI
/180.0 * op
[0]->value
.f
[c
];
1239 } else if (strcmp(callee
, "reflect") == 0) {
1240 assert(op
[0]->type
->is_float());
1241 float dot_NI
= dot(op
[1], op
[0]);
1242 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1243 data
.f
[c
] = op
[0]->value
.f
[c
] - 2 * dot_NI
* op
[1]->value
.f
[c
];
1244 } else if (strcmp(callee
, "refract") == 0) {
1245 const float eta
= op
[2]->value
.f
[0];
1246 const float dot_NI
= dot(op
[1], op
[0]);
1247 const float k
= 1.0 - eta
* eta
* (1.0 - dot_NI
* dot_NI
);
1249 return ir_constant::zero(mem_ctx
, this->type
);
1251 for (unsigned c
= 0; c
< type
->components(); c
++) {
1252 data
.f
[c
] = eta
* op
[0]->value
.f
[c
] - (eta
* dot_NI
+ sqrtf(k
))
1253 * op
[1]->value
.f
[c
];
1256 } else if (strcmp(callee
, "sign") == 0) {
1257 expr
= new(mem_ctx
) ir_expression(ir_unop_sign
, type
, op
[0], NULL
);
1258 } else if (strcmp(callee
, "sin") == 0) {
1259 expr
= new(mem_ctx
) ir_expression(ir_unop_sin
, type
, op
[0], NULL
);
1260 } else if (strcmp(callee
, "sinh") == 0) {
1261 assert(op
[0]->type
->is_float());
1262 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1263 data
.f
[c
] = sinhf(op
[0]->value
.f
[c
]);
1264 } else if (strcmp(callee
, "smoothstep") == 0) {
1265 assert(num_parameters
== 3);
1266 assert(op
[1]->type
== op
[0]->type
);
1267 unsigned edge_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1268 for (unsigned c
= 0, e
= 0; c
< type
->components(); e
+= edge_inc
, c
++) {
1269 const float edge0
= op
[0]->value
.f
[e
];
1270 const float edge1
= op
[1]->value
.f
[e
];
1271 if (edge0
== edge1
) {
1272 data
.f
[c
] = 0.0; /* Avoid a crash - results are undefined anyway */
1274 const float numerator
= op
[2]->value
.f
[c
] - edge0
;
1275 const float denominator
= edge1
- edge0
;
1276 const float t
= CLAMP(numerator
/denominator
, 0, 1);
1277 data
.f
[c
] = t
* t
* (3 - 2 * t
);
1280 } else if (strcmp(callee
, "sqrt") == 0) {
1281 expr
= new(mem_ctx
) ir_expression(ir_unop_sqrt
, type
, op
[0], NULL
);
1282 } else if (strcmp(callee
, "step") == 0) {
1283 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1284 /* op[0] (edge) may be either a scalar or a vector */
1285 const unsigned c0_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1286 for (unsigned c
= 0, c0
= 0; c
< type
->components(); c0
+= c0_inc
, c
++)
1287 data
.f
[c
] = (op
[1]->value
.f
[c
] < op
[0]->value
.f
[c0
]) ? 0.0 : 1.0;
1288 } else if (strcmp(callee
, "tan") == 0) {
1289 assert(op
[0]->type
->is_float());
1290 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1291 data
.f
[c
] = tanf(op
[0]->value
.f
[c
]);
1292 } else if (strcmp(callee
, "tanh") == 0) {
1293 assert(op
[0]->type
->is_float());
1294 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1295 data
.f
[c
] = tanhf(op
[0]->value
.f
[c
]);
1296 } else if (strcmp(callee
, "transpose") == 0) {
1297 assert(op
[0]->type
->is_matrix());
1298 const unsigned n
= op
[0]->type
->vector_elements
;
1299 const unsigned m
= op
[0]->type
->matrix_columns
;
1300 for (unsigned j
= 0; j
< m
; j
++) {
1301 for (unsigned i
= 0; i
< n
; i
++) {
1302 data
.f
[m
*i
+j
] += op
[0]->value
.f
[i
+n
*j
];
1306 /* Unsupported builtin - some are not allowed in constant expressions. */
1311 return expr
->constant_expression_value();
1313 return new(mem_ctx
) ir_constant(this->type
, &data
);