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

Reply via email to