101e04c3fSmrg# 201e04c3fSmrg# Copyright (C) 2015 Intel Corporation 301e04c3fSmrg# 401e04c3fSmrg# Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg# copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg# to deal in the Software without restriction, including without limitation 701e04c3fSmrg# the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg# and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg# Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg# 1101e04c3fSmrg# The above copyright notice and this permission notice (including the next 1201e04c3fSmrg# paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg# Software. 1401e04c3fSmrg# 1501e04c3fSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg# IN THE SOFTWARE. 2201e04c3fSmrg 2301e04c3fSmrgimport mako.template 2401e04c3fSmrgimport sys 2501e04c3fSmrg 2601e04c3fSmrgclass type(object): 2701e04c3fSmrg def __init__(self, c_type, union_field, glsl_type): 2801e04c3fSmrg self.c_type = c_type 2901e04c3fSmrg self.union_field = union_field 3001e04c3fSmrg self.glsl_type = glsl_type 3101e04c3fSmrg 3201e04c3fSmrg 3301e04c3fSmrgclass type_signature_iter(object): 3401e04c3fSmrg """Basic iterator for a set of type signatures. Various kinds of sequences of 3501e04c3fSmrg types come in, and an iteration of type_signature objects come out. 3601e04c3fSmrg 3701e04c3fSmrg """ 3801e04c3fSmrg 3901e04c3fSmrg def __init__(self, source_types, num_operands): 4001e04c3fSmrg """Initialize an iterator from a sequence of input types and a number 4101e04c3fSmrg operands. This is for signatures where all the operands have the same 4201e04c3fSmrg type and the result type of the operation is the same as the input type. 4301e04c3fSmrg 4401e04c3fSmrg """ 4501e04c3fSmrg self.dest_type = None 4601e04c3fSmrg self.source_types = source_types 4701e04c3fSmrg self.num_operands = num_operands 4801e04c3fSmrg self.i = 0 4901e04c3fSmrg 5001e04c3fSmrg def __init__(self, dest_type, source_types, num_operands): 5101e04c3fSmrg """Initialize an iterator from a result tpye, a sequence of input types and a 5201e04c3fSmrg number operands. This is for signatures where all the operands have the 5301e04c3fSmrg same type but the result type of the operation is different from the 5401e04c3fSmrg input type. 5501e04c3fSmrg 5601e04c3fSmrg """ 5701e04c3fSmrg self.dest_type = dest_type 5801e04c3fSmrg self.source_types = source_types 5901e04c3fSmrg self.num_operands = num_operands 6001e04c3fSmrg self.i = 0 6101e04c3fSmrg 6201e04c3fSmrg def __iter__(self): 6301e04c3fSmrg return self 6401e04c3fSmrg 6501e04c3fSmrg def __next__(self): 6601e04c3fSmrg if self.i < len(self.source_types): 6701e04c3fSmrg i = self.i 6801e04c3fSmrg self.i += 1 6901e04c3fSmrg 7001e04c3fSmrg if self.dest_type is None: 7101e04c3fSmrg dest_type = self.source_types[i] 7201e04c3fSmrg else: 7301e04c3fSmrg dest_type = self.dest_type 7401e04c3fSmrg 7501e04c3fSmrg return (dest_type, self.num_operands * (self.source_types[i],)) 7601e04c3fSmrg else: 7701e04c3fSmrg raise StopIteration() 7801e04c3fSmrg 7901e04c3fSmrg next = __next__ 8001e04c3fSmrg 8101e04c3fSmrg 8201e04c3fSmrguint_type = type("unsigned", "u", "GLSL_TYPE_UINT") 8301e04c3fSmrgint_type = type("int", "i", "GLSL_TYPE_INT") 8401e04c3fSmrguint64_type = type("uint64_t", "u64", "GLSL_TYPE_UINT64") 8501e04c3fSmrgint64_type = type("int64_t", "i64", "GLSL_TYPE_INT64") 8601e04c3fSmrgfloat_type = type("float", "f", "GLSL_TYPE_FLOAT") 8701e04c3fSmrgdouble_type = type("double", "d", "GLSL_TYPE_DOUBLE") 8801e04c3fSmrgbool_type = type("bool", "b", "GLSL_TYPE_BOOL") 8901e04c3fSmrg 9001e04c3fSmrgall_types = (uint_type, int_type, float_type, double_type, uint64_type, int64_type, bool_type) 9101e04c3fSmrgnumeric_types = (uint_type, int_type, float_type, double_type, uint64_type, int64_type) 9201e04c3fSmrgsigned_numeric_types = (int_type, float_type, double_type, int64_type) 9301e04c3fSmrginteger_types = (uint_type, int_type, uint64_type, int64_type) 9401e04c3fSmrgreal_types = (float_type, double_type) 9501e04c3fSmrg 9601e04c3fSmrg# This template is for operations that can have operands of a several 9701e04c3fSmrg# different types, and each type may or may not has a different C expression. 9801e04c3fSmrg# This is used by most operations. 9901e04c3fSmrgconstant_template_common = mako.template.Template("""\ 10001e04c3fSmrg case ${op.get_enum_name()}: 10101e04c3fSmrg for (unsigned c = 0; c < op[0]->type->components(); c++) { 10201e04c3fSmrg switch (op[0]->type->base_type) { 10301e04c3fSmrg % for dst_type, src_types in op.signatures(): 10401e04c3fSmrg case ${src_types[0].glsl_type}: 10501e04c3fSmrg data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types)}; 10601e04c3fSmrg break; 10701e04c3fSmrg % endfor 10801e04c3fSmrg default: 10901e04c3fSmrg unreachable("invalid type"); 11001e04c3fSmrg } 11101e04c3fSmrg } 11201e04c3fSmrg break;""") 11301e04c3fSmrg 11401e04c3fSmrg# This template is for binary operations that can operate on some combination 11501e04c3fSmrg# of scalar and vector operands. 11601e04c3fSmrgconstant_template_vector_scalar = mako.template.Template("""\ 11701e04c3fSmrg case ${op.get_enum_name()}: 11801e04c3fSmrg % if "mixed" in op.flags: 11901e04c3fSmrg % for i in range(op.num_operands): 12001e04c3fSmrg assert(op[${i}]->type->base_type == ${op.source_types[0].glsl_type} || 12101e04c3fSmrg % for src_type in op.source_types[1:-1]: 12201e04c3fSmrg op[${i}]->type->base_type == ${src_type.glsl_type} || 12301e04c3fSmrg % endfor 12401e04c3fSmrg op[${i}]->type->base_type == ${op.source_types[-1].glsl_type}); 12501e04c3fSmrg % endfor 12601e04c3fSmrg % else: 12701e04c3fSmrg assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 12801e04c3fSmrg % endif 12901e04c3fSmrg for (unsigned c = 0, c0 = 0, c1 = 0; 13001e04c3fSmrg c < components; 13101e04c3fSmrg c0 += c0_inc, c1 += c1_inc, c++) { 13201e04c3fSmrg 13301e04c3fSmrg switch (op[0]->type->base_type) { 13401e04c3fSmrg % for dst_type, src_types in op.signatures(): 13501e04c3fSmrg case ${src_types[0].glsl_type}: 13601e04c3fSmrg data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types, ("c0", "c1", "c2"))}; 13701e04c3fSmrg break; 13801e04c3fSmrg % endfor 13901e04c3fSmrg default: 14001e04c3fSmrg unreachable("invalid type"); 14101e04c3fSmrg } 14201e04c3fSmrg } 14301e04c3fSmrg break;""") 14401e04c3fSmrg 14501e04c3fSmrg# This template is for multiplication. It is unique because it has to support 14601e04c3fSmrg# matrix * vector and matrix * matrix operations, and those are just different. 14701e04c3fSmrgconstant_template_mul = mako.template.Template("""\ 14801e04c3fSmrg case ${op.get_enum_name()}: 14901e04c3fSmrg /* Check for equal types, or unequal types involving scalars */ 15001e04c3fSmrg if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix()) 15101e04c3fSmrg || op0_scalar || op1_scalar) { 15201e04c3fSmrg for (unsigned c = 0, c0 = 0, c1 = 0; 15301e04c3fSmrg c < components; 15401e04c3fSmrg c0 += c0_inc, c1 += c1_inc, c++) { 15501e04c3fSmrg 15601e04c3fSmrg switch (op[0]->type->base_type) { 15701e04c3fSmrg % for dst_type, src_types in op.signatures(): 15801e04c3fSmrg case ${src_types[0].glsl_type}: 15901e04c3fSmrg data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types, ("c0", "c1", "c2"))}; 16001e04c3fSmrg break; 16101e04c3fSmrg % endfor 16201e04c3fSmrg default: 16301e04c3fSmrg unreachable("invalid type"); 16401e04c3fSmrg } 16501e04c3fSmrg } 16601e04c3fSmrg } else { 16701e04c3fSmrg assert(op[0]->type->is_matrix() || op[1]->type->is_matrix()); 16801e04c3fSmrg 16901e04c3fSmrg /* Multiply an N-by-M matrix with an M-by-P matrix. Since either 17001e04c3fSmrg * matrix can be a GLSL vector, either N or P can be 1. 17101e04c3fSmrg * 17201e04c3fSmrg * For vec*mat, the vector is treated as a row vector. This 17301e04c3fSmrg * means the vector is a 1-row x M-column matrix. 17401e04c3fSmrg * 17501e04c3fSmrg * For mat*vec, the vector is treated as a column vector. Since 17601e04c3fSmrg * matrix_columns is 1 for vectors, this just works. 17701e04c3fSmrg */ 17801e04c3fSmrg const unsigned n = op[0]->type->is_vector() 17901e04c3fSmrg ? 1 : op[0]->type->vector_elements; 18001e04c3fSmrg const unsigned m = op[1]->type->vector_elements; 18101e04c3fSmrg const unsigned p = op[1]->type->matrix_columns; 18201e04c3fSmrg for (unsigned j = 0; j < p; j++) { 18301e04c3fSmrg for (unsigned i = 0; i < n; i++) { 18401e04c3fSmrg for (unsigned k = 0; k < m; k++) { 18501e04c3fSmrg if (op[0]->type->is_double()) 18601e04c3fSmrg data.d[i+n*j] += op[0]->value.d[i+n*k]*op[1]->value.d[k+m*j]; 18701e04c3fSmrg else 18801e04c3fSmrg data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j]; 18901e04c3fSmrg } 19001e04c3fSmrg } 19101e04c3fSmrg } 19201e04c3fSmrg } 19301e04c3fSmrg break;""") 19401e04c3fSmrg 19501e04c3fSmrg# This template is for operations that are horizontal and either have only a 19601e04c3fSmrg# single type or the implementation for all types is identical. That is, the 19701e04c3fSmrg# operation consumes a vector and produces a scalar. 19801e04c3fSmrgconstant_template_horizontal_single_implementation = mako.template.Template("""\ 19901e04c3fSmrg case ${op.get_enum_name()}: 20001e04c3fSmrg data.${op.dest_type.union_field}[0] = ${op.c_expression['default']}; 20101e04c3fSmrg break;""") 20201e04c3fSmrg 20301e04c3fSmrg# This template is for operations that are horizontal and do not assign the 20401e04c3fSmrg# result. The various unpack operations are examples. 20501e04c3fSmrgconstant_template_horizontal_nonassignment = mako.template.Template("""\ 20601e04c3fSmrg case ${op.get_enum_name()}: 20701e04c3fSmrg ${op.c_expression['default']}; 20801e04c3fSmrg break;""") 20901e04c3fSmrg 21001e04c3fSmrg# This template is for binary operations that are horizontal. That is, the 21101e04c3fSmrg# operation consumes a vector and produces a scalar. 21201e04c3fSmrgconstant_template_horizontal = mako.template.Template("""\ 21301e04c3fSmrg case ${op.get_enum_name()}: 21401e04c3fSmrg switch (op[0]->type->base_type) { 21501e04c3fSmrg % for dst_type, src_types in op.signatures(): 21601e04c3fSmrg case ${src_types[0].glsl_type}: 21701e04c3fSmrg data.${dst_type.union_field}[0] = ${op.get_c_expression(src_types)}; 21801e04c3fSmrg break; 21901e04c3fSmrg % endfor 22001e04c3fSmrg default: 22101e04c3fSmrg unreachable("invalid type"); 22201e04c3fSmrg } 22301e04c3fSmrg break;""") 22401e04c3fSmrg 22501e04c3fSmrg# This template is for ir_binop_vector_extract. 22601e04c3fSmrgconstant_template_vector_extract = mako.template.Template("""\ 22701e04c3fSmrg case ${op.get_enum_name()}: { 22801e04c3fSmrg const int c = CLAMP(op[1]->value.i[0], 0, 22901e04c3fSmrg (int) op[0]->type->vector_elements - 1); 23001e04c3fSmrg 23101e04c3fSmrg switch (op[0]->type->base_type) { 23201e04c3fSmrg % for dst_type, src_types in op.signatures(): 23301e04c3fSmrg case ${src_types[0].glsl_type}: 23401e04c3fSmrg data.${dst_type.union_field}[0] = op[0]->value.${src_types[0].union_field}[c]; 23501e04c3fSmrg break; 23601e04c3fSmrg % endfor 23701e04c3fSmrg default: 23801e04c3fSmrg unreachable("invalid type"); 23901e04c3fSmrg } 24001e04c3fSmrg break; 24101e04c3fSmrg }""") 24201e04c3fSmrg 24301e04c3fSmrg# This template is for ir_triop_vector_insert. 24401e04c3fSmrgconstant_template_vector_insert = mako.template.Template("""\ 24501e04c3fSmrg case ${op.get_enum_name()}: { 24601e04c3fSmrg const unsigned idx = op[2]->value.u[0]; 24701e04c3fSmrg 24801e04c3fSmrg memcpy(&data, &op[0]->value, sizeof(data)); 24901e04c3fSmrg 2507ec681f3Smrg switch (return_type->base_type) { 25101e04c3fSmrg % for dst_type, src_types in op.signatures(): 25201e04c3fSmrg case ${src_types[0].glsl_type}: 25301e04c3fSmrg data.${dst_type.union_field}[idx] = op[1]->value.${src_types[0].union_field}[0]; 25401e04c3fSmrg break; 25501e04c3fSmrg % endfor 25601e04c3fSmrg default: 25701e04c3fSmrg unreachable("invalid type"); 25801e04c3fSmrg } 25901e04c3fSmrg break; 26001e04c3fSmrg }""") 26101e04c3fSmrg 26201e04c3fSmrg# This template is for ir_quadop_vector. 26301e04c3fSmrgconstant_template_vector = mako.template.Template("""\ 26401e04c3fSmrg case ${op.get_enum_name()}: 2657ec681f3Smrg for (unsigned c = 0; c < return_type->vector_elements; c++) { 2667ec681f3Smrg switch (return_type->base_type) { 26701e04c3fSmrg % for dst_type, src_types in op.signatures(): 26801e04c3fSmrg case ${src_types[0].glsl_type}: 26901e04c3fSmrg data.${dst_type.union_field}[c] = op[c]->value.${src_types[0].union_field}[0]; 27001e04c3fSmrg break; 27101e04c3fSmrg % endfor 27201e04c3fSmrg default: 27301e04c3fSmrg unreachable("invalid type"); 27401e04c3fSmrg } 27501e04c3fSmrg } 27601e04c3fSmrg break;""") 27701e04c3fSmrg 27801e04c3fSmrg# This template is for ir_triop_lrp. 27901e04c3fSmrgconstant_template_lrp = mako.template.Template("""\ 28001e04c3fSmrg case ${op.get_enum_name()}: { 28101e04c3fSmrg assert(op[0]->type->is_float() || op[0]->type->is_double()); 28201e04c3fSmrg assert(op[1]->type->is_float() || op[1]->type->is_double()); 28301e04c3fSmrg assert(op[2]->type->is_float() || op[2]->type->is_double()); 28401e04c3fSmrg 28501e04c3fSmrg unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; 28601e04c3fSmrg for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) { 2877ec681f3Smrg switch (return_type->base_type) { 28801e04c3fSmrg % for dst_type, src_types in op.signatures(): 28901e04c3fSmrg case ${src_types[0].glsl_type}: 29001e04c3fSmrg data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types, ("c", "c", "c2"))}; 29101e04c3fSmrg break; 29201e04c3fSmrg % endfor 29301e04c3fSmrg default: 29401e04c3fSmrg unreachable("invalid type"); 29501e04c3fSmrg } 29601e04c3fSmrg } 29701e04c3fSmrg break; 29801e04c3fSmrg }""") 29901e04c3fSmrg 30001e04c3fSmrg# This template is for ir_triop_csel. This expression is really unique 30101e04c3fSmrg# because not all of the operands are the same type, and the second operand 30201e04c3fSmrg# determines the type of the expression (instead of the first). 30301e04c3fSmrgconstant_template_csel = mako.template.Template("""\ 30401e04c3fSmrg case ${op.get_enum_name()}: 30501e04c3fSmrg for (unsigned c = 0; c < components; c++) { 3067ec681f3Smrg switch (return_type->base_type) { 30701e04c3fSmrg % for dst_type, src_types in op.signatures(): 30801e04c3fSmrg case ${src_types[1].glsl_type}: 30901e04c3fSmrg data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types)}; 31001e04c3fSmrg break; 31101e04c3fSmrg % endfor 31201e04c3fSmrg default: 31301e04c3fSmrg unreachable("invalid type"); 31401e04c3fSmrg } 31501e04c3fSmrg } 31601e04c3fSmrg break;""") 31701e04c3fSmrg 31801e04c3fSmrg 31901e04c3fSmrgvector_scalar_operation = "vector-scalar" 32001e04c3fSmrghorizontal_operation = "horizontal" 32101e04c3fSmrgtypes_identical_operation = "identical" 32201e04c3fSmrgnon_assign_operation = "nonassign" 32301e04c3fSmrgmixed_type_operation = "mixed" 32401e04c3fSmrg 32501e04c3fSmrgclass operation(object): 32601e04c3fSmrg def __init__(self, name, num_operands, printable_name = None, source_types = None, dest_type = None, c_expression = None, flags = None, all_signatures = None): 32701e04c3fSmrg self.name = name 32801e04c3fSmrg self.num_operands = num_operands 32901e04c3fSmrg 33001e04c3fSmrg if printable_name is None: 33101e04c3fSmrg self.printable_name = name 33201e04c3fSmrg else: 33301e04c3fSmrg self.printable_name = printable_name 33401e04c3fSmrg 33501e04c3fSmrg self.all_signatures = all_signatures 33601e04c3fSmrg 33701e04c3fSmrg if source_types is None: 33801e04c3fSmrg self.source_types = tuple() 33901e04c3fSmrg else: 34001e04c3fSmrg self.source_types = source_types 34101e04c3fSmrg 34201e04c3fSmrg self.dest_type = dest_type 34301e04c3fSmrg 34401e04c3fSmrg if c_expression is None: 34501e04c3fSmrg self.c_expression = None 34601e04c3fSmrg elif isinstance(c_expression, str): 34701e04c3fSmrg self.c_expression = {'default': c_expression} 34801e04c3fSmrg else: 34901e04c3fSmrg self.c_expression = c_expression 35001e04c3fSmrg 35101e04c3fSmrg if flags is None: 35201e04c3fSmrg self.flags = frozenset() 35301e04c3fSmrg elif isinstance(flags, str): 35401e04c3fSmrg self.flags = frozenset([flags]) 35501e04c3fSmrg else: 35601e04c3fSmrg self.flags = frozenset(flags) 35701e04c3fSmrg 35801e04c3fSmrg 35901e04c3fSmrg def get_enum_name(self): 36001e04c3fSmrg return "ir_{0}op_{1}".format(("un", "bin", "tri", "quad")[self.num_operands-1], self.name) 36101e04c3fSmrg 36201e04c3fSmrg 36301e04c3fSmrg def get_template(self): 36401e04c3fSmrg if self.c_expression is None: 36501e04c3fSmrg return None 36601e04c3fSmrg 36701e04c3fSmrg if horizontal_operation in self.flags: 36801e04c3fSmrg if non_assign_operation in self.flags: 36901e04c3fSmrg return constant_template_horizontal_nonassignment.render(op=self) 37001e04c3fSmrg elif types_identical_operation in self.flags: 37101e04c3fSmrg return constant_template_horizontal_single_implementation.render(op=self) 37201e04c3fSmrg else: 37301e04c3fSmrg return constant_template_horizontal.render(op=self) 37401e04c3fSmrg 37501e04c3fSmrg if self.num_operands == 2: 37601e04c3fSmrg if self.name == "mul": 37701e04c3fSmrg return constant_template_mul.render(op=self) 37801e04c3fSmrg elif self.name == "vector_extract": 37901e04c3fSmrg return constant_template_vector_extract.render(op=self) 38001e04c3fSmrg elif vector_scalar_operation in self.flags: 38101e04c3fSmrg return constant_template_vector_scalar.render(op=self) 38201e04c3fSmrg elif self.num_operands == 3: 38301e04c3fSmrg if self.name == "vector_insert": 38401e04c3fSmrg return constant_template_vector_insert.render(op=self) 38501e04c3fSmrg elif self.name == "lrp": 38601e04c3fSmrg return constant_template_lrp.render(op=self) 38701e04c3fSmrg elif self.name == "csel": 38801e04c3fSmrg return constant_template_csel.render(op=self) 38901e04c3fSmrg elif self.num_operands == 4: 39001e04c3fSmrg if self.name == "vector": 39101e04c3fSmrg return constant_template_vector.render(op=self) 39201e04c3fSmrg 39301e04c3fSmrg return constant_template_common.render(op=self) 39401e04c3fSmrg 39501e04c3fSmrg 39601e04c3fSmrg def get_c_expression(self, types, indices=("c", "c", "c")): 39701e04c3fSmrg src0 = "op[0]->value.{0}[{1}]".format(types[0].union_field, indices[0]) 39801e04c3fSmrg src1 = "op[1]->value.{0}[{1}]".format(types[1].union_field, indices[1]) if len(types) >= 2 else "ERROR" 39901e04c3fSmrg src2 = "op[2]->value.{0}[{1}]".format(types[2].union_field, indices[2]) if len(types) >= 3 else "ERROR" 40001e04c3fSmrg src3 = "op[3]->value.{0}[c]".format(types[3].union_field) if len(types) >= 4 else "ERROR" 40101e04c3fSmrg 40201e04c3fSmrg expr = self.c_expression[types[0].union_field] if types[0].union_field in self.c_expression else self.c_expression['default'] 40301e04c3fSmrg 40401e04c3fSmrg return expr.format(src0=src0, 40501e04c3fSmrg src1=src1, 40601e04c3fSmrg src2=src2, 40701e04c3fSmrg src3=src3) 40801e04c3fSmrg 40901e04c3fSmrg 41001e04c3fSmrg def signatures(self): 41101e04c3fSmrg if self.all_signatures is not None: 41201e04c3fSmrg return self.all_signatures 41301e04c3fSmrg else: 41401e04c3fSmrg return type_signature_iter(self.dest_type, self.source_types, self.num_operands) 41501e04c3fSmrg 41601e04c3fSmrg 41701e04c3fSmrgir_expression_operation = [ 41801e04c3fSmrg operation("bit_not", 1, printable_name="~", source_types=integer_types, c_expression="~ {src0}"), 41901e04c3fSmrg operation("logic_not", 1, printable_name="!", source_types=(bool_type,), c_expression="!{src0}"), 4207ec681f3Smrg operation("neg", 1, source_types=numeric_types, c_expression={'u': "-((int) {src0})", 'u64': "-((int64_t) {src0})", 'default': "-{src0}"}), 42101e04c3fSmrg 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}"}), 42201e04c3fSmrg 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)"}), 42301e04c3fSmrg operation("rcp", 1, source_types=real_types, c_expression={'f': "1.0F / {src0}", 'd': "1.0 / {src0}"}), 42401e04c3fSmrg operation("rsq", 1, source_types=real_types, c_expression={'f': "1.0F / sqrtf({src0})", 'd': "1.0 / sqrt({src0})"}), 42501e04c3fSmrg operation("sqrt", 1, source_types=real_types, c_expression={'f': "sqrtf({src0})", 'd': "sqrt({src0})"}), 42601e04c3fSmrg operation("exp", 1, source_types=(float_type,), c_expression="expf({src0})"), # Log base e on gentype 42701e04c3fSmrg operation("log", 1, source_types=(float_type,), c_expression="logf({src0})"), # Natural log on gentype 42801e04c3fSmrg operation("exp2", 1, source_types=(float_type,), c_expression="exp2f({src0})"), 42901e04c3fSmrg operation("log2", 1, source_types=(float_type,), c_expression="log2f({src0})"), 43001e04c3fSmrg 43101e04c3fSmrg # Float-to-integer conversion. 43201e04c3fSmrg operation("f2i", 1, source_types=(float_type,), dest_type=int_type, c_expression="(int) {src0}"), 43301e04c3fSmrg # Float-to-unsigned conversion. 43401e04c3fSmrg operation("f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="(unsigned) {src0}"), 43501e04c3fSmrg # Integer-to-float conversion. 43601e04c3fSmrg operation("i2f", 1, source_types=(int_type,), dest_type=float_type, c_expression="(float) {src0}"), 43701e04c3fSmrg # Float-to-boolean conversion 43801e04c3fSmrg operation("f2b", 1, source_types=(float_type,), dest_type=bool_type, c_expression="{src0} != 0.0F ? true : false"), 43901e04c3fSmrg # Boolean-to-float conversion 44001e04c3fSmrg operation("b2f", 1, source_types=(bool_type,), dest_type=float_type, c_expression="{src0} ? 1.0F : 0.0F"), 4417ec681f3Smrg # Boolean-to-float16 conversion 4427ec681f3Smrg operation("b2f16", 1, source_types=(bool_type,), dest_type=float_type, c_expression="{src0} ? 1.0F : 0.0F"), 44301e04c3fSmrg # int-to-boolean conversion 44401e04c3fSmrg operation("i2b", 1, source_types=(uint_type, int_type), dest_type=bool_type, c_expression="{src0} ? true : false"), 44501e04c3fSmrg # Boolean-to-int conversion 44601e04c3fSmrg operation("b2i", 1, source_types=(bool_type,), dest_type=int_type, c_expression="{src0} ? 1 : 0"), 44701e04c3fSmrg # Unsigned-to-float conversion. 44801e04c3fSmrg operation("u2f", 1, source_types=(uint_type,), dest_type=float_type, c_expression="(float) {src0}"), 44901e04c3fSmrg # Integer-to-unsigned conversion. 45001e04c3fSmrg operation("i2u", 1, source_types=(int_type,), dest_type=uint_type, c_expression="{src0}"), 45101e04c3fSmrg # Unsigned-to-integer conversion. 45201e04c3fSmrg operation("u2i", 1, source_types=(uint_type,), dest_type=int_type, c_expression="{src0}"), 45301e04c3fSmrg # Double-to-float conversion. 45401e04c3fSmrg operation("d2f", 1, source_types=(double_type,), dest_type=float_type, c_expression="{src0}"), 45501e04c3fSmrg # Float-to-double conversion. 45601e04c3fSmrg operation("f2d", 1, source_types=(float_type,), dest_type=double_type, c_expression="{src0}"), 4577ec681f3Smrg # Half-float conversions. These all operate on and return float types, 4587ec681f3Smrg # since the framework expands half to full float before calling in. We 4597ec681f3Smrg # still have to handle them here so that we can constant propagate through 4607ec681f3Smrg # them, but they are no-ops. 4617ec681f3Smrg operation("f2f16", 1, source_types=(float_type,), dest_type=float_type, c_expression="{src0}"), 4627ec681f3Smrg operation("f2fmp", 1, source_types=(float_type,), dest_type=float_type, c_expression="{src0}"), 4637ec681f3Smrg operation("f162f", 1, source_types=(float_type,), dest_type=float_type, c_expression="{src0}"), 4647ec681f3Smrg # int16<->int32 conversion. 4657ec681f3Smrg operation("i2i", 1, source_types=(int_type,), dest_type=int_type, c_expression="{src0}"), 4667ec681f3Smrg operation("i2imp", 1, source_types=(int_type,), dest_type=int_type, c_expression="{src0}"), 4677ec681f3Smrg operation("u2u", 1, source_types=(uint_type,), dest_type=uint_type, c_expression="{src0}"), 4687ec681f3Smrg operation("u2ump", 1, source_types=(uint_type,), dest_type=uint_type, c_expression="{src0}"), 46901e04c3fSmrg # Double-to-integer conversion. 47001e04c3fSmrg operation("d2i", 1, source_types=(double_type,), dest_type=int_type, c_expression="{src0}"), 47101e04c3fSmrg # Integer-to-double conversion. 47201e04c3fSmrg operation("i2d", 1, source_types=(int_type,), dest_type=double_type, c_expression="{src0}"), 47301e04c3fSmrg # Double-to-unsigned conversion. 47401e04c3fSmrg operation("d2u", 1, source_types=(double_type,), dest_type=uint_type, c_expression="{src0}"), 47501e04c3fSmrg # Unsigned-to-double conversion. 47601e04c3fSmrg operation("u2d", 1, source_types=(uint_type,), dest_type=double_type, c_expression="{src0}"), 47701e04c3fSmrg # Double-to-boolean conversion. 47801e04c3fSmrg operation("d2b", 1, source_types=(double_type,), dest_type=bool_type, c_expression="{src0} != 0.0"), 4797ec681f3Smrg # Float16-to-boolean conversion. 4807ec681f3Smrg operation("f162b", 1, source_types=(float_type,), dest_type=bool_type, c_expression="{src0} != 0.0"), 48101e04c3fSmrg # 'Bit-identical int-to-float "conversion" 48201e04c3fSmrg operation("bitcast_i2f", 1, source_types=(int_type,), dest_type=float_type, c_expression="bitcast_u2f({src0})"), 48301e04c3fSmrg # 'Bit-identical float-to-int "conversion" 48401e04c3fSmrg operation("bitcast_f2i", 1, source_types=(float_type,), dest_type=int_type, c_expression="bitcast_f2u({src0})"), 48501e04c3fSmrg # 'Bit-identical uint-to-float "conversion" 48601e04c3fSmrg operation("bitcast_u2f", 1, source_types=(uint_type,), dest_type=float_type, c_expression="bitcast_u2f({src0})"), 48701e04c3fSmrg # 'Bit-identical float-to-uint "conversion" 48801e04c3fSmrg operation("bitcast_f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="bitcast_f2u({src0})"), 48901e04c3fSmrg # Bit-identical u64-to-double "conversion" 49001e04c3fSmrg operation("bitcast_u642d", 1, source_types=(uint64_type,), dest_type=double_type, c_expression="bitcast_u642d({src0})"), 49101e04c3fSmrg # Bit-identical i64-to-double "conversion" 49201e04c3fSmrg operation("bitcast_i642d", 1, source_types=(int64_type,), dest_type=double_type, c_expression="bitcast_i642d({src0})"), 49301e04c3fSmrg # Bit-identical double-to_u64 "conversion" 49401e04c3fSmrg operation("bitcast_d2u64", 1, source_types=(double_type,), dest_type=uint64_type, c_expression="bitcast_d2u64({src0})"), 49501e04c3fSmrg # Bit-identical double-to-i64 "conversion" 49601e04c3fSmrg operation("bitcast_d2i64", 1, source_types=(double_type,), dest_type=int64_type, c_expression="bitcast_d2i64({src0})"), 49701e04c3fSmrg # i64-to-i32 conversion 49801e04c3fSmrg operation("i642i", 1, source_types=(int64_type,), dest_type=int_type, c_expression="{src0}"), 49901e04c3fSmrg # ui64-to-i32 conversion 50001e04c3fSmrg operation("u642i", 1, source_types=(uint64_type,), dest_type=int_type, c_expression="{src0}"), 50101e04c3fSmrg operation("i642u", 1, source_types=(int64_type,), dest_type=uint_type, c_expression="{src0}"), 50201e04c3fSmrg operation("u642u", 1, source_types=(uint64_type,), dest_type=uint_type, c_expression="{src0}"), 50301e04c3fSmrg operation("i642b", 1, source_types=(int64_type,), dest_type=bool_type, c_expression="{src0} != 0"), 50401e04c3fSmrg operation("i642f", 1, source_types=(int64_type,), dest_type=float_type, c_expression="{src0}"), 50501e04c3fSmrg operation("u642f", 1, source_types=(uint64_type,), dest_type=float_type, c_expression="{src0}"), 50601e04c3fSmrg operation("i642d", 1, source_types=(int64_type,), dest_type=double_type, c_expression="{src0}"), 50701e04c3fSmrg operation("u642d", 1, source_types=(uint64_type,), dest_type=double_type, c_expression="{src0}"), 50801e04c3fSmrg operation("i2i64", 1, source_types=(int_type,), dest_type=int64_type, c_expression="{src0}"), 50901e04c3fSmrg operation("u2i64", 1, source_types=(uint_type,), dest_type=int64_type, c_expression="{src0}"), 51001e04c3fSmrg operation("b2i64", 1, source_types=(bool_type,), dest_type=int64_type, c_expression="{src0}"), 51101e04c3fSmrg operation("f2i64", 1, source_types=(float_type,), dest_type=int64_type, c_expression="{src0}"), 51201e04c3fSmrg operation("d2i64", 1, source_types=(double_type,), dest_type=int64_type, c_expression="{src0}"), 51301e04c3fSmrg operation("i2u64", 1, source_types=(int_type,), dest_type=uint64_type, c_expression="{src0}"), 51401e04c3fSmrg operation("u2u64", 1, source_types=(uint_type,), dest_type=uint64_type, c_expression="{src0}"), 51501e04c3fSmrg operation("f2u64", 1, source_types=(float_type,), dest_type=uint64_type, c_expression="{src0}"), 51601e04c3fSmrg operation("d2u64", 1, source_types=(double_type,), dest_type=uint64_type, c_expression="{src0}"), 51701e04c3fSmrg operation("u642i64", 1, source_types=(uint64_type,), dest_type=int64_type, c_expression="{src0}"), 51801e04c3fSmrg operation("i642u64", 1, source_types=(int64_type,), dest_type=uint64_type, c_expression="{src0}"), 51901e04c3fSmrg 52001e04c3fSmrg 52101e04c3fSmrg # Unary floating-point rounding operations. 52201e04c3fSmrg operation("trunc", 1, source_types=real_types, c_expression={'f': "truncf({src0})", 'd': "trunc({src0})"}), 52301e04c3fSmrg operation("ceil", 1, source_types=real_types, c_expression={'f': "ceilf({src0})", 'd': "ceil({src0})"}), 52401e04c3fSmrg operation("floor", 1, source_types=real_types, c_expression={'f': "floorf({src0})", 'd': "floor({src0})"}), 52501e04c3fSmrg operation("fract", 1, source_types=real_types, c_expression={'f': "{src0} - floorf({src0})", 'd': "{src0} - floor({src0})"}), 52601e04c3fSmrg operation("round_even", 1, source_types=real_types, c_expression={'f': "_mesa_roundevenf({src0})", 'd': "_mesa_roundeven({src0})"}), 52701e04c3fSmrg 52801e04c3fSmrg # Trigonometric operations. 52901e04c3fSmrg operation("sin", 1, source_types=(float_type,), c_expression="sinf({src0})"), 53001e04c3fSmrg operation("cos", 1, source_types=(float_type,), c_expression="cosf({src0})"), 5317ec681f3Smrg operation("atan", 1, source_types=(float_type,), c_expression="atan({src0})"), 53201e04c3fSmrg 53301e04c3fSmrg # Partial derivatives. 53401e04c3fSmrg operation("dFdx", 1, source_types=(float_type,), c_expression="0.0f"), 53501e04c3fSmrg operation("dFdx_coarse", 1, printable_name="dFdxCoarse", source_types=(float_type,), c_expression="0.0f"), 53601e04c3fSmrg operation("dFdx_fine", 1, printable_name="dFdxFine", source_types=(float_type,), c_expression="0.0f"), 53701e04c3fSmrg operation("dFdy", 1, source_types=(float_type,), c_expression="0.0f"), 53801e04c3fSmrg operation("dFdy_coarse", 1, printable_name="dFdyCoarse", source_types=(float_type,), c_expression="0.0f"), 53901e04c3fSmrg operation("dFdy_fine", 1, printable_name="dFdyFine", source_types=(float_type,), c_expression="0.0f"), 54001e04c3fSmrg 54101e04c3fSmrg # Floating point pack and unpack operations. 54201e04c3fSmrg 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), 54301e04c3fSmrg 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), 54401e04c3fSmrg 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), 54501e04c3fSmrg 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), 54601e04c3fSmrg 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), 54701e04c3fSmrg 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))), 54801e04c3fSmrg 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))), 54901e04c3fSmrg 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))), 55001e04c3fSmrg 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))), 55101e04c3fSmrg 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))), 55201e04c3fSmrg 55301e04c3fSmrg # Bit operations, part of ARB_gpu_shader5. 55401e04c3fSmrg operation("bitfield_reverse", 1, source_types=(uint_type, int_type), c_expression="bitfield_reverse({src0})"), 55501e04c3fSmrg operation("bit_count", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression="util_bitcount({src0})"), 55601e04c3fSmrg 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})"}), 55701e04c3fSmrg operation("find_lsb", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression="find_msb_uint({src0} & -{src0})"), 5587ec681f3Smrg operation("clz", 1, source_types=(uint_type,), dest_type=uint_type, c_expression="(unsigned)(31 - find_msb_uint({src0}))"), 55901e04c3fSmrg 56001e04c3fSmrg operation("saturate", 1, printable_name="sat", source_types=(float_type,), c_expression="CLAMP({src0}, 0.0f, 1.0f)"), 56101e04c3fSmrg 56201e04c3fSmrg # Double packing, part of ARB_gpu_shader_fp64. 5637ec681f3Smrg 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))), 5647ec681f3Smrg 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))), 56501e04c3fSmrg 56601e04c3fSmrg # Sampler/Image packing, part of ARB_bindless_texture. 5677ec681f3Smrg 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))), 5687ec681f3Smrg 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))), 5697ec681f3Smrg 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))), 5707ec681f3Smrg 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))), 57101e04c3fSmrg 57201e04c3fSmrg operation("frexp_sig", 1), 57301e04c3fSmrg operation("frexp_exp", 1), 57401e04c3fSmrg 57501e04c3fSmrg operation("subroutine_to_int", 1), 57601e04c3fSmrg 57701e04c3fSmrg # Interpolate fs input at centroid 57801e04c3fSmrg # 57901e04c3fSmrg # operand0 is the fs input. 58001e04c3fSmrg operation("interpolate_at_centroid", 1), 58101e04c3fSmrg 58201e04c3fSmrg # Ask the driver for the total size of a buffer block. 58301e04c3fSmrg # operand0 is the ir_constant buffer block index in the linked shader. 58401e04c3fSmrg operation("get_buffer_size", 1), 58501e04c3fSmrg 58601e04c3fSmrg # Calculate length of an unsized array inside a buffer block. 58701e04c3fSmrg # This opcode is going to be replaced in a lowering pass inside 58801e04c3fSmrg # the linker. 58901e04c3fSmrg # 59001e04c3fSmrg # operand0 is the unsized array's ir_value for the calculation 59101e04c3fSmrg # of its length. 59201e04c3fSmrg operation("ssbo_unsized_array_length", 1), 59301e04c3fSmrg 5947ec681f3Smrg # Calculate length of an implicitly sized array. 5957ec681f3Smrg # This opcode is going to be replaced with a constant expression at link 5967ec681f3Smrg # time. 5977ec681f3Smrg operation("implicitly_sized_array_length", 1), 5987ec681f3Smrg 59901e04c3fSmrg # 64-bit integer packing ops. 6007ec681f3Smrg 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))), 6017ec681f3Smrg 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))), 6027ec681f3Smrg 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))), 6037ec681f3Smrg 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))), 60401e04c3fSmrg 60501e04c3fSmrg operation("add", 2, printable_name="+", source_types=numeric_types, c_expression="{src0} + {src1}", flags=vector_scalar_operation), 60601e04c3fSmrg operation("sub", 2, printable_name="-", source_types=numeric_types, c_expression="{src0} - {src1}", flags=vector_scalar_operation), 6077ec681f3Smrg operation("add_sat", 2, printable_name="add_sat", source_types=integer_types, c_expression={ 6087ec681f3Smrg 'u': "({src0} + {src1}) < {src0} ? UINT32_MAX : ({src0} + {src1})", 6097ec681f3Smrg 'i': "iadd_saturate({src0}, {src1})", 6107ec681f3Smrg 'u64': "({src0} + {src1}) < {src0} ? UINT64_MAX : ({src0} + {src1})", 6117ec681f3Smrg 'i64': "iadd64_saturate({src0}, {src1})" 6127ec681f3Smrg }), 6137ec681f3Smrg operation("sub_sat", 2, printable_name="sub_sat", source_types=integer_types, c_expression={ 6147ec681f3Smrg 'u': "({src1} > {src0}) ? 0 : {src0} - {src1}", 6157ec681f3Smrg 'i': "isub_saturate({src0}, {src1})", 6167ec681f3Smrg 'u64': "({src1} > {src0}) ? 0 : {src0} - {src1}", 6177ec681f3Smrg 'i64': "isub64_saturate({src0}, {src1})" 6187ec681f3Smrg }), 6197ec681f3Smrg operation("abs_sub", 2, printable_name="abs_sub", source_types=integer_types, c_expression={ 6207ec681f3Smrg 'u': "({src1} > {src0}) ? {src1} - {src0} : {src0} - {src1}", 6217ec681f3Smrg 'i': "({src1} > {src0}) ? (unsigned){src1} - (unsigned){src0} : (unsigned){src0} - (unsigned){src1}", 6227ec681f3Smrg 'u64': "({src1} > {src0}) ? {src1} - {src0} : {src0} - {src1}", 6237ec681f3Smrg 'i64': "({src1} > {src0}) ? (uint64_t){src1} - (uint64_t){src0} : (uint64_t){src0} - (uint64_t){src1}", 6247ec681f3Smrg }), 6257ec681f3Smrg operation("avg", 2, printable_name="average", source_types=integer_types, c_expression="({src0} >> 1) + ({src1} >> 1) + (({src0} & {src1}) & 1)"), 6267ec681f3Smrg operation("avg_round", 2, printable_name="average_rounded", source_types=integer_types, c_expression="({src0} >> 1) + ({src1} >> 1) + (({src0} | {src1}) & 1)"), 6277ec681f3Smrg 62801e04c3fSmrg # "Floating-point or low 32-bit integer multiply." 62901e04c3fSmrg operation("mul", 2, printable_name="*", source_types=numeric_types, c_expression="{src0} * {src1}"), 6307ec681f3Smrg operation("mul_32x16", 2, printable_name="*", source_types=(uint_type, int_type), c_expression={ 6317ec681f3Smrg 'u': "{src0} * (uint16_t){src1}", 6327ec681f3Smrg 'i': "{src0} * (int16_t){src0}" 6337ec681f3Smrg }), 63401e04c3fSmrg operation("imul_high", 2), # Calculates the high 32-bits of a 64-bit multiply. 63501e04c3fSmrg 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), 63601e04c3fSmrg 63701e04c3fSmrg # Returns the carry resulting from the addition of the two arguments. 63801e04c3fSmrg operation("carry", 2), 63901e04c3fSmrg 64001e04c3fSmrg # Returns the borrow resulting from the subtraction of the second argument 64101e04c3fSmrg # from the first argument. 64201e04c3fSmrg operation("borrow", 2), 64301e04c3fSmrg 64401e04c3fSmrg # Either (vector % vector) or (vector % scalar) 64501e04c3fSmrg # 64601e04c3fSmrg # We don't use fmod because it rounds toward zero; GLSL specifies the use 64701e04c3fSmrg # of floor. 64801e04c3fSmrg 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), 64901e04c3fSmrg 65001e04c3fSmrg # Binary comparison operators which return a boolean vector. 65101e04c3fSmrg # The type of both operands must be equal. 65201e04c3fSmrg operation("less", 2, printable_name="<", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} < {src1}"), 65301e04c3fSmrg operation("gequal", 2, printable_name=">=", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} >= {src1}"), 65401e04c3fSmrg operation("equal", 2, printable_name="==", source_types=all_types, dest_type=bool_type, c_expression="{src0} == {src1}"), 65501e04c3fSmrg operation("nequal", 2, printable_name="!=", source_types=all_types, dest_type=bool_type, c_expression="{src0} != {src1}"), 65601e04c3fSmrg 65701e04c3fSmrg # Returns single boolean for whether all components of operands[0] 65801e04c3fSmrg # equal the components of operands[1]. 65901e04c3fSmrg 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))), 66001e04c3fSmrg 66101e04c3fSmrg # Returns single boolean for whether any component of operands[0] 66201e04c3fSmrg # is not equal to the corresponding component of operands[1]. 66301e04c3fSmrg 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))), 66401e04c3fSmrg 66501e04c3fSmrg # Bit-wise binary operations. 66601e04c3fSmrg operation("lshift", 2, printable_name="<<", source_types=integer_types, c_expression="{src0} << {src1}", flags=frozenset((vector_scalar_operation, mixed_type_operation))), 66701e04c3fSmrg operation("rshift", 2, printable_name=">>", source_types=integer_types, c_expression="{src0} >> {src1}", flags=frozenset((vector_scalar_operation, mixed_type_operation))), 66801e04c3fSmrg operation("bit_and", 2, printable_name="&", source_types=integer_types, c_expression="{src0} & {src1}", flags=vector_scalar_operation), 66901e04c3fSmrg operation("bit_xor", 2, printable_name="^", source_types=integer_types, c_expression="{src0} ^ {src1}", flags=vector_scalar_operation), 67001e04c3fSmrg operation("bit_or", 2, printable_name="|", source_types=integer_types, c_expression="{src0} | {src1}", flags=vector_scalar_operation), 67101e04c3fSmrg 67201e04c3fSmrg operation("logic_and", 2, printable_name="&&", source_types=(bool_type,), c_expression="{src0} && {src1}"), 67301e04c3fSmrg operation("logic_xor", 2, printable_name="^^", source_types=(bool_type,), c_expression="{src0} != {src1}"), 67401e04c3fSmrg operation("logic_or", 2, printable_name="||", source_types=(bool_type,), c_expression="{src0} || {src1}"), 67501e04c3fSmrg 67601e04c3fSmrg 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), 67701e04c3fSmrg operation("min", 2, source_types=numeric_types, c_expression="MIN2({src0}, {src1})", flags=vector_scalar_operation), 67801e04c3fSmrg operation("max", 2, source_types=numeric_types, c_expression="MAX2({src0}, {src1})", flags=vector_scalar_operation), 67901e04c3fSmrg 68001e04c3fSmrg operation("pow", 2, source_types=(float_type,), c_expression="powf({src0}, {src1})"), 68101e04c3fSmrg 68201e04c3fSmrg # Load a value the size of a given GLSL type from a uniform block. 68301e04c3fSmrg # 68401e04c3fSmrg # operand0 is the ir_constant uniform block index in the linked shader. 68501e04c3fSmrg # operand1 is a byte offset within the uniform block. 68601e04c3fSmrg operation("ubo_load", 2), 68701e04c3fSmrg 68801e04c3fSmrg # Multiplies a number by two to a power, part of ARB_gpu_shader5. 68901e04c3fSmrg operation("ldexp", 2, 69001e04c3fSmrg all_signatures=((float_type, (float_type, int_type)), 69101e04c3fSmrg (double_type, (double_type, int_type))), 69201e04c3fSmrg c_expression={'f': "ldexpf_flush_subnormal({src0}, {src1})", 69301e04c3fSmrg 'd': "ldexp_flush_subnormal({src0}, {src1})"}), 69401e04c3fSmrg 69501e04c3fSmrg # Extract a scalar from a vector 69601e04c3fSmrg # 69701e04c3fSmrg # operand0 is the vector 69801e04c3fSmrg # operand1 is the index of the field to read from operand0 69901e04c3fSmrg operation("vector_extract", 2, source_types=all_types, c_expression="anything-except-None"), 70001e04c3fSmrg 70101e04c3fSmrg # Interpolate fs input at offset 70201e04c3fSmrg # 70301e04c3fSmrg # operand0 is the fs input 70401e04c3fSmrg # operand1 is the offset from the pixel center 70501e04c3fSmrg operation("interpolate_at_offset", 2), 70601e04c3fSmrg 70701e04c3fSmrg # Interpolate fs input at sample position 70801e04c3fSmrg # 70901e04c3fSmrg # operand0 is the fs input 71001e04c3fSmrg # operand1 is the sample ID 71101e04c3fSmrg operation("interpolate_at_sample", 2), 71201e04c3fSmrg 7137ec681f3Smrg operation("atan2", 2, source_types=(float_type,), c_expression="atan2({src0}, {src1})"), 7147ec681f3Smrg 71501e04c3fSmrg # Fused floating-point multiply-add, part of ARB_gpu_shader5. 71601e04c3fSmrg operation("fma", 3, source_types=real_types, c_expression="{src0} * {src1} + {src2}"), 71701e04c3fSmrg 71801e04c3fSmrg operation("lrp", 3, source_types=real_types, c_expression={'f': "{src0} * (1.0f - {src2}) + ({src1} * {src2})", 'd': "{src0} * (1.0 - {src2}) + ({src1} * {src2})"}), 71901e04c3fSmrg 72001e04c3fSmrg # Conditional Select 72101e04c3fSmrg # 72201e04c3fSmrg # A vector conditional select instruction (like ?:, but operating per- 72301e04c3fSmrg # component on vectors). 72401e04c3fSmrg # 72501e04c3fSmrg # See also lower_instructions_visitor::ldexp_to_arith 72601e04c3fSmrg operation("csel", 3, 72701e04c3fSmrg all_signatures=zip(all_types, zip(len(all_types) * (bool_type,), all_types, all_types)), 72801e04c3fSmrg c_expression="{src0} ? {src1} : {src2}"), 72901e04c3fSmrg 73001e04c3fSmrg operation("bitfield_extract", 3, 73101e04c3fSmrg all_signatures=((int_type, (uint_type, int_type, int_type)), 73201e04c3fSmrg (int_type, (int_type, int_type, int_type))), 73301e04c3fSmrg c_expression={'u': "bitfield_extract_uint({src0}, {src1}, {src2})", 73401e04c3fSmrg 'i': "bitfield_extract_int({src0}, {src1}, {src2})"}), 73501e04c3fSmrg 73601e04c3fSmrg # Generate a value with one field of a vector changed 73701e04c3fSmrg # 73801e04c3fSmrg # operand0 is the vector 73901e04c3fSmrg # operand1 is the value to write into the vector result 74001e04c3fSmrg # operand2 is the index in operand0 to be modified 74101e04c3fSmrg operation("vector_insert", 3, source_types=all_types, c_expression="anything-except-None"), 74201e04c3fSmrg 74301e04c3fSmrg operation("bitfield_insert", 4, 74401e04c3fSmrg all_signatures=((uint_type, (uint_type, uint_type, int_type, int_type)), 74501e04c3fSmrg (int_type, (int_type, int_type, int_type, int_type))), 74601e04c3fSmrg c_expression="bitfield_insert({src0}, {src1}, {src2}, {src3})"), 74701e04c3fSmrg 74801e04c3fSmrg operation("vector", 4, source_types=all_types, c_expression="anything-except-None"), 74901e04c3fSmrg] 75001e04c3fSmrg 75101e04c3fSmrg 75201e04c3fSmrgif __name__ == "__main__": 75301e04c3fSmrg copyright = """/* 75401e04c3fSmrg * Copyright (C) 2010 Intel Corporation 75501e04c3fSmrg * 75601e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 75701e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 75801e04c3fSmrg * to deal in the Software without restriction, including without limitation 75901e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 76001e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 76101e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 76201e04c3fSmrg * 76301e04c3fSmrg * The above copyright notice and this permission notice (including the next 76401e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 76501e04c3fSmrg * Software. 76601e04c3fSmrg * 76701e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 76801e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 76901e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 77001e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 77101e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 77201e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 77301e04c3fSmrg * DEALINGS IN THE SOFTWARE. 77401e04c3fSmrg */ 77501e04c3fSmrg""" 77601e04c3fSmrg enum_template = mako.template.Template(copyright + """ 77701e04c3fSmrgenum ir_expression_operation { 77801e04c3fSmrg% for item in values: 77901e04c3fSmrg ${item.get_enum_name()}, 78001e04c3fSmrg% endfor 78101e04c3fSmrg 78201e04c3fSmrg /* Sentinels marking the last of each kind of operation. */ 78301e04c3fSmrg% for item in lasts: 78401e04c3fSmrg ir_last_${("un", "bin", "tri", "quad")[item.num_operands - 1]}op = ${item.get_enum_name()}, 78501e04c3fSmrg% endfor 78601e04c3fSmrg ir_last_opcode = ir_quadop_${lasts[3].name} 78701e04c3fSmrg};""") 78801e04c3fSmrg 78901e04c3fSmrg strings_template = mako.template.Template(copyright + """ 79001e04c3fSmrgconst char *const ir_expression_operation_strings[] = { 79101e04c3fSmrg% for item in values: 79201e04c3fSmrg "${item.printable_name}", 79301e04c3fSmrg% endfor 79401e04c3fSmrg}; 79501e04c3fSmrg 79601e04c3fSmrgconst char *const ir_expression_operation_enum_strings[] = { 79701e04c3fSmrg% for item in values: 79801e04c3fSmrg "${item.name}", 79901e04c3fSmrg% endfor 80001e04c3fSmrg};""") 80101e04c3fSmrg 80201e04c3fSmrg constant_template = mako.template.Template("""\ 80301e04c3fSmrg switch (this->operation) { 80401e04c3fSmrg% for op in values: 80501e04c3fSmrg % if op.c_expression is not None: 80601e04c3fSmrg${op.get_template()} 80701e04c3fSmrg 80801e04c3fSmrg % endif 80901e04c3fSmrg% endfor 81001e04c3fSmrg default: 81101e04c3fSmrg /* FINISHME: Should handle all expression types. */ 81201e04c3fSmrg return NULL; 81301e04c3fSmrg } 81401e04c3fSmrg""") 81501e04c3fSmrg 81601e04c3fSmrg if sys.argv[1] == "enum": 81701e04c3fSmrg lasts = [None, None, None, None] 81801e04c3fSmrg for item in reversed(ir_expression_operation): 81901e04c3fSmrg i = item.num_operands - 1 82001e04c3fSmrg if lasts[i] is None: 82101e04c3fSmrg lasts[i] = item 82201e04c3fSmrg 82301e04c3fSmrg print(enum_template.render(values=ir_expression_operation, 82401e04c3fSmrg lasts=lasts)) 82501e04c3fSmrg elif sys.argv[1] == "strings": 82601e04c3fSmrg print(strings_template.render(values=ir_expression_operation)) 82701e04c3fSmrg elif sys.argv[1] == "constant": 82801e04c3fSmrg print(constant_template.render(values=ir_expression_operation)) 829