From 2dc6458563c9886ea61ca3c0f807355def93d6c3 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 19 Dec 2020 13:46:59 -0800 Subject: [PATCH] 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 Part-of: --- src/freedreno/ir3/disasm-a3xx.c | 12 ++++++------ src/freedreno/ir3/instr-a3xx.h | 8 ++++---- src/freedreno/ir3/ir3.c | 8 ++++++-- src/freedreno/ir3/ir3.h | 6 ++++-- src/freedreno/ir3/ir3_legalize.c | 4 ++-- src/freedreno/ir3/ir3_parser.y | 8 ++++---- src/freedreno/ir3/ir3_print.c | 29 ++++++++++++++++++++++++++++- 7 files changed, 54 insertions(+), 21 deletions(-) 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)); }