xref: /aosp_15_r20/external/mesa3d/src/asahi/compiler/agx_builder.h.py (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1template = """/*
2 * Copyright 2021 Alyssa Rosenzweig
3 * SPDX-License-Identifier: MIT
4 */
5
6#ifndef _AGX_BUILDER_
7#define _AGX_BUILDER_
8
9#include "agx_compiler.h"
10
11static inline agx_instr *
12agx_alloc_instr(agx_builder *b, enum agx_opcode op, uint8_t nr_dests, uint8_t nr_srcs)
13{
14   size_t size = sizeof(agx_instr);
15   size += sizeof(agx_index) * nr_dests;
16   size += sizeof(agx_index) * nr_srcs;
17
18   agx_instr *I = (agx_instr *) rzalloc_size(b->shader, size);
19   I->dest = (agx_index *) (I + 1);
20   I->src = I->dest + nr_dests;
21
22   I->op = op;
23   I->nr_dests = nr_dests;
24   I->nr_srcs = nr_srcs;
25   return I;
26}
27
28% for opcode in opcodes:
29<%
30   op = opcodes[opcode]
31   dests = op.dests
32   srcs = op.srcs
33   imms = [x for x in op.imms if (x.name != 'scoreboard' or opcode == 'wait')]
34   suffix = "_to" if dests > 0 else ""
35   nr_dests = "nr_dests" if op.variable_dests else str(dests)
36   nr_srcs = "nr_srcs" if op.variable_srcs else str(srcs)
37%>
38
39static inline agx_instr *
40agx_${opcode}${suffix}(agx_builder *b
41
42% if op.variable_dests:
43   , unsigned nr_dests
44% endif
45
46% for dest in range(dests):
47   , agx_index dst${dest}
48% endfor
49
50% if op.variable_srcs:
51   , unsigned nr_srcs
52% endif
53
54% for src in range(srcs):
55   , agx_index src${src}
56% endfor
57
58% for imm in imms:
59   , ${imm.ctype} ${imm.name}
60% endfor
61
62) {
63   agx_instr *I = agx_alloc_instr(b, AGX_OPCODE_${opcode.upper()}, ${nr_dests}, ${nr_srcs});
64
65% for dest in range(dests):
66   I->dest[${dest}] = dst${dest};
67% endfor
68
69% for src in range(srcs):
70   I->src[${src}] = src${src};
71% endfor
72
73% for imm in imms:
74   I->${imm.name} = ${imm.name};
75% endfor
76
77   agx_builder_insert(&b->cursor, I);
78   return I;
79}
80
81% if dests == 1 and not op.variable_srcs and not op.variable_dests:
82static inline agx_index
83agx_${opcode}(agx_builder *b
84
85% if srcs == 0:
86   , unsigned size
87% endif
88
89% for src in range(srcs):
90   , agx_index src${src}
91% endfor
92
93% for imm in imms:
94   , ${imm.ctype} ${imm.name}
95% endfor
96
97) {
98<%
99   args = ["tmp"]
100   args += ["src" + str(i) for i in range(srcs)]
101   args += [imm.name for imm in imms]
102%>
103% if srcs == 0:
104   agx_index tmp = agx_temp(b->shader, agx_size_for_bits(size));
105% else:
106   agx_index tmp = agx_temp(b->shader, src0.size);
107% endif
108   agx_${opcode}_to(b, ${", ".join(args)});
109   return tmp;
110}
111% endif
112
113% endfor
114
115/* Convenience methods */
116
117enum agx_bitop_table {
118   AGX_BITOP_NOR   = 0x1,
119   AGX_BITOP_ANDN2 = 0x2,
120   AGX_BITOP_ANDN1 = 0x4,
121   AGX_BITOP_NOT   = 0x5,
122   AGX_BITOP_XOR   = 0x6,
123   AGX_BITOP_NAND  = 0x7,
124   AGX_BITOP_AND   = 0x8,
125   AGX_BITOP_XNOR  = 0x9,
126   AGX_BITOP_MOV   = 0xA,
127   AGX_BITOP_ORN2  = 0xB,
128   AGX_BITOP_ORN1  = 0xD,
129   AGX_BITOP_OR    = 0xE
130};
131
132#define BINOP_BITOP(name, table)                                                     \
133   static inline agx_instr *                                                         \
134   agx_## name ##_to(agx_builder *b, agx_index dst0, agx_index src0, agx_index src1) \
135   {                                                                                 \
136      return agx_bitop_to(b, dst0, src0, src1, AGX_BITOP_ ## table);                 \
137   }                                                                                 \
138                                                                                     \
139   static inline agx_index                                                           \
140   agx_## name (agx_builder *b, agx_index src0, agx_index src1)                      \
141   {                                                                                 \
142      agx_index tmp = agx_temp(b->shader, src0.size);                                \
143      agx_##name##_to(b, tmp, src0, src1);                                           \
144      return tmp;                                                                    \
145   }
146
147BINOP_BITOP(nor, NOR)
148BINOP_BITOP(andn2, ANDN2)
149BINOP_BITOP(andn1, ANDN1)
150BINOP_BITOP(xor, XOR)
151BINOP_BITOP(nand, NAND)
152BINOP_BITOP(and, AND)
153BINOP_BITOP(xnor, XNOR)
154BINOP_BITOP(orn2, ORN2)
155BINOP_BITOP(orn1, ORN1)
156BINOP_BITOP(or, OR)
157
158#undef BINOP_BITOP
159
160static inline agx_instr *
161agx_fmov_to(agx_builder *b, agx_index dst0, agx_index src0)
162{
163   return agx_fadd_to(b, dst0, src0, agx_negzero());
164}
165
166static inline agx_instr *
167agx_push_exec(agx_builder *b, unsigned n)
168{
169   return agx_if_fcmp(b, agx_zero(), agx_zero(), n, AGX_FCOND_EQ, false, NULL);
170}
171
172static inline agx_instr *
173agx_ushr_to(agx_builder *b, agx_index dst, agx_index s0, agx_index s1)
174{
175    return agx_bfeil_to(b, dst, agx_zero(), s0, s1, 0);
176}
177
178static inline agx_index
179agx_ushr(agx_builder *b, agx_index s0, agx_index s1)
180{
181    agx_index tmp = agx_temp(b->shader, s0.size);
182    agx_ushr_to(b, tmp, s0, s1);
183    return tmp;
184}
185
186#endif
187"""
188
189from mako.template import Template
190from agx_opcodes import opcodes
191
192print(Template(template).render(opcodes=opcodes))
193