summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2017-10-30 19:24:59 -0400
committerRob Clark <[email protected]>2017-11-12 12:28:59 -0500
commit6da513007474ddee48edf256e435a0fa7a65335d (patch)
treeb9627059f5b8055f60d7c2c4d2eae737471c0a86
parent33f5f63b8fc157fa2fd2a142783f31db987c9d55 (diff)
freedreno/ir3: add cat7 instructions
Needed for memory and execution barriers. Signed-off-by: Rob Clark <[email protected]>
-rw-r--r--src/gallium/drivers/freedreno/ir3/disasm-a3xx.c21
-rw-r--r--src/gallium/drivers/freedreno/ir3/instr-a3xx.h26
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3.c19
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3.h15
4 files changed, 79 insertions, 2 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c b/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c
index 4685ed6deae..96b34649c37 100644
--- a/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c
+++ b/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c
@@ -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)");
diff --git a/src/gallium/drivers/freedreno/ir3/instr-a3xx.h b/src/gallium/drivers/freedreno/ir3/instr-a3xx.h
index b429b3b9ffc..9edcc58ce9c 100644
--- a/src/gallium/drivers/freedreno/ir3/instr-a3xx.h
+++ b/src/gallium/drivers/freedreno/ir3/instr-a3xx.h
@@ -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;
}
}
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.c b/src/gallium/drivers/freedreno/ir3/ir3.c
index d703f4e7f38..61bc3b5ad47 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3.c
@@ -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,
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h
index de7a2a88733..25fddbf00f4 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3.h
@@ -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.. */