diff --git a/src/panfrost/compiler/bi_lower_swizzle.c b/src/panfrost/compiler/bi_lower_swizzle.c index 99c004b7469..593a16d3b8d 100644 --- a/src/panfrost/compiler/bi_lower_swizzle.c +++ b/src/panfrost/compiler/bi_lower_swizzle.c @@ -174,8 +174,8 @@ lower_swizzle(bi_context *ctx, bi_instr *ins, unsigned src) /* Lower it away */ bi_builder b = bi_init_builder(ctx, bi_before_instr(ins)); - bool is_8 = (bi_opcode_props[ins->op].size == BI_SIZE_8) || - (bi_opcode_props[ins->op].size == BI_SIZE_32 && + bool is_8 = (bi_get_opcode_props(ins)->size == BI_SIZE_8) || + (bi_get_opcode_props(ins)->size == BI_SIZE_32 && ins->src[src].swizzle >= BI_SWIZZLE_B0000); bi_index orig = ins->src[src]; @@ -241,13 +241,13 @@ bi_instr_replicates(bi_instr *I, BITSET_WORD *replicates_16) } /* Replication analysis only makes sense for ALU instructions */ - if (bi_opcode_props[I->op].message != BIFROST_MESSAGE_NONE) + if (bi_get_opcode_props(I)->message != BIFROST_MESSAGE_NONE) return false; /* We only analyze 16-bit instructions for 16-bit replication. We could * maybe do better. */ - if (bi_opcode_props[I->op].size != BI_SIZE_16) + if (bi_get_opcode_props(I)->size != BI_SIZE_16) return false; bi_foreach_src(I, s) { @@ -296,7 +296,7 @@ bi_lower_swizzle(bi_context *ctx) if (ins->op == BI_OPCODE_SWZ_V2I16 && bi_is_ssa(ins->src[0]) && BITSET_TEST(replicates_16, ins->src[0].value)) { - ins->op = BI_OPCODE_MOV_I32; + bi_set_opcode(ins, BI_OPCODE_MOV_I32); ins->src[0].swizzle = BI_SWIZZLE_H01; } diff --git a/src/panfrost/compiler/bi_opt_copy_prop.c b/src/panfrost/compiler/bi_opt_copy_prop.c index 1a3bc5ae042..faaba39a818 100644 --- a/src/panfrost/compiler/bi_opt_copy_prop.c +++ b/src/panfrost/compiler/bi_opt_copy_prop.c @@ -50,13 +50,13 @@ bi_opt_copy_prop(bi_context *ctx) if (I->op == BI_OPCODE_COLLECT_I32) { /* Rewrite trivial collects while we're at it */ if (I->nr_srcs == 1) - I->op = BI_OPCODE_MOV_I32; + bi_set_opcode(I, BI_OPCODE_MOV_I32); collects[I->dest[0].value] = I; } else if (I->op == BI_OPCODE_SPLIT_I32) { /* Rewrite trivial splits while we're at it */ if (I->nr_dests == 1) - I->op = BI_OPCODE_MOV_I32; + bi_set_opcode(I, BI_OPCODE_MOV_I32); bi_instr *collect = collects[I->src[0].value]; if (!collect) diff --git a/src/panfrost/compiler/bi_opt_cse.c b/src/panfrost/compiler/bi_opt_cse.c index 28e3519c338..16f27cb802b 100644 --- a/src/panfrost/compiler/bi_opt_cse.c +++ b/src/panfrost/compiler/bi_opt_cse.c @@ -136,7 +136,7 @@ instr_can_cse(const bi_instr *I) /* Be conservative about which message-passing instructions we CSE, * since most are not pure even within a thread. */ - if (bi_opcode_props[I->op].message && I->op != BI_OPCODE_LEA_BUF_IMM) + if (bi_get_opcode_props(I)->message && I->op != BI_OPCODE_LEA_BUF_IMM) return false; if (I->branch_target) diff --git a/src/panfrost/compiler/bi_opt_dce.c b/src/panfrost/compiler/bi_opt_dce.c index 2a74eab6c11..4af84c12461 100644 --- a/src/panfrost/compiler/bi_opt_dce.c +++ b/src/panfrost/compiler/bi_opt_dce.c @@ -172,7 +172,7 @@ bi_opt_dce_post_ra(bi_context *ctx) unsigned reg = ins->dest[d].value; uint64_t mask = (BITFIELD64_MASK(nr) << reg); bool cullable = (ins->op != BI_OPCODE_BLEND); - cullable &= !bi_opcode_props[ins->op].sr_write; + cullable &= !bi_get_opcode_props(ins)->sr_write; if (!(live & mask) && cullable) ins->dest[d] = bi_null(); diff --git a/src/panfrost/compiler/bi_opt_mod_props.c b/src/panfrost/compiler/bi_opt_mod_props.c index 35a172a113b..edcf7d887ed 100644 --- a/src/panfrost/compiler/bi_opt_mod_props.c +++ b/src/panfrost/compiler/bi_opt_mod_props.c @@ -60,7 +60,7 @@ bi_takes_fabs(unsigned arch, bi_instr *I, bi_index repl, unsigned s) /* TODO: Need to check mode */ return false; default: - return bi_opcode_props[I->op].abs & BITFIELD_BIT(s); + return bi_get_opcode_props(I)->abs & BITFIELD_BIT(s); } } @@ -79,7 +79,7 @@ bi_takes_fneg(unsigned arch, bi_instr *I, unsigned s) /* TODO: Need to check mode */ return false; default: - return bi_opcode_props[I->op].neg & BITFIELD_BIT(s); + return bi_get_opcode_props(I)->neg & BITFIELD_BIT(s); } } @@ -188,7 +188,7 @@ bi_fuse_small_int_to_f32(bi_instr *I, bi_instr *mod) assert(I->src[0].swizzle == BI_SWIZZLE_H01); I->src[0] = mod->src[0]; I->round = BI_ROUND_NONE; - I->op = bi_small_int_patterns[i].replacement; + bi_set_opcode(I, bi_small_int_patterns[i].replacement); } } @@ -221,7 +221,7 @@ bi_opt_mod_prop_forward(bi_context *ctx) if (!mod) continue; - unsigned size = bi_opcode_props[I->op].size; + unsigned size = bi_get_opcode_props(I)->size; /* All small int instructions we were relying on here are gone on v11 */ if (ctx->arch < 11) @@ -258,7 +258,7 @@ bi_takes_clamp(bi_instr *I) return !(I->src[0].abs && I->src[1].abs && bi_is_word_equiv(I->src[0], I->src[1])); default: - return bi_opcode_props[I->op].clamp; + return bi_get_opcode_props(I)->clamp; } } @@ -272,7 +272,7 @@ bi_is_fclamp(enum bi_opcode op, enum bi_size size) static bool bi_optimizer_clamp(bi_instr *I, bi_instr *use) { - if (!bi_is_fclamp(use->op, bi_opcode_props[I->op].size)) + if (!bi_is_fclamp(use->op, bi_get_opcode_props(I)->size)) return false; if (!bi_takes_clamp(I)) return false; @@ -337,7 +337,7 @@ bi_takes_float_result_type(enum bi_opcode op) static bool bi_optimizer_result_type(bi_instr *I, bi_instr *mux) { - if (bi_opcode_props[I->op].size != bi_opcode_props[mux->op].size) + if (bi_get_opcode_props(I)->size != bi_get_opcode_props(mux)->size) return false; if (bi_is_fixed_mux(mux, 32, bi_imm_f32(1.0)) || @@ -392,7 +392,7 @@ bi_optimizer_var_tex(bi_context *ctx, bi_instr *var, bi_instr *tex) I->skip = tex->skip; if (tex->op == BI_OPCODE_TEXS_2D_F16) - I->op = BI_OPCODE_VAR_TEX_F16; + bi_set_opcode(I, BI_OPCODE_VAR_TEX_F16); /* Dead code elimination will clean up for us */ return true; diff --git a/src/panfrost/compiler/bi_opt_push_ubo.c b/src/panfrost/compiler/bi_opt_push_ubo.c index 6e69e3c11c7..9a4f3c527a7 100644 --- a/src/panfrost/compiler/bi_opt_push_ubo.c +++ b/src/panfrost/compiler/bi_opt_push_ubo.c @@ -32,7 +32,7 @@ static bool bi_is_ubo(bi_instr *ins) { - return (bi_opcode_props[ins->op].message == BIFROST_MESSAGE_LOAD) && + return (bi_get_opcode_props(ins)->message == BIFROST_MESSAGE_LOAD) && (ins->seg == BI_SEG_UBO); } @@ -74,7 +74,7 @@ bi_analyze_ranges(bi_context *ctx) unsigned ubo = pan_res_handle_get_index(ins->src[1].value); unsigned word = ins->src[0].value / 4; - unsigned channels = bi_opcode_props[ins->op].sr_count; + unsigned channels = bi_get_opcode_props(ins)->sr_count; assert(ubo < res.nr_blocks); assert(channels > 0 && channels <= 4); @@ -163,7 +163,7 @@ bi_opt_push_ubo(bi_context *ctx) /* Replace the UBO load with moves from FAU */ bi_builder b = bi_init_builder(ctx, bi_after_instr(ins)); - unsigned nr = bi_opcode_props[ins->op].sr_count; + unsigned nr = bi_get_opcode_props(ins)->sr_count; bi_instr *vec = bi_collect_i32_to(&b, ins->dest[0], nr); bi_foreach_src(vec, w) { diff --git a/src/panfrost/compiler/bi_pressure_schedule.c b/src/panfrost/compiler/bi_pressure_schedule.c index 96cd9e2b19a..db29e973445 100644 --- a/src/panfrost/compiler/bi_pressure_schedule.c +++ b/src/panfrost/compiler/bi_pressure_schedule.c @@ -69,7 +69,7 @@ create_dag(bi_context *ctx, bi_block *block, void *memctx) bi_foreach_instr_in_block(block, I) { /* Leave branches at the end */ - if (I->op == BI_OPCODE_JUMP || bi_opcode_props[I->op].branch) + if (I->op == BI_OPCODE_JUMP || bi_get_opcode_props(I)->branch) break; assert(I->branch_target == NULL); @@ -87,7 +87,7 @@ create_dag(bi_context *ctx, bi_block *block, void *memctx) add_dep(node, preload); - switch (bi_opcode_props[I->op].message) { + switch (bi_get_opcode_props(I)->message) { case BIFROST_MESSAGE_LOAD: /* Regular memory loads needs to be serialized against * other memory access. However, UBO memory is read-only diff --git a/src/panfrost/compiler/bi_printer.c.py b/src/panfrost/compiler/bi_printer.c.py index 9501601d5b9..cb9226d6fc7 100644 --- a/src/panfrost/compiler/bi_printer.c.py +++ b/src/panfrost/compiler/bi_printer.c.py @@ -169,7 +169,7 @@ bi_print_instr(const bi_instr *I, FILE *fp) if (I->nr_dests > 0) fputs(" = ", fp); - fprintf(fp, "%s", bi_opcode_props[I->op].name); + fprintf(fp, "%s", bi_get_opcode_props(I)->name); if (I->table) fprintf(fp, ".table%u", I->table); diff --git a/src/panfrost/compiler/bifrost/bi_pack.c b/src/panfrost/compiler/bifrost/bi_pack.c index 7782c07ecd6..948560bd657 100644 --- a/src/panfrost/compiler/bifrost/bi_pack.c +++ b/src/panfrost/compiler/bifrost/bi_pack.c @@ -110,8 +110,8 @@ bi_assign_slots(bi_tuple *now, bi_tuple *prev) * use the data registers, which has its own mechanism entirely * and thus gets skipped over here. */ - bool read_dreg = now->add && bi_opcode_props[now->add->op].sr_read; - bool write_dreg = prev->add && bi_opcode_props[prev->add->op].sr_write; + bool read_dreg = now->add && bi_get_opcode_props(now->add)->sr_read; + bool write_dreg = prev->add && bi_get_opcode_props(prev->add)->sr_write; /* First, assign reads */ @@ -327,7 +327,7 @@ bi_pack_tuple(bi_clause *clause, bi_tuple *tuple, bi_tuple *prev, bi_flip_slots(&tuple->regs); - bool sr_read = tuple->add && bi_opcode_props[(tuple->add)->op].sr_read; + bool sr_read = tuple->add && bi_get_opcode_props(tuple->add)->sr_read; uint64_t reg = bi_pack_registers(tuple->regs); uint64_t fma = @@ -345,7 +345,7 @@ bi_pack_tuple(bi_clause *clause, bi_tuple *tuple, bi_tuple *prev, bi_instr *add = tuple->add; bool sr_write = - bi_opcode_props[add->op].sr_write && !bi_is_null(add->dest[0]); + bi_get_opcode_props(add)->sr_write && !bi_is_null(add->dest[0]); if (sr_read && !bi_is_null(add->src[0])) { assert(add->src[0].type == BI_INDEX_REGISTER); @@ -713,7 +713,7 @@ bi_lower_texc_dual(bi_context *ctx) bi_foreach_instr_global(ctx, I) { if (I->op == BI_OPCODE_TEXC_DUAL) { /* In hardware, TEXC has 1 destination */ - I->op = BI_OPCODE_TEXC; + bi_set_opcode(I, BI_OPCODE_TEXC); bi_drop_dests(I, 1); } } diff --git a/src/panfrost/compiler/bifrost/bi_schedule.c b/src/panfrost/compiler/bifrost/bi_schedule.c index f55e364f928..c1d162a3b58 100644 --- a/src/panfrost/compiler/bifrost/bi_schedule.c +++ b/src/panfrost/compiler/bifrost/bi_schedule.c @@ -148,7 +148,7 @@ struct bi_clause_state { static enum bifrost_message_type bi_message_type_for_instr(bi_instr *ins) { - enum bifrost_message_type msg = bi_opcode_props[ins->op].message; + enum bifrost_message_type msg = bi_get_opcode_props(ins)->message; bool ld_var_special = (ins->op == BI_OPCODE_LD_VAR_SPECIAL); if (ld_var_special && ins->varying_name == BI_VARYING_NAME_FRAG_Z) @@ -337,7 +337,7 @@ bi_lower_cubeface(bi_context *ctx, struct bi_clause_state *clause, bi_instr *cubeface1 = bi_cubeface1_to(&b, pinstr->dest[0], pinstr->src[0], pinstr->src[1], pinstr->src[2]); - pinstr->op = BI_OPCODE_CUBEFACE2; + bi_set_opcode(pinstr, BI_OPCODE_CUBEFACE2); pinstr->dest[0] = pinstr->dest[1]; bi_drop_dests(pinstr, 1); @@ -361,7 +361,7 @@ bi_lower_atom_c(bi_context *ctx, struct bi_clause_state *clause, pinstr->src[0], pinstr->atom_opc); if (bi_is_null(pinstr->dest[0])) - atom_c->op = BI_OPCODE_ATOM_C_I32; + bi_set_opcode(atom_c, BI_OPCODE_ATOM_C_I32); bi_instr *atom_cx = bi_atom_cx_to(&b, pinstr->dest[0], pinstr->src[0], pinstr->src[1], @@ -382,7 +382,7 @@ bi_lower_atom_c1(bi_context *ctx, struct bi_clause_state *clause, pinstr->atom_opc); if (bi_is_null(pinstr->dest[0])) - atom_c->op = BI_OPCODE_ATOM_C1_I32; + bi_set_opcode(atom_c, BI_OPCODE_ATOM_C1_I32); bi_instr *atom_cx = bi_atom_cx_to(&b, pinstr->dest[0], bi_null(), pinstr->src[0], @@ -403,7 +403,7 @@ bi_lower_seg_add(bi_context *ctx, struct bi_clause_state *clause, bi_instr *fma = bi_seg_add_to(&b, pinstr->dest[0], pinstr->src[0], pinstr->preserve_null, pinstr->seg); - pinstr->op = BI_OPCODE_SEG_ADD; + bi_set_opcode(pinstr, BI_OPCODE_SEG_ADD); pinstr->src[0] = pinstr->src[1]; bi_drop_srcs(pinstr, 1); @@ -546,7 +546,7 @@ bi_can_fma(bi_instr *ins) return false; /* TODO: some additional fp16 constraints */ - return bi_opcode_props[ins->op].fma; + return bi_get_opcode_props(ins)->fma; } static bool @@ -576,7 +576,7 @@ bi_can_add(bi_instr *ins) return false; /* TODO: some additional fp16 constraints */ - return bi_opcode_props[ins->op].add; + return bi_get_opcode_props(ins)->add; } /* Architecturally, no single instruction has a "not last" constraint. However, @@ -604,7 +604,7 @@ bi_must_not_last(bi_instr *ins) bool bi_must_message(bi_instr *ins) { - return (bi_opcode_props[ins->op].message != BIFROST_MESSAGE_NONE) || + return (bi_get_opcode_props(ins)->message != BIFROST_MESSAGE_NONE) || (ins->op == BI_OPCODE_DISCARD_F32); } @@ -730,11 +730,11 @@ bool bi_reads_t(bi_instr *ins, unsigned src) { /* Branch offset cannot come from passthrough */ - if (bi_opcode_props[ins->op].branch) + if (bi_get_opcode_props(ins)->branch) return src != 2; /* Table can never read passthrough */ - if (bi_opcode_props[ins->op].table) + if (bi_get_opcode_props(ins)->table) return false; /* Staging register reads may happen before the succeeding register @@ -1005,7 +1005,7 @@ bi_write_count(bi_instr *instr, uint64_t live_after_temp) unsigned count = 0; bi_foreach_dest(instr, d) { - if (d == 0 && bi_opcode_props[instr->op].sr_write) + if (d == 0 && bi_get_opcode_props(instr)->sr_write) continue; assert(instr->dest[0].type == BI_INDEX_REGISTER); @@ -1060,7 +1060,7 @@ bi_instr_schedulable(bi_instr *instr, struct bi_clause_state *clause, return false; /* Some instructions have placement requirements */ - if (bi_opcode_props[instr->op].last && !tuple->last) + if (bi_get_opcode_props(instr)->last && !tuple->last) return false; if (bi_must_not_last(instr) && tuple->last) @@ -1074,7 +1074,7 @@ bi_instr_schedulable(bi_instr *instr, struct bi_clause_state *clause, * same clause (most likely they will not), so if a later instruction * in the clause accesses the destination, the message-passing * instruction can't be scheduled */ - if (bi_opcode_props[instr->op].sr_write) { + if (bi_get_opcode_props(instr)->sr_write) { bi_foreach_dest(instr, d) { unsigned nr = bi_count_write_registers(instr, d); assert(instr->dest[d].type == BI_INDEX_REGISTER); @@ -1090,7 +1090,7 @@ bi_instr_schedulable(bi_instr *instr, struct bi_clause_state *clause, } } - if (bi_opcode_props[instr->op].sr_read && !bi_is_null(instr->src[0])) { + if (bi_get_opcode_props(instr)->sr_read && !bi_is_null(instr->src[0])) { unsigned nr = bi_count_read_registers(instr, 0); assert(instr->src[0].type == BI_INDEX_REGISTER); unsigned reg = instr->src[0].value; @@ -1183,7 +1183,7 @@ bi_instr_cost(bi_instr *instr, struct bi_tuple_state *tuple) cost--; /* Last instructions are big constraints (XXX: no effect on shader-db) */ - if (bi_opcode_props[instr->op].last) + if (bi_get_opcode_props(instr)->last) cost -= 2; return cost; @@ -1361,7 +1361,7 @@ bi_use_passthrough(bi_instr *ins, bi_index old, enum bifrost_packed_src new, static void bi_rewrite_passthrough(bi_tuple prec, bi_tuple succ) { - bool sr_read = succ.add ? bi_opcode_props[succ.add->op].sr_read : false; + bool sr_read = succ.add ? bi_get_opcode_props(succ.add)->sr_read : false; if (prec.add && prec.add->nr_dests) { bi_use_passthrough(succ.fma, prec.add->dest[0], BIFROST_SRC_PASS_ADD, @@ -1738,7 +1738,7 @@ bi_schedule_clause(bi_context *ctx, bi_block *block, struct bi_worklist st, tuple = &clause->tuples[idx]; - if (clause->message && bi_opcode_props[clause->message->op].sr_read && + if (clause->message && bi_get_opcode_props(clause->message)->sr_read && !bi_is_null(clause->message->src[0])) { unsigned nr = bi_count_read_registers(clause->message, 0); live_after_temp |= @@ -2008,7 +2008,7 @@ bi_check_fau_src(bi_instr *ins, unsigned s, uint32_t *constants, if (src.type == BI_INDEX_CONSTANT) { /* Allow fast zero */ - if (src.value == 0 && bi_opcode_props[ins->op].fma && bi_reads_zero(ins)) + if (src.value == 0 && bi_get_opcode_props(ins)->fma && bi_reads_zero(ins)) return true; if (!bi_is_null(*fau)) @@ -2104,7 +2104,7 @@ bi_add_nop_for_atest(bi_context *ctx) * clause */ bi_instr *I = rzalloc(ctx, bi_instr); - I->op = BI_OPCODE_NOP; + bi_set_opcode(I, BI_OPCODE_NOP); bi_clause *new_clause = ralloc(ctx, bi_clause); *new_clause = (bi_clause){ diff --git a/src/panfrost/compiler/bifrost/bi_scoreboard.c b/src/panfrost/compiler/bifrost/bi_scoreboard.c index 735bcf4a677..a1edd4222e5 100644 --- a/src/panfrost/compiler/bifrost/bi_scoreboard.c +++ b/src/panfrost/compiler/bifrost/bi_scoreboard.c @@ -76,7 +76,7 @@ bi_should_serialize(bi_instr *I) if (I->op == BI_OPCODE_LD_ATTR_TEX) return true; - switch (bi_opcode_props[I->op].message) { + switch (bi_get_opcode_props(I)->message) { case BIFROST_MESSAGE_VARYING: case BIFROST_MESSAGE_LOAD: case BIFROST_MESSAGE_STORE: @@ -113,7 +113,7 @@ bi_read_mask(bi_instr *I, bool staging_only) { uint64_t mask = 0; - if (staging_only && !bi_opcode_props[I->op].sr_read) + if (staging_only && !bi_get_opcode_props(I)->sr_read) return mask; bi_foreach_src(I, s) { @@ -154,7 +154,7 @@ bi_write_mask(bi_instr *I) * Obscurely, ATOM_CX is sr_write but can ignore the staging register in * certain circumstances; this does not require consideration. */ - if (bi_opcode_props[I->op].sr_write && I->nr_dests && I->nr_srcs && + if (bi_get_opcode_props(I)->sr_write && I->nr_dests && I->nr_srcs && bi_is_null(I->dest[0]) && !bi_is_null(I->src[0])) { unsigned reg = I->src[0].value; @@ -179,7 +179,7 @@ bi_push_clause(struct bi_scoreboard_state *st, bi_clause *clause) st->read[slot] |= bi_read_mask(I, true); - if (bi_opcode_props[I->op].sr_write) + if (bi_get_opcode_props(I)->sr_write) st->write[slot] |= bi_write_mask(I); } diff --git a/src/panfrost/compiler/bir.c b/src/panfrost/compiler/bir.c index 9520eb8af3b..abc55612afa 100644 --- a/src/panfrost/compiler/bir.c +++ b/src/panfrost/compiler/bir.c @@ -66,7 +66,7 @@ bi_is_regfmt_16(enum bi_register_format fmt) static unsigned bi_count_staging_registers(const bi_instr *ins) { - enum bi_sr_count count = bi_opcode_props[ins->op].sr_count; + enum bi_sr_count count = bi_get_opcode_props(ins)->sr_count; unsigned vecsize = ins->vecsize + 1; /* XXX: off-by-one */ switch (count) { @@ -90,7 +90,7 @@ bi_count_read_registers(const bi_instr *ins, unsigned s) /* ATOM reads 1 but writes 2. Exception for ACMPXCHG */ if (s == 0 && ins->op == BI_OPCODE_ATOM_RETURN_I32) return (ins->atom_opc == BI_ATOM_OPC_ACMPXCHG) ? 2 : 1; - else if (s == 0 && bi_opcode_props[ins->op].sr_read) + else if (s == 0 && bi_get_opcode_props(ins)->sr_read) return bi_count_staging_registers(ins); else if (s == 4 && ins->op == BI_OPCODE_BLEND) return ins->sr_count_2; /* Dual source blending */ @@ -103,7 +103,7 @@ bi_count_read_registers(const bi_instr *ins, unsigned s) unsigned bi_count_write_registers(const bi_instr *ins, unsigned d) { - if (d == 0 && bi_opcode_props[ins->op].sr_write) { + if (d == 0 && bi_get_opcode_props(ins)->sr_write) { switch (ins->op) { case BI_OPCODE_TEXC: case BI_OPCODE_TEXC_DUAL: @@ -185,7 +185,7 @@ bi_next_clause(bi_context *ctx, bi_block *block, bi_clause *clause) bool bi_side_effects(const bi_instr *I) { - if (bi_opcode_props[I->op].last) + if (bi_get_opcode_props(I)->last) return true; switch (I->op) { @@ -196,7 +196,7 @@ bi_side_effects(const bi_instr *I) break; } - switch (bi_opcode_props[I->op].message) { + switch (bi_get_opcode_props(I)->message) { case BIFROST_MESSAGE_NONE: case BIFROST_MESSAGE_VARYING: case BIFROST_MESSAGE_ATTRIBUTE: @@ -288,6 +288,7 @@ bi_csel_from_mux(bi_builder *b, const bi_instr *I, bool must_sign) I->src[0], I->src[1], cmpf); /* Fixup the opcode and use it */ - csel->op = bi_csel_for_mux(must_sign, I->op == BI_OPCODE_MUX_I32, I->mux); + bi_set_opcode(csel, + bi_csel_for_mux(must_sign, I->op == BI_OPCODE_MUX_I32, I->mux)); return csel; } diff --git a/src/panfrost/compiler/compiler.h b/src/panfrost/compiler/compiler.h index b4dc34c47b1..672699add68 100644 --- a/src/panfrost/compiler/compiler.h +++ b/src/panfrost/compiler/compiler.h @@ -559,10 +559,30 @@ typedef struct { }; } bi_instr; +/* + * Helpers to set opcode and to get properties related to + * the opcode. In principle this would allow different + * properties to be used based on the architecture. In practice + * we've unified the valhall/bifrost descriptions so this + * isn't necessary now. We may want it for a future architecture + * though. + */ +static inline void +bi_set_opcode(bi_instr *I, enum bi_opcode opc) +{ + I->op = opc; +} + +static inline struct bi_op_props * +bi_get_opcode_props(const bi_instr *I) +{ + return &bi_opcode_props[I->op]; +} + static inline bool bi_is_staging_src(const bi_instr *I, unsigned s) { - return (s == 0 || s == 4) && bi_opcode_props[I->op].sr_read; + return (s == 0 || s == 4) && bi_get_opcode_props(I)->sr_read; } /* diff --git a/src/panfrost/compiler/valhall/va_insert_flow.c b/src/panfrost/compiler/valhall/va_insert_flow.c index 00560c60b31..5296338d2ea 100644 --- a/src/panfrost/compiler/valhall/va_insert_flow.c +++ b/src/panfrost/compiler/valhall/va_insert_flow.c @@ -105,7 +105,7 @@ static bool bi_ld_vary_writes_hidden_register(const bi_instr *I) { /* Only varying loads can write the hidden register */ - if (bi_opcode_props[I->op].message != BIFROST_MESSAGE_VARYING) + if (bi_get_opcode_props(I)->message != BIFROST_MESSAGE_VARYING) return false; /* They only write in some update modes */ @@ -130,7 +130,7 @@ bi_is_memory_access(const bi_instr *I) if (I->seg == BI_SEG_UBO) return false; - switch (bi_opcode_props[I->op].message) { + switch (bi_get_opcode_props(I)->message) { case BIFROST_MESSAGE_LOAD: case BIFROST_MESSAGE_STORE: case BIFROST_MESSAGE_ATOMIC: @@ -145,13 +145,13 @@ bi_is_memory_access(const bi_instr *I) static void bi_push_instr(struct bi_scoreboard_state *st, bi_instr *I) { - if (bi_opcode_props[I->op].sr_write) + if (bi_get_opcode_props(I)->sr_write) st->write[I->slot] |= bi_write_mask(I); if (bi_is_memory_access(I)) st->memory |= BITFIELD_BIT(I->slot); - if (bi_opcode_props[I->op].message == BIFROST_MESSAGE_VARYING) + if (bi_get_opcode_props(I)->message == BIFROST_MESSAGE_VARYING) st->varying |= BITFIELD_BIT(I->slot); } @@ -528,7 +528,7 @@ va_assign_slots(bi_context *ctx) I->slot = 7; } else if (I->op == BI_OPCODE_ZS_EMIT || I->op == BI_OPCODE_ATEST) { I->slot = 0; - } else if (bi_opcode_props[I->op].message) { + } else if (bi_get_opcode_props(I)->message) { I->slot = counter++; if (counter == 3) diff --git a/src/panfrost/compiler/valhall/va_lower_isel.c b/src/panfrost/compiler/valhall/va_lower_isel.c index 9f74a9a8cfe..d69b37f6e10 100644 --- a/src/panfrost/compiler/valhall/va_lower_isel.c +++ b/src/panfrost/compiler/valhall/va_lower_isel.c @@ -95,8 +95,9 @@ lower(bi_builder *b, bi_instr *I) case BI_OPCODE_CSEL_V2I16: assert(I->cmpf == BI_CMPF_EQ || I->cmpf == BI_CMPF_NE); - I->op = (I->op == BI_OPCODE_CSEL_I32) ? BI_OPCODE_CSEL_U32 - : BI_OPCODE_CSEL_V2U16; + bi_set_opcode(I, + (I->op == BI_OPCODE_CSEL_I32) ? BI_OPCODE_CSEL_U32 + : BI_OPCODE_CSEL_V2U16); return NULL; /* Jump -> conditional branch with condition tied to true. */ @@ -110,13 +111,13 @@ lower(bi_builder *b, bi_instr *I) } case BI_OPCODE_AXCHG_I32: - I->op = BI_OPCODE_ATOM_RETURN_I32; + bi_set_opcode(I, BI_OPCODE_ATOM_RETURN_I32); I->atom_opc = BI_ATOM_OPC_AXCHG; I->sr_count = 1; return NULL; case BI_OPCODE_ACMPXCHG_I32: - I->op = BI_OPCODE_ATOM_RETURN_I32; + bi_set_opcode(I, BI_OPCODE_ATOM_RETURN_I32); I->atom_opc = BI_ATOM_OPC_ACMPXCHG; /* Reads 2, this is special cased in bir.c */ I->sr_count = 1; @@ -124,7 +125,7 @@ lower(bi_builder *b, bi_instr *I) case BI_OPCODE_ATOM_RETURN_I32: if (bi_is_null(I->dest[0])) - I->op = BI_OPCODE_ATOM_I32; + bi_set_opcode(I, BI_OPCODE_ATOM_I32); return NULL; diff --git a/src/panfrost/compiler/valhall/va_merge_flow.c b/src/panfrost/compiler/valhall/va_merge_flow.c index 05de5109260..99cd0abc7b3 100644 --- a/src/panfrost/compiler/valhall/va_merge_flow.c +++ b/src/panfrost/compiler/valhall/va_merge_flow.c @@ -149,7 +149,7 @@ merge_waits(bi_block *block) * we're waiting for. If we wanted to optimize this case, we could check * the signaled slots. */ - if (bi_opcode_props[I->op].message) + if (bi_get_opcode_props(I)->message) last_free = NULL; /* We can only merge with instructions whose flow control is a wait. diff --git a/src/panfrost/compiler/valhall/va_optimize.c b/src/panfrost/compiler/valhall/va_optimize.c index 4eab8d6cbf6..ebd55e6c2c4 100644 --- a/src/panfrost/compiler/valhall/va_optimize.c +++ b/src/panfrost/compiler/valhall/va_optimize.c @@ -74,7 +74,7 @@ va_lower_mov_imm(bi_instr *I) assert(I->nr_srcs == 1); if (I->src[0].type == BI_INDEX_CONSTANT) { - I->op = BI_OPCODE_IADD_IMM_I32; + bi_set_opcode(I, BI_OPCODE_IADD_IMM_I32); I->index = I->src[0].value; I->src[0] = bi_zero(); } @@ -104,7 +104,7 @@ va_fuse_add_imm(bi_instr *I) if (!va_is_add_imm(I, 1 - s)) return; - I->op = op; + bi_set_opcode(I, op); I->index = bi_apply_swizzle(I->src[s].value, I->src[s].swizzle); assert(!I->src[s].abs && "redundant .abs set"); diff --git a/src/panfrost/compiler/valhall/va_pack.c b/src/panfrost/compiler/valhall/va_pack.c index 8ebe3002091..3bc1ac25a73 100644 --- a/src/panfrost/compiler/valhall/va_pack.c +++ b/src/panfrost/compiler/valhall/va_pack.c @@ -566,7 +566,7 @@ va_pack_alu(const bi_instr *I, unsigned arch) bool swap12 = va_swap_12(I->op); /* First src is staging if we read, skip it when packing sources */ - unsigned src_offset = bi_opcode_props[I->op].sr_read ? 1 : 0; + unsigned src_offset = bi_get_opcode_props(I)->sr_read ? 1 : 0; for (unsigned i = 0; i < info.nr_srcs; ++i) { unsigned logical_i = (swap12 && i == 1) ? 2 : (swap12 && i == 2) ? 1 : i; @@ -805,7 +805,7 @@ va_pack_instr(const bi_instr *I, unsigned arch) hex |= ((uint64_t)I->slot << 30); if (info.sr_count) { - bool read = bi_opcode_props[I->op].sr_read; + bool read = bi_get_opcode_props(I)->sr_read; bi_index sr = read ? I->src[0] : I->dest[0]; unsigned count =