case OPC_STG:
case OPC_STL:
case OPC_STP:
- case OPC_STI:
case OPC_STLW:
case OPC_STIB:
dst.full = true;
ss = 'g';
nodst = true;
break;
-
- case OPC_STI:
- dst.full = false; // XXX or inverts??
- break;
}
if ((_OPC(6, cat6->opc) == OPC_STGB) || (_OPC(6, cat6->opc) == OPC_STIB)) {
{
instr_cat6_a6xx_t *cat6 = &instr->cat6_a6xx;
struct reginfo src1, src2;
+ bool has_dest = _OPC(6, cat6->opc) == OPC_LDIB;
char ss = 0;
memset(&src1, 0, sizeof(src1));
fprintf(ctx->out, ".%s", type[cat6->type]);
fprintf(ctx->out, ".%u ", cat6->type_size + 1);
+ if (has_dest) {
+ src2.reg = (reg_t)(cat6->src2);
+ src2.full = true; // XXX
+ print_src(ctx, &src2);
+
+ fprintf(ctx->out, ", ");
+ }
+
/* NOTE: blob seems to use old encoding for ldl/stl (local memory) */
ss = 'g';
src1.reg = (reg_t)(cat6->src1);
src1.full = true; // XXX
print_src(ctx, &src1);
- fprintf(ctx->out, ", ");
- src2.reg = (reg_t)(cat6->src2);
- src2.full = true; // XXX
- print_src(ctx, &src2);
+ if (!has_dest) {
+ fprintf(ctx->out, ", ");
+
+ src2.reg = (reg_t)(cat6->src2);
+ src2.full = true; // XXX
+ print_src(ctx, &src2);
+ }
if (debug & PRINT_VERBOSE) {
fprintf(ctx->out, " (pad1=%x, pad2=%x, pad3=%x, pad4=%x)", cat6->pad1,
OPC(6, OPC_STG, stg),
OPC(6, OPC_STL, stl),
OPC(6, OPC_STP, stp),
- OPC(6, OPC_STI, sti),
+ OPC(6, OPC_LDIB, ldib),
OPC(6, OPC_G2L, g2l),
OPC(6, OPC_L2G, l2g),
OPC(6, OPC_PREFETCH, prefetch),
OPC_STG = _OPC(6, 3), /* store-global */
OPC_STL = _OPC(6, 4),
OPC_STP = _OPC(6, 5),
- OPC_STI = _OPC(6, 6),
+ OPC_LDIB = _OPC(6, 6),
OPC_G2L = _OPC(6, 7),
OPC_L2G = _OPC(6, 8),
OPC_PREFETCH = _OPC(6, 9),
* src1 - vecN offset/coords
* src2 - value to store
*
+ * For ldib:
+ * pad1=1, pad2=c, pad3=0, pad4=2
+ * src1 - vecN offset/coords
+ *
* for ldc (load from UBO using descriptor):
* pad1=0, pad2=8, pad3=0, pad4=2
*/
uint32_t src1 : 8; /* coordinate/offset */
/* dword1: */
- uint32_t src2 : 8;
+ uint32_t src2 : 8; /* or the dst for load instructions */
uint32_t pad3 : 1; //mustbe0 ?? or zero means imm vs reg for ssbo??
uint32_t ssbo : 8; /* ssbo/image binding point */
uint32_t type : 3;
{
struct ir3_register *src1, *src2;
instr_cat6_a6xx_t *cat6 = ptr;
+ bool has_dest = (instr->opc == OPC_LDIB);
/* first reg should be SSBO binding point: */
iassert(instr->regs[1]->flags & IR3_REG_IMMED);
src1 = instr->regs[2];
- src2 = instr->regs[3];
+
+ if (has_dest) {
+ /* the src2 field in the instruction is actually the destination
+ * register for load instructions:
+ */
+ src2 = instr->regs[0];
+ } else {
+ src2 = instr->regs[3];
+ }
cat6->type = instr->cat6.type;
cat6->d = instr->cat6.d - 1;
cat6->pad3 = 0x0;
cat6->pad4 = 0x2;
break;
+ case OPC_LDIB:
+ cat6->pad1 = 0x1;
+ cat6->pad2 = 0xc;
+ cat6->pad3 = 0x0;
+ cat6->pad4 = 0x2;
+ break;
case OPC_LDC:
cat6->pad1 = 0x0;
cat6->pad2 = 0x8;
break;
/* fallthrough */
case OPC_STIB:
+ case OPC_LDIB:
case OPC_LDC:
return emit_cat6_a6xx(instr, ptr, info);
default:
case OPC_STG:
case OPC_STL:
case OPC_STP:
- case OPC_STI:
case OPC_STLW:
case OPC_STIB:
/* no dst, so regs[0] is dummy */