freedreno/ir3: add cat7 instructions
authorRob Clark <robdclark@gmail.com>
Mon, 30 Oct 2017 23:24:59 +0000 (19:24 -0400)
committerRob Clark <robdclark@gmail.com>
Sun, 12 Nov 2017 17:28:59 +0000 (12:28 -0500)
Needed for memory and execution barriers.

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

index 4685ed6deae32fc9a2e323803aa2c18e3b05a9a3..96b34649c37815e05d2e39438338c93284e76cd2 100644 (file)
@@ -714,6 +714,23 @@ static void print_instr_cat6(instr_t *instr)
        }
 }
 
+static void print_instr_cat7(instr_t *instr)
+{
+       instr_cat7_t *cat7 = &instr->cat7;
+
+       if (cat7->g)
+               printf(".g");
+       if (cat7->l)
+               printf(".l");
+
+       if (_OPC(7, cat7->opc) == OPC_FENCE) {
+               if (cat7->r)
+                       printf(".r");
+               if (cat7->w)
+                       printf(".w");
+       }
+}
+
 /* size of largest OPC field of all the instruction categories: */
 #define NOPC_BITS 6
 
@@ -879,6 +896,8 @@ static const struct opc_info {
        OPC(6, OPC_LDC,          ldc),
        OPC(6, OPC_LDLV,         ldlv),
 
+       OPC(7, OPC_BAR,          bar),
+       OPC(7, OPC_FENCE,        fence),
 
 #undef OPC
 };
@@ -909,7 +928,7 @@ static void print_instr(uint32_t *dwords, int level, int n)
 
        if (instr->sync)
                printf("(sy)");
-       if (instr->ss && (instr->opc_cat <= 4))
+       if (instr->ss && ((instr->opc_cat <= 4) || (instr->opc_cat == 7)))
                printf("(ss)");
        if (instr->jmp_tgt)
                printf("(jp)");
index b429b3b9ffcccc91a3f802531cbb32f341798ef4..9edcc58ce9c169a719df4e63c535e907f9fe7d87 100644 (file)
@@ -195,6 +195,10 @@ typedef enum {
        OPC_LDC             = _OPC(6, 30),
        OPC_LDLV            = _OPC(6, 31),
 
+       /* category 7: */
+       OPC_BAR             = _OPC(7, 0),
+       OPC_FENCE           = _OPC(7, 1),
+
        /* meta instructions (category -1): */
        /* placeholder instr to mark shader inputs: */
        OPC_META_INPUT      = _OPC(-1, 0),
@@ -715,6 +719,24 @@ typedef union PACKED {
        };
 } instr_cat6_t;
 
+typedef struct PACKED {
+       /* dword0: */
+       uint32_t pad1     : 32;
+
+       /* dword1: */
+       uint32_t pad2     : 12;
+       uint32_t ss       : 1;  /* maybe in the encoding, but blob only uses (sy) */
+       uint32_t pad3     : 6;
+       uint32_t w        : 1;  /* write */
+       uint32_t r        : 1;  /* read */
+       uint32_t l        : 1;  /* local */
+       uint32_t g        : 1;  /* global */
+       uint32_t opc      : 4;  /* presumed, but only a couple known OPCs */
+       uint32_t jmp_tgt  : 1;  /* (jp) */
+       uint32_t sync     : 1;  /* (sy) */
+       uint32_t opc_cat  : 3;
+} instr_cat7_t;
+
 typedef union PACKED {
        instr_cat0_t cat0;
        instr_cat1_t cat1;
@@ -723,12 +745,13 @@ typedef union PACKED {
        instr_cat4_t cat4;
        instr_cat5_t cat5;
        instr_cat6_t cat6;
+       instr_cat7_t cat7;
        struct PACKED {
                /* dword0: */
                uint64_t pad1     : 40;
                uint32_t repeat   : 3;  /* cat0-cat4 */
                uint32_t pad2     : 1;
-               uint32_t ss       : 1;  /* cat1-cat4 (cat0??) */
+               uint32_t ss       : 1;  /* cat1-cat4 (cat0??) and cat7 (?) */
                uint32_t ul       : 1;  /* cat2-cat4 (and cat1 in blob.. which may be bug??) */
                uint32_t pad3     : 13;
                uint32_t jmp_tgt  : 1;
@@ -748,6 +771,7 @@ static inline uint32_t instr_opc(instr_t *instr)
        case 4:  return instr->cat4.opc;
        case 5:  return instr->cat5.opc;
        case 6:  return instr->cat6.opc;
+       case 7:  return instr->cat7.opc;
        default: return 0;
        }
 }
index d703f4e7f38eb2f903a4a1963670bf5b1ad20ba6..61bc3b5ad47f928b5440da998c5380ecbeb3d90b 100644 (file)
@@ -604,9 +604,28 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr,
        return 0;
 }
 
+static int emit_cat7(struct ir3_instruction *instr, void *ptr,
+               struct ir3_info *info)
+{
+       instr_cat7_t *cat7 = ptr;
+
+       cat7->ss      = !!(instr->flags & IR3_INSTR_SS);
+       cat7->w       = instr->cat7.w;
+       cat7->r       = instr->cat7.r;
+       cat7->l       = instr->cat7.l;
+       cat7->g       = instr->cat7.g;
+       cat7->opc     = instr->opc;
+       cat7->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
+       cat7->sync    = !!(instr->flags & IR3_INSTR_SY);
+       cat7->opc_cat = 7;
+
+       return 0;
+}
+
 static int (*emit[])(struct ir3_instruction *instr, void *ptr,
                struct ir3_info *info) = {
        emit_cat0, emit_cat1, emit_cat2, emit_cat3, emit_cat4, emit_cat5, emit_cat6,
+       emit_cat7,
 };
 
 void * ir3_assemble(struct ir3 *shader, struct ir3_info *info,
index de7a2a887333c4e781501e3154ebb7d220516fa5..25fddbf00f4772102cbdce36e43db99c2f724108 100644 (file)
@@ -228,6 +228,12 @@ struct ir3_instruction {
                        int dst_offset;
                        int iim_val;          /* for ldgb/stgb, # of components */
                } cat6;
+               struct {
+                       unsigned w : 1;       /* write */
+                       unsigned r : 1;       /* read */
+                       unsigned l : 1;       /* local */
+                       unsigned g : 1;       /* global */
+               } cat7;
                /* for meta-instructions, just used to hold extra data
                 * before instruction scheduling, etc
                 */
@@ -605,6 +611,11 @@ static inline bool is_mem(struct ir3_instruction *instr)
        return (opc_cat(instr->opc) == 6);
 }
 
+static inline bool is_barrier(struct ir3_instruction *instr)
+{
+       return (opc_cat(instr->opc) == 7);
+}
+
 static inline bool
 is_store(struct ir3_instruction *instr)
 {
@@ -1179,6 +1190,10 @@ INSTR4(ATOMIC_AND);
 INSTR4(ATOMIC_OR);
 INSTR4(ATOMIC_XOR);
 
+/* cat7 instructions: */
+INSTR0(BAR);
+INSTR0(FENCE);
+
 /* ************************************************************************* */
 /* split this out or find some helper to use.. like main/bitset.h.. */