xref: /aosp_15_r20/external/mesa3d/src/nouveau/mme/mme_tu104.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Collabora Ltd.
3  * SPDX-License-Identifier: MIT
4  */
5 #include "mme_tu104.h"
6 
7 #include "mme_bitpack_helpers.h"
8 
9 #include <stdlib.h>
10 
11 #include "nv_push_clc597.h"
12 
13 #define PRED_TO_STR(OP) [MME_TU104_PRED_##OP] = #OP
14 const char *pred_to_str[] = {
15    PRED_TO_STR(UUUU),
16    PRED_TO_STR(TTTT),
17    PRED_TO_STR(FFFF),
18    PRED_TO_STR(TTUU),
19    PRED_TO_STR(FFUU),
20    PRED_TO_STR(TFUU),
21    PRED_TO_STR(TUUU),
22    PRED_TO_STR(FUUU),
23    PRED_TO_STR(UUTT),
24    PRED_TO_STR(UUTF),
25    PRED_TO_STR(UUTU),
26    PRED_TO_STR(UUFT),
27    PRED_TO_STR(UUFF),
28    PRED_TO_STR(UUFU),
29    PRED_TO_STR(UUUT),
30    PRED_TO_STR(UUUF),
31 };
32 #undef PRED_TO_STR
33 
34 const char *
mme_tu104_pred_to_str(enum mme_tu104_pred pred)35 mme_tu104_pred_to_str(enum mme_tu104_pred pred)
36 {
37    assert(pred < ARRAY_SIZE(pred_to_str));
38    return pred_to_str[pred];
39 }
40 
41 #define OP_TO_STR(OP) [MME_TU104_ALU_OP_##OP] = #OP
42 static const char *alu_op_to_str[] = {
43    OP_TO_STR(ADD),
44    OP_TO_STR(ADDC),
45    OP_TO_STR(SUB),
46    OP_TO_STR(SUBB),
47    OP_TO_STR(MUL),
48    OP_TO_STR(MULH),
49    OP_TO_STR(MULU),
50    OP_TO_STR(EXTENDED),
51    OP_TO_STR(CLZ),
52    OP_TO_STR(SLL),
53    OP_TO_STR(SRL),
54    OP_TO_STR(SRA),
55    OP_TO_STR(AND),
56    OP_TO_STR(NAND),
57    OP_TO_STR(OR),
58    OP_TO_STR(XOR),
59    OP_TO_STR(MERGE),
60    OP_TO_STR(SLT),
61    OP_TO_STR(SLTU),
62    OP_TO_STR(SLE),
63    OP_TO_STR(SLEU),
64    OP_TO_STR(SEQ),
65    OP_TO_STR(STATE),
66    OP_TO_STR(LOOP),
67    OP_TO_STR(JAL),
68    OP_TO_STR(BLT),
69    OP_TO_STR(BLTU),
70    OP_TO_STR(BLE),
71    OP_TO_STR(BLEU),
72    OP_TO_STR(BEQ),
73    OP_TO_STR(DREAD),
74    OP_TO_STR(DWRITE),
75 };
76 #undef OP_TO_STR
77 
78 const char *
mme_tu104_alu_op_to_str(enum mme_tu104_alu_op op)79 mme_tu104_alu_op_to_str(enum mme_tu104_alu_op op)
80 {
81    assert(op < ARRAY_SIZE(alu_op_to_str));
82    return alu_op_to_str[op];
83 }
84 
85 void
mme_tu104_encode(uint32_t * out,uint32_t inst_count,const struct mme_tu104_inst * insts)86 mme_tu104_encode(uint32_t *out, uint32_t inst_count,
87                  const struct mme_tu104_inst *insts)
88 {
89    for (uint32_t i = 0; i < inst_count; i++) {
90       uint32_t b[3] = { 0, 0, 0};
91 
92       pack_uint(b,  0,  0, insts[i].end_next);
93       pack_uint(b,  1,  4, insts[i].pred_mode);
94       pack_uint(b,  5,  9, insts[i].pred);
95 
96       pack_uint(b, 10, 14, insts[i].alu[0].op);
97       pack_uint(b, 15, 19, insts[i].alu[0].dst);
98       pack_uint(b, 20, 24, insts[i].alu[0].src[0]);
99       pack_uint(b, 25, 29, insts[i].alu[0].src[1]);
100       pack_uint(b, 30, 45, insts[i].imm[0]);
101 
102       pack_uint(b, 46, 50, insts[i].alu[1].op);
103       pack_uint(b, 51, 55, insts[i].alu[1].dst);
104       pack_uint(b, 56, 60, insts[i].alu[1].src[0]);
105       pack_uint(b, 61, 65, insts[i].alu[1].src[1]);
106       pack_uint(b, 66, 81, insts[i].imm[1]);
107 
108       pack_uint(b, 82, 84, insts[i].out[0].mthd);
109       pack_uint(b, 85, 88, insts[i].out[0].emit);
110 
111       pack_uint(b, 89, 91, insts[i].out[1].mthd);
112       pack_uint(b, 92, 95, insts[i].out[1].emit);
113 
114       /* Annoyingly, the words are reversed in the actual encoding */
115       out[i * 3 + 2] = b[0];
116       out[i * 3 + 1] = b[1];
117       out[i * 3 + 0] = b[2];
118    }
119 }
120 
121 void
mme_tu104_decode(struct mme_tu104_inst * insts,const uint32_t * in,uint32_t inst_count)122 mme_tu104_decode(struct mme_tu104_inst *insts,
123                  const uint32_t *in, uint32_t inst_count)
124 {
125    for (uint32_t i = 0; i < inst_count; i++) {
126       /* Annoyingly, the words are reversed in the actual encoding */
127       const uint32_t b[3] = {
128          in[i * 3 + 2],
129          in[i * 3 + 1],
130          in[i * 3 + 0],
131       };
132 
133       insts[i].end_next       = unpack_uint(b,  0,  0);
134       insts[i].pred_mode      = unpack_uint(b,  1,  4);
135       insts[i].pred           = unpack_uint(b,  5,  9);
136 
137       insts[i].alu[0].op      = unpack_uint(b, 10, 14);
138       insts[i].alu[0].dst     = unpack_uint(b, 15, 19);
139       insts[i].alu[0].src[0]  = unpack_uint(b, 20, 24);
140       insts[i].alu[0].src[1]  = unpack_uint(b, 25, 29);
141       insts[i].imm[0]         = unpack_uint(b, 30, 45);
142 
143       insts[i].alu[1].op      = unpack_uint(b, 46, 50);
144       insts[i].alu[1].dst     = unpack_uint(b, 51, 55);
145       insts[i].alu[1].src[0]  = unpack_uint(b, 56, 60);
146       insts[i].alu[1].src[1]  = unpack_uint(b, 61, 65);
147       insts[i].imm[1]         = unpack_uint(b, 66, 81);
148 
149       insts[i].out[0].mthd    = unpack_uint(b, 82, 84);
150       insts[i].out[0].emit    = unpack_uint(b, 85, 88);
151 
152       insts[i].out[1].mthd    = unpack_uint(b, 89, 91);
153       insts[i].out[1].emit    = unpack_uint(b, 92, 95);
154    }
155 }
156 
157 static void
print_indent(FILE * fp,unsigned depth)158 print_indent(FILE *fp, unsigned depth)
159 {
160    for (unsigned i = 0; i < depth; i++)
161       fprintf(fp, "    ");
162 }
163 
164 static bool
mme_tu104_alu_src_is_imm(const struct mme_tu104_inst * inst,unsigned alu_idx,unsigned src_idx,uint32_t * imm)165 mme_tu104_alu_src_is_imm(const struct mme_tu104_inst *inst,
166                          unsigned alu_idx, unsigned src_idx,
167                          uint32_t *imm)
168 {
169    const enum mme_tu104_reg reg = inst->alu[alu_idx].src[src_idx];
170 
171    switch (reg) {
172    case MME_TU104_REG_ZERO:
173       *imm = 0;
174       return true;
175    case MME_TU104_REG_IMM:
176       *imm = (int32_t)(int16_t)inst->imm[alu_idx];
177       return true;
178    case MME_TU104_REG_IMMPAIR:
179       *imm = (int32_t)(int16_t)inst->imm[1 - alu_idx];
180       return true;
181    case MME_TU104_REG_IMM32:
182       *imm = ((uint32_t)inst->imm[0] << 16) | inst->imm[1];
183       return true;
184    default:
185       return false;
186    }
187 }
188 
189 static void
mme_tu104_print_alu_src(FILE * fp,const struct mme_tu104_inst * inst,unsigned alu_idx,unsigned src_idx)190 mme_tu104_print_alu_src(FILE *fp, const struct mme_tu104_inst *inst,
191                         unsigned alu_idx, unsigned src_idx)
192 {
193    const enum mme_tu104_reg reg = inst->alu[alu_idx].src[src_idx];
194    if (reg <= MME_TU104_REG_R23) {
195       fprintf(fp, " $r%u", (unsigned)reg);
196    } else {
197       switch (reg) {
198       case MME_TU104_REG_ZERO:
199          fprintf(fp, " $zero");
200          break;
201       case MME_TU104_REG_IMM:
202          fprintf(fp, " %d /* 0x%04x */", (int)(int16_t)inst->imm[alu_idx],
203                  (unsigned)inst->imm[alu_idx]);
204          break;
205       case MME_TU104_REG_IMMPAIR:
206          fprintf(fp, " %d /* 0x%04x */", (int)(int16_t)inst->imm[1 - alu_idx],
207                  (unsigned)inst->imm[1 - alu_idx]);
208          break;
209       case MME_TU104_REG_IMM32:
210          fprintf(fp, " 0x%x", ((uint32_t)inst->imm[0] << 16) | inst->imm[1]);
211          break;
212       case MME_TU104_REG_LOAD0:
213          fprintf(fp, " $load0");
214          break;
215       case MME_TU104_REG_LOAD1:
216          fprintf(fp, " $load1");
217          break;
218       default:
219          unreachable("Invalid ALU source register");
220       }
221    }
222 }
223 
224 bool
mme_tu104_alu_op_has_implicit_imm(enum mme_tu104_alu_op op)225 mme_tu104_alu_op_has_implicit_imm(enum mme_tu104_alu_op op)
226 {
227    switch (op) {
228    case MME_TU104_ALU_OP_MERGE:
229    case MME_TU104_ALU_OP_LOOP:
230    case MME_TU104_ALU_OP_JAL:
231    case MME_TU104_ALU_OP_BLT:
232    case MME_TU104_ALU_OP_BLTU:
233    case MME_TU104_ALU_OP_BLE:
234    case MME_TU104_ALU_OP_BLEU:
235    case MME_TU104_ALU_OP_BEQ:
236       return true;
237    default:
238       return false;
239    }
240 }
241 
242 bool
mme_tu104_alu_op_has_side_effects(enum mme_tu104_alu_op op)243 mme_tu104_alu_op_has_side_effects(enum mme_tu104_alu_op op)
244 {
245    return mme_tu104_alu_op_is_control_flow(op) ||
246           op == MME_TU104_ALU_OP_EXTENDED ||
247           op == MME_TU104_ALU_OP_DWRITE;
248 }
249 
250 bool
mme_tu104_alu_op_is_control_flow(enum mme_tu104_alu_op op)251 mme_tu104_alu_op_is_control_flow(enum mme_tu104_alu_op op)
252 {
253    switch (op) {
254    case MME_TU104_ALU_OP_LOOP:
255    case MME_TU104_ALU_OP_JAL:
256    case MME_TU104_ALU_OP_BLT:
257    case MME_TU104_ALU_OP_BLTU:
258    case MME_TU104_ALU_OP_BLE:
259    case MME_TU104_ALU_OP_BLEU:
260    case MME_TU104_ALU_OP_BEQ:
261       return true;
262    default:
263       return false;
264    }
265 }
266 
267 bool
mme_tu104_alu_op_may_depend_on_mthd(enum mme_tu104_alu_op op)268 mme_tu104_alu_op_may_depend_on_mthd(enum mme_tu104_alu_op op)
269 {
270    switch (op) {
271    case MME_TU104_ALU_OP_EXTENDED:
272    case MME_TU104_ALU_OP_STATE:
273       return true;
274    default:
275       return false;
276    }
277 }
278 
279 bool
mme_tu104_alus_have_dependency(const struct mme_tu104_alu * first,const struct mme_tu104_alu * second)280 mme_tu104_alus_have_dependency(const struct mme_tu104_alu *first,
281                                const struct mme_tu104_alu *second)
282 {
283    if (first->dst != MME_TU104_REG_ZERO &&
284        (first->dst == second->dst ||
285         first->dst == second->src[0] ||
286         first->dst == second->src[1]))
287       return true;
288 
289    /* TODO: This could be more detailed */
290    if (first->op == MME_TU104_ALU_OP_DWRITE &&
291        (second->op == MME_TU104_ALU_OP_DREAD ||
292         second->op == MME_TU104_ALU_OP_DWRITE))
293       return true;
294 
295    /* TODO: This could be more detailed */
296    if (second->op == MME_TU104_ALU_OP_DWRITE &&
297        (first->op == MME_TU104_ALU_OP_DREAD ||
298         first->op == MME_TU104_ALU_OP_DWRITE))
299       return true;
300 
301    /* EXTENDED acts like a barrier between MME_DMA_READ_FIFOED and LOAD0/1 */
302    if (first->op == MME_TU104_ALU_OP_EXTENDED &&
303        (second->src[0] == MME_TU104_REG_LOAD0 ||
304         second->src[0] == MME_TU104_REG_LOAD1 ||
305         second->src[1] == MME_TU104_REG_LOAD0 ||
306         second->src[1] == MME_TU104_REG_LOAD1))
307       return true;
308 
309    return false;
310 }
311 
312 static bool
mme_tu104_alu_is_branch(const struct mme_tu104_inst * inst,unsigned alu_idx,int * then_offset,unsigned * else_offset)313 mme_tu104_alu_is_branch(const struct mme_tu104_inst *inst, unsigned alu_idx,
314                         int *then_offset, unsigned *else_offset)
315 {
316    switch (inst->alu[alu_idx].op) {
317    case MME_TU104_ALU_OP_BLT:
318    case MME_TU104_ALU_OP_BLTU:
319    case MME_TU104_ALU_OP_BLE:
320    case MME_TU104_ALU_OP_BLEU:
321    case MME_TU104_ALU_OP_BEQ:
322       *then_offset = util_mask_sign_extend(inst->imm[alu_idx], 14);
323       *else_offset = (inst->imm[alu_idx] >> 14) & 0x3;
324       return true;
325    default:
326       return false;
327    }
328 }
329 
330 static void
mme_tu104_print_alu(FILE * fp,unsigned indent,const struct mme_tu104_inst * inst,unsigned alu_idx)331 mme_tu104_print_alu(FILE *fp, unsigned indent,
332                     const struct mme_tu104_inst *inst,
333                     unsigned alu_idx)
334 {
335    const struct mme_tu104_alu *alu = &inst->alu[alu_idx];
336 
337    const bool used_by_out =
338       inst->out[0].mthd == MME_TU104_OUT_OP_ALU0 + alu_idx ||
339       inst->out[0].emit == MME_TU104_OUT_OP_ALU0 + alu_idx ||
340       inst->out[1].mthd == MME_TU104_OUT_OP_ALU0 + alu_idx ||
341       inst->out[1].emit == MME_TU104_OUT_OP_ALU0 + alu_idx;
342 
343    if (!used_by_out && alu->dst == MME_TU104_REG_ZERO &&
344        !mme_tu104_alu_op_has_side_effects(alu->op))
345       return;
346 
347    print_indent(fp, indent);
348 
349    if (used_by_out || alu->dst != MME_TU104_REG_ZERO) {
350       if (used_by_out)
351          fprintf(fp, "$alu%u", alu_idx);
352       if (alu->dst <= MME_TU104_REG_R23) {
353          fprintf(fp, "%s$r%u", used_by_out ? ", " : "", (unsigned)alu->dst);
354       } else {
355          assert(alu->dst == MME_TU104_REG_ZERO);
356       }
357       fprintf(fp, " = ");
358    }
359 
360    switch (alu->op) {
361    case MME_TU104_ALU_OP_ADDC:
362       assert(alu_idx == 1);
363       fprintf(fp, "ADDC");
364       mme_tu104_print_alu_src(fp, inst, alu_idx, 0);
365       mme_tu104_print_alu_src(fp, inst, alu_idx, 1);
366       fprintf(fp, " $carry");
367       break;
368    case MME_TU104_ALU_OP_SUBB:
369       assert(alu_idx == 1);
370       fprintf(fp, "SUBB");
371       mme_tu104_print_alu_src(fp, inst, alu_idx, 0);
372       mme_tu104_print_alu_src(fp, inst, alu_idx, 1);
373       fprintf(fp, " $borrow");
374       break;
375    case MME_TU104_ALU_OP_MULH:
376       assert(alu_idx == 1);
377       assert(alu->src[0] == MME_TU104_REG_ZERO);
378       assert(alu->src[1] == MME_TU104_REG_ZERO);
379       fprintf(fp, "MULH $alu0");
380       break;
381    case MME_TU104_ALU_OP_MERGE: {
382       uint16_t immed = inst->imm[alu_idx];
383       uint32_t src_pos  = (immed >> 0)  & 0x1f;
384       uint32_t bits     = (immed >> 5)  & 0x1f;
385       uint32_t dst_pos  = (immed >> 10) & 0x3f;
386       fprintf(fp, "MERGE");
387       mme_tu104_print_alu_src(fp, inst, alu_idx, 0);
388       mme_tu104_print_alu_src(fp, inst, alu_idx, 1);
389       fprintf(fp, " (%u, %u, %u)", dst_pos, bits, src_pos);
390       break;
391    }
392    case MME_TU104_ALU_OP_STATE: {
393       fprintf(fp, "STATE");
394       mme_tu104_print_alu_src(fp, inst, alu_idx, 0);
395       if (alu->src[1] != MME_TU104_REG_ZERO) {
396          fprintf(fp, " +");
397          mme_tu104_print_alu_src(fp, inst, alu_idx, 1);
398       }
399       uint32_t imm;
400       if (mme_tu104_alu_src_is_imm(inst, alu_idx, 0, &imm)) {
401          uint32_t mthd = imm << 2;
402          fprintf(fp, " /* %s", P_PARSE_NVC597_MTHD(mthd));
403          if (alu->src[1] != MME_TU104_REG_ZERO) {
404             fprintf(fp, " +");
405             mme_tu104_print_alu_src(fp, inst, alu_idx, 1);
406          }
407          fprintf(fp, " */");
408       }
409       break;
410    }
411    case MME_TU104_ALU_OP_JAL:
412       assert(alu->src[0] == MME_TU104_REG_ZERO);
413       assert(alu->src[1] == MME_TU104_REG_ZERO);
414       fprintf(fp, "JAL (0x%04x)", (unsigned)inst->imm[alu_idx]);
415       break;
416    case MME_TU104_ALU_OP_LOOP:
417    case MME_TU104_ALU_OP_DREAD:
418       fprintf(fp, "%s", mme_tu104_alu_op_to_str(alu->op));
419       mme_tu104_print_alu_src(fp, inst, alu_idx, 0);
420       assert(alu->src[1] == MME_TU104_REG_ZERO);
421       break;
422    default:
423       fprintf(fp, "%s", mme_tu104_alu_op_to_str(alu->op));
424       mme_tu104_print_alu_src(fp, inst, alu_idx, 0);
425       mme_tu104_print_alu_src(fp, inst, alu_idx, 1);
426       break;
427    }
428 
429    int then_offset;
430    unsigned else_offset;
431    if (mme_tu104_alu_is_branch(inst, alu_idx, &then_offset, &else_offset))
432       fprintf(fp, " (%d, %u)", then_offset, else_offset);
433 
434    if (alu->op == MME_TU104_ALU_OP_LOOP)
435       fprintf(fp, " (%d)", (unsigned)inst->imm[alu_idx]);
436 
437    fprintf(fp, "\n");
438 }
439 
440 static bool
mme_tu104_out_is_imm(const struct mme_tu104_inst * inst,enum mme_tu104_out_op op,uint32_t * imm)441 mme_tu104_out_is_imm(const struct mme_tu104_inst *inst,
442                      enum mme_tu104_out_op op, uint32_t *imm)
443 {
444    switch (op) {
445    case MME_TU104_OUT_OP_IMM0:
446    case MME_TU104_OUT_OP_IMM1:
447       *imm = inst->imm[op - MME_TU104_OUT_OP_IMM0];
448       return true;
449    case MME_TU104_OUT_OP_IMMHIGH0:
450    case MME_TU104_OUT_OP_IMMHIGH1:
451       *imm = inst->imm[op - MME_TU104_OUT_OP_IMMHIGH0] >> 12;
452       return true;
453    case MME_TU104_OUT_OP_IMM32:
454       *imm = ((uint32_t)inst->imm[0] << 16) | inst->imm[1];
455       return true;
456    default:
457       return false;
458    }
459 }
460 
461 static void
mme_tu104_print_out_src(FILE * fp,const struct mme_tu104_inst * inst,enum mme_tu104_out_op op)462 mme_tu104_print_out_src(FILE *fp, const struct mme_tu104_inst *inst,
463                         enum mme_tu104_out_op op)
464 {
465    switch (op) {
466    case MME_TU104_OUT_OP_ALU0:
467    case MME_TU104_OUT_OP_ALU1:
468       fprintf(fp, "$alu%u", (int)op - MME_TU104_OUT_OP_ALU0);
469       break;
470    case MME_TU104_OUT_OP_LOAD0:
471    case MME_TU104_OUT_OP_LOAD1:
472       fprintf(fp, "$load%u", (int)op - MME_TU104_OUT_OP_LOAD0);
473       break;
474    case MME_TU104_OUT_OP_IMM0:
475    case MME_TU104_OUT_OP_IMM1:
476       fprintf(fp, "0x%x", (unsigned)inst->imm[op - MME_TU104_OUT_OP_IMM0]);
477       break;
478    case MME_TU104_OUT_OP_RESERVED:
479       fprintf(fp, "RESERVED");
480       break;
481    case MME_TU104_OUT_OP_IMMHIGH0:
482    case MME_TU104_OUT_OP_IMMHIGH1:
483       fprintf(fp, "%u",
484               (unsigned)(inst->imm[op - MME_TU104_OUT_OP_IMMHIGH0] >> 12));
485       break;
486    case MME_TU104_OUT_OP_IMM32:
487       fprintf(fp, "0x%x", ((uint32_t)inst->imm[0] << 16) | inst->imm[1]);
488       break;
489    default:
490       unreachable("Invalid output source");
491    }
492 };
493 
494 static void
mme_tu104_print_out(FILE * fp,unsigned indent,const struct mme_tu104_inst * inst,unsigned out_idx)495 mme_tu104_print_out(FILE *fp, unsigned indent,
496                     const struct mme_tu104_inst *inst,
497                     unsigned out_idx)
498 {
499    const struct mme_tu104_out *out = &inst->out[out_idx];
500 
501    if (out->mthd != MME_TU104_OUT_OP_NONE) {
502       print_indent(fp, indent);
503       fprintf(fp, "mthd(");
504       uint32_t imm;
505       if (mme_tu104_out_is_imm(inst, out->mthd, &imm)) {
506          uint32_t mthd = (imm & 0xfff) << 2;
507          uint32_t incr = imm >> 12;
508          fprintf(fp, "0x%04x, %u)", mthd, incr);
509          fprintf(fp, " /* %s */", P_PARSE_NVC597_MTHD(mthd));
510       } else {
511          mme_tu104_print_out_src(fp, inst, out->mthd);
512          fprintf(fp, ")");
513       }
514       fprintf(fp, "\n");
515    }
516    if (out->emit != MME_TU104_OUT_OP_NONE) {
517       print_indent(fp, indent);
518       fprintf(fp, "emit(");
519       mme_tu104_print_out_src(fp, inst, out->emit);
520       fprintf(fp, ")\n");
521    }
522 }
523 
524 void
mme_tu104_print_inst(FILE * fp,unsigned indent,const struct mme_tu104_inst * inst)525 mme_tu104_print_inst(FILE *fp, unsigned indent,
526                      const struct mme_tu104_inst *inst)
527 {
528    if (inst->pred_mode != MME_TU104_PRED_UUUU) {
529       print_indent(fp, indent);
530       fprintf(fp, "pred %s", mme_tu104_pred_to_str(inst->pred_mode));
531       fprintf(fp, " $r%u {\n", (unsigned)inst->pred);
532       indent++;
533    }
534 
535    mme_tu104_print_alu(fp, indent, inst, 0);
536    mme_tu104_print_alu(fp, indent, inst, 1);
537    mme_tu104_print_out(fp, indent, inst, 0);
538    mme_tu104_print_out(fp, indent, inst, 1);
539 
540    if (inst->pred_mode != MME_TU104_PRED_UUUU) {
541       indent--;
542       print_indent(fp, indent);
543       fprintf(fp, "}\n");
544    }
545 }
546 
547 void
mme_tu104_print(FILE * fp,const struct mme_tu104_inst * insts,uint32_t inst_count)548 mme_tu104_print(FILE *fp, const struct mme_tu104_inst *insts,
549                 uint32_t inst_count)
550 {
551    for (uint32_t i = 0; i < inst_count; i++) {
552       fprintf(fp, "%u:\n", i);
553       mme_tu104_print_inst(fp, 1, &insts[i]);
554    }
555 }
556 
557 void
mme_tu104_dump(FILE * fp,uint32_t * encoded,size_t encoded_size)558 mme_tu104_dump(FILE *fp, uint32_t *encoded, size_t encoded_size)
559 {
560    uint32_t inst_count = encoded_size / 12;
561    for (uint32_t i = 0; i < inst_count; i++) {
562       struct mme_tu104_inst inst;
563       mme_tu104_decode(&inst, &encoded[i * 3], 1);
564       mme_tu104_print_inst(fp, 1, &inst);
565    }
566 }
567