• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#
2# Copyright (C) 2015 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 DEALINGS
21# IN THE SOFTWARE.
22
23import mako.template
24import sys
25
26class type(object):
27   def __init__(self, c_type, union_field, glsl_type):
28      self.c_type = c_type
29      self.union_field = union_field
30      self.glsl_type = glsl_type
31
32
33class type_signature_iter(object):
34   """Basic iterator for a set of type signatures.  Various kinds of sequences of
35   types come in, and an iteration of type_signature objects come out.
36
37   """
38
39   def __init__(self, source_types, num_operands):
40      """Initialize an iterator from a sequence of input types and a number
41      operands.  This is for signatures where all the operands have the same
42      type and the result type of the operation is the same as the input type.
43
44      """
45      self.dest_type = None
46      self.source_types = source_types
47      self.num_operands = num_operands
48      self.i = 0
49
50   def __init__(self, dest_type, source_types, num_operands):
51      """Initialize an iterator from a result tpye, a sequence of input types and a
52      number operands.  This is for signatures where all the operands have the
53      same type but the result type of the operation is different from the
54      input type.
55
56      """
57      self.dest_type = dest_type
58      self.source_types = source_types
59      self.num_operands = num_operands
60      self.i = 0
61
62   def __iter__(self):
63      return self
64
65   def __next__(self):
66      if self.i < len(self.source_types):
67         i = self.i
68         self.i += 1
69
70         if self.dest_type is None:
71            dest_type = self.source_types[i]
72         else:
73            dest_type = self.dest_type
74
75         return (dest_type, self.num_operands * (self.source_types[i],))
76      else:
77         raise StopIteration()
78
79   next = __next__
80
81
82uint_type = type("unsigned", "u", "GLSL_TYPE_UINT")
83int_type = type("int", "i", "GLSL_TYPE_INT")
84uint64_type = type("uint64_t", "u64", "GLSL_TYPE_UINT64")
85int64_type = type("int64_t", "i64", "GLSL_TYPE_INT64")
86float_type = type("float", "f", "GLSL_TYPE_FLOAT")
87double_type = type("double", "d", "GLSL_TYPE_DOUBLE")
88bool_type = type("bool", "b", "GLSL_TYPE_BOOL")
89
90all_types = (uint_type, int_type, float_type, double_type, uint64_type, int64_type, bool_type)
91numeric_types = (uint_type, int_type, float_type, double_type, uint64_type, int64_type)
92signed_numeric_types = (int_type, float_type, double_type, int64_type)
93integer_types = (uint_type, int_type, uint64_type, int64_type)
94real_types = (float_type, double_type)
95
96# This template is for operations that can have operands of a several
97# different types, and each type may or may not has a different C expression.
98# This is used by most operations.
99constant_template_common = mako.template.Template("""\
100   case ${op.get_enum_name()}:
101      for (unsigned c = 0; c < op[0]->type->components(); c++) {
102         switch (op[0]->type->base_type) {
103    % for dst_type, src_types in op.signatures():
104         case ${src_types[0].glsl_type}:
105            data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types)};
106            break;
107    % endfor
108         default:
109            unreachable("invalid type");
110         }
111      }
112      break;""")
113
114# This template is for binary operations that can operate on some combination
115# of scalar and vector operands.
116constant_template_vector_scalar = mako.template.Template("""\
117   case ${op.get_enum_name()}:
118    % if "mixed" in op.flags:
119        % for i in range(op.num_operands):
120      assert(op[${i}]->type->base_type == ${op.source_types[0].glsl_type} ||
121            % for src_type in op.source_types[1:-1]:
122             op[${i}]->type->base_type == ${src_type.glsl_type} ||
123            % endfor
124             op[${i}]->type->base_type == ${op.source_types[-1].glsl_type});
125        % endfor
126    % else:
127      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
128    % endif
129      for (unsigned c = 0, c0 = 0, c1 = 0;
130           c < components;
131           c0 += c0_inc, c1 += c1_inc, c++) {
132
133         switch (op[0]->type->base_type) {
134    % for dst_type, src_types in op.signatures():
135         case ${src_types[0].glsl_type}:
136            data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types, ("c0", "c1", "c2"))};
137            break;
138    % endfor
139         default:
140            unreachable("invalid type");
141         }
142      }
143      break;""")
144
145# This template is for multiplication.  It is unique because it has to support
146# matrix * vector and matrix * matrix operations, and those are just different.
147constant_template_mul = mako.template.Template("""\
148   case ${op.get_enum_name()}:
149      /* Check for equal types, or unequal types involving scalars */
150      if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
151          || op0_scalar || op1_scalar) {
152         for (unsigned c = 0, c0 = 0, c1 = 0;
153              c < components;
154              c0 += c0_inc, c1 += c1_inc, c++) {
155
156            switch (op[0]->type->base_type) {
157    % for dst_type, src_types in op.signatures():
158            case ${src_types[0].glsl_type}:
159               data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types, ("c0", "c1", "c2"))};
160               break;
161    % endfor
162            default:
163               unreachable("invalid type");
164            }
165         }
166      } else {
167         assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
168
169         /* Multiply an N-by-M matrix with an M-by-P matrix.  Since either
170          * matrix can be a GLSL vector, either N or P can be 1.
171          *
172          * For vec*mat, the vector is treated as a row vector.  This
173          * means the vector is a 1-row x M-column matrix.
174          *
175          * For mat*vec, the vector is treated as a column vector.  Since
176          * matrix_columns is 1 for vectors, this just works.
177          */
178         const unsigned n = op[0]->type->is_vector()
179            ? 1 : op[0]->type->vector_elements;
180         const unsigned m = op[1]->type->vector_elements;
181         const unsigned p = op[1]->type->matrix_columns;
182         for (unsigned j = 0; j < p; j++) {
183            for (unsigned i = 0; i < n; i++) {
184               for (unsigned k = 0; k < m; k++) {
185                  if (op[0]->type->is_double())
186                     data.d[i+n*j] += op[0]->value.d[i+n*k]*op[1]->value.d[k+m*j];
187                  else
188                     data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
189               }
190            }
191         }
192      }
193      break;""")
194
195# This template is for operations that are horizontal and either have only a
196# single type or the implementation for all types is identical.  That is, the
197# operation consumes a vector and produces a scalar.
198constant_template_horizontal_single_implementation = mako.template.Template("""\
199   case ${op.get_enum_name()}:
200      data.${op.dest_type.union_field}[0] = ${op.c_expression['default']};
201      break;""")
202
203# This template is for operations that are horizontal and do not assign the
204# result.  The various unpack operations are examples.
205constant_template_horizontal_nonassignment = mako.template.Template("""\
206   case ${op.get_enum_name()}:
207      ${op.c_expression['default']};
208      break;""")
209
210# This template is for binary operations that are horizontal.  That is, the
211# operation consumes a vector and produces a scalar.
212constant_template_horizontal = mako.template.Template("""\
213   case ${op.get_enum_name()}:
214      switch (op[0]->type->base_type) {
215    % for dst_type, src_types in op.signatures():
216      case ${src_types[0].glsl_type}:
217         data.${dst_type.union_field}[0] = ${op.get_c_expression(src_types)};
218         break;
219    % endfor
220      default:
221         unreachable("invalid type");
222      }
223      break;""")
224
225# This template is for ir_binop_vector_extract.
226constant_template_vector_extract = mako.template.Template("""\
227   case ${op.get_enum_name()}: {
228      const int c = CLAMP(op[1]->value.i[0], 0,
229                          (int) op[0]->type->vector_elements - 1);
230
231      switch (op[0]->type->base_type) {
232    % for dst_type, src_types in op.signatures():
233      case ${src_types[0].glsl_type}:
234         data.${dst_type.union_field}[0] = op[0]->value.${src_types[0].union_field}[c];
235         break;
236    % endfor
237      default:
238         unreachable("invalid type");
239      }
240      break;
241   }""")
242
243# This template is for ir_triop_vector_insert.
244constant_template_vector_insert = mako.template.Template("""\
245   case ${op.get_enum_name()}: {
246      const unsigned idx = op[2]->value.u[0];
247
248      memcpy(&data, &op[0]->value, sizeof(data));
249
250      switch (return_type->base_type) {
251    % for dst_type, src_types in op.signatures():
252      case ${src_types[0].glsl_type}:
253         data.${dst_type.union_field}[idx] = op[1]->value.${src_types[0].union_field}[0];
254         break;
255    % endfor
256      default:
257         unreachable("invalid type");
258      }
259      break;
260   }""")
261
262# This template is for ir_quadop_vector.
263constant_template_vector = mako.template.Template("""\
264   case ${op.get_enum_name()}:
265      for (unsigned c = 0; c < return_type->vector_elements; c++) {
266         switch (return_type->base_type) {
267    % for dst_type, src_types in op.signatures():
268         case ${src_types[0].glsl_type}:
269            data.${dst_type.union_field}[c] = op[c]->value.${src_types[0].union_field}[0];
270            break;
271    % endfor
272         default:
273            unreachable("invalid type");
274         }
275      }
276      break;""")
277
278# This template is for ir_triop_lrp.
279constant_template_lrp = mako.template.Template("""\
280   case ${op.get_enum_name()}: {
281      assert(op[0]->type->is_float() || op[0]->type->is_double());
282      assert(op[1]->type->is_float() || op[1]->type->is_double());
283      assert(op[2]->type->is_float() || op[2]->type->is_double());
284
285      unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
286      for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
287         switch (return_type->base_type) {
288    % for dst_type, src_types in op.signatures():
289         case ${src_types[0].glsl_type}:
290            data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types, ("c", "c", "c2"))};
291            break;
292    % endfor
293         default:
294            unreachable("invalid type");
295         }
296      }
297      break;
298   }""")
299
300# This template is for ir_triop_csel.  This expression is really unique
301# because not all of the operands are the same type, and the second operand
302# determines the type of the expression (instead of the first).
303constant_template_csel = mako.template.Template("""\
304   case ${op.get_enum_name()}:
305      for (unsigned c = 0; c < components; c++) {
306         switch (return_type->base_type) {
307    % for dst_type, src_types in op.signatures():
308         case ${src_types[1].glsl_type}:
309            data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types)};
310            break;
311    % endfor
312         default:
313            unreachable("invalid type");
314         }
315      }
316      break;""")
317
318
319vector_scalar_operation = "vector-scalar"
320horizontal_operation = "horizontal"
321types_identical_operation = "identical"
322non_assign_operation = "nonassign"
323mixed_type_operation = "mixed"
324
325class operation(object):
326   def __init__(self, name, num_operands, printable_name = None, source_types = None, dest_type = None, c_expression = None, flags = None, all_signatures = None):
327      self.name = name
328      self.num_operands = num_operands
329
330      if printable_name is None:
331         self.printable_name = name
332      else:
333         self.printable_name = printable_name
334
335      self.all_signatures = all_signatures
336
337      if source_types is None:
338         self.source_types = tuple()
339      else:
340         self.source_types = source_types
341
342      self.dest_type = dest_type
343
344      if c_expression is None:
345         self.c_expression = None
346      elif isinstance(c_expression, str):
347         self.c_expression = {'default': c_expression}
348      else:
349         self.c_expression = c_expression
350
351      if flags is None:
352         self.flags = frozenset()
353      elif isinstance(flags, str):
354         self.flags = frozenset([flags])
355      else:
356         self.flags = frozenset(flags)
357
358
359   def get_enum_name(self):
360      return "ir_{0}op_{1}".format(("un", "bin", "tri", "quad")[self.num_operands-1], self.name)
361
362
363   def get_template(self):
364      if self.c_expression is None:
365         return None
366
367      if horizontal_operation in self.flags:
368         if non_assign_operation in self.flags:
369            return constant_template_horizontal_nonassignment.render(op=self)
370         elif types_identical_operation in self.flags:
371            return constant_template_horizontal_single_implementation.render(op=self)
372         else:
373            return constant_template_horizontal.render(op=self)
374
375      if self.num_operands == 2:
376         if self.name == "mul":
377            return constant_template_mul.render(op=self)
378         elif self.name == "vector_extract":
379            return constant_template_vector_extract.render(op=self)
380         elif vector_scalar_operation in self.flags:
381            return constant_template_vector_scalar.render(op=self)
382      elif self.num_operands == 3:
383         if self.name == "vector_insert":
384            return constant_template_vector_insert.render(op=self)
385         elif self.name == "lrp":
386            return constant_template_lrp.render(op=self)
387         elif self.name == "csel":
388            return constant_template_csel.render(op=self)
389      elif self.num_operands == 4:
390         if self.name == "vector":
391            return constant_template_vector.render(op=self)
392
393      return constant_template_common.render(op=self)
394
395
396   def get_c_expression(self, types, indices=("c", "c", "c")):
397      src0 = "op[0]->value.{0}[{1}]".format(types[0].union_field, indices[0])
398      src1 = "op[1]->value.{0}[{1}]".format(types[1].union_field, indices[1]) if len(types) >= 2 else "ERROR"
399      src2 = "op[2]->value.{0}[{1}]".format(types[2].union_field, indices[2]) if len(types) >= 3 else "ERROR"
400      src3 = "op[3]->value.{0}[c]".format(types[3].union_field) if len(types) >= 4 else "ERROR"
401
402      expr = self.c_expression[types[0].union_field] if types[0].union_field in self.c_expression else self.c_expression['default']
403
404      return expr.format(src0=src0,
405                         src1=src1,
406                         src2=src2,
407                         src3=src3)
408
409
410   def signatures(self):
411      if self.all_signatures is not None:
412         return self.all_signatures
413      else:
414         return type_signature_iter(self.dest_type, self.source_types, self.num_operands)
415
416
417ir_expression_operation = [
418   operation("bit_not", 1, printable_name="~", source_types=integer_types, c_expression="~ {src0}"),
419   operation("logic_not", 1, printable_name="!", source_types=(bool_type,), c_expression="!{src0}"),
420   operation("neg", 1, source_types=numeric_types, c_expression={'u': "-((int) {src0})", 'u64': "-((int64_t) {src0})", 'default': "-{src0}"}),
421   operation("abs", 1, source_types=signed_numeric_types, c_expression={'i': "{src0} < 0 ? -{src0} : {src0}", 'f': "fabsf({src0})", 'd': "fabs({src0})", 'i64': "{src0} < 0 ? -{src0} : {src0}"}),
422   operation("sign", 1, source_types=signed_numeric_types, c_expression={'i': "({src0} > 0) - ({src0} < 0)", 'f': "float(({src0} > 0.0F) - ({src0} < 0.0F))", 'd': "double(({src0} > 0.0) - ({src0} < 0.0))", 'i64': "({src0} > 0) - ({src0} < 0)"}),
423   operation("rcp", 1, source_types=real_types, c_expression={'f': "1.0F / {src0}", 'd': "1.0 / {src0}"}),
424   operation("rsq", 1, source_types=real_types, c_expression={'f': "1.0F / sqrtf({src0})", 'd': "1.0 / sqrt({src0})"}),
425   operation("sqrt", 1, source_types=real_types, c_expression={'f': "sqrtf({src0})", 'd': "sqrt({src0})"}),
426   operation("exp", 1, source_types=(float_type,), c_expression="expf({src0})"),         # Log base e on gentype
427   operation("log", 1, source_types=(float_type,), c_expression="logf({src0})"),         # Natural log on gentype
428   operation("exp2", 1, source_types=(float_type,), c_expression="exp2f({src0})"),
429   operation("log2", 1, source_types=(float_type,), c_expression="log2f({src0})"),
430
431   # Float-to-integer conversion.
432   operation("f2i", 1, source_types=(float_type,), dest_type=int_type, c_expression="(int) {src0}"),
433   # Float-to-unsigned conversion.
434   operation("f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="(unsigned) {src0}"),
435   # Integer-to-float conversion.
436   operation("i2f", 1, source_types=(int_type,), dest_type=float_type, c_expression="(float) {src0}"),
437   # Float-to-boolean conversion
438   operation("f2b", 1, source_types=(float_type,), dest_type=bool_type, c_expression="{src0} != 0.0F ? true : false"),
439   # Boolean-to-float conversion
440   operation("b2f", 1, source_types=(bool_type,), dest_type=float_type, c_expression="{src0} ? 1.0F : 0.0F"),
441   # Boolean-to-float16 conversion
442   operation("b2f16", 1, source_types=(bool_type,), dest_type=float_type, c_expression="{src0} ? 1.0F : 0.0F"),
443   # int-to-boolean conversion
444   operation("i2b", 1, source_types=(uint_type, int_type), dest_type=bool_type, c_expression="{src0} ? true : false"),
445   # Boolean-to-int conversion
446   operation("b2i", 1, source_types=(bool_type,), dest_type=int_type, c_expression="{src0} ? 1 : 0"),
447   # Unsigned-to-float conversion.
448   operation("u2f", 1, source_types=(uint_type,), dest_type=float_type, c_expression="(float) {src0}"),
449   # Integer-to-unsigned conversion.
450   operation("i2u", 1, source_types=(int_type,), dest_type=uint_type, c_expression="{src0}"),
451   # Unsigned-to-integer conversion.
452   operation("u2i", 1, source_types=(uint_type,), dest_type=int_type, c_expression="{src0}"),
453   # Double-to-float conversion.
454   operation("d2f", 1, source_types=(double_type,), dest_type=float_type, c_expression="{src0}"),
455   # Float-to-double conversion.
456   operation("f2d", 1, source_types=(float_type,), dest_type=double_type, c_expression="{src0}"),
457   # Half-float conversions. These all operate on and return float types,
458   # since the framework expands half to full float before calling in.  We
459   # still have to handle them here so that we can constant propagate through
460   # them, but they are no-ops.
461   operation("f2f16", 1, source_types=(float_type,), dest_type=float_type, c_expression="{src0}"),
462   operation("f2fmp", 1, source_types=(float_type,), dest_type=float_type, c_expression="{src0}"),
463   operation("f162f", 1, source_types=(float_type,), dest_type=float_type, c_expression="{src0}"),
464   # int16<->int32 conversion.
465   operation("i2i", 1, source_types=(int_type,), dest_type=int_type, c_expression="{src0}"),
466   operation("i2imp", 1, source_types=(int_type,), dest_type=int_type, c_expression="{src0}"),
467   operation("u2u", 1, source_types=(uint_type,), dest_type=uint_type, c_expression="{src0}"),
468   operation("u2ump", 1, source_types=(uint_type,), dest_type=uint_type, c_expression="{src0}"),
469   # Double-to-integer conversion.
470   operation("d2i", 1, source_types=(double_type,), dest_type=int_type, c_expression="{src0}"),
471   # Integer-to-double conversion.
472   operation("i2d", 1, source_types=(int_type,), dest_type=double_type, c_expression="{src0}"),
473   # Double-to-unsigned conversion.
474   operation("d2u", 1, source_types=(double_type,), dest_type=uint_type, c_expression="{src0}"),
475   # Unsigned-to-double conversion.
476   operation("u2d", 1, source_types=(uint_type,), dest_type=double_type, c_expression="{src0}"),
477   # Double-to-boolean conversion.
478   operation("d2b", 1, source_types=(double_type,), dest_type=bool_type, c_expression="{src0} != 0.0"),
479   # Float16-to-boolean conversion.
480   operation("f162b", 1, source_types=(float_type,), dest_type=bool_type, c_expression="{src0} != 0.0"),
481   # 'Bit-identical int-to-float "conversion"
482   operation("bitcast_i2f", 1, source_types=(int_type,), dest_type=float_type, c_expression="bitcast_u2f({src0})"),
483   # 'Bit-identical float-to-int "conversion"
484   operation("bitcast_f2i", 1, source_types=(float_type,), dest_type=int_type, c_expression="bitcast_f2u({src0})"),
485   # 'Bit-identical uint-to-float "conversion"
486   operation("bitcast_u2f", 1, source_types=(uint_type,), dest_type=float_type, c_expression="bitcast_u2f({src0})"),
487   # 'Bit-identical float-to-uint "conversion"
488   operation("bitcast_f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="bitcast_f2u({src0})"),
489   # Bit-identical u64-to-double "conversion"
490   operation("bitcast_u642d", 1, source_types=(uint64_type,), dest_type=double_type, c_expression="bitcast_u642d({src0})"),
491   # Bit-identical i64-to-double "conversion"
492   operation("bitcast_i642d", 1, source_types=(int64_type,), dest_type=double_type, c_expression="bitcast_i642d({src0})"),
493   # Bit-identical double-to_u64 "conversion"
494   operation("bitcast_d2u64", 1, source_types=(double_type,), dest_type=uint64_type, c_expression="bitcast_d2u64({src0})"),
495   # Bit-identical double-to-i64 "conversion"
496   operation("bitcast_d2i64", 1, source_types=(double_type,), dest_type=int64_type, c_expression="bitcast_d2i64({src0})"),
497   # i64-to-i32 conversion
498   operation("i642i", 1, source_types=(int64_type,), dest_type=int_type, c_expression="{src0}"),
499   # ui64-to-i32 conversion
500   operation("u642i", 1, source_types=(uint64_type,), dest_type=int_type, c_expression="{src0}"),
501   operation("i642u", 1, source_types=(int64_type,), dest_type=uint_type, c_expression="{src0}"),
502   operation("u642u", 1, source_types=(uint64_type,), dest_type=uint_type, c_expression="{src0}"),
503   operation("i642b", 1, source_types=(int64_type,), dest_type=bool_type, c_expression="{src0} != 0"),
504   operation("i642f", 1, source_types=(int64_type,), dest_type=float_type, c_expression="{src0}"),
505   operation("u642f", 1, source_types=(uint64_type,), dest_type=float_type, c_expression="{src0}"),
506   operation("i642d", 1, source_types=(int64_type,), dest_type=double_type, c_expression="{src0}"),
507   operation("u642d", 1, source_types=(uint64_type,), dest_type=double_type, c_expression="{src0}"),
508   operation("i2i64", 1, source_types=(int_type,), dest_type=int64_type, c_expression="{src0}"),
509   operation("u2i64", 1, source_types=(uint_type,), dest_type=int64_type, c_expression="{src0}"),
510   operation("b2i64", 1, source_types=(bool_type,), dest_type=int64_type, c_expression="{src0}"),
511   operation("f2i64", 1, source_types=(float_type,), dest_type=int64_type, c_expression="{src0}"),
512   operation("d2i64", 1, source_types=(double_type,), dest_type=int64_type, c_expression="{src0}"),
513   operation("i2u64", 1, source_types=(int_type,), dest_type=uint64_type, c_expression="{src0}"),
514   operation("u2u64", 1, source_types=(uint_type,), dest_type=uint64_type, c_expression="{src0}"),
515   operation("f2u64", 1, source_types=(float_type,), dest_type=uint64_type, c_expression="{src0}"),
516   operation("d2u64", 1, source_types=(double_type,), dest_type=uint64_type, c_expression="{src0}"),
517   operation("u642i64", 1, source_types=(uint64_type,), dest_type=int64_type, c_expression="{src0}"),
518   operation("i642u64", 1, source_types=(int64_type,), dest_type=uint64_type, c_expression="{src0}"),
519
520
521   # Unary floating-point rounding operations.
522   operation("trunc", 1, source_types=real_types, c_expression={'f': "truncf({src0})", 'd': "trunc({src0})"}),
523   operation("ceil", 1, source_types=real_types, c_expression={'f': "ceilf({src0})", 'd': "ceil({src0})"}),
524   operation("floor", 1, source_types=real_types, c_expression={'f': "floorf({src0})", 'd': "floor({src0})"}),
525   operation("fract", 1, source_types=real_types, c_expression={'f': "{src0} - floorf({src0})", 'd': "{src0} - floor({src0})"}),
526   operation("round_even", 1, source_types=real_types, c_expression={'f': "_mesa_roundevenf({src0})", 'd': "_mesa_roundeven({src0})"}),
527
528   # Trigonometric operations.
529   operation("sin", 1, source_types=(float_type,), c_expression="sinf({src0})"),
530   operation("cos", 1, source_types=(float_type,), c_expression="cosf({src0})"),
531   operation("atan", 1, source_types=(float_type,), c_expression="atan({src0})"),
532
533   # Partial derivatives.
534   operation("dFdx", 1, source_types=(float_type,), c_expression="0.0f"),
535   operation("dFdx_coarse", 1, printable_name="dFdxCoarse", source_types=(float_type,), c_expression="0.0f"),
536   operation("dFdx_fine", 1, printable_name="dFdxFine", source_types=(float_type,), c_expression="0.0f"),
537   operation("dFdy", 1, source_types=(float_type,), c_expression="0.0f"),
538   operation("dFdy_coarse", 1, printable_name="dFdyCoarse", source_types=(float_type,), c_expression="0.0f"),
539   operation("dFdy_fine", 1, printable_name="dFdyFine", source_types=(float_type,), c_expression="0.0f"),
540
541   # Floating point pack and unpack operations.
542   operation("pack_snorm_2x16", 1, printable_name="packSnorm2x16", source_types=(float_type,), dest_type=uint_type, c_expression="pack_2x16(pack_snorm_1x16, op[0]->value.f[0], op[0]->value.f[1])", flags=horizontal_operation),
543   operation("pack_snorm_4x8", 1, printable_name="packSnorm4x8", source_types=(float_type,), dest_type=uint_type, c_expression="pack_4x8(pack_snorm_1x8, op[0]->value.f[0], op[0]->value.f[1], op[0]->value.f[2], op[0]->value.f[3])", flags=horizontal_operation),
544   operation("pack_unorm_2x16", 1, printable_name="packUnorm2x16", source_types=(float_type,), dest_type=uint_type, c_expression="pack_2x16(pack_unorm_1x16, op[0]->value.f[0], op[0]->value.f[1])", flags=horizontal_operation),
545   operation("pack_unorm_4x8", 1, printable_name="packUnorm4x8", source_types=(float_type,), dest_type=uint_type, c_expression="pack_4x8(pack_unorm_1x8, op[0]->value.f[0], op[0]->value.f[1], op[0]->value.f[2], op[0]->value.f[3])", flags=horizontal_operation),
546   operation("pack_half_2x16", 1, printable_name="packHalf2x16", source_types=(float_type,), dest_type=uint_type, c_expression="pack_2x16(pack_half_1x16, op[0]->value.f[0], op[0]->value.f[1])", flags=horizontal_operation),
547   operation("unpack_snorm_2x16", 1, printable_name="unpackSnorm2x16", source_types=(uint_type,), dest_type=float_type, c_expression="unpack_2x16(unpack_snorm_1x16, op[0]->value.u[0], &data.f[0], &data.f[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
548   operation("unpack_snorm_4x8", 1, printable_name="unpackSnorm4x8", source_types=(uint_type,), dest_type=float_type, c_expression="unpack_4x8(unpack_snorm_1x8, op[0]->value.u[0], &data.f[0], &data.f[1], &data.f[2], &data.f[3])", flags=frozenset((horizontal_operation, non_assign_operation))),
549   operation("unpack_unorm_2x16", 1, printable_name="unpackUnorm2x16", source_types=(uint_type,), dest_type=float_type, c_expression="unpack_2x16(unpack_unorm_1x16, op[0]->value.u[0], &data.f[0], &data.f[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
550   operation("unpack_unorm_4x8", 1, printable_name="unpackUnorm4x8", source_types=(uint_type,), dest_type=float_type, c_expression="unpack_4x8(unpack_unorm_1x8, op[0]->value.u[0], &data.f[0], &data.f[1], &data.f[2], &data.f[3])", flags=frozenset((horizontal_operation, non_assign_operation))),
551   operation("unpack_half_2x16", 1, printable_name="unpackHalf2x16", source_types=(uint_type,), dest_type=float_type, c_expression="unpack_2x16(unpack_half_1x16, op[0]->value.u[0], &data.f[0], &data.f[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
552
553   # Bit operations, part of ARB_gpu_shader5.
554   operation("bitfield_reverse", 1, source_types=(uint_type, int_type), c_expression="bitfield_reverse({src0})"),
555   operation("bit_count", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression="util_bitcount({src0})"),
556   operation("find_msb", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression={'u': "find_msb_uint({src0})", 'i': "find_msb_int({src0})"}),
557   operation("find_lsb", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression="find_msb_uint({src0} & -{src0})"),
558   operation("clz", 1, source_types=(uint_type,), dest_type=uint_type, c_expression="(unsigned)(31 - find_msb_uint({src0}))"),
559
560   operation("saturate", 1, printable_name="sat", source_types=(float_type,), c_expression="CLAMP({src0}, 0.0f, 1.0f)"),
561
562   # Double packing, part of ARB_gpu_shader_fp64.
563   operation("pack_double_2x32", 1, printable_name="packDouble2x32", source_types=(uint_type,), dest_type=double_type, c_expression="data.u64[0] = pack_2x32(op[0]->value.u[0], op[0]->value.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
564   operation("unpack_double_2x32", 1, printable_name="unpackDouble2x32", source_types=(double_type,), dest_type=uint_type, c_expression="unpack_2x32(op[0]->value.u64[0], &data.u[0], &data.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
565
566   # Sampler/Image packing, part of ARB_bindless_texture.
567   operation("pack_sampler_2x32", 1, printable_name="packSampler2x32", source_types=(uint_type,), dest_type=uint64_type, c_expression="data.u64[0] = pack_2x32(op[0]->value.u[0], op[0]->value.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
568   operation("pack_image_2x32", 1, printable_name="packImage2x32", source_types=(uint_type,), dest_type=uint64_type, c_expression="data.u64[0] = pack_2x32(op[0]->value.u[0], op[0]->value.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
569   operation("unpack_sampler_2x32", 1, printable_name="unpackSampler2x32", source_types=(uint64_type,), dest_type=uint_type, c_expression="unpack_2x32(op[0]->value.u64[0], &data.u[0], &data.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
570   operation("unpack_image_2x32", 1, printable_name="unpackImage2x32", source_types=(uint64_type,), dest_type=uint_type, c_expression="unpack_2x32(op[0]->value.u64[0], &data.u[0], &data.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
571
572   operation("frexp_sig", 1),
573   operation("frexp_exp", 1),
574
575   operation("subroutine_to_int", 1),
576
577   # Interpolate fs input at centroid
578   #
579   # operand0 is the fs input.
580   operation("interpolate_at_centroid", 1),
581
582   # Ask the driver for the total size of a buffer block.
583   # operand0 is the ir_constant buffer block index in the linked shader.
584   operation("get_buffer_size", 1),
585
586   # Calculate length of an unsized array inside a buffer block.
587   # This opcode is going to be replaced in a lowering pass inside
588   # the linker.
589   #
590   # operand0 is the unsized array's ir_value for the calculation
591   # of its length.
592   operation("ssbo_unsized_array_length", 1),
593
594   # Calculate length of an implicitly sized array.
595   # This opcode is going to be replaced with a constant expression at link
596   # time.
597   operation("implicitly_sized_array_length", 1),
598
599   # 64-bit integer packing ops.
600   operation("pack_int_2x32", 1, printable_name="packInt2x32", source_types=(int_type,), dest_type=int64_type, c_expression="data.u64[0] = pack_2x32(op[0]->value.u[0], op[0]->value.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
601   operation("pack_uint_2x32", 1, printable_name="packUint2x32", source_types=(uint_type,), dest_type=uint64_type, c_expression="data.u64[0] = pack_2x32(op[0]->value.u[0], op[0]->value.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
602   operation("unpack_int_2x32", 1, printable_name="unpackInt2x32", source_types=(int64_type,), dest_type=int_type, c_expression="unpack_2x32(op[0]->value.u64[0], &data.u[0], &data.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
603   operation("unpack_uint_2x32", 1, printable_name="unpackUint2x32", source_types=(uint64_type,), dest_type=uint_type, c_expression="unpack_2x32(op[0]->value.u64[0], &data.u[0], &data.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
604
605   operation("add", 2, printable_name="+", source_types=numeric_types, c_expression="{src0} + {src1}", flags=vector_scalar_operation),
606   operation("sub", 2, printable_name="-", source_types=numeric_types, c_expression="{src0} - {src1}", flags=vector_scalar_operation),
607   operation("add_sat", 2, printable_name="add_sat", source_types=integer_types, c_expression={
608      'u': "({src0} + {src1}) < {src0} ? UINT32_MAX : ({src0} + {src1})",
609      'i': "iadd_saturate({src0}, {src1})",
610      'u64': "({src0} + {src1}) < {src0} ? UINT64_MAX : ({src0} + {src1})",
611      'i64': "iadd64_saturate({src0}, {src1})"
612   }),
613   operation("sub_sat", 2, printable_name="sub_sat", source_types=integer_types, c_expression={
614      'u': "({src1} > {src0}) ? 0 : {src0} - {src1}",
615      'i': "isub_saturate({src0}, {src1})",
616      'u64': "({src1} > {src0}) ? 0 : {src0} - {src1}",
617      'i64': "isub64_saturate({src0}, {src1})"
618   }),
619   operation("abs_sub", 2, printable_name="abs_sub", source_types=integer_types, c_expression={
620      'u': "({src1} > {src0}) ? {src1} - {src0} : {src0} - {src1}",
621      'i': "({src1} > {src0}) ? (unsigned){src1} - (unsigned){src0} : (unsigned){src0} - (unsigned){src1}",
622      'u64': "({src1} > {src0}) ? {src1} - {src0} : {src0} - {src1}",
623      'i64': "({src1} > {src0}) ? (uint64_t){src1} - (uint64_t){src0} : (uint64_t){src0} - (uint64_t){src1}",
624   }),
625   operation("avg", 2, printable_name="average", source_types=integer_types, c_expression="({src0} >> 1) + ({src1} >> 1) + (({src0} & {src1}) & 1)"),
626   operation("avg_round", 2, printable_name="average_rounded", source_types=integer_types, c_expression="({src0} >> 1) + ({src1} >> 1) + (({src0} | {src1}) & 1)"),
627
628   # "Floating-point or low 32-bit integer multiply."
629   operation("mul", 2, printable_name="*", source_types=numeric_types, c_expression="{src0} * {src1}"),
630   operation("mul_32x16", 2, printable_name="*", source_types=(uint_type, int_type), c_expression={
631      'u': "{src0} * (uint16_t){src1}",
632      'i': "{src0} * (int16_t){src0}"
633   }),
634   operation("imul_high", 2),       # Calculates the high 32-bits of a 64-bit multiply.
635   operation("div", 2, printable_name="/", source_types=numeric_types, c_expression={'u': "{src1} == 0 ? 0 : {src0} / {src1}", 'i': "{src1} == 0 ? 0 : {src0} / {src1}", 'u64': "{src1} == 0 ? 0 : {src0} / {src1}", 'i64': "{src1} == 0 ? 0 : {src0} / {src1}", 'default': "{src0} / {src1}"}, flags=vector_scalar_operation),
636
637   # Returns the carry resulting from the addition of the two arguments.
638   operation("carry", 2),
639
640   # Returns the borrow resulting from the subtraction of the second argument
641   # from the first argument.
642   operation("borrow", 2),
643
644   # Either (vector % vector) or (vector % scalar)
645   #
646   # We don't use fmod because it rounds toward zero; GLSL specifies the use
647   # of floor.
648   operation("mod", 2, printable_name="%", source_types=numeric_types, c_expression={'u': "{src1} == 0 ? 0 : {src0} % {src1}", 'i': "{src1} == 0 ? 0 : {src0} % {src1}", 'f': "{src0} - {src1} * floorf({src0} / {src1})", 'd': "{src0} - {src1} * floor({src0} / {src1})", 'u64': "{src1} == 0 ? 0 : {src0} % {src1}", 'i64': "{src1} == 0 ? 0 : {src0} % {src1}"}, flags=vector_scalar_operation),
649
650   # Binary comparison operators which return a boolean vector.
651   # The type of both operands must be equal.
652   operation("less", 2, printable_name="<", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} < {src1}"),
653   operation("gequal", 2, printable_name=">=", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} >= {src1}"),
654   operation("equal", 2, printable_name="==", source_types=all_types, dest_type=bool_type, c_expression="{src0} == {src1}"),
655   operation("nequal", 2, printable_name="!=", source_types=all_types, dest_type=bool_type, c_expression="{src0} != {src1}"),
656
657   # Returns single boolean for whether all components of operands[0]
658   # equal the components of operands[1].
659   operation("all_equal", 2, source_types=all_types, dest_type=bool_type, c_expression="op[0]->has_value(op[1])", flags=frozenset((horizontal_operation, types_identical_operation))),
660
661   # Returns single boolean for whether any component of operands[0]
662   # is not equal to the corresponding component of operands[1].
663   operation("any_nequal", 2, source_types=all_types, dest_type=bool_type, c_expression="!op[0]->has_value(op[1])", flags=frozenset((horizontal_operation, types_identical_operation))),
664
665   # Bit-wise binary operations.
666   operation("lshift", 2, printable_name="<<", source_types=integer_types, c_expression="{src0} << {src1}", flags=frozenset((vector_scalar_operation, mixed_type_operation))),
667   operation("rshift", 2, printable_name=">>", source_types=integer_types, c_expression="{src0} >> {src1}", flags=frozenset((vector_scalar_operation, mixed_type_operation))),
668   operation("bit_and", 2, printable_name="&", source_types=integer_types, c_expression="{src0} & {src1}", flags=vector_scalar_operation),
669   operation("bit_xor", 2, printable_name="^", source_types=integer_types, c_expression="{src0} ^ {src1}", flags=vector_scalar_operation),
670   operation("bit_or", 2, printable_name="|", source_types=integer_types, c_expression="{src0} | {src1}", flags=vector_scalar_operation),
671
672   operation("logic_and", 2, printable_name="&&", source_types=(bool_type,), c_expression="{src0} && {src1}"),
673   operation("logic_xor", 2, printable_name="^^", source_types=(bool_type,), c_expression="{src0} != {src1}"),
674   operation("logic_or", 2, printable_name="||", source_types=(bool_type,), c_expression="{src0} || {src1}"),
675
676   operation("dot", 2, source_types=real_types, c_expression={'f': "dot_f(op[0], op[1])", 'd': "dot_d(op[0], op[1])"}, flags=horizontal_operation),
677   operation("min", 2, source_types=numeric_types, c_expression="MIN2({src0}, {src1})", flags=vector_scalar_operation),
678   operation("max", 2, source_types=numeric_types, c_expression="MAX2({src0}, {src1})", flags=vector_scalar_operation),
679
680   operation("pow", 2, source_types=(float_type,), c_expression="powf({src0}, {src1})"),
681
682   # Load a value the size of a given GLSL type from a uniform block.
683   #
684   # operand0 is the ir_constant uniform block index in the linked shader.
685   # operand1 is a byte offset within the uniform block.
686   operation("ubo_load", 2),
687
688   # Multiplies a number by two to a power, part of ARB_gpu_shader5.
689   operation("ldexp", 2,
690             all_signatures=((float_type, (float_type, int_type)),
691                             (double_type, (double_type, int_type))),
692             c_expression={'f': "ldexpf_flush_subnormal({src0}, {src1})",
693                           'd': "ldexp_flush_subnormal({src0}, {src1})"}),
694
695   # Extract a scalar from a vector
696   #
697   # operand0 is the vector
698   # operand1 is the index of the field to read from operand0
699   operation("vector_extract", 2, source_types=all_types, c_expression="anything-except-None"),
700
701   # Interpolate fs input at offset
702   #
703   # operand0 is the fs input
704   # operand1 is the offset from the pixel center
705   operation("interpolate_at_offset", 2),
706
707   # Interpolate fs input at sample position
708   #
709   # operand0 is the fs input
710   # operand1 is the sample ID
711   operation("interpolate_at_sample", 2),
712
713   operation("atan2", 2, source_types=(float_type,), c_expression="atan2({src0}, {src1})"),
714
715   # Fused floating-point multiply-add, part of ARB_gpu_shader5.
716   operation("fma", 3, source_types=real_types, c_expression="{src0} * {src1} + {src2}"),
717
718   operation("lrp", 3, source_types=real_types, c_expression={'f': "{src0} * (1.0f - {src2}) + ({src1} * {src2})", 'd': "{src0} * (1.0 - {src2}) + ({src1} * {src2})"}),
719
720   # Conditional Select
721   #
722   # A vector conditional select instruction (like ?:, but operating per-
723   # component on vectors).
724   #
725   # See also lower_instructions_visitor::ldexp_to_arith
726   operation("csel", 3,
727             all_signatures=zip(all_types, zip(len(all_types) * (bool_type,), all_types, all_types)),
728             c_expression="{src0} ? {src1} : {src2}"),
729
730   operation("bitfield_extract", 3,
731             all_signatures=((int_type, (uint_type, int_type, int_type)),
732                             (int_type, (int_type, int_type, int_type))),
733             c_expression={'u': "bitfield_extract_uint({src0}, {src1}, {src2})",
734                           'i': "bitfield_extract_int({src0}, {src1}, {src2})"}),
735
736   # Generate a value with one field of a vector changed
737   #
738   # operand0 is the vector
739   # operand1 is the value to write into the vector result
740   # operand2 is the index in operand0 to be modified
741   operation("vector_insert", 3, source_types=all_types, c_expression="anything-except-None"),
742
743   operation("bitfield_insert", 4,
744             all_signatures=((uint_type, (uint_type, uint_type, int_type, int_type)),
745                             (int_type, (int_type, int_type, int_type, int_type))),
746             c_expression="bitfield_insert({src0}, {src1}, {src2}, {src3})"),
747
748   operation("vector", 4, source_types=all_types, c_expression="anything-except-None"),
749]
750
751
752if __name__ == "__main__":
753   copyright = """/*
754 * Copyright (C) 2010 Intel Corporation
755 *
756 * Permission is hereby granted, free of charge, to any person obtaining a
757 * copy of this software and associated documentation files (the "Software"),
758 * to deal in the Software without restriction, including without limitation
759 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
760 * and/or sell copies of the Software, and to permit persons to whom the
761 * Software is furnished to do so, subject to the following conditions:
762 *
763 * The above copyright notice and this permission notice (including the next
764 * paragraph) shall be included in all copies or substantial portions of the
765 * Software.
766 *
767 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
768 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
769 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
770 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
771 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
772 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
773 * DEALINGS IN THE SOFTWARE.
774 */
775"""
776   enum_template = mako.template.Template(copyright + """
777enum ir_expression_operation {
778% for item in values:
779   ${item.get_enum_name()},
780% endfor
781
782   /* Sentinels marking the last of each kind of operation. */
783% for item in lasts:
784   ir_last_${("un", "bin", "tri", "quad")[item.num_operands - 1]}op = ${item.get_enum_name()},
785% endfor
786   ir_last_opcode = ir_quadop_${lasts[3].name}
787};""")
788
789   strings_template = mako.template.Template(copyright + """
790const char *const ir_expression_operation_strings[] = {
791% for item in values:
792   "${item.printable_name}",
793% endfor
794};
795
796const char *const ir_expression_operation_enum_strings[] = {
797% for item in values:
798   "${item.name}",
799% endfor
800};""")
801
802   constant_template = mako.template.Template("""\
803   switch (this->operation) {
804% for op in values:
805    % if op.c_expression is not None:
806${op.get_template()}
807
808    % endif
809% endfor
810   default:
811      /* FINISHME: Should handle all expression types. */
812      return NULL;
813   }
814""")
815
816   if sys.argv[1] == "enum":
817      lasts = [None, None, None, None]
818      for item in reversed(ir_expression_operation):
819         i = item.num_operands - 1
820         if lasts[i] is None:
821            lasts[i] = item
822
823      print(enum_template.render(values=ir_expression_operation,
824                                 lasts=lasts))
825   elif sys.argv[1] == "strings":
826      print(strings_template.render(values=ir_expression_operation))
827   elif sys.argv[1] == "constant":
828      print(constant_template.render(values=ir_expression_operation))
829