freedreno/ir3: Various cat0 updates
Update the IR and packer to handle the additional cat0 fields, in prep for adding support in the assembler (in prep for adding round trip parsing/packing test coverage). We don't actually use these yet from the ir3 compiler, but at least this is one less thing to worry about when we start trying to use them. Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8175>
This commit is contained in:
@@ -412,8 +412,8 @@ static void print_instr_cat0(struct disasm_ctx *ctx, instr_t *instr)
|
||||
case OPC_KILL:
|
||||
case OPC_PREDT:
|
||||
case OPC_PREDF:
|
||||
fprintf(ctx->out, " %sp0.%c", cat0->inv0 ? "!" : "",
|
||||
component[cat0->comp0]);
|
||||
fprintf(ctx->out, " %sp0.%c", cat0->inv1 ? "!" : "",
|
||||
component[cat0->comp1]);
|
||||
break;
|
||||
case OPC_B:
|
||||
fprintf(ctx->out, "%s", brinfo[cat0->brtype].suffix);
|
||||
@@ -421,13 +421,13 @@ static void print_instr_cat0(struct disasm_ctx *ctx, instr_t *instr)
|
||||
fprintf(ctx->out, ".%u", cat0->idx);
|
||||
}
|
||||
if (brinfo[cat0->brtype].nsrc >= 1) {
|
||||
fprintf(ctx->out, " %sp0.%c,", cat0->inv0 ? "!" : "",
|
||||
component[cat0->comp0]);
|
||||
}
|
||||
if (brinfo[cat0->brtype].nsrc >= 2) {
|
||||
fprintf(ctx->out, " %sp0.%c,", cat0->inv1 ? "!" : "",
|
||||
component[cat0->comp1]);
|
||||
}
|
||||
if (brinfo[cat0->brtype].nsrc >= 2) {
|
||||
fprintf(ctx->out, " %sp0.%c,", cat0->inv2 ? "!" : "",
|
||||
component[cat0->comp2]);
|
||||
}
|
||||
fprintf(ctx->out, " #%d", cat0->a3xx.immed);
|
||||
break;
|
||||
case OPC_JUMP:
|
||||
|
||||
@@ -397,13 +397,13 @@ typedef struct PACKED {
|
||||
uint32_t repeat : 3;
|
||||
uint32_t dummy3 : 1;
|
||||
uint32_t ss : 1;
|
||||
uint32_t inv1 : 1;
|
||||
uint32_t comp1 : 2;
|
||||
uint32_t inv2 : 1;
|
||||
uint32_t comp2 : 2;
|
||||
uint32_t eq : 1;
|
||||
uint32_t opc_hi : 1; /* at least one bit */
|
||||
uint32_t dummy4 : 2;
|
||||
uint32_t inv0 : 1;
|
||||
uint32_t comp0 : 2; /* component for first src */
|
||||
uint32_t inv1 : 1;
|
||||
uint32_t comp1 : 2; /* component for first src */
|
||||
uint32_t opc : 4;
|
||||
uint32_t jmp_tgt : 1;
|
||||
uint32_t sync : 1;
|
||||
|
||||
@@ -144,8 +144,12 @@ static int emit_cat0(struct ir3_instruction *instr, void *ptr,
|
||||
}
|
||||
cat0->repeat = instr->repeat;
|
||||
cat0->ss = !!(instr->flags & IR3_INSTR_SS);
|
||||
cat0->inv0 = instr->cat0.inv;
|
||||
cat0->comp0 = instr->cat0.comp;
|
||||
cat0->inv1 = instr->cat0.inv1;
|
||||
cat0->comp1 = instr->cat0.comp1;
|
||||
cat0->inv2 = instr->cat0.inv2;
|
||||
cat0->comp2 = instr->cat0.comp2;
|
||||
cat0->brtype = instr->cat0.brtype;
|
||||
cat0->idx = instr->cat0.idx;
|
||||
cat0->opc = instr->opc;
|
||||
cat0->opc_hi = instr->opc >= 16;
|
||||
cat0->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
|
||||
|
||||
@@ -247,10 +247,12 @@ struct ir3_instruction {
|
||||
struct ir3_register **regs;
|
||||
union {
|
||||
struct {
|
||||
char inv;
|
||||
char comp;
|
||||
char inv1, inv2;
|
||||
char comp1, comp2;
|
||||
int immed;
|
||||
struct ir3_block *target;
|
||||
brtype_t brtype;
|
||||
unsigned idx; /* for brac.N */
|
||||
} cat0;
|
||||
struct {
|
||||
type_t src_type, dst_type;
|
||||
|
||||
@@ -517,7 +517,7 @@ resolve_jump(struct ir3_instruction *instr)
|
||||
* then we can just drop the jump.
|
||||
*/
|
||||
unsigned next_block;
|
||||
if (instr->cat0.inv == true)
|
||||
if (instr->cat0.inv1 == true)
|
||||
next_block = 2;
|
||||
else
|
||||
next_block = 1;
|
||||
@@ -609,7 +609,7 @@ block_sched(struct ir3 *ir)
|
||||
* frequently/always end up being a fall-thru):
|
||||
*/
|
||||
br = ir3_B(block, block->condition, 0);
|
||||
br->cat0.inv = true;
|
||||
br->cat0.inv1 = true;
|
||||
br->cat0.target = block->successors[1];
|
||||
|
||||
/* "then" branch: */
|
||||
|
||||
@@ -586,17 +586,17 @@ instr: iflags cat0_instr
|
||||
| iflags cat5_instr
|
||||
| iflags cat6_instr
|
||||
|
||||
cat0_src: '!' T_P0 { instr->cat0.inv = true; instr->cat0.comp = $2 >> 1; }
|
||||
| T_P0 { instr->cat0.comp = $1 >> 1; }
|
||||
cat0_src1: '!' T_P0 { instr->cat0.inv1 = true; instr->cat0.comp1 = $2 >> 1; }
|
||||
| T_P0 { instr->cat0.comp1 = $1 >> 1; }
|
||||
|
||||
cat0_immed: '#' integer { instr->cat0.immed = $2; }
|
||||
|
||||
cat0_instr: T_OP_NOP { new_instr(OPC_NOP); }
|
||||
| T_OP_BR { new_instr(OPC_B); } cat0_src ',' cat0_immed
|
||||
| T_OP_BR { new_instr(OPC_B); } cat0_src1 ',' cat0_immed
|
||||
| T_OP_JUMP { new_instr(OPC_JUMP); } cat0_immed
|
||||
| T_OP_CALL { new_instr(OPC_CALL); } cat0_immed
|
||||
| T_OP_RET { new_instr(OPC_RET); }
|
||||
| T_OP_KILL { new_instr(OPC_KILL); } cat0_src
|
||||
| T_OP_KILL { new_instr(OPC_KILL); } cat0_src1
|
||||
| T_OP_END { new_instr(OPC_END); }
|
||||
| T_OP_EMIT { new_instr(OPC_EMIT); }
|
||||
| T_OP_CUT { new_instr(OPC_CUT); }
|
||||
|
||||
@@ -290,7 +290,34 @@ print_instr(struct ir3_instruction *instr, int lvl)
|
||||
if (is_flow(instr) && instr->cat0.target) {
|
||||
/* the predicate register src is implied: */
|
||||
if (instr->opc == OPC_B) {
|
||||
printf("r %sp0.x", instr->cat0.inv ? "!" : "");
|
||||
static const struct {
|
||||
const char *suffix;
|
||||
int nsrc;
|
||||
bool idx;
|
||||
} brinfo[7] = {
|
||||
[BRANCH_PLAIN] = { "r", 1, false },
|
||||
[BRANCH_OR] = { "rao", 2, false },
|
||||
[BRANCH_AND] = { "raa", 2, false },
|
||||
[BRANCH_CONST] = { "rac", 0, true },
|
||||
[BRANCH_ANY] = { "any", 1, false },
|
||||
[BRANCH_ALL] = { "all", 1, false },
|
||||
[BRANCH_X] = { "rax", 0, false },
|
||||
};
|
||||
|
||||
printf("%s", brinfo[instr->cat0.brtype].suffix);
|
||||
if (brinfo[instr->cat0.brtype].idx) {
|
||||
printf(".%u", instr->cat0.idx);
|
||||
}
|
||||
if (brinfo[instr->cat0.brtype].nsrc >= 1) {
|
||||
printf(" %sp0.%c,", instr->cat0.inv1 ? "!" : "",
|
||||
"xyzw"[instr->cat0.comp1 & 0x3]);
|
||||
}
|
||||
if (brinfo[instr->cat0.brtype].nsrc >= 2) {
|
||||
printf(" %sp0.%c,", instr->cat0.inv2 ? "!" : "",
|
||||
"xyzw"[instr->cat0.comp2 & 0x3]);
|
||||
}
|
||||
|
||||
printf("r %sp0.%c", instr->cat0.inv1 ? "!" : "", "xyzw"[instr->cat0.comp1 & 0x3]);
|
||||
}
|
||||
printf(", target=block%u", block_id(instr->cat0.target));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user