freedreno/ir3: add cat7 instructions

Needed for memory and execution barriers.

Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
Rob Clark 2017-10-30 19:24:59 -04:00
parent 33f5f63b8f
commit 6da5130074
4 changed files with 79 additions and 2 deletions

View 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)");

View 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;
}
}

View 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,

View 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.. */