From 62d2069617ec3a8789acfe406c98b0c24e134f90 Mon Sep 17 00:00:00 2001 From: Job Noorman Date: Mon, 3 Mar 2025 09:58:54 +0100 Subject: [PATCH] ir3: add helper to create STC Creating STC is complicated since we might need to use a1.x for addressing. Extract the current code into a helper so that it can be used elsewhere. Signed-off-by: Job Noorman Part-of: --- src/freedreno/ir3/ir3.c | 37 ++++++++++++++++++++++++++++ src/freedreno/ir3/ir3.h | 5 ++++ src/freedreno/ir3/ir3_compiler_nir.c | 27 +------------------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index d2705bde452..b57344e30b8 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -1006,6 +1006,43 @@ ir3_create_addr1(struct ir3_builder *build, unsigned const_val) return instr; } +struct ir3_instruction * +ir3_store_const(struct ir3_shader_variant *so, struct ir3_builder *build, + struct ir3_instruction *src, unsigned dst) +{ + unsigned dst_lo = dst & 0xff; + unsigned dst_hi = dst >> 8; + unsigned components = util_last_bit(src->dsts[0]->wrmask); + + struct ir3_instruction *a1 = NULL; + if (dst_hi) { + /* Encode only the high part of the destination in a1.x to increase the + * chance that we can reuse the a1.x value in subsequent stc + * instructions. + */ + a1 = ir3_create_addr1(build, dst_hi << 8); + } + + struct ir3_instruction *stc = + ir3_STC(build, create_immed(build, dst_lo), 0, src, 0); + stc->cat6.iim_val = components; + stc->cat6.type = TYPE_U32; + stc->barrier_conflict = IR3_BARRIER_CONST_W; + + if (a1) { + ir3_instr_set_address(stc, a1); + stc->flags |= IR3_INSTR_A1EN; + } + + /* The assembler isn't aware of what value a1.x has, so make sure that + * constlen includes the stc here. + */ + so->constlen = MAX2(so->constlen, DIV_ROUND_UP(dst + components, 4)); + struct ir3_block *block = ir3_cursor_current_block(build->cursor); + array_insert(block, block->keeps, stc); + return stc; +} + /* Does this instruction use the scalar ALU? */ bool diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 2afed573ad3..e6860745f04 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -2676,6 +2676,11 @@ ir3_BALLOT_MACRO(struct ir3_builder *build, struct ir3_instruction *src, return instr; } +struct ir3_instruction *ir3_store_const(struct ir3_shader_variant *so, + struct ir3_builder *build, + struct ir3_instruction *src, + unsigned dst); + /* clang-format off */ #define __INSTR0(flag, name, opc) \ static inline struct ir3_instruction *ir3_##name(struct ir3_builder *build) \ diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index e48aadcb4d9..feb41ff4d3b 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -3358,37 +3358,12 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr) case nir_intrinsic_store_const_ir3: { unsigned components = nir_src_num_components(intr->src[0]); unsigned dst = nir_intrinsic_base(intr); - unsigned dst_lo = dst & 0xff; - unsigned dst_hi = dst >> 8; struct ir3_instruction *src = ir3_create_collect(b, ir3_get_src_shared(ctx, &intr->src[0], ctx->compiler->has_scalar_alu), components); - struct ir3_instruction *a1 = NULL; - if (dst_hi) { - /* Encode only the high part of the destination in a1.x to increase the - * chance that we can reuse the a1.x value in subsequent stc - * instructions. - */ - a1 = ir3_create_addr1(&ctx->build, dst_hi << 8); - } - - struct ir3_instruction *stc = - ir3_STC(b, create_immed(b, dst_lo), 0, src, 0); - stc->cat6.iim_val = components; - stc->cat6.type = TYPE_U32; - stc->barrier_conflict = IR3_BARRIER_CONST_W; - if (a1) { - ir3_instr_set_address(stc, a1); - stc->flags |= IR3_INSTR_A1EN; - } - /* The assembler isn't aware of what value a1.x has, so make sure that - * constlen includes the stc here. - */ - ctx->so->constlen = - MAX2(ctx->so->constlen, DIV_ROUND_UP(dst + components, 4)); - array_insert(ctx->block, ctx->block->keeps, stc); + ir3_store_const(ctx->so, b, src, dst); break; } case nir_intrinsic_copy_push_const_to_uniform_ir3: {