xref: /aosp_15_r20/external/mesa3d/src/panfrost/compiler/valhall/valhall.c.py (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1#encoding=utf-8
2
3# Copyright (C) 2021 Collabora, Ltd.
4#
5# Permission is hereby granted, free of charge, to any person obtaining a
6# copy of this software and associated documentation files (the "Software"),
7# to deal in the Software without restriction, including without limitation
8# the rights to use, copy, modify, merge, publish, distribute, sublicense,
9# and/or sell copies of the Software, and to permit persons to whom the
10# Software is furnished to do so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice (including the next
13# paragraph) shall be included in all copies or substantial portions of the
14# Software.
15#
16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22# IN THE SOFTWARE.
23
24import sys
25from valhall import valhall_parse_isa
26from mako.template import Template
27from mako import exceptions
28
29(instructions, immediates, enums, typesize, safe_name) = valhall_parse_isa()
30
31SKIP = set([
32        # Extra conversions
33        "S8_TO_S16",
34        "S8_TO_F16",
35        "U8_TO_U16",
36        "U8_TO_F16",
37
38        # Saturating multiplies
39        "IMUL.s32",
40        "IMUL.v2s16",
41        "IMUL.v4s8",
42
43        # 64-bit support
44        "IADD.u64",
45        "IADD.s64",
46        "ISUB.u64",
47        "ISUB.s64",
48        "IMULD.u64",
49        "SHADDX.u64",
50        "SHADDX.s64",
51        "IMULD.u64",
52        "CLPER.s64",
53        "CLPER.u64",
54        "LSHIFT_AND.i64",
55        "RSHIFT_AND.i64",
56        "LSHIFT_OR.i64",
57        "RSHIFT_OR.i64",
58        "LSHIFT_XOR.i64",
59        "RSHIFT_XOR.i64",
60        "ATOM.i64",
61        "ATOM_RETURN.i64",
62        "ATOM1_RETURN.i64",
63
64        # CLPER widens
65        "CLPER.s32",
66        "CLPER.v2s16",
67        "CLPER.v4s8",
68        "CLPER.v2u16",
69        "CLPER.v4u8",
70
71        # VAR_TEX
72        "VAR_TEX_SINGLE",
73        "VAR_TEX_GATHER",
74        "VAR_TEX_GRADIENT",
75        "VAR_TEX_DUAL",
76        "VAR_TEX_BUF_SINGLE",
77        "VAR_TEX_BUF_GATHER",
78        "VAR_TEX_BUF_GRADIENT",
79        "VAR_TEX_BUF_DUAL",
80
81        # Special cased
82        "FMA_RSCALE_N.f32",
83        "FMA_RSCALE_LEFT.f32",
84        "FMA_RSCALE_SCALE16.f32",
85
86        # Deprecated instruction
87        "NOT_OLD.i32",
88        "NOT_OLD.i64",
89
90        # TODO
91        "IDP.v4s8",
92        "IDP.v4u8",
93        "FATAN_ASSIST.f32",
94        "SEG_ADD.u64",
95        "TEX_DUAL",
96    ])
97
98template = """
99#include "valhall.h"
100#include "bi_opcodes.h"
101
102const uint32_t valhall_immediates[32] = {
103% for imm in immediates:
104    ${hex(imm)},
105% endfor
106};
107
108<%
109def ibool(x):
110    return '1' if x else '0'
111
112def hasmod(x, mod):
113    return ibool(any([x.name == mod for x in op.modifiers]))
114
115%>
116const struct va_opcode_info
117valhall_opcodes[BI_NUM_OPCODES] = {
118% for op in instructions:
119% if op.name not in skip:
120<%
121    name = op.name
122    if name == 'BRANCHZ':
123        name = 'BRANCHZ.i16'
124
125    sr_control = 0
126
127    if len(op.staging) > 0:
128        sr_control = op.staging[0].encoded_flags >> 6
129%>
130    [BI_OPCODE_${name.replace('.', '_').upper()}] = {
131        .exact = ${hex(exact(op))}ULL,
132        .srcs = {
133% for src in ([sr for sr in op.staging if sr.read] + op.srcs):
134            {
135                .absneg = ${ibool(src.absneg)},
136                .swizzle = ${ibool(src.swizzle)},
137                .notted = ${ibool(src.notted)},
138                .widen = ${ibool(src.widen)},
139                .lanes = ${ibool(src.lanes)},
140                .halfswizzle = ${ibool(src.halfswizzle)},
141                .lane = ${ibool(src.lane)},
142                .combine = ${ibool(src.combine)},
143% if src.size in [8, 16, 32, 64]:
144                .size = VA_SIZE_${src.size},
145% endif
146            },
147% endfor
148        },
149        .type_size = ${typesize(op.name)},
150        .has_dest = ${ibool(len(op.dests) > 0)},
151        .is_signed = ${ibool(op.is_signed)},
152        .unit = VA_UNIT_${op.unit},
153        .nr_srcs = ${len(op.srcs)},
154        .nr_staging_srcs = ${sum([sr.read for sr in op.staging])},
155        .nr_staging_dests = ${sum([sr.write for sr in op.staging])},
156        .clamp = ${hasmod(x, 'clamp')},
157        .saturate = ${hasmod(x, 'saturate')},
158        .rhadd = ${hasmod(x, 'rhadd')},
159        .round_mode = ${hasmod(x, 'round_mode')},
160        .condition = ${hasmod(x, 'condition')},
161        .result_type = ${hasmod(x, 'result_type')},
162        .vecsize = ${hasmod(x, 'vector_size')},
163        .register_format = ${hasmod(x, 'register_format')},
164        .slot = ${hasmod(x, 'slot')},
165        .sr_count = ${hasmod(x, 'staging_register_count')},
166        .sr_write_count = ${hasmod(x, 'staging_register_write_count')},
167        .sr_control = ${sr_control},
168    },
169% endif
170% endfor
171};
172"""
173
174# Exact value to be ORed in to every opcode
175def exact_op(op):
176    return (op.opcode << 48) | (op.opcode2 << op.secondary_shift)
177
178try:
179    print(Template(template).render(immediates = immediates, instructions = instructions, skip = SKIP, exact = exact_op, typesize = typesize))
180except:
181    print(exceptions.text_error_template().render())
182