diff options
author | Roger Sayle <roger@nextmovesoftware.com> | 2023-10-16 13:03:09 +0100 |
---|---|---|
committer | Roger Sayle <roger@nextmovesoftware.com> | 2023-10-16 13:03:09 +0100 |
commit | 817a701681924706a8ef035e107b9d45d21a2360 (patch) | |
tree | 3b7a2692e08b25a9b51ae8a2dfadc4ad780c90bb | |
parent | d6ebe61889732afaf2e8fbf1c1fcc4a5486a5f93 (diff) | |
download | gcc-817a701681924706a8ef035e107b9d45d21a2360.zip gcc-817a701681924706a8ef035e107b9d45d21a2360.tar.gz gcc-817a701681924706a8ef035e107b9d45d21a2360.tar.bz2 |
ARC: Split asl dst,1,src into bset dst,0,src to implement 1<<x.
This patch adds a pre-reload splitter to arc.md, to use the bset (set
specific bit instruction) to implement 1<<x (i.e. left shifts of one)
on ARC processors that don't have a barrel shifter.
Currently,
int foo(int x) {
return 1 << x;
}
when compiled with -O2 -mcpu=em is compiled as a loop:
foo: mov_s r2,1 ;3
and.f lp_count,r0, 0x1f
lpnz 2f
add r2,r2,r2
nop
2: # end single insn loop
j_s.d [blink]
mov_s r0,r2 ;4
with this patch we instead generate a single instruction:
foo: bset r0,0,r0
j_s [blink]
2023-10-16 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
* config/arc/arc.md (*ashlsi3_1): New pre-reload splitter to
use bset dst,0,src to implement 1<<x on !TARGET_BARREL_SHIFTER.
-rw-r--r-- | gcc/config/arc/arc.md | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index a936a8b..22af0bf 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -3421,6 +3421,22 @@ archs4x, archs4xd" (set_attr "predicable" "no,no,yes,no,no") (set_attr "cond" "nocond,canuse,canuse,nocond,nocond")]) +;; Split asl dst,1,src into bset dst,0,src. +(define_insn_and_split "*ashlsi3_1" + [(set (match_operand:SI 0 "dest_reg_operand") + (ashift:SI (const_int 1) + (match_operand:SI 1 "nonmemory_operand")))] + "!TARGET_BARREL_SHIFTER + && arc_pre_reload_split ()" + "#" + "&& 1" + [(set (match_dup 0) + (ior:SI (ashift:SI (const_int 1) (match_dup 1)) + (const_int 0)))] + "" + [(set_attr "type" "shift") + (set_attr "length" "8")]) + (define_insn_and_split "*ashlsi3_nobs" [(set (match_operand:SI 0 "dest_reg_operand") (ashift:SI (match_operand:SI 1 "register_operand") |