1bf215546Sopenharmony_ci#
2bf215546Sopenharmony_ci# Copyright (C) 2020 Collabora, Ltd.
3bf215546Sopenharmony_ci#
4bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci# copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci# to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci# the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci# and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci# Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci#
11bf215546Sopenharmony_ci# The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci# paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci# Software.
14bf215546Sopenharmony_ci#
15bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci# IN THE SOFTWARE.
22bf215546Sopenharmony_ci
23bf215546Sopenharmony_ciTEMPLATE = """#include <stdio.h>
24bf215546Sopenharmony_ci#include "compiler.h"
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_cistatic const char *
27bf215546Sopenharmony_cibi_swizzle_as_str(enum bi_swizzle swz)
28bf215546Sopenharmony_ci{
29bf215546Sopenharmony_ci        switch (swz) {
30bf215546Sopenharmony_ci        case BI_SWIZZLE_H00: return ".h00";
31bf215546Sopenharmony_ci        case BI_SWIZZLE_H01: return "";
32bf215546Sopenharmony_ci        case BI_SWIZZLE_H10: return ".h10";
33bf215546Sopenharmony_ci        case BI_SWIZZLE_H11: return ".h11";
34bf215546Sopenharmony_ci        case BI_SWIZZLE_B0000: return ".b0";
35bf215546Sopenharmony_ci        case BI_SWIZZLE_B1111: return ".b1";
36bf215546Sopenharmony_ci        case BI_SWIZZLE_B2222: return ".b2";
37bf215546Sopenharmony_ci        case BI_SWIZZLE_B3333: return ".b3";
38bf215546Sopenharmony_ci        case BI_SWIZZLE_B0011: return ".b0011";
39bf215546Sopenharmony_ci        case BI_SWIZZLE_B2233: return ".b2233";
40bf215546Sopenharmony_ci        case BI_SWIZZLE_B1032: return ".b1032";
41bf215546Sopenharmony_ci        case BI_SWIZZLE_B3210: return ".b3210";
42bf215546Sopenharmony_ci        case BI_SWIZZLE_B0022: return ".b0022";
43bf215546Sopenharmony_ci        }
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci        unreachable("Invalid swizzle");
46bf215546Sopenharmony_ci}
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_cistatic const char *
49bf215546Sopenharmony_cibir_fau_name(unsigned fau_idx)
50bf215546Sopenharmony_ci{
51bf215546Sopenharmony_ci    const char *names[] = {
52bf215546Sopenharmony_ci            "zero", "lane-id", "wrap-id", "core-id", "fb-extent",
53bf215546Sopenharmony_ci            "atest-param", "sample-pos", "reserved",
54bf215546Sopenharmony_ci            "blend_descriptor_0", "blend_descriptor_1",
55bf215546Sopenharmony_ci            "blend_descriptor_2", "blend_descriptor_3",
56bf215546Sopenharmony_ci            "blend_descriptor_4", "blend_descriptor_5",
57bf215546Sopenharmony_ci            "blend_descriptor_6", "blend_descriptor_7",
58bf215546Sopenharmony_ci            "tls_ptr", "wls_ptr", "program_counter",
59bf215546Sopenharmony_ci    };
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci    assert(fau_idx < ARRAY_SIZE(names));
62bf215546Sopenharmony_ci    return names[fau_idx];
63bf215546Sopenharmony_ci}
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_cistatic const char *
66bf215546Sopenharmony_cibir_passthrough_name(unsigned idx)
67bf215546Sopenharmony_ci{
68bf215546Sopenharmony_ci    const char *names[] = {
69bf215546Sopenharmony_ci            "s0", "s1", "s2", "t", "fau.x", "fau.y", "t0", "t1"
70bf215546Sopenharmony_ci    };
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci    assert(idx < ARRAY_SIZE(names));
73bf215546Sopenharmony_ci    return names[idx];
74bf215546Sopenharmony_ci}
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_cistatic void
77bf215546Sopenharmony_cibi_print_index(FILE *fp, bi_index index)
78bf215546Sopenharmony_ci{
79bf215546Sopenharmony_ci    if (index.discard)
80bf215546Sopenharmony_ci        fputs("^", fp);
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci    if (bi_is_null(index))
83bf215546Sopenharmony_ci        fprintf(fp, "_");
84bf215546Sopenharmony_ci    else if (index.type == BI_INDEX_CONSTANT)
85bf215546Sopenharmony_ci        fprintf(fp, "#0x%x", index.value);
86bf215546Sopenharmony_ci    else if (index.type == BI_INDEX_FAU && index.value >= BIR_FAU_UNIFORM)
87bf215546Sopenharmony_ci        fprintf(fp, "u%u", index.value & ~BIR_FAU_UNIFORM);
88bf215546Sopenharmony_ci    else if (index.type == BI_INDEX_FAU)
89bf215546Sopenharmony_ci        fprintf(fp, "%s", bir_fau_name(index.value));
90bf215546Sopenharmony_ci    else if (index.type == BI_INDEX_PASS)
91bf215546Sopenharmony_ci        fprintf(fp, "%s", bir_passthrough_name(index.value));
92bf215546Sopenharmony_ci    else if (index.type == BI_INDEX_REGISTER)
93bf215546Sopenharmony_ci        fprintf(fp, "br%u", index.value);
94bf215546Sopenharmony_ci    else if (index.type == BI_INDEX_NORMAL && index.reg)
95bf215546Sopenharmony_ci        fprintf(fp, "r%u", index.value);
96bf215546Sopenharmony_ci    else if (index.type == BI_INDEX_NORMAL)
97bf215546Sopenharmony_ci        fprintf(fp, "%u", index.value);
98bf215546Sopenharmony_ci    else
99bf215546Sopenharmony_ci        unreachable("Invalid index");
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci    if (index.offset)
102bf215546Sopenharmony_ci        fprintf(fp, "[%u]", index.offset);
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci    if (index.abs)
105bf215546Sopenharmony_ci        fputs(".abs", fp);
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci    if (index.neg)
108bf215546Sopenharmony_ci        fputs(".neg", fp);
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci    fputs(bi_swizzle_as_str(index.swizzle), fp);
111bf215546Sopenharmony_ci}
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci% for mod in sorted(modifiers):
114bf215546Sopenharmony_ci% if len(modifiers[mod]) > 2: # otherwise just boolean
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ciUNUSED static inline const char *
117bf215546Sopenharmony_cibi_${mod}_as_str(enum bi_${mod} ${mod})
118bf215546Sopenharmony_ci{
119bf215546Sopenharmony_ci    switch (${mod}) {
120bf215546Sopenharmony_ci% for i, state in enumerate(sorted(modifiers[mod])):
121bf215546Sopenharmony_ci% if state == "none":
122bf215546Sopenharmony_ci    case BI_${mod.upper()}_NONE: return "";
123bf215546Sopenharmony_ci% elif state != "reserved":
124bf215546Sopenharmony_ci    case BI_${mod.upper()}_${state.upper()}: return ".${state.lower()}";
125bf215546Sopenharmony_ci% endif
126bf215546Sopenharmony_ci% endfor
127bf215546Sopenharmony_ci    }
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ci    unreachable("Invalid ${mod}");
130bf215546Sopenharmony_ci};
131bf215546Sopenharmony_ci% endif
132bf215546Sopenharmony_ci% endfor
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci<%def name="print_modifiers(mods, table)">
135bf215546Sopenharmony_ci    % for mod in mods:
136bf215546Sopenharmony_ci    % if mod not in ["lane_dest"]:
137bf215546Sopenharmony_ci    % if len(table[mod]) > 2:
138bf215546Sopenharmony_ci        fputs(bi_${mod}_as_str(I->${mod}), fp);
139bf215546Sopenharmony_ci    % else:
140bf215546Sopenharmony_ci        if (I->${mod}) fputs(".${mod}", fp);
141bf215546Sopenharmony_ci    % endif
142bf215546Sopenharmony_ci    % endif
143bf215546Sopenharmony_ci    % endfor
144bf215546Sopenharmony_ci</%def>
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci<%def name="print_source_modifiers(mods, src, table)">
147bf215546Sopenharmony_ci    % for mod in mods:
148bf215546Sopenharmony_ci    % if mod[0:-1] not in ["lane", "lanes", "replicate", "swz", "widen", "swap", "abs", "neg", "sign", "not"]:
149bf215546Sopenharmony_ci    % if len(table[mod[0:-1]]) > 2:
150bf215546Sopenharmony_ci        fputs(bi_${mod[0:-1]}_as_str(I->${mod[0:-1]}[${src}]), fp);
151bf215546Sopenharmony_ci    % elif mod == "bytes2":
152bf215546Sopenharmony_ci        if (I->bytes2) fputs(".bytes", fp);
153bf215546Sopenharmony_ci    % else:
154bf215546Sopenharmony_ci        if (I->${mod[0:-1]}[${src}]) fputs(".${mod[0:-1]}", fp);
155bf215546Sopenharmony_ci    % endif
156bf215546Sopenharmony_ci    %endif
157bf215546Sopenharmony_ci    % endfor
158bf215546Sopenharmony_ci</%def>
159bf215546Sopenharmony_ci
160bf215546Sopenharmony_civoid
161bf215546Sopenharmony_cibi_print_instr(const bi_instr *I, FILE *fp)
162bf215546Sopenharmony_ci{
163bf215546Sopenharmony_ci    if (I->op == BI_OPCODE_SPLIT_I32) {
164bf215546Sopenharmony_ci        for (unsigned d = 0; d < I->nr_dests; ++d) {
165bf215546Sopenharmony_ci            if (d > 0) fprintf(fp, ", ");
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci            bi_print_index(fp, I->dest[d]);
168bf215546Sopenharmony_ci        }
169bf215546Sopenharmony_ci    } else {
170bf215546Sopenharmony_ci        bi_foreach_dest(I, d) {
171bf215546Sopenharmony_ci            if (bi_is_null(I->dest[d])) break;
172bf215546Sopenharmony_ci            if (d > 0) fprintf(fp, ", ");
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci            bi_print_index(fp, I->dest[d]);
175bf215546Sopenharmony_ci        }
176bf215546Sopenharmony_ci    }
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci    fprintf(fp, " = %s", bi_opcode_props[I->op].name);
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci    if (I->table)
181bf215546Sopenharmony_ci        fprintf(fp, ".table%u", I->table);
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_ci    if (I->flow)
184bf215546Sopenharmony_ci        fprintf(fp, ".flow%u", I->flow);
185bf215546Sopenharmony_ci
186bf215546Sopenharmony_ci    if (I->op == BI_OPCODE_COLLECT_I32) {
187bf215546Sopenharmony_ci        for (unsigned i = 0; i < I->nr_srcs; ++i) {
188bf215546Sopenharmony_ci            if (i > 0)
189bf215546Sopenharmony_ci                fputs(", ", fp);
190bf215546Sopenharmony_ci            else
191bf215546Sopenharmony_ci                fputs(" ", fp);
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci            bi_print_index(fp, I->src[i]);
194bf215546Sopenharmony_ci        }
195bf215546Sopenharmony_ci    }
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci    switch (I->op) {
198bf215546Sopenharmony_ci% for opcode in ops:
199bf215546Sopenharmony_ci<%
200bf215546Sopenharmony_ci    # Extract modifiers that are not per-source
201bf215546Sopenharmony_ci    root_modifiers = [x for x in ops[opcode]["modifiers"] if x[-1] not in "0123"]
202bf215546Sopenharmony_ci%>
203bf215546Sopenharmony_ci    case BI_OPCODE_${opcode.replace('.', '_').upper()}:
204bf215546Sopenharmony_ci        ${print_modifiers(root_modifiers, modifiers)}
205bf215546Sopenharmony_ci        fputs(" ", fp);
206bf215546Sopenharmony_ci    % for src in range(src_count(ops[opcode])):
207bf215546Sopenharmony_ci    % if src > 0:
208bf215546Sopenharmony_ci        fputs(", ", fp);
209bf215546Sopenharmony_ci    % endif
210bf215546Sopenharmony_ci        bi_print_index(fp, I->src[${src}]);
211bf215546Sopenharmony_ci        ${print_source_modifiers([m for m in ops[opcode]["modifiers"] if m[-1] == str(src)], src, modifiers)}
212bf215546Sopenharmony_ci    % endfor
213bf215546Sopenharmony_ci    % for imm in ops[opcode]["immediates"]:
214bf215546Sopenharmony_ci        fprintf(fp, ", ${imm}:%u", I->${imm});
215bf215546Sopenharmony_ci    % endfor
216bf215546Sopenharmony_ci        break;
217bf215546Sopenharmony_ci% endfor
218bf215546Sopenharmony_ci    default:
219bf215546Sopenharmony_ci        unreachable("Invalid opcode");
220bf215546Sopenharmony_ci    }
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci    if (I->branch_target)
223bf215546Sopenharmony_ci            fprintf(fp, " -> block%u", I->branch_target->index);
224bf215546Sopenharmony_ci
225bf215546Sopenharmony_ci    fputs("\\n", fp);
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_ci}"""
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ciimport sys
230bf215546Sopenharmony_cifrom bifrost_isa import *
231bf215546Sopenharmony_cifrom mako.template import Template
232bf215546Sopenharmony_ci
233bf215546Sopenharmony_ciinstructions = parse_instructions(sys.argv[1], include_pseudo = True)
234bf215546Sopenharmony_ciir_instructions = partition_mnemonics(instructions)
235bf215546Sopenharmony_cimodifier_lists = order_modifiers(ir_instructions)
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_ciprint(Template(COPYRIGHT + TEMPLATE).render(ops = ir_instructions, modifiers = modifier_lists, src_count = src_count))
238