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