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