freedreno/ir3: sync instr/disasm and add ldib encoding
authorRob Clark <robdclark@gmail.com>
Wed, 20 Feb 2019 15:21:18 +0000 (10:21 -0500)
committerRob Clark <robdclark@gmail.com>
Wed, 20 Feb 2019 23:50:08 +0000 (18:50 -0500)
Resync disasm and instr header from envytools, and add ldib encoding.
This replaces an opcode from a3xx which was never seen in practice,
since that seemed easier than dealing with the same opc # meaning a
different thing on a6xx.  (Not really sure if 'sti' was actually a
real thing, I think it was only seen in fuzzing.)

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/freedreno/ir3/disasm-a3xx.c
src/freedreno/ir3/instr-a3xx.h
src/freedreno/ir3/ir3.c
src/freedreno/ir3/ir3.h

index 9c0432c67ab7b1cf8a69204574267a2601b20792..b857b381212044e508aa47ea01276e87abaa3e88 100644 (file)
@@ -520,7 +520,6 @@ static void print_instr_cat6_a3xx(struct disasm_ctx *ctx, instr_t *instr)
        case OPC_STG:
        case OPC_STL:
        case OPC_STP:
-       case OPC_STI:
        case OPC_STLW:
        case OPC_STIB:
                dst.full  = true;
@@ -617,10 +616,6 @@ static void print_instr_cat6_a3xx(struct disasm_ctx *ctx, instr_t *instr)
                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)) {
@@ -788,6 +783,7 @@ static void print_instr_cat6_a6xx(struct disasm_ctx *ctx, instr_t *instr)
 {
        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));
@@ -798,6 +794,14 @@ static void print_instr_cat6_a6xx(struct disasm_ctx *ctx, instr_t *instr)
        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';
 
@@ -806,11 +810,14 @@ static void print_instr_cat6_a6xx(struct disasm_ctx *ctx, instr_t *instr)
        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,
@@ -990,7 +997,7 @@ static const struct opc_info {
        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),
index eff720dacd548fe497ca7893421342ca59c73cd7..9e83e04c816f5a00f342514ea234add5e79f054a 100644 (file)
@@ -172,7 +172,7 @@ typedef enum {
        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),
@@ -741,6 +741,10 @@ typedef union PACKED {
  *    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
  */
@@ -755,7 +759,7 @@ typedef struct PACKED {
        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;
index 8c28e05f19e206cb390e51fdb2ae3852f4290d6f..a4de1d3ab493e8c3da314092ea64b27c7d017cbc 100644 (file)
@@ -485,12 +485,21 @@ static int emit_cat6_a6xx(struct ir3_instruction *instr, void *ptr,
 {
        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;
@@ -528,6 +537,12 @@ static int emit_cat6_a6xx(struct ir3_instruction *instr, void *ptr,
                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;
@@ -568,6 +583,7 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr,
                                break;
                        /* fallthrough */
                case OPC_STIB:
+               case OPC_LDIB:
                case OPC_LDC:
                        return emit_cat6_a6xx(instr, ptr, info);
                default:
@@ -598,7 +614,6 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr,
        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 */
index 918fce833f2d29c49b1f73dfb4a99a57bfea77d1..36d645f0b50caff025754084950fb88ee1eff0f4 100644 (file)
@@ -688,6 +688,7 @@ static inline bool is_load(struct ir3_instruction *instr)
        switch (instr->opc) {
        case OPC_LDG:
        case OPC_LDGB:
+       case OPC_LDIB:
        case OPC_LDL:
        case OPC_LDP:
        case OPC_L2G:
@@ -1360,6 +1361,7 @@ INSTR2(ATOMIC_OR)
 INSTR2(ATOMIC_XOR)
 #if GPU >= 600
 INSTR3(STIB);
+INSTR2(LDIB);
 INSTR3F(G, ATOMIC_ADD)
 INSTR3F(G, ATOMIC_SUB)
 INSTR3F(G, ATOMIC_XCHG)