summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/freedreno/ir3/disasm-a3xx.c')
-rw-r--r--src/gallium/drivers/freedreno/ir3/disasm-a3xx.c74
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);