Construct an ir_constant from a scalar component of another ir_constant
[mesa.git] / ir.cpp
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 #include <string.h>
24 #include "main/imports.h"
25 #include "ir.h"
26 #include "ir_visitor.h"
27 #include "glsl_types.h"
28
29 ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
30 ir_rvalue *condition)
31 {
32 this->lhs = lhs;
33 this->rhs = rhs;
34 this->condition = condition;
35 }
36
37
38 ir_expression::ir_expression(int op, const struct glsl_type *type,
39 ir_rvalue *op0, ir_rvalue *op1)
40 {
41 this->type = type;
42 this->operation = ir_expression_operation(op);
43 this->operands[0] = op0;
44 this->operands[1] = op1;
45 }
46
47 unsigned int
48 ir_expression::get_num_operands(ir_expression_operation op)
49 {
50 /* Update ir_print_visitor.cpp when updating this list. */
51 const int num_operands[] = {
52 1, /* ir_unop_bit_not */
53 1, /* ir_unop_logic_not */
54 1, /* ir_unop_neg */
55 1, /* ir_unop_abs */
56 1, /* ir_unop_sign */
57 1, /* ir_unop_rcp */
58 1, /* ir_unop_rsq */
59 1, /* ir_unop_sqrt */
60 1, /* ir_unop_exp */
61 1, /* ir_unop_log */
62 1, /* ir_unop_exp2 */
63 1, /* ir_unop_log2 */
64 1, /* ir_unop_f2i */
65 1, /* ir_unop_i2f */
66 1, /* ir_unop_f2b */
67 1, /* ir_unop_b2f */
68 1, /* ir_unop_i2b */
69 1, /* ir_unop_b2i */
70 1, /* ir_unop_u2f */
71
72 1, /* ir_unop_trunc */
73 1, /* ir_unop_ceil */
74 1, /* ir_unop_floor */
75
76 1, /* ir_unop_sin */
77 1, /* ir_unop_cos */
78
79 1, /* ir_unop_dFdx */
80 1, /* ir_unop_dFdy */
81
82 2, /* ir_binop_add */
83 2, /* ir_binop_sub */
84 2, /* ir_binop_mul */
85 2, /* ir_binop_div */
86 2, /* ir_binop_mod */
87
88 2, /* ir_binop_less */
89 2, /* ir_binop_greater */
90 2, /* ir_binop_lequal */
91 2, /* ir_binop_gequal */
92 2, /* ir_binop_equal */
93 2, /* ir_binop_nequal */
94
95 2, /* ir_binop_lshift */
96 2, /* ir_binop_rshift */
97 2, /* ir_binop_bit_and */
98 2, /* ir_binop_bit_xor */
99 2, /* ir_binop_bit_or */
100
101 2, /* ir_binop_logic_and */
102 2, /* ir_binop_logic_xor */
103 2, /* ir_binop_logic_or */
104
105 2, /* ir_binop_dot */
106 2, /* ir_binop_min */
107 2, /* ir_binop_max */
108
109 2, /* ir_binop_pow */
110 };
111
112 assert(sizeof(num_operands) / sizeof(num_operands[0]) == ir_binop_pow + 1);
113
114 return num_operands[op];
115 }
116
117 static const char *const operator_strs[] = {
118 "~",
119 "!",
120 "neg",
121 "abs",
122 "sign",
123 "rcp",
124 "rsq",
125 "sqrt",
126 "exp",
127 "log",
128 "exp2",
129 "log2",
130 "f2i",
131 "i2f",
132 "f2b",
133 "b2f",
134 "i2b",
135 "b2i",
136 "u2f",
137 "trunc",
138 "ceil",
139 "floor",
140 "sin",
141 "cos",
142 "dFdx",
143 "dFdy",
144 "+",
145 "-",
146 "*",
147 "/",
148 "%",
149 "<",
150 ">",
151 "<=",
152 ">=",
153 "==",
154 "!=",
155 "<<",
156 ">>",
157 "&",
158 "^",
159 "|",
160 "&&",
161 "^^",
162 "||",
163 "dot",
164 "min",
165 "max",
166 "pow",
167 };
168
169 const char *ir_expression::operator_string()
170 {
171 assert((unsigned int) operation <=
172 sizeof(operator_strs) / sizeof(operator_strs[0]));
173 return operator_strs[operation];
174 }
175
176 ir_expression_operation
177 ir_expression::get_operator(const char *str)
178 {
179 const int operator_count = sizeof(operator_strs) / sizeof(operator_strs[0]);
180 for (int op = 0; op < operator_count; op++) {
181 if (strcmp(str, operator_strs[op]) == 0)
182 return (ir_expression_operation) op;
183 }
184 return (ir_expression_operation) -1;
185 }
186
187 ir_constant::ir_constant(const struct glsl_type *type, const void *data)
188 {
189 unsigned size = 0;
190
191 this->type = type;
192 switch (type->base_type) {
193 case GLSL_TYPE_UINT: size = sizeof(this->value.u[0]); break;
194 case GLSL_TYPE_INT: size = sizeof(this->value.i[0]); break;
195 case GLSL_TYPE_FLOAT: size = sizeof(this->value.f[0]); break;
196 case GLSL_TYPE_BOOL: size = sizeof(this->value.b[0]); break;
197 default:
198 /* FINISHME: What to do? Exceptions are not the answer.
199 */
200 break;
201 }
202
203 memcpy(& this->value, data, size * type->components());
204 }
205
206 ir_constant::ir_constant(float f)
207 {
208 this->type = glsl_type::float_type;
209 this->value.f[0] = f;
210 }
211
212 ir_constant::ir_constant(unsigned int u)
213 {
214 this->type = glsl_type::uint_type;
215 this->value.u[0] = u;
216 }
217
218 ir_constant::ir_constant(int i)
219 {
220 this->type = glsl_type::int_type;
221 this->value.i[0] = i;
222 }
223
224 ir_constant::ir_constant(bool b)
225 {
226 this->type = glsl_type::bool_type;
227 this->value.b[0] = b;
228 }
229
230 ir_constant::ir_constant(const ir_constant *c, unsigned i)
231 {
232 this->type = c->type->get_base_type();
233
234 switch (this->type->base_type) {
235 case GLSL_TYPE_UINT: this->value.u[0] = c->value.u[i]; break;
236 case GLSL_TYPE_INT: this->value.i[0] = c->value.i[i]; break;
237 case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
238 case GLSL_TYPE_BOOL: this->value.b[0] = c->value.b[i]; break;
239 default: assert(!"Should not get here."); break;
240 }
241 }
242
243
244 ir_dereference_variable::ir_dereference_variable(ir_variable *var)
245 {
246 this->var = var;
247 this->type = (var != NULL) ? var->type : glsl_type::error_type;
248 }
249
250
251 ir_dereference_array::ir_dereference_array(ir_rvalue *value,
252 ir_rvalue *array_index)
253 {
254 this->array_index = array_index;
255 this->set_array(value);
256 }
257
258
259 ir_dereference_array::ir_dereference_array(ir_variable *var,
260 ir_rvalue *array_index)
261 {
262 this->array_index = array_index;
263 this->set_array(new ir_dereference_variable(var));
264 }
265
266
267 void
268 ir_dereference_array::set_array(ir_rvalue *value)
269 {
270 this->array = value;
271 this->type = glsl_type::error_type;
272
273 if (this->array != NULL) {
274 const glsl_type *const vt = this->array->type;
275
276 if (vt->is_array()) {
277 type = vt->element_type();
278 } else if (vt->is_matrix()) {
279 type = vt->column_type();
280 } else if (vt->is_vector()) {
281 type = vt->get_base_type();
282 }
283 }
284 }
285
286
287 ir_dereference_record::ir_dereference_record(ir_rvalue *value,
288 const char *field)
289 {
290 this->record = value;
291 this->field = field;
292 this->type = (this->record != NULL)
293 ? this->record->type->field_type(field) : glsl_type::error_type;
294 }
295
296
297 ir_dereference_record::ir_dereference_record(ir_variable *var,
298 const char *field)
299 {
300 this->record = new ir_dereference_variable(var);
301 this->field = field;
302 this->type = (this->record != NULL)
303 ? this->record->type->field_type(field) : glsl_type::error_type;
304 }
305
306
307 bool
308 ir_dereference::is_lvalue()
309 {
310 ir_variable *var = this->variable_referenced();
311
312 /* Every l-value derference chain eventually ends in a variable.
313 */
314 if ((var == NULL) || var->read_only)
315 return false;
316
317 if (this->type->is_array() && !var->array_lvalue)
318 return false;
319
320 return true;
321 }
322
323
324 const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf" };
325
326 const char *ir_texture::opcode_string()
327 {
328 assert((unsigned int) op <=
329 sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]));
330 return tex_opcode_strs[op];
331 }
332
333 ir_texture_opcode
334 ir_texture::get_opcode(const char *str)
335 {
336 const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]);
337 for (int op = 0; op < count; op++) {
338 if (strcmp(str, tex_opcode_strs[op]) == 0)
339 return (ir_texture_opcode) op;
340 }
341 return (ir_texture_opcode) -1;
342 }
343
344
345 void
346 ir_texture::set_sampler(ir_dereference *sampler)
347 {
348 assert(sampler != NULL);
349 this->sampler = sampler;
350
351 switch (sampler->type->sampler_type) {
352 case GLSL_TYPE_FLOAT:
353 this->type = glsl_type::vec4_type;
354 break;
355 case GLSL_TYPE_INT:
356 this->type = glsl_type::ivec4_type;
357 break;
358 case GLSL_TYPE_UINT:
359 this->type = glsl_type::uvec4_type;
360 break;
361 }
362 }
363
364
365 ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
366 unsigned w, unsigned count)
367 : val(val)
368 {
369 assert((count >= 1) && (count <= 4));
370
371 const unsigned dup_mask = 0
372 | ((count > 1) ? ((1U << y) & ((1U << x) )) : 0)
373 | ((count > 2) ? ((1U << z) & ((1U << x) | (1U << y) )) : 0)
374 | ((count > 3) ? ((1U << w) & ((1U << x) | (1U << y) | (1U << z))) : 0);
375
376 assert(x <= 3);
377 assert(y <= 3);
378 assert(z <= 3);
379 assert(w <= 3);
380
381 mask.x = x;
382 mask.y = y;
383 mask.z = z;
384 mask.w = w;
385 mask.num_components = count;
386 mask.has_duplicates = dup_mask != 0;
387
388 /* Based on the number of elements in the swizzle and the base type
389 * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
390 * generate the type of the resulting value.
391 */
392 type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
393 }
394
395 ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
396 {
397 this->val = val;
398 this->mask = mask;
399 this->type = glsl_type::get_instance(val->type->base_type,
400 mask.num_components, 1);
401 }
402
403 #define X 1
404 #define R 5
405 #define S 9
406 #define I 13
407
408 ir_swizzle *
409 ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
410 {
411 /* For each possible swizzle character, this table encodes the value in
412 * \c idx_map that represents the 0th element of the vector. For invalid
413 * swizzle characters (e.g., 'k'), a special value is used that will allow
414 * detection of errors.
415 */
416 static const unsigned char base_idx[26] = {
417 /* a b c d e f g h i j k l m */
418 R, R, I, I, I, I, R, I, I, I, I, I, I,
419 /* n o p q r s t u v w x y z */
420 I, I, S, S, R, S, S, I, I, X, X, X, X
421 };
422
423 /* Each valid swizzle character has an entry in the previous table. This
424 * table encodes the base index encoded in the previous table plus the actual
425 * index of the swizzle character. When processing swizzles, the first
426 * character in the string is indexed in the previous table. Each character
427 * in the string is indexed in this table, and the value found there has the
428 * value form the first table subtracted. The result must be on the range
429 * [0,3].
430 *
431 * For example, the string "wzyx" will get X from the first table. Each of
432 * the charcaters will get X+3, X+2, X+1, and X+0 from this table. After
433 * subtraction, the swizzle values are { 3, 2, 1, 0 }.
434 *
435 * The string "wzrg" will get X from the first table. Each of the characters
436 * will get X+3, X+2, R+0, and R+1 from this table. After subtraction, the
437 * swizzle values are { 3, 2, 4, 5 }. Since 4 and 5 are outside the range
438 * [0,3], the error is detected.
439 */
440 static const unsigned char idx_map[26] = {
441 /* a b c d e f g h i j k l m */
442 R+3, R+2, 0, 0, 0, 0, R+1, 0, 0, 0, 0, 0, 0,
443 /* n o p q r s t u v w x y z */
444 0, 0, S+2, S+3, R+0, S+0, S+1, 0, 0, X+3, X+0, X+1, X+2
445 };
446
447 int swiz_idx[4] = { 0, 0, 0, 0 };
448 unsigned i;
449
450
451 /* Validate the first character in the swizzle string and look up the base
452 * index value as described above.
453 */
454 if ((str[0] < 'a') || (str[0] > 'z'))
455 return NULL;
456
457 const unsigned base = base_idx[str[0] - 'a'];
458
459
460 for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
461 /* Validate the next character, and, as described above, convert it to a
462 * swizzle index.
463 */
464 if ((str[i] < 'a') || (str[i] > 'z'))
465 return NULL;
466
467 swiz_idx[i] = idx_map[str[i] - 'a'] - base;
468 if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
469 return NULL;
470 }
471
472 if (str[i] != '\0')
473 return NULL;
474
475 return new ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
476 swiz_idx[3], i);
477 }
478
479 #undef X
480 #undef R
481 #undef S
482 #undef I
483
484 ir_variable *
485 ir_swizzle::variable_referenced()
486 {
487 return this->val->variable_referenced();
488 }
489
490 ir_variable::ir_variable(const struct glsl_type *type, const char *name)
491 : max_array_access(0), read_only(false), centroid(false), invariant(false),
492 mode(ir_var_auto), interpolation(ir_var_smooth)
493 {
494 this->type = type;
495 this->name = name;
496 this->constant_value = NULL;
497
498 if (type && type->base_type == GLSL_TYPE_SAMPLER)
499 this->read_only = true;
500 }
501
502
503 ir_function_signature::ir_function_signature(const glsl_type *return_type)
504 : return_type(return_type), is_defined(false)
505 {
506 /* empty */
507 }
508
509
510 const char *
511 ir_function_signature::qualifiers_match(exec_list *params)
512 {
513 exec_list_iterator iter_a = parameters.iterator();
514 exec_list_iterator iter_b = params->iterator();
515
516 /* check that the qualifiers match. */
517 while (iter_a.has_next()) {
518 ir_variable *a = (ir_variable *)iter_a.get();
519 ir_variable *b = (ir_variable *)iter_b.get();
520
521 if (a->read_only != b->read_only ||
522 a->mode != b->mode ||
523 a->interpolation != b->interpolation ||
524 a->centroid != b->centroid) {
525
526 /* parameter a's qualifiers don't match */
527 return a->name;
528 }
529
530 iter_a.next();
531 iter_b.next();
532 }
533 return NULL;
534 }
535
536
537 void
538 ir_function_signature::replace_parameters(exec_list *new_params)
539 {
540 /* Destroy all of the previous parameter information. If the previous
541 * parameter information comes from the function prototype, it may either
542 * specify incorrect parameter names or not have names at all.
543 */
544 foreach_iter(exec_list_iterator, iter, parameters) {
545 assert(((ir_instruction *) iter.get())->as_variable() != NULL);
546
547 iter.remove();
548 delete (ir_instruction*) iter.get();
549 }
550
551 new_params->move_nodes_to(&parameters);
552 }
553
554
555 ir_function::ir_function(const char *name)
556 : name(name)
557 {
558 /* empty */
559 }
560
561
562 ir_call *
563 ir_call::get_error_instruction()
564 {
565 ir_call *call = new ir_call;
566
567 call->type = glsl_type::error_type;
568 return call;
569 }
570
571 void
572 visit_exec_list(exec_list *list, ir_visitor *visitor)
573 {
574 foreach_iter(exec_list_iterator, iter, *list) {
575 ((ir_instruction *)iter.get())->accept(visitor);
576 }
577 }
578