]> git.ipfire.org Git - thirdparty/gcc.git/commit
ARC: Improved SImode shifts and rotates with -mswap.
authorRoger Sayle <roger@nextmovesoftware.com>
Mon, 30 Oct 2023 16:12:30 +0000 (16:12 +0000)
committerRoger Sayle <roger@nextmovesoftware.com>
Mon, 30 Oct 2023 16:12:30 +0000 (16:12 +0000)
commitd24c3c533454449f4bfe3db5a4c7d0eaff08e3c7
tree5a8e904ec77b7022753b4aab7b6bc93a3f183e49
parentfb1941d08fc3711b058c1e148e9ce7ed9b7dfbba
ARC: Improved SImode shifts and rotates with -mswap.

This patch improves the code generated by the ARC back-end for CPUs
without a barrel shifter but with -mswap.  The -mswap option provides
a SWAP instruction that implements SImode rotations by 16, but also
logical shift instructions (left and right) by 16 bits.  Clearly these
are also useful building blocks for implementing shifts by 17, 18, etc.
which would otherwise require a loop.

As a representative example:
int shl20 (int x) { return x << 20; }

GCC with -O2 -mcpu=em -mswap would previously generate:

shl20:  mov     lp_count,10
        lp      2f
        add     r0,r0,r0
        add     r0,r0,r0
2:      # end single insn loop
        j_s     [blink]

with this patch we now generate:

shl20:  mov_s   r2,0    ;3
        lsl16   r0,r0
        add3    r0,r2,r0
        j_s.d   [blink]
        asl_s r0,r0

Although both are four instructions (excluding the j_s),
the original takes ~22 cycles, and replacement ~4 cycles.

2023-10-30  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
* config/arc/arc.cc (arc_split_ashl): Use lsl16 on TARGET_SWAP.
(arc_split_ashr): Use swap and sign-extend on TARGET_SWAP.
(arc_split_lshr): Use lsr16 on TARGET_SWAP.
(arc_split_rotl): Use swap on TARGET_SWAP.
(arc_split_rotr): Likewise.
* config/arc/arc.md (ANY_ROTATE): New code iterator.
(<ANY_ROTATE>si2_cnt16): New define_insn for alternate form of
swap instruction on TARGET_SWAP.
(ashlsi2_cnt16): Rename from *ashlsi16_cnt16 and move earlier.
(lshrsi2_cnt16): New define_insn for LSR16 instruction.
(*ashlsi2_cnt16): See above.

gcc/testsuite/ChangeLog
* gcc.target/arc/lsl16-1.c: New test case.
* gcc.target/arc/lsr16-1.c: Likewise.
* gcc.target/arc/swap-1.c: Likewise.
* gcc.target/arc/swap-2.c: Likewise.
gcc/config/arc/arc.cc
gcc/config/arc/arc.md
gcc/testsuite/gcc.target/arc/lsl16-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/lsr16-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/swap-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/swap-2.c [new file with mode: 0644]