ir.cpp revision bfd7c9ac228c7ed8aec04c3b3aa33f40ee00b035
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/core.h" /* for MAX2 */
25#include "ir.h"
26#include "ir_visitor.h"
27#include "glsl_types.h"
28
29ir_rvalue::ir_rvalue()
30{
31   this->type = glsl_type::error_type;
32}
33
34/**
35 * Modify the swizzle make to move one component to another
36 *
37 * \param m    IR swizzle to be modified
38 * \param from Component in the RHS that is to be swizzled
39 * \param to   Desired swizzle location of \c from
40 */
41static void
42update_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to)
43{
44   switch (to) {
45   case 0: m.x = from; break;
46   case 1: m.y = from; break;
47   case 2: m.z = from; break;
48   case 3: m.w = from; break;
49   default: assert(!"Should not get here.");
50   }
51
52   m.num_components = MAX2(m.num_components, (to + 1));
53}
54
55void
56ir_assignment::set_lhs(ir_rvalue *lhs)
57{
58   while (lhs != NULL) {
59      ir_swizzle *swiz = lhs->as_swizzle();
60
61      if (swiz == NULL)
62	 break;
63
64      unsigned write_mask = 0;
65      ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
66
67      for (unsigned i = 0; i < swiz->mask.num_components; i++) {
68	 unsigned c = 0;
69
70	 switch (i) {
71	 case 0: c = swiz->mask.x; break;
72	 case 1: c = swiz->mask.y; break;
73	 case 2: c = swiz->mask.z; break;
74	 case 3: c = swiz->mask.w; break;
75	 default: assert(!"Should not get here.");
76	 }
77
78	 write_mask |= (((this->write_mask >> i) & 1) << c);
79	 update_rhs_swizzle(rhs_swiz, i, c);
80      }
81
82      this->write_mask = write_mask;
83      lhs = swiz->val;
84
85      this->rhs = new(this) ir_swizzle(this->rhs, rhs_swiz);
86   }
87
88   assert((lhs == NULL) || lhs->as_dereference());
89
90   this->lhs = (ir_dereference *) lhs;
91}
92
93ir_variable *
94ir_assignment::whole_variable_written()
95{
96   ir_variable *v = this->lhs->whole_variable_referenced();
97
98   if (v == NULL)
99      return NULL;
100
101   if (v->type->is_scalar())
102      return v;
103
104   if (v->type->is_vector()) {
105      const unsigned mask = (1U << v->type->vector_elements) - 1;
106
107      if (mask != this->write_mask)
108	 return NULL;
109   }
110
111   /* Either all the vector components are assigned or the variable is some
112    * composite type (and the whole thing is assigned.
113    */
114   return v;
115}
116
117ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs,
118			     ir_rvalue *condition, unsigned write_mask)
119{
120   this->ir_type = ir_type_assignment;
121   this->condition = condition;
122   this->rhs = rhs;
123   this->lhs = lhs;
124   this->write_mask = write_mask;
125}
126
127ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
128			     ir_rvalue *condition)
129{
130   this->ir_type = ir_type_assignment;
131   this->condition = condition;
132   this->rhs = rhs;
133
134   /* If the RHS is a vector type, assume that all components of the vector
135    * type are being written to the LHS.  The write mask comes from the RHS
136    * because we can have a case where the LHS is a vec4 and the RHS is a
137    * vec3.  In that case, the assignment is:
138    *
139    *     (assign (...) (xyz) (var_ref lhs) (var_ref rhs))
140    */
141   if (rhs->type->is_vector())
142      this->write_mask = (1U << rhs->type->vector_elements) - 1;
143   else if (rhs->type->is_scalar())
144      this->write_mask = 1;
145   else
146      this->write_mask = 0;
147
148   this->set_lhs(lhs);
149}
150
151
152ir_expression::ir_expression(int op, const struct glsl_type *type,
153			     ir_rvalue *op0, ir_rvalue *op1)
154{
155   this->ir_type = ir_type_expression;
156   this->type = type;
157   this->operation = ir_expression_operation(op);
158   this->operands[0] = op0;
159   this->operands[1] = op1;
160}
161
162unsigned int
163ir_expression::get_num_operands(ir_expression_operation op)
164{
165/* Update ir_print_visitor.cpp when updating this list. */
166   const int num_operands[] = {
167      1, /* ir_unop_bit_not */
168      1, /* ir_unop_logic_not */
169      1, /* ir_unop_neg */
170      1, /* ir_unop_abs */
171      1, /* ir_unop_sign */
172      1, /* ir_unop_rcp */
173      1, /* ir_unop_rsq */
174      1, /* ir_unop_sqrt */
175      1, /* ir_unop_exp */
176      1, /* ir_unop_log */
177      1, /* ir_unop_exp2 */
178      1, /* ir_unop_log2 */
179      1, /* ir_unop_f2i */
180      1, /* ir_unop_i2f */
181      1, /* ir_unop_f2b */
182      1, /* ir_unop_b2f */
183      1, /* ir_unop_i2b */
184      1, /* ir_unop_b2i */
185      1, /* ir_unop_u2f */
186      1, /* ir_unop_any */
187
188      1, /* ir_unop_trunc */
189      1, /* ir_unop_ceil */
190      1, /* ir_unop_floor */
191      1, /* ir_unop_fract */
192
193      1, /* ir_unop_sin */
194      1, /* ir_unop_cos */
195
196      1, /* ir_unop_dFdx */
197      1, /* ir_unop_dFdy */
198
199      2, /* ir_binop_add */
200      2, /* ir_binop_sub */
201      2, /* ir_binop_mul */
202      2, /* ir_binop_div */
203      2, /* ir_binop_mod */
204
205      2, /* ir_binop_less */
206      2, /* ir_binop_greater */
207      2, /* ir_binop_lequal */
208      2, /* ir_binop_gequal */
209      2, /* ir_binop_equal */
210      2, /* ir_binop_nequal */
211
212      2, /* ir_binop_lshift */
213      2, /* ir_binop_rshift */
214      2, /* ir_binop_bit_and */
215      2, /* ir_binop_bit_xor */
216      2, /* ir_binop_bit_or */
217
218      2, /* ir_binop_logic_and */
219      2, /* ir_binop_logic_xor */
220      2, /* ir_binop_logic_or */
221
222      2, /* ir_binop_dot */
223      2, /* ir_binop_cross */
224      2, /* ir_binop_min */
225      2, /* ir_binop_max */
226
227      2, /* ir_binop_pow */
228   };
229
230   assert(sizeof(num_operands) / sizeof(num_operands[0]) == ir_binop_pow + 1);
231
232   return num_operands[op];
233}
234
235static const char *const operator_strs[] = {
236   "~",
237   "!",
238   "neg",
239   "abs",
240   "sign",
241   "rcp",
242   "rsq",
243   "sqrt",
244   "exp",
245   "log",
246   "exp2",
247   "log2",
248   "f2i",
249   "i2f",
250   "f2b",
251   "b2f",
252   "i2b",
253   "b2i",
254   "u2f",
255   "any",
256   "trunc",
257   "ceil",
258   "floor",
259   "fract",
260   "sin",
261   "cos",
262   "dFdx",
263   "dFdy",
264   "+",
265   "-",
266   "*",
267   "/",
268   "%",
269   "<",
270   ">",
271   "<=",
272   ">=",
273   "==",
274   "!=",
275   "<<",
276   ">>",
277   "&",
278   "^",
279   "|",
280   "&&",
281   "^^",
282   "||",
283   "dot",
284   "cross",
285   "min",
286   "max",
287   "pow",
288};
289
290const char *ir_expression::operator_string()
291{
292   assert((unsigned int) operation <=
293	  sizeof(operator_strs) / sizeof(operator_strs[0]));
294   return operator_strs[operation];
295}
296
297ir_expression_operation
298ir_expression::get_operator(const char *str)
299{
300   const int operator_count = sizeof(operator_strs) / sizeof(operator_strs[0]);
301   for (int op = 0; op < operator_count; op++) {
302      if (strcmp(str, operator_strs[op]) == 0)
303	 return (ir_expression_operation) op;
304   }
305   return (ir_expression_operation) -1;
306}
307
308ir_constant::ir_constant()
309{
310   this->ir_type = ir_type_constant;
311}
312
313ir_constant::ir_constant(const struct glsl_type *type,
314			 const ir_constant_data *data)
315{
316   assert((type->base_type >= GLSL_TYPE_UINT)
317	  && (type->base_type <= GLSL_TYPE_BOOL));
318
319   this->ir_type = ir_type_constant;
320   this->type = type;
321   memcpy(& this->value, data, sizeof(this->value));
322}
323
324ir_constant::ir_constant(float f)
325{
326   this->ir_type = ir_type_constant;
327   this->type = glsl_type::float_type;
328   this->value.f[0] = f;
329}
330
331ir_constant::ir_constant(unsigned int u)
332{
333   this->ir_type = ir_type_constant;
334   this->type = glsl_type::uint_type;
335   this->value.u[0] = u;
336}
337
338ir_constant::ir_constant(int i)
339{
340   this->ir_type = ir_type_constant;
341   this->type = glsl_type::int_type;
342   this->value.i[0] = i;
343}
344
345ir_constant::ir_constant(bool b)
346{
347   this->ir_type = ir_type_constant;
348   this->type = glsl_type::bool_type;
349   this->value.b[0] = b;
350}
351
352ir_constant::ir_constant(const ir_constant *c, unsigned i)
353{
354   this->ir_type = ir_type_constant;
355   this->type = c->type->get_base_type();
356
357   switch (this->type->base_type) {
358   case GLSL_TYPE_UINT:  this->value.u[0] = c->value.u[i]; break;
359   case GLSL_TYPE_INT:   this->value.i[0] = c->value.i[i]; break;
360   case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
361   case GLSL_TYPE_BOOL:  this->value.b[0] = c->value.b[i]; break;
362   default:              assert(!"Should not get here."); break;
363   }
364}
365
366ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
367{
368   this->ir_type = ir_type_constant;
369   this->type = type;
370
371   assert(type->is_scalar() || type->is_vector() || type->is_matrix()
372	  || type->is_record() || type->is_array());
373
374   if (type->is_array()) {
375      this->array_elements = talloc_array(this, ir_constant *, type->length);
376      unsigned i = 0;
377      foreach_list(node, value_list) {
378	 ir_constant *value = (ir_constant *) node;
379	 assert(value->as_constant() != NULL);
380
381	 this->array_elements[i++] = value;
382      }
383      return;
384   }
385
386   /* If the constant is a record, the types of each of the entries in
387    * value_list must be a 1-for-1 match with the structure components.  Each
388    * entry must also be a constant.  Just move the nodes from the value_list
389    * to the list in the ir_constant.
390    */
391   /* FINISHME: Should there be some type checking and / or assertions here? */
392   /* FINISHME: Should the new constant take ownership of the nodes from
393    * FINISHME: value_list, or should it make copies?
394    */
395   if (type->is_record()) {
396      value_list->move_nodes_to(& this->components);
397      return;
398   }
399
400
401   ir_constant *value = (ir_constant *) (value_list->head);
402
403   /* Use each component from each entry in the value_list to initialize one
404    * component of the constant being constructed.
405    */
406   for (unsigned i = 0; i < type->components(); /* empty */) {
407      assert(value->as_constant() != NULL);
408      assert(!value->is_tail_sentinel());
409
410      for (unsigned j = 0; j < value->type->components(); j++) {
411	 switch (type->base_type) {
412	 case GLSL_TYPE_UINT:
413	    this->value.u[i] = value->get_uint_component(j);
414	    break;
415	 case GLSL_TYPE_INT:
416	    this->value.i[i] = value->get_int_component(j);
417	    break;
418	 case GLSL_TYPE_FLOAT:
419	    this->value.f[i] = value->get_float_component(j);
420	    break;
421	 case GLSL_TYPE_BOOL:
422	    this->value.b[i] = value->get_bool_component(j);
423	    break;
424	 default:
425	    /* FINISHME: What to do?  Exceptions are not the answer.
426	     */
427	    break;
428	 }
429
430	 i++;
431	 if (i >= type->components())
432	    break;
433      }
434
435      value = (ir_constant *) value->next;
436   }
437}
438
439ir_constant *
440ir_constant::zero(void *mem_ctx, const glsl_type *type)
441{
442   assert(type->is_numeric());
443
444   ir_constant *c = new(mem_ctx) ir_constant;
445   c->type = type;
446   memset(&c->value, 0, sizeof(c->value));
447
448   return c;
449}
450
451bool
452ir_constant::get_bool_component(unsigned i) const
453{
454   switch (this->type->base_type) {
455   case GLSL_TYPE_UINT:  return this->value.u[i] != 0;
456   case GLSL_TYPE_INT:   return this->value.i[i] != 0;
457   case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
458   case GLSL_TYPE_BOOL:  return this->value.b[i];
459   default:              assert(!"Should not get here."); break;
460   }
461
462   /* Must return something to make the compiler happy.  This is clearly an
463    * error case.
464    */
465   return false;
466}
467
468float
469ir_constant::get_float_component(unsigned i) const
470{
471   switch (this->type->base_type) {
472   case GLSL_TYPE_UINT:  return (float) this->value.u[i];
473   case GLSL_TYPE_INT:   return (float) this->value.i[i];
474   case GLSL_TYPE_FLOAT: return this->value.f[i];
475   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0 : 0.0;
476   default:              assert(!"Should not get here."); break;
477   }
478
479   /* Must return something to make the compiler happy.  This is clearly an
480    * error case.
481    */
482   return 0.0;
483}
484
485int
486ir_constant::get_int_component(unsigned i) const
487{
488   switch (this->type->base_type) {
489   case GLSL_TYPE_UINT:  return this->value.u[i];
490   case GLSL_TYPE_INT:   return this->value.i[i];
491   case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
492   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
493   default:              assert(!"Should not get here."); break;
494   }
495
496   /* Must return something to make the compiler happy.  This is clearly an
497    * error case.
498    */
499   return 0;
500}
501
502unsigned
503ir_constant::get_uint_component(unsigned i) const
504{
505   switch (this->type->base_type) {
506   case GLSL_TYPE_UINT:  return this->value.u[i];
507   case GLSL_TYPE_INT:   return this->value.i[i];
508   case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
509   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
510   default:              assert(!"Should not get here."); break;
511   }
512
513   /* Must return something to make the compiler happy.  This is clearly an
514    * error case.
515    */
516   return 0;
517}
518
519ir_constant *
520ir_constant::get_array_element(unsigned i) const
521{
522   assert(this->type->is_array());
523
524   /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec:
525    *
526    *     "Behavior is undefined if a shader subscripts an array with an index
527    *     less than 0 or greater than or equal to the size the array was
528    *     declared with."
529    *
530    * Most out-of-bounds accesses are removed before things could get this far.
531    * There are cases where non-constant array index values can get constant
532    * folded.
533    */
534   if (int(i) < 0)
535      i = 0;
536   else if (i >= this->type->length)
537      i = this->type->length - 1;
538
539   return array_elements[i];
540}
541
542ir_constant *
543ir_constant::get_record_field(const char *name)
544{
545   int idx = this->type->field_index(name);
546
547   if (idx < 0)
548      return NULL;
549
550   if (this->components.is_empty())
551      return NULL;
552
553   exec_node *node = this->components.head;
554   for (int i = 0; i < idx; i++) {
555      node = node->next;
556
557      /* If the end of the list is encountered before the element matching the
558       * requested field is found, return NULL.
559       */
560      if (node->is_tail_sentinel())
561	 return NULL;
562   }
563
564   return (ir_constant *) node;
565}
566
567
568bool
569ir_constant::has_value(const ir_constant *c) const
570{
571   if (this->type != c->type)
572      return false;
573
574   if (this->type->is_array()) {
575      for (unsigned i = 0; i < this->type->length; i++) {
576	 if (this->array_elements[i]->has_value(c->array_elements[i]))
577	    return false;
578      }
579      return true;
580   }
581
582   if (this->type->base_type == GLSL_TYPE_STRUCT) {
583      const exec_node *a_node = this->components.head;
584      const exec_node *b_node = c->components.head;
585
586      while (!a_node->is_tail_sentinel()) {
587	 assert(!b_node->is_tail_sentinel());
588
589	 const ir_constant *const a_field = (ir_constant *) a_node;
590	 const ir_constant *const b_field = (ir_constant *) b_node;
591
592	 if (!a_field->has_value(b_field))
593	    return false;
594
595	 a_node = a_node->next;
596	 b_node = b_node->next;
597      }
598
599      return true;
600   }
601
602   for (unsigned i = 0; i < this->type->components(); i++) {
603      switch (this->type->base_type) {
604      case GLSL_TYPE_UINT:
605	 if (this->value.u[i] != c->value.u[i])
606	    return false;
607	 break;
608      case GLSL_TYPE_INT:
609	 if (this->value.i[i] != c->value.i[i])
610	    return false;
611	 break;
612      case GLSL_TYPE_FLOAT:
613	 if (this->value.f[i] != c->value.f[i])
614	    return false;
615	 break;
616      case GLSL_TYPE_BOOL:
617	 if (this->value.b[i] != c->value.b[i])
618	    return false;
619	 break;
620      default:
621	 assert(!"Should not get here.");
622	 return false;
623      }
624   }
625
626   return true;
627}
628
629ir_dereference_variable::ir_dereference_variable(ir_variable *var)
630{
631   this->ir_type = ir_type_dereference_variable;
632   this->var = var;
633   this->type = (var != NULL) ? var->type : glsl_type::error_type;
634}
635
636
637ir_dereference_array::ir_dereference_array(ir_rvalue *value,
638					   ir_rvalue *array_index)
639{
640   this->ir_type = ir_type_dereference_array;
641   this->array_index = array_index;
642   this->set_array(value);
643}
644
645
646ir_dereference_array::ir_dereference_array(ir_variable *var,
647					   ir_rvalue *array_index)
648{
649   void *ctx = talloc_parent(var);
650
651   this->ir_type = ir_type_dereference_array;
652   this->array_index = array_index;
653   this->set_array(new(ctx) ir_dereference_variable(var));
654}
655
656
657void
658ir_dereference_array::set_array(ir_rvalue *value)
659{
660   this->array = value;
661   this->type = glsl_type::error_type;
662
663   if (this->array != NULL) {
664      const glsl_type *const vt = this->array->type;
665
666      if (vt->is_array()) {
667	 type = vt->element_type();
668      } else if (vt->is_matrix()) {
669	 type = vt->column_type();
670      } else if (vt->is_vector()) {
671	 type = vt->get_base_type();
672      }
673   }
674}
675
676
677ir_dereference_record::ir_dereference_record(ir_rvalue *value,
678					     const char *field)
679{
680   this->ir_type = ir_type_dereference_record;
681   this->record = value;
682   this->field = talloc_strdup(this, field);
683   this->type = (this->record != NULL)
684      ? this->record->type->field_type(field) : glsl_type::error_type;
685}
686
687
688ir_dereference_record::ir_dereference_record(ir_variable *var,
689					     const char *field)
690{
691   void *ctx = talloc_parent(var);
692
693   this->ir_type = ir_type_dereference_record;
694   this->record = new(ctx) ir_dereference_variable(var);
695   this->field = talloc_strdup(this, field);
696   this->type = (this->record != NULL)
697      ? this->record->type->field_type(field) : glsl_type::error_type;
698}
699
700
701bool
702ir_dereference::is_lvalue()
703{
704   ir_variable *var = this->variable_referenced();
705
706   /* Every l-value derference chain eventually ends in a variable.
707    */
708   if ((var == NULL) || var->read_only)
709      return false;
710
711   if (this->type->is_array() && !var->array_lvalue)
712      return false;
713
714   return true;
715}
716
717
718const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf" };
719
720const char *ir_texture::opcode_string()
721{
722   assert((unsigned int) op <=
723	  sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]));
724   return tex_opcode_strs[op];
725}
726
727ir_texture_opcode
728ir_texture::get_opcode(const char *str)
729{
730   const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]);
731   for (int op = 0; op < count; op++) {
732      if (strcmp(str, tex_opcode_strs[op]) == 0)
733	 return (ir_texture_opcode) op;
734   }
735   return (ir_texture_opcode) -1;
736}
737
738
739void
740ir_texture::set_sampler(ir_dereference *sampler)
741{
742   assert(sampler != NULL);
743   this->sampler = sampler;
744
745   switch (sampler->type->sampler_type) {
746   case GLSL_TYPE_FLOAT:
747      this->type = glsl_type::vec4_type;
748      break;
749   case GLSL_TYPE_INT:
750      this->type = glsl_type::ivec4_type;
751      break;
752   case GLSL_TYPE_UINT:
753      this->type = glsl_type::uvec4_type;
754      break;
755   }
756}
757
758
759void
760ir_swizzle::init_mask(const unsigned *comp, unsigned count)
761{
762   assert((count >= 1) && (count <= 4));
763
764   memset(&this->mask, 0, sizeof(this->mask));
765   this->mask.num_components = count;
766
767   unsigned dup_mask = 0;
768   switch (count) {
769   case 4:
770      assert(comp[3] <= 3);
771      dup_mask |= (1U << comp[3])
772	 & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2]));
773      this->mask.w = comp[3];
774
775   case 3:
776      assert(comp[2] <= 3);
777      dup_mask |= (1U << comp[2])
778	 & ((1U << comp[0]) | (1U << comp[1]));
779      this->mask.z = comp[2];
780
781   case 2:
782      assert(comp[1] <= 3);
783      dup_mask |= (1U << comp[1])
784	 & ((1U << comp[0]));
785      this->mask.y = comp[1];
786
787   case 1:
788      assert(comp[0] <= 3);
789      this->mask.x = comp[0];
790   }
791
792   this->mask.has_duplicates = dup_mask != 0;
793
794   /* Based on the number of elements in the swizzle and the base type
795    * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
796    * generate the type of the resulting value.
797    */
798   type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
799}
800
801ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
802		       unsigned w, unsigned count)
803   : val(val)
804{
805   const unsigned components[4] = { x, y, z, w };
806   this->ir_type = ir_type_swizzle;
807   this->init_mask(components, count);
808}
809
810ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp,
811		       unsigned count)
812   : val(val)
813{
814   this->ir_type = ir_type_swizzle;
815   this->init_mask(comp, count);
816}
817
818ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
819{
820   this->ir_type = ir_type_swizzle;
821   this->val = val;
822   this->mask = mask;
823   this->type = glsl_type::get_instance(val->type->base_type,
824					mask.num_components, 1);
825}
826
827#define X 1
828#define R 5
829#define S 9
830#define I 13
831
832ir_swizzle *
833ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
834{
835   void *ctx = talloc_parent(val);
836
837   /* For each possible swizzle character, this table encodes the value in
838    * \c idx_map that represents the 0th element of the vector.  For invalid
839    * swizzle characters (e.g., 'k'), a special value is used that will allow
840    * detection of errors.
841    */
842   static const unsigned char base_idx[26] = {
843   /* a  b  c  d  e  f  g  h  i  j  k  l  m */
844      R, R, I, I, I, I, R, I, I, I, I, I, I,
845   /* n  o  p  q  r  s  t  u  v  w  x  y  z */
846      I, I, S, S, R, S, S, I, I, X, X, X, X
847   };
848
849   /* Each valid swizzle character has an entry in the previous table.  This
850    * table encodes the base index encoded in the previous table plus the actual
851    * index of the swizzle character.  When processing swizzles, the first
852    * character in the string is indexed in the previous table.  Each character
853    * in the string is indexed in this table, and the value found there has the
854    * value form the first table subtracted.  The result must be on the range
855    * [0,3].
856    *
857    * For example, the string "wzyx" will get X from the first table.  Each of
858    * the charcaters will get X+3, X+2, X+1, and X+0 from this table.  After
859    * subtraction, the swizzle values are { 3, 2, 1, 0 }.
860    *
861    * The string "wzrg" will get X from the first table.  Each of the characters
862    * will get X+3, X+2, R+0, and R+1 from this table.  After subtraction, the
863    * swizzle values are { 3, 2, 4, 5 }.  Since 4 and 5 are outside the range
864    * [0,3], the error is detected.
865    */
866   static const unsigned char idx_map[26] = {
867   /* a    b    c    d    e    f    g    h    i    j    k    l    m */
868      R+3, R+2, 0,   0,   0,   0,   R+1, 0,   0,   0,   0,   0,   0,
869   /* n    o    p    q    r    s    t    u    v    w    x    y    z */
870      0,   0,   S+2, S+3, R+0, S+0, S+1, 0,   0,   X+3, X+0, X+1, X+2
871   };
872
873   int swiz_idx[4] = { 0, 0, 0, 0 };
874   unsigned i;
875
876
877   /* Validate the first character in the swizzle string and look up the base
878    * index value as described above.
879    */
880   if ((str[0] < 'a') || (str[0] > 'z'))
881      return NULL;
882
883   const unsigned base = base_idx[str[0] - 'a'];
884
885
886   for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
887      /* Validate the next character, and, as described above, convert it to a
888       * swizzle index.
889       */
890      if ((str[i] < 'a') || (str[i] > 'z'))
891	 return NULL;
892
893      swiz_idx[i] = idx_map[str[i] - 'a'] - base;
894      if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
895	 return NULL;
896   }
897
898   if (str[i] != '\0')
899	 return NULL;
900
901   return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
902			      swiz_idx[3], i);
903}
904
905#undef X
906#undef R
907#undef S
908#undef I
909
910ir_variable *
911ir_swizzle::variable_referenced()
912{
913   return this->val->variable_referenced();
914}
915
916
917ir_variable::ir_variable(const struct glsl_type *type, const char *name,
918			 ir_variable_mode mode)
919   : max_array_access(0), read_only(false), centroid(false), invariant(false),
920     mode(mode), interpolation(ir_var_smooth), array_lvalue(false)
921{
922   this->ir_type = ir_type_variable;
923   this->type = type;
924   this->name = talloc_strdup(this, name);
925   this->location = -1;
926   this->warn_extension = NULL;
927   this->constant_value = NULL;
928   this->origin_upper_left = false;
929   this->pixel_center_integer = false;
930
931   if (type && type->base_type == GLSL_TYPE_SAMPLER)
932      this->read_only = true;
933}
934
935
936const char *
937ir_variable::interpolation_string() const
938{
939   switch (this->interpolation) {
940   case ir_var_smooth:        return "smooth";
941   case ir_var_flat:          return "flat";
942   case ir_var_noperspective: return "noperspective";
943   }
944
945   assert(!"Should not get here.");
946   return "";
947}
948
949
950unsigned
951ir_variable::component_slots() const
952{
953   /* FINISHME: Sparsely accessed arrays require fewer slots. */
954   return this->type->component_slots();
955}
956
957
958ir_function_signature::ir_function_signature(const glsl_type *return_type)
959   : return_type(return_type), is_defined(false), _function(NULL)
960{
961   this->ir_type = ir_type_function_signature;
962   this->is_built_in = false;
963}
964
965
966const char *
967ir_function_signature::qualifiers_match(exec_list *params)
968{
969   exec_list_iterator iter_a = parameters.iterator();
970   exec_list_iterator iter_b = params->iterator();
971
972   /* check that the qualifiers match. */
973   while (iter_a.has_next()) {
974      ir_variable *a = (ir_variable *)iter_a.get();
975      ir_variable *b = (ir_variable *)iter_b.get();
976
977      if (a->read_only != b->read_only ||
978	  a->mode != b->mode ||
979	  a->interpolation != b->interpolation ||
980	  a->centroid != b->centroid) {
981
982	 /* parameter a's qualifiers don't match */
983	 return a->name;
984      }
985
986      iter_a.next();
987      iter_b.next();
988   }
989   return NULL;
990}
991
992
993void
994ir_function_signature::replace_parameters(exec_list *new_params)
995{
996   /* Destroy all of the previous parameter information.  If the previous
997    * parameter information comes from the function prototype, it may either
998    * specify incorrect parameter names or not have names at all.
999    */
1000   foreach_iter(exec_list_iterator, iter, parameters) {
1001      assert(((ir_instruction *) iter.get())->as_variable() != NULL);
1002
1003      iter.remove();
1004   }
1005
1006   new_params->move_nodes_to(&parameters);
1007}
1008
1009
1010ir_function::ir_function(const char *name)
1011{
1012   this->ir_type = ir_type_function;
1013   this->name = talloc_strdup(this, name);
1014}
1015
1016
1017ir_call *
1018ir_call::get_error_instruction(void *ctx)
1019{
1020   ir_call *call = new(ctx) ir_call;
1021
1022   call->type = glsl_type::error_type;
1023   return call;
1024}
1025
1026void
1027ir_call::set_callee(ir_function_signature *sig)
1028{
1029   assert((this->type == NULL) || (this->type == sig->return_type));
1030
1031   this->callee = sig;
1032}
1033
1034void
1035visit_exec_list(exec_list *list, ir_visitor *visitor)
1036{
1037   foreach_iter(exec_list_iterator, iter, *list) {
1038      ((ir_instruction *)iter.get())->accept(visitor);
1039   }
1040}
1041
1042
1043static void
1044steal_memory(ir_instruction *ir, void *new_ctx)
1045{
1046   ir_variable *var = ir->as_variable();
1047   ir_constant *constant = ir->as_constant();
1048   if (var != NULL && var->constant_value != NULL)
1049      steal_memory(var->constant_value, ir);
1050
1051   /* The components of aggregate constants are not visited by the normal
1052    * visitor, so steal their values by hand.
1053    */
1054   if (constant != NULL) {
1055      if (constant->type->is_record()) {
1056	 foreach_iter(exec_list_iterator, iter, constant->components) {
1057	    ir_constant *field = (ir_constant *)iter.get();
1058	    steal_memory(field, ir);
1059	 }
1060      } else if (constant->type->is_array()) {
1061	 for (unsigned int i = 0; i < constant->type->length; i++) {
1062	    steal_memory(constant->array_elements[i], ir);
1063	 }
1064      }
1065   }
1066
1067   talloc_steal(new_ctx, ir);
1068}
1069
1070
1071void
1072reparent_ir(exec_list *list, void *mem_ctx)
1073{
1074   foreach_list(node, list) {
1075      visit_tree((ir_instruction *) node, steal_memory, mem_ctx);
1076   }
1077}
1078