1bf215546Sopenharmony_ci# Copyright © 2021 Intel Corporation
2bf215546Sopenharmony_ci#
3bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a
4bf215546Sopenharmony_ci# copy of this software and associated documentation files (the
5bf215546Sopenharmony_ci# "Software"), to deal in the Software without restriction, including
6bf215546Sopenharmony_ci# without limitation the rights to use, copy, modify, merge, publish,
7bf215546Sopenharmony_ci# distribute, sub license, and/or sell copies of the Software, and to
8bf215546Sopenharmony_ci# permit persons to whom the Software is furnished to do so, subject to
9bf215546Sopenharmony_ci# the following conditions:
10bf215546Sopenharmony_ci#
11bf215546Sopenharmony_ci# The above copyright notice and this permission notice (including the
12bf215546Sopenharmony_ci# next paragraph) shall be included in all copies or substantial portions
13bf215546Sopenharmony_ci# of the Software.
14bf215546Sopenharmony_ci#
15bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16bf215546Sopenharmony_ci# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17bf215546Sopenharmony_ci# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
18bf215546Sopenharmony_ci# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
19bf215546Sopenharmony_ci# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20bf215546Sopenharmony_ci# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21bf215546Sopenharmony_ci# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci
23bf215546Sopenharmony_ciimport docutils.nodes
24bf215546Sopenharmony_ciimport mako.template
25bf215546Sopenharmony_ciimport os
26bf215546Sopenharmony_ciimport sphinx
27bf215546Sopenharmony_cifrom sphinx.directives import SphinxDirective
28bf215546Sopenharmony_cifrom sphinx.domains import Domain
29bf215546Sopenharmony_cifrom sphinx.util.nodes import make_refnode
30bf215546Sopenharmony_ciimport sys
31bf215546Sopenharmony_ciimport textwrap
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ciTHIS_DIR = os.path.dirname(os.path.abspath(__file__))
34bf215546Sopenharmony_ciMESA_DIR = os.path.join(THIS_DIR, '..', '..')
35bf215546Sopenharmony_ciNIR_PATH = os.path.join(MESA_DIR, 'src', 'compiler', 'nir')
36bf215546Sopenharmony_cisys.path.append(NIR_PATH)
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ciimport nir_opcodes
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ciOP_DESC_TEMPLATE = mako.template.Template("""
41bf215546Sopenharmony_ci<%
42bf215546Sopenharmony_cidef src_decl_list(num_srcs):
43bf215546Sopenharmony_ci   return ', '.join('nir_ssa_def *src' + str(i) for i in range(num_srcs))
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_cidef to_yn(b):
46bf215546Sopenharmony_ci    return 'Y' if b else 'N'
47bf215546Sopenharmony_ci%>
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci**Properties:**
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci.. list-table::
52bf215546Sopenharmony_ci   :header-rows: 1
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci   * - Per-component
55bf215546Sopenharmony_ci     - Associative
56bf215546Sopenharmony_ci     - 2-src commutative
57bf215546Sopenharmony_ci   * - ${to_yn(op.output_size == 0)}
58bf215546Sopenharmony_ci     - ${to_yn('associative' in op.algebraic_properties)}
59bf215546Sopenharmony_ci     - ${to_yn('2src_commutative' in op.algebraic_properties)}
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci**Constant-folding:**
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci.. code-block:: c
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_ci${textwrap.indent(op.const_expr, '    ')}
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_ci**Builder function:**
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_ci.. c:function:: nir_ssa_def *nir_${op.name}(nir_builder *, ${src_decl_list(op.num_inputs)})
70bf215546Sopenharmony_ci""")
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_cidef parse_rst(state, parent, rst):
73bf215546Sopenharmony_ci    vl = docutils.statemachine.ViewList(rst.splitlines())
74bf215546Sopenharmony_ci    state.nested_parse(vl, 0, parent)
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_cidef nir_alu_type_name(t, s):
77bf215546Sopenharmony_ci    if s:
78bf215546Sopenharmony_ci        return '{}[{}]'.format(t, s)
79bf215546Sopenharmony_ci    else:
80bf215546Sopenharmony_ci        return '{}[N]'.format(t)
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_cidef build_alu_op_desc(state, env, op):
83bf215546Sopenharmony_ci    desc = sphinx.addnodes.desc(domain='nir', objtype='aluop')
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci    # Add the signature
86bf215546Sopenharmony_ci    sig = sphinx.addnodes.desc_signature()
87bf215546Sopenharmony_ci    desc.append(sig)
88bf215546Sopenharmony_ci    sig += sphinx.addnodes.desc_name(op.name, op.name)
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci    params = sphinx.addnodes.desc_parameterlist()
91bf215546Sopenharmony_ci    for i, t, s in zip(range(100), op.input_types, op.input_sizes):
92bf215546Sopenharmony_ci        params += docutils.nodes.Text(nir_alu_type_name(t, s) + ' ')
93bf215546Sopenharmony_ci        params += sphinx.addnodes.desc_parameter('', 'src' + str(i))
94bf215546Sopenharmony_ci    sig += params
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci    sig += sphinx.addnodes.desc_returns('',
97bf215546Sopenharmony_ci        nir_alu_type_name(op.output_type, op.output_size))
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci    nir_domain = env.get_domain('nir')
100bf215546Sopenharmony_ci    sig['ids'].append(nir_domain.add_alu_op_ref(op))
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci    # Build the description
103bf215546Sopenharmony_ci    content = sphinx.addnodes.desc_content()
104bf215546Sopenharmony_ci    desc.append(content)
105bf215546Sopenharmony_ci    parse_rst(state, content, OP_DESC_TEMPLATE.render(op=op, textwrap=textwrap))
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci    return desc
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ciclass NIRALUOpcodesDirective(SphinxDirective):
110bf215546Sopenharmony_ci    def run(self):
111bf215546Sopenharmony_ci        return [build_alu_op_desc(self.state, self.env, op)
112bf215546Sopenharmony_ci                for op in nir_opcodes.opcodes.values()]
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ciclass NIRDomain(Domain):
115bf215546Sopenharmony_ci    """A new NIR directive
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci    To list all NIR ALU opcodes with their descriptions:
118bf215546Sopenharmony_ci    ```rst
119bf215546Sopenharmony_ci    .. nir:alu-opcodes::
120bf215546Sopenharmony_ci    ```
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_ci    To reference a NIR opcode, ``:nir:alu-op:`fadd```
123bf215546Sopenharmony_ci    """
124bf215546Sopenharmony_ci    name = 'nir'
125bf215546Sopenharmony_ci    roles = {
126bf215546Sopenharmony_ci        'alu-op' : sphinx.roles.XRefRole(),
127bf215546Sopenharmony_ci    }
128bf215546Sopenharmony_ci    directives = {
129bf215546Sopenharmony_ci        'alu-opcodes' : NIRALUOpcodesDirective,
130bf215546Sopenharmony_ci    }
131bf215546Sopenharmony_ci    initial_data = {
132bf215546Sopenharmony_ci        'alu-op-refs': [],
133bf215546Sopenharmony_ci    }
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci    def add_alu_op_ref(self, op):
136bf215546Sopenharmony_ci        """Add reference to an ALU op."""
137bf215546Sopenharmony_ci        self.data['alu-op-refs'].append((op.name, self.env.docname))
138bf215546Sopenharmony_ci        return 'nir-alu-op-' + op.name
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci    def resolve_xref(self, env, fromdocname, builder, typ, target, node,
141bf215546Sopenharmony_ci                     contnode):
142bf215546Sopenharmony_ci        for opname, todocname in self.data['alu-op-refs']:
143bf215546Sopenharmony_ci            if target == opname:
144bf215546Sopenharmony_ci                targ = 'nir-alu-op-' + opname
145bf215546Sopenharmony_ci                return make_refnode(builder, fromdocname, todocname, targ,
146bf215546Sopenharmony_ci                                    contnode, targ)
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci        return None
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_cidef setup(app):
151bf215546Sopenharmony_ci    app.add_domain(NIRDomain)
152