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.
This commit is contained in:
parent
d6ebe61889
commit
817a701681
1 changed files with 16 additions and 0 deletions
|
@ -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")
|
||||
|
|
Loading…
Add table
Reference in a new issue