diff --git a/src/freedreno/ir3/disasm-a3xx.c b/src/freedreno/ir3/disasm-a3xx.c index 9e54fc441bf..8f19e2f3e43 100644 --- a/src/freedreno/ir3/disasm-a3xx.c +++ b/src/freedreno/ir3/disasm-a3xx.c @@ -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: diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index 25864302242..595f1c920d5 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -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; diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index c99b5382bb7..85c905b9999 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -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); diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 6982702bb9a..8f3df782042 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -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; diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c index 69efdbabc3f..cde28abbec1 100644 --- a/src/freedreno/ir3/ir3_legalize.c +++ b/src/freedreno/ir3/ir3_legalize.c @@ -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: */ diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index f2dc91f47d8..e3b8146280b 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -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); } diff --git a/src/freedreno/ir3/ir3_print.c b/src/freedreno/ir3/ir3_print.c index b680959a447..dc1e6a94261 100644 --- a/src/freedreno/ir3/ir3_print.c +++ b/src/freedreno/ir3/ir3_print.c @@ -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)); }