Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 1 | /* |
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 | |||
36 | #include |
||
37 | #include "main/core.h" /* for MAX2, MIN2, CLAMP */ |
||
38 | #include "util/rounding.h" /* for _mesa_roundeven */ |
||
39 | #include "ir.h" |
||
40 | #include "glsl_types.h" |
||
41 | #include "program/hash_table.h" |
||
42 | |||
43 | #if defined(_MSC_VER) && (_MSC_VER < 1800) |
||
44 | static int isnormal(double x) |
||
45 | { |
||
46 | return _fpclass(x) == _FPCLASS_NN || _fpclass(x) == _FPCLASS_PN; |
||
47 | } |
||
48 | #elif defined(__SUNPRO_CC) && !defined(isnormal) |
||
49 | #include |
||
50 | static int isnormal(double x) |
||
51 | { |
||
52 | return fpclass(x) == FP_NORMAL; |
||
53 | } |
||
54 | #endif |
||
55 | |||
56 | #if defined(_MSC_VER) |
||
57 | static double copysign(double x, double y) |
||
58 | { |
||
59 | return _copysign(x, y); |
||
60 | } |
||
61 | #endif |
||
62 | |||
63 | static float |
||
64 | dot_f(ir_constant *op0, ir_constant *op1) |
||
65 | { |
||
66 | assert(op0->type->is_float() && op1->type->is_float()); |
||
67 | |||
68 | float result = 0; |
||
69 | for (unsigned c = 0; c < op0->type->components(); c++) |
||
70 | result += op0->value.f[c] * op1->value.f[c]; |
||
71 | |||
72 | return result; |
||
73 | } |
||
74 | |||
75 | static double |
||
76 | dot_d(ir_constant *op0, ir_constant *op1) |
||
77 | { |
||
78 | assert(op0->type->is_double() && op1->type->is_double()); |
||
79 | |||
80 | double result = 0; |
||
81 | for (unsigned c = 0; c < op0->type->components(); c++) |
||
82 | result += op0->value.d[c] * op1->value.d[c]; |
||
83 | |||
84 | return result; |
||
85 | } |
||
86 | |||
87 | /* This method is the only one supported by gcc. Unions in particular |
||
88 | * are iffy, and read-through-converted-pointer is killed by strict |
||
89 | * aliasing. OTOH, the compiler sees through the memcpy, so the |
||
90 | * resulting asm is reasonable. |
||
91 | */ |
||
92 | static float |
||
93 | bitcast_u2f(unsigned int u) |
||
94 | { |
||
95 | assert(sizeof(float) == sizeof(unsigned int)); |
||
96 | float f; |
||
97 | memcpy(&f, &u, sizeof(f)); |
||
98 | return f; |
||
99 | } |
||
100 | |||
101 | static unsigned int |
||
102 | bitcast_f2u(float f) |
||
103 | { |
||
104 | assert(sizeof(float) == sizeof(unsigned int)); |
||
105 | unsigned int u; |
||
106 | memcpy(&u, &f, sizeof(f)); |
||
107 | return u; |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * Evaluate one component of a floating-point 4x8 unpacking function. |
||
112 | */ |
||
113 | typedef uint8_t |
||
114 | (*pack_1x8_func_t)(float); |
||
115 | |||
116 | /** |
||
117 | * Evaluate one component of a floating-point 2x16 unpacking function. |
||
118 | */ |
||
119 | typedef uint16_t |
||
120 | (*pack_1x16_func_t)(float); |
||
121 | |||
122 | /** |
||
123 | * Evaluate one component of a floating-point 4x8 unpacking function. |
||
124 | */ |
||
125 | typedef float |
||
126 | (*unpack_1x8_func_t)(uint8_t); |
||
127 | |||
128 | /** |
||
129 | * Evaluate one component of a floating-point 2x16 unpacking function. |
||
130 | */ |
||
131 | typedef float |
||
132 | (*unpack_1x16_func_t)(uint16_t); |
||
133 | |||
134 | /** |
||
135 | * Evaluate a 2x16 floating-point packing function. |
||
136 | */ |
||
137 | static uint32_t |
||
138 | pack_2x16(pack_1x16_func_t pack_1x16, |
||
139 | float x, float y) |
||
140 | { |
||
141 | /* From section 8.4 of the GLSL ES 3.00 spec: |
||
142 | * |
||
143 | * packSnorm2x16 |
||
144 | * ------------- |
||
145 | * The first component of the vector will be written to the least |
||
146 | * significant bits of the output; the last component will be written to |
||
147 | * the most significant bits. |
||
148 | * |
||
149 | * The specifications for the other packing functions contain similar |
||
150 | * language. |
||
151 | */ |
||
152 | uint32_t u = 0; |
||
153 | u |= ((uint32_t) pack_1x16(x) << 0); |
||
154 | u |= ((uint32_t) pack_1x16(y) << 16); |
||
155 | return u; |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * Evaluate a 4x8 floating-point packing function. |
||
160 | */ |
||
161 | static uint32_t |
||
162 | pack_4x8(pack_1x8_func_t pack_1x8, |
||
163 | float x, float y, float z, float w) |
||
164 | { |
||
165 | /* From section 8.4 of the GLSL 4.30 spec: |
||
166 | * |
||
167 | * packSnorm4x8 |
||
168 | * ------------ |
||
169 | * The first component of the vector will be written to the least |
||
170 | * significant bits of the output; the last component will be written to |
||
171 | * the most significant bits. |
||
172 | * |
||
173 | * The specifications for the other packing functions contain similar |
||
174 | * language. |
||
175 | */ |
||
176 | uint32_t u = 0; |
||
177 | u |= ((uint32_t) pack_1x8(x) << 0); |
||
178 | u |= ((uint32_t) pack_1x8(y) << 8); |
||
179 | u |= ((uint32_t) pack_1x8(z) << 16); |
||
180 | u |= ((uint32_t) pack_1x8(w) << 24); |
||
181 | return u; |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * Evaluate a 2x16 floating-point unpacking function. |
||
186 | */ |
||
187 | static void |
||
188 | unpack_2x16(unpack_1x16_func_t unpack_1x16, |
||
189 | uint32_t u, |
||
190 | float *x, float *y) |
||
191 | { |
||
192 | /* From section 8.4 of the GLSL ES 3.00 spec: |
||
193 | * |
||
194 | * unpackSnorm2x16 |
||
195 | * --------------- |
||
196 | * The first component of the returned vector will be extracted from |
||
197 | * the least significant bits of the input; the last component will be |
||
198 | * extracted from the most significant bits. |
||
199 | * |
||
200 | * The specifications for the other unpacking functions contain similar |
||
201 | * language. |
||
202 | */ |
||
203 | *x = unpack_1x16((uint16_t) (u & 0xffff)); |
||
204 | *y = unpack_1x16((uint16_t) (u >> 16)); |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * Evaluate a 4x8 floating-point unpacking function. |
||
209 | */ |
||
210 | static void |
||
211 | unpack_4x8(unpack_1x8_func_t unpack_1x8, uint32_t u, |
||
212 | float *x, float *y, float *z, float *w) |
||
213 | { |
||
214 | /* From section 8.4 of the GLSL 4.30 spec: |
||
215 | * |
||
216 | * unpackSnorm4x8 |
||
217 | * -------------- |
||
218 | * The first component of the returned vector will be extracted from |
||
219 | * the least significant bits of the input; the last component will be |
||
220 | * extracted from the most significant bits. |
||
221 | * |
||
222 | * The specifications for the other unpacking functions contain similar |
||
223 | * language. |
||
224 | */ |
||
225 | *x = unpack_1x8((uint8_t) (u & 0xff)); |
||
226 | *y = unpack_1x8((uint8_t) (u >> 8)); |
||
227 | *z = unpack_1x8((uint8_t) (u >> 16)); |
||
228 | *w = unpack_1x8((uint8_t) (u >> 24)); |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * Evaluate one component of packSnorm4x8. |
||
233 | */ |
||
234 | static uint8_t |
||
235 | pack_snorm_1x8(float x) |
||
236 | { |
||
237 | /* From section 8.4 of the GLSL 4.30 spec: |
||
238 | * |
||
239 | * packSnorm4x8 |
||
240 | * ------------ |
||
241 | * The conversion for component c of v to fixed point is done as |
||
242 | * follows: |
||
243 | * |
||
244 | * packSnorm4x8: round(clamp(c, -1, +1) * 127.0) |
||
245 | * |
||
246 | * We must first cast the float to an int, because casting a negative |
||
247 | * float to a uint is undefined. |
||
248 | */ |
||
249 | return (uint8_t) (int) |
||
250 | _mesa_roundevenf(CLAMP(x, -1.0f, +1.0f) * 127.0f); |
||
251 | } |
||
252 | |||
253 | /** |
||
254 | * Evaluate one component of packSnorm2x16. |
||
255 | */ |
||
256 | static uint16_t |
||
257 | pack_snorm_1x16(float x) |
||
258 | { |
||
259 | /* From section 8.4 of the GLSL ES 3.00 spec: |
||
260 | * |
||
261 | * packSnorm2x16 |
||
262 | * ------------- |
||
263 | * The conversion for component c of v to fixed point is done as |
||
264 | * follows: |
||
265 | * |
||
266 | * packSnorm2x16: round(clamp(c, -1, +1) * 32767.0) |
||
267 | * |
||
268 | * We must first cast the float to an int, because casting a negative |
||
269 | * float to a uint is undefined. |
||
270 | */ |
||
271 | return (uint16_t) (int) |
||
272 | _mesa_roundevenf(CLAMP(x, -1.0f, +1.0f) * 32767.0f); |
||
273 | } |
||
274 | |||
275 | /** |
||
276 | * Evaluate one component of unpackSnorm4x8. |
||
277 | */ |
||
278 | static float |
||
279 | unpack_snorm_1x8(uint8_t u) |
||
280 | { |
||
281 | /* From section 8.4 of the GLSL 4.30 spec: |
||
282 | * |
||
283 | * unpackSnorm4x8 |
||
284 | * -------------- |
||
285 | * The conversion for unpacked fixed-point value f to floating point is |
||
286 | * done as follows: |
||
287 | * |
||
288 | * unpackSnorm4x8: clamp(f / 127.0, -1, +1) |
||
289 | */ |
||
290 | return CLAMP((int8_t) u / 127.0f, -1.0f, +1.0f); |
||
291 | } |
||
292 | |||
293 | /** |
||
294 | * Evaluate one component of unpackSnorm2x16. |
||
295 | */ |
||
296 | static float |
||
297 | unpack_snorm_1x16(uint16_t u) |
||
298 | { |
||
299 | /* From section 8.4 of the GLSL ES 3.00 spec: |
||
300 | * |
||
301 | * unpackSnorm2x16 |
||
302 | * --------------- |
||
303 | * The conversion for unpacked fixed-point value f to floating point is |
||
304 | * done as follows: |
||
305 | * |
||
306 | * unpackSnorm2x16: clamp(f / 32767.0, -1, +1) |
||
307 | */ |
||
308 | return CLAMP((int16_t) u / 32767.0f, -1.0f, +1.0f); |
||
309 | } |
||
310 | |||
311 | /** |
||
312 | * Evaluate one component packUnorm4x8. |
||
313 | */ |
||
314 | static uint8_t |
||
315 | pack_unorm_1x8(float x) |
||
316 | { |
||
317 | /* From section 8.4 of the GLSL 4.30 spec: |
||
318 | * |
||
319 | * packUnorm4x8 |
||
320 | * ------------ |
||
321 | * The conversion for component c of v to fixed point is done as |
||
322 | * follows: |
||
323 | * |
||
324 | * packUnorm4x8: round(clamp(c, 0, +1) * 255.0) |
||
325 | */ |
||
326 | return (uint8_t) (int) _mesa_roundevenf(CLAMP(x, 0.0f, 1.0f) * 255.0f); |
||
327 | } |
||
328 | |||
329 | /** |
||
330 | * Evaluate one component packUnorm2x16. |
||
331 | */ |
||
332 | static uint16_t |
||
333 | pack_unorm_1x16(float x) |
||
334 | { |
||
335 | /* From section 8.4 of the GLSL ES 3.00 spec: |
||
336 | * |
||
337 | * packUnorm2x16 |
||
338 | * ------------- |
||
339 | * The conversion for component c of v to fixed point is done as |
||
340 | * follows: |
||
341 | * |
||
342 | * packUnorm2x16: round(clamp(c, 0, +1) * 65535.0) |
||
343 | */ |
||
344 | return (uint16_t) (int) |
||
345 | _mesa_roundevenf(CLAMP(x, 0.0f, 1.0f) * 65535.0f); |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * Evaluate one component of unpackUnorm4x8. |
||
350 | */ |
||
351 | static float |
||
352 | unpack_unorm_1x8(uint8_t u) |
||
353 | { |
||
354 | /* From section 8.4 of the GLSL 4.30 spec: |
||
355 | * |
||
356 | * unpackUnorm4x8 |
||
357 | * -------------- |
||
358 | * The conversion for unpacked fixed-point value f to floating point is |
||
359 | * done as follows: |
||
360 | * |
||
361 | * unpackUnorm4x8: f / 255.0 |
||
362 | */ |
||
363 | return (float) u / 255.0f; |
||
364 | } |
||
365 | |||
366 | /** |
||
367 | * Evaluate one component of unpackUnorm2x16. |
||
368 | */ |
||
369 | static float |
||
370 | unpack_unorm_1x16(uint16_t u) |
||
371 | { |
||
372 | /* From section 8.4 of the GLSL ES 3.00 spec: |
||
373 | * |
||
374 | * unpackUnorm2x16 |
||
375 | * --------------- |
||
376 | * The conversion for unpacked fixed-point value f to floating point is |
||
377 | * done as follows: |
||
378 | * |
||
379 | * unpackUnorm2x16: f / 65535.0 |
||
380 | */ |
||
381 | return (float) u / 65535.0f; |
||
382 | } |
||
383 | |||
384 | /** |
||
385 | * Evaluate one component of packHalf2x16. |
||
386 | */ |
||
387 | static uint16_t |
||
388 | pack_half_1x16(float x) |
||
389 | { |
||
390 | return _mesa_float_to_half(x); |
||
391 | } |
||
392 | |||
393 | /** |
||
394 | * Evaluate one component of unpackHalf2x16. |
||
395 | */ |
||
396 | static float |
||
397 | unpack_half_1x16(uint16_t u) |
||
398 | { |
||
399 | return _mesa_half_to_float(u); |
||
400 | } |
||
401 | |||
402 | /** |
||
403 | * Get the constant that is ultimately referenced by an r-value, in a constant |
||
404 | * expression evaluation context. |
||
405 | * |
||
406 | * The offset is used when the reference is to a specific column of a matrix. |
||
407 | */ |
||
408 | static bool |
||
409 | constant_referenced(const ir_dereference *deref, |
||
410 | struct hash_table *variable_context, |
||
411 | ir_constant *&store, int &offset) |
||
412 | { |
||
413 | store = NULL; |
||
414 | offset = 0; |
||
415 | |||
416 | if (variable_context == NULL) |
||
417 | return false; |
||
418 | |||
419 | switch (deref->ir_type) { |
||
420 | case ir_type_dereference_array: { |
||
421 | const ir_dereference_array *const da = |
||
422 | (const ir_dereference_array *) deref; |
||
423 | |||
424 | ir_constant *const index_c = |
||
425 | da->array_index->constant_expression_value(variable_context); |
||
426 | |||
427 | if (!index_c || !index_c->type->is_scalar() || !index_c->type->is_integer()) |
||
428 | break; |
||
429 | |||
430 | const int index = index_c->type->base_type == GLSL_TYPE_INT ? |
||
431 | index_c->get_int_component(0) : |
||
432 | index_c->get_uint_component(0); |
||
433 | |||
434 | ir_constant *substore; |
||
435 | int suboffset; |
||
436 | |||
437 | const ir_dereference *const deref = da->array->as_dereference(); |
||
438 | if (!deref) |
||
439 | break; |
||
440 | |||
441 | if (!constant_referenced(deref, variable_context, substore, suboffset)) |
||
442 | break; |
||
443 | |||
444 | const glsl_type *const vt = da->array->type; |
||
445 | if (vt->is_array()) { |
||
446 | store = substore->get_array_element(index); |
||
447 | offset = 0; |
||
448 | } else if (vt->is_matrix()) { |
||
449 | store = substore; |
||
450 | offset = index * vt->vector_elements; |
||
451 | } else if (vt->is_vector()) { |
||
452 | store = substore; |
||
453 | offset = suboffset + index; |
||
454 | } |
||
455 | |||
456 | break; |
||
457 | } |
||
458 | |||
459 | case ir_type_dereference_record: { |
||
460 | const ir_dereference_record *const dr = |
||
461 | (const ir_dereference_record *) deref; |
||
462 | |||
463 | const ir_dereference *const deref = dr->record->as_dereference(); |
||
464 | if (!deref) |
||
465 | break; |
||
466 | |||
467 | ir_constant *substore; |
||
468 | int suboffset; |
||
469 | |||
470 | if (!constant_referenced(deref, variable_context, substore, suboffset)) |
||
471 | break; |
||
472 | |||
473 | /* Since we're dropping it on the floor... |
||
474 | */ |
||
475 | assert(suboffset == 0); |
||
476 | |||
477 | store = substore->get_record_field(dr->field); |
||
478 | break; |
||
479 | } |
||
480 | |||
481 | case ir_type_dereference_variable: { |
||
482 | const ir_dereference_variable *const dv = |
||
483 | (const ir_dereference_variable *) deref; |
||
484 | |||
485 | store = (ir_constant *) hash_table_find(variable_context, dv->var); |
||
486 | break; |
||
487 | } |
||
488 | |||
489 | default: |
||
490 | assert(!"Should not get here."); |
||
491 | break; |
||
492 | } |
||
493 | |||
494 | return store != NULL; |
||
495 | } |
||
496 | |||
497 | |||
498 | ir_constant * |
||
499 | ir_rvalue::constant_expression_value(struct hash_table *) |
||
500 | { |
||
501 | assert(this->type->is_error()); |
||
502 | return NULL; |
||
503 | } |
||
504 | |||
505 | ir_constant * |
||
506 | ir_expression::constant_expression_value(struct hash_table *variable_context) |
||
507 | { |
||
508 | if (this->type->is_error()) |
||
509 | return NULL; |
||
510 | |||
511 | ir_constant *op[ARRAY_SIZE(this->operands)] = { NULL, }; |
||
512 | ir_constant_data data; |
||
513 | |||
514 | memset(&data, 0, sizeof(data)); |
||
515 | |||
516 | for (unsigned operand = 0; operand < this->get_num_operands(); operand++) { |
||
517 | op[operand] = this->operands[operand]->constant_expression_value(variable_context); |
||
518 | if (!op[operand]) |
||
519 | return NULL; |
||
520 | } |
||
521 | |||
522 | if (op[1] != NULL) |
||
523 | switch (this->operation) { |
||
524 | case ir_binop_lshift: |
||
525 | case ir_binop_rshift: |
||
526 | case ir_binop_ldexp: |
||
527 | case ir_binop_interpolate_at_offset: |
||
528 | case ir_binop_interpolate_at_sample: |
||
529 | case ir_binop_vector_extract: |
||
530 | case ir_triop_csel: |
||
531 | case ir_triop_bitfield_extract: |
||
532 | break; |
||
533 | |||
534 | default: |
||
535 | assert(op[0]->type->base_type == op[1]->type->base_type); |
||
536 | break; |
||
537 | } |
||
538 | |||
539 | bool op0_scalar = op[0]->type->is_scalar(); |
||
540 | bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar(); |
||
541 | |||
542 | /* When iterating over a vector or matrix's components, we want to increase |
||
543 | * the loop counter. However, for scalars, we want to stay at 0. |
||
544 | */ |
||
545 | unsigned c0_inc = op0_scalar ? 0 : 1; |
||
546 | unsigned c1_inc = op1_scalar ? 0 : 1; |
||
547 | unsigned components; |
||
548 | if (op1_scalar || !op[1]) { |
||
549 | components = op[0]->type->components(); |
||
550 | } else { |
||
551 | components = op[1]->type->components(); |
||
552 | } |
||
553 | |||
554 | void *ctx = ralloc_parent(this); |
||
555 | |||
556 | /* Handle array operations here, rather than below. */ |
||
557 | if (op[0]->type->is_array()) { |
||
558 | assert(op[1] != NULL && op[1]->type->is_array()); |
||
559 | switch (this->operation) { |
||
560 | case ir_binop_all_equal: |
||
561 | return new(ctx) ir_constant(op[0]->has_value(op[1])); |
||
562 | case ir_binop_any_nequal: |
||
563 | return new(ctx) ir_constant(!op[0]->has_value(op[1])); |
||
564 | default: |
||
565 | break; |
||
566 | } |
||
567 | return NULL; |
||
568 | } |
||
569 | |||
570 | switch (this->operation) { |
||
571 | case ir_unop_bit_not: |
||
572 | switch (op[0]->type->base_type) { |
||
573 | case GLSL_TYPE_INT: |
||
574 | for (unsigned c = 0; c < components; c++) |
||
575 | data.i[c] = ~ op[0]->value.i[c]; |
||
576 | break; |
||
577 | case GLSL_TYPE_UINT: |
||
578 | for (unsigned c = 0; c < components; c++) |
||
579 | data.u[c] = ~ op[0]->value.u[c]; |
||
580 | break; |
||
581 | default: |
||
582 | assert(0); |
||
583 | } |
||
584 | break; |
||
585 | |||
586 | case ir_unop_logic_not: |
||
587 | assert(op[0]->type->base_type == GLSL_TYPE_BOOL); |
||
588 | for (unsigned c = 0; c < op[0]->type->components(); c++) |
||
589 | data.b[c] = !op[0]->value.b[c]; |
||
590 | break; |
||
591 | |||
592 | case ir_unop_f2i: |
||
593 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
594 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
595 | data.i[c] = (int) op[0]->value.f[c]; |
||
596 | } |
||
597 | break; |
||
598 | case ir_unop_f2u: |
||
599 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
600 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
601 | data.i[c] = (unsigned) op[0]->value.f[c]; |
||
602 | } |
||
603 | break; |
||
604 | case ir_unop_i2f: |
||
605 | assert(op[0]->type->base_type == GLSL_TYPE_INT); |
||
606 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
607 | data.f[c] = (float) op[0]->value.i[c]; |
||
608 | } |
||
609 | break; |
||
610 | case ir_unop_u2f: |
||
611 | assert(op[0]->type->base_type == GLSL_TYPE_UINT); |
||
612 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
613 | data.f[c] = (float) op[0]->value.u[c]; |
||
614 | } |
||
615 | break; |
||
616 | case ir_unop_b2f: |
||
617 | assert(op[0]->type->base_type == GLSL_TYPE_BOOL); |
||
618 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
619 | data.f[c] = op[0]->value.b[c] ? 1.0F : 0.0F; |
||
620 | } |
||
621 | break; |
||
622 | case ir_unop_f2b: |
||
623 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
624 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
625 | data.b[c] = op[0]->value.f[c] != 0.0F ? true : false; |
||
626 | } |
||
627 | break; |
||
628 | case ir_unop_b2i: |
||
629 | assert(op[0]->type->base_type == GLSL_TYPE_BOOL); |
||
630 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
631 | data.u[c] = op[0]->value.b[c] ? 1 : 0; |
||
632 | } |
||
633 | break; |
||
634 | case ir_unop_i2b: |
||
635 | assert(op[0]->type->is_integer()); |
||
636 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
637 | data.b[c] = op[0]->value.u[c] ? true : false; |
||
638 | } |
||
639 | break; |
||
640 | case ir_unop_u2i: |
||
641 | assert(op[0]->type->base_type == GLSL_TYPE_UINT); |
||
642 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
643 | data.i[c] = op[0]->value.u[c]; |
||
644 | } |
||
645 | break; |
||
646 | case ir_unop_i2u: |
||
647 | assert(op[0]->type->base_type == GLSL_TYPE_INT); |
||
648 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
649 | data.u[c] = op[0]->value.i[c]; |
||
650 | } |
||
651 | break; |
||
652 | case ir_unop_bitcast_i2f: |
||
653 | assert(op[0]->type->base_type == GLSL_TYPE_INT); |
||
654 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
655 | data.f[c] = bitcast_u2f(op[0]->value.i[c]); |
||
656 | } |
||
657 | break; |
||
658 | case ir_unop_bitcast_f2i: |
||
659 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
660 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
661 | data.i[c] = bitcast_f2u(op[0]->value.f[c]); |
||
662 | } |
||
663 | break; |
||
664 | case ir_unop_bitcast_u2f: |
||
665 | assert(op[0]->type->base_type == GLSL_TYPE_UINT); |
||
666 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
667 | data.f[c] = bitcast_u2f(op[0]->value.u[c]); |
||
668 | } |
||
669 | break; |
||
670 | case ir_unop_bitcast_f2u: |
||
671 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
672 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
673 | data.u[c] = bitcast_f2u(op[0]->value.f[c]); |
||
674 | } |
||
675 | break; |
||
676 | case ir_unop_any: |
||
677 | assert(op[0]->type->is_boolean()); |
||
678 | data.b[0] = false; |
||
679 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
680 | if (op[0]->value.b[c]) |
||
681 | data.b[0] = true; |
||
682 | } |
||
683 | break; |
||
684 | case ir_unop_d2f: |
||
685 | assert(op[0]->type->base_type == GLSL_TYPE_DOUBLE); |
||
686 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
687 | data.f[c] = op[0]->value.d[c]; |
||
688 | } |
||
689 | break; |
||
690 | case ir_unop_f2d: |
||
691 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
692 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
693 | data.d[c] = op[0]->value.f[c]; |
||
694 | } |
||
695 | break; |
||
696 | case ir_unop_d2i: |
||
697 | assert(op[0]->type->base_type == GLSL_TYPE_DOUBLE); |
||
698 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
699 | data.i[c] = op[0]->value.d[c]; |
||
700 | } |
||
701 | break; |
||
702 | case ir_unop_i2d: |
||
703 | assert(op[0]->type->base_type == GLSL_TYPE_INT); |
||
704 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
705 | data.d[c] = op[0]->value.i[c]; |
||
706 | } |
||
707 | break; |
||
708 | case ir_unop_d2u: |
||
709 | assert(op[0]->type->base_type == GLSL_TYPE_DOUBLE); |
||
710 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
711 | data.u[c] = op[0]->value.d[c]; |
||
712 | } |
||
713 | break; |
||
714 | case ir_unop_u2d: |
||
715 | assert(op[0]->type->base_type == GLSL_TYPE_UINT); |
||
716 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
717 | data.d[c] = op[0]->value.u[c]; |
||
718 | } |
||
719 | break; |
||
720 | case ir_unop_d2b: |
||
721 | assert(op[0]->type->base_type == GLSL_TYPE_DOUBLE); |
||
722 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
723 | data.b[c] = op[0]->value.d[c] != 0.0; |
||
724 | } |
||
725 | break; |
||
726 | case ir_unop_trunc: |
||
727 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
728 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) |
||
729 | data.d[c] = trunc(op[0]->value.d[c]); |
||
730 | else |
||
731 | data.f[c] = truncf(op[0]->value.f[c]); |
||
732 | } |
||
733 | break; |
||
734 | |||
735 | case ir_unop_round_even: |
||
736 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
737 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) |
||
738 | data.d[c] = _mesa_roundeven(op[0]->value.d[c]); |
||
739 | else |
||
740 | data.f[c] = _mesa_roundevenf(op[0]->value.f[c]); |
||
741 | } |
||
742 | break; |
||
743 | |||
744 | case ir_unop_ceil: |
||
745 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
746 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) |
||
747 | data.d[c] = ceil(op[0]->value.d[c]); |
||
748 | else |
||
749 | data.f[c] = ceilf(op[0]->value.f[c]); |
||
750 | } |
||
751 | break; |
||
752 | |||
753 | case ir_unop_floor: |
||
754 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
755 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) |
||
756 | data.d[c] = floor(op[0]->value.d[c]); |
||
757 | else |
||
758 | data.f[c] = floorf(op[0]->value.f[c]); |
||
759 | } |
||
760 | break; |
||
761 | |||
762 | case ir_unop_fract: |
||
763 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
764 | switch (this->type->base_type) { |
||
765 | case GLSL_TYPE_UINT: |
||
766 | data.u[c] = 0; |
||
767 | break; |
||
768 | case GLSL_TYPE_INT: |
||
769 | data.i[c] = 0; |
||
770 | break; |
||
771 | case GLSL_TYPE_FLOAT: |
||
772 | data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]); |
||
773 | break; |
||
774 | case GLSL_TYPE_DOUBLE: |
||
775 | data.d[c] = op[0]->value.d[c] - floor(op[0]->value.d[c]); |
||
776 | break; |
||
777 | default: |
||
778 | assert(0); |
||
779 | } |
||
780 | } |
||
781 | break; |
||
782 | |||
783 | case ir_unop_sin: |
||
784 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
785 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
786 | data.f[c] = sinf(op[0]->value.f[c]); |
||
787 | } |
||
788 | break; |
||
789 | |||
790 | case ir_unop_cos: |
||
791 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
792 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
793 | data.f[c] = cosf(op[0]->value.f[c]); |
||
794 | } |
||
795 | break; |
||
796 | |||
797 | case ir_unop_neg: |
||
798 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
799 | switch (this->type->base_type) { |
||
800 | case GLSL_TYPE_UINT: |
||
801 | data.u[c] = -((int) op[0]->value.u[c]); |
||
802 | break; |
||
803 | case GLSL_TYPE_INT: |
||
804 | data.i[c] = -op[0]->value.i[c]; |
||
805 | break; |
||
806 | case GLSL_TYPE_FLOAT: |
||
807 | data.f[c] = -op[0]->value.f[c]; |
||
808 | break; |
||
809 | case GLSL_TYPE_DOUBLE: |
||
810 | data.d[c] = -op[0]->value.d[c]; |
||
811 | break; |
||
812 | default: |
||
813 | assert(0); |
||
814 | } |
||
815 | } |
||
816 | break; |
||
817 | |||
818 | case ir_unop_abs: |
||
819 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
820 | switch (this->type->base_type) { |
||
821 | case GLSL_TYPE_UINT: |
||
822 | data.u[c] = op[0]->value.u[c]; |
||
823 | break; |
||
824 | case GLSL_TYPE_INT: |
||
825 | data.i[c] = op[0]->value.i[c]; |
||
826 | if (data.i[c] < 0) |
||
827 | data.i[c] = -data.i[c]; |
||
828 | break; |
||
829 | case GLSL_TYPE_FLOAT: |
||
830 | data.f[c] = fabs(op[0]->value.f[c]); |
||
831 | break; |
||
832 | case GLSL_TYPE_DOUBLE: |
||
833 | data.d[c] = fabs(op[0]->value.d[c]); |
||
834 | break; |
||
835 | default: |
||
836 | assert(0); |
||
837 | } |
||
838 | } |
||
839 | break; |
||
840 | |||
841 | case ir_unop_sign: |
||
842 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
843 | switch (this->type->base_type) { |
||
844 | case GLSL_TYPE_UINT: |
||
845 | data.u[c] = op[0]->value.i[c] > 0; |
||
846 | break; |
||
847 | case GLSL_TYPE_INT: |
||
848 | data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0); |
||
849 | break; |
||
850 | case GLSL_TYPE_FLOAT: |
||
851 | data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0)); |
||
852 | break; |
||
853 | case GLSL_TYPE_DOUBLE: |
||
854 | data.d[c] = double((op[0]->value.d[c] > 0)-(op[0]->value.d[c] < 0)); |
||
855 | break; |
||
856 | default: |
||
857 | assert(0); |
||
858 | } |
||
859 | } |
||
860 | break; |
||
861 | |||
862 | case ir_unop_rcp: |
||
863 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
864 | switch (this->type->base_type) { |
||
865 | case GLSL_TYPE_UINT: |
||
866 | if (op[0]->value.u[c] != 0.0) |
||
867 | data.u[c] = 1 / op[0]->value.u[c]; |
||
868 | break; |
||
869 | case GLSL_TYPE_INT: |
||
870 | if (op[0]->value.i[c] != 0.0) |
||
871 | data.i[c] = 1 / op[0]->value.i[c]; |
||
872 | break; |
||
873 | case GLSL_TYPE_FLOAT: |
||
874 | if (op[0]->value.f[c] != 0.0) |
||
875 | data.f[c] = 1.0F / op[0]->value.f[c]; |
||
876 | break; |
||
877 | case GLSL_TYPE_DOUBLE: |
||
878 | if (op[0]->value.d[c] != 0.0) |
||
879 | data.d[c] = 1.0 / op[0]->value.d[c]; |
||
880 | break; |
||
881 | default: |
||
882 | assert(0); |
||
883 | } |
||
884 | } |
||
885 | break; |
||
886 | |||
887 | case ir_unop_rsq: |
||
888 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
889 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) |
||
890 | data.d[c] = 1.0 / sqrt(op[0]->value.d[c]); |
||
891 | else |
||
892 | data.f[c] = 1.0F / sqrtf(op[0]->value.f[c]); |
||
893 | } |
||
894 | break; |
||
895 | |||
896 | case ir_unop_sqrt: |
||
897 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
898 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) |
||
899 | data.d[c] = sqrt(op[0]->value.d[c]); |
||
900 | else |
||
901 | data.f[c] = sqrtf(op[0]->value.f[c]); |
||
902 | } |
||
903 | break; |
||
904 | |||
905 | case ir_unop_exp: |
||
906 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
907 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
908 | data.f[c] = expf(op[0]->value.f[c]); |
||
909 | } |
||
910 | break; |
||
911 | |||
912 | case ir_unop_exp2: |
||
913 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
914 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
915 | data.f[c] = exp2f(op[0]->value.f[c]); |
||
916 | } |
||
917 | break; |
||
918 | |||
919 | case ir_unop_log: |
||
920 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
921 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
922 | data.f[c] = logf(op[0]->value.f[c]); |
||
923 | } |
||
924 | break; |
||
925 | |||
926 | case ir_unop_log2: |
||
927 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
928 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
929 | data.f[c] = log2f(op[0]->value.f[c]); |
||
930 | } |
||
931 | break; |
||
932 | |||
933 | case ir_unop_dFdx: |
||
934 | case ir_unop_dFdx_coarse: |
||
935 | case ir_unop_dFdx_fine: |
||
936 | case ir_unop_dFdy: |
||
937 | case ir_unop_dFdy_coarse: |
||
938 | case ir_unop_dFdy_fine: |
||
939 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
940 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
941 | data.f[c] = 0.0; |
||
942 | } |
||
943 | break; |
||
944 | |||
945 | case ir_unop_pack_snorm_2x16: |
||
946 | assert(op[0]->type == glsl_type::vec2_type); |
||
947 | data.u[0] = pack_2x16(pack_snorm_1x16, |
||
948 | op[0]->value.f[0], |
||
949 | op[0]->value.f[1]); |
||
950 | break; |
||
951 | case ir_unop_pack_snorm_4x8: |
||
952 | assert(op[0]->type == glsl_type::vec4_type); |
||
953 | data.u[0] = pack_4x8(pack_snorm_1x8, |
||
954 | op[0]->value.f[0], |
||
955 | op[0]->value.f[1], |
||
956 | op[0]->value.f[2], |
||
957 | op[0]->value.f[3]); |
||
958 | break; |
||
959 | case ir_unop_unpack_snorm_2x16: |
||
960 | assert(op[0]->type == glsl_type::uint_type); |
||
961 | unpack_2x16(unpack_snorm_1x16, |
||
962 | op[0]->value.u[0], |
||
963 | &data.f[0], &data.f[1]); |
||
964 | break; |
||
965 | case ir_unop_unpack_snorm_4x8: |
||
966 | assert(op[0]->type == glsl_type::uint_type); |
||
967 | unpack_4x8(unpack_snorm_1x8, |
||
968 | op[0]->value.u[0], |
||
969 | &data.f[0], &data.f[1], &data.f[2], &data.f[3]); |
||
970 | break; |
||
971 | case ir_unop_pack_unorm_2x16: |
||
972 | assert(op[0]->type == glsl_type::vec2_type); |
||
973 | data.u[0] = pack_2x16(pack_unorm_1x16, |
||
974 | op[0]->value.f[0], |
||
975 | op[0]->value.f[1]); |
||
976 | break; |
||
977 | case ir_unop_pack_unorm_4x8: |
||
978 | assert(op[0]->type == glsl_type::vec4_type); |
||
979 | data.u[0] = pack_4x8(pack_unorm_1x8, |
||
980 | op[0]->value.f[0], |
||
981 | op[0]->value.f[1], |
||
982 | op[0]->value.f[2], |
||
983 | op[0]->value.f[3]); |
||
984 | break; |
||
985 | case ir_unop_unpack_unorm_2x16: |
||
986 | assert(op[0]->type == glsl_type::uint_type); |
||
987 | unpack_2x16(unpack_unorm_1x16, |
||
988 | op[0]->value.u[0], |
||
989 | &data.f[0], &data.f[1]); |
||
990 | break; |
||
991 | case ir_unop_unpack_unorm_4x8: |
||
992 | assert(op[0]->type == glsl_type::uint_type); |
||
993 | unpack_4x8(unpack_unorm_1x8, |
||
994 | op[0]->value.u[0], |
||
995 | &data.f[0], &data.f[1], &data.f[2], &data.f[3]); |
||
996 | break; |
||
997 | case ir_unop_pack_half_2x16: |
||
998 | assert(op[0]->type == glsl_type::vec2_type); |
||
999 | data.u[0] = pack_2x16(pack_half_1x16, |
||
1000 | op[0]->value.f[0], |
||
1001 | op[0]->value.f[1]); |
||
1002 | break; |
||
1003 | case ir_unop_unpack_half_2x16: |
||
1004 | assert(op[0]->type == glsl_type::uint_type); |
||
1005 | unpack_2x16(unpack_half_1x16, |
||
1006 | op[0]->value.u[0], |
||
1007 | &data.f[0], &data.f[1]); |
||
1008 | break; |
||
1009 | case ir_binop_pow: |
||
1010 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); |
||
1011 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
1012 | data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]); |
||
1013 | } |
||
1014 | break; |
||
1015 | |||
1016 | case ir_binop_dot: |
||
1017 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) |
||
1018 | data.d[0] = dot_d(op[0], op[1]); |
||
1019 | else |
||
1020 | data.f[0] = dot_f(op[0], op[1]); |
||
1021 | break; |
||
1022 | |||
1023 | case ir_binop_min: |
||
1024 | assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); |
||
1025 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1026 | c < components; |
||
1027 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1028 | |||
1029 | switch (op[0]->type->base_type) { |
||
1030 | case GLSL_TYPE_UINT: |
||
1031 | data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]); |
||
1032 | break; |
||
1033 | case GLSL_TYPE_INT: |
||
1034 | data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]); |
||
1035 | break; |
||
1036 | case GLSL_TYPE_FLOAT: |
||
1037 | data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]); |
||
1038 | break; |
||
1039 | case GLSL_TYPE_DOUBLE: |
||
1040 | data.d[c] = MIN2(op[0]->value.d[c0], op[1]->value.d[c1]); |
||
1041 | break; |
||
1042 | default: |
||
1043 | assert(0); |
||
1044 | } |
||
1045 | } |
||
1046 | |||
1047 | break; |
||
1048 | case ir_binop_max: |
||
1049 | assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); |
||
1050 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1051 | c < components; |
||
1052 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1053 | |||
1054 | switch (op[0]->type->base_type) { |
||
1055 | case GLSL_TYPE_UINT: |
||
1056 | data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]); |
||
1057 | break; |
||
1058 | case GLSL_TYPE_INT: |
||
1059 | data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]); |
||
1060 | break; |
||
1061 | case GLSL_TYPE_FLOAT: |
||
1062 | data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]); |
||
1063 | break; |
||
1064 | case GLSL_TYPE_DOUBLE: |
||
1065 | data.d[c] = MAX2(op[0]->value.d[c0], op[1]->value.d[c1]); |
||
1066 | break; |
||
1067 | default: |
||
1068 | assert(0); |
||
1069 | } |
||
1070 | } |
||
1071 | break; |
||
1072 | |||
1073 | case ir_binop_add: |
||
1074 | assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); |
||
1075 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1076 | c < components; |
||
1077 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1078 | |||
1079 | switch (op[0]->type->base_type) { |
||
1080 | case GLSL_TYPE_UINT: |
||
1081 | data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1]; |
||
1082 | break; |
||
1083 | case GLSL_TYPE_INT: |
||
1084 | data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1]; |
||
1085 | break; |
||
1086 | case GLSL_TYPE_FLOAT: |
||
1087 | data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1]; |
||
1088 | break; |
||
1089 | case GLSL_TYPE_DOUBLE: |
||
1090 | data.d[c] = op[0]->value.d[c0] + op[1]->value.d[c1]; |
||
1091 | break; |
||
1092 | default: |
||
1093 | assert(0); |
||
1094 | } |
||
1095 | } |
||
1096 | |||
1097 | break; |
||
1098 | case ir_binop_sub: |
||
1099 | assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); |
||
1100 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1101 | c < components; |
||
1102 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1103 | |||
1104 | switch (op[0]->type->base_type) { |
||
1105 | case GLSL_TYPE_UINT: |
||
1106 | data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1]; |
||
1107 | break; |
||
1108 | case GLSL_TYPE_INT: |
||
1109 | data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1]; |
||
1110 | break; |
||
1111 | case GLSL_TYPE_FLOAT: |
||
1112 | data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]; |
||
1113 | break; |
||
1114 | case GLSL_TYPE_DOUBLE: |
||
1115 | data.d[c] = op[0]->value.d[c0] - op[1]->value.d[c1]; |
||
1116 | break; |
||
1117 | default: |
||
1118 | assert(0); |
||
1119 | } |
||
1120 | } |
||
1121 | |||
1122 | break; |
||
1123 | case ir_binop_mul: |
||
1124 | /* Check for equal types, or unequal types involving scalars */ |
||
1125 | if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix()) |
||
1126 | || op0_scalar || op1_scalar) { |
||
1127 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1128 | c < components; |
||
1129 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1130 | |||
1131 | switch (op[0]->type->base_type) { |
||
1132 | case GLSL_TYPE_UINT: |
||
1133 | data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1]; |
||
1134 | break; |
||
1135 | case GLSL_TYPE_INT: |
||
1136 | data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1]; |
||
1137 | break; |
||
1138 | case GLSL_TYPE_FLOAT: |
||
1139 | data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1]; |
||
1140 | break; |
||
1141 | case GLSL_TYPE_DOUBLE: |
||
1142 | data.d[c] = op[0]->value.d[c0] * op[1]->value.d[c1]; |
||
1143 | break; |
||
1144 | default: |
||
1145 | assert(0); |
||
1146 | } |
||
1147 | } |
||
1148 | } else { |
||
1149 | assert(op[0]->type->is_matrix() || op[1]->type->is_matrix()); |
||
1150 | |||
1151 | /* Multiply an N-by-M matrix with an M-by-P matrix. Since either |
||
1152 | * matrix can be a GLSL vector, either N or P can be 1. |
||
1153 | * |
||
1154 | * For vec*mat, the vector is treated as a row vector. This |
||
1155 | * means the vector is a 1-row x M-column matrix. |
||
1156 | * |
||
1157 | * For mat*vec, the vector is treated as a column vector. Since |
||
1158 | * matrix_columns is 1 for vectors, this just works. |
||
1159 | */ |
||
1160 | const unsigned n = op[0]->type->is_vector() |
||
1161 | ? 1 : op[0]->type->vector_elements; |
||
1162 | const unsigned m = op[1]->type->vector_elements; |
||
1163 | const unsigned p = op[1]->type->matrix_columns; |
||
1164 | for (unsigned j = 0; j < p; j++) { |
||
1165 | for (unsigned i = 0; i < n; i++) { |
||
1166 | for (unsigned k = 0; k < m; k++) { |
||
1167 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) |
||
1168 | data.d[i+n*j] += op[0]->value.d[i+n*k]*op[1]->value.d[k+m*j]; |
||
1169 | else |
||
1170 | data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j]; |
||
1171 | } |
||
1172 | } |
||
1173 | } |
||
1174 | } |
||
1175 | |||
1176 | break; |
||
1177 | case ir_binop_div: |
||
1178 | /* FINISHME: Emit warning when division-by-zero is detected. */ |
||
1179 | assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); |
||
1180 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1181 | c < components; |
||
1182 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1183 | |||
1184 | switch (op[0]->type->base_type) { |
||
1185 | case GLSL_TYPE_UINT: |
||
1186 | if (op[1]->value.u[c1] == 0) { |
||
1187 | data.u[c] = 0; |
||
1188 | } else { |
||
1189 | data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1]; |
||
1190 | } |
||
1191 | break; |
||
1192 | case GLSL_TYPE_INT: |
||
1193 | if (op[1]->value.i[c1] == 0) { |
||
1194 | data.i[c] = 0; |
||
1195 | } else { |
||
1196 | data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1]; |
||
1197 | } |
||
1198 | break; |
||
1199 | case GLSL_TYPE_FLOAT: |
||
1200 | data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1]; |
||
1201 | break; |
||
1202 | case GLSL_TYPE_DOUBLE: |
||
1203 | data.d[c] = op[0]->value.d[c0] / op[1]->value.d[c1]; |
||
1204 | break; |
||
1205 | default: |
||
1206 | assert(0); |
||
1207 | } |
||
1208 | } |
||
1209 | |||
1210 | break; |
||
1211 | case ir_binop_mod: |
||
1212 | /* FINISHME: Emit warning when division-by-zero is detected. */ |
||
1213 | assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); |
||
1214 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1215 | c < components; |
||
1216 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1217 | |||
1218 | switch (op[0]->type->base_type) { |
||
1219 | case GLSL_TYPE_UINT: |
||
1220 | if (op[1]->value.u[c1] == 0) { |
||
1221 | data.u[c] = 0; |
||
1222 | } else { |
||
1223 | data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1]; |
||
1224 | } |
||
1225 | break; |
||
1226 | case GLSL_TYPE_INT: |
||
1227 | if (op[1]->value.i[c1] == 0) { |
||
1228 | data.i[c] = 0; |
||
1229 | } else { |
||
1230 | data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1]; |
||
1231 | } |
||
1232 | break; |
||
1233 | case GLSL_TYPE_FLOAT: |
||
1234 | /* We don't use fmod because it rounds toward zero; GLSL specifies |
||
1235 | * the use of floor. |
||
1236 | */ |
||
1237 | data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1] |
||
1238 | * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]); |
||
1239 | break; |
||
1240 | case GLSL_TYPE_DOUBLE: |
||
1241 | /* We don't use fmod because it rounds toward zero; GLSL specifies |
||
1242 | * the use of floor. |
||
1243 | */ |
||
1244 | data.d[c] = op[0]->value.d[c0] - op[1]->value.d[c1] |
||
1245 | * floor(op[0]->value.d[c0] / op[1]->value.d[c1]); |
||
1246 | break; |
||
1247 | default: |
||
1248 | assert(0); |
||
1249 | } |
||
1250 | } |
||
1251 | |||
1252 | break; |
||
1253 | |||
1254 | case ir_binop_logic_and: |
||
1255 | assert(op[0]->type->base_type == GLSL_TYPE_BOOL); |
||
1256 | for (unsigned c = 0; c < op[0]->type->components(); c++) |
||
1257 | data.b[c] = op[0]->value.b[c] && op[1]->value.b[c]; |
||
1258 | break; |
||
1259 | case ir_binop_logic_xor: |
||
1260 | assert(op[0]->type->base_type == GLSL_TYPE_BOOL); |
||
1261 | for (unsigned c = 0; c < op[0]->type->components(); c++) |
||
1262 | data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c]; |
||
1263 | break; |
||
1264 | case ir_binop_logic_or: |
||
1265 | assert(op[0]->type->base_type == GLSL_TYPE_BOOL); |
||
1266 | for (unsigned c = 0; c < op[0]->type->components(); c++) |
||
1267 | data.b[c] = op[0]->value.b[c] || op[1]->value.b[c]; |
||
1268 | break; |
||
1269 | |||
1270 | case ir_binop_less: |
||
1271 | assert(op[0]->type == op[1]->type); |
||
1272 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
1273 | switch (op[0]->type->base_type) { |
||
1274 | case GLSL_TYPE_UINT: |
||
1275 | data.b[c] = op[0]->value.u[c] < op[1]->value.u[c]; |
||
1276 | break; |
||
1277 | case GLSL_TYPE_INT: |
||
1278 | data.b[c] = op[0]->value.i[c] < op[1]->value.i[c]; |
||
1279 | break; |
||
1280 | case GLSL_TYPE_FLOAT: |
||
1281 | data.b[c] = op[0]->value.f[c] < op[1]->value.f[c]; |
||
1282 | break; |
||
1283 | case GLSL_TYPE_DOUBLE: |
||
1284 | data.b[c] = op[0]->value.d[c] < op[1]->value.d[c]; |
||
1285 | break; |
||
1286 | default: |
||
1287 | assert(0); |
||
1288 | } |
||
1289 | } |
||
1290 | break; |
||
1291 | case ir_binop_greater: |
||
1292 | assert(op[0]->type == op[1]->type); |
||
1293 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
1294 | switch (op[0]->type->base_type) { |
||
1295 | case GLSL_TYPE_UINT: |
||
1296 | data.b[c] = op[0]->value.u[c] > op[1]->value.u[c]; |
||
1297 | break; |
||
1298 | case GLSL_TYPE_INT: |
||
1299 | data.b[c] = op[0]->value.i[c] > op[1]->value.i[c]; |
||
1300 | break; |
||
1301 | case GLSL_TYPE_FLOAT: |
||
1302 | data.b[c] = op[0]->value.f[c] > op[1]->value.f[c]; |
||
1303 | break; |
||
1304 | case GLSL_TYPE_DOUBLE: |
||
1305 | data.b[c] = op[0]->value.d[c] > op[1]->value.d[c]; |
||
1306 | break; |
||
1307 | default: |
||
1308 | assert(0); |
||
1309 | } |
||
1310 | } |
||
1311 | break; |
||
1312 | case ir_binop_lequal: |
||
1313 | assert(op[0]->type == op[1]->type); |
||
1314 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
1315 | switch (op[0]->type->base_type) { |
||
1316 | case GLSL_TYPE_UINT: |
||
1317 | data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c]; |
||
1318 | break; |
||
1319 | case GLSL_TYPE_INT: |
||
1320 | data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c]; |
||
1321 | break; |
||
1322 | case GLSL_TYPE_FLOAT: |
||
1323 | data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c]; |
||
1324 | break; |
||
1325 | case GLSL_TYPE_DOUBLE: |
||
1326 | data.b[c] = op[0]->value.d[c] <= op[1]->value.d[c]; |
||
1327 | break; |
||
1328 | default: |
||
1329 | assert(0); |
||
1330 | } |
||
1331 | } |
||
1332 | break; |
||
1333 | case ir_binop_gequal: |
||
1334 | assert(op[0]->type == op[1]->type); |
||
1335 | for (unsigned c = 0; c < op[0]->type->components(); c++) { |
||
1336 | switch (op[0]->type->base_type) { |
||
1337 | case GLSL_TYPE_UINT: |
||
1338 | data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c]; |
||
1339 | break; |
||
1340 | case GLSL_TYPE_INT: |
||
1341 | data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c]; |
||
1342 | break; |
||
1343 | case GLSL_TYPE_FLOAT: |
||
1344 | data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c]; |
||
1345 | break; |
||
1346 | case GLSL_TYPE_DOUBLE: |
||
1347 | data.b[c] = op[0]->value.d[c] >= op[1]->value.d[c]; |
||
1348 | break; |
||
1349 | default: |
||
1350 | assert(0); |
||
1351 | } |
||
1352 | } |
||
1353 | break; |
||
1354 | case ir_binop_equal: |
||
1355 | assert(op[0]->type == op[1]->type); |
||
1356 | for (unsigned c = 0; c < components; c++) { |
||
1357 | switch (op[0]->type->base_type) { |
||
1358 | case GLSL_TYPE_UINT: |
||
1359 | data.b[c] = op[0]->value.u[c] == op[1]->value.u[c]; |
||
1360 | break; |
||
1361 | case GLSL_TYPE_INT: |
||
1362 | data.b[c] = op[0]->value.i[c] == op[1]->value.i[c]; |
||
1363 | break; |
||
1364 | case GLSL_TYPE_FLOAT: |
||
1365 | data.b[c] = op[0]->value.f[c] == op[1]->value.f[c]; |
||
1366 | break; |
||
1367 | case GLSL_TYPE_BOOL: |
||
1368 | data.b[c] = op[0]->value.b[c] == op[1]->value.b[c]; |
||
1369 | break; |
||
1370 | case GLSL_TYPE_DOUBLE: |
||
1371 | data.b[c] = op[0]->value.d[c] == op[1]->value.d[c]; |
||
1372 | break; |
||
1373 | default: |
||
1374 | assert(0); |
||
1375 | } |
||
1376 | } |
||
1377 | break; |
||
1378 | case ir_binop_nequal: |
||
1379 | assert(op[0]->type == op[1]->type); |
||
1380 | for (unsigned c = 0; c < components; c++) { |
||
1381 | switch (op[0]->type->base_type) { |
||
1382 | case GLSL_TYPE_UINT: |
||
1383 | data.b[c] = op[0]->value.u[c] != op[1]->value.u[c]; |
||
1384 | break; |
||
1385 | case GLSL_TYPE_INT: |
||
1386 | data.b[c] = op[0]->value.i[c] != op[1]->value.i[c]; |
||
1387 | break; |
||
1388 | case GLSL_TYPE_FLOAT: |
||
1389 | data.b[c] = op[0]->value.f[c] != op[1]->value.f[c]; |
||
1390 | break; |
||
1391 | case GLSL_TYPE_BOOL: |
||
1392 | data.b[c] = op[0]->value.b[c] != op[1]->value.b[c]; |
||
1393 | break; |
||
1394 | case GLSL_TYPE_DOUBLE: |
||
1395 | data.b[c] = op[0]->value.d[c] != op[1]->value.d[c]; |
||
1396 | break; |
||
1397 | default: |
||
1398 | assert(0); |
||
1399 | } |
||
1400 | } |
||
1401 | break; |
||
1402 | case ir_binop_all_equal: |
||
1403 | data.b[0] = op[0]->has_value(op[1]); |
||
1404 | break; |
||
1405 | case ir_binop_any_nequal: |
||
1406 | data.b[0] = !op[0]->has_value(op[1]); |
||
1407 | break; |
||
1408 | |||
1409 | case ir_binop_lshift: |
||
1410 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1411 | c < components; |
||
1412 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1413 | |||
1414 | if (op[0]->type->base_type == GLSL_TYPE_INT && |
||
1415 | op[1]->type->base_type == GLSL_TYPE_INT) { |
||
1416 | data.i[c] = op[0]->value.i[c0] << op[1]->value.i[c1]; |
||
1417 | |||
1418 | } else if (op[0]->type->base_type == GLSL_TYPE_INT && |
||
1419 | op[1]->type->base_type == GLSL_TYPE_UINT) { |
||
1420 | data.i[c] = op[0]->value.i[c0] << op[1]->value.u[c1]; |
||
1421 | |||
1422 | } else if (op[0]->type->base_type == GLSL_TYPE_UINT && |
||
1423 | op[1]->type->base_type == GLSL_TYPE_INT) { |
||
1424 | data.u[c] = op[0]->value.u[c0] << op[1]->value.i[c1]; |
||
1425 | |||
1426 | } else if (op[0]->type->base_type == GLSL_TYPE_UINT && |
||
1427 | op[1]->type->base_type == GLSL_TYPE_UINT) { |
||
1428 | data.u[c] = op[0]->value.u[c0] << op[1]->value.u[c1]; |
||
1429 | } |
||
1430 | } |
||
1431 | break; |
||
1432 | |||
1433 | case ir_binop_rshift: |
||
1434 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1435 | c < components; |
||
1436 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1437 | |||
1438 | if (op[0]->type->base_type == GLSL_TYPE_INT && |
||
1439 | op[1]->type->base_type == GLSL_TYPE_INT) { |
||
1440 | data.i[c] = op[0]->value.i[c0] >> op[1]->value.i[c1]; |
||
1441 | |||
1442 | } else if (op[0]->type->base_type == GLSL_TYPE_INT && |
||
1443 | op[1]->type->base_type == GLSL_TYPE_UINT) { |
||
1444 | data.i[c] = op[0]->value.i[c0] >> op[1]->value.u[c1]; |
||
1445 | |||
1446 | } else if (op[0]->type->base_type == GLSL_TYPE_UINT && |
||
1447 | op[1]->type->base_type == GLSL_TYPE_INT) { |
||
1448 | data.u[c] = op[0]->value.u[c0] >> op[1]->value.i[c1]; |
||
1449 | |||
1450 | } else if (op[0]->type->base_type == GLSL_TYPE_UINT && |
||
1451 | op[1]->type->base_type == GLSL_TYPE_UINT) { |
||
1452 | data.u[c] = op[0]->value.u[c0] >> op[1]->value.u[c1]; |
||
1453 | } |
||
1454 | } |
||
1455 | break; |
||
1456 | |||
1457 | case ir_binop_bit_and: |
||
1458 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1459 | c < components; |
||
1460 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1461 | |||
1462 | switch (op[0]->type->base_type) { |
||
1463 | case GLSL_TYPE_INT: |
||
1464 | data.i[c] = op[0]->value.i[c0] & op[1]->value.i[c1]; |
||
1465 | break; |
||
1466 | case GLSL_TYPE_UINT: |
||
1467 | data.u[c] = op[0]->value.u[c0] & op[1]->value.u[c1]; |
||
1468 | break; |
||
1469 | default: |
||
1470 | assert(0); |
||
1471 | } |
||
1472 | } |
||
1473 | break; |
||
1474 | |||
1475 | case ir_binop_bit_or: |
||
1476 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1477 | c < components; |
||
1478 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1479 | |||
1480 | switch (op[0]->type->base_type) { |
||
1481 | case GLSL_TYPE_INT: |
||
1482 | data.i[c] = op[0]->value.i[c0] | op[1]->value.i[c1]; |
||
1483 | break; |
||
1484 | case GLSL_TYPE_UINT: |
||
1485 | data.u[c] = op[0]->value.u[c0] | op[1]->value.u[c1]; |
||
1486 | break; |
||
1487 | default: |
||
1488 | assert(0); |
||
1489 | } |
||
1490 | } |
||
1491 | break; |
||
1492 | |||
1493 | case ir_binop_vector_extract: { |
||
1494 | const int c = CLAMP(op[1]->value.i[0], 0, |
||
1495 | (int) op[0]->type->vector_elements - 1); |
||
1496 | |||
1497 | switch (op[0]->type->base_type) { |
||
1498 | case GLSL_TYPE_UINT: |
||
1499 | data.u[0] = op[0]->value.u[c]; |
||
1500 | break; |
||
1501 | case GLSL_TYPE_INT: |
||
1502 | data.i[0] = op[0]->value.i[c]; |
||
1503 | break; |
||
1504 | case GLSL_TYPE_FLOAT: |
||
1505 | data.f[0] = op[0]->value.f[c]; |
||
1506 | break; |
||
1507 | case GLSL_TYPE_DOUBLE: |
||
1508 | data.d[0] = op[0]->value.d[c]; |
||
1509 | break; |
||
1510 | case GLSL_TYPE_BOOL: |
||
1511 | data.b[0] = op[0]->value.b[c]; |
||
1512 | break; |
||
1513 | default: |
||
1514 | assert(0); |
||
1515 | } |
||
1516 | break; |
||
1517 | } |
||
1518 | |||
1519 | case ir_binop_bit_xor: |
||
1520 | for (unsigned c = 0, c0 = 0, c1 = 0; |
||
1521 | c < components; |
||
1522 | c0 += c0_inc, c1 += c1_inc, c++) { |
||
1523 | |||
1524 | switch (op[0]->type->base_type) { |
||
1525 | case GLSL_TYPE_INT: |
||
1526 | data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1]; |
||
1527 | break; |
||
1528 | case GLSL_TYPE_UINT: |
||
1529 | data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1]; |
||
1530 | break; |
||
1531 | default: |
||
1532 | assert(0); |
||
1533 | } |
||
1534 | } |
||
1535 | break; |
||
1536 | |||
1537 | case ir_unop_bitfield_reverse: |
||
1538 | /* http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious */ |
||
1539 | for (unsigned c = 0; c < components; c++) { |
||
1540 | unsigned int v = op[0]->value.u[c]; // input bits to be reversed |
||
1541 | unsigned int r = v; // r will be reversed bits of v; first get LSB of v |
||
1542 | int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end |
||
1543 | |||
1544 | for (v >>= 1; v; v >>= 1) { |
||
1545 | r <<= 1; |
||
1546 | r |= v & 1; |
||
1547 | s--; |
||
1548 | } |
||
1549 | r <<= s; // shift when v's highest bits are zero |
||
1550 | |||
1551 | data.u[c] = r; |
||
1552 | } |
||
1553 | break; |
||
1554 | |||
1555 | case ir_unop_bit_count: |
||
1556 | for (unsigned c = 0; c < components; c++) { |
||
1557 | unsigned count = 0; |
||
1558 | unsigned v = op[0]->value.u[c]; |
||
1559 | |||
1560 | for (; v; count++) { |
||
1561 | v &= v - 1; |
||
1562 | } |
||
1563 | data.u[c] = count; |
||
1564 | } |
||
1565 | break; |
||
1566 | |||
1567 | case ir_unop_find_msb: |
||
1568 | for (unsigned c = 0; c < components; c++) { |
||
1569 | int v = op[0]->value.i[c]; |
||
1570 | |||
1571 | if (v == 0 || (op[0]->type->base_type == GLSL_TYPE_INT && v == -1)) |
||
1572 | data.i[c] = -1; |
||
1573 | else { |
||
1574 | int count = 0; |
||
1575 | int top_bit = op[0]->type->base_type == GLSL_TYPE_UINT |
||
1576 | ? 0 : v & (1 << 31); |
||
1577 | |||
1578 | while (((v & (1 << 31)) == top_bit) && count != 32) { |
||
1579 | count++; |
||
1580 | v <<= 1; |
||
1581 | } |
||
1582 | |||
1583 | data.i[c] = 31 - count; |
||
1584 | } |
||
1585 | } |
||
1586 | break; |
||
1587 | |||
1588 | case ir_unop_find_lsb: |
||
1589 | for (unsigned c = 0; c < components; c++) { |
||
1590 | if (op[0]->value.i[c] == 0) |
||
1591 | data.i[c] = -1; |
||
1592 | else { |
||
1593 | unsigned pos = 0; |
||
1594 | unsigned v = op[0]->value.u[c]; |
||
1595 | |||
1596 | for (; !(v & 1); v >>= 1) { |
||
1597 | pos++; |
||
1598 | } |
||
1599 | data.u[c] = pos; |
||
1600 | } |
||
1601 | } |
||
1602 | break; |
||
1603 | |||
1604 | case ir_unop_saturate: |
||
1605 | for (unsigned c = 0; c < components; c++) { |
||
1606 | data.f[c] = CLAMP(op[0]->value.f[c], 0.0f, 1.0f); |
||
1607 | } |
||
1608 | break; |
||
1609 | case ir_unop_pack_double_2x32: { |
||
1610 | /* XXX needs to be checked on big-endian */ |
||
1611 | uint64_t temp; |
||
1612 | temp = (uint64_t)op[0]->value.u[0] | ((uint64_t)op[0]->value.u[1] << 32); |
||
1613 | data.d[0] = *(double *)&temp; |
||
1614 | |||
1615 | break; |
||
1616 | } |
||
1617 | case ir_unop_unpack_double_2x32: |
||
1618 | /* XXX needs to be checked on big-endian */ |
||
1619 | data.u[0] = *(uint32_t *)&op[0]->value.d[0]; |
||
1620 | data.u[1] = *((uint32_t *)&op[0]->value.d[0] + 1); |
||
1621 | break; |
||
1622 | |||
1623 | case ir_triop_bitfield_extract: { |
||
1624 | int offset = op[1]->value.i[0]; |
||
1625 | int bits = op[2]->value.i[0]; |
||
1626 | |||
1627 | for (unsigned c = 0; c < components; c++) { |
||
1628 | if (bits == 0) |
||
1629 | data.u[c] = 0; |
||
1630 | else if (offset < 0 || bits < 0) |
||
1631 | data.u[c] = 0; /* Undefined, per spec. */ |
||
1632 | else if (offset + bits > 32) |
||
1633 | data.u[c] = 0; /* Undefined, per spec. */ |
||
1634 | else { |
||
1635 | if (op[0]->type->base_type == GLSL_TYPE_INT) { |
||
1636 | /* int so that the right shift will sign-extend. */ |
||
1637 | int value = op[0]->value.i[c]; |
||
1638 | value <<= 32 - bits - offset; |
||
1639 | value >>= 32 - bits; |
||
1640 | data.i[c] = value; |
||
1641 | } else { |
||
1642 | unsigned value = op[0]->value.u[c]; |
||
1643 | value <<= 32 - bits - offset; |
||
1644 | value >>= 32 - bits; |
||
1645 | data.u[c] = value; |
||
1646 | } |
||
1647 | } |
||
1648 | } |
||
1649 | break; |
||
1650 | } |
||
1651 | |||
1652 | case ir_binop_bfm: { |
||
1653 | int bits = op[0]->value.i[0]; |
||
1654 | int offset = op[1]->value.i[0]; |
||
1655 | |||
1656 | for (unsigned c = 0; c < components; c++) { |
||
1657 | if (bits == 0) |
||
1658 | data.u[c] = op[0]->value.u[c]; |
||
1659 | else if (offset < 0 || bits < 0) |
||
1660 | data.u[c] = 0; /* Undefined for bitfieldInsert, per spec. */ |
||
1661 | else if (offset + bits > 32) |
||
1662 | data.u[c] = 0; /* Undefined for bitfieldInsert, per spec. */ |
||
1663 | else |
||
1664 | data.u[c] = ((1 << bits) - 1) << offset; |
||
1665 | } |
||
1666 | break; |
||
1667 | } |
||
1668 | |||
1669 | case ir_binop_ldexp: |
||
1670 | for (unsigned c = 0; c < components; c++) { |
||
1671 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) { |
||
1672 | data.d[c] = ldexp(op[0]->value.d[c], op[1]->value.i[c]); |
||
1673 | /* Flush subnormal values to zero. */ |
||
1674 | if (!isnormal(data.d[c])) |
||
1675 | data.d[c] = copysign(0.0, op[0]->value.d[c]); |
||
1676 | } else { |
||
1677 | data.f[c] = ldexp(op[0]->value.f[c], op[1]->value.i[c]); |
||
1678 | /* Flush subnormal values to zero. */ |
||
1679 | if (!isnormal(data.f[c])) |
||
1680 | data.f[c] = copysign(0.0f, op[0]->value.f[c]); |
||
1681 | } |
||
1682 | } |
||
1683 | break; |
||
1684 | |||
1685 | case ir_triop_fma: |
||
1686 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT || |
||
1687 | op[0]->type->base_type == GLSL_TYPE_DOUBLE); |
||
1688 | assert(op[1]->type->base_type == GLSL_TYPE_FLOAT || |
||
1689 | op[1]->type->base_type == GLSL_TYPE_DOUBLE); |
||
1690 | assert(op[2]->type->base_type == GLSL_TYPE_FLOAT || |
||
1691 | op[2]->type->base_type == GLSL_TYPE_DOUBLE); |
||
1692 | |||
1693 | for (unsigned c = 0; c < components; c++) { |
||
1694 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) |
||
1695 | data.d[c] = op[0]->value.d[c] * op[1]->value.d[c] |
||
1696 | + op[2]->value.d[c]; |
||
1697 | else |
||
1698 | data.f[c] = op[0]->value.f[c] * op[1]->value.f[c] |
||
1699 | + op[2]->value.f[c]; |
||
1700 | } |
||
1701 | break; |
||
1702 | |||
1703 | case ir_triop_lrp: { |
||
1704 | assert(op[0]->type->base_type == GLSL_TYPE_FLOAT || |
||
1705 | op[0]->type->base_type == GLSL_TYPE_DOUBLE); |
||
1706 | assert(op[1]->type->base_type == GLSL_TYPE_FLOAT || |
||
1707 | op[1]->type->base_type == GLSL_TYPE_DOUBLE); |
||
1708 | assert(op[2]->type->base_type == GLSL_TYPE_FLOAT || |
||
1709 | op[2]->type->base_type == GLSL_TYPE_DOUBLE); |
||
1710 | |||
1711 | unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; |
||
1712 | for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) { |
||
1713 | if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) |
||
1714 | data.d[c] = op[0]->value.d[c] * (1.0 - op[2]->value.d[c2]) + |
||
1715 | (op[1]->value.d[c] * op[2]->value.d[c2]); |
||
1716 | else |
||
1717 | data.f[c] = op[0]->value.f[c] * (1.0f - op[2]->value.f[c2]) + |
||
1718 | (op[1]->value.f[c] * op[2]->value.f[c2]); |
||
1719 | } |
||
1720 | break; |
||
1721 | } |
||
1722 | |||
1723 | case ir_triop_csel: |
||
1724 | for (unsigned c = 0; c < components; c++) { |
||
1725 | if (op[1]->type->base_type == GLSL_TYPE_DOUBLE) |
||
1726 | data.d[c] = op[0]->value.b[c] ? op[1]->value.d[c] |
||
1727 | : op[2]->value.d[c]; |
||
1728 | else |
||
1729 | data.u[c] = op[0]->value.b[c] ? op[1]->value.u[c] |
||
1730 | : op[2]->value.u[c]; |
||
1731 | } |
||
1732 | break; |
||
1733 | |||
1734 | case ir_triop_vector_insert: { |
||
1735 | const unsigned idx = op[2]->value.u[0]; |
||
1736 | |||
1737 | memcpy(&data, &op[0]->value, sizeof(data)); |
||
1738 | |||
1739 | switch (this->type->base_type) { |
||
1740 | case GLSL_TYPE_INT: |
||
1741 | data.i[idx] = op[1]->value.i[0]; |
||
1742 | break; |
||
1743 | case GLSL_TYPE_UINT: |
||
1744 | data.u[idx] = op[1]->value.u[0]; |
||
1745 | break; |
||
1746 | case GLSL_TYPE_FLOAT: |
||
1747 | data.f[idx] = op[1]->value.f[0]; |
||
1748 | break; |
||
1749 | case GLSL_TYPE_BOOL: |
||
1750 | data.b[idx] = op[1]->value.b[0]; |
||
1751 | break; |
||
1752 | case GLSL_TYPE_DOUBLE: |
||
1753 | data.d[idx] = op[1]->value.d[0]; |
||
1754 | break; |
||
1755 | default: |
||
1756 | assert(!"Should not get here."); |
||
1757 | break; |
||
1758 | } |
||
1759 | break; |
||
1760 | } |
||
1761 | |||
1762 | case ir_quadop_bitfield_insert: { |
||
1763 | int offset = op[2]->value.i[0]; |
||
1764 | int bits = op[3]->value.i[0]; |
||
1765 | |||
1766 | for (unsigned c = 0; c < components; c++) { |
||
1767 | if (bits == 0) |
||
1768 | data.u[c] = op[0]->value.u[c]; |
||
1769 | else if (offset < 0 || bits < 0) |
||
1770 | data.u[c] = 0; /* Undefined, per spec. */ |
||
1771 | else if (offset + bits > 32) |
||
1772 | data.u[c] = 0; /* Undefined, per spec. */ |
||
1773 | else { |
||
1774 | unsigned insert_mask = ((1 << bits) - 1) << offset; |
||
1775 | |||
1776 | unsigned insert = op[1]->value.u[c]; |
||
1777 | insert <<= offset; |
||
1778 | insert &= insert_mask; |
||
1779 | |||
1780 | unsigned base = op[0]->value.u[c]; |
||
1781 | base &= ~insert_mask; |
||
1782 | |||
1783 | data.u[c] = base | insert; |
||
1784 | } |
||
1785 | } |
||
1786 | break; |
||
1787 | } |
||
1788 | |||
1789 | case ir_quadop_vector: |
||
1790 | for (unsigned c = 0; c < this->type->vector_elements; c++) { |
||
1791 | switch (this->type->base_type) { |
||
1792 | case GLSL_TYPE_INT: |
||
1793 | data.i[c] = op[c]->value.i[0]; |
||
1794 | break; |
||
1795 | case GLSL_TYPE_UINT: |
||
1796 | data.u[c] = op[c]->value.u[0]; |
||
1797 | break; |
||
1798 | case GLSL_TYPE_FLOAT: |
||
1799 | data.f[c] = op[c]->value.f[0]; |
||
1800 | break; |
||
1801 | case GLSL_TYPE_DOUBLE: |
||
1802 | data.d[c] = op[c]->value.d[0]; |
||
1803 | break; |
||
1804 | default: |
||
1805 | assert(0); |
||
1806 | } |
||
1807 | } |
||
1808 | break; |
||
1809 | |||
1810 | default: |
||
1811 | /* FINISHME: Should handle all expression types. */ |
||
1812 | return NULL; |
||
1813 | } |
||
1814 | |||
1815 | return new(ctx) ir_constant(this->type, &data); |
||
1816 | } |
||
1817 | |||
1818 | |||
1819 | ir_constant * |
||
1820 | ir_texture::constant_expression_value(struct hash_table *) |
||
1821 | { |
||
1822 | /* texture lookups aren't constant expressions */ |
||
1823 | return NULL; |
||
1824 | } |
||
1825 | |||
1826 | |||
1827 | ir_constant * |
||
1828 | ir_swizzle::constant_expression_value(struct hash_table *variable_context) |
||
1829 | { |
||
1830 | ir_constant *v = this->val->constant_expression_value(variable_context); |
||
1831 | |||
1832 | if (v != NULL) { |
||
1833 | ir_constant_data data = { { 0 } }; |
||
1834 | |||
1835 | const unsigned swiz_idx[4] = { |
||
1836 | this->mask.x, this->mask.y, this->mask.z, this->mask.w |
||
1837 | }; |
||
1838 | |||
1839 | for (unsigned i = 0; i < this->mask.num_components; i++) { |
||
1840 | switch (v->type->base_type) { |
||
1841 | case GLSL_TYPE_UINT: |
||
1842 | case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break; |
||
1843 | case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break; |
||
1844 | case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break; |
||
1845 | case GLSL_TYPE_DOUBLE:data.d[i] = v->value.d[swiz_idx[i]]; break; |
||
1846 | default: assert(!"Should not get here."); break; |
||
1847 | } |
||
1848 | } |
||
1849 | |||
1850 | void *ctx = ralloc_parent(this); |
||
1851 | return new(ctx) ir_constant(this->type, &data); |
||
1852 | } |
||
1853 | return NULL; |
||
1854 | } |
||
1855 | |||
1856 | |||
1857 | ir_constant * |
||
1858 | ir_dereference_variable::constant_expression_value(struct hash_table *variable_context) |
||
1859 | { |
||
1860 | /* This may occur during compile and var->type is glsl_type::error_type */ |
||
1861 | if (!var) |
||
1862 | return NULL; |
||
1863 | |||
1864 | /* Give priority to the context hashtable, if it exists */ |
||
1865 | if (variable_context) { |
||
1866 | ir_constant *value = (ir_constant *)hash_table_find(variable_context, var); |
||
1867 | if(value) |
||
1868 | return value; |
||
1869 | } |
||
1870 | |||
1871 | /* The constant_value of a uniform variable is its initializer, |
||
1872 | * not the lifetime constant value of the uniform. |
||
1873 | */ |
||
1874 | if (var->data.mode == ir_var_uniform) |
||
1875 | return NULL; |
||
1876 | |||
1877 | if (!var->constant_value) |
||
1878 | return NULL; |
||
1879 | |||
1880 | return var->constant_value->clone(ralloc_parent(var), NULL); |
||
1881 | } |
||
1882 | |||
1883 | |||
1884 | ir_constant * |
||
1885 | ir_dereference_array::constant_expression_value(struct hash_table *variable_context) |
||
1886 | { |
||
1887 | ir_constant *array = this->array->constant_expression_value(variable_context); |
||
1888 | ir_constant *idx = this->array_index->constant_expression_value(variable_context); |
||
1889 | |||
1890 | if ((array != NULL) && (idx != NULL)) { |
||
1891 | void *ctx = ralloc_parent(this); |
||
1892 | if (array->type->is_matrix()) { |
||
1893 | /* Array access of a matrix results in a vector. |
||
1894 | */ |
||
1895 | const unsigned column = idx->value.u[0]; |
||
1896 | |||
1897 | const glsl_type *const column_type = array->type->column_type(); |
||
1898 | |||
1899 | /* Offset in the constant matrix to the first element of the column |
||
1900 | * to be extracted. |
||
1901 | */ |
||
1902 | const unsigned mat_idx = column * column_type->vector_elements; |
||
1903 | |||
1904 | ir_constant_data data = { { 0 } }; |
||
1905 | |||
1906 | switch (column_type->base_type) { |
||
1907 | case GLSL_TYPE_UINT: |
||
1908 | case GLSL_TYPE_INT: |
||
1909 | for (unsigned i = 0; i < column_type->vector_elements; i++) |
||
1910 | data.u[i] = array->value.u[mat_idx + i]; |
||
1911 | |||
1912 | break; |
||
1913 | |||
1914 | case GLSL_TYPE_FLOAT: |
||
1915 | for (unsigned i = 0; i < column_type->vector_elements; i++) |
||
1916 | data.f[i] = array->value.f[mat_idx + i]; |
||
1917 | |||
1918 | break; |
||
1919 | |||
1920 | case GLSL_TYPE_DOUBLE: |
||
1921 | for (unsigned i = 0; i < column_type->vector_elements; i++) |
||
1922 | data.d[i] = array->value.d[mat_idx + i]; |
||
1923 | |||
1924 | break; |
||
1925 | |||
1926 | default: |
||
1927 | assert(!"Should not get here."); |
||
1928 | break; |
||
1929 | } |
||
1930 | |||
1931 | return new(ctx) ir_constant(column_type, &data); |
||
1932 | } else if (array->type->is_vector()) { |
||
1933 | const unsigned component = idx->value.u[0]; |
||
1934 | |||
1935 | return new(ctx) ir_constant(array, component); |
||
1936 | } else { |
||
1937 | const unsigned index = idx->value.u[0]; |
||
1938 | return array->get_array_element(index)->clone(ctx, NULL); |
||
1939 | } |
||
1940 | } |
||
1941 | return NULL; |
||
1942 | } |
||
1943 | |||
1944 | |||
1945 | ir_constant * |
||
1946 | ir_dereference_record::constant_expression_value(struct hash_table *) |
||
1947 | { |
||
1948 | ir_constant *v = this->record->constant_expression_value(); |
||
1949 | |||
1950 | return (v != NULL) ? v->get_record_field(this->field) : NULL; |
||
1951 | } |
||
1952 | |||
1953 | |||
1954 | ir_constant * |
||
1955 | ir_assignment::constant_expression_value(struct hash_table *) |
||
1956 | { |
||
1957 | /* FINISHME: Handle CEs involving assignment (return RHS) */ |
||
1958 | return NULL; |
||
1959 | } |
||
1960 | |||
1961 | |||
1962 | ir_constant * |
||
1963 | ir_constant::constant_expression_value(struct hash_table *) |
||
1964 | { |
||
1965 | return this; |
||
1966 | } |
||
1967 | |||
1968 | |||
1969 | ir_constant * |
||
1970 | ir_call::constant_expression_value(struct hash_table *variable_context) |
||
1971 | { |
||
1972 | return this->callee->constant_expression_value(&this->actual_parameters, variable_context); |
||
1973 | } |
||
1974 | |||
1975 | |||
1976 | bool ir_function_signature::constant_expression_evaluate_expression_list(const struct exec_list &body, |
||
1977 | struct hash_table *variable_context, |
||
1978 | ir_constant **result) |
||
1979 | { |
||
1980 | foreach_in_list(ir_instruction, inst, &body) { |
||
1981 | switch(inst->ir_type) { |
||
1982 | |||
1983 | /* (declare () type symbol) */ |
||
1984 | case ir_type_variable: { |
||
1985 | ir_variable *var = inst->as_variable(); |
||
1986 | hash_table_insert(variable_context, ir_constant::zero(this, var->type), var); |
||
1987 | break; |
||
1988 | } |
||
1989 | |||
1990 | /* (assign [condition] (write-mask) (ref) (value)) */ |
||
1991 | case ir_type_assignment: { |
||
1992 | ir_assignment *asg = inst->as_assignment(); |
||
1993 | if (asg->condition) { |
||
1994 | ir_constant *cond = asg->condition->constant_expression_value(variable_context); |
||
1995 | if (!cond) |
||
1996 | return false; |
||
1997 | if (!cond->get_bool_component(0)) |
||
1998 | break; |
||
1999 | } |
||
2000 | |||
2001 | ir_constant *store = NULL; |
||
2002 | int offset = 0; |
||
2003 | |||
2004 | if (!constant_referenced(asg->lhs, variable_context, store, offset)) |
||
2005 | return false; |
||
2006 | |||
2007 | ir_constant *value = asg->rhs->constant_expression_value(variable_context); |
||
2008 | |||
2009 | if (!value) |
||
2010 | return false; |
||
2011 | |||
2012 | store->copy_masked_offset(value, offset, asg->write_mask); |
||
2013 | break; |
||
2014 | } |
||
2015 | |||
2016 | /* (return (expression)) */ |
||
2017 | case ir_type_return: |
||
2018 | assert (result); |
||
2019 | *result = inst->as_return()->value->constant_expression_value(variable_context); |
||
2020 | return *result != NULL; |
||
2021 | |||
2022 | /* (call name (ref) (params))*/ |
||
2023 | case ir_type_call: { |
||
2024 | ir_call *call = inst->as_call(); |
||
2025 | |||
2026 | /* Just say no to void functions in constant expressions. We |
||
2027 | * don't need them at that point. |
||
2028 | */ |
||
2029 | |||
2030 | if (!call->return_deref) |
||
2031 | return false; |
||
2032 | |||
2033 | ir_constant *store = NULL; |
||
2034 | int offset = 0; |
||
2035 | |||
2036 | if (!constant_referenced(call->return_deref, variable_context, |
||
2037 | store, offset)) |
||
2038 | return false; |
||
2039 | |||
2040 | ir_constant *value = call->constant_expression_value(variable_context); |
||
2041 | |||
2042 | if(!value) |
||
2043 | return false; |
||
2044 | |||
2045 | store->copy_offset(value, offset); |
||
2046 | break; |
||
2047 | } |
||
2048 | |||
2049 | /* (if condition (then-instructions) (else-instructions)) */ |
||
2050 | case ir_type_if: { |
||
2051 | ir_if *iif = inst->as_if(); |
||
2052 | |||
2053 | ir_constant *cond = iif->condition->constant_expression_value(variable_context); |
||
2054 | if (!cond || !cond->type->is_boolean()) |
||
2055 | return false; |
||
2056 | |||
2057 | exec_list &branch = cond->get_bool_component(0) ? iif->then_instructions : iif->else_instructions; |
||
2058 | |||
2059 | *result = NULL; |
||
2060 | if (!constant_expression_evaluate_expression_list(branch, variable_context, result)) |
||
2061 | return false; |
||
2062 | |||
2063 | /* If there was a return in the branch chosen, drop out now. */ |
||
2064 | if (*result) |
||
2065 | return true; |
||
2066 | |||
2067 | break; |
||
2068 | } |
||
2069 | |||
2070 | /* Every other expression type, we drop out. */ |
||
2071 | default: |
||
2072 | return false; |
||
2073 | } |
||
2074 | } |
||
2075 | |||
2076 | /* Reaching the end of the block is not an error condition */ |
||
2077 | if (result) |
||
2078 | *result = NULL; |
||
2079 | |||
2080 | return true; |
||
2081 | } |
||
2082 | |||
2083 | ir_constant * |
||
2084 | ir_function_signature::constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context) |
||
2085 | { |
||
2086 | const glsl_type *type = this->return_type; |
||
2087 | if (type == glsl_type::void_type) |
||
2088 | return NULL; |
||
2089 | |||
2090 | /* From the GLSL 1.20 spec, page 23: |
||
2091 | * "Function calls to user-defined functions (non-built-in functions) |
||
2092 | * cannot be used to form constant expressions." |
||
2093 | */ |
||
2094 | if (!this->is_builtin()) |
||
2095 | return NULL; |
||
2096 | |||
2097 | /* |
||
2098 | * Of the builtin functions, only the texture lookups and the noise |
||
2099 | * ones must not be used in constant expressions. They all include |
||
2100 | * specific opcodes so they don't need to be special-cased at this |
||
2101 | * point. |
||
2102 | */ |
||
2103 | |||
2104 | /* Initialize the table of dereferencable names with the function |
||
2105 | * parameters. Verify their const-ness on the way. |
||
2106 | * |
||
2107 | * We expect the correctness of the number of parameters to have |
||
2108 | * been checked earlier. |
||
2109 | */ |
||
2110 | hash_table *deref_hash = hash_table_ctor(8, hash_table_pointer_hash, |
||
2111 | hash_table_pointer_compare); |
||
2112 | |||
2113 | /* If "origin" is non-NULL, then the function body is there. So we |
||
2114 | * have to use the variable objects from the object with the body, |
||
2115 | * but the parameter instanciation on the current object. |
||
2116 | */ |
||
2117 | const exec_node *parameter_info = origin ? origin->parameters.head : parameters.head; |
||
2118 | |||
2119 | foreach_in_list(ir_rvalue, n, actual_parameters) { |
||
2120 | ir_constant *constant = n->constant_expression_value(variable_context); |
||
2121 | if (constant == NULL) { |
||
2122 | hash_table_dtor(deref_hash); |
||
2123 | return NULL; |
||
2124 | } |
||
2125 | |||
2126 | |||
2127 | ir_variable *var = (ir_variable *)parameter_info; |
||
2128 | hash_table_insert(deref_hash, constant, var); |
||
2129 | |||
2130 | parameter_info = parameter_info->next; |
||
2131 | } |
||
2132 | |||
2133 | ir_constant *result = NULL; |
||
2134 | |||
2135 | /* Now run the builtin function until something non-constant |
||
2136 | * happens or we get the result. |
||
2137 | */ |
||
2138 | if (constant_expression_evaluate_expression_list(origin ? origin->body : body, deref_hash, &result) && result) |
||
2139 | result = result->clone(ralloc_parent(this), NULL); |
||
2140 | |||
2141 | hash_table_dtor(deref_hash); |
||
2142 | |||
2143 | return result; |
||
2144 | }>>>>>=><=>><>><>>>>>>>>><>><>>>>=><=>=><=>>>>><>>>=><=>><>><>>>=><=>=><=>>>>>>><>><>><>><>>>>>=>=>=>=>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><>><>><>><>><>><>>>> |