1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2016 Broadcom
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_ci
24bf215546Sopenharmony_ci#include <string.h>
25bf215546Sopenharmony_ci#include <stdio.h>
26bf215546Sopenharmony_ci#include "util/ralloc.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "broadcom/common/v3d_device_info.h"
29bf215546Sopenharmony_ci#include "qpu_instr.h"
30bf215546Sopenharmony_ci#include "qpu_disasm.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_cistruct disasm_state {
33bf215546Sopenharmony_ci        const struct v3d_device_info *devinfo;
34bf215546Sopenharmony_ci        char *string;
35bf215546Sopenharmony_ci        size_t offset;
36bf215546Sopenharmony_ci};
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_cistatic void
39bf215546Sopenharmony_ciappend(struct disasm_state *disasm, const char *fmt, ...)
40bf215546Sopenharmony_ci{
41bf215546Sopenharmony_ci        va_list args;
42bf215546Sopenharmony_ci        va_start(args, fmt);
43bf215546Sopenharmony_ci        ralloc_vasprintf_rewrite_tail(&disasm->string,
44bf215546Sopenharmony_ci                                      &disasm->offset,
45bf215546Sopenharmony_ci                                      fmt, args);
46bf215546Sopenharmony_ci        va_end(args);
47bf215546Sopenharmony_ci}
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_cistatic void
50bf215546Sopenharmony_cipad_to(struct disasm_state *disasm, int n)
51bf215546Sopenharmony_ci{
52bf215546Sopenharmony_ci        /* FIXME: Do a single append somehow. */
53bf215546Sopenharmony_ci        while (disasm->offset < n)
54bf215546Sopenharmony_ci                append(disasm, " ");
55bf215546Sopenharmony_ci}
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_cistatic void
59bf215546Sopenharmony_civ3d_qpu_disasm_raddr(struct disasm_state *disasm,
60bf215546Sopenharmony_ci                     const struct v3d_qpu_instr *instr, uint8_t mux)
61bf215546Sopenharmony_ci{
62bf215546Sopenharmony_ci        if (mux == V3D_QPU_MUX_A) {
63bf215546Sopenharmony_ci                append(disasm, "rf%d", instr->raddr_a);
64bf215546Sopenharmony_ci        } else if (mux == V3D_QPU_MUX_B) {
65bf215546Sopenharmony_ci                if (instr->sig.small_imm) {
66bf215546Sopenharmony_ci                        uint32_t val;
67bf215546Sopenharmony_ci                        ASSERTED bool ok =
68bf215546Sopenharmony_ci                                v3d_qpu_small_imm_unpack(disasm->devinfo,
69bf215546Sopenharmony_ci                                                         instr->raddr_b,
70bf215546Sopenharmony_ci                                                         &val);
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci                        if ((int)val >= -16 && (int)val <= 15)
73bf215546Sopenharmony_ci                                append(disasm, "%d", val);
74bf215546Sopenharmony_ci                        else
75bf215546Sopenharmony_ci                                append(disasm, "0x%08x", val);
76bf215546Sopenharmony_ci                        assert(ok);
77bf215546Sopenharmony_ci                } else {
78bf215546Sopenharmony_ci                        append(disasm, "rf%d", instr->raddr_b);
79bf215546Sopenharmony_ci                }
80bf215546Sopenharmony_ci        } else {
81bf215546Sopenharmony_ci                append(disasm, "r%d", mux);
82bf215546Sopenharmony_ci        }
83bf215546Sopenharmony_ci}
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_cistatic void
86bf215546Sopenharmony_civ3d_qpu_disasm_waddr(struct disasm_state *disasm, uint32_t waddr, bool magic)
87bf215546Sopenharmony_ci{
88bf215546Sopenharmony_ci        if (!magic) {
89bf215546Sopenharmony_ci                append(disasm, "rf%d", waddr);
90bf215546Sopenharmony_ci                return;
91bf215546Sopenharmony_ci        }
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci        const char *name = v3d_qpu_magic_waddr_name(disasm->devinfo, waddr);
94bf215546Sopenharmony_ci        if (name)
95bf215546Sopenharmony_ci                append(disasm, "%s", name);
96bf215546Sopenharmony_ci        else
97bf215546Sopenharmony_ci                append(disasm, "waddr UNKNOWN %d", waddr);
98bf215546Sopenharmony_ci}
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_cistatic void
101bf215546Sopenharmony_civ3d_qpu_disasm_add(struct disasm_state *disasm,
102bf215546Sopenharmony_ci                   const struct v3d_qpu_instr *instr)
103bf215546Sopenharmony_ci{
104bf215546Sopenharmony_ci        bool has_dst = v3d_qpu_add_op_has_dst(instr->alu.add.op);
105bf215546Sopenharmony_ci        int num_src = v3d_qpu_add_op_num_src(instr->alu.add.op);
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci        append(disasm, "%s", v3d_qpu_add_op_name(instr->alu.add.op));
108bf215546Sopenharmony_ci        if (!v3d_qpu_sig_writes_address(disasm->devinfo, &instr->sig))
109bf215546Sopenharmony_ci                append(disasm, "%s", v3d_qpu_cond_name(instr->flags.ac));
110bf215546Sopenharmony_ci        append(disasm, "%s", v3d_qpu_pf_name(instr->flags.apf));
111bf215546Sopenharmony_ci        append(disasm, "%s", v3d_qpu_uf_name(instr->flags.auf));
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci        append(disasm, " ");
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci        if (has_dst) {
116bf215546Sopenharmony_ci                v3d_qpu_disasm_waddr(disasm, instr->alu.add.waddr,
117bf215546Sopenharmony_ci                                     instr->alu.add.magic_write);
118bf215546Sopenharmony_ci                append(disasm, v3d_qpu_pack_name(instr->alu.add.output_pack));
119bf215546Sopenharmony_ci        }
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci        if (num_src >= 1) {
122bf215546Sopenharmony_ci                if (has_dst)
123bf215546Sopenharmony_ci                        append(disasm, ", ");
124bf215546Sopenharmony_ci                v3d_qpu_disasm_raddr(disasm, instr, instr->alu.add.a);
125bf215546Sopenharmony_ci                append(disasm, "%s",
126bf215546Sopenharmony_ci                       v3d_qpu_unpack_name(instr->alu.add.a_unpack));
127bf215546Sopenharmony_ci        }
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ci        if (num_src >= 2) {
130bf215546Sopenharmony_ci                append(disasm, ", ");
131bf215546Sopenharmony_ci                v3d_qpu_disasm_raddr(disasm, instr, instr->alu.add.b);
132bf215546Sopenharmony_ci                append(disasm, "%s",
133bf215546Sopenharmony_ci                       v3d_qpu_unpack_name(instr->alu.add.b_unpack));
134bf215546Sopenharmony_ci        }
135bf215546Sopenharmony_ci}
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_cistatic void
138bf215546Sopenharmony_civ3d_qpu_disasm_mul(struct disasm_state *disasm,
139bf215546Sopenharmony_ci                   const struct v3d_qpu_instr *instr)
140bf215546Sopenharmony_ci{
141bf215546Sopenharmony_ci        bool has_dst = v3d_qpu_mul_op_has_dst(instr->alu.mul.op);
142bf215546Sopenharmony_ci        int num_src = v3d_qpu_mul_op_num_src(instr->alu.mul.op);
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci        pad_to(disasm, 30);
145bf215546Sopenharmony_ci        append(disasm, "; ");
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci        append(disasm, "%s", v3d_qpu_mul_op_name(instr->alu.mul.op));
148bf215546Sopenharmony_ci        if (!v3d_qpu_sig_writes_address(disasm->devinfo, &instr->sig))
149bf215546Sopenharmony_ci                append(disasm, "%s", v3d_qpu_cond_name(instr->flags.mc));
150bf215546Sopenharmony_ci        append(disasm, "%s", v3d_qpu_pf_name(instr->flags.mpf));
151bf215546Sopenharmony_ci        append(disasm, "%s", v3d_qpu_uf_name(instr->flags.muf));
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci        if (instr->alu.mul.op == V3D_QPU_M_NOP)
154bf215546Sopenharmony_ci                return;
155bf215546Sopenharmony_ci
156bf215546Sopenharmony_ci        append(disasm, " ");
157bf215546Sopenharmony_ci
158bf215546Sopenharmony_ci        if (has_dst) {
159bf215546Sopenharmony_ci                v3d_qpu_disasm_waddr(disasm, instr->alu.mul.waddr,
160bf215546Sopenharmony_ci                                     instr->alu.mul.magic_write);
161bf215546Sopenharmony_ci                append(disasm, v3d_qpu_pack_name(instr->alu.mul.output_pack));
162bf215546Sopenharmony_ci        }
163bf215546Sopenharmony_ci
164bf215546Sopenharmony_ci        if (num_src >= 1) {
165bf215546Sopenharmony_ci                if (has_dst)
166bf215546Sopenharmony_ci                        append(disasm, ", ");
167bf215546Sopenharmony_ci                v3d_qpu_disasm_raddr(disasm, instr, instr->alu.mul.a);
168bf215546Sopenharmony_ci                append(disasm, "%s",
169bf215546Sopenharmony_ci                       v3d_qpu_unpack_name(instr->alu.mul.a_unpack));
170bf215546Sopenharmony_ci        }
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci        if (num_src >= 2) {
173bf215546Sopenharmony_ci                append(disasm, ", ");
174bf215546Sopenharmony_ci                v3d_qpu_disasm_raddr(disasm, instr, instr->alu.mul.b);
175bf215546Sopenharmony_ci                append(disasm, "%s",
176bf215546Sopenharmony_ci                       v3d_qpu_unpack_name(instr->alu.mul.b_unpack));
177bf215546Sopenharmony_ci        }
178bf215546Sopenharmony_ci}
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_cistatic void
181bf215546Sopenharmony_civ3d_qpu_disasm_sig_addr(struct disasm_state *disasm,
182bf215546Sopenharmony_ci                        const struct v3d_qpu_instr *instr)
183bf215546Sopenharmony_ci{
184bf215546Sopenharmony_ci        if (disasm->devinfo->ver < 41)
185bf215546Sopenharmony_ci                return;
186bf215546Sopenharmony_ci
187bf215546Sopenharmony_ci        if (!instr->sig_magic)
188bf215546Sopenharmony_ci                append(disasm, ".rf%d", instr->sig_addr);
189bf215546Sopenharmony_ci        else {
190bf215546Sopenharmony_ci                const char *name =
191bf215546Sopenharmony_ci                        v3d_qpu_magic_waddr_name(disasm->devinfo,
192bf215546Sopenharmony_ci                                                 instr->sig_addr);
193bf215546Sopenharmony_ci                if (name)
194bf215546Sopenharmony_ci                        append(disasm, ".%s", name);
195bf215546Sopenharmony_ci                else
196bf215546Sopenharmony_ci                        append(disasm, ".UNKNOWN%d", instr->sig_addr);
197bf215546Sopenharmony_ci        }
198bf215546Sopenharmony_ci}
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_cistatic void
201bf215546Sopenharmony_civ3d_qpu_disasm_sig(struct disasm_state *disasm,
202bf215546Sopenharmony_ci                   const struct v3d_qpu_instr *instr)
203bf215546Sopenharmony_ci{
204bf215546Sopenharmony_ci        const struct v3d_qpu_sig *sig = &instr->sig;
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_ci        if (!sig->thrsw &&
207bf215546Sopenharmony_ci            !sig->ldvary &&
208bf215546Sopenharmony_ci            !sig->ldvpm &&
209bf215546Sopenharmony_ci            !sig->ldtmu &&
210bf215546Sopenharmony_ci            !sig->ldtlb &&
211bf215546Sopenharmony_ci            !sig->ldtlbu &&
212bf215546Sopenharmony_ci            !sig->ldunif &&
213bf215546Sopenharmony_ci            !sig->ldunifrf &&
214bf215546Sopenharmony_ci            !sig->ldunifa &&
215bf215546Sopenharmony_ci            !sig->ldunifarf &&
216bf215546Sopenharmony_ci            !sig->wrtmuc) {
217bf215546Sopenharmony_ci                return;
218bf215546Sopenharmony_ci        }
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci        pad_to(disasm, 60);
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci        if (sig->thrsw)
223bf215546Sopenharmony_ci                append(disasm, "; thrsw");
224bf215546Sopenharmony_ci        if (sig->ldvary) {
225bf215546Sopenharmony_ci                append(disasm, "; ldvary");
226bf215546Sopenharmony_ci                v3d_qpu_disasm_sig_addr(disasm, instr);
227bf215546Sopenharmony_ci        }
228bf215546Sopenharmony_ci        if (sig->ldvpm)
229bf215546Sopenharmony_ci                append(disasm, "; ldvpm");
230bf215546Sopenharmony_ci        if (sig->ldtmu) {
231bf215546Sopenharmony_ci                append(disasm, "; ldtmu");
232bf215546Sopenharmony_ci                v3d_qpu_disasm_sig_addr(disasm, instr);
233bf215546Sopenharmony_ci        }
234bf215546Sopenharmony_ci        if (sig->ldtlb) {
235bf215546Sopenharmony_ci                append(disasm, "; ldtlb");
236bf215546Sopenharmony_ci                v3d_qpu_disasm_sig_addr(disasm, instr);
237bf215546Sopenharmony_ci        }
238bf215546Sopenharmony_ci        if (sig->ldtlbu) {
239bf215546Sopenharmony_ci                append(disasm, "; ldtlbu");
240bf215546Sopenharmony_ci                v3d_qpu_disasm_sig_addr(disasm, instr);
241bf215546Sopenharmony_ci        }
242bf215546Sopenharmony_ci        if (sig->ldunif)
243bf215546Sopenharmony_ci                append(disasm, "; ldunif");
244bf215546Sopenharmony_ci        if (sig->ldunifrf) {
245bf215546Sopenharmony_ci                append(disasm, "; ldunifrf");
246bf215546Sopenharmony_ci                v3d_qpu_disasm_sig_addr(disasm, instr);
247bf215546Sopenharmony_ci        }
248bf215546Sopenharmony_ci        if (sig->ldunifa)
249bf215546Sopenharmony_ci                append(disasm, "; ldunifa");
250bf215546Sopenharmony_ci        if (sig->ldunifarf) {
251bf215546Sopenharmony_ci                append(disasm, "; ldunifarf");
252bf215546Sopenharmony_ci                v3d_qpu_disasm_sig_addr(disasm, instr);
253bf215546Sopenharmony_ci        }
254bf215546Sopenharmony_ci        if (sig->wrtmuc)
255bf215546Sopenharmony_ci                append(disasm, "; wrtmuc");
256bf215546Sopenharmony_ci}
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_cistatic void
259bf215546Sopenharmony_civ3d_qpu_disasm_alu(struct disasm_state *disasm,
260bf215546Sopenharmony_ci                   const struct v3d_qpu_instr *instr)
261bf215546Sopenharmony_ci{
262bf215546Sopenharmony_ci        v3d_qpu_disasm_add(disasm, instr);
263bf215546Sopenharmony_ci        v3d_qpu_disasm_mul(disasm, instr);
264bf215546Sopenharmony_ci        v3d_qpu_disasm_sig(disasm, instr);
265bf215546Sopenharmony_ci}
266bf215546Sopenharmony_ci
267bf215546Sopenharmony_cistatic void
268bf215546Sopenharmony_civ3d_qpu_disasm_branch(struct disasm_state *disasm,
269bf215546Sopenharmony_ci                      const struct v3d_qpu_instr *instr)
270bf215546Sopenharmony_ci{
271bf215546Sopenharmony_ci        append(disasm, "b");
272bf215546Sopenharmony_ci        if (instr->branch.ub)
273bf215546Sopenharmony_ci                append(disasm, "u");
274bf215546Sopenharmony_ci        append(disasm, "%s", v3d_qpu_branch_cond_name(instr->branch.cond));
275bf215546Sopenharmony_ci        append(disasm, "%s", v3d_qpu_msfign_name(instr->branch.msfign));
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_ci        switch (instr->branch.bdi) {
278bf215546Sopenharmony_ci        case V3D_QPU_BRANCH_DEST_ABS:
279bf215546Sopenharmony_ci                append(disasm, "  zero_addr+0x%08x", instr->branch.offset);
280bf215546Sopenharmony_ci                break;
281bf215546Sopenharmony_ci
282bf215546Sopenharmony_ci        case V3D_QPU_BRANCH_DEST_REL:
283bf215546Sopenharmony_ci                append(disasm, "  %d", instr->branch.offset);
284bf215546Sopenharmony_ci                break;
285bf215546Sopenharmony_ci
286bf215546Sopenharmony_ci        case V3D_QPU_BRANCH_DEST_LINK_REG:
287bf215546Sopenharmony_ci                append(disasm, "  lri");
288bf215546Sopenharmony_ci                break;
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci        case V3D_QPU_BRANCH_DEST_REGFILE:
291bf215546Sopenharmony_ci                append(disasm, "  rf%d", instr->branch.raddr_a);
292bf215546Sopenharmony_ci                break;
293bf215546Sopenharmony_ci        }
294bf215546Sopenharmony_ci
295bf215546Sopenharmony_ci        if (instr->branch.ub) {
296bf215546Sopenharmony_ci                switch (instr->branch.bdu) {
297bf215546Sopenharmony_ci                case V3D_QPU_BRANCH_DEST_ABS:
298bf215546Sopenharmony_ci                        append(disasm, ", a:unif");
299bf215546Sopenharmony_ci                        break;
300bf215546Sopenharmony_ci
301bf215546Sopenharmony_ci                case V3D_QPU_BRANCH_DEST_REL:
302bf215546Sopenharmony_ci                        append(disasm, ", r:unif");
303bf215546Sopenharmony_ci                        break;
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci                case V3D_QPU_BRANCH_DEST_LINK_REG:
306bf215546Sopenharmony_ci                        append(disasm, ", lri");
307bf215546Sopenharmony_ci                        break;
308bf215546Sopenharmony_ci
309bf215546Sopenharmony_ci                case V3D_QPU_BRANCH_DEST_REGFILE:
310bf215546Sopenharmony_ci                        append(disasm, ", rf%d", instr->branch.raddr_a);
311bf215546Sopenharmony_ci                        break;
312bf215546Sopenharmony_ci                }
313bf215546Sopenharmony_ci        }
314bf215546Sopenharmony_ci}
315bf215546Sopenharmony_ci
316bf215546Sopenharmony_ciconst char *
317bf215546Sopenharmony_civ3d_qpu_decode(const struct v3d_device_info *devinfo,
318bf215546Sopenharmony_ci               const struct v3d_qpu_instr *instr)
319bf215546Sopenharmony_ci{
320bf215546Sopenharmony_ci        struct disasm_state disasm = {
321bf215546Sopenharmony_ci                .string = rzalloc_size(NULL, 1),
322bf215546Sopenharmony_ci                .offset = 0,
323bf215546Sopenharmony_ci                .devinfo = devinfo,
324bf215546Sopenharmony_ci        };
325bf215546Sopenharmony_ci
326bf215546Sopenharmony_ci        switch (instr->type) {
327bf215546Sopenharmony_ci        case V3D_QPU_INSTR_TYPE_ALU:
328bf215546Sopenharmony_ci                v3d_qpu_disasm_alu(&disasm, instr);
329bf215546Sopenharmony_ci                break;
330bf215546Sopenharmony_ci
331bf215546Sopenharmony_ci        case V3D_QPU_INSTR_TYPE_BRANCH:
332bf215546Sopenharmony_ci                v3d_qpu_disasm_branch(&disasm, instr);
333bf215546Sopenharmony_ci                break;
334bf215546Sopenharmony_ci        }
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_ci        return disasm.string;
337bf215546Sopenharmony_ci}
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci/**
340bf215546Sopenharmony_ci * Returns a string containing the disassembled representation of the QPU
341bf215546Sopenharmony_ci * instruction.  It is the caller's responsibility to free the return value
342bf215546Sopenharmony_ci * with ralloc_free().
343bf215546Sopenharmony_ci */
344bf215546Sopenharmony_ciconst char *
345bf215546Sopenharmony_civ3d_qpu_disasm(const struct v3d_device_info *devinfo, uint64_t inst)
346bf215546Sopenharmony_ci{
347bf215546Sopenharmony_ci        struct v3d_qpu_instr instr;
348bf215546Sopenharmony_ci        bool ok = v3d_qpu_instr_unpack(devinfo, inst, &instr);
349bf215546Sopenharmony_ci        assert(ok); (void)ok;
350bf215546Sopenharmony_ci
351bf215546Sopenharmony_ci        return v3d_qpu_decode(devinfo, &instr);
352bf215546Sopenharmony_ci}
353bf215546Sopenharmony_ci
354bf215546Sopenharmony_civoid
355bf215546Sopenharmony_civ3d_qpu_dump(const struct v3d_device_info *devinfo,
356bf215546Sopenharmony_ci             const struct v3d_qpu_instr *instr)
357bf215546Sopenharmony_ci{
358bf215546Sopenharmony_ci        const char *decoded = v3d_qpu_decode(devinfo, instr);
359bf215546Sopenharmony_ci        fprintf(stderr, "%s", decoded);
360bf215546Sopenharmony_ci        ralloc_free((char *)decoded);
361bf215546Sopenharmony_ci}
362