diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index 1fcc45fd3cb..b45738636cb 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -1174,6 +1174,25 @@ ir3_split_dest(struct ir3_builder *build, struct ir3_instruction **dst, } } +/* Split off the first 1 (bit_size < 64) or 2 (bit_size == 64) components from + * src and create a new 32b or 64b value. + */ +struct ir3_instruction * +ir3_split_off_scalar(struct ir3_builder *build, struct ir3_instruction *src, + unsigned bit_size) +{ + unsigned num_comps = bit_size == 64 ? 2 : 1; + assert((src->dsts[0]->wrmask & MASK(num_comps)) == MASK(num_comps)); + + if (num_comps == 1 && src->dsts[0]->wrmask == 0x1) { + return src; + } + + struct ir3_instruction *comps[num_comps]; + ir3_split_dest(build, comps, src, 0, num_comps); + return bit_size == 64 ? ir3_64b(build, comps[0], comps[1]) : comps[0]; +} + struct ir3_instruction * ir3_store_const(struct ir3_shader_variant *so, struct ir3_builder *build, struct ir3_instruction *src, unsigned dst) diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 44dd8f30e94..32b97f55712 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -2697,6 +2697,9 @@ struct ir3_instruction *ir3_create_collect(struct ir3_builder *build, void ir3_split_dest(struct ir3_builder *build, struct ir3_instruction **dst, struct ir3_instruction *src, unsigned base, unsigned n); +struct ir3_instruction *ir3_split_off_scalar(struct ir3_builder *build, + struct ir3_instruction *src, + unsigned bit_size); static inline struct ir3_instruction * ir3_64b(struct ir3_builder *build, struct ir3_instruction *lo,