On Mon, May 25, 2026 at 3:33 PM Takayuki 'January June' Suwa <[email protected]> wrote: > > By default, the RTX generation pass conservatively expands bit-field > insertion to an insn sequence consisting of the bit mask and shift of > the inserted value, the bit-inversion mask of the destination, and finally > a logical-OR. > > However, if the logical-AND operation on an inverted bit-field mask is > relatively expensive, it is more advantageous to shift the inserted value > without masking it and then follow the idiom '(A & M) | (B & ~M)' -> > '((A ^ B) & M) ^ B'. > > /* example */ > struct foo { > unsigned int x:10; > unsigned int y:11; > unsigned int z:11; > }; > struct foo test0(struct foo a, unsigned int b) { > a.x = b; > return a; > } > struct foo test1(struct foo a, unsigned int b) { > a.y = b; > return a; > } > > ;; before (-Os ; !BITS_BIG_ENDIAN | !TARGET_DEPBITS) > test0: > entry sp, 32 > movi a8, -0x400 ;; = ~0x000003FF > extui a3, a3, 0, 10 ;; mask > and a2, a2, a8 ;; inverted mask > or a2, a2, a3 ;; logical-OR > retw.n > .literal_position > .literal .LC0, -2096129 ;; = ~0x001FFC00 > test1: > entry sp, 32 > l32r a8, .LC0 > extui a3, a3, 0, 11 ;; mask > slli a3, a3, 10 ;; > and a2, a2, a8 ;; inverted mask > or a2, a2, a3 ;; logical-OR > retw.n > > ;; after (-Os ; !BITS_BIG_ENDIAN | !TARGET_DEPBITS) > test0: > entry sp, 32 > xor a3, a2, a3 > extui a3, a3, 0, 10 ;; mask > xor a2, a2, a3 > retw.n > test1: > entry sp, 32 > slli a3, a3, 10 ;; bit-position alignment > xor a3, a2, a3 > extui a3, a3, 10, 11 ;; mask > slli a3, a3, 10 ;; > xor a2, a2, a3 > retw.n > > gcc/ChangeLog: > > * config/xtensa/xtensa.md (insvsi_intermal): > Rename from 'insvsi'. > (insvsi): New expansion pattern that also addresses situations > where the DEPBITS machine instruction is unavailable. > --- > gcc/config/xtensa/xtensa.md | 30 +++++++++++++++++++++++++++++- > 1 file changed, 29 insertions(+), 1 deletion(-)
Regtested for target=xtensa-linux-uclibc, no new regressions. Committed to master. -- Thanks. -- Max
