diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2024-03-05 15:29:45 +0100 |
---|---|---|
committer | Georg-Johann Lay <avr@gjlay.de> | 2024-03-05 15:36:15 +0100 |
commit | 08ec4adb0285f6a472865cf386bf035ed0eaebce (patch) | |
tree | 7f02da7bb956424f0338a7dccc343cd9016f5260 /gcc | |
parent | db2e13d11a2c2ee60ff1db46dcacd7cecf30ce8f (diff) | |
download | gcc-08ec4adb0285f6a472865cf386bf035ed0eaebce.zip gcc-08ec4adb0285f6a472865cf386bf035ed0eaebce.tar.gz gcc-08ec4adb0285f6a472865cf386bf035ed0eaebce.tar.bz2 |
AVR: Add two RTL peepholes.
Register alloc may expand a 3-operand arithmetic X = Y o CST as
X = CST
X o= Y
where it may be better to instead:
X = Y
X o= CST
because 1) the first insn may use MOVW for "X = Y", and 2) the
operation may be more efficient when performed with a constant,
for example when ADIW or SBIW can be used, or some bytes of
the constant are 0x00 or 0xff.
gcc/
* config/avr/avr.md: Add two RTL peepholes for PLUS, IOR and AND
in HI, PSI, SI that swap operation order from "X = CST, X o= Y"
to "X = Y, X o= CST".
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/avr/avr.md | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 6bdf468..bc8a59c 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -932,6 +932,55 @@ operands[5] = gen_rtx_REG (HImode, REGNO (operands[3])); }) + +;; Register alloc may expand a 3-operand arithmetic X = Y o CST as +;; X = CST +;; X o= Y +;; where it may be better to instead: +;; X = Y +;; X o= CST +;; because 1) the first insn may use MOVW for "X = Y", and 2) the +;; operation may be more efficient when performed with a constant, +;; for example when ADIW or SBIW can be used, or some bytes of +;; the constant are 0x00 or 0xff. +(define_peephole2 + [(parallel [(set (match_operand:HISI 0 "d_register_operand") + (match_operand:HISI 1 "const_int_operand")) + (clobber (reg:CC REG_CC))]) + (parallel [(set (match_dup 0) + (piaop:HISI (match_dup 0) + (match_operand:HISI 2 "register_operand"))) + (clobber (scratch:QI)) + (clobber (reg:CC REG_CC))])] + "! reg_overlap_mentioned_p (operands[0], operands[2])" + [(parallel [(set (match_dup 0) + (match_dup 2)) + (clobber (reg:CC REG_CC))]) + (parallel [(set (match_dup 0) + (piaop:HISI (match_dup 0) + (match_dup 1))) + (clobber (scratch:QI)) + (clobber (reg:CC REG_CC))])]) + +;; Same, but just for plus:HI without a scratch:QI. +(define_peephole2 + [(parallel [(set (match_operand:HI 0 "d_register_operand") + (match_operand:HI 1 "const_int_operand")) + (clobber (reg:CC REG_CC))]) + (parallel [(set (match_dup 0) + (plus:HI (match_dup 0) + (match_operand:HI 2 "register_operand"))) + (clobber (reg:CC REG_CC))])] + "! reg_overlap_mentioned_p (operands[0], operands[2])" + [(parallel [(set (match_dup 0) + (match_dup 2)) + (clobber (reg:CC REG_CC))]) + (parallel [(set (match_dup 0) + (plus:HI (match_dup 0) + (match_dup 1))) + (clobber (reg:CC REG_CC))])]) + + ;; For LPM loads from AS1 we split ;; R = *Z ;; to @@ -1644,9 +1693,9 @@ [(set_attr "length" "6") (set_attr "adjust_len" "addto_sp")]) -;; "*addhi3" -;; "*addhq3" "*adduhq3" -;; "*addha3" "*adduha3" +;; "*addhi3_split" +;; "*addhq3_split" "*adduhq3_split" +;; "*addha3_split" "*adduha3_split" (define_insn_and_split "*add<mode>3_split" [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d") (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0") @@ -1661,6 +1710,9 @@ "" [(set_attr "isa" "*,*,adiw,*")]) +;; "*addhi3" +;; "*addhq3" "*adduhq3" +;; "*addha3" "*adduha3" (define_insn "*add<mode>3" [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d") (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0") @@ -1732,6 +1784,9 @@ (clobber (match_dup 3)) (clobber (reg:CC REG_CC))])]) +;; "*addhi3_clobber" +;; "*addhq3_clobber" "*adduhq3_clobber" +;; "*addha3_clobber" "*adduha3_clobber" (define_insn "*add<mode>3_clobber" [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r") (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0") |