From: Iago Toral Quiroga Date: Tue, 12 Feb 2019 11:55:28 +0000 (+0100) Subject: compiler/nir: add an is_conversion field to nir_op_info X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ca2b5e9069177ea603efbe250e675dc7d194ef90;p=mesa.git compiler/nir: add an is_conversion field to nir_op_info This is set to True only for numeric conversion opcodes. Reviewed-by: Jason Ekstrand Reviewed-by: Matt Turner Reviewed-by: Jordan Justen Reviewed-by: Kenneth Graunke --- diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index a6690682c83..0d5b70b1c34 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -918,6 +918,9 @@ typedef struct { nir_alu_type input_types[NIR_MAX_VEC_COMPONENTS]; nir_op_algebraic_property algebraic_properties; + + /* Whether this represents a numeric conversion opcode */ + bool is_conversion; } nir_op_info; extern const nir_op_info nir_op_infos[nir_num_opcodes]; diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py index 5da3cafabb2..9bbfe66ccdc 100644 --- a/src/compiler/nir/nir_opcodes.py +++ b/src/compiler/nir/nir_opcodes.py @@ -33,12 +33,13 @@ class Opcode(object): 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, const_expr): + input_types, is_conversion, algebraic_properties, const_expr): """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 + - is_conversion is true if this opcode represents a type conversion - algebraic_properties is a space-seperated string, where nir_op_is_ is prepended before each entry - const_expr is an expression or series of statements that computes the @@ -70,6 +71,7 @@ class Opcode(object): assert isinstance(input_sizes[0], int) assert isinstance(input_types, list) assert isinstance(input_types[0], str) + assert isinstance(is_conversion, bool) assert isinstance(algebraic_properties, str) assert isinstance(const_expr, str) assert len(input_sizes) == len(input_types) @@ -84,6 +86,7 @@ class Opcode(object): self.output_type = output_type self.input_sizes = input_sizes self.input_types = input_types + self.is_conversion = is_conversion self.algebraic_properties = algebraic_properties self.const_expr = const_expr @@ -138,21 +141,22 @@ associative = "associative " opcodes = {} def opcode(name, output_size, output_type, input_sizes, input_types, - algebraic_properties, const_expr): + is_conversion, algebraic_properties, const_expr): assert name not in opcodes opcodes[name] = Opcode(name, output_size, output_type, input_sizes, - input_types, algebraic_properties, const_expr) + input_types, is_conversion, algebraic_properties, + const_expr) def unop_convert(name, out_type, in_type, const_expr): - opcode(name, 0, out_type, [0], [in_type], "", const_expr) + opcode(name, 0, out_type, [0], [in_type], False, "", const_expr) def unop(name, ty, const_expr): - opcode(name, 0, ty, [0], [ty], "", const_expr) + opcode(name, 0, ty, [0], [ty], False, "", const_expr) def unop_horiz(name, output_size, output_type, input_size, input_type, const_expr): - opcode(name, output_size, output_type, [input_size], [input_type], "", - const_expr) + opcode(name, output_size, output_type, [input_size], [input_type], + False, "", const_expr) def unop_reduce(name, output_size, output_type, input_type, prereduce_expr, reduce_expr, final_expr): @@ -173,6 +177,8 @@ def unop_reduce(name, output_size, output_type, input_type, prereduce_expr, unop_horiz(name + "4", output_size, output_type, 4, input_type, final(reduce_(reduce_(src0, src1), reduce_(src2, src3)))) +def unop_numeric_convert(name, out_type, in_type, const_expr): + opcode(name, 0, out_type, [0], [in_type], True, "", const_expr) # These two move instructions differ in what modifiers they support and what # the negate modifier means. Otherwise, they are identical. @@ -215,13 +221,13 @@ for src_t in [tint, tuint, tfloat, tbool]: if bit_size == 16 and dst_t == tfloat and src_t == tfloat: rnd_modes = ['_rtne', '_rtz', ''] for rnd_mode in rnd_modes: - unop_convert("{0}2{1}{2}{3}".format(src_t[0], dst_t[0], - bit_size, rnd_mode), - dst_t + str(bit_size), src_t, "src0") + unop_numeric_convert("{0}2{1}{2}{3}".format(src_t[0], dst_t[0], + bit_size, rnd_mode), + dst_t + str(bit_size), src_t, "src0") else: conv_expr = "src0 != 0" if dst_t == tbool else "src0" - unop_convert("{0}2{1}{2}".format(src_t[0], dst_t[0], bit_size), - dst_t + str(bit_size), src_t, conv_expr) + unop_numeric_convert("{0}2{1}{2}".format(src_t[0], dst_t[0], bit_size), + dst_t + str(bit_size), src_t, conv_expr) # Unary floating-point rounding operations. @@ -426,7 +432,8 @@ if (src0.z < 0 && absZ >= absX && absZ >= absY) dst.x = 5; def binop_convert(name, out_type, in_type, alg_props, const_expr): - opcode(name, 0, out_type, [0, 0], [in_type, in_type], alg_props, const_expr) + opcode(name, 0, out_type, [0, 0], [in_type, in_type], + False, alg_props, const_expr) def binop(name, ty, alg_props, const_expr): binop_convert(name, ty, ty, alg_props, const_expr) @@ -440,7 +447,7 @@ def binop_compare32(name, ty, alg_props, const_expr): def binop_horiz(name, out_size, out_type, src1_size, src1_type, src2_size, src2_type, const_expr): opcode(name, out_size, out_type, [src1_size, src2_size], [src1_type, src2_type], - "", const_expr) + False, "", const_expr) def binop_reduce(name, output_size, output_type, src_type, prereduce_expr, reduce_expr, final_expr): @@ -455,13 +462,13 @@ def binop_reduce(name, output_size, output_type, src_type, prereduce_expr, src2 = prereduce("src0.z", "src1.z") src3 = prereduce("src0.w", "src1.w") opcode(name + "2", output_size, output_type, - [2, 2], [src_type, src_type], commutative, + [2, 2], [src_type, src_type], False, commutative, final(reduce_(src0, src1))) opcode(name + "3", output_size, output_type, - [3, 3], [src_type, src_type], commutative, + [3, 3], [src_type, src_type], False, commutative, final(reduce_(reduce_(src0, src1), src2))) opcode(name + "4", output_size, output_type, - [4, 4], [src_type, src_type], commutative, + [4, 4], [src_type, src_type], False, commutative, final(reduce_(reduce_(src0, src1), reduce_(src2, src3)))) binop("fadd", tfloat, commutative + associative, "src0 + src1") @@ -657,9 +664,12 @@ binop("sne", tfloat32, commutative, "(src0 != src1) ? 1.0f : 0.0f") # Set on Not # SPIRV shifts are undefined for shift-operands >= bitsize, # but SM5 shifts are defined to use the least significant bits, only # The NIR definition is according to the SM5 specification. -opcode("ishl", 0, tint, [0, 0], [tint, tuint32], "", "src0 << (src1 & (sizeof(src0) * 8 - 1))") -opcode("ishr", 0, tint, [0, 0], [tint, tuint32], "", "src0 >> (src1 & (sizeof(src0) * 8 - 1))") -opcode("ushr", 0, tuint, [0, 0], [tuint, tuint32], "", "src0 >> (src1 & (sizeof(src0) * 8 - 1))") +opcode("ishl", 0, tint, [0, 0], [tint, tuint32], False, "", + "src0 << (src1 & (sizeof(src0) * 8 - 1))") +opcode("ishr", 0, tint, [0, 0], [tint, tuint32], False, "", + "src0 >> (src1 & (sizeof(src0) * 8 - 1))") +opcode("ushr", 0, tuint, [0, 0], [tuint, tuint32], False, "", + "src0 >> (src1 & (sizeof(src0) * 8 - 1))") # bitwise logic operators # @@ -690,9 +700,9 @@ binop_reduce("fdot", 1, tfloat, tfloat, "{src0} * {src1}", "{src0} + {src1}", binop_reduce("fdot_replicated", 4, tfloat, tfloat, "{src0} * {src1}", "{src0} + {src1}", "{src}") -opcode("fdph", 1, tfloat, [3, 4], [tfloat, tfloat], "", +opcode("fdph", 1, tfloat, [3, 4], [tfloat, tfloat], False, "", "src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src1.w") -opcode("fdph_replicated", 4, tfloat, [3, 4], [tfloat, tfloat], "", +opcode("fdph_replicated", 4, tfloat, [3, 4], [tfloat, tfloat], False, "", "src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src1.w") binop("fmin", tfloat, "", "fminf(src0, src1)") @@ -769,7 +779,7 @@ else dst = ((1u << bits) - 1) << offset; """) -opcode("ldexp", 0, tfloat, [0, 0], [tfloat, tint32], "", """ +opcode("ldexp", 0, tfloat, [0, 0], [tfloat, tint32], False, "", """ dst = (bit_size == 64) ? ldexp(src0, src1) : ldexpf(src0, src1); /* flush denormals to zero. */ if (!isnormal(dst)) @@ -793,11 +803,11 @@ binop("extract_i16", tint, "", "(int16_t)(src0 >> (src1 * 16))") def triop(name, ty, const_expr): - opcode(name, 0, ty, [0, 0, 0], [ty, ty, ty], "", const_expr) + opcode(name, 0, ty, [0, 0, 0], [ty, ty, ty], False, "", const_expr) def triop_horiz(name, output_size, src1_size, src2_size, src3_size, const_expr): opcode(name, output_size, tuint, [src1_size, src2_size, src3_size], - [tuint, tuint, tuint], "", const_expr) + [tuint, tuint, tuint], False, "", const_expr) triop("ffma", tfloat, "src0 * src1 + src2") @@ -826,9 +836,9 @@ triop("imed3", tint, "MAX2(MIN2(MAX2(src0, src1), src2), MIN2(src0, src1))") triop("umed3", tuint, "MAX2(MIN2(MAX2(src0, src1), src2), MIN2(src0, src1))") opcode("bcsel", 0, tuint, [0, 0, 0], - [tbool1, tuint, tuint], "", "src0 ? src1 : src2") + [tbool1, tuint, tuint], False, "", "src0 ? src1 : src2") opcode("b32csel", 0, tuint, [0, 0, 0], - [tbool32, tuint, tuint], "", "src0 ? src1 : src2") + [tbool32, tuint, tuint], False, "", "src0 ? src1 : src2") # SM5 bfi assembly triop("bfi", tuint32, """ @@ -847,7 +857,7 @@ if (mask == 0) { # SM5 ubfe/ibfe assembly opcode("ubfe", 0, tuint32, - [0, 0, 0], [tuint32, tint32, tint32], "", """ + [0, 0, 0], [tuint32, tint32, tint32], False, "", """ unsigned base = src0; int offset = src1, bits = src2; if (bits == 0) { @@ -861,7 +871,7 @@ if (bits == 0) { } """) opcode("ibfe", 0, tint32, - [0, 0, 0], [tint32, tint32, tint32], "", """ + [0, 0, 0], [tint32, tint32, tint32], False, "", """ int base = src0; int offset = src1, bits = src2; if (bits == 0) { @@ -877,7 +887,7 @@ if (bits == 0) { # GLSL bitfieldExtract() opcode("ubitfield_extract", 0, tuint32, - [0, 0, 0], [tuint32, tint32, tint32], "", """ + [0, 0, 0], [tuint32, tint32, tint32], False, "", """ unsigned base = src0; int offset = src1, bits = src2; if (bits == 0) { @@ -889,7 +899,7 @@ if (bits == 0) { } """) opcode("ibitfield_extract", 0, tint32, - [0, 0, 0], [tint32, tint32, tint32], "", """ + [0, 0, 0], [tint32, tint32, tint32], False, "", """ int base = src0; int offset = src1, bits = src2; if (bits == 0) { @@ -914,10 +924,10 @@ def quadop_horiz(name, output_size, src1_size, src2_size, src3_size, opcode(name, output_size, tuint, [src1_size, src2_size, src3_size, src4_size], [tuint, tuint, tuint, tuint], - "", const_expr) + False, "", const_expr) opcode("bitfield_insert", 0, tuint32, [0, 0, 0, 0], - [tuint32, tuint32, tint32, tint32], "", """ + [tuint32, tuint32, tint32, tint32], False, "", """ unsigned base = src0, insert = src1; int offset = src2, bits = src3; if (bits == 0) { diff --git a/src/compiler/nir/nir_opcodes_c.py b/src/compiler/nir/nir_opcodes_c.py index 017c8b7ea9a..96c71a1b2c5 100644 --- a/src/compiler/nir/nir_opcodes_c.py +++ b/src/compiler/nir/nir_opcodes_c.py @@ -117,6 +117,7 @@ const nir_op_info nir_op_infos[nir_num_opcodes] = { .input_types = { ${ ", ".join("nir_type_" + type for type in opcode.input_types) } }, + .is_conversion = ${"true" if opcode.is_conversion else "false"}, .algebraic_properties = ${ "0" if opcode.algebraic_properties == "" else " | ".join( "NIR_OP_IS_" + prop.upper() for prop in