This patch reworks the CTZ, CLZ and FFS insns in avr.md.
1) It gets rid of explicit hard registers that are used to model the
respective libgcc asm functions. It uses hard-reg constraints instead.
2) It uses code iterators to represent the insns more neatly.
3) Instead of the clunky (truncate:HI (clz:SI (reg:SI))) it
uses (clz:HI (reg:SI)).
Passes without new regressions. Ok for trunk?
Johann
--
AVR: target/121343 - Overhaul CLZ, CTZ and FFS insns.
CLZ, CTZ and FFS insns used explicit hard regs in order to model
the register footprint of their libgcc asm implementations.
This patch uses hard-reg constraints instead. It also uses
code iterators in order to factor out commonalities.
The respective insns don't rely on insn combine, and hence
https://gcc.gnu.org/r17-438 in not a blocker.
PR target/121343
gcc/
* config/avr/avr.md (ctz_ffs, cxz_ffs): New code iterators.
(clzhi2, ctzhi2, ffshi2, clzsi2, ctzsi2, ffssi2): New
insn-and-split's from former expanders.
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index d4c20fb4e99..c58ec87610e 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -9112,54 +9112,41 @@ (define_insn "*bitreversesi2.libgcc"
;; Count Leading Zeros
+;; Count Trailing Zeros
+;; Find First Set
-(define_expand "clzhi2"
- [(set (reg:HI 24)
- (match_operand:HI 1 "register_operand" ""))
- (parallel [(set (reg:HI 24)
- (clz:HI (reg:HI 24)))
- (clobber (reg:QI 26))])
- (set (match_operand:HI 0 "register_operand" "")
- (reg:HI 24))])
-
-(define_expand "clzsi2"
- [(set (reg:SI 22)
- (match_operand:SI 1 "register_operand" ""))
- (parallel [(set (reg:HI 24)
- (truncate:HI (clz:SI (reg:SI 22))))
- (clobber (reg:QI 26))])
- (set (match_dup 2)
- (reg:HI 24))
- (set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_dup 2)))]
- ""
- {
- operands[2] = gen_reg_rtx (HImode);
- })
+(define_code_iterator ctz_ffs [ctz ffs])
+(define_code_iterator cxz_ffs [clz ctz ffs])
-(define_insn_and_split "*clzhi2.libgcc_split"
- [(set (reg:HI 24)
- (clz:HI (reg:HI 24)))
- (clobber (reg:QI 26))]
+;; "clzhi2"
+;; "ctzhi2"
+;; "ffshi2"
+(define_insn_and_split "<code>hi2"
+ [(set (match_operand:HI 0 "register_operand" "={r24}")
+ (cxz_ffs:HI (match_operand:HI 1 "register_operand" "{r24}")))
+ (clobber (match_scratch:QI 2 "={r26}"))]
""
"#"
"&& reload_completed"
[(scratch)]
{ DONE_ADD_CCC })
-(define_insn "*clzhi2.libgcc"
+;; "*clzhi2.libgcc"
+;; "*ctzhi2.libgcc"
+;; "*ffshi2.libgcc"
+(define_insn "*<code>hi2.libgcc"
[(set (reg:HI 24)
- (clz:HI (reg:HI 24)))
+ (cxz_ffs:HI (reg:HI 24)))
(clobber (reg:QI 26))
(clobber (reg:CC REG_CC))]
"reload_completed"
- "%~call __clzhi2"
+ "%~call __<code>hi2"
[(set_attr "type" "xcall")])
-(define_insn_and_split "*clzsihi2.libgcc_split"
- [(set (reg:HI 24)
- (truncate:HI (clz:SI (reg:SI 22))))
- (clobber (reg:QI 26))]
+(define_insn_and_split "clzsi2"
+ [(set (match_operand:HI 0 "register_operand" "={r24}")
+ (clz:HI (match_operand:SI 1 "register_operand" "{r22}")))
+ (clobber (match_scratch:QI 2 "={r26}"))]
""
"#"
"&& reload_completed"
@@ -9168,146 +9155,38 @@ (define_insn_and_split "*clzsihi2.libgcc_split"
(define_insn "*clzsihi2.libgcc"
[(set (reg:HI 24)
- (truncate:HI (clz:SI (reg:SI 22))))
+ (clz:HI (reg:SI 22)))
(clobber (reg:QI 26))
(clobber (reg:CC REG_CC))]
"reload_completed"
"%~call __clzsi2"
[(set_attr "type" "xcall")])
-;; Count Trailing Zeros
-
-(define_expand "ctzhi2"
- [(set (reg:HI 24)
- (match_operand:HI 1 "register_operand" ""))
- (parallel [(set (reg:HI 24)
- (ctz:HI (reg:HI 24)))
- (clobber (reg:QI 26))])
- (set (match_operand:HI 0 "register_operand" "")
- (reg:HI 24))])
-
-(define_expand "ctzsi2"
- [(set (reg:SI 22)
- (match_operand:SI 1 "register_operand" ""))
- (parallel [(set (reg:HI 24)
- (truncate:HI (ctz:SI (reg:SI 22))))
- (clobber (reg:QI 22))
- (clobber (reg:QI 26))])
- (set (match_dup 2)
- (reg:HI 24))
- (set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_dup 2)))]
- ""
- {
- operands[2] = gen_reg_rtx (HImode);
- })
-
-(define_insn_and_split "*ctzhi2.libgcc_split"
- [(set (reg:HI 24)
- (ctz:HI (reg:HI 24)))
- (clobber (reg:QI 26))]
+;; "ctzsi2"
+;; "ffssi2"
+(define_insn_and_split "<code>si2"
+ [(set (match_operand:HI 0 "register_operand" "={r24}")
+ (ctz_ffs:HI (match_operand:SI 1 "register_operand" "{r22}")))
+ (clobber (match_scratch:QI 2 "={r22}"))
+ (clobber (match_scratch:QI 3 "={r26}"))]
""
"#"
"&& reload_completed"
[(scratch)]
{ DONE_ADD_CCC })
-(define_insn "*ctzhi2.libgcc"
- [(set (reg:HI 24)
- (ctz:HI (reg:HI 24)))
- (clobber (reg:QI 26))
- (clobber (reg:CC REG_CC))]
- "reload_completed"
- "%~call __ctzhi2"
- [(set_attr "type" "xcall")])
-
-(define_insn_and_split "*ctzsihi2.libgcc_split"
+;; "*ctzsihi2.libgcc"
+;; "*ffssihi2.libgcc"
+(define_insn "*<code>hi2.libgcc"
[(set (reg:HI 24)
- (truncate:HI (ctz:SI (reg:SI 22))))
+ (ctz_ffs:HI (reg:SI 22)))
(clobber (reg:QI 22))
- (clobber (reg:QI 26))]
- ""
- "#"
- "&& reload_completed"
- [(scratch)]
- { DONE_ADD_CCC })
-
-(define_insn "*ctzsihi2.libgcc"
- [(set (reg:HI 24)
- (truncate:HI (ctz:SI (reg:SI 22))))
- (clobber (reg:QI 22))
- (clobber (reg:QI 26))
- (clobber (reg:CC REG_CC))]
- "reload_completed"
- "%~call __ctzsi2"
- [(set_attr "type" "xcall")])
-
-;; Find First Set
-
-(define_expand "ffshi2"
- [(set (reg:HI 24)
- (match_operand:HI 1 "register_operand" ""))
- (parallel [(set (reg:HI 24)
- (ffs:HI (reg:HI 24)))
- (clobber (reg:QI 26))])
- (set (match_operand:HI 0 "register_operand" "")
- (reg:HI 24))])
-
-(define_expand "ffssi2"
- [(set (reg:SI 22)
- (match_operand:SI 1 "register_operand" ""))
- (parallel [(set (reg:HI 24)
- (truncate:HI (ffs:SI (reg:SI 22))))
- (clobber (reg:QI 22))
- (clobber (reg:QI 26))])
- (set (match_dup 2)
- (reg:HI 24))
- (set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_dup 2)))]
- ""
- {
- operands[2] = gen_reg_rtx (HImode);
- })
-
-(define_insn_and_split "*ffshi2.libgcc_split"
- [(set (reg:HI 24)
- (ffs:HI (reg:HI 24)))
- (clobber (reg:QI 26))]
- ""
- "#"
- "&& reload_completed"
- [(scratch)]
- { DONE_ADD_CCC })
-
-(define_insn "*ffshi2.libgcc"
- [(set (reg:HI 24)
- (ffs:HI (reg:HI 24)))
(clobber (reg:QI 26))
(clobber (reg:CC REG_CC))]
"reload_completed"
- "%~call __ffshi2"
+ "%~call __<code>si2"
[(set_attr "type" "xcall")])
-(define_insn_and_split "*ffssihi2.libgcc_split"
- [(set (reg:HI 24)
- (truncate:HI (ffs:SI (reg:SI 22))))
- (clobber (reg:QI 22))
- (clobber (reg:QI 26))]
- ""
- "#"
- "&& reload_completed"
- [(scratch)]
- { DONE_ADD_CCC })
-
-(define_insn "*ffssihi2.libgcc"
- [(set (reg:HI 24)
- (truncate:HI (ffs:SI (reg:SI 22))))
- (clobber (reg:QI 22))
- (clobber (reg:QI 26))
- (clobber (reg:CC REG_CC))]
- "reload_completed"
- "%~call __ffssi2"
- [(set_attr "type" "xcall")])
;; Copysign