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