untested amd gcn gfx6 disassembler
[vulkan-misc.git] / amd / gcn / gfx6 / dis / dis.c
blobc381a07d84d0837a4e43a632e03bae2999bc0db0
1 /* amd gpu gfx6 */
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <stdbool.h>
7 /*
8 * ABBREVIATIONS:
10 * opd(s) : OPeranD)S)
11 * s = Scalar
12 * src : SouRCe
13 * v(s) : Vector(S)
14 * w(s) : Word(S)
17 * we could not care less about memory management
18 */
19 #define u8 uint8_t
20 #define u16 uint16_t
21 #define u32 uint32_t
22 #define loop for(;;)
23 #define out(fmt,...) fprintf(stdout,fmt, ##__VA_ARGS__)
24 #define STR_SZ_MAX 256
25 #define pf(fmt,...) snprintf(str, STR_SZ_MAX, fmt, ##__VA_ARGS__)
26 #define CASE_STR(a,b) \
27 case a:\
28 strcpy(str, b);\
29 break
31 static u32 w;
33 #define OK 0
34 #define END 1
35 #define ERR 2
36 static u8 read_w(u32 *w)
38 size_t read_bytes_n;
39 read_bytes_n = fread(w, sizeof(*w), 1, stdin);
40 if (read_bytes_n != sizeof(*w)) {
41 if (feof(stdin) != 0)
42 return END;
43 if (ferror(stdin) != 0)
44 return ERR;
48 /* op must be in range */
49 static u8 *v_op_blk_0_to_str(u8 op)
51 static u8 str[STR_SZ_MAX];
53 switch (op) {
54 CASE_STR( 0, "v_cndmask_b32");
55 CASE_STR( 1, "v_readlane_b32");
56 CASE_STR( 2, "v_writelane_b32");
57 CASE_STR( 3, "v_add_f32");
58 CASE_STR( 4, "v_sub_f32");
59 CASE_STR( 5, "v_subrev_f32");
60 CASE_STR( 6, "v_mac_legacy_f32");
61 CASE_STR( 7, "v_mul_legacy_f32");
62 CASE_STR( 8, "v_mul_f32");
63 CASE_STR( 9, "v_mul_i32_i24");
64 CASE_STR(10, "v_mul_hi_i32_i24");
65 CASE_STR(11, "v_mul_u32_u24");
66 CASE_STR(12, "v_mul_hi_u32_u24");
67 CASE_STR(13, "v_min_legacy_f32");
68 CASE_STR(14, "v_max_legacy_f32");
69 CASE_STR(15, "v_min_f32");
70 CASE_STR(16, "v_max_f32");
71 CASE_STR(17, "v_min_i32");
72 CASE_STR(18, "v_max_i32");
73 CASE_STR(19, "v_min_u32");
74 CASE_STR(20, "v_max_u32");
75 CASE_STR(21, "v_lshr_b32");
76 CASE_STR(22, "v_lshrrev_b32");
77 CASE_STR(23, "v_ashr_i32");
78 CASE_STR(24, "v_ashrrev_i32");
79 CASE_STR(25, "v_lshl_b32");
80 CASE_STR(26, "v_lshlrev_b32");
81 CASE_STR(27, "v_and_b32");
82 CASE_STR(28, "v_or_b32");
83 CASE_STR(29, "v_xor_b32");
84 CASE_STR(30, "v_bfm_b32");
85 CASE_STR(31, "v_mac_b32");
86 CASE_STR(32, "v_madmk_f32");
87 CASE_STR(33, "v_madak_f32");
88 CASE_STR(34, "v_bcnt_u32_b32");
89 CASE_STR(35, "v_mbcnt_lo_u32_b32");
90 CASE_STR(36, "v_mbcnt_hi_u32_b32");
91 default:
92 out("ERROR:vector opcode blk 0 unknown code %u\n", op);
93 exit(1);
94 break;
98 /* op must be in range */
99 static u8 *v_op_blk_1_to_str(u8 op)
101 static u8 str[STR_SZ_MAX];
103 switch (op) {
104 CASE_STR(0, "v_add_i32" );
105 CASE_STR(1, "v_sub_i32");
106 CASE_STR(2, "v_subrev_i32");
107 CASE_STR(3, "v_addc_u32");
108 CASE_STR(4, "v_subb_u32");
109 CASE_STR(5, "v_subbrev_u32");
110 default:
111 out("ERROR:vector opcode blk 1 unknown code %u\n", op);
112 exit(1);
113 break;
117 /* op must be in range */
118 static u8 *v_op_blk_2_to_str(u8 op)
120 static u8 str[STR_SZ_MAX];
122 switch (op) {
123 CASE_STR(0, "v_ldexp_f32");
124 CASE_STR(1, "v_cvt_pkaccum_u8_f32");
125 CASE_STR(2, "v_cvt_pknorm_i16_f32");
126 CASE_STR(3, "v_cvt_pknorm_u16_f32");
127 CASE_STR(4, "v_cvt_pkrtz_f16_f32");
128 CASE_STR(5, "v_cvt_pk_u16_u32");
129 CASE_STR(6, "v_cvt_pk_i16_i32");
130 default:
131 out("ERROR:vector opcode blk 2 unknown code %u\n", op);
132 exit(1);
133 break;
137 static u8 *s_opd_to_str(u8 opd, bool *literal_was_read, u32 *literal)
139 u8 r;
140 u8 *str;
142 str = malloc(STR_SZ_MAX);
144 if (opd <= 103) {
145 pf("sgpr%u", opd);
146 goto exit;
148 if (112 <= opd && opd <= 123) {
149 pf("ttmp%u", opd);
150 goto exit;
152 if (128 <= opd && opd <= 192) {
153 pf("%u", opd - 128);
154 goto exit;
156 if (193 <= opd && opd <= 208) {
157 pf("-%u", opd - 193 + 1);
158 goto exit;
160 switch (opd) {
161 CASE_STR(106, "vcc_lo");
162 CASE_STR(107, "vcc_hi");
163 CASE_STR(108, "tba_lo");
164 CASE_STR(109, "tba_hi");
165 CASE_STR(110, "tma_lo");
166 CASE_STR(111, "tma_hi");
167 CASE_STR(124, "m0");
168 CASE_STR(126, "exec_lo");
169 CASE_STR(127, "exec_hi");
170 CASE_STR(240, "0.5");
171 CASE_STR(241, "-0.5");
172 CASE_STR(242, "1.0");
173 CASE_STR(243, "-1.0");
174 CASE_STR(244, "2.0");
175 CASE_STR(245, "-2.0");
176 CASE_STR(246, "4.0");
177 CASE_STR(247, "-4.0");
178 CASE_STR(251, "vccz");
179 CASE_STR(252, "execz");
180 CASE_STR(253, "scc");
181 case 255:
182 if (!*literal_was_read) {
183 r = read_w(literal);
184 if (r != OK) {
185 out("ERROR:missing literal\n");
186 exit(1);
188 *literal_was_read = true;
190 pf("literal(=0x%08x)", *literal);
191 break;
192 default:
193 pf("unknown_operand(=0x%02x)", opd);
194 break;
196 exit:
197 return str;
200 static u8 *v_opd_to_str(u16 v_opd, bool *literal_was_read, u32 *literal)
202 u8 *str;
204 if (256 <= v_opd && v_opd <= 511) {
205 str = malloc(STR_SZ_MAX);
206 pf("vgpr%u", v_opd - 256);
207 goto exit;
210 str = s_opd_to_str((u8)v_opd, literal_was_read, literal);
211 exit:
212 return str;
215 static u8 *sop1_op_to_str(u8 op)
217 static u8 str[STR_SZ_MAX];
219 switch (op) {
220 CASE_STR( 3, "s_mov_b32");
221 CASE_STR( 4, "s_mov_b64");
222 CASE_STR( 5, "s_cmov_b32");
223 CASE_STR( 6, "s_cmov_b64");
224 CASE_STR( 7, "s_not_b32");
225 CASE_STR( 8, "s_not_b64");
226 CASE_STR( 9, "s_wqm_b32");
227 CASE_STR( 10, "s_wqm_b64");
228 CASE_STR( 11, "s_brev_b32");
229 CASE_STR( 12, "s_brev_b64");
230 CASE_STR( 13, "s_bctn0_i32_b32");
231 CASE_STR( 14, "s_bctn0_i32_b64");
232 CASE_STR( 15, "s_bctn1_i32_b32");
233 CASE_STR( 16, "s_bctn1_i32_b64");
234 CASE_STR( 17, "s_ff0_i32_b32");
235 CASE_STR( 18, "s_ff0_i32_b64");
236 CASE_STR( 19, "s_ff1_i32_b32");
237 CASE_STR( 20, "s_ff1_i32_b64");
238 CASE_STR( 21, "s_flbit_i32_b32");
239 CASE_STR( 22, "s_flbit_i32_b64");
240 CASE_STR( 23, "s_flbit_i32");
241 CASE_STR( 24, "s_flbit_i32_i64");
242 CASE_STR( 25, "s_sext_i32_i8");
243 CASE_STR( 26, "s_sext_i32_i16");
244 CASE_STR( 27, "s_bitset0_b32");
245 CASE_STR( 28, "s_bitset0_b64");
246 CASE_STR( 29, "s_bitset1_b32");
247 CASE_STR( 30, "s_bitset1_b64");
248 CASE_STR( 31, "s_getpc_b64");
249 CASE_STR( 32, "s_setpc_b64");
250 CASE_STR( 33, "s_swappc_b64");
251 CASE_STR( 34, "s_rfe_b64");
252 CASE_STR( 36, "s_and_saveexec_b64");
253 CASE_STR( 37, "s_or_saveexec_b64");
254 CASE_STR( 38, "s_xor_saveexec_b64");
255 CASE_STR( 39, "s_andn2_saveexec_b64");
256 CASE_STR( 40, "s_orn2_saveexec_b64");
257 CASE_STR( 41, "s_nand_saveexec_b64");
258 CASE_STR( 42, "s_nor_saveexec_b64");
259 CASE_STR( 43, "s_xnor_saveexec_b64");
260 CASE_STR( 44, "s_quadmask_b32");
261 CASE_STR( 45, "s_quadmask_b64");
262 CASE_STR( 46, "s_movrels_b32");
263 CASE_STR( 47, "s_movrels_b64");
264 CASE_STR( 48, "s_movreld_b32");
265 CASE_STR( 49, "s_movreld_b64");
266 CASE_STR( 50, "s_cbranch_join");
267 CASE_STR( 52, "s_abs_i32");
268 CASE_STR( 53, "s_mov_fed_b32");
269 default:
270 pf("unknown_sop1_op(%u)", op);
271 break;
273 return str;
276 static void sop1(void)
278 u8 op;
279 u8 *op_str;
281 u32 literal;
282 bool literal_was_read;
284 u8 ssrc0;
285 u8 *ssrc0_str;
287 u8 sdst;
288 u8 *sdst_str;
290 literal_was_read = false;
292 op = (u8)(w >> 8);
293 ssrc0 = (u8)w; /* 8 bits */
294 sdst = ((u8)(w >> 16)) & 0x7f; /* 7 bits */
296 op_str = sop1_op_to_str(op);
297 ssrc0_str = s_opd_to_str(ssrc0, &literal_was_read, &literal);
298 sdst_str = s_opd_to_str(sdst, &literal_was_read, &literal);
300 out("%s ssrc0=%s sdst=%s\n", op_str, ssrc0_str, sdst_str);
303 static u8 *sopc_op_to_str(u8 op)
305 static u8 str[STR_SZ_MAX];
307 switch (op) {
308 CASE_STR( 0, "s_cmp_eq_i32");
309 CASE_STR( 1, "s_cmp_lg_i32");
310 CASE_STR( 2, "s_cmp_gt_i32");
311 CASE_STR( 3, "s_cmp_ge_i32");
312 CASE_STR( 4, "s_cmp_lt_i32");
313 CASE_STR( 5, "s_cmp_le_i32");
314 CASE_STR( 6, "s_cmp_eq_u32");
315 CASE_STR( 7, "s_cmp_lg_u32");
316 CASE_STR( 8, "s_cmp_gt_u32");
317 CASE_STR( 9, "s_cmp_ge_u32");
318 CASE_STR(10, "s_cmp_lt_u32");
319 CASE_STR(11, "s_cmp_le_u32");
320 CASE_STR(12, "s_bitcmp0_b32");
321 CASE_STR(13, "s_bitcmp1_b32");
322 CASE_STR(14, "s_bitcmp0_b64");
323 CASE_STR(15, "s_bitcmp1_b64");
324 CASE_STR(16, "s_setvskip");
325 default:
326 pf("unknown_sopc_op(%u)", op);
327 break;
329 return str;
332 static void sopc(void)
334 u8 op;
335 u8 *op_str;
337 u32 literal;
338 bool literal_was_read;
340 u8 ssrc0;
341 u8 *ssrc0_str;
343 u8 ssrc1;
344 u8 *ssrc1_str;
346 literal_was_read = false;
348 op = ((u8)(w >> 16)) & 0x7f; /* 7 bits */
349 ssrc0 = (u8)w; /* 8 bits */
350 ssrc1 = (u8)(w >> 8); /* 8 bits */
352 op_str = sopc_op_to_str(op);
353 ssrc0_str = s_opd_to_str(ssrc0, &literal_was_read, &literal);
354 ssrc1_str = s_opd_to_str(ssrc1, &literal_was_read, &literal);
356 out("%s ssrc0=%s ssrc1=%s\n", op_str, ssrc0_str, ssrc1_str);
359 static u8 *vop1_op_to_str(u8 op)
361 static u8 str[STR_SZ_MAX];
363 switch (op) {
364 CASE_STR( 0, "v_nop");
365 CASE_STR( 1, "v_mov_b32");
366 CASE_STR( 2, "v_readfirstlane_b32");
367 CASE_STR( 3, "v_cvt_i32_f64");
368 CASE_STR( 4, "v_cvt_f64_i32");
369 CASE_STR( 5, "v_cvt_f32_i32");
370 CASE_STR( 6, "v_cvt_f32_u32");
371 CASE_STR( 7, "v_cvt_u32_f32");
372 CASE_STR( 8, "v_cvt_i32_f32");
373 CASE_STR( 9, "v_mov_fed_b32");
374 CASE_STR( 10, "v_cvt_f16_f32");
375 CASE_STR( 11, "v_cvt_f32_f16");
376 CASE_STR( 12, "v_cvt_rpi_i32_f32");
377 CASE_STR( 13, "v_cvt_flr_i32_f32");
378 CASE_STR( 14, "v_cvt_off_f32_i4");
379 CASE_STR( 15, "v_cvt_f32_f64");
380 CASE_STR( 16, "v_cvt_f64_f32");
381 CASE_STR( 17, "v_cvt_f32_ubyte0");
382 CASE_STR( 18, "v_cvt_f32_ubyte1");
383 CASE_STR( 19, "v_cvt_f32_ubyte2");
384 CASE_STR( 20, "v_cvt_f32_ubyte3");
385 CASE_STR( 21, "v_cvt_u32_f64");
386 CASE_STR( 22, "v_cvt_f64_u32");
387 CASE_STR( 32, "v_fract_f32");
388 CASE_STR( 33, "v_trunc_f32");
389 CASE_STR( 34, "v_ceil_f32");
390 CASE_STR( 35, "v_rndne_f32");
391 CASE_STR( 36, "v_floor_f32");
392 CASE_STR( 37, "v_exp_f32");
393 CASE_STR( 38, "v_log_clamp_f32");
394 CASE_STR( 39, "v_log_f32");
395 CASE_STR( 40, "v_rcp_clamp_f32");
396 CASE_STR( 41, "v_rcp_legacy_f32");
397 CASE_STR( 42, "v_rcp_f32");
398 CASE_STR( 43, "v_rcp_iflag_f32");
399 CASE_STR( 44, "v_rsq_clamp_f32");
400 CASE_STR( 45, "v_rsq_legacy_f32");
401 CASE_STR( 46, "v_rsq_f32");
402 CASE_STR( 47, "v_rsp_f64");
403 CASE_STR( 48, "v_rsp_clamp_f64");
404 CASE_STR( 49, "v_rsq_f64");
405 CASE_STR( 50, "v_rsq_clamp_f64");
406 CASE_STR( 51, "v_sqrt_f32");
407 CASE_STR( 52, "v_sqrt_f64");
408 CASE_STR( 53, "v_sin_f64");
409 CASE_STR( 54, "v_cos_f64");
410 CASE_STR( 55, "v_not_b32");
411 CASE_STR( 56, "v_bfrev_b32");
412 CASE_STR( 57, "v_ffbh_u32");
413 CASE_STR( 58, "v_ffbl_b32");
414 CASE_STR( 59, "v_ffbh_i32");
415 CASE_STR( 60, "v_frexp_exp_i32_f64");
416 CASE_STR( 61, "v_frexp_mant_f64");
417 CASE_STR( 62, "v_frac_f64");
418 CASE_STR( 63, "v_frexp_exp_i32_f32");
419 CASE_STR( 64, "v_frexp_mant_f32");
420 CASE_STR( 65, "v_clrexcp");
421 CASE_STR( 66, "v_movreld_b32");
422 CASE_STR( 67, "v_movrels_b32");
423 CASE_STR( 68, "v_movrelsd_b32");
424 default:
425 pf("unknown_vop1_op(%u)", op);
426 break;
428 return str;
431 static void vop1(void)
433 u8 op;
434 u8 *op_str;
436 u32 literal;
437 bool literal_was_read;
439 u16 src0;
440 u8 *src0_str;
442 u8 vdst;
444 literal_was_read = false;
446 op = (u8)(w >> 9); /* 8 bits */
447 src0 = (u16)(w) & 0x1ff; /* 9 bits */
448 vdst = (u8)(w >> 17); /* 8 bits */
450 op_str = vop1_op_to_str(op);
451 src0_str = v_opd_to_str(op, &literal_was_read, &literal);
453 out("%s src0=%s vdst=vgpr%u\n", op_str, src0_str, vdst);
456 static u8 *cmp_op_16_to_str(u8 offset)
458 static u8 str[STR_SZ_MAX];
460 switch (offset) {
461 case 0:
462 strcpy(str, "f");
463 break;
464 case 1:
465 strcpy(str,"lt");
466 break;
467 case 2:
468 strcpy(str, "eq");
469 break;
470 case 3:
471 strcpy(str, "le");
472 break;
473 case 4:
474 strcpy(str, "gt");
475 break;
476 case 5:
477 strcpy(str, "lg");
478 break;
479 case 6:
480 strcpy(str, "ge");
481 break;
482 case 7:
483 strcpy(str, "o");
484 break;
485 case 8:
486 strcpy(str, "u");
487 break;
488 case 9:
489 strcpy(str, "nge");
490 break;
491 case 10:
492 strcpy(str, "nlg");
493 break;
494 case 11:
495 strcpy(str, "ngt");
496 break;
497 case 12:
498 strcpy(str, "nle");
499 break;
500 case 13:
501 strcpy(str, "neq");
502 break;
503 case 14:
504 strcpy(str, "nlt");
505 break;
506 case 15:
507 strcpy(str, "tru");
508 break;
509 default:
510 pf("unknown_cmp_op_16(%u)", offset);
511 break;
513 return str;
516 static u8 *cmp_op_8_to_str(u8 offset)
518 static u8 str[STR_SZ_MAX];
520 switch (offset) {
521 case 0:
522 strcpy(str, "f");
523 break;
524 case 1:
525 strcpy(str, "lt");
526 break;
527 case 2:
528 strcpy(str, "eq");
529 break;
530 case 3:
531 strcpy(str, "le");
532 break;
533 case 4:
534 strcpy(str, "gt");
535 break;
536 case 5:
537 strcpy(str, "lg");
538 break;
539 case 6:
540 strcpy(str, "ge");
541 break;
542 case 7:
543 strcpy(str, "tru");
544 break;
545 default:
546 pf("unknown_cmp_op_8(%u)", offset);
547 break;
549 return str;
552 static u8 *vopc_op_to_str(u8 op)
554 static u8 str[STR_SZ_MAX];
556 if (0x00 <= op && op <= 0x0f) {
557 pf("v_cmp_%s_f32", cmp_op_16_to_str(op));
558 goto exit;
561 if (0x10 <= op && op <= 0x1f) {
562 pf("v_cmpx_%s_f32", cmp_op_16_to_str(op));
563 goto exit;
566 if (0x20 <= op && op <= 0x2f) {
567 pf("v_cmp_%s_f64", cmp_op_16_to_str(op));
568 goto exit;
571 if (0x30 <= op && op <= 0x3f) {
572 pf("v_cmpx_%s_f64", cmp_op_16_to_str(op));
573 goto exit;
576 if (0x40 <= op && op <= 0x4f) {
577 pf("v_cmps_%s_f32", cmp_op_16_to_str(op));
578 goto exit;
581 if (0x50 <= op && op <= 0x5f) {
582 pf("v_cmpsx_%s_f32", cmp_op_16_to_str(op));
583 goto exit;
586 if (0x60 <= op && op <= 0x6f) {
587 pf("v_cmps_%s_f64", cmp_op_16_to_str(op));
588 goto exit;
591 if (0x70 <= op && op <= 0x7f) {
592 pf("v_cmpsx_%s_f64", cmp_op_16_to_str(op));
593 goto exit;
596 if (0x80 <= op && op <= 0x87) {
597 pf("v_cmp_%s_i32", cmp_op_8_to_str(op));
598 goto exit;
601 if (0x90 <= op && op <= 0x97) {
602 pf("v_cmpx_%s_i32", cmp_op_8_to_str(op));
603 goto exit;
606 if (0xa0 <= op && op <= 0xa7) {
607 pf("v_cmp_%s_i64", cmp_op_8_to_str(op));
608 goto exit;
611 if (0xb0 <= op && op <= 0xb7) {
612 pf("v_cmpx_%s_i64", cmp_op_8_to_str(op));
613 goto exit;
616 if (0xc0 <= op && op <= 0xc7) {
617 pf("v_cmp_%s_u64", cmp_op_8_to_str(op));
618 goto exit;
621 if (0xd0 <= op && op <= 0xd7) {
622 pf("v_cmpx_%s_u32", cmp_op_8_to_str(op));
623 goto exit;
626 if (0xe0 <= op && op <= 0xe7) {
627 pf("v_cmp_%s_u64", cmp_op_8_to_str(op));
628 goto exit;
631 if (0xf0 <= op && op <= 0xf7) {
632 pf("v_cmpx_%s_u64", cmp_op_8_to_str(op));
633 goto exit;
635 switch (op) {
636 case 0x88:
637 pf("v_cmp_class_f32");
638 break;
639 case 0x98:
640 pf("v_cmpx_class_f32");
641 break;
642 case 0xa8:
643 pf("v_cmp_class_f64");
644 break;
645 case 0xb8:
646 pf("v_cmpx_class_f64");
647 break;
648 default:
649 pf("unknown_vopc_op(%u)", op);
650 break;
652 exit:
653 return str;
656 static void vopc(void)
658 u8 op;
659 u8 *op_str;
661 u32 literal;
662 bool literal_was_read;
664 u16 src0;
665 u8 *src0_str;
667 u8 vsrc1;
669 literal_was_read = false;
671 op = (u8)(w >> 17); /* 8 bits */
672 src0 = (u16)(w) & 0x1ff; /* 9 bits */
673 vsrc1 = (u8)(w >> 9); /* 8 bits */
675 op_str = vopc_op_to_str(op);
676 src0_str = v_opd_to_str(op, &literal_was_read, &literal);
678 out("%s src0=%s vsrc1=vgpr%u\n", op_str, src0_str, vsrc1);
681 static void export(void)
683 u8 r;
684 u32 w1;
686 u8 en;
687 u8 tgt;
688 u8 compr;
689 u8 done;
690 u8 vm;
692 u8 vsrc0;
693 u8 vsrc1;
694 u8 vsrc2;
695 u8 vsrc3;
697 r = read_w(&w1);
698 if (r != OK) {
699 out("ERROR:export:missing 2nd instruction word\n");
700 exit(1);
703 en = ((u8)w) & 0x0f; /* 4 bits */
704 tgt = (u8)(w >> 4) & 0x3f; /* 6 bits */
705 compr = (u8)(w >> 10) & 1; /* 1 bit */
706 done = (u8)(w >> 11) & 1; /* 1 bit */
707 vm = (u8)(w >> 12) & 1; /* 1 bit */
709 vsrc0 = (u8)(w1); /* 8 bits */
710 vsrc1 = (u8)(w1 >> 8); /* 8 bits */
711 vsrc2 = (u8)(w1 >> 16); /* 8 bits */
712 vsrc3 = (u8)(w1 >> 24); /* 8 bits */
714 out("export en=%u tgt=%u compr=%s done=%s vm=%s vsrc0=vgpr%u vsrc1=vgpr%u vsrc2=vgpr%u vsrc3=%u\n", en , tgt, (compr != 0) ? "true" : "false", (done != 0) ? "true" : "false", (vm != 0) ? "true" : "false", vsrc0, vsrc1, vsrc2, vsrc3);
717 static u8 *vintrp_op_to_str(u8 op)
719 static u8 str[STR_SZ_MAX];
721 switch (op) {
722 CASE_STR(0, "vinterp_p1_f32" );
723 CASE_STR(1, "vinterp_p2_f32" );
724 CASE_STR(2, "vinterp_mov_f32" );
725 default:
726 pf("unknown_vinterp_op(%u)", op);
727 break;
729 return str;
732 static void vintrp(void)
734 u8 vsrc;
735 u8 attrchan;
736 u8 attr;
737 u8 op;
738 u8 *op_str;
739 u8 vdst;
741 vsrc = (u8)w; /* 8 bits */
742 attrchan = (u8)(w >> 8) & 0x03; /* 2 bits */
743 attr = (u8)(w >> 10) & 0x3f; /* 6 bits */
744 op = (u8)(w >> 16) & 0x03; /* 2 bits */
746 op_str = vintrp_op_to_str(op);
748 out("%s vsrc=vgpr%u attrchan=%u attr=%u vdst=vgpr%u\n", op_str, vsrc, attrchan, attr, vdst);
751 static u8 *vop3b_op_to_str(u16 op)
753 static u8 str[STR_SZ_MAX];
755 if (293 <= op && op <= 298) {
756 strcpy(str, v_op_blk_1_to_str((u8)(op - 293)));
757 goto exit;
760 switch (op) {
761 CASE_STR(365, "v_div_scale_f32");
762 CASE_STR(366, "v_div_scale_f64");
763 default:
764 pf("unknown_vop3b_op(%u)", op);
765 break;
767 exit:
768 return str;
771 static void vop3b(u16 op, u32 w1)
773 u8 vdst;
774 u8 sdst;
775 u8 *sdst_str;
776 u8 *op_str;
777 u16 src0;
778 u8 *src0_str;
779 u16 src1;
780 u8 *src1_str;
781 u16 src2;
782 u8 *src2_str;
783 u8 omod;
784 u8 neg;
786 bool literal_was_read;
787 u32 literal;
789 literal_was_read = false;
791 vdst = (u8)w; /* 8 bits */
792 sdst = (u8)(w >> 8) & 0x7f; /* 7 bits */
793 src0 = (u16)w1 & 0x1ff; /* 9 bits */
794 /* documentation seems wrong on bit offsets, see vop3a */
795 src1 = (u16)(w1 >> 9) & 0x1ff; /* 9 bits */
796 src2 = (u16)(w1 >> 18) & 0x1ff; /* 9 bits */
797 omod = (u8)(w1 >> 27) & 0x03; /* 2 bits */
798 neg = (u8)(w1 >> 29) & 0x07; /* 3 bits */
800 op_str = vop3b_op_to_str(op);
801 sdst_str = v_opd_to_str((u16)sdst, &literal_was_read, &literal);
802 src0_str = v_opd_to_str(src0, &literal_was_read, &literal);
803 src1_str = v_opd_to_str(src1, &literal_was_read, &literal);
804 src2_str = v_opd_to_str(src2, &literal_was_read, &literal);
806 out("%s vdst=vgpr%u sdst=%s src0=%s src1=%s src2=%s omod=%u neg=%u\n", op_str, vdst, sdst_str, src0_str, src1_str, src2_str, omod, neg);
809 static u8 *vop3a_op_to_str(u16 op)
811 static u8 str[STR_SZ_MAX];
813 if (op <= 255) {
814 strcpy(str, vopc_op_to_str((u8)op));
815 goto exit;
817 if (256 <= op && op <= 292) {
818 strcpy(str, v_op_blk_0_to_str((u8)(op - 256)));
819 goto exit;
821 if ((293 <= op && op <= 298) || (365 <= op && op <= 366)) {
822 strcpy(str, vop3b_op_to_str(op));
823 goto exit;
825 if (299 <= op && op <= 305) {
826 strcpy(str, v_op_blk_2_to_str((u8)(op - 299)));
827 goto exit;
829 if (384 <= op && op <= 452) {
830 strcpy(str, vop1_op_to_str((u8)(op - 384)));
831 goto exit;
833 switch (op) {
834 CASE_STR(320, "v_mad_legacy_f32");
835 CASE_STR(321, "v_mad_f32");
836 CASE_STR(322, "v_mad_i32_i24");
837 CASE_STR(323, "v_mad_u32_u24");
838 CASE_STR(324, "v_cubeid_f32");
839 CASE_STR(325, "v_cubesc_f32");
840 CASE_STR(326, "v_cubetc_f32");
841 CASE_STR(327, "v_cubema_f32");
842 CASE_STR(328, "v_bfe_i32");
843 CASE_STR(329, "v_bfe_u32");
844 CASE_STR(330, "v_bfi_b32");
845 CASE_STR(331, "v_fma_f32");
846 CASE_STR(332, "v_fma_f64");
847 CASE_STR(333, "v_lerp_u8");
848 CASE_STR(334, "v_alignbit_b32");
849 CASE_STR(335, "v_alignbyte_b32");
850 CASE_STR(336, "v_mullit_f32");
851 CASE_STR(337, "v_min3_f32");
852 CASE_STR(338, "v_min3_i32");
853 CASE_STR(339, "v_min3_u32");
854 CASE_STR(340, "v_max3_f32");
855 CASE_STR(341, "v_max3_i32");
856 CASE_STR(342, "v_max3_u32");
857 CASE_STR(343, "v_med3_f32");
858 CASE_STR(344, "v_med3_i32");
859 CASE_STR(345, "v_med3_u32");
860 CASE_STR(346, "v_sad_u8");
861 CASE_STR(347, "v_sad_hi_u8");
862 CASE_STR(348, "v_sad_u16");
863 CASE_STR(349, "v_sad_u32");
864 CASE_STR(350, "v_cvt_pk_u8_f32");
865 CASE_STR(351, "v_div_fixup_f32");
866 CASE_STR(352, "v_div_fixup_f64");
867 CASE_STR(353, "v_lshl_b64");
868 CASE_STR(354, "v_lshr_b64");
869 CASE_STR(355, "v_ashr_i64");
870 CASE_STR(356, "v_add_f64");
871 CASE_STR(357, "v_mul_f64");
872 CASE_STR(358, "v_min_f64");
873 CASE_STR(359, "v_max_f64");
874 CASE_STR(360, "v_ldexp_f64");
875 CASE_STR(361, "v_mul_lo_u32");
876 CASE_STR(362, "v_mul_hi_u32");
877 CASE_STR(363, "v_mul_lo_i32");
878 CASE_STR(364, "v_mul_hi_i32");
879 CASE_STR(367, "v_div_fmas_f32");
880 CASE_STR(368, "v_div_fmas_f64");
881 CASE_STR(369, "v_msad_u8");
882 CASE_STR(370, "v_qsad_u8");
883 CASE_STR(371, "v_mqsad_u8");
884 CASE_STR(372, "v_trig_preop_f64");
885 default:
886 pf("unknown_vop3a_op(%u)", op);
888 exit:
889 return str;
892 static void vop3a(u16 op, u32 w1)
894 u8 vdst;
895 u8 abs;
896 u8 clamp;
897 u8 *op_str;
898 u16 src0;
899 u8 *src0_str;
900 u16 src1;
901 u8 *src1_str;
902 u16 src2;
903 u8 *src2_str;
904 u8 omod;
905 u8 neg;
907 bool literal_was_read;
908 u32 literal;
910 literal_was_read = false;
912 vdst = (u8)w; /* 8 bits */
913 abs = (u8)(w >> 8) & 0x07; /* 3 bits */
914 clamp = (u8)(w >> 11) & 0x01; /* 1 bits */
915 src0 = (u16)w1 & 0x1ff; /* 9 bits */
916 src1 = (u16)(w1 >> 9) & 0x1ff; /* 9 bits */
917 src2 = (u16)(w1 >> 18) & 0x1ff; /* 9 bits */
918 omod = (u8)(w1 >> 27) & 0x03; /* 2 bits */
919 neg = (u8)(w1 >> 29) & 0x07; /* 3 bits */
921 op_str = vop3a_op_to_str(op);
922 src0_str = v_opd_to_str(src0, &literal_was_read, &literal);
923 src1_str = v_opd_to_str(src1, &literal_was_read, &literal);
924 src2_str = v_opd_to_str(src2, &literal_was_read, &literal);
926 out("%s vdst=vgpr%u abs=%u clamp=%s src0=%s src1=%s src2=%s omod=%u neg=%u\n", op_str, vdst, abs, (clamp != 0) ? "yes" : "no", src0_str, src1_str, src2_str, omod, neg);
929 static void vop3(void)
931 u8 r;
932 u32 w1;
933 u16 op;
935 r = read_w(&w1);
936 if (r != OK) {
937 out("ERROR:vop3[ab]:missing 2nd instruction word\n");
938 exit(1);
941 op = (u16)(w >> 17) & 0x1f;
943 if (293 <= op && op <= 366)
944 vop3b(op, w1);
945 else
946 vop3a(op, w1);
949 static u8 *ds_op_to_str(u8 op)
951 static u8 str[STR_SZ_MAX];
953 switch (op) {
954 CASE_STR( 0, "ds_add_u32");
955 CASE_STR( 1, "ds_sub_u32");
956 CASE_STR( 2, "ds_rsub_u32");
957 CASE_STR( 3, "ds_inc_u32");
958 CASE_STR( 4, "ds_dec_u32");
959 CASE_STR( 5, "ds_min_i32");
960 CASE_STR( 6, "ds_max_i32");
961 CASE_STR( 7, "ds_min_u32");
962 CASE_STR( 8, "ds_max_u32");
963 CASE_STR( 9, "ds_and_b32");
964 CASE_STR( 10, "ds_or_b32");
965 CASE_STR( 11, "ds_xor_b32");
966 CASE_STR( 12, "ds_mskor_b32");
967 CASE_STR( 13, "ds_write_b32");
968 CASE_STR( 14, "ds_write2_b32");
969 CASE_STR( 15, "ds_write2st64_b32");
970 CASE_STR( 16, "ds_cmpst_b32");
971 CASE_STR( 17, "ds_cmpst_f32");
972 CASE_STR( 18, "ds_min_f32");
973 CASE_STR( 19, "ds_max_f32");
974 CASE_STR( 25, "ds_gws_init");
975 CASE_STR( 26, "ds_gws_sema_v");
976 CASE_STR( 27, "ds_gws_sema_br");
977 CASE_STR( 28, "ds_gws_sema_p");
978 CASE_STR( 29, "ds_gws_barrier");
979 CASE_STR( 30, "ds_write_b8");
980 CASE_STR( 31, "ds_write_b16");
981 CASE_STR( 32, "ds_add_rtn_u32");
982 CASE_STR( 33, "ds_sub_rtn_u32");
983 CASE_STR( 34, "ds_rsub_rtn_u32");
984 CASE_STR( 35, "ds_inc_rtn_u32");
985 CASE_STR( 36, "ds_dec_rtn_u32");
986 CASE_STR( 37, "ds_min_rtn_i32");
987 CASE_STR( 38, "ds_max_rtn_i32");
988 CASE_STR( 39, "ds_min_rtn_u32");
989 CASE_STR( 40, "ds_max_rtn_u32");
990 CASE_STR( 41, "ds_and_rtn_b32");
991 CASE_STR( 42, "ds_or_rtn_b32");
992 CASE_STR( 43, "ds_xor_rtn_b32");
993 CASE_STR( 44, "ds_mskor_rtn_b32");
994 CASE_STR( 45, "ds_wrxchg_rtn_b32");
995 CASE_STR( 46, "ds_wrxchg2_rtn_b32");
996 CASE_STR( 47, "ds_wrxchg2st64_rtn_b32");
997 CASE_STR( 48, "ds_cmpst_rtn_b32");
998 CASE_STR( 49, "ds_cmpst_rtn_f32");
999 CASE_STR( 50, "ds_min_rtn_f32");
1000 CASE_STR( 51, "ds_max_rtn_f32");
1001 CASE_STR( 53, "ds_swizzle_b32");
1002 CASE_STR( 54, "ds_read_b32");
1003 CASE_STR( 55, "ds_read2_b32");
1004 CASE_STR( 56, "ds_read2st_b32");
1005 CASE_STR( 57, "ds_read_i8");
1006 CASE_STR( 58, "ds_read_u8");
1007 CASE_STR( 59, "ds_read_i16");
1008 CASE_STR( 60, "ds_read_u16");
1009 CASE_STR( 61, "ds_consume");
1010 CASE_STR( 62, "ds_append");
1011 CASE_STR( 63, "ds_ordered_count");
1012 CASE_STR( 64, "ds_add_u64");
1013 CASE_STR( 65, "ds_sub_u64");
1014 CASE_STR( 66, "ds_rsub_u64");
1015 CASE_STR( 67, "ds_inc_u64");
1016 CASE_STR( 68, "ds_dec_u64");
1017 CASE_STR( 69, "ds_min_i64");
1018 CASE_STR( 70, "ds_max_i64");
1019 CASE_STR( 71, "ds_min_u64");
1020 CASE_STR( 72, "ds_max_u64");
1021 CASE_STR( 73, "ds_and_b64");
1022 CASE_STR( 74, "ds_or_b64");
1023 CASE_STR( 75, "ds_xor_b64");
1024 CASE_STR( 76, "ds_mskor_b64");
1025 CASE_STR( 77, "ds_write_b64");
1026 CASE_STR( 78, "ds_write2_b64");
1027 CASE_STR( 79, "ds_write2st64_b64");
1028 CASE_STR( 80, "ds_cmpst_b64");
1029 CASE_STR( 81, "ds_cmpst_f64");
1030 CASE_STR( 82, "ds_min_f64");
1031 CASE_STR( 83, "ds_max_f64");
1032 CASE_STR( 96, "ds_add_rtn_u64");
1033 CASE_STR( 97, "ds_sub_rtn_u64");
1034 CASE_STR( 98, "ds_rsub_rtn_u64");
1035 CASE_STR( 99, "ds_inc_rtn_u64");
1036 CASE_STR(100, "ds_dec_rtn_u64");
1037 CASE_STR(101, "ds_min_rtn_i64");
1038 CASE_STR(102, "ds_max_rtn_i64");
1039 CASE_STR(103, "ds_min_rtn_u64");
1040 CASE_STR(104, "ds_max_rtn_u64");
1041 CASE_STR(105, "ds_and_rtn_b64");
1042 CASE_STR(106, "ds_or_rtn_b64");
1043 CASE_STR(107, "ds_xor_rtn_b64");
1044 CASE_STR(108, "ds_mskxor_rtn_b64");
1045 CASE_STR(109, "ds_wrxchg_rtn_b64");
1046 CASE_STR(110, "ds_wrxchg2_rtn_b64");
1047 CASE_STR(111, "ds_wrxchg2st64_rtn_b64");
1048 CASE_STR(112, "ds_cmpst_rtn_b64");
1049 CASE_STR(113, "ds_cmpst_rtn_f64");
1050 CASE_STR(114, "ds_min_rtn_f64");
1051 CASE_STR(115, "ds_max_rtn_f64");
1052 CASE_STR(118, "ds_read_b64");
1053 CASE_STR(119, "ds_read2_b64");
1054 CASE_STR(120, "ds_read2st64_b64");
1055 CASE_STR(128, "ds_add_src2_u32");
1056 CASE_STR(129, "ds_sub_src2_u32");
1057 CASE_STR(130, "ds_rsub_src2_u32");
1058 CASE_STR(131, "ds_inc_src2_u32");
1059 CASE_STR(132, "ds_dec_src2_u32");
1060 CASE_STR(133, "ds_min_src2_i32");
1061 CASE_STR(134, "ds_max_src2_i32");
1062 CASE_STR(135, "ds_min_src2_u32");
1063 CASE_STR(136, "ds_max_src2_u32");
1064 CASE_STR(137, "ds_and_src2_b32");
1065 CASE_STR(138, "ds_or_src2_b32");
1066 CASE_STR(139, "ds_xor_src2_b32");
1067 CASE_STR(140, "ds_write_src2_b32");
1068 CASE_STR(146, "ds_min_src2_f32");
1069 CASE_STR(147, "ds_max_src2_f32");
1070 CASE_STR(192, "ds_add_src2_u64");
1071 CASE_STR(193, "ds_sub_src2_u64");
1072 CASE_STR(194, "ds_rsub_src2_u64");
1073 CASE_STR(195, "ds_inc_src2_u64");
1074 CASE_STR(196, "ds_dec_src2_u64");
1075 CASE_STR(197, "ds_min_src2_i64");
1076 CASE_STR(198, "ds_max_src2_i64");
1077 CASE_STR(199, "ds_min_src2_u64");
1078 CASE_STR(200, "ds_max_src2_u64");
1079 CASE_STR(201, "ds_and_src2_b64");
1080 CASE_STR(202, "ds_or_src2_b64");
1081 CASE_STR(203, "ds_xor_src2_b64");
1082 CASE_STR(204, "ds_write_src2_b64");
1083 CASE_STR(210, "ds_min_src2_f64");
1084 CASE_STR(211, "ds_max_src2_f64");
1085 default:
1086 pf("unknown_ds_op(%u)", op);
1087 break;
1092 static void ds(void)
1094 u8 r;
1095 u32 w1;
1097 u8 offset0;
1098 u8 offset1;
1099 u8 gds;
1100 u8 op;
1101 u8 *op_str;
1102 u8 addr;
1103 u8 data0;
1104 u8 data1;
1105 u8 vdst;
1107 r = read_w(&w1);
1108 if (r != OK) {
1109 out("ERROR:ds:missing 2nd instruction word\n");
1110 exit(1);
1113 offset0 = (u8)w; /* 8 bits */
1114 offset1 = (u8)(w >> 8); /* 8 bits */
1115 gds = (u8)(w >> 17) & 0x01; /* 1 bit */
1116 op = (u8)(w >> 18); /* 8 bits */
1117 addr = (u8)w1; /* 8 bits */
1118 data0 = (u8)(w1 >> 8); /* 8 bits */
1119 data1 = (u8)(w1 >> 16); /* 8 bits */
1120 vdst = (u8)(w1 >> 24); /* 8 bits */
1122 op_str = ds_op_to_str(op);
1124 out("%s offset0=%u offset1=%u %s addr=vgpr%u data0=vgpr%u data1=vgpr%u vdst=vgpr%u\n", op_str, offset0, offset1, (gds != 0) ? "gds" : "lds", addr, data0, data1, vdst);
1127 static u8 *mubuf_op_to_str(u8 op)
1129 static u8 str[STR_SZ_MAX];
1131 switch (op) {
1132 CASE_STR( 0, "buffer_load_format_x");
1133 CASE_STR( 1, "buffer_load_format_xy");
1134 CASE_STR( 2, "buffer_load_format_xyz");
1135 CASE_STR( 3, "buffer_load_format_xyzw");
1136 CASE_STR( 4, "buffer_store_format_x");
1137 CASE_STR( 5, "buffer_store_format_xy");
1138 CASE_STR( 6, "buffer_store_format_xyz");
1139 CASE_STR( 7, "buffer_store_format_xyzw");
1140 CASE_STR( 8, "buffer_load_ubyte");
1141 CASE_STR( 9, "buffer_load_sbyte");
1142 CASE_STR( 10, "buffer_load_ushort");
1143 CASE_STR( 11, "buffer_load_sshort");
1144 CASE_STR( 12, "buffer_load_dword");
1145 CASE_STR( 13, "buffer_load_dwordx2");
1146 CASE_STR( 14, "buffer_load_dwordx4");
1147 CASE_STR( 24, "buffer_store_byte");
1148 CASE_STR( 26, "buffer_store_short");
1149 CASE_STR( 28, "buffer_store_dword");
1150 CASE_STR( 29, "buffer_store_dwordx2");
1151 CASE_STR( 30, "buffer_store_dwordx4");
1152 CASE_STR( 48, "buffer_atomic_swap");
1153 CASE_STR( 49, "buffer_atomic_cmpswap");
1154 CASE_STR( 50, "buffer_atomic_add");
1155 CASE_STR( 51, "buffer_atomic_sub");
1156 CASE_STR( 52, "buffer_atomic_rsub");
1157 CASE_STR( 53, "buffer_atomic_smin");
1158 CASE_STR( 54, "buffer_atomic_umin");
1159 CASE_STR( 55, "buffer_atomic_smax");
1160 CASE_STR( 56, "buffer_atomic_umax");
1161 CASE_STR( 57, "buffer_atomic_and");
1162 CASE_STR( 58, "buffer_atomic_or");
1163 CASE_STR( 59, "buffer_atomic_xor");
1164 CASE_STR( 60, "buffer_atomic_inc");
1165 CASE_STR( 61, "buffer_atomic_dec");
1166 CASE_STR( 62, "buffer_atomic_fcmpswap");
1167 CASE_STR( 63, "buffer_atomic_fmin");
1168 CASE_STR( 64, "buffer_atomic_fmax");
1169 CASE_STR( 80, "buffer_atomic_swap_x2");
1170 CASE_STR( 81, "buffer_atomic_cmpswap_x2");
1171 CASE_STR( 82, "buffer_atomic_add_x2");
1172 CASE_STR( 83, "buffer_atomic_sub_x2");
1173 CASE_STR( 84, "buffer_atomic_rsub_x2");
1174 CASE_STR( 85, "buffer_atomic_smin_x2");
1175 CASE_STR( 86, "buffer_atomic_umin_x2");
1176 CASE_STR( 87, "buffer_atomic_smax_x2");
1177 CASE_STR( 88, "buffer_atomic_umax_x2");
1178 CASE_STR( 89, "buffer_atomic_and_x2");
1179 CASE_STR( 90, "buffer_atomic_or_x2");
1180 CASE_STR( 91, "buffer_atomic_xor_x2");
1181 CASE_STR( 92, "buffer_atomic_inc_x2");
1182 CASE_STR( 93, "buffer_atomic_dec_x2");
1183 CASE_STR( 94, "buffer_atomic_fcmpswap_x2");
1184 CASE_STR( 95, "buffer_atomic_fmin_x2");
1185 CASE_STR( 96, "buffer_atomic_fmax_x2");
1186 CASE_STR(112, "buffer_wbinvl1_sc");
1187 CASE_STR(113, "buffer_wbinvl1");
1188 default:
1189 pf("unknown_mubuf_op(%u)", op);
1190 break;
1192 return str;
1195 static void mubuf(void)
1197 u8 r;
1198 u32 w1;
1200 u16 offset;
1201 u8 offen;
1202 u8 idxen;
1203 u8 glc;
1204 u8 addr64;
1205 u8 lds;
1206 u8 op;
1207 u8 *op_str;
1208 u8 vaddr;
1209 u8 vdata;
1210 u8 srsrc;
1211 u8 slc;
1212 u8 tfe;
1213 u8 soffset;
1214 u8 *soffset_str;
1216 u32 literal;
1217 bool literal_was_read;
1219 r = read_w(&w1);
1220 if (r != OK) {
1221 out("ERROR:mubuf:missing 2nd instruction word\n");
1222 exit(1);
1225 literal_was_read = false;
1227 offset = (u16)w & 0x0fff; /* 12 bits */
1228 offen = (u8)(w >> 12) & 0x01; /* 1 bit */
1229 idxen = (u8)(w >> 13) & 0x01; /* 1 bit */
1230 glc = (u8)(w >> 14) & 0x01; /* 1 bit */
1231 addr64 = (u8)(w >> 15) & 0x01; /* 1 bit */
1232 lds = (u8)(w >> 16) & 0x01; /* 1 bit */
1233 op = (u8)(w >> 18) & 0x7f; /* 7 bits */
1234 vaddr = (u8)w1 & 0xff; /* 8 bits */
1235 vdata = (u8)(w1 >> 8) & 0xff; /* 8 bits */
1236 srsrc = (u8)(w1 >> 16) & 0x1f; /* 5 bits */
1237 slc = (u8)(w1 >> 22) & 0x01; /* 1 bits */
1238 tfe = (u8)(w1 >> 23) & 0x01; /* 1 bits */
1239 soffset = (u8)(w1 >> 24) & 0xff; /* 8 bits */
1241 op_str = mubuf_op_to_str(op);
1242 soffset_str = s_opd_to_str(soffset, &literal_was_read, &literal);
1244 out("%s offset=%u offen=%u idxen=%u glc=%u addr64=%u lds=%u vaddr=vgpr%u vdata=vgpr%u srsrc=%u(sgpr%u) slc=%u tfe=%u soffset=%s\n", op_str, offset, offen, idxen, glc, addr64, lds, vaddr, vdata, srsrc, srsrc << 2, slc, tfe, soffset_str);
1247 static u8 *mtbuf_op_to_str(u8 op)
1249 static u8 str[STR_SZ_MAX];
1251 switch (op) {
1252 CASE_STR(0, "tbuffer_load_format_x");
1253 CASE_STR(1, "tbuffer_load_format_xy");
1254 CASE_STR(2, "tbuffer_load_format_xyz");
1255 CASE_STR(3, "tbuffer_load_format_xyzw");
1256 CASE_STR(4, "tbuffer_store_format_x");
1257 CASE_STR(5, "tbuffer_store_format_xy");
1258 CASE_STR(6, "tbuffer_store_format_xyz");
1259 CASE_STR(8, "tbuffer_store_format_xyzw");
1260 default:
1261 pf("unknown_mtbuf_op(%u)", op);
1262 break;
1264 return str;
1267 static void mtbuf(void)
1269 u8 r;
1270 u32 w1;
1272 u8 offset;
1273 u8 offen;
1274 u8 idxen;
1275 u8 glc;
1276 u8 addr64;
1277 u8 op;
1278 u8 *op_str;
1279 u8 dfmt;
1280 u8 nfmt;
1281 u8 vaddr;
1282 u8 vdata;
1283 u8 srsrc;
1284 u8 slc;
1285 u8 tfe;
1286 u8 soffset;
1287 u8 *soffset_str;
1289 u32 literal;
1290 bool literal_was_read;
1292 r = read_w(&w1);
1293 if (r != OK) {
1294 out("ERROR:mtbuf:missing 2nd instruction word\n");
1295 exit(1);
1298 literal_was_read = false;
1300 offset = (u16)w & 0x0fff; /* 12 bits */
1301 offen = (u8)(w >> 12) & 0x01; /* 1 bit */
1302 idxen = (u8)(w >> 13) & 0x01; /* 1 bit */
1303 glc = (u8)(w >> 14) & 0x01; /* 1 bit */
1304 addr64 = (u8)(w >> 15) & 0x01; /* 1 bit */
1305 op = (u8)(w >> 16) & 0x07; /* 3 bits */
1306 dfmt = (u8)(w >> 19) & 0x0f; /* 4 bits */
1307 nfmt = (u8)(w >> 23) & 0x07; /* 3 bits */
1308 vaddr = (u8)w1 & 0xff; /* 8 bits */
1309 vdata = (u8)(w1 >> 8) & 0xff; /* 8 bits */
1310 srsrc = (u8)(w1 >> 16) & 0x1f; /* 5 bits */
1311 slc = (u8)(w1 >> 22) & 0x01; /* 1 bits */
1312 tfe = (u8)(w1 >> 23) & 0x01; /* 1 bits */
1313 soffset = (u8)(w1 >> 24) & 0xff; /* 8 bits */
1315 op_str = mtbuf_op_to_str(op);
1316 soffset_str = s_opd_to_str(soffset, &literal_was_read, &literal);
1318 out("%s offset=%u offen=%u idxen=%u glc=%u addr64=%u dfmt=%u nfmt=%u vaddr=vgpr%u vdata=vgpr%u srsrc=%u(sgpr%u) slc=%u tfe=%u soffset=%s\n", op_str, offset, offen, idxen, glc, addr64, dfmt, nfmt, vaddr, vdata, srsrc, srsrc << 2, slc, tfe, soffset_str);
1321 static u8 *mimg_op_to_str(u8 op)
1323 static u8 str[STR_SZ_MAX];
1325 switch (op) {
1326 CASE_STR( 0, "image_load");
1327 CASE_STR( 1, "image_load_mip");
1328 CASE_STR( 2, "image_load_pck");
1329 CASE_STR( 3, "image_load_pck_sgn");
1330 CASE_STR( 4, "image_load_mip_pck");
1331 CASE_STR( 5, "image_load_mip_pck_sgn");
1332 CASE_STR( 8, "image_store");
1333 CASE_STR( 9, "image_store_mip");
1334 CASE_STR( 10, "image_store_pck");
1335 CASE_STR( 11, "image_store_mip_pck");
1336 CASE_STR( 14, "image_res_info");
1337 CASE_STR( 15, "image_atomic_swap");
1338 CASE_STR( 16, "image_atomic_cmpswap");
1339 CASE_STR( 17, "image_atomic_add");
1340 CASE_STR( 18, "image_atomic_sub");
1341 CASE_STR( 19, "image_atomic_rsub");
1342 CASE_STR( 20, "image_atomic_smin");
1343 CASE_STR( 21, "image_atomic_umin");
1344 CASE_STR( 22, "image_atomic_smax");
1345 CASE_STR( 23, "image_atomic_umax");
1346 CASE_STR( 24, "image_atomic_and");
1347 CASE_STR( 25, "image_atomic_or");
1348 CASE_STR( 26, "image_atomic_xor");
1349 CASE_STR( 27, "image_atomic_inc");
1350 CASE_STR( 28, "image_atomic_dec");
1351 CASE_STR( 29, "image_atomic_fcmpswap");
1352 CASE_STR( 30, "image_atomic_fmin");
1353 CASE_STR( 31, "image_atomic_fmax");
1354 CASE_STR( 32, "image_sample");
1355 CASE_STR( 33, "image_sample_cl");
1356 CASE_STR( 34, "image_sample_d");
1357 CASE_STR( 35, "image_sample_d_cl");
1358 CASE_STR( 36, "image_sample_l");
1359 CASE_STR( 37, "image_sample_b");
1360 CASE_STR( 38, "image_sample_b_cl");
1361 CASE_STR( 39, "image_sample_lz");
1362 CASE_STR( 40, "image_sample_c");
1363 CASE_STR( 41, "image_sample_c_cl");
1364 CASE_STR( 42, "image_sample_c_d");
1365 CASE_STR( 43, "image_sample_c_d_cl");
1366 CASE_STR( 44, "image_sample_c_l");
1367 CASE_STR( 45, "image_sample_c_b");
1368 CASE_STR( 46, "image_sample_c_b_cl");
1369 CASE_STR( 47, "image_sample_c_lz");
1370 CASE_STR( 48, "image_sample_o");
1371 CASE_STR( 49, "image_sample_cl_o");
1372 CASE_STR( 50, "image_sample_d_o");
1373 CASE_STR( 51, "image_sample_d_cl_o");
1374 CASE_STR( 52, "image_sample_l_o");
1375 CASE_STR( 53, "image_sample_b_o");
1376 CASE_STR( 54, "image_sample_b_cl_o");
1377 CASE_STR( 55, "image_sample_b_lz_o");
1378 CASE_STR( 56, "image_sample_c_o");
1379 CASE_STR( 57, "image_sample_c_cl_o");
1380 CASE_STR( 58, "image_sample_c_d_o");
1381 CASE_STR( 59, "image_sample_c_d_cl_o");
1382 CASE_STR( 60, "image_sample_c_l_o");
1383 CASE_STR( 61, "image_sample_c_b_o");
1384 CASE_STR( 62, "image_sample_c_b_cl_o");
1385 CASE_STR( 63, "image_sample_c_lz_o");
1386 CASE_STR( 64, "image_gather4");
1387 CASE_STR( 65, "image_gather4_cl");
1388 CASE_STR( 66, "image_gather4_l");
1389 CASE_STR( 67, "image_gather4_b");
1390 CASE_STR( 68, "image_gather4_b_cl");
1391 CASE_STR( 69, "image_gather4_lz");
1392 CASE_STR( 70, "image_gather4_c");
1393 CASE_STR( 71, "image_gather4_c_cl");
1394 CASE_STR( 76, "image_gather4_c_cl");
1395 CASE_STR( 77, "image_gather4_c_b");
1396 CASE_STR( 78, "image_gather4_c_b_cl");
1397 CASE_STR( 79, "image_gather4_c_lz");
1398 CASE_STR( 80, "image_gather4_o");
1399 CASE_STR( 81, "image_gather4_cl_o");
1400 CASE_STR( 84, "image_gather4_l_o");
1401 CASE_STR( 85, "image_gather4_b_o");
1402 CASE_STR( 86, "image_gather4_b_cl_o");
1403 CASE_STR( 87, "image_gather4_lz_o");
1404 CASE_STR( 88, "image_gather4_c_o");
1405 CASE_STR( 89, "image_gather4_c_cl_o");
1406 CASE_STR( 92, "image_gather4_c_l_o");
1407 CASE_STR( 93, "image_gather4_c_b_o");
1408 CASE_STR( 94, "image_gather4_c_b_cl_o");
1409 CASE_STR( 95, "image_gather4_c_lz_o");
1410 CASE_STR( 96, "image_get_lod");
1411 CASE_STR(104, "image_sample_cd");
1412 CASE_STR(105, "image_sample_cd_ld");
1413 CASE_STR(106, "image_sample_c_cd");
1414 CASE_STR(107, "image_sample_c_cd_cl");
1415 CASE_STR(108, "image_sample_cd_o");
1416 CASE_STR(109, "image_sample_cd_cl_o");
1417 CASE_STR(110, "image_sample_c_cd_o");
1418 CASE_STR(111, "image_sample_c_cd_cl_o");
1419 efault:
1420 pf("unknown_mimg_op(%u)", op);
1421 break;
1423 return str;
1426 static void mimg(void)
1428 u8 r;
1429 u32 w1;
1431 u8 dmask;
1432 u8 unorm;
1433 u8 glc;
1434 u8 da;
1435 u8 r128;
1436 u8 tfe;
1437 u8 lwe;
1438 u8 op;
1439 u8 *op_str;
1440 u8 slc;
1441 u8 vaddr;
1442 u8 vdata;
1443 u8 srsrc;
1444 u8 ssamp;
1446 r = read_w(&w1);
1447 if (r != OK) {
1448 out("ERROR:mimg:missing 2nd instruction word\n");
1449 exit(1);
1452 dmask = (u8)(w >> 8) & 0x0f; /* 4 bits */
1453 unorm = (u8)(w >> 12) & 0x01; /* 1 bit */
1454 glc = (u8)(w >> 13) & 0x01; /* 1 bit */
1455 da = (u8)(w >> 14) & 0x01; /* 1 bit */
1456 r128 = (u8)(w >> 15) & 0x01; /* 1 bit */
1457 tfe = (u8)(w >> 16) & 0x01; /* 1 bit */
1458 lwe = (u8)(w >> 17) & 0x01; /* 1 bit */
1459 op = (u8)(w >> 18) & 0xff; /* 8 bits */
1460 slc = (u8)(w >> 25) & 0x01; /* 1 bit */
1461 vaddr = (u8)w1 & 0xff; /* 8 bits */
1462 vdata = (u8)(w1 >> 8) & 0xff; /* 8 bits */
1463 srsrc = (u8)(w1 >> 16) & 0x1f; /* 5 bits */
1464 ssamp = (u8)(w1 >> 21) & 0x1f; /* 5 bits */
1466 op_str = mimg_op_to_str(op);
1468 out("%s dmask=%u unorm=%u glc=%u da=%u r128=%u tfe=%u lwe=%u slc=%u vaddr=vgpr%u vdata=vgpr%u srsrc=%u(sgpr%u) ssamp=%u(sgpr%u)\n", op_str, dmask, unorm, glc, da, r128, tfe, lwe, slc, vaddr, vdata, srsrc, srsrc << 2, ssamp, ssamp << 2);
1471 static u8 *smrd_op_to_str(u8 op)
1473 static u8 str[STR_SZ_MAX];
1475 switch (op) {
1476 CASE_STR( 0,"s_load_dword");
1477 CASE_STR( 1,"s_load_dwordx2");
1478 CASE_STR( 2,"s_load_dwordx4");
1479 CASE_STR( 3,"s_load_dwordx8");
1480 CASE_STR( 4,"s_load_dwordx16");
1481 CASE_STR( 8,"s_buffer_load_dword");
1482 CASE_STR( 9,"s_buffer_load_dwordx2");
1483 CASE_STR(10,"s_buffer_load_dwordx4");
1484 CASE_STR(11,"s_buffer_load_dwordx8");
1485 CASE_STR(12,"s_buffer_load_dwordx16");
1486 CASE_STR(30,"s_memtime");
1487 CASE_STR(31,"s_dcache_inv");
1488 default:
1489 pf("unknown_smrd_op(%u)", op);
1490 break;
1492 return str;
1495 static void smrd(void)
1497 u8 offset;
1498 u8 imm;
1499 u8 sbase;
1500 u8 sdst;
1501 u8 *sdst_str;
1502 u8 op;
1503 u8 *op_str;
1505 u32 literal;
1506 bool literal_was_read;
1508 literal_was_read = false;
1510 offset = (u8)w;
1511 imm = (u8)(w >> 8) & 0x01; /* 1 bit */
1512 sbase = (u8)(w >> 9) & 0x3f; /* 6 bits */
1513 sdst = (u8)(w >> 15) & 0xef; /* 7 bits */
1514 op = (u8)(w >> 22) & 0x1f; /* 5 bits */
1516 sdst_str = s_opd_to_str(sdst, &literal_was_read, &literal);
1517 op_str = smrd_op_to_str(op);
1519 out("%s offset=%u imm=%u sbase=%u sdst=%s\n", op_str, offset, imm, sbase, sdst_str);
1522 static u8 *sopk_op_to_str(u8 op)
1524 static u8 str[STR_SZ_MAX];
1526 switch (op) {
1527 CASE_STR( 0, "s_movk_i32");
1528 CASE_STR( 2, "s_cmovk_i32");
1529 CASE_STR( 3, "s_cmpk_eq_i32");
1530 CASE_STR( 4, "s_cmpk_lg_i32");
1531 CASE_STR( 5, "s_cmpk_gt_i32");
1532 CASE_STR( 6, "s_cmpk_ge_i32");
1533 CASE_STR( 7, "s_cmpk_lt_i32");
1534 CASE_STR( 8, "s_cmpk_le_i32");
1535 CASE_STR( 9, "s_cmpk_eq_u32");
1536 CASE_STR(10, "s_cmpk_lg_u32");
1537 CASE_STR(11, "s_cmpk_gt_u32");
1538 CASE_STR(12, "s_cmpk_ge_u32");
1539 CASE_STR(13, "s_cmpk_lt_u32");
1540 CASE_STR(14, "s_cmpk_le_u32");
1541 CASE_STR(15, "s_addk_i32");
1542 CASE_STR(16, "s_mulk_i32");
1543 CASE_STR(17, "s_cbranch_i_fork");
1544 CASE_STR(18, "s_getreg_b32");
1545 CASE_STR(19, "s_setreg_b32");
1546 CASE_STR(21, "s_setreg_imm32_b32");
1547 default:
1548 pf("unknown_sopk_op(%u)", op);
1549 break; }
1550 return str;
1553 static void sopk(void)
1555 u16 simm16;
1556 u8 *simm16_str;
1557 u8 xdst; /* carefull: actually used as a src or dest */
1558 u8 *xdst_str;
1559 u8 op;
1560 u8 *op_str;
1561 u32 imm32;
1563 u32 literal;
1564 bool literal_was_read;
1566 literal_was_read = false;
1568 simm16 = (u16)w & 0xffff; /* 16 bits */
1569 xdst = (u8)(w >> 16) & 0x7f; /* 7 bits */
1570 op = (u8)(w >> 23) & 0x1f; /* 5 bits */
1572 op_str = sopk_op_to_str(op);
1573 xdst_str = s_opd_to_str(xdst, &literal_was_read, &literal);
1575 out("%s simm16=0x%04x xdst=%s", op_str, simm16, xdst_str);
1577 if (op == 21) { /* s_setreg_imm32_b32 */
1578 u8 r;
1580 r = read_w(&imm32);
1581 if (r != OK) {
1582 out("ERROR:sopk:s_setreg_imm32_b32:missing imm32 word\n");
1583 exit(1);
1585 out("0x%08x\n", imm32);
1586 } else {
1587 out("\n");
1591 static u8 *sop2_op_to_str(u8 op)
1593 static u8 str[STR_SZ_MAX];
1595 switch (op) {
1596 CASE_STR( 0, "s_add_u32");
1597 CASE_STR( 1, "s_sub_u32");
1598 CASE_STR( 2, "s_add_i32");
1599 CASE_STR( 3, "s_sub_i32");
1600 CASE_STR( 4, "s_addc_u32");
1601 CASE_STR( 5, "s_subb_u32");
1602 CASE_STR( 6, "s_min_i32");
1603 CASE_STR( 7, "s_min_u32");
1604 CASE_STR( 8, "s_max_i32");
1605 CASE_STR( 9, "s_max_u32");
1606 CASE_STR(10, "s_cselect_b32");
1607 CASE_STR(11, "s_cselect_b64");
1608 CASE_STR(14, "s_and_b32");
1609 CASE_STR(15, "s_and_b64");
1610 CASE_STR(16, "s_or_b32");
1611 CASE_STR(17, "s_or_b64");
1612 CASE_STR(18, "s_xor_b32");
1613 CASE_STR(19, "s_xor_b64");
1614 CASE_STR(20, "s_andn2_b32");
1615 CASE_STR(21, "s_andn2_b64");
1616 CASE_STR(22, "s_orn2_b32");
1617 CASE_STR(23, "s_orn2_b64");
1618 CASE_STR(24, "s_nand_b32");
1619 CASE_STR(25, "s_nand_b64");
1620 CASE_STR(26, "s_nor_b32");
1621 CASE_STR(27, "s_nor_b64");
1622 CASE_STR(28, "s_xnor_b32");
1623 CASE_STR(29, "s_xnor_b64");
1624 CASE_STR(30, "s_lshl_b32");
1625 CASE_STR(31, "s_lshl_b64");
1626 CASE_STR(32, "s_lshr_b32");
1627 CASE_STR(33, "s_lshr_b64");
1628 CASE_STR(34, "s_ashr_i32");
1629 CASE_STR(35, "s_ashr_i64");
1630 CASE_STR(36, "s_bfm_b32");
1631 CASE_STR(37, "s_bfm_b64");
1632 CASE_STR(38, "s_mul_i32");
1633 CASE_STR(39, "s_bfe_u32");
1634 CASE_STR(40, "s_bfe_i32");
1635 CASE_STR(41, "s_bfe_u64");
1636 CASE_STR(42, "s_bfe_i64");
1637 CASE_STR(43, "s_cbranch_g_fork");
1638 CASE_STR(44, "s_absdiff_i32");
1639 default:
1640 pf("unknown_sop2_op(%u)", op);
1641 break;
1643 return str;
1646 static void sop2(void)
1648 u8 ssrc0;
1649 u8 *ssrc0_str;
1650 u8 ssrc1;
1651 u8 *ssrc1_str;
1652 u8 sdst;
1653 u8 *sdst_str;
1654 u8 op;
1655 u8 *op_str;
1657 u32 literal;
1658 bool literal_was_read;
1660 literal_was_read = false;
1662 ssrc0 = (u8)w & 0xff; /* 8 bits */
1663 ssrc1 = (u8)(w >> 8) & 0xff; /* 8 bits */
1664 sdst = (u8)(w >> 16) & 0x7f; /* 8 bits */
1666 ssrc0_str = s_opd_to_str(ssrc0, &literal_was_read, &literal);
1667 ssrc1_str = s_opd_to_str(ssrc0, &literal_was_read, &literal);
1668 sdst_str = s_opd_to_str(ssrc0, &literal_was_read, &literal);
1669 op_str = sop2_op_to_str(op);
1671 out("%s ssrc0=%s ssrc1=%s sdst=%s\n", op_str, ssrc0_str, ssrc1_str, sdst_str);
1674 static u8 *vop2_op_to_str(u8 op)
1676 static u8 str[STR_SZ_MAX];
1678 if (op <= 36) {
1679 strcpy(str, v_op_blk_0_to_str(op));
1680 goto exit;
1682 if (37 <= op && op <= 42) {
1683 strcpy(str, v_op_blk_1_to_str(op - 37));
1684 goto exit;
1686 if (43 <= op && op <= 49) {
1687 strcpy(str, v_op_blk_2_to_str(op - 43));
1688 goto exit;
1690 pf("unknown_vop2_op(%u)", op);
1691 exit:
1692 return str;
1695 static void vop2(void)
1697 u16 src0;
1698 u8 *src0_str;
1699 u8 vsrc1;
1700 u8 vdst;
1701 u8 op;
1702 u8 *op_str;
1704 u32 literal;
1705 bool literal_was_read;
1707 literal_was_read = false;
1709 src0 = (u16)w & 0x01ff; /* 9 bits */
1710 vsrc1 = (u8)(w >> 9) & 0xff; /* 8 bits */
1711 vdst = (u8)(w >> 17) & 0xff; /* 8 bits */
1712 op = (u8)(w >> 25) & 0x3f; /* 6 bits */
1714 src0_str = v_opd_to_str(src0, &literal_was_read, &literal);
1715 op_str = vop2_op_to_str(op);
1717 out("%s src0=%s vsrc1=vgpr%u vdst=vgpr%u\n", op_str, src0_str, vsrc1, vdst);
1720 static void microcode_route(void)
1722 if ((w & 0xff800000) == 0xbe800000) /* 9 bits */
1723 sop1();
1724 else if ((w & 0xff800000) == 0xbf000000) /* 9 bits */
1725 sopc();
1726 /*-------------------------------------------------*/
1727 else if ((w & 0xfe000000) == 0xee000000) /* 7 bits */
1728 vop1();
1729 else if ((w & 0xfe000000) == 0x7b000000) /* 7 bits */
1730 vopc();
1731 else if ((w & 0xfe000000) == 0x76000000) /* 7 bits */
1732 export();
1733 /*-------------------------------------------------*/
1734 else if ((w & 0xfc000000) == 0xc8000000) /* 6 bits */
1735 vintrp();
1736 else if ((w & 0xfc000000) == 0xd4000000) /* 6 bits */
1737 vop3();
1738 else if ((w & 0xfc000000) == 0xd8000000) /* 6 bits */
1739 ds();
1740 else if ((w & 0xfc000000) == 0xe0000000) /* 6 bits */
1741 mubuf();
1742 else if ((w & 0xfc000000) == 0xe8000000) /* 6 bits */
1743 mtbuf();
1744 else if ((w & 0xfc000000) == 0xf0000000) /* 6 bits */
1745 mimg();
1746 /*-------------------------------------------------*/
1747 else if ((w & 0xf8000000) == 0xc0000000) /* 5 bits */
1748 smrd();
1749 /*-------------------------------------------------*/
1750 else if ((w & 0xf0000000) == 0xb0000000) /* 4 bits */
1751 sopk();
1752 /*-------------------------------------------------*/
1753 else if ((w & 0xc0000000) == 0x80000000) /* 2 bits */
1754 sop2();
1755 /*-------------------------------------------------*/
1756 else if ((w & 0x80000000) == 0x00000000) /* 1 bit */
1757 vop2();
1759 #undef MATCH
1761 int main(void)
1763 u8 r;
1764 clearerr(stdin);
1765 loop {
1766 r = read_w(&w);
1767 if (r != OK)
1768 exit(0);
1770 microcode_route();