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
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)
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
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):
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.
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.
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)
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):
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")
# 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
#
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)")
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))
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")
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, """
# 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) {
}
""")
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) {
# 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) {
}
""")
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) {
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) {