diff options
Diffstat (limited to 'src/gallium/drivers/freedreno/ir3/disasm-a3xx.c')
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/disasm-a3xx.c | 74 |
1 files changed, 64 insertions, 10 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c b/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c index 96b34649c37..4cb174cb2a4 100644 --- a/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c +++ b/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c @@ -520,7 +520,9 @@ static void print_instr_cat6(instr_t *instr) switch (_OPC(6, cat6->opc)) { case OPC_PREFETCH: + break; case OPC_RESINFO: + printf(".%dd", cat6->ldgb.d + 1); break; case OPC_LDGB: printf(".%s", cat6->ldgb.typed ? "typed" : "untyped"); @@ -529,6 +531,7 @@ static void print_instr_cat6(instr_t *instr) printf(".%d", cat6->ldgb.type_size + 1); break; case OPC_STGB: + case OPC_STIB: printf(".%s", cat6->stgb.typed ? "typed" : "untyped"); printf(".%dd", cat6->stgb.d + 1); printf(".%s", type[cat6->type]); @@ -546,8 +549,11 @@ static void print_instr_cat6(instr_t *instr) case OPC_ATOMIC_OR: case OPC_ATOMIC_XOR: ss = cat6->g ? 'g' : 'l'; - printf(".%c", ss); + printf(".%s", cat6->ldgb.typed ? "typed" : "untyped"); + printf(".%dd", cat6->ldgb.d + 1); printf(".%s", type[cat6->type]); + printf(".%d", cat6->ldgb.type_size + 1); + printf(".%c", ss); break; default: dst.im = cat6->g && !cat6->dst_off; @@ -601,7 +607,7 @@ static void print_instr_cat6(instr_t *instr) break; } - if (_OPC(6, cat6->opc) == OPC_STGB) { + if ((_OPC(6, cat6->opc) == OPC_STGB) || (_OPC(6, cat6->opc) == OPC_STIB)) { struct reginfo src3; memset(&src3, 0, sizeof(src3)); @@ -626,7 +632,7 @@ static void print_instr_cat6(instr_t *instr) return; } - if ((_OPC(6, cat6->opc) == OPC_LDGB) || is_atomic(_OPC(6, cat6->opc))) { + if (is_atomic(_OPC(6, cat6->opc))) { src1.reg = (reg_t)(cat6->ldgb.src1); src1.im = cat6->ldgb.src1_im; @@ -636,21 +642,69 @@ static void print_instr_cat6(instr_t *instr) print_src(&dst); printf(", "); - printf("g[%u], ", cat6->ldgb.src_ssbo); - print_src(&src1); - printf(", "); - print_src(&src2); - - if (is_atomic(_OPC(6, cat6->opc))) { + if (ss == 'g') { struct reginfo src3; memset(&src3, 0, sizeof(src3)); + src3.reg = (reg_t)(cat6->ldgb.src3); src3.full = true; + /* For images, the ".typed" variant is used and src2 is + * the ivecN coordinates, ie ivec2 for 2d. + * + * For SSBOs, the ".untyped" variant is used and src2 is + * a simple dword offset.. src3 appears to be + * uvec2(offset * 4, 0). Not sure the point of that. + */ + + printf("g[%u], ", cat6->ldgb.src_ssbo); + print_src(&src1); /* value */ printf(", "); - print_src(&src3); + print_src(&src2); /* offset/coords */ + printf(", "); + print_src(&src3); /* 64b byte offset.. */ + + if (debug & PRINT_VERBOSE) { + printf(" (pad0=%x, pad3=%x, mustbe0=%x)", cat6->ldgb.pad0, + cat6->ldgb.pad3, cat6->ldgb.mustbe0); + } + } else { /* ss == 'l' */ + printf("l["); + print_src(&src1); /* simple byte offset */ + printf("], "); + print_src(&src2); /* value */ + + if (debug & PRINT_VERBOSE) { + printf(" (src3=%x, pad0=%x, pad3=%x, mustbe0=%x)", + cat6->ldgb.src3, cat6->ldgb.pad0, + cat6->ldgb.pad3, cat6->ldgb.mustbe0); + } } + return; + } else if (_OPC(6, cat6->opc) == OPC_RESINFO) { + dst.reg = (reg_t)(cat6->ldgb.dst); + + print_src(&dst); + printf(", "); + printf("g[%u]", cat6->ldgb.src_ssbo); + + return; + } else if (_OPC(6, cat6->opc) == OPC_LDGB) { + + src1.reg = (reg_t)(cat6->ldgb.src1); + src1.im = cat6->ldgb.src1_im; + src2.reg = (reg_t)(cat6->ldgb.src2); + src2.im = cat6->ldgb.src2_im; + dst.reg = (reg_t)(cat6->ldgb.dst); + + print_src(&dst); + printf(", "); + printf("g[%u], ", cat6->ldgb.src_ssbo); + print_src(&src1); + printf(", "); + print_src(&src2); + if (debug & PRINT_VERBOSE) printf(" (pad0=%x, pad3=%x, mustbe0=%x)", cat6->ldgb.pad0, cat6->ldgb.pad3, cat6->ldgb.mustbe0); |