[Mesa-dev] [PATCH 2/5] nir: use Python to autogenerate opcode information

Connor Abbott cwabbott0 at gmail.com
Fri Jan 16 19:18:43 PST 2015


Hi Dylan,

On Fri, Jan 16, 2015 at 7:01 PM, Dylan Baker <baker.dylan.c at gmail.com> wrote:
> Hi Conner, I have a couple of things you should change, and a suggestion
> for you below, hopefully it all makes sense.
>
> On Friday, January 16, 2015 04:46:07 PM Connor Abbott wrote:
>> Before, we used a system where a file, nir_opcodes.h, defined some macros that
>> were included to generate the enum values and the nir_op_infos structure. This
>> worked pretty well, but for development the error messages were never very
>> useful, Python tools couldn't understand the opcode list, and it was difficult
>> to use nir_opcodes.h to do other things like autogenerate a builder API. Now, we
>> store opcode information in nir_opcodes.py, and we have nir_opcodes_c.py to
>> generate the old nir_opcodes.c and nir_opcodes_h.py to generate nir_opcodes.h,
>> which contains all the enum names and gets included into nir.h like before.  In
>> addition to solving the above problems, using Python and Mako to generate
>> everything means that it's much easier to add keep information centralized as we
>> add new things like constant propagation that require per-opcode information.
>>
>> Signed-off-by: Connor Abbott <cwabbott0 at gmail.com>
>> ---
>>  src/glsl/Makefile.am          |  15 +-
>>  src/glsl/Makefile.sources     |   6 +-
>>  src/glsl/nir/.gitignore       |   2 +
>>  src/glsl/nir/nir.h            |   9 -
>>  src/glsl/nir/nir_opcodes.c    |  46 ------
>>  src/glsl/nir/nir_opcodes.h    | 366 ----------------------------------------
>>  src/glsl/nir/nir_opcodes.py   | 377 ++++++++++++++++++++++++++++++++++++++++++
>>  src/glsl/nir/nir_opcodes_c.py |  56 +++++++
>>  src/glsl/nir/nir_opcodes_h.py |  39 +++++
>>  9 files changed, 491 insertions(+), 425 deletions(-)
>>  delete mode 100644 src/glsl/nir/nir_opcodes.c
>>  delete mode 100644 src/glsl/nir/nir_opcodes.h
>>  create mode 100644 src/glsl/nir/nir_opcodes.py
>>  create mode 100644 src/glsl/nir/nir_opcodes_c.py
>>  create mode 100644 src/glsl/nir/nir_opcodes_h.py
>>
>> diff --git a/src/glsl/Makefile.am b/src/glsl/Makefile.am
>> index b2b74a9..b2fe16a 100644
>> --- a/src/glsl/Makefile.am
>> +++ b/src/glsl/Makefile.am
>> @@ -27,6 +27,7 @@ AM_CPPFLAGS = \
>>       -I$(top_srcdir)/src/glsl/glcpp \
>>       -I$(top_srcdir)/src/glsl/nir \
>>       -I$(top_srcdir)/src/gtest/include \
>> +     -I$(top_builddir)/src/glsl/nir \
>>       $(DEFINES)
>>  AM_CFLAGS = $(VISIBILITY_CFLAGS)
>>  AM_CXXFLAGS = $(VISIBILITY_CXXFLAGS)
>> @@ -207,7 +208,9 @@ BUILT_SOURCES =                                           \
>>       glsl_lexer.cpp                                  \
>>       glcpp/glcpp-parse.c                             \
>>       glcpp/glcpp-lex.c                               \
>> -     nir/nir_opt_algebraic.c
>> +     nir/nir_opt_algebraic.c                         \
>> +     nir/nir_opcodes.h                               \
>> +     nir/nir_opcodes.c
>>  CLEANFILES =                                         \
>>       glcpp/glcpp-parse.h                             \
>>       glsl_parser.h                                   \
>> @@ -223,3 +226,13 @@ dist-hook:
>>  nir/nir_opt_algebraic.c: nir/nir_opt_algebraic.py nir/nir_algebraic.py
>>       $(MKDIR_P) nir;                                                 \
>>       $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opt_algebraic.py > $@
>> +
>> +nir/nir_opcodes.h: nir/nir_opcodes.py nir/nir_opcodes_h.py
>> +     $(MKDIR_P) nir;                                                 \
>> +     $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_h.py > $@
>> +
>> +nir/nir_opcodes.c: nir/nir_opcodes.py nir/nir_opcodes_c.py
>> +     $(MKDIR_P) nir;                                                 \
>> +     $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_c.py > $@
>> +
>> +nir/nir.h: nir/nir_opcodes.h
>> diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources
>> index a951ca7..03b4f2e 100644
>> --- a/src/glsl/Makefile.sources
>> +++ b/src/glsl/Makefile.sources
>> @@ -14,7 +14,9 @@ LIBGLCPP_GENERATED_FILES = \
>>       $(GLSL_BUILDDIR)/glcpp/glcpp-parse.c
>>
>>  NIR_GENERATED_FILES = \
>> -     $(GLSL_BUILDDIR)/nir/nir_opt_algebraic.c
>> +     $(GLSL_BUILDDIR)/nir/nir_opt_algebraic.c \
>> +     $(GLSL_BUILDDIR)/nir/nir_opcodes.h \
>> +     $(GLSL_BUILDDIR)/nir/nir_opcodes.c
>>
>>  NIR_FILES = \
>>       $(GLSL_SRCDIR)/nir/nir.c \
>> @@ -35,8 +37,6 @@ NIR_FILES = \
>>       $(GLSL_SRCDIR)/nir/nir_lower_var_copies.c \
>>       $(GLSL_SRCDIR)/nir/nir_lower_vec_to_movs.c \
>>       $(GLSL_SRCDIR)/nir/nir_metadata.c \
>> -     $(GLSL_SRCDIR)/nir/nir_opcodes.c \
>> -     $(GLSL_SRCDIR)/nir/nir_opcodes.h \
>>       $(GLSL_SRCDIR)/nir/nir_opt_constant_folding.c \
>>       $(GLSL_SRCDIR)/nir/nir_opt_copy_propagate.c \
>>       $(GLSL_SRCDIR)/nir/nir_opt_cse.c \
>> diff --git a/src/glsl/nir/.gitignore b/src/glsl/nir/.gitignore
>> index 6d954fe..4c28193 100644
>> --- a/src/glsl/nir/.gitignore
>> +++ b/src/glsl/nir/.gitignore
>> @@ -1 +1,3 @@
>>  nir_opt_algebraic.c
>> +nir_opcodes.c
>> +nir_opcodes.h
>> diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h
>> index d5fa0e3..890113c 100644
>> --- a/src/glsl/nir/nir.h
>> +++ b/src/glsl/nir/nir.h
>> @@ -532,20 +532,11 @@ typedef struct {
>>     unsigned write_mask : 4; /* ignored if dest.is_ssa is true */
>>  } nir_alu_dest;
>>
>> -#define OPCODE(name, num_inputs, output_size, output_type, \
>> -               input_sizes, input_types, algebraic_props) \
>> -   nir_op_##name,
>> -
>> -#define LAST_OPCODE(name) nir_last_opcode = nir_op_##name,
>> -
>>  typedef enum {
>>  #include "nir_opcodes.h"
>>     nir_num_opcodes = nir_last_opcode + 1
>>  } nir_op;
>>
>> -#undef OPCODE
>> -#undef LAST_OPCODE
>> -
>>  typedef enum {
>>     nir_type_float,
>>     nir_type_int,
>> diff --git a/src/glsl/nir/nir_opcodes.c b/src/glsl/nir/nir_opcodes.c
>> deleted file mode 100644
>> index 1e66c55..0000000
>> --- a/src/glsl/nir/nir_opcodes.c
>> +++ /dev/null
>> @@ -1,46 +0,0 @@
>> -/*
>> - * Copyright © 2014 Intel Corporation
>> - *
>> - * 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 (cwabbott0 at gmail.com)
>> - *
>> - */
>> -
>> -#include "nir.h"
>> -
>> -#define OPCODE(_name, _num_inputs, _output_size, _output_type, \
>> -               _input_sizes, _input_types, _algebraic_props) \
>> -{ \
>> -   .name = #_name, \
>> -   .num_inputs = _num_inputs, \
>> -   .output_size = _output_size, \
>> -   .output_type = _output_type, \
>> -   .input_sizes = _input_sizes, \
>> -   .input_types = _input_types, \
>> -   .algebraic_properties = _algebraic_props, \
>> -},
>> -
>> -#define LAST_OPCODE(name)
>> -
>> -const nir_op_info nir_op_infos[nir_num_opcodes] = {
>> -#include "nir_opcodes.h"
>> -};
>> diff --git a/src/glsl/nir/nir_opcodes.h b/src/glsl/nir/nir_opcodes.h
>> deleted file mode 100644
>> index c16b7fe..0000000
>> --- a/src/glsl/nir/nir_opcodes.h
>> +++ /dev/null
>> @@ -1,366 +0,0 @@
>> -/*
>> - * Copyright © 2014 Intel Corporation
>> - *
>> - * 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 (cwabbott0 at gmail.com)
>> - *
>> - */
>> -
>> -/**
>> - * This header file defines all the available opcodes in one place. It expands
>> - * to a list of macros of the form:
>> - *
>> - * OPCODE(name, num_inputs, output_size, output_type,
>> - *        input_sizes, input_types, algebraic_properties)
>> - *
>> - * Which should correspond one-to-one with the nir_op_info structure. It is
>> - * included in both ir.h to create the nir_op enum (with members of the form
>> - * nir_op_(name)) and and in opcodes.c to create nir_op_infos, which is a
>> - * const array of nir_op_info structures for each opcode.
>> - */
>> -
>> -#define ARR(...) { __VA_ARGS__ }
>> -
>> -#define UNOP(name, type) OPCODE(name, 1, 0, type, ARR(0), ARR(type), 0)
>> -#define UNOP_CONVERT(name, in_type, out_type) \
>> -   OPCODE(name, 1, 0, out_type, ARR(0), ARR(in_type), 0)
>> -#define UNOP_HORIZ(name, output_size, output_type, input_size, input_type) \
>> -   OPCODE(name, 1, output_size, output_type, ARR(input_size), \
>> -          ARR(input_type), 0)
>> -
>> -#define 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, nir_type_float)
>> -UNOP(imov, nir_type_int)
>> -
>> -UNOP(ineg, nir_type_int)
>> -UNOP(fneg, nir_type_float)
>> -UNOP(inot, nir_type_int) /* invert every bit of the integer */
>> -UNOP(fnot, nir_type_float) /* (src == 0.0) ? 1.0 : 0.0 */
>> -UNOP(fsign, nir_type_float)
>> -UNOP(isign, nir_type_int)
>> -UNOP(iabs, nir_type_int)
>> -UNOP(fabs, nir_type_float)
>> -UNOP(fsat, nir_type_float)
>> -UNOP(frcp, nir_type_float)
>> -UNOP(frsq, nir_type_float)
>> -UNOP(fsqrt, nir_type_float)
>> -UNOP(fexp, nir_type_float) /* < e^x */
>> -UNOP(flog, nir_type_float) /* log base e */
>> -UNOP(fexp2, nir_type_float)
>> -UNOP(flog2, nir_type_float)
>> -UNOP_CONVERT(f2i, nir_type_float, nir_type_int)       /**< Float-to-integer conversion. */
>> -UNOP_CONVERT(f2u, nir_type_float, nir_type_unsigned)  /**< Float-to-unsigned conversion. */
>> -UNOP_CONVERT(i2f, nir_type_int, nir_type_float)       /**< Integer-to-float conversion. */
>> -UNOP_CONVERT(f2b, nir_type_float, nir_type_bool)      /**< Float-to-boolean conversion */
>> -UNOP_CONVERT(b2f, nir_type_bool, nir_type_float)      /**< Boolean-to-float conversion */
>> -UNOP_CONVERT(i2b, nir_type_int, nir_type_bool)        /**< int-to-boolean conversion */
>> -UNOP_CONVERT(b2i, nir_type_bool, nir_type_int)        /**< Boolean-to-int conversion */
>> -UNOP_CONVERT(u2f, nir_type_unsigned, nir_type_float)  /**< Unsigned-to-float conversion. */
>> -
>> -UNOP_REDUCE(bany, 1, nir_type_bool, nir_type_bool) /* returns ~0 if any component of src[0] != 0 */
>> -UNOP_REDUCE(ball, 1, nir_type_bool, nir_type_bool) /* returns ~0 if all components of src[0] != 0 */
>> -UNOP_REDUCE(fany, 1, nir_type_float, nir_type_float) /* returns 1.0 if any component of src[0] != 0 */
>> -UNOP_REDUCE(fall, 1, nir_type_float, nir_type_float) /* returns 1.0 if all components of src[0] != 0 */
>> -
>> -/**
>> - * \name Unary floating-point rounding operations.
>> - */
>> -/*@{*/
>> -UNOP(ftrunc, nir_type_float)
>> -UNOP(fceil, nir_type_float)
>> -UNOP(ffloor, nir_type_float)
>> -UNOP(ffract, nir_type_float)
>> -UNOP(fround_even, nir_type_float)
>> -/*@}*/
>> -
>> -/**
>> - * \name Trigonometric operations.
>> - */
>> -/*@{*/
>> -UNOP(fsin, nir_type_float)
>> -UNOP(fcos, nir_type_float)
>> -UNOP(fsin_reduced, nir_type_float)
>> -UNOP(fcos_reduced, nir_type_float)
>> -/*@}*/
>> -
>> -/**
>> - * \name Partial derivatives.
>> - */
>> -/*@{*/
>> -UNOP(fddx, nir_type_float)
>> -UNOP(fddy, nir_type_float)
>> -UNOP(fddx_fine, nir_type_float)
>> -UNOP(fddy_fine, nir_type_float)
>> -UNOP(fddx_coarse, nir_type_float)
>> -UNOP(fddy_coarse, nir_type_float)
>> -/*@}*/
>> -
>> -/**
>> - * \name Floating point pack and unpack operations.
>> - */
>> -/*@{*/
>> -UNOP_HORIZ(pack_snorm_2x16, 1, nir_type_unsigned, 2, nir_type_float)
>> -UNOP_HORIZ(pack_snorm_4x8, 1, nir_type_unsigned, 4, nir_type_float)
>> -UNOP_HORIZ(pack_unorm_2x16, 1, nir_type_unsigned, 2, nir_type_float)
>> -UNOP_HORIZ(pack_unorm_4x8, 1, nir_type_unsigned, 4, nir_type_float)
>> -UNOP_HORIZ(pack_half_2x16, 1, nir_type_unsigned, 2, nir_type_float)
>> -UNOP_HORIZ(unpack_snorm_2x16, 2, nir_type_float, 1, nir_type_unsigned)
>> -UNOP_HORIZ(unpack_snorm_4x8, 4, nir_type_float, 1, nir_type_unsigned)
>> -UNOP_HORIZ(unpack_unorm_2x16, 2, nir_type_float, 1, nir_type_unsigned)
>> -UNOP_HORIZ(unpack_unorm_4x8, 4, nir_type_float, 1, nir_type_unsigned)
>> -UNOP_HORIZ(unpack_half_2x16, 2, nir_type_float, 1, nir_type_unsigned)
>> -/*@}*/
>> -
>> -/**
>> - * \name Lowered floating point unpacking operations.
>> - */
>> -/*@{*/
>> -UNOP_HORIZ(unpack_half_2x16_split_x, 1, nir_type_float, 1, nir_type_unsigned)
>> -UNOP_HORIZ(unpack_half_2x16_split_y, 1, nir_type_float, 1, nir_type_unsigned)
>> -/*@}*/
>> -
>> -/**
>> - * \name Bit operations, part of ARB_gpu_shader5.
>> - */
>> -/*@{*/
>> -UNOP(bitfield_reverse, nir_type_unsigned)
>> -UNOP(bit_count, nir_type_unsigned)
>> -UNOP_CONVERT(ufind_msb, nir_type_unsigned, nir_type_int)
>> -UNOP(ifind_msb, nir_type_int)
>> -UNOP(find_lsb, nir_type_int)
>> -/*@}*/
>> -
>> -UNOP_HORIZ(fnoise1_1, 1, nir_type_float, 1, nir_type_float)
>> -UNOP_HORIZ(fnoise1_2, 1, nir_type_float, 2, nir_type_float)
>> -UNOP_HORIZ(fnoise1_3, 1, nir_type_float, 3, nir_type_float)
>> -UNOP_HORIZ(fnoise1_4, 1, nir_type_float, 4, nir_type_float)
>> -UNOP_HORIZ(fnoise2_1, 2, nir_type_float, 1, nir_type_float)
>> -UNOP_HORIZ(fnoise2_2, 2, nir_type_float, 2, nir_type_float)
>> -UNOP_HORIZ(fnoise2_3, 2, nir_type_float, 3, nir_type_float)
>> -UNOP_HORIZ(fnoise2_4, 2, nir_type_float, 4, nir_type_float)
>> -UNOP_HORIZ(fnoise3_1, 3, nir_type_float, 1, nir_type_float)
>> -UNOP_HORIZ(fnoise3_2, 3, nir_type_float, 2, nir_type_float)
>> -UNOP_HORIZ(fnoise3_3, 3, nir_type_float, 3, nir_type_float)
>> -UNOP_HORIZ(fnoise3_4, 3, nir_type_float, 4, nir_type_float)
>> -UNOP_HORIZ(fnoise4_1, 4, nir_type_float, 1, nir_type_float)
>> -UNOP_HORIZ(fnoise4_2, 4, nir_type_float, 2, nir_type_float)
>> -UNOP_HORIZ(fnoise4_3, 4, nir_type_float, 3, nir_type_float)
>> -UNOP_HORIZ(fnoise4_4, 4, nir_type_float, 4, nir_type_float)
>> -
>> -#define BINOP(name, type, alg_props) \
>> -   OPCODE(name, 2, 0, type, ARR(0, 0), ARR(type, type), alg_props)
>> -#define BINOP_CONVERT(name, out_type, in_type, alg_props) \
>> -   OPCODE(name, 2, 0, out_type, ARR(0, 0), ARR(in_type, in_type), alg_props)
>> -#define BINOP_COMPARE(name, type, alg_props) \
>> -   OPCODE(name, 2, 0, nir_type_bool, ARR(0, 0), ARR(type, type), alg_props)
>> -#define BINOP_HORIZ(name, output_size, output_type, src1_size, src1_type, \
>> -                    src2_size, src2_type) \
>> -   OPCODE(name, 2, output_size, output_type, ARR(src1_size, src2_size), \
>> -          ARR(src1_type, src2_type), 0)
>> -#define BINOP_REDUCE(name, output_size, output_type, src_type) \
>> -   OPCODE(name##2, 2, output_size, output_type, \
>> -          ARR(2, 2), ARR(src_type, src_type), NIR_OP_IS_COMMUTATIVE) \
>> -   OPCODE(name##3, 2, output_size, output_type, \
>> -          ARR(3, 3), ARR(src_type, src_type), NIR_OP_IS_COMMUTATIVE) \
>> -   OPCODE(name##4, 2, output_size, output_type, \
>> -          ARR(4, 4), ARR(src_type, src_type), NIR_OP_IS_COMMUTATIVE)
>> -
>> -BINOP(fadd, nir_type_float, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -BINOP(iadd, nir_type_int, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -BINOP(fsub, nir_type_float, 0)
>> -BINOP(isub, nir_type_int, 0)
>> -
>> -BINOP(fmul, nir_type_float, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -/* low 32-bits of signed/unsigned integer multiply */
>> -BINOP(imul, nir_type_int, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -/* high 32-bits of signed integer multiply */
>> -BINOP(imul_high, nir_type_int, NIR_OP_IS_COMMUTATIVE)
>> -/* high 32-bits of unsigned integer multiply */
>> -BINOP(umul_high, nir_type_unsigned, NIR_OP_IS_COMMUTATIVE)
>> -
>> -BINOP(fdiv, nir_type_float, 0)
>> -BINOP(idiv, nir_type_int, 0)
>> -BINOP(udiv, nir_type_unsigned, 0)
>> -
>> -/**
>> - * returns a boolean representing the carry resulting from the addition of
>> - * the two unsigned arguments.
>> - */
>> -BINOP_CONVERT(uadd_carry, nir_type_bool, nir_type_unsigned,
>> -              NIR_OP_IS_COMMUTATIVE)
>> -
>> -/**
>> - * returns a boolean representing the borrow resulting from the subtraction
>> - * of the two unsigned arguments.
>> - */
>> -BINOP_CONVERT(usub_borrow, nir_type_bool, nir_type_unsigned, 0)
>> -
>> -BINOP(fmod, nir_type_float, 0)
>> -BINOP(umod, nir_type_unsigned, 0)
>> -
>> -/**
>> - * \name comparisons
>> - */
>> -/*@{*/
>> -
>> -/**
>> - * these integer-aware comparisons return a boolean (0 or ~0)
>> - */
>> -BINOP_COMPARE(flt, nir_type_float, 0)
>> -BINOP_COMPARE(fge, nir_type_float, 0)
>> -BINOP_COMPARE(feq, nir_type_float, NIR_OP_IS_COMMUTATIVE)
>> -BINOP_COMPARE(fne, nir_type_float, NIR_OP_IS_COMMUTATIVE)
>> -BINOP_COMPARE(ilt, nir_type_int, 0)
>> -BINOP_COMPARE(ige, nir_type_int, 0)
>> -BINOP_COMPARE(ieq, nir_type_int, NIR_OP_IS_COMMUTATIVE)
>> -BINOP_COMPARE(ine, nir_type_int, NIR_OP_IS_COMMUTATIVE)
>> -BINOP_COMPARE(ult, nir_type_unsigned, 0)
>> -BINOP_COMPARE(uge, nir_type_unsigned, 0)
>> -
>> -/** integer-aware GLSL-style comparisons that compare floats and ints */
>> -BINOP_REDUCE(ball_fequal,  1, nir_type_bool, nir_type_float)
>> -BINOP_REDUCE(bany_fnequal, 1, nir_type_bool, nir_type_float)
>> -BINOP_REDUCE(ball_iequal,  1, nir_type_bool, nir_type_int)
>> -BINOP_REDUCE(bany_inequal, 1, nir_type_bool, nir_type_int)
>> -
>> -/** non-integer-aware GLSL-style comparisons that return 0.0 or 1.0 */
>> -BINOP_REDUCE(fall_equal,  1, nir_type_float, nir_type_float)
>> -BINOP_REDUCE(fany_nequal, 1, nir_type_float, nir_type_float)
>> -
>> -/**
>> - * These comparisons for integer-less hardware return 1.0 and 0.0 for true
>> - * and false respectively
>> - */
>> -BINOP(slt, nir_type_float, 0) /* Set on Less Than */
>> -BINOP(sge, nir_type_float, 0) /* Set on Greater Than or Equal */
>> -BINOP(seq, nir_type_float, NIR_OP_IS_COMMUTATIVE) /* Set on Equal */
>> -BINOP(sne, nir_type_float, NIR_OP_IS_COMMUTATIVE) /* Set on Not Equal */
>> -
>> -/*@}*/
>> -
>> -BINOP(ishl, nir_type_int, 0)
>> -BINOP(ishr, nir_type_int, 0)
>> -BINOP(ushr, nir_type_unsigned, 0)
>> -
>> -/**
>> - * \name bitwise logic operators
>> - *
>> - * These are also used as boolean and, or, xor for hardware supporting
>> - * integers.
>> - */
>> -/*@{*/
>> -BINOP(iand, nir_type_unsigned, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -BINOP(ior, nir_type_unsigned, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -BINOP(ixor, nir_type_unsigned, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -/*@{*/
>> -
>> -/**
>> - * \name 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, nir_type_float, NIR_OP_IS_COMMUTATIVE)
>> -BINOP(for, nir_type_float, NIR_OP_IS_COMMUTATIVE)
>> -BINOP(fxor, nir_type_float, NIR_OP_IS_COMMUTATIVE)
>> -
>> -BINOP_REDUCE(fdot, 1, nir_type_float, nir_type_float)
>> -
>> -BINOP(fmin, nir_type_float, 0)
>> -BINOP(imin, nir_type_int, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -BINOP(umin, nir_type_unsigned, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -BINOP(fmax, nir_type_float, 0)
>> -BINOP(imax, nir_type_int, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -BINOP(umax, nir_type_unsigned, NIR_OP_IS_COMMUTATIVE | NIR_OP_IS_ASSOCIATIVE)
>> -
>> -BINOP(fpow, nir_type_float, 0)
>> -
>> -BINOP_HORIZ(pack_half_2x16_split, 1, nir_type_unsigned, 1, nir_type_float, 1, nir_type_float)
>> -
>> -BINOP(bfm, nir_type_unsigned, 0)
>> -
>> -BINOP(ldexp, nir_type_unsigned, 0)
>> -
>> -/**
>> - * Combines the first component of each input to make a 2-component vector.
>> - */
>> -BINOP_HORIZ(vec2, 2, nir_type_unsigned, 1, nir_type_unsigned, 1, nir_type_unsigned)
>> -
>> -#define TRIOP(name, type) \
>> -   OPCODE(name, 3, 0, type, ARR(0, 0, 0), ARR(type, type, type), 0)
>> -#define TRIOP_HORIZ(name, output_size, src1_size, src2_size, src3_size) \
>> -   OPCODE(name, 3, output_size, nir_type_unsigned, \
>> -   ARR(src1_size, src2_size, src3_size), \
>> -   ARR(nir_type_unsigned, nir_type_unsigned, nir_type_unsigned), 0)
>> -
>> -/* fma(a, b, c) = (a * b) + c */
>> -TRIOP(ffma, nir_type_float)
>> -
>> -TRIOP(flrp, nir_type_float)
>> -
>> -/**
>> - * \name 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, nir_type_float)
>> -OPCODE(bcsel, 3, 0, nir_type_unsigned, ARR(0, 0, 0),
>> -       ARR(nir_type_bool, nir_type_unsigned, nir_type_unsigned), 0)
>> -
>> -TRIOP(bfi, nir_type_unsigned)
>> -
>> -TRIOP(ubitfield_extract, nir_type_unsigned)
>> -OPCODE(ibitfield_extract, 3, 0, nir_type_int, ARR(0, 0, 0),
>> -       ARR(nir_type_int, nir_type_unsigned, nir_type_unsigned), 0)
>> -
>> -/**
>> - * Combines the first component of each input to make a 3-component vector.
>> - */
>> -TRIOP_HORIZ(vec3, 3, 1, 1, 1)
>> -
>> -#define QUADOP(name) \
>> -   OPCODE(name, 4, 0, nir_type_unsigned, ARR(0, 0, 0, 0), \
>> -          ARR(nir_type_unsigned, nir_type_unsigned, nir_type_unsigned, nir_type_unsigned), \
>> -          0)
>> -#define QUADOP_HORIZ(name, output_size, src1_size, src2_size, src3_size, \
>> -                     src4_size) \
>> -   OPCODE(name, 4, output_size, nir_type_unsigned, \
>> -          ARR(src1_size, src2_size, src3_size, src4_size), \
>> -          ARR(nir_type_unsigned, nir_type_unsigned, nir_type_unsigned, nir_type_unsigned), \
>> -          0)
>> -
>> -QUADOP(bitfield_insert)
>> -
>> -QUADOP_HORIZ(vec4, 4, 1, 1, 1, 1)
>> -
>> -LAST_OPCODE(vec4)
>> diff --git a/src/glsl/nir/nir_opcodes.py b/src/glsl/nir/nir_opcodes.py
>> new file mode 100644
>> index 0000000..fa2f563
>> --- /dev/null
>> +++ b/src/glsl/nir/nir_opcodes.py
>> @@ -0,0 +1,377 @@
>> +#! /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 (cwabbott0 at gmail.com)
>> +
>> +# Class that represents all the information we have about the opcode
>> +# NOTE: this must be kept in sync with nir_op_info
>> +
>> +class Opcode:
>
> you want all of your classes to descend from object, otherwise you're
> creating old-style classes, which can lead to odd behavior in a lot of
> cases.
>
>> +   # 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
>> +   def __init__(self, name, output_size, output_type, input_sizes,
>> +                input_types, algebraic_properties):
>> +      assert(isinstance(name, str))
>
> assert is a keyword in python, no parens needed. Also, it's a really
> good idea not to use them, since if a ',' in there will create a tuple,
> and assert with a tuple does not do what you expect/want
>
>> +      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
>
> See my comment below, but I think you should add the following code to
> the class:
>     def __lt__(self, other):
>         if isinstance(other, Opcode):
>             return self.name < other.name
>         raise NotImplementedError
>
>     def __eq__(self, other):
>         if isinstance(other, Opcode):
>             return self.name == other.name
>         raise NotImplementedError
>
>     def __hash__(self):
>         return hash(self.name)
>
> You might need more than that, but I think just __lt__ and __eq__ is
> sufficient to make sorted() work. Note that I'm assuming that you want
> to sort based on name, you define whatever you wanted for sorting
> really.

If I keep the dictionary, I don't need these? Right? Or is there still
some value to them in making things simpler?

>
>> +
>> +# helper variables for strings
>> +tfloat = "float"
>> +tint = "int"
>> +tbool = "bool"
>> +tunsigned = "unsigned"
>> +
>> +commutative = "commutative "
>> +associative = "associative "
>> +
>> +# global dictionary of opcodes
>> +opcodes = {}
>
> I think you can use either a list() or a set() here instead of a dict
> here, just use .append() or .add() (respective to which class you use),
> you'll need to implemented __lt__ and __eq__ for Opcode so they can be
> sorted, and you'll need __hash__ if you use set(). There's a few other
> changes needed, I've pointed most of them out below.

The reason I decided to use a dict here is that in the future, we'll
probably want to be able to easily lookup the opcode information given
a name. For example, in nir_opt_algebraic.py, we want to be able to
figure out the input types for an opcode in an expression tree so that
we emit the right constant type if its input is a constant. I can add
a patch to the series that does that and a comment to make this more
clear. Also, we use the fact that you can easily check if a given name
is in the dict to make sure that we don't add two opcodes with the
same name a few lines below this, although I guess it would work with
a set too.

>
>> +
>> +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 range(1, 5):
>> +   for j in range(1, 5):
>
> use xrange instead of range.
>
>> +      unop_horiz("fnoise" + str(i) + "_" + str(j), i, tfloat, j, tfloat)
>
> I think str.format makes this more readable: 'fnoise{0}_{1}'.format(i, j)

Sure.

>
>> +
>> +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, commutative + associative)
>> +binop("imin", tint, commutative + associative)
>> +binop("umin", tunsigned, commutative + associative)
>> +binop("fmax", tfloat, commutative + associative)
>> +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)
>> +
>> +
>> diff --git a/src/glsl/nir/nir_opcodes_c.py b/src/glsl/nir/nir_opcodes_c.py
>> new file mode 100644
>> index 0000000..04a22b5
>> --- /dev/null
>> +++ b/src/glsl/nir/nir_opcodes_c.py
>> @@ -0,0 +1,56 @@
>> +#! /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 (cwabbott0 at gmail.com)
>> +
>> +from nir_opcodes import opcodes
>> +from mako.template import Template
>> +
>> +template = Template("""
>
> If you replace """ with """\ you won't get an extra newline at the top
> of the file
>
>> +#include "nir.h"
>> +
>> +const nir_op_info nir_op_infos[nir_num_opcodes] = {
>> +% for name, opcode in sorted(opcodes.iteritems()):
>
> would need to be updated for list or set
>
>> +{
>> +   .name = "${name}",
>
> If you take my suggestion to use a list or set you'll need to update the
> above to opcode.name
>
>> +   .num_inputs = ${opcode.num_inputs},
>> +   .output_size = ${opcode.output_size},
>> +   .output_type = ${"nir_type_" + opcode.output_type},
>> +   .input_sizes = {
>> +      ${ ", ".join(str(size) for size in opcode.input_sizes) }
>> +   },
>> +   .input_types = {
>> +      ${ ", ".join("nir_type_" + type for type in opcode.input_types) }
>> +   },
>> +   .algebraic_properties =
>> +      ${ "0" if opcode.algebraic_properties == "" else " | ".join(
>> +            "NIR_OP_IS_" + prop.upper() for prop in
>> +               opcode.algebraic_properties.strip().split(" ")) }
>> +},
>> +% endfor
>> +};
>> +""")
>> +
>> +print template.render(opcodes=opcodes)
>> +
>> diff --git a/src/glsl/nir/nir_opcodes_h.py b/src/glsl/nir/nir_opcodes_h.py
>> new file mode 100644
>> index 0000000..84d004c
>> --- /dev/null
>> +++ b/src/glsl/nir/nir_opcodes_h.py
>> @@ -0,0 +1,39 @@
>> +#! /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 (cwabbott0 at gmail.com)
>> +
>> +from nir_opcodes import opcodes
>> +from mako.template import Template
>> +
>> +
>> +template = Template("""
>> +% for name in sorted(opcodes):
>
> If you take my suggestion you'll need to update the lines above and
> below,
>
> If you don't, I think this should actually be:
> % for name in sorted(opcodes.iterkeys()):
> otherwise you're getting a tuple out of your for loop.
>
>> +nir_op_${name},
>> +% endfor
>> +nir_last_opcode = nir_op_${sorted(opcodes)[-1]},
>> +""")
>> +
>> +print template.render(opcodes=opcodes)
>> +
>> --
>> 2.1.0
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>


More information about the mesa-dev mailing list