break;
case OPC_BR:
printf(" %sp0.%c, #%d", cat0->inv ? "!" : "",
- component[cat0->comp], cat0->a3xx.immed);
+ component[cat0->comp], cat0->a5xx.immed);
break;
case OPC_JUMP:
case OPC_CALL:
- printf(" #%d", cat0->a3xx.immed);
+ printf(" #%d", cat0->a5xx.immed);
break;
}
- if ((debug & PRINT_VERBOSE) && (cat0->a3xx.dummy1|cat0->dummy2|cat0->dummy3|cat0->dummy4))
- printf("\t{0: %x,%x,%x,%x}", cat0->a3xx.dummy1, cat0->dummy2, cat0->dummy3, cat0->dummy4);
+ if ((debug & PRINT_VERBOSE) && (cat0->dummy2|cat0->dummy3|cat0->dummy4))
+ printf("\t{0: %x,%x,%x}", cat0->dummy2, cat0->dummy3, cat0->dummy4);
}
static void print_instr_cat1(instr_t *instr)
case OPC_STP:
case OPC_STI:
case OPC_STLW:
- case OPC_STGB_4D_4:
case OPC_STIB:
dst.full = true;
src1.full = type_size(cat6->type) == 32;
case OPC_PREFETCH:
case OPC_RESINFO:
break;
+ case OPC_LDGB:
+ 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);
+ break;
+ case OPC_STGB:
+ printf(".%s", cat6->stgb.typed ? "typed" : "untyped");
+ printf(".%dd", cat6->stgb.d + 1);
+ printf(".%s", type[cat6->type]);
+ printf(".%d", cat6->stgb.type_size + 1);
+ break;
case OPC_ATOMIC_ADD:
case OPC_ATOMIC_SUB:
case OPC_ATOMIC_XCHG:
break;
case OPC_LDG:
+ case OPC_LDC:
ss = 'g';
break;
case OPC_LDP:
break;
}
+ if (_OPC(6, cat6->opc) == OPC_STGB) {
+ struct reginfo src3;
+
+ memset(&src3, 0, sizeof(src3));
+
+ src1.reg = (reg_t)(cat6->stgb.src1);
+ src2.reg = (reg_t)(cat6->stgb.src2);
+ src2.im = cat6->stgb.src2_im;
+ src3.reg = (reg_t)(cat6->stgb.src3);
+ src3.im = cat6->stgb.src3_im;
+ src3.full = true;
+
+ printf("g[%u], ", cat6->stgb.dst_ssbo);
+ print_src(&src1);
+ printf(", ");
+ print_src(&src2);
+ printf(", ");
+ print_src(&src3);
+
+ if (debug & PRINT_VERBOSE)
+ printf(" (pad0=%x, pad3=%x)", cat6->stgb.pad0, cat6->stgb.pad3);
+
+ return;
+ }
+
+ if ((_OPC(6, cat6->opc) == OPC_LDGB) || is_atomic(_OPC(6, cat6->opc))) {
+
+ 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 (is_atomic(_OPC(6, cat6->opc))) {
+ struct reginfo src3;
+ memset(&src3, 0, sizeof(src3));
+ src3.reg = (reg_t)(cat6->ldgb.src3);
+ src3.full = true;
+
+ printf(", ");
+ print_src(&src3);
+ }
+
+ if (debug & PRINT_VERBOSE)
+ printf(" (pad0=%x, pad3=%x, mustbe0=%x)", cat6->ldgb.pad0, cat6->ldgb.pad3, cat6->ldgb.mustbe0);
+
+ return;
+ }
if (cat6->dst_off) {
dst.reg = (reg_t)(cat6->c.dst);
dstoff = cat6->c.off;
OPC(6, OPC_ATOMIC_AND, atomic.and),
OPC(6, OPC_ATOMIC_OR, atomic.or),
OPC(6, OPC_ATOMIC_XOR, atomic.xor),
- OPC(6, OPC_LDGB_TYPED_4D, ldgb.typed.3d),
- OPC(6, OPC_STGB_4D_4, stgb.4d.4),
+ OPC(6, OPC_LDGB, ldgb),
+ OPC(6, OPC_STGB, stgb),
OPC(6, OPC_STIB, stib),
- OPC(6, OPC_LDC_4, ldc.4),
+ OPC(6, OPC_LDC, ldc),
OPC(6, OPC_LDLV, ldlv),
OPC_ATOMIC_AND = _OPC(6, 24),
OPC_ATOMIC_OR = _OPC(6, 25),
OPC_ATOMIC_XOR = _OPC(6, 26),
- OPC_LDGB_TYPED_4D = _OPC(6, 27),
- OPC_STGB_4D_4 = _OPC(6, 28),
+ OPC_LDGB = _OPC(6, 27),
+ OPC_STGB = _OPC(6, 28),
OPC_STIB = _OPC(6, 29),
- OPC_LDC_4 = _OPC(6, 30),
+ OPC_LDC = _OPC(6, 30),
OPC_LDLV = _OPC(6, 31),
/* meta instructions (category -1): */
uint32_t dst : 8;
uint32_t mustbe0 : 1;
- uint32_t pad0 : 23;
+ uint32_t idx : 8;
+ uint32_t pad0 : 15;
} instr_cat6d_t;
-/* I think some of the other cat6 instructions use additional
- * sub-encodings..
+/* ldgb and atomics.. atomics use 3rd src and pad0=1, pad3=3. For
+ * ldgb pad0=0, pad3=2
*/
+typedef struct PACKED {
+ /* dword0: */
+ uint32_t pad0 : 1;
+ uint32_t src3 : 8;
+ uint32_t d : 2;
+ uint32_t typed : 1;
+ uint32_t type_size : 2;
+ uint32_t src1 : 8;
+ uint32_t src1_im : 1;
+ uint32_t src2_im : 1;
+ uint32_t src2 : 8;
+
+ /* dword1: */
+ uint32_t dst : 8;
+ uint32_t mustbe0 : 1;
+ uint32_t src_ssbo : 8;
+ uint32_t pad2 : 3; // type
+ uint32_t pad3 : 2;
+ uint32_t pad4 : 10; // opc/jmp_tgt/sync/opc_cat
+} instr_cat6ldgb_t;
+
+/* stgb, pad0=0, pad3=2
+ */
+typedef struct PACKED {
+ /* dword0: */
+ uint32_t mustbe1 : 1; // ???
+ uint32_t src1 : 8;
+ uint32_t d : 2;
+ uint32_t typed : 1;
+ uint32_t type_size : 2;
+ uint32_t pad0 : 9;
+ uint32_t src2_im : 1;
+ uint32_t src2 : 8;
+
+ /* dword1: */
+ uint32_t src3 : 8;
+ uint32_t src3_im : 1;
+ uint32_t dst_ssbo : 8;
+ uint32_t pad2 : 3; // type
+ uint32_t pad3 : 2;
+ uint32_t pad4 : 10; // opc/jmp_tgt/sync/opc_cat
+} instr_cat6stgb_t;
typedef union PACKED {
instr_cat6a_t a;
instr_cat6b_t b;
instr_cat6c_t c;
instr_cat6d_t d;
+ instr_cat6ldgb_t ldgb;
+ instr_cat6stgb_t stgb;
struct PACKED {
/* dword0: */
uint32_t src_off : 1;
}
}
+static inline bool is_atomic(opc_t opc)
+{
+ switch (opc) {
+ case OPC_ATOMIC_ADD:
+ case OPC_ATOMIC_SUB:
+ case OPC_ATOMIC_XCHG:
+ case OPC_ATOMIC_INC:
+ case OPC_ATOMIC_DEC:
+ case OPC_ATOMIC_CMPXCHG:
+ case OPC_ATOMIC_MIN:
+ case OPC_ATOMIC_MAX:
+ case OPC_ATOMIC_AND:
+ case OPC_ATOMIC_OR:
+ case OPC_ATOMIC_XOR:
+ return true;
+ default:
+ return false;
+ }
+}
+
#endif /* INSTR_A3XX_H_ */