diff options
Diffstat (limited to 'src/glsl/nir/nir_opcodes.py')
-rw-r--r-- | src/glsl/nir/nir_opcodes.py | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/src/glsl/nir/nir_opcodes.py b/src/glsl/nir/nir_opcodes.py new file mode 100644 index 00000000000..5bafbb0229e --- /dev/null +++ b/src/glsl/nir/nir_opcodes.py @@ -0,0 +1,381 @@ +#! /usr/bin/env python +# +# Copyright (C) 2014 Connor Abbott +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# Authors: +# Connor Abbott ([email protected]) + +# Class that represents all the information we have about the opcode +# NOTE: this must be kept in sync with nir_op_info + +class Opcode(object): + """Class that represents all the information we have about the opcode + NOTE: this must be kept in sync with nir_op_info + """ + def __init__(self, name, output_size, output_type, input_sizes, + input_types, algebraic_properties): + """Parameters: + + - name is the name of the opcode (prepend nir_op_ for the enum name) + - all types are strings that get nir_type_ prepended to them + - input_types is a list of types + - algebraic_properties is a space-seperated string, where nir_op_is_ is + prepended before each entry + """ + assert isinstance(name, str) + assert isinstance(output_size, int) + assert isinstance(output_type, str) + assert isinstance(input_sizes, list) + assert isinstance(input_sizes[0], int) + assert isinstance(input_types, list) + assert isinstance(input_types[0], str) + assert isinstance(algebraic_properties, str) + assert len(input_sizes) == len(input_types) + assert 0 <= output_size <= 4 + for size in input_sizes: + assert 0 <= size <= 4 + if output_size != 0: + assert size != 0 + self.name = name + self.num_inputs = len(input_sizes) + self.output_size = output_size + self.output_type = output_type + self.input_sizes = input_sizes + self.input_types = input_types + self.algebraic_properties = algebraic_properties + +# helper variables for strings +tfloat = "float" +tint = "int" +tbool = "bool" +tunsigned = "unsigned" + +commutative = "commutative " +associative = "associative " + +# global dictionary of opcodes +opcodes = {} + +def opcode(name, output_size, output_type, input_sizes, input_types, + algebraic_properties): + assert name not in opcodes + opcodes[name] = Opcode(name, output_size, output_type, input_sizes, + input_types, algebraic_properties) + +def unop_convert(name, in_type, out_type): + opcode(name, 0, out_type, [0], [in_type], "") + +def unop(name, ty): + opcode(name, 0, ty, [0], [ty], "") + +def unop_horiz(name, output_size, output_type, input_size, input_type): + opcode(name, output_size, output_type, [input_size], [input_type], "") + +def unop_reduce(name, output_size, output_type, input_type): + unop_horiz(name + "2", output_size, output_type, 2, input_type) + unop_horiz(name + "3", output_size, output_type, 3, input_type) + unop_horiz(name + "4", output_size, output_type, 4, input_type) + + +# These two move instructions differ in what modifiers they support and what +# the negate modifier means. Otherwise, they are identical. +unop("fmov", tfloat) +unop("imov", tint) + +unop("ineg", tint) +unop("fneg", tfloat) +unop("inot", tint) # invert every bit of the integer +unop("fnot", tfloat) # (src == 0.0) ? 1.0 : 0.0 +unop("fsign", tfloat) +unop("isign", tint) +unop("iabs", tint) +unop("fabs", tfloat) +unop("fsat", tfloat) +unop("frcp", tfloat) +unop("frsq", tfloat) +unop("fsqrt", tfloat) +unop("fexp", tfloat) # < e^x +unop("flog", tfloat) # log base e +unop("fexp2", tfloat) +unop("flog2", tfloat) +unop_convert("f2i", tfloat, tint) # Float-to-integer conversion. +unop_convert("f2u", tfloat, tunsigned) # Float-to-unsigned conversion +unop_convert("i2f", tint, tfloat) # Integer-to-float conversion. +unop_convert("f2b", tfloat, tbool) # Float-to-boolean conversion +unop_convert("b2f", tbool, tfloat) # Boolean-to-float conversion +unop_convert("i2b", tint, tbool) # int-to-boolean conversion +unop_convert("b2i", tbool, tint) # Boolean-to-int conversion +unop_convert("u2f", tunsigned, tfloat) #Unsigned-to-float conversion. + +unop_reduce("bany", 1, tbool, tbool) # returns ~0 if any component of src[0] != 0 +unop_reduce("ball", 1, tbool, tbool) # returns ~0 if all components of src[0] != 0 +unop_reduce("fany", 1, tfloat, tfloat) # returns 1.0 if any component of src[0] != 0 +unop_reduce("fall", 1, tfloat, tfloat) # returns 1.0 if all components of src[0] != 0 + +# Unary floating-point rounding operations. + + +unop("ftrunc", tfloat) +unop("fceil", tfloat) +unop("ffloor", tfloat) +unop("ffract", tfloat) +unop("fround_even", tfloat) + + +# Trigonometric operations. + + +unop("fsin", tfloat) +unop("fcos", tfloat) +unop("fsin_reduced", tfloat) +unop("fcos_reduced", tfloat) + + +# Partial derivatives. + + +unop("fddx", tfloat) +unop("fddy", tfloat) +unop("fddx_fine", tfloat) +unop("fddy_fine", tfloat) +unop("fddx_coarse", tfloat) +unop("fddy_coarse", tfloat) + + +# Floating point pack and unpack operations. + + +unop_horiz("pack_snorm_2x16", 1, tunsigned, 2, tfloat) +unop_horiz("pack_snorm_4x8", 1, tunsigned, 4, tfloat) +unop_horiz("pack_unorm_2x16", 1, tunsigned, 2, tfloat) +unop_horiz("pack_unorm_4x8", 1, tunsigned, 4, tfloat) +unop_horiz("pack_half_2x16", 1, tunsigned, 2, tfloat) +unop_horiz("unpack_snorm_2x16", 2, tfloat, 1, tunsigned) +unop_horiz("unpack_snorm_4x8", 4, tfloat, 1, tunsigned) +unop_horiz("unpack_unorm_2x16", 2, tfloat, 1, tunsigned) +unop_horiz("unpack_unorm_4x8", 4, tfloat, 1, tunsigned) +unop_horiz("unpack_half_2x16", 2, tfloat, 1, tunsigned) + + +# Lowered floating point unpacking operations. + + +unop_horiz("unpack_half_2x16_split_x", 1, tfloat, 1, tunsigned) +unop_horiz("unpack_half_2x16_split_y", 1, tfloat, 1, tunsigned) + + +# Bit operations, part of ARB_gpu_shader5. + + +unop("bitfield_reverse", tunsigned) +unop("bit_count", tunsigned) +unop_convert("ufind_msb", tunsigned, tint) +unop("ifind_msb", tint) +unop("find_lsb", tint) + + +for i in xrange(1, 5): + for j in xrange(1, 5): + unop_horiz("fnoise{0}_{1}".format(i, j), i, tfloat, j, tfloat) + +def binop_convert(name, out_type, in_type, alg_props): + opcode(name, 0, out_type, [0, 0], [in_type, in_type], alg_props) + +def binop(name, ty, alg_props): + binop_convert(name, ty, ty, alg_props) + +def binop_compare(name, ty, alg_props): + binop_convert(name, ty, tbool, alg_props) + +def binop_horiz(name, out_size, out_type, src1_size, src1_type, src2_size, + src2_type): + opcode(name, out_size, out_type, [src1_size, src2_size], [src1_type, src2_type], "") + +def binop_reduce(name, output_size, output_type, src_type): + opcode(name + "2",output_size, output_type, + [2, 2], [src_type, src_type], commutative) + opcode(name + "3", output_size, output_type, + [3, 3], [src_type, src_type], commutative) + opcode(name + "4", output_size, output_type, + [4, 4], [src_type, src_type], commutative) + +binop("fadd", tfloat, commutative + associative) +binop("iadd", tint, commutative + associative) +binop("fsub", tfloat, "") +binop("isub", tint, "") + +binop("fmul", tfloat, commutative + associative) +# low 32-bits of signed/unsigned integer multiply +binop("imul", tint, commutative + associative) +# high 32-bits of signed integer multiply +binop("imul_high", tint, commutative) +# high 32-bits of unsigned integer multiply +binop("umul_high", tunsigned, commutative) + +binop("fdiv", tfloat, "") +binop("idiv", tint, "") +binop("udiv", tunsigned, "") + +# returns a boolean representing the carry resulting from the addition of +# the two unsigned arguments. + +binop_convert("uadd_carry", tbool, tunsigned, + commutative) + +# returns a boolean representing the borrow resulting from the subtraction +# of the two unsigned arguments. + +binop_convert("usub_borrow", tbool, tunsigned, "") + +binop("fmod", tfloat, "") +binop("umod", tunsigned, "") + +# +# Comparisons +# + + +# these integer-aware comparisons return a boolean (0 or ~0) + +binop_compare("flt", tfloat, "") +binop_compare("fge", tfloat, "") +binop_compare("feq", tfloat, commutative) +binop_compare("fne", tfloat, commutative) +binop_compare("ilt", tint, "") +binop_compare("ige", tint, "") +binop_compare("ieq", tint, commutative) +binop_compare("ine", tint, commutative) +binop_compare("ult", tunsigned, "") +binop_compare("uge", tunsigned, "") + +# integer-aware GLSL-style comparisons that compare floats and ints + +binop_reduce("ball_fequal", 1, tbool, tfloat) +binop_reduce("bany_fnequal", 1, tbool, tfloat) +binop_reduce("ball_iequal", 1, tbool, tint) +binop_reduce("bany_inequal", 1, tbool, tint) + +# non-integer-aware GLSL-style comparisons that return 0.0 or 1.0 + +binop_reduce("fall_equal", 1, tfloat, tfloat) +binop_reduce("fany_nequal", 1, tfloat, tfloat) + +# These comparisons for integer-less hardware return 1.0 and 0.0 for true +# and false respectively + +binop("slt", tfloat, "") # Set on Less Than +binop("sge", tfloat, "") # Set on Greater Than or Equal +binop("seq", tfloat, commutative) # Set on Equal +binop("sne", tfloat, commutative) # Set on Not Equal + + +binop("ishl", tint, "") +binop("ishr", tint, "") +binop("ushr", tunsigned, "") + +# bitwise logic operators +# +# These are also used as boolean and, or, xor for hardware supporting +# integers. + + +binop("iand", tunsigned, commutative + associative) +binop("ior", tunsigned, commutative + associative) +binop("ixor", tunsigned, commutative + associative) + + +# floating point logic operators +# +# These use (src != 0.0) for testing the truth of the input, and output 1.0 +# for true and 0.0 for false + +binop("fand", tfloat, commutative) +binop("for", tfloat, commutative) +binop("fxor", tfloat, commutative) + +binop_reduce("fdot", 1, tfloat, tfloat) + +binop("fmin", tfloat, "") +binop("imin", tint, commutative + associative) +binop("umin", tunsigned, commutative + associative) +binop("fmax", tfloat, "") +binop("imax", tint, commutative + associative) +binop("umax", tunsigned, commutative + associative) + +binop("fpow", tfloat, "") + +binop_horiz("pack_half_2x16_split", 1, tunsigned, 1, tfloat, 1, tfloat) + +binop("bfm", tunsigned, "") + +binop("ldexp", tunsigned, "") + +# Combines the first component of each input to make a 2-component vector. + +binop_horiz("vec2", 2, tunsigned, 1, tunsigned, 1, tunsigned) + +def triop(name, ty): + opcode(name, 0, ty, [0, 0, 0], [ty, ty, ty], "") +def triop_horiz(name, output_size, src1_size, src2_size, src3_size): + opcode(name, output_size, tunsigned, + [src1_size, src2_size, src3_size], + [tunsigned, tunsigned, tunsigned], "") + +# fma(a, b, c) = (a# b) + c +triop("ffma", tfloat) + +triop("flrp", tfloat) + +# Conditional Select +# +# A vector conditional select instruction (like ?:, but operating per- +# component on vectors). There are two versions, one for floating point +# bools (0.0 vs 1.0) and one for integer bools (0 vs ~0). + + +triop("fcsel", tfloat) +opcode("bcsel", 0, tunsigned, [0, 0, 0], + [tbool, tunsigned, tunsigned], "") + +triop("bfi", tunsigned) + +triop("ubitfield_extract", tunsigned) +opcode("ibitfield_extract", 0, tint, [0, 0, 0], + [tint, tunsigned, tunsigned], "") + +# Combines the first component of each input to make a 3-component vector. + +triop_horiz("vec3", 3, 1, 1, 1) + +def quadop(name): + opcode(name, 0, tunsigned, [0, 0, 0, 0], + [tunsigned, tunsigned, tunsigned, tunsigned], + "") +def quadop_horiz(name, output_size, src1_size, src2_size, src3_size, src4_size): + opcode(name, output_size, tunsigned, + [src1_size, src2_size, src3_size, src4_size], + [tunsigned, tunsigned, tunsigned, tunsigned], + "") + +quadop("bitfield_insert") + +quadop_horiz("vec4", 4, 1, 1, 1, 1) |