diff options
Diffstat (limited to 'gcc/config/avr')
-rw-r--r-- | gcc/config/avr/avr-dimode.md | 87 | ||||
-rw-r--r-- | gcc/config/avr/avr-fixed.md | 129 | ||||
-rw-r--r-- | gcc/config/avr/avr-log.cc | 1 | ||||
-rw-r--r-- | gcc/config/avr/avr-mcus.def | 17 | ||||
-rw-r--r-- | gcc/config/avr/avr-passes.cc | 224 | ||||
-rw-r--r-- | gcc/config/avr/avr-passes.def | 20 | ||||
-rw-r--r-- | gcc/config/avr/avr-protos.h | 7 | ||||
-rw-r--r-- | gcc/config/avr/avr.cc | 347 | ||||
-rw-r--r-- | gcc/config/avr/avr.h | 18 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 1433 | ||||
-rw-r--r-- | gcc/config/avr/avr.opt | 12 | ||||
-rw-r--r-- | gcc/config/avr/avr.opt.urls | 8 | ||||
-rw-r--r-- | gcc/config/avr/specs.h | 2 |
13 files changed, 1164 insertions, 1141 deletions
diff --git a/gcc/config/avr/avr-dimode.md b/gcc/config/avr/avr-dimode.md index 903bfbf..66ba5a9 100644 --- a/gcc/config/avr/avr-dimode.md +++ b/gcc/config/avr/avr-dimode.md @@ -101,10 +101,8 @@ "avr_have_dimode" "#" "&& reload_completed" - [(parallel [(set (reg:ALL8 ACC_A) - (plus:ALL8 (reg:ALL8 ACC_A) - (reg:ALL8 ACC_B))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*add<mode>3_insn" [(set (reg:ALL8 ACC_A) @@ -122,10 +120,8 @@ "avr_have_dimode" "#" "&& reload_completed" - [(parallel [(set (reg:DI ACC_A) - (plus:DI (reg:DI ACC_A) - (sign_extend:DI (reg:QI REG_X)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*adddi3_const8_insn" [(set (reg:DI ACC_A) @@ -146,12 +142,10 @@ (match_operand:ALL8 0 "const_operand" "n Ynn")))] "avr_have_dimode && !s8_operand (operands[0], VOIDmode)" - "#" - "&& reload_completed" - [(parallel [(set (reg:ALL8 ACC_A) - (plus:ALL8 (reg:ALL8 ACC_A) - (match_dup 0))) - (clobber (reg:CC REG_CC))])]) + "#" + "&& reload_completed" + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*add<mode>3_const_insn" [(set (reg:ALL8 ACC_A) @@ -211,10 +205,8 @@ "avr_have_dimode" "#" "&& reload_completed" - [(parallel [(set (reg:ALL8 ACC_A) - (minus:ALL8 (reg:ALL8 ACC_A) - (reg:ALL8 ACC_B))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sub<mode>3_insn" [(set (reg:ALL8 ACC_A) @@ -236,10 +228,8 @@ "avr_have_dimode" "#" "&& reload_completed" - [(parallel [(set (reg:ALL8 ACC_A) - (minus:ALL8 (reg:ALL8 ACC_A) - (match_dup 0))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sub<mode>3_const_insn" [(set (reg:ALL8 ACC_A) @@ -288,10 +278,8 @@ "avr_have_dimode" "#" "&& reload_completed" - [(parallel [(set (reg:ALL8S ACC_A) - (ss_addsub:ALL8S (reg:ALL8S ACC_A) - (reg:ALL8S ACC_B))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code_stdname><mode>3_insn" [(set (reg:ALL8S ACC_A) @@ -309,10 +297,8 @@ "avr_have_dimode" "#" "&& reload_completed" - [(parallel [(set (reg:ALL8S ACC_A) - (ss_addsub:ALL8S (reg:ALL8S ACC_A) - (match_dup 0))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code_stdname><mode>3_const_insn" [(set (reg:ALL8S ACC_A) @@ -361,10 +347,8 @@ "avr_have_dimode" "#" "&& reload_completed" - [(parallel [(set (reg:ALL8U ACC_A) - (us_addsub:ALL8U (reg:ALL8U ACC_A) - (reg:ALL8U ACC_B))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code_stdname><mode>3_insn" [(set (reg:ALL8U ACC_A) @@ -382,10 +366,8 @@ "avr_have_dimode" "#" "&& reload_completed" - [(parallel [(set (reg:ALL8U ACC_A) - (us_addsub:ALL8U (reg:ALL8U ACC_A) - (match_operand:ALL8U 0 "const_operand" "n Ynn"))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code_stdname><mode>3_const_insn" [(set (reg:ALL8U ACC_A) @@ -421,9 +403,8 @@ "avr_have_dimode" "#" "&& reload_completed" - [(parallel [(set (reg:DI ACC_A) - (neg:DI (reg:DI ACC_A))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*negdi2_insn" [(set (reg:DI ACC_A) @@ -500,7 +481,7 @@ "avr_have_dimode" "#" "&& reload_completed" - [(const_int 0)] + [(scratch)] { emit_insn (gen_compare_<mode>2 ()); emit_jump_insn (gen_conditional_jump (operands[0], operands[1])); @@ -529,7 +510,7 @@ "avr_have_dimode" "#" "&& reload_completed" - [(const_int 0)] + [(scratch)] { emit_insn (gen_compare_const8_di2 ()); emit_jump_insn (gen_conditional_jump (operands[0], operands[1])); @@ -556,7 +537,7 @@ && !s8_operand (operands[1], VOIDmode)" "#" "&& reload_completed" - [(const_int 0)] + [(scratch)] { emit_insn (gen_compare_const_<mode>2 (operands[1], operands[3])); emit_jump_insn (gen_conditional_jump (operands[0], operands[2])); @@ -629,10 +610,8 @@ "avr_have_dimode" "#" "&& reload_completed" - [(parallel [(set (reg:ALL8 ACC_A) - (di_shifts:ALL8 (reg:ALL8 ACC_A) - (reg:QI 16))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code_stdname><mode>3_insn" [(set (reg:ALL8 ACC_A) @@ -674,14 +653,10 @@ (clobber (reg:HI REG_Z))] "avr_have_dimode && AVR_HAVE_MUL" - "#" - "&& reload_completed" - [(parallel [(set (reg:DI ACC_A) - (mult:DI (any_extend:DI (reg:SI 18)) - (any_extend:DI (reg:SI 22)))) - (clobber (reg:HI REG_X)) - (clobber (reg:HI REG_Z)) - (clobber (reg:CC REG_CC))])]) + "#" + "&& reload_completed" + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<extend_u>mulsidi3_insn" [(set (reg:DI ACC_A) diff --git a/gcc/config/avr/avr-fixed.md b/gcc/config/avr/avr-fixed.md index ce46beb..22061fc 100644 --- a/gcc/config/avr/avr-fixed.md +++ b/gcc/config/avr/avr-fixed.md @@ -62,10 +62,8 @@ "<FIXED_B:MODE>mode != <FIXED_A:MODE>mode" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (fract_convert:FIXED_A - (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*fract<FIXED_B:mode><FIXED_A:mode>2" [(set (match_operand:FIXED_A 0 "register_operand" "=r") @@ -86,10 +84,8 @@ "<FIXED_B:MODE>mode != <FIXED_A:MODE>mode" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (unsigned_fract_convert:FIXED_A - (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*fractuns<FIXED_B:mode><FIXED_A:mode>2" [(set (match_operand:FIXED_A 0 "register_operand" "=r") @@ -124,10 +120,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ss_addsub:ALL124S (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code_stdname><mode>3" [(set (match_operand:ALL124S 0 "register_operand" "=??d,d") @@ -149,10 +143,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (us_addsub:ALL124U (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code_stdname><mode>3" [(set (match_operand:ALL124U 0 "register_operand" "=??r,d") @@ -189,9 +181,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ss_neg:QQ (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*ssnegqq2" [(set (match_operand:QQ 0 "register_operand" "=r") @@ -207,9 +198,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ss_abs:QQ (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*ssabsqq2" [(set (match_operand:QQ 0 "register_operand" "=r") @@ -241,9 +231,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:ALL2S 24) - (ss_abs_neg:ALL2S (reg:ALL2S 24))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code_stdname><mode>2" [(set (reg:ALL2S 24) @@ -261,9 +250,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:ALL4S 22) - (ss_abs_neg:ALL4S (reg:ALL4S 22))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code_stdname><mode>2" [(set (reg:ALL4S 22) @@ -296,10 +284,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:QQ (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulqq3_enh" [(set (match_operand:QQ 0 "register_operand" "=r") @@ -317,10 +303,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:UQQ (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*muluqq3_enh" [(set (match_operand:UQQ 0 "register_operand" "=r") @@ -377,12 +361,8 @@ "!AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:QQ 23) - (mult:QQ (reg:QQ 24) - (reg:QQ 25))) - (clobber (reg:QI 22)) - (clobber (reg:HI 24)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulqq3.call" [(set (reg:QQ 23) @@ -425,11 +405,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:ALL2QA 24) - (mult:ALL2QA (reg:ALL2QA 18) - (reg:ALL2QA 26))) - (clobber (reg:HI 22)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mul<mode>3.call" [(set (reg:ALL2QA 24) @@ -468,10 +445,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:ALL4A 24) - (mult:ALL4A (reg:ALL4A 16) - (reg:ALL4A 20))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mul<mode>3.call" [(set (reg:ALL4A 24) @@ -514,11 +489,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:ALL1Q 24) - (usdiv:ALL1Q (reg:ALL1Q 25) - (reg:ALL1Q 22))) - (clobber (reg:QI 25)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code><mode>3.call" [(set (reg:ALL1Q 24) @@ -560,12 +532,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:ALL2QA 24) - (usdiv:ALL2QA (reg:ALL2QA 26) - (reg:ALL2QA 22))) - (clobber (reg:HI 26)) - (clobber (reg:QI 21)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code><mode>3.call" [(set (reg:ALL2QA 24) @@ -608,12 +576,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:ALL4A 22) - (usdiv:ALL4A (reg:ALL4A 24) - (reg:ALL4A 18))) - (clobber (reg:HI 26)) - (clobber (reg:HI 30)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<code><mode>3.call" [(set (reg:ALL4A 22) @@ -684,12 +648,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (unspec:ALL124QA [(match_dup 1) - (match_dup 2) - (const_int 0)] - UNSPEC_ROUND)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*round<mode>3_const" [(set (match_operand:ALL124QA 0 "register_operand" "=d") @@ -714,11 +674,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:ALL1Q 24) - (unspec:ALL1Q [(reg:ALL1Q 22) - (reg:QI 24)] UNSPEC_ROUND)) - (clobber (reg:ALL1Q 22)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*round<mode>3.libgcc" [(set (reg:ALL1Q 24) @@ -740,11 +697,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:ALL2QA 24) - (unspec:ALL2QA [(reg:ALL2QA 22) - (reg:QI 24)] UNSPEC_ROUND)) - (clobber (reg:ALL2QA 22)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*round<mode>3.libgcc" [(set (reg:ALL2QA 24) @@ -766,11 +720,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:ALL4QA 22) - (unspec:ALL4QA [(reg:ALL4QA 18) - (reg:QI 24)] UNSPEC_ROUND)) - (clobber (reg:ALL4QA 18)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*round<mode>3.libgcc" [(set (reg:ALL4QA 22) diff --git a/gcc/config/avr/avr-log.cc b/gcc/config/avr/avr-log.cc index fadb3ca..972ba6b 100644 --- a/gcc/config/avr/avr-log.cc +++ b/gcc/config/avr/avr-log.cc @@ -373,7 +373,6 @@ avr_log_set_avr_log (void) SET_DUMP_DETAIL (insn_addresses); SET_DUMP_DETAIL (legitimate_address_p); SET_DUMP_DETAIL (legitimize_address); - SET_DUMP_DETAIL (legitimize_reload_address); SET_DUMP_DETAIL (progmem); SET_DUMP_DETAIL (rtx_costs); diff --git a/gcc/config/avr/avr-mcus.def b/gcc/config/avr/avr-mcus.def index 9f79a9a..2e7c8ac 100644 --- a/gcc/config/avr/avr-mcus.def +++ b/gcc/config/avr/avr-mcus.def @@ -313,6 +313,10 @@ AVR_MCU ("avr64da28", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR AVR_MCU ("avr64da32", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA32__", 0x6000, 0x0, 0x10000, 0) AVR_MCU ("avr64da48", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA48__", 0x6000, 0x0, 0x10000, 0) AVR_MCU ("avr64da64", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA64__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da28s", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA28S__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da32s", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA32S__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da48s", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA48S__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da64s", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA64S__", 0x6000, 0x0, 0x10000, 0) AVR_MCU ("avr64db28", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DB28__", 0x6000, 0x0, 0x10000, 0) AVR_MCU ("avr64db32", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DB32__", 0x6000, 0x0, 0x10000, 0) AVR_MCU ("avr64db48", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DB48__", 0x6000, 0x0, 0x10000, 0) @@ -326,6 +330,9 @@ AVR_MCU ("avr64du32", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR AVR_MCU ("avr64ea28", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64EA28__", 0x6800, 0x0, 0x10000, 0) AVR_MCU ("avr64ea32", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64EA32__", 0x6800, 0x0, 0x10000, 0) AVR_MCU ("avr64ea48", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64EA48__", 0x6800, 0x0, 0x10000, 0) +AVR_MCU ("avr64sd28", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64SD28__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64sd32", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64SD32__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64sd48", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64SD48__", 0x6000, 0x0, 0x10000, 0) /* Xmega, Flash + RAM < 64K, flash visible in RAM address space */ AVR_MCU ("avrxmega3", ARCH_AVRXMEGA3, AVR_ISA_NONE, NULL, 0x3f00, 0x0, 0x8000, 0) AVR_MCU ("attiny202", ARCH_AVRXMEGA3, AVR_CVT | AVR_ISA_RCALL, "__AVR_ATtiny202__", 0x3f80, 0x0, 0x800, 0x8000) @@ -386,6 +393,9 @@ AVR_MCU ("avr16du32", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR AVR_MCU ("avr32da28", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA28__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32da32", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA32__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32da48", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA48__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32da28s", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA28S__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32da32s", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA32S__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32da48s", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA48S__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32db28", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DB28__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32db32", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DB32__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32db48", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DB48__", 0x7000, 0x0, 0x8000, 0x8000) @@ -407,6 +417,9 @@ AVR_MCU ("avr16ea48", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR AVR_MCU ("avr32ea28", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32EA28__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32ea32", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32EA32__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32ea48", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32EA48__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32sd20", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32SD20__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32sd28", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32SD28__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32sd32", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32SD32__", 0x7000, 0x0, 0x8000, 0x8000) /* Xmega, 64K < Flash <= 128K, RAM <= 64K */ AVR_MCU ("avrxmega4", ARCH_AVRXMEGA4, AVR_ISA_NONE, NULL, 0x2000, 0x0, 0x11000, 0) AVR_MCU ("atxmega64a3", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_ATxmega64A3__", 0x2000, 0x0, 0x11000, 0) @@ -421,6 +434,10 @@ AVR_MCU ("avr128da28", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR AVR_MCU ("avr128da32", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA32__", 0x4000, 0x0, 0x20000, 0) AVR_MCU ("avr128da48", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA48__", 0x4000, 0x0, 0x20000, 0) AVR_MCU ("avr128da64", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA64__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da28s", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA28S__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da32s", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA32S__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da48s", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA48S__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da64s", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA64S__", 0x4000, 0x0, 0x20000, 0) AVR_MCU ("avr128db28", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DB28__", 0x4000, 0x0, 0x20000, 0) AVR_MCU ("avr128db32", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DB32__", 0x4000, 0x0, 0x20000, 0) AVR_MCU ("avr128db48", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DB48__", 0x4000, 0x0, 0x20000, 0) diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc index 184619a..69df6d2 100644 --- a/gcc/config/avr/avr-passes.cc +++ b/gcc/config/avr/avr-passes.cc @@ -29,6 +29,7 @@ #include "target.h" #include "rtl.h" #include "tree.h" +#include "diagnostic-core.h" #include "cfghooks.h" #include "cfganal.h" #include "df.h" @@ -3166,8 +3167,7 @@ bbinfo_t::optimize_one_block (bool &changed) || (bbinfo_t::try_split_any_p && od.try_split_any (this)) || (bbinfo_t::try_mem0_p && od.try_mem0 (this))); - rtx_insn *new_insns = get_insns (); - end_sequence (); + rtx_insn *new_insns = end_sequence (); gcc_assert (found == (od.n_new_insns >= 0)); @@ -3942,10 +3942,7 @@ avr_parallel_insn_from_insns (rtx_insn *i[5]) PATTERN (i[3]), PATTERN (i[4])); start_sequence (); emit (gen_rtx_PARALLEL (VOIDmode, vec)); - rtx_insn *insn = get_insns (); - end_sequence (); - - return insn; + return end_sequence (); } @@ -4123,9 +4120,8 @@ avr_optimize_casesi (rtx_insn *insns[5], rtx *xop) JUMP_LABEL (cbranch) = xop[4]; ++LABEL_NUSES (xop[4]); - rtx_insn *seq1 = get_insns (); rtx_insn *last1 = get_last_insn (); - end_sequence (); + rtx_insn *seq1 = end_sequence (); emit_insn_after (seq1, insns[2]); @@ -4144,9 +4140,8 @@ avr_optimize_casesi (rtx_insn *insns[5], rtx *xop) emit_insn (pat_4); - rtx_insn *seq2 = get_insns (); rtx_insn *last2 = get_last_insn (); - end_sequence (); + rtx_insn *seq2 = end_sequence (); emit_insn_after (seq2, insns[3]); @@ -4848,6 +4843,201 @@ avr_pass_fuse_add::execute1 (function *func) ////////////////////////////////////////////////////////////////////////////// +// Fuse 2 move insns after combine. + +static const pass_data avr_pass_data_2moves = +{ + RTL_PASS, // type + "", // name (will be patched) + OPTGROUP_NONE, // optinfo_flags + TV_DF_SCAN, // tv_id + 0, // properties_required + 0, // properties_provided + 0, // properties_destroyed + 0, // todo_flags_start + 0 // todo_flags_finish +}; + +class avr_pass_2moves : public rtl_opt_pass +{ +public: + avr_pass_2moves (gcc::context *ctxt, const char *name) + : rtl_opt_pass (avr_pass_data_2moves, ctxt) + { + this->name = name; + } + + unsigned int execute (function *func) final override + { + if (optimize && avropt_fuse_move2) + { + bool changed = false; + basic_block bb; + + FOR_EACH_BB_FN (bb, func) + { + changed |= optimize_2moves_bb (bb); + } + + if (changed) + { + df_note_add_problem (); + df_analyze (); + } + } + + return 0; + } + + bool optimize_2moves (rtx_insn *, rtx_insn *); + bool optimize_2moves_bb (basic_block); +}; // avr_pass_2moves + +bool +avr_pass_2moves::optimize_2moves_bb (basic_block bb) +{ + bool changed = false; + rtx_insn *insn1 = nullptr; + rtx_insn *insn2 = nullptr; + rtx_insn *curr; + + FOR_BB_INSNS (bb, curr) + { + if (insn1 && INSN_P (insn1) + && insn2 && INSN_P (insn2)) + changed |= optimize_2moves (insn1, insn2); + + insn1 = insn2; + insn2 = curr; + } + + return changed; +} + +bool +avr_pass_2moves::optimize_2moves (rtx_insn *insn1, rtx_insn *insn2) +{ + bool good = false; + bool bad = false; + rtx set1, dest1, src1; + rtx set2, dest2, src2; + + if ((set1 = single_set (insn1)) + && (set2 = single_set (insn2)) + && (src1 = SET_SRC (set1)) + && REG_P (src2 = SET_SRC (set2)) + && REG_P (dest1 = SET_DEST (set1)) + && REG_P (dest2 = SET_DEST (set2)) + && rtx_equal_p (dest1, src2) + // Now we have: + // insn1: dest1 = src1 + // insn2: dest2 = dest1 + && REGNO (dest1) >= FIRST_PSEUDO_REGISTER + // Paranoia. + && GET_CODE (PATTERN (insn1)) != PARALLEL + && GET_CODE (PATTERN (insn2)) != PARALLEL + && (rtx_equal_p (dest2, src1) + || !reg_overlap_mentioned_p (dest2, src1))) + { + avr_dump ("\n;; Found 2moves:\n%r\n%r\n", insn1, insn2); + avr_dump (";; reg %d: insn uses uids:", REGNO (dest1)); + + // Go check that dest1 is used exactly once, namely by insn2. + + df_ref use = DF_REG_USE_CHAIN (REGNO (dest1)); + for (; use; use = DF_REF_NEXT_REG (use)) + { + rtx_insn *user = DF_REF_INSN (use); + avr_dump (" %d", INSN_UID (user)); + good |= INSN_UID (user) == INSN_UID (insn2); + bad |= INSN_UID (user) != INSN_UID (insn2); + } + avr_dump (".\n"); + + if (good && !bad + // Propagate src1 to insn2: + // insn1: # Deleted + // insn2: dest2 = src1 + && validate_change (insn2, &SET_SRC (set2), src1, false)) + { + SET_INSN_DELETED (insn1); + return true; + } + } + + if (good && !bad) + avr_dump (";; Failed\n"); + + return false; +} + + + +////////////////////////////////////////////////////////////////////////////// +// Split insns with nonzero_bits() after combine. + +static const pass_data avr_pass_data_split_nzb = +{ + RTL_PASS, // type + "", // name (will be patched) + OPTGROUP_NONE, // optinfo_flags + TV_DF_SCAN, // tv_id + 0, // properties_required + 0, // properties_provided + 0, // properties_destroyed + 0, // todo_flags_start + 0 // todo_flags_finish +}; + +class avr_pass_split_nzb : public rtl_opt_pass +{ +public: + avr_pass_split_nzb (gcc::context *ctxt, const char *name) + : rtl_opt_pass (avr_pass_data_split_nzb, ctxt) + { + this->name = name; + } + + unsigned int execute (function *) final override + { + if (avropt_use_nonzero_bits) + split_nzb_insns (); + return 0; + } + + void split_nzb_insns (); + +}; // avr_pass_split_nzb + + +void +avr_pass_split_nzb::split_nzb_insns () +{ + rtx_insn *next; + + for (rtx_insn *insn = get_insns (); insn; insn = next) + { + next = NEXT_INSN (insn); + + if (INSN_P (insn) + && single_set (insn) + && get_attr_nzb (insn) == NZB_YES) + { + rtx_insn *last = try_split (PATTERN (insn), insn, 1 /*last*/); + + // The nonzero_bits() insns *must* split. If not: ICE. + if (last == insn) + { + debug_rtx (insn); + internal_error ("failed to split insn"); + } + } + } +} + + + +////////////////////////////////////////////////////////////////////////////// // Split shift insns after peephole2 / befor avr-fuse-move. static const pass_data avr_pass_data_split_after_peephole2 = @@ -5645,6 +5835,20 @@ make_avr_pass_casesi (gcc::context *ctxt) return new avr_pass_casesi (ctxt, "avr-casesi"); } +// Optimize 2 consecutive moves after combine. + +rtl_opt_pass * +make_avr_pass_2moves (gcc::context *ctxt) +{ + return new avr_pass_2moves (ctxt, "avr-2moves"); +} + +rtl_opt_pass * +make_avr_pass_split_nzb (gcc::context *ctxt) +{ + return new avr_pass_split_nzb (ctxt, "avr-split-nzb"); +} + // Try to replace 2 cbranch insns with 1 comparison and 2 branches. rtl_opt_pass * diff --git a/gcc/config/avr/avr-passes.def b/gcc/config/avr/avr-passes.def index 091005e..d668c7f 100644 --- a/gcc/config/avr/avr-passes.def +++ b/gcc/config/avr/avr-passes.def @@ -74,6 +74,26 @@ INSERT_PASS_BEFORE (pass_free_cfg, 1, avr_pass_recompute_notes); INSERT_PASS_AFTER (pass_expand, 1, avr_pass_casesi); +/* Insn combine may come up with superfluous reg-reg moves, where the combine + people say that these are no problem since reg-alloc is supposed to optimize + them. The issue is that the lower-subreg pass sitting between combine and + reg-alloc may split such moves, coming up with a zoo of subregs which are + only handled poorly by the register allocator. */ + +INSERT_PASS_AFTER (pass_combine, 1, avr_pass_2moves); + +/* Some combine insns have nonzero_bits() in their condition, though insns + should not use such stuff in their condition. Therefore, we split such + insn into something without nonzero_bits() in their condition right after + insn combine. + + Since neither split_all_insns() nor split_all_insns_noflow() work at that + point (presumably since there are splits involving branches), we split + respective insns (and only such insns) by hand. Respective insns are + tagged with insn attribute nzb = "yes" so that they are easy to spot. */ + +INSERT_PASS_AFTER (pass_combine, 1, avr_pass_split_nzb); + /* If-else decision trees generated for switch / case may produce sequences like diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index 83137c7..8ba1945 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -136,6 +136,7 @@ extern bool reg_unused_after (rtx_insn *insn, rtx reg); extern int avr_jump_mode (rtx x, rtx_insn *insn, int = 0); extern bool test_hard_reg_class (enum reg_class rclass, rtx x); extern bool jump_over_one_insn_p (rtx_insn *insn, rtx dest); +extern bool avr_nonzero_bits_lsr_operands_p (rtx_code, rtx *); extern void avr_final_prescan_insn (rtx_insn *insn, rtx *operand, int num_operands); @@ -145,7 +146,6 @@ extern void out_shift_with_cnt (const char *templ, rtx_insn *insn, extern enum reg_class avr_mode_code_base_reg_class (machine_mode, addr_space_t, rtx_code, rtx_code); extern bool avr_regno_mode_code_ok_for_base_p (int, machine_mode, addr_space_t, rtx_code, rtx_code); extern rtx avr_incoming_return_addr_rtx (void); -extern rtx avr_legitimize_reload_address (rtx*, machine_mode, int, int, int, int, rtx (*)(rtx,int)); extern bool avr_adiw_reg_p (rtx); extern bool avr_mem_flash_p (rtx); extern bool avr_mem_flashx_p (rtx); @@ -167,6 +167,8 @@ regmask (machine_mode mode, unsigned regno) extern void avr_fix_inputs (rtx*, unsigned, unsigned); extern bool avr_emit3_fix_outputs (rtx (*)(rtx,rtx,rtx), rtx*, unsigned, unsigned); +extern rtx avr_add_ccclobber (rtx_insn *); +#define DONE_ADD_CCC emit (avr_add_ccclobber (curr_insn)); DONE; extern rtx lpm_reg_rtx; extern rtx lpm_addr_reg_rtx; @@ -205,7 +207,9 @@ extern rtl_opt_pass *make_avr_pass_pre_proep (gcc::context *); extern rtl_opt_pass *make_avr_pass_recompute_notes (gcc::context *); extern rtl_opt_pass *make_avr_pass_casesi (gcc::context *); extern rtl_opt_pass *make_avr_pass_ifelse (gcc::context *); +extern rtl_opt_pass *make_avr_pass_split_nzb (gcc::context *); extern rtl_opt_pass *make_avr_pass_split_after_peephole2 (gcc::context *); +extern rtl_opt_pass *make_avr_pass_2moves (gcc::context *); #ifdef RTX_CODE extern bool avr_casei_sequence_check_operands (rtx *xop); extern bool avr_split_fake_addressing_move (rtx_insn *insn, rtx *operands); @@ -236,7 +240,6 @@ typedef struct unsigned insn_addresses :1; unsigned legitimate_address_p :1; unsigned legitimize_address :1; - unsigned legitimize_reload_address :1; unsigned progmem :1; unsigned rtx_costs :1; } avr_log_t; diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 71c03b4..ae49d4d 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -411,6 +411,29 @@ avr_to_int_mode (rtx x) } +/* Return the pattern of INSN, but with added (clobber (reg:CC REG_CC)). + The pattern of INSN must be a PARALLEL or a SET. INSN is unchanged. */ + +rtx +avr_add_ccclobber (rtx_insn *insn) +{ + rtx pat = PATTERN (insn); + gcc_assert (GET_CODE (pat) == SET || GET_CODE (pat) == PARALLEL); + + int newlen = GET_CODE (pat) == SET ? 2 : 1 + XVECLEN (pat, 0); + rtx newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (newlen)); + rtx elt0 = GET_CODE (pat) == SET ? pat : XVECEXP (pat, 0, 0); + + XVECEXP (newpat, 0, 0) = copy_rtx (elt0); + XVECEXP (newpat, 0, newlen - 1) = gen_rtx_CLOBBER (VOIDmode, cc_reg_rtx); + + for (int i = 1; i < newlen - 1; ++i) + XVECEXP (newpat, 0, i) = copy_rtx (XVECEXP (pat, 0, i)); + + return newpat; +} + + /* Return true if hard register REG supports the ADIW and SBIW instructions. */ bool @@ -430,13 +453,6 @@ avr_ld_regno_p (int regno) } -static bool -ra_in_progress () -{ - return avropt_lra_p ? lra_in_progress : reload_in_progress; -} - - /* Set `avr_arch' as specified by `-mmcu='. Return true on success. */ @@ -567,6 +583,7 @@ avr_option_override (void) { opt_pass *extra_peephole2 = g->get_passes ()->get_pass_peephole2 ()->clone (); + extra_peephole2->name = "avr-peep2-after-fuse-move"; register_pass_info peep2_2_info = { extra_peephole2, "avr-fuse-move", 1, PASS_POS_INSERT_AFTER }; @@ -1659,8 +1676,7 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set) -size_cfa))); } - fp_plus_insns = get_insns (); - end_sequence (); + fp_plus_insns = end_sequence (); /************ Method 2: Adjust Stack pointer ************/ @@ -1692,8 +1708,7 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set) RTX_FRAME_RELATED_P (insn) = 1; } - sp_plus_insns = get_insns (); - end_sequence (); + sp_plus_insns = end_sequence (); /************ Use shortest method ************/ @@ -2059,8 +2074,7 @@ avr_expand_epilogue (bool sibcall_p) emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp, GEN_INT (irq_state))); - rtx_insn *fp_plus_insns = get_insns (); - end_sequence (); + rtx_insn *fp_plus_insns = end_sequence (); /********** Method 2: Adjust Stack pointer **********/ @@ -2071,8 +2085,7 @@ avr_expand_epilogue (bool sibcall_p) emit_move_insn (stack_pointer_rtx, plus_constant (Pmode, stack_pointer_rtx, size)); - rtx_insn *sp_plus_insns = get_insns (); - end_sequence (); + rtx_insn *sp_plus_insns = end_sequence (); /************ Use shortest method ************/ @@ -2327,8 +2340,8 @@ avr_legitimate_address_p (machine_mode mode, rtx x, bool strict) if (avr_log.legitimate_address_p) { avr_edump ("\n%?: ret=%d, mode=%m strict=%d " - "reload_completed=%d ra_in_progress=%d %s:", - ok, mode, strict, reload_completed, ra_in_progress (), + "reload_completed=%d lra_in_progress=%d %s:", + ok, mode, strict, reload_completed, lra_in_progress, reg_renumber ? "(reg_renumber)" : ""); if (GET_CODE (x) == PLUS @@ -2398,88 +2411,6 @@ avr_legitimize_address (rtx x, rtx oldx, machine_mode mode) } -/* Implement `LEGITIMIZE_RELOAD_ADDRESS'. */ -/* This will allow register R26/27 to be used where it is no worse than normal - base pointers R28/29 or R30/31. For example, if base offset is greater - than 63 bytes or for R++ or --R addressing. */ - -rtx -avr_legitimize_reload_address (rtx *px, machine_mode mode, int opnum, - int type, int addr_type, int /*ind_levels*/, - rtx (*mk_memloc)(rtx,int)) -{ - rtx x = *px; - - if (avr_log.legitimize_reload_address) - avr_edump ("\n%?:%m %r\n", mode, x); - - if (1 && (GET_CODE (x) == POST_INC - || GET_CODE (x) == PRE_DEC)) - { - push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0), - POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0, - opnum, RELOAD_OTHER); - - if (avr_log.legitimize_reload_address) - avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n", - POINTER_REGS, XEXP (x, 0), XEXP (x, 0)); - - return x; - } - - if (GET_CODE (x) == PLUS - && REG_P (XEXP (x, 0)) - && reg_equiv_constant (REGNO (XEXP (x, 0))) == 0 - && CONST_INT_P (XEXP (x, 1)) - && INTVAL (XEXP (x, 1)) >= 1) - { - bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode); - - if (fit) - { - if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0) - { - int regno = REGNO (XEXP (x, 0)); - rtx mem = mk_memloc (x, regno); - - push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL, - POINTER_REGS, Pmode, VOIDmode, 0, 0, - 1, (enum reload_type) addr_type); - - if (avr_log.legitimize_reload_address) - avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n", - POINTER_REGS, XEXP (mem, 0), NULL_RTX); - - push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL, - BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0, - opnum, (enum reload_type) type); - - if (avr_log.legitimize_reload_address) - avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n", - BASE_POINTER_REGS, mem, NULL_RTX); - - return x; - } - } - else if (! (frame_pointer_needed - && XEXP (x, 0) == frame_pointer_rtx)) - { - push_reload (x, NULL_RTX, px, NULL, - POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0, - opnum, (enum reload_type) type); - - if (avr_log.legitimize_reload_address) - avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n", - POINTER_REGS, x, NULL_RTX); - - return x; - } - } - - return NULL_RTX; -} - - /* Helper function to print assembler resp. track instruction sequence lengths. Always return "". @@ -11736,6 +11667,23 @@ avr_handle_isr_attribute (tree node, tree *attrs, const char *name) } +/* Helper for `avr_insert_attributes'. + Return the section name from attribute "section" in attribute list ATTRS. + When no "section" attribute is present, then return nullptr. */ + +static const char * +avr_attrs_section_name (tree attrs) +{ + if (tree a_sec = lookup_attribute ("section", attrs)) + if (TREE_VALUE (a_sec)) + if (tree t_section_name = TREE_VALUE (TREE_VALUE (a_sec))) + if (TREE_CODE (t_section_name) == STRING_CST) + return TREE_STRING_POINTER (t_section_name); + + return nullptr; +} + + /* Implement `TARGET_INSERT_ATTRIBUTES'. */ static void @@ -11768,25 +11716,31 @@ avr_insert_attributes (tree node, tree *attributes) NULL, *attributes); } + const char *section_name = avr_attrs_section_name (*attributes); + + // When the function is in an .initN or .finiN section, then add "used" + // since such functions are never called. + if (section_name + && strlen (section_name) == strlen (".init*") + && IN_RANGE (section_name[5], '0', '9') + && (startswith (section_name, ".init") + || startswith (section_name, ".fini")) + && !lookup_attribute ("used", *attributes)) + { + *attributes = tree_cons (get_identifier ("used"), NULL, *attributes); + } + #if defined WITH_AVRLIBC if (avropt_call_main == 0 && TREE_CODE (node) == FUNCTION_DECL && MAIN_NAME_P (DECL_NAME (node))) { - const char *s_section_name = nullptr; - - if (tree a_sec = lookup_attribute ("section", *attributes)) - if (TREE_VALUE (a_sec)) - if (tree t_section_name = TREE_VALUE (TREE_VALUE (a_sec))) - if (TREE_CODE (t_section_name) == STRING_CST) - s_section_name = TREE_STRING_POINTER (t_section_name); - - bool in_init9_p = s_section_name && !strcmp (s_section_name, ".init9"); + bool in_init9_p = section_name && !strcmp (section_name, ".init9"); - if (s_section_name && !in_init9_p) + if (section_name && !in_init9_p) { warning (OPT_Wattributes, "%<section(\"%s\")%> attribute on main" - " function inhibits %<-mno-call-main%>", s_section_name); + " function inhibits %<-mno-call-main%>", section_name); } else { @@ -12683,6 +12637,50 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, } } + // Insns with nonzero_bits() == 1 in the condition. + if (avropt_use_nonzero_bits + && mode == QImode + && (code == AND || code == IOR || code == XOR) + && REG_P (XEXP (x, 1))) + { + // "*nzb=1.<code>.lsr_split" + // "*nzb=1.<code>.lsr.not_split" + bool is_nzb = (GET_CODE (XEXP (x, 0)) == LSHIFTRT + && (REG_P (XEXP (XEXP (x, 0), 0)) + || GET_CODE (XEXP (XEXP (x, 0), 0)) == XOR) + && const_0_to_7_operand (XEXP (XEXP (x, 0), 1), QImode)); + // "*nzb=1.<code>.zerox_split" + // "*nzb=1.<code>.zerox.not_split" + is_nzb |= (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT + && (REG_P (XEXP (XEXP (x, 0), 0)) + || GET_CODE (XEXP (XEXP (x, 0), 0)) == XOR) + && const1_operand (XEXP (XEXP (x, 0), 1), QImode) + && const_0_to_7_operand (XEXP (XEXP (x, 0), 2), QImode)); + // "*nzb=1.<code>.ge0_split" + is_nzb |= (GET_CODE (XEXP (x, 0)) == GE + && REG_P (XEXP (XEXP (x, 0), 0)) + && const0_operand (XEXP (XEXP (x, 0), 1), QImode)); + if (is_nzb) + { + *total = COSTS_N_INSNS (code == XOR ? 3 : 2); + return true; + } + } + + // Insn "*nzb=1.ior.ashift_split" with nonzero_bits() == 1 in the condition. + if (avropt_use_nonzero_bits + && mode == QImode + && code == IOR + && REG_P (XEXP (x, 1)) + && GET_CODE (XEXP (x, 0)) == ASHIFT + && REG_P (XEXP (XEXP (x, 0), 0)) + && CONST_INT_P (XEXP (XEXP (x, 0), 1))) + { + *total = COSTS_N_INSNS (2); + return true; + } + + switch (code) { case CONST_INT: @@ -12760,6 +12758,16 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, return true; case SIGN_EXTEND: + if (GET_CODE (XEXP (x, 0)) == ASHIFT + && CONST_INT_P (XEXP (XEXP (x, 0), 1))) + { + // "*sext.ashift<QIPSI:mode><HISI:mode>2_split" + int m0 = GET_MODE_SIZE (GET_MODE (XEXP (x, 0))); + int m1 = GET_MODE_SIZE (mode); + *total = COSTS_N_INSNS (m0 * INTVAL (XEXP (XEXP (x, 0), 1)) + + m1 - m0); + return true; + } *total = COSTS_N_INSNS (n_bytes + 2 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0)))); *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)), @@ -13661,6 +13669,28 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); return true; + case GE: + if (mode == QImode + && REG_P (XEXP (x, 0)) + && XEXP (x, 1) == const0_rtx) + { + *total = COSTS_N_INSNS (3); + return true; + } + break; + + case ZERO_EXTRACT: + if (mode == QImode + && REG_P (XEXP (x, 0)) + && XEXP (x, 1) == const1_rtx + && CONST_INT_P (XEXP (x, 2))) + { + int bpos = INTVAL (XEXP (x, 2)); + *total = COSTS_N_INSNS (bpos == 0 ? 1 : bpos == 1 ? 2 : 3); + return true; + } + break; + case COMPARE: switch (GET_MODE (XEXP (x, 0))) { @@ -13850,8 +13880,8 @@ extra_constraint_Q (rtx x) || xx == arg_pointer_rtx); if (avr_log.constraints) - avr_edump ("\n%?=%d reload_completed=%d ra_in_progress=%d\n %r\n", - ok, reload_completed, ra_in_progress (), x); + avr_edump ("\n%?=%d reload_completed=%d lra_in_progress=%d\n %r\n", + ok, reload_completed, lra_in_progress, x); } return ok; @@ -14056,17 +14086,6 @@ avr_hard_regno_mode_ok (unsigned int regno, machine_mode mode) if (GET_MODE_SIZE (mode) == 1) return true; - /* FIXME: Ideally, the following test is not needed. - However, it turned out that it can reduce the number - of spill fails. AVR and it's poor endowment with - address registers is extreme stress test for reload. */ - - if (GET_MODE_SIZE (mode) >= 4 - && regno >= REG_X - // This problem only concerned the old reload. - && ! avropt_lra_p) - return false; - /* All modes larger than 8 bits should start in an even register. */ return !(regno & 1); @@ -14332,6 +14351,13 @@ avr_output_addr_vec (rtx_insn *labl, rtx table) // Output the label that precedes the table. ASM_OUTPUT_ALIGN (stream, 1); + + char s_labl[40]; + targetm.asm_out.generate_internal_label (s_labl, "L", + CODE_LABEL_NUMBER (labl)); + ASM_OUTPUT_TYPE_DIRECTIVE (stream, s_labl, + AVR_HAVE_JMP_CALL ? "object" : "function"); + targetm.asm_out.internal_label (stream, "L", CODE_LABEL_NUMBER (labl)); // Output the table's content. @@ -14821,8 +14847,8 @@ avr_addr_space_legitimate_address_p (machine_mode mode, rtx x, bool strict, if (avr_log.legitimate_address_p) { avr_edump ("\n%?: ret=%b, mode=%m strict=%d " - "reload_completed=%d ra_in_progress=%d %s:", - ok, mode, strict, reload_completed, ra_in_progress (), + "reload_completed=%d lra_in_progress=%d %s:", + ok, mode, strict, reload_completed, lra_in_progress, reg_renumber ? "(reg_renumber)" : ""); if (GET_CODE (x) == PLUS @@ -14898,10 +14924,11 @@ avr_addr_space_convert (rtx src, tree type_old, tree type_new) /* Linearize memory: RAM has bit 23 set. When as_new = __flashx then this is basically UB since __flashx mistreats RAM addresses, but there - is no way to bail out. (Though -Waddr-space-convert will tell.) */ + is no way to bail out. (Though -Waddr-space-convert will tell.) + ...but PR121277 is confusing, in particular when NULL is coming in. */ int msb = ADDR_SPACE_GENERIC_P (as_old) - ? 0x80 + ? as_new == ADDR_SPACE_MEMX ? 0x80 : 0x00 : avr_addrspace[as_old].segment; src = force_reg (Pmode, src); @@ -14999,10 +15026,16 @@ avr_convert_to_type (tree type, tree expr) const char *name_old = avr_addrspace[as_old].name; const char *name_new = avr_addrspace[as_new].name; - warning (OPT_Waddr_space_convert, - "conversion from address space %qs to address space %qs", - ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old, - ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new); + // Be relaxed when NULL is used, and when 0x0 stands for + // address 0x0. + bool nowarn = (expr == null_pointer_node + && (as_new == ADDR_SPACE_FLASHX + || as_new == ADDR_SPACE_FLASH)); + if (!nowarn) + warning (OPT_Waddr_space_convert, + "conversion from address space %qs to address space %qs", + ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old, + ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new); return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr); } @@ -15148,6 +15181,46 @@ avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op, } +/* A helper for the insn condition of "*nzb=1.<code>.lsr[.not]_split" + where <code> is AND, IOR or XOR. Return true when + + OP[0] <code>= OP[1] >> OP[2] + + can be performed by means of the code of "*nzb=1.<code>.zerox", i.e. + + OP[0] <code>= OP[1].OP[2] + + For example, when OP[0] is in { 0, 1 }, then R24 &= R10.4 + can be performed by means of SBRS R10,4 $ CLR R24. + Notice that the constraint of OP[3] is "0". */ + +bool +avr_nonzero_bits_lsr_operands_p (rtx_code code, rtx *op) +{ + if (reload_completed) + return false; + + const auto offs = INTVAL (op[2]); + const auto op1_non0 = nonzero_bits (op[1], QImode); + const auto op3_non0 = nonzero_bits (op[3], QImode); + + switch (code) + { + default: + gcc_unreachable (); + + case IOR: + case XOR: + return op1_non0 >> offs == 1; + + case AND: + return op3_non0 == 1; + } + + return false; +} + + /* Worker function for cpymemhi expander. XOP[0] Destination as MEM:BLK XOP[1] Source " " @@ -16553,15 +16626,6 @@ avr_unwind_word_mode () return Pmode; } - -/* Implement `TARGET_LRA_P'. */ - -static bool -avr_use_lra_p () -{ - return avropt_lra_p; -} - /* Initialize the GCC target structure. */ @@ -16703,9 +16767,6 @@ avr_use_lra_p () #undef TARGET_CONVERT_TO_TYPE #define TARGET_CONVERT_TO_TYPE avr_convert_to_type -#undef TARGET_LRA_P -#define TARGET_LRA_P avr_use_lra_p - #undef TARGET_ADDR_SPACE_SUBSET_P #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index cb818c3..335f9fa5 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -309,12 +309,6 @@ enum reg_class { #define STATIC_CHAIN_REGNUM ((AVR_TINY) ? 18 :2) -#define RELOAD_ELIMINABLE_REGS { \ - { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ - { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \ - { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ - { FRAME_POINTER_REGNUM + 1, STACK_POINTER_REGNUM + 1 } } - #define ELIMINABLE_REGS \ { \ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ @@ -358,18 +352,6 @@ typedef struct avr_args #define MAX_REGS_PER_ADDRESS 1 -#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_L,WIN) \ - do { \ - rtx new_x = avr_legitimize_reload_address (&(X), MODE, OPNUM, TYPE, \ - ADDR_TYPE (TYPE), \ - IND_L, make_memloc); \ - if (new_x) \ - { \ - X = new_x; \ - goto WIN; \ - } \ - } while (0) - /* We increase branch costs after reload in order to keep basic-block reordering from introducing out-of-line jumps and to prefer fall-through edges instead. The default branch costs are 0, mainly because otherwise diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 06e31aa..60b1f60 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -84,6 +84,7 @@ [UNSPEC_STRLEN UNSPEC_CPYMEM UNSPEC_INDEX_JMP + UNSPEC_NZB UNSPEC_FMUL UNSPEC_FMULS UNSPEC_FMULSU @@ -175,6 +176,10 @@ no" (const_string "no")) +(define_attr "nzb" + "yes, no" + (const_string "no")) + ;; Flavours of instruction set architecture (ISA), used in enabled attribute ;; mov : ISA has no MOVW movw : ISA has MOVW @@ -569,9 +574,8 @@ && REG_Z == REGNO (XEXP (operands[0], 0))" "#" "&& reload_completed" - [(parallel [(set (reg:MOVMODE 22) - (match_dup 0)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*load_<mode>_libgcc" [(set (reg:MOVMODE 22) @@ -711,17 +715,15 @@ || avr_load_libgcc_insn_p (insn, ADDR_SPACE_FLASHX, true)" "#" "&& reload_completed" - [(parallel [(set (reg:MOVMODE REG_22) - (match_dup 0)) - (clobber (reg:CC REG_CC))])] - { - operands[0] = SET_SRC (single_set (curr_insn)); - }) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*fxload_<mode>_libgcc" [(set (reg:MOVMODE REG_22) (mem:MOVMODE (lo_sum:PSI (reg:QI REG_21) (reg:HI REG_Z)))) + (clobber (reg:QI REG_21)) + (clobber (reg:HI REG_Z)) (clobber (reg:CC REG_CC))] "reload_completed && (avr_load_libgcc_insn_p (insn, ADDR_SPACE_MEMX, true) @@ -844,9 +846,8 @@ || reg_or_0_operand (operands[1], <MODE>mode)" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) ;; "movqi_insn" ;; "movqq_insn" "movuqq_insn" @@ -955,9 +956,8 @@ || reg_or_0_operand (operands[1], <MODE>mode)" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mov<mode>" [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r") @@ -1128,9 +1128,8 @@ || const0_rtx == operands[1]" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*movpsi" [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") @@ -1188,9 +1187,8 @@ || reg_or_0_operand (operands[1], <MODE>mode)" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mov<mode>" [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r") @@ -1236,9 +1234,8 @@ || reg_or_0_operand (operands[1], SFmode)" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*movsf" [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") @@ -1317,16 +1314,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (mem:BLK (reg:HI REG_X)) - (mem:BLK (reg:HI REG_Z))) - (unspec [(match_dup 0)] - UNSPEC_CPYMEM) - (use (match_dup 1)) - (clobber (reg:HI REG_X)) - (clobber (reg:HI REG_Z)) - (clobber (reg:QI LPM_REGNO)) - (clobber (match_dup 2)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*cpymem_<mode>" [(set (mem:BLK (reg:HI REG_X)) @@ -1373,22 +1362,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (mem:BLK (reg:HI REG_X)) - (match_dup 2)) - (unspec [(match_dup 0)] - UNSPEC_CPYMEM) - (use (reg:QIHI 24)) - (clobber (reg:HI REG_X)) - (clobber (reg:HI REG_Z)) - (clobber (reg:QI LPM_REGNO)) - (clobber (reg:HI 24)) - (clobber (reg:QI 23)) - (clobber (mem:QI (match_dup 1))) - (clobber (reg:CC REG_CC))])] - { - rtx xset = XVECEXP (PATTERN (curr_insn), 0, 0); - operands[2] = SET_SRC (xset); - }) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*cpymemx_<mode>" [(set (mem:BLK (reg:HI REG_X)) @@ -1452,13 +1427,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (mem:BLK (match_dup 0)) - (const_int 0)) - (use (match_dup 1)) - (use (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*clrmemqi" [(set (mem:BLK (match_operand:HI 0 "register_operand" "e")) @@ -1483,14 +1453,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (mem:BLK (match_dup 0)) - (const_int 0)) - (use (match_dup 1)) - (use (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "adiw,*")]) @@ -1541,13 +1505,8 @@ "" "#" "&& reload_completed" - [(parallel - [(set (match_dup 0) - (unspec:HI [(mem:BLK (match_dup 1)) - (const_int 0) - (match_dup 2)] - UNSPEC_STRLEN)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*strlenhi" [(set (match_operand:HI 0 "register_operand" "=e") @@ -1572,10 +1531,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:ALL1 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*add<mode>3" [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r") @@ -1631,10 +1588,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:HI (zero_extend:HI (match_dup 1)) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*addhi3_zero_extend" [(set (match_operand:HI 0 "register_operand" "=r,*?r") @@ -1654,10 +1609,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:HI (match_dup 1) - (zero_extend:HI (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*addhi3_zero_extend1" [(set (match_operand:HI 0 "register_operand" "=r") @@ -1675,10 +1628,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:HI (zero_extend:HI (match_dup 1)) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*addhi3_zero_extend.const" [(set (match_operand:HI 0 "register_operand" "=d") @@ -1714,11 +1665,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:HI (ashift:HI (zero_extend:HI (match_dup 1)) - (const_int 1)) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*addhi3_zero_extend.ashift1" [(set (match_operand:HI 0 "register_operand" "=r") @@ -1743,11 +1691,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:HI (zero_extend:HI (match_dup 1)) - (zero_extend:HI (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) - + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*usum_widenqihi3" [(set (match_operand:HI 0 "register_operand" "=r") @@ -1765,10 +1710,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (minus:HI (zero_extend:HI (match_dup 1)) - (zero_extend:HI (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*udiff_widenqihi3" [(set (match_operand:HI 0 "register_operand" "=r") @@ -1788,7 +1731,7 @@ return avr_out_addto_sp (operands, NULL); } "" - [(const_int 0)] + [(scratch)] { // Do not attempt to split this pattern. This FAIL is necessary // to prevent the splitter from matching *add<ALL2>3_split, splitting @@ -1900,11 +1843,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:ALL2 (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) ;; "*addhi3_clobber" ;; "*addhq3_clobber" "*adduhq3_clobber" @@ -1934,11 +1874,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:ALL4 (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*add<mode>3" [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r") @@ -1970,10 +1907,8 @@ && (<HISI:SIZE> > 2 || <CODE> == SIGN_EXTEND)" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:HISI (any_extend:HISI (match_dup 1)) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) ;; "*addhi3.sign_extend.qi" ;; "*addpsi3.zero_extend.qi" "*addpsi3.sign_extend.qi" @@ -2010,10 +1945,8 @@ "<HISI:SIZE> > <QIPSI:SIZE>" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (minus:HISI (match_dup 1) - (any_extend:HISI (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) ;; "*subhi3.zero_extend.qi" "*subhi3.sign_extend.qi" ;; "*subpsi3.zero_extend.qi" "*subpsi3.sign_extend.qi" @@ -2044,11 +1977,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:PSI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3 )) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*addpsi3" [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r") @@ -2070,10 +2000,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (minus:PSI (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*subpsi3" [(set (match_operand:PSI 0 "register_operand" "=r") @@ -2097,10 +2025,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (minus:ALL1 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sub<mode>3" [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r") @@ -2128,11 +2054,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (minus:ALL2 (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sub<mode>3" [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r") @@ -2158,11 +2081,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (minus:ALL4 (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sub<mode>3" [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r") @@ -2200,10 +2120,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:QI (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulqi3_enh" [(set (match_operand:QI 0 "register_operand" "=r") @@ -2234,10 +2152,8 @@ "!AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:QI 24) - (mult:QI (reg:QI 24) (reg:QI 22))) - (clobber (reg:QI 22)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulqi3_call" [(set (reg:QI 24) @@ -2260,12 +2176,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (truncate:QI - (lshiftrt:HI (mult:HI (any_extend:HI (match_dup 1)) - (any_extend:HI (match_dup 2))) - (const_int 8)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<extend_su>mulqi3_highpart" [(set (match_operand:QI 0 "register_operand" "=r") @@ -2352,21 +2264,21 @@ (const_int 0)))) (clobber (reg:CC REG_CC))])]) -;; *subqi3.lt0 *subqi3.ge0 -;; *subhi3.lt0 *subhi3.ge0 -;; *subpsi3.lt0 *subpsi3.ge0 -;; *subsi3.lt0 *subsi3.ge0 -(define_insn "*sub<QISI:mode>3.<code>0" - [(set (match_operand:QISI 0 "register_operand" "=r") - (minus:QISI (match_operand:QISI 1 "register_operand" "0") - (gelt:QISI (match_operand:QISI2 2 "register_operand" "r") - (const_int 0)))) - (clobber (reg:CC REG_CC))] - "reload_completed" - { - return avr_out_add_msb (insn, operands, <CODE>, nullptr); - } - [(set_attr "adjust_len" "add_<code>0")]) +;; *addqi3.lt0_split *addqi3.ge0_split +;; *addhi3.lt0_split *addhi3.ge0_split +;; *addpsi3.lt0_split *addpsi3.ge0_split +;; *addsi3.lt0_split *addsi3.ge0_split +(define_insn_and_split "*add<QISI:mode>3.<code>0_split" + [(set (match_operand:QISI 0 "register_operand" "=r") + (plus:QISI (gelt:QISI (match_operand:QISI2 1 "register_operand" "r") + (const_int 0)) + (match_operand:QISI 2 "register_operand" "0")))] + "" + "#" + "&& reload_completed" + ; *add<QISI:mode>3.<code>0 + [(scratch)] + { DONE_ADD_CCC }) ;; *addqi3.lt0 *addqi3.ge0 ;; *addhi3.lt0 *addhi3.ge0 @@ -2384,25 +2296,6 @@ } [(set_attr "adjust_len" "add_<code>0")]) -;; *addqi3.lt0_split *addqi3.ge0_split -;; *addhi3.lt0_split *addhi3.ge0_split -;; *addpsi3.lt0_split *addpsi3.ge0_split -;; *addsi3.lt0_split *addsi3.ge0_split -(define_insn_and_split "*add<QISI:mode>3.<code>0_split" - [(set (match_operand:QISI 0 "register_operand" "=r") - (plus:QISI (gelt:QISI (match_operand:QISI2 1 "register_operand" "r") - (const_int 0)) - (match_operand:QISI 2 "register_operand" "0")))] - "" - "#" - "&& reload_completed" - [; *add<QISI:mode>3.<code>0 - (parallel [(set (match_dup 0) - (plus:QISI (gelt:QISI (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) - ;; *subqi3.lt0_split *subqi3.ge0_split ;; *subhi3.lt0_split *subhi3.ge0_split ;; *subpsi3.lt0_split *subpsi3.ge0_split @@ -2415,13 +2308,25 @@ "" "#" "&& reload_completed" - [; *sub<QISI:mode>3.<code>0 - (parallel [(set (match_dup 0) - (minus:QISI (match_dup 1) - (gelt:QISI (match_dup 2) - (const_int 0)))) - (clobber (reg:CC REG_CC))])]) + ; *sub<QISI:mode>3.<code>0 + [(scratch)] + { DONE_ADD_CCC }) +;; *subqi3.lt0 *subqi3.ge0 +;; *subhi3.lt0 *subhi3.ge0 +;; *subpsi3.lt0 *subpsi3.ge0 +;; *subsi3.lt0 *subsi3.ge0 +(define_insn "*sub<QISI:mode>3.<code>0" + [(set (match_operand:QISI 0 "register_operand" "=r") + (minus:QISI (match_operand:QISI 1 "register_operand" "0") + (gelt:QISI (match_operand:QISI2 2 "register_operand" "r") + (const_int 0)))) + (clobber (reg:CC REG_CC))] + "reload_completed" + { + return avr_out_add_msb (insn, operands, <CODE>, nullptr); + } + [(set_attr "adjust_len" "add_<code>0")]) (define_insn_and_split "*umulqihi3.call_split" [(set (reg:HI 24) @@ -2432,12 +2337,8 @@ "!AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (mult:HI (zero_extend:HI (reg:QI 22)) - (zero_extend:HI (reg:QI 24)))) - (clobber (reg:QI 21)) - (clobber (reg:HI 22)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*umulqihi3.call" [(set (reg:HI 24) @@ -2460,10 +2361,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:HI (any_extend:HI (match_dup 1)) - (any_extend:HI (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "<extend_u>mulqihi3" [(set (match_operand:HI 0 "register_operand" "=r") @@ -2483,10 +2382,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:HI (zero_extend:HI (match_dup 1)) - (sign_extend:HI (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*usmulqihi3" [(set (match_operand:HI 0 "register_operand" "=r") @@ -2508,10 +2405,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:HI (sign_extend:HI (match_dup 1)) - (zero_extend:HI (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sumulqihi3" [(set (match_operand:HI 0 "register_operand" "=r") @@ -2533,10 +2428,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1)))) - (sign_extend:HI (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*osmulqihi3" [(set (match_operand:HI 0 "register_operand" "=&r") @@ -2557,10 +2450,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1)))) - (zero_extend:HI (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*oumulqihi3" [(set (match_operand:HI 0 "register_operand" "=&r") @@ -2587,11 +2478,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:QI (mult:QI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*maddqi4" [(set (match_operand:QI 0 "register_operand" "=r") @@ -2613,11 +2501,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (minus:QI (match_dup 3) - (mult:QI (match_dup 1) - (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*msubqi4" [(set (match_operand:QI 0 "register_operand" "=r") @@ -2696,11 +2581,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:HI (mult:HI (any_extend:HI (match_dup 1)) - (any_extend:HI (match_dup 2))) - (match_dup 3))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<extend_u>maddqihi4" [(set (match_operand:HI 0 "register_operand" "=r") @@ -2725,11 +2607,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (minus:HI (match_dup 3) - (mult:HI (any_extend:HI (match_dup 1)) - (any_extend:HI (match_dup 2))))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<extend_u>msubqihi4" [(set (match_operand:HI 0 "register_operand" "=r") @@ -2756,11 +2635,8 @@ && <any_extend:CODE> != <any_extend2:CODE>" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (plus:HI (mult:HI (any_extend:HI (match_dup 1)) - (any_extend2:HI (match_dup 2))) - (match_dup 3))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4" [(set (match_operand:HI 0 "register_operand" "=r") @@ -2791,11 +2667,8 @@ && <any_extend:CODE> != <any_extend2:CODE>" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (minus:HI (match_dup 3) - (mult:HI (any_extend:HI (match_dup 1)) - (any_extend2:HI (match_dup 2))))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4" [(set (match_operand:HI 0 "register_operand" "=r") @@ -3063,16 +2936,14 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ashift:HI (sign_extend:HI (match_dup 1)) - (const_int 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*ashiftqihi2.signx.1" [(set (match_operand:HI 0 "register_operand" "=r,*r") (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r")) (const_int 1))) - (clobber (reg:CC REG_CC)) ] + (clobber (reg:CC REG_CC))] "reload_completed" "@ lsl %A0\;sbc %B0,%B0 @@ -3133,6 +3004,41 @@ operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode); }) +(define_insn_and_split "*sext.ashift<QIPSI:mode><HISI:mode>2_split" + [(set (match_operand:HISI 0 "register_operand" "=r") + (sign_extend:HISI (ashift:QIPSI (match_operand:QIPSI 1 "register_operand" "0") + (match_operand:QI 2 "const_int_operand" "PKC03"))))] + "<HISI:SIZE> > <QIPSI:SIZE> + && IN_RANGE (INTVAL (operands[2]), 1, 2 + (<QIPSI:SIZE> <= 2))" + "#" + "&& reload_completed" + [(scratch)] + { DONE_ADD_CCC }) + +(define_insn "*sext.ashift<QIPSI:mode><HISI:mode>2" + [(set (match_operand:HISI 0 "register_operand" "=r") + (sign_extend:HISI (ashift:QIPSI (match_operand:QIPSI 1 "register_operand" "0") + (match_operand:QI 2 "const_int_operand" "PKC03")))) + (clobber (reg:CC REG_CC))] + "reload_completed + && <HISI:SIZE> > <QIPSI:SIZE> + && IN_RANGE (INTVAL (operands[2]), 1, 2 + (<QIPSI:SIZE> <= 2))" + { + const int regno = REGNO (operands[0]); + // The shift. + for (int s = 0; s < (int) INTVAL (operands[2]); ++s) + for (int b = 0; b < <QIPSI:SIZE>; ++b) + output_asm_insn (b == 0 ? "lsl %0" : "rol %0", + &all_regs_rtx[regno + b]); + // Sign-extend can use carry. + for (int b = <QIPSI:SIZE>; b < <HISI:SIZE>; ++b) + output_asm_insn ("sbc %0,%0", &all_regs_rtx[regno + b]); + return ""; + } + [(set (attr "length") + (plus (symbol_ref "<QIPSI:SIZE> * INTVAL (operands[2])") + (symbol_ref "<HISI:SIZE> - <QIPSI:SIZE>")))]) + ;****************************************************************************** ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg ;****************************************************************************** @@ -3144,10 +3050,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:HI (sign_extend:HI (match_dup 1)) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulsqihi3" [(set (match_operand:HI 0 "register_operand" "=&r") @@ -3169,10 +3073,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:HI (zero_extend:HI (match_dup 1)) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*muluqihi3" [(set (match_operand:HI 0 "register_operand" "=&r") @@ -3196,10 +3098,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1)))) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*muloqihi3" [(set (match_operand:HI 0 "register_operand" "=&r") @@ -3268,10 +3168,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:HI (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulhi3_enh" [(set (match_operand:HI 0 "register_operand" "=&r") @@ -3310,11 +3208,8 @@ "!AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (mult:HI (reg:HI 24) (reg:HI 22))) - (clobber (reg:HI 22)) - (clobber (reg:QI 21)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulhi3_call" [(set (reg:HI 24) @@ -3710,11 +3605,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:SI 22) - (mult:SI (reg:SI 22) - (reg:SI 18))) - (clobber (reg:HI 26)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn_and_split "*mulsi3_call_pr118012_split" [(set (reg:SI 22) @@ -3728,13 +3620,8 @@ && ! AVR_TINY" "#" "&& reload_completed" - [(parallel [(set (reg:SI 22) - (mult:SI (reg:SI 22) - (reg:SI 18))) - (clobber (reg:SI 18)) - (clobber (reg:HI 26)) - (clobber (reg:HI 30)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulsi3_call" [(set (reg:SI 22) @@ -3770,10 +3657,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:SI 22) - (mult:SI (any_extend:SI (reg:HI 18)) - (any_extend:SI (reg:HI 26)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<extend_u>mulhisi3_call" [(set (reg:SI 22) @@ -3795,12 +3680,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18)) - (any_extend:SI (reg:HI 26))) - (const_int 16)))) - (clobber (reg:HI 22)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*<extend_su>mulhi3_highpart_call" [(set (reg:HI 24) @@ -3820,10 +3701,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:SI 22) - (mult:SI (zero_extend:SI (reg:HI 18)) - (sign_extend:SI (reg:HI 26)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*usmulhisi3_call" [(set (reg:SI 22) @@ -3841,10 +3720,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:SI 22) - (mult:SI (any_extend:SI (reg:HI 26)) - (reg:SI 18))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mul<extend_su>hisi3_call" [(set (reg:SI 22) @@ -3862,10 +3739,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:SI 22) - (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26)))) - (reg:SI 18))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulohisi3_call" [(set (reg:SI 22) @@ -3916,11 +3791,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22))) - (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22))) - (clobber (reg:QI 22)) - (clobber (reg:QI 23)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*divmodqi4_call" [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22))) @@ -3960,10 +3832,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22))) - (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22))) - (clobber (reg:QI 23)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*udivmodqi4_call" [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22))) @@ -4004,11 +3874,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22))) - (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22))) - (clobber (reg:HI 26)) - (clobber (reg:QI 21)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*divmodhi4_call" [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22))) @@ -4050,11 +3917,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22))) - (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22))) - (clobber (reg:HI 26)) - (clobber (reg:QI 21)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*udivmodhi4_call" [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22))) @@ -4103,10 +3967,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (mult:PSI (zero_extend:PSI (match_dup 1)) - (zero_extend:PSI (match_dup 2)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*umulqihipsi3" [(set (match_operand:PSI 0 "register_operand" "=&r") @@ -4125,31 +3987,17 @@ (define_insn_and_split "*umulhiqipsi3_split" [(set (match_operand:PSI 0 "register_operand" "=&r") - (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r")) - (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))] + (mult:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r")) + (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))] "AVR_HAVE_MUL" "#" "&& reload_completed" + ; "*umulqihipsi3" [(parallel [(set (match_dup 0) (mult:PSI (zero_extend:PSI (match_dup 2)) (zero_extend:PSI (match_dup 1)))) (clobber (reg:CC REG_CC))])]) -(define_insn "*umulhiqipsi3" - [(set (match_operand:PSI 0 "register_operand" "=&r") - (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r")) - (zero_extend:PSI (match_operand:QI 1 "register_operand" "r")))) - (clobber (reg:CC REG_CC))] - "AVR_HAVE_MUL && reload_completed" - "mul %1,%A2 - movw %A0,r0 - mul %1,%B2 - add %B0,r0 - mov %C0,r1 - clr __zero_reg__ - adc %C0,__zero_reg__" - [(set_attr "length" "7")]) - (define_expand "mulsqipsi3" [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "") (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "")) @@ -4220,10 +4068,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:PSI 18) - (mult:PSI (sign_extend:PSI (reg:QI 25)) - (reg:PSI 22))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulsqipsi3.libgcc" [(set (reg:PSI 18) @@ -4244,13 +4090,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:PSI 22) - (mult:PSI (reg:PSI 22) - (reg:PSI 18))) - (clobber (reg:QI 21)) - (clobber (reg:QI 25)) - (clobber (reg:HI 26)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*mulpsi3.libgcc" [(set (reg:PSI 22) @@ -4302,12 +4143,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18))) - (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18))) - (clobber (reg:QI 21)) - (clobber (reg:QI 25)) - (clobber (reg:QI 26)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*divmodpsi4_call" [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18))) @@ -4351,12 +4188,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18))) - (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18))) - (clobber (reg:QI 21)) - (clobber (reg:QI 25)) - (clobber (reg:QI 26)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*udivmodpsi4_call" [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18))) @@ -4402,11 +4235,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18))) - (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18))) - (clobber (reg:HI 26)) - (clobber (reg:HI 30)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*divmodsi4_call" [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18))) @@ -4449,11 +4279,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18))) - (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18))) - (clobber (reg:HI 26)) - (clobber (reg:HI 30)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*udivmodsi4_call" [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18))) @@ -4475,10 +4302,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (and:QI (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*andqi3" [(set (match_operand:QI 0 "register_operand" "=??r,d,*l ,r") @@ -4502,11 +4327,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (and:HI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*andhi3" [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r ,r") @@ -4536,11 +4358,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (and:PSI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*andpsi3" [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r ,r") @@ -4571,11 +4390,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*andsi3" [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r ,r") @@ -4625,10 +4441,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ior:QI (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*iorqi3" [(set (match_operand:QI 0 "register_operand" "=??r,d,*l") @@ -4650,11 +4464,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ior:HI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*iorhi3" [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r") @@ -4682,11 +4493,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ior:PSI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*iorpsi3" [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r") @@ -4714,11 +4522,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ior:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*iorsi3" [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r") @@ -4749,10 +4554,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (xor:QI (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*xorqi3" [(set (match_operand:QI 0 "register_operand" "=r") @@ -4771,11 +4574,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (xor:HI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*xorhi3" [(set (match_operand:HI 0 "register_operand" "=??r,r ,d ,r") @@ -4801,11 +4601,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (xor:PSI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*xorpsi3" [(set (match_operand:PSI 0 "register_operand" "=??r,r ,d ,r") @@ -4833,11 +4630,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (xor:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*xorsi3" [(set (match_operand:SI 0 "register_operand" "=??r,r ,d ,r") @@ -4909,7 +4703,7 @@ (clobber (reg:CC REG_CC))])] "optimize && reload_completed" - [(const_int 1)] + [(scratch)] { for (int i = 0; i < <SIZE>; i++) { @@ -5017,10 +4811,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (rotate:QI (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*rotlqi3" [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r") @@ -5090,10 +4882,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (rotate:HI (match_dup 1) - (const_int 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*rotlhi2.1" [(set (match_operand:HI 0 "register_operand" "=r") @@ -5111,10 +4901,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (rotate:HI (match_dup 1) - (const_int 15))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*rotlhi2.15" [(set (match_operand:HI 0 "register_operand" "=r") @@ -5132,10 +4920,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (rotate:PSI (match_dup 1) - (const_int 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*rotlpsi2.1" [(set (match_operand:PSI 0 "register_operand" "=r") @@ -5153,10 +4939,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (rotate:PSI (match_dup 1) - (const_int 23))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*rotlpsi2.23" [(set (match_operand:PSI 0 "register_operand" "=r") @@ -5174,10 +4958,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (rotate:SI (match_dup 1) - (const_int 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*rotlsi2.1" [(set (match_operand:SI 0 "register_operand" "=r") @@ -5195,10 +4977,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (rotate:SI (match_dup 1) - (const_int 31))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*rotlsi2.31" [(set (match_operand:SI 0 "register_operand" "=r") @@ -5230,7 +5010,7 @@ && 0 == INTVAL (operands[2]) % 16" "#" "&& reload_completed" - [(const_int 0)] + [(scratch)] { avr_rotate_bytes (operands); DONE; @@ -5254,7 +5034,7 @@ && 0 == INTVAL (operands[2]) % 16))" "#" "&& reload_completed" - [(const_int 0)] + [(scratch)] { avr_rotate_bytes (operands); DONE; @@ -5319,10 +5099,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ashift:ALL1 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*ashl<mode>3" [(set (match_operand:ALL1 0 "register_operand" "=r,r ,r ,r,r") @@ -5346,11 +5124,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ashift:ALL2 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "*,*,*,3op,*,*")]) ;; "*ashlhi3" @@ -5462,11 +5237,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ashift:ALL4 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "*,*,*,3op,*,*")]) (define_insn "*ashl<mode>3" @@ -5705,12 +5477,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ashift:PSI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "*,*,*,3op,*")]) (define_insn "*ashlpsi3" @@ -5764,10 +5532,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ashiftrt:ALL1 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*ashr<mode>3" [(set (match_operand:ALL1 0 "register_operand" "=r,r ,r ,r") @@ -5791,11 +5557,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ashiftrt:ALL2 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "*,*,*,3op,*,*")]) ;; "*ashrhi3" @@ -5822,12 +5585,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ashiftrt:PSI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "*,*,*,3op,*")]) (define_insn "*ashrpsi3" @@ -5854,11 +5613,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (ashiftrt:ALL4 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "*,*,*,3op,*,*")]) (define_insn "*ashr<mode>3" @@ -5969,10 +5725,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (lshiftrt:ALL1 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*lshr<mode>3" [(set (match_operand:ALL1 0 "register_operand" "=r,r ,r ,r,r") @@ -5995,11 +5749,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (lshiftrt:ALL2 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "*,*,*,3op,*,*")]) (define_insn "*lshr<mode>3" @@ -6022,12 +5773,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (lshiftrt:PSI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "*,*,*,3op,*")]) (define_insn "*lshrpsi3" @@ -6054,11 +5801,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (lshiftrt:ALL4 (match_dup 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "*,*,*,3op,*,*")]) (define_insn "*lshr<mode>3" @@ -6173,9 +5917,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (abs:QI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*absqi2" [(set (match_operand:QI 0 "register_operand" "=r") @@ -6193,9 +5936,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (abs:SF (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*abssf2" [(set (match_operand:SF 0 "register_operand" "=d,r") @@ -6216,9 +5958,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (neg:QI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*negqi2" [(set (match_operand:QI 0 "register_operand" "=r") @@ -6234,9 +5975,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (neg:HI (sign_extend:HI (match_dup 1)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*negqihi2" [(set (match_operand:HI 0 "register_operand" "=r") @@ -6252,9 +5992,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (neg:HI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*neghi2" [(set (match_operand:HI 0 "register_operand" "=r,&r") @@ -6272,9 +6011,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (neg:PSI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*negpsi2" [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r") @@ -6293,10 +6031,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (neg:SI (match_dup 1))) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "*,*,mov,movw")]) (define_insn "*negsi2.libgcc" @@ -6327,9 +6063,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (neg:SF (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*negsf2" [(set (match_operand:SF 0 "register_operand" "=d,r") @@ -6350,9 +6085,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (not:QI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*one_cmplqi2" [(set (match_operand:QI 0 "register_operand" "=r") @@ -6368,9 +6102,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (not:HI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*one_cmplhi2" [(set (match_operand:HI 0 "register_operand" "=r") @@ -6387,9 +6120,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (not:PSI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*one_cmplpsi2" [(set (match_operand:PSI 0 "register_operand" "=r") @@ -6405,9 +6137,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (not:SI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*one_cmplsi2" [(set (match_operand:SI 0 "register_operand" "=r") @@ -6436,9 +6167,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (sign_extend:HI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*extendqihi2" [(set (match_operand:HI 0 "register_operand" "=r,r") @@ -6457,9 +6187,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (sign_extend:PSI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*extendqipsi2" [(set (match_operand:PSI 0 "register_operand" "=r,r") @@ -6478,9 +6207,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (sign_extend:SI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*extendqisi2" [(set (match_operand:SI 0 "register_operand" "=r,r") @@ -6499,9 +6227,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (sign_extend:PSI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*extendhipsi2" [(set (match_operand:PSI 0 "register_operand" "=r,r") @@ -6520,9 +6247,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (sign_extend:SI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*extendhisi2" [(set (match_operand:SI 0 "register_operand" "=r,r") @@ -6541,9 +6267,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (sign_extend:SI (match_dup 1))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*extendpsisi2" [(set (match_operand:SI 0 "register_operand" "=r") @@ -6988,10 +6713,11 @@ "#" "reload_completed" [(set (reg:CC REG_CC) - (compare:CC (match_dup 1) (match_dup 2))) + (compare:CC (match_dup 1) + (match_dup 2))) (set (pc) - (if_then_else (match_op_dup 0 - [(reg:CC REG_CC) (const_int 0)]) + (if_then_else (match_op_dup 0 [(reg:CC REG_CC) + (const_int 0)]) (label_ref (match_dup 3)) (pc)))]) @@ -7010,11 +6736,12 @@ "#" "reload_completed" [(parallel [(set (reg:CC REG_CC) - (compare:CC (match_dup 1) (match_dup 2))) + (compare:CC (match_dup 1) + (match_dup 2))) (clobber (match_dup 4))]) (set (pc) - (if_then_else (match_op_dup 0 - [(reg:CC REG_CC) (const_int 0)]) + (if_then_else (match_op_dup 0 [(reg:CC REG_CC) + (const_int 0)]) (label_ref (match_dup 3)) (pc)))] { @@ -7037,11 +6764,12 @@ "#" "reload_completed" [(parallel [(set (reg:CC REG_CC) - (compare:CC (match_dup 1) (match_dup 2))) + (compare:CC (match_dup 1) + (match_dup 2))) (clobber (match_dup 4))]) (set (pc) - (if_then_else (match_op_dup 0 - [(reg:CC REG_CC) (const_int 0)]) + (if_then_else (match_op_dup 0 [(reg:CC REG_CC) + (const_int 0)]) (label_ref (match_dup 3)) (pc)))] { @@ -7065,11 +6793,12 @@ "#" "reload_completed" [(parallel [(set (reg:CC REG_CC) - (compare:CC (match_dup 1) (match_dup 2))) + (compare:CC (match_dup 1) + (match_dup 2))) (clobber (match_dup 4))]) (set (pc) - (if_then_else (match_op_dup 0 - [(reg:CC REG_CC) (const_int 0)]) + (if_then_else (match_op_dup 0 [(reg:CC REG_CC) + (const_int 0)]) (label_ref (match_dup 3)) (pc)))] { @@ -7624,17 +7353,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (pc) - (if_then_else - (match_op_dup 0 - [(zero_extract:QIDI - (match_dup 1) - (const_int 1) - (match_dup 2)) - (const_int 0)]) - (label_ref (match_dup 3)) - (pc))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sbrx_branch<mode>" [(set (pc) @@ -7677,13 +7397,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (pc) - (if_then_else (match_op_dup 0 [(and:QISI (match_dup 1) - (match_dup 2)) - (const_int 0)]) - (label_ref (match_dup 3)) - (pc))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sbrx_and_branch<mode>" [(set (pc) @@ -7924,14 +7639,8 @@ "!AVR_HAVE_EIJMP_EICALL" "#" "&& reload_completed" - [(parallel [(set (pc) - (unspec:HI [(match_dup 0)] - UNSPEC_INDEX_JMP)) - (use (label_ref (match_dup 1))) - (clobber (match_dup 2)) - (clobber (const_int 0)) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "rjmp,rjmp,jmp")]) (define_insn "*tablejump" @@ -7960,14 +7669,8 @@ "AVR_HAVE_EIJMP_EICALL" "#" "&& reload_completed" - [(parallel [(set (pc) - (unspec:HI [(reg:HI REG_Z)] - UNSPEC_INDEX_JMP)) - (use (label_ref (match_dup 0))) - (clobber (reg:HI REG_Z)) - (clobber (reg:QI 24)) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "eijmp")]) @@ -8138,17 +7841,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (pc) - (if_then_else - (match_operator 0 "eqne_operator" - [(zero_extract:QIHI - (mem:QI (match_dup 1)) - (const_int 1) - (match_dup 2)) - (const_int 0)]) - (label_ref (match_dup 3)) - (pc))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sbix_branch" [(set (pc) @@ -8186,14 +7880,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (pc) - (if_then_else - (match_operator 0 "gelt_operator" - [(mem:QI (match_dup 1)) - (const_int 0)]) - (label_ref (match_dup 2)) - (pc))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sbix_branch_bit7" [(set (pc) @@ -8233,17 +7921,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (pc) - (if_then_else - (match_operator 0 "eqne_operator" - [(zero_extract:QIHI - (mem:QI (match_dup 1)) - (const_int 1) - (match_dup 2)) - (const_int 0)]) - (label_ref (match_dup 3)) - (pc))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sbix_branch_tmp" [(set (pc) @@ -8280,14 +7959,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (pc) - (if_then_else - (match_operator 0 "gelt_operator" - [(mem:QI (match_dup 1)) - (const_int 0)]) - (label_ref (match_dup 2)) - (pc))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sbix_branch_tmp_bit7" [(set (pc) @@ -8740,13 +8413,8 @@ "" "#" "&& reload_completed" - [(parallel [(unspec_volatile [(match_dup 0) - (const_int 1)] - UNSPECV_DELAY_CYCLES) - (set (match_dup 1) - (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) - (clobber (match_dup 2)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*delay_cycles_1" [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n") @@ -8772,14 +8440,8 @@ "" "#" "&& reload_completed" - [(parallel [(unspec_volatile [(match_dup 0) - (const_int 2)] - UNSPECV_DELAY_CYCLES) - (set (match_dup 1) - (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) - (clobber (match_dup 2)) - (clobber (reg:CC REG_CC))])] - "" + [(scratch)] + { DONE_ADD_CCC } [(set_attr "isa" "adiw,no_adiw")]) (define_insn "*delay_cycles_2" @@ -8809,15 +8471,8 @@ "" "#" "&& reload_completed" - [(parallel [(unspec_volatile [(match_dup 0) - (const_int 3)] - UNSPECV_DELAY_CYCLES) - (set (match_dup 1) - (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*delay_cycles_3" [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") @@ -8852,16 +8507,8 @@ "" "#" "&& reload_completed" - [(parallel [(unspec_volatile [(match_dup 0) - (const_int 4)] - UNSPECV_DELAY_CYCLES) - (set (match_dup 1) - (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*delay_cycles_4" [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") @@ -8898,12 +8545,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (unspec:QI [(match_dup 1) - (match_dup 2) - (match_dup 3)] - UNSPEC_INSERT_BITS)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*insert_bits" [(set (match_operand:QI 0 "register_operand" "=r ,d ,r") @@ -9083,12 +8726,13 @@ "#" "reload_completed" [(set (reg:CC REG_CC) - (compare:CC (match_dup 0) (const_int 0))) + (compare:CC (match_dup 0) + (const_int 0))) (set (pc) - (if_then_else (ge (reg:CC REG_CC) (const_int 0)) + (if_then_else (ge (reg:CC REG_CC) + (const_int 0)) (label_ref (match_dup 1)) - (pc)))] - "") + (pc)))]) (define_expand "flash_segment" [(parallel [(match_operand:QI 0 "register_operand" "") @@ -9191,9 +8835,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (parity:HI (reg:HI 24))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*parityhi2.libgcc" [(set (reg:HI 24) @@ -9209,9 +8852,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (zero_extend:HI (parity:QI (reg:QI 24)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*parityqihi2.libgcc" [(set (reg:HI 24) @@ -9227,9 +8869,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (truncate:HI (parity:SI (reg:SI 22)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*paritysihi2.libgcc" [(set (reg:HI 24) @@ -9285,9 +8926,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (popcount:HI (reg:HI 24))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*popcounthi2.libgcc" [(set (reg:HI 24) @@ -9303,9 +8943,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (truncate:HI (popcount:SI (reg:SI 22)))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*popcountsi2.libgcc" [(set (reg:HI 24) @@ -9321,9 +8960,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:QI 24) - (popcount:QI (reg:QI 24))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*popcountqi2.libgcc" [(set (reg:QI 24) @@ -9377,10 +9015,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (clz:HI (reg:HI 24))) - (clobber (reg:QI 26)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*clzhi2.libgcc" [(set (reg:HI 24) @@ -9398,10 +9034,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (truncate:HI (clz:SI (reg:SI 22)))) - (clobber (reg:QI 26)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*clzsihi2.libgcc" [(set (reg:HI 24) @@ -9446,10 +9080,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (ctz:HI (reg:HI 24))) - (clobber (reg:QI 26)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*ctzhi2.libgcc" [(set (reg:HI 24) @@ -9468,11 +9100,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (truncate:HI (ctz:SI (reg:SI 22)))) - (clobber (reg:QI 22)) - (clobber (reg:QI 26)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*ctzsihi2.libgcc" [(set (reg:HI 24) @@ -9518,10 +9147,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (ffs:HI (reg:HI 24))) - (clobber (reg:QI 26)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*ffshi2.libgcc" [(set (reg:HI 24) @@ -9540,11 +9167,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:HI 24) - (truncate:HI (ffs:SI (reg:SI 22)))) - (clobber (reg:QI 22)) - (clobber (reg:QI 26)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*ffssihi2.libgcc" [(set (reg:HI 24) @@ -9589,9 +9213,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (reg:SI 22) - (bswap:SI (reg:SI 22))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*bswapsi2.libgcc" [(set (reg:SI 22) @@ -9698,11 +9321,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (unspec:HI [(match_dup 1) - (match_dup 2)] - UNSPEC_FMUL)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*fmul_insn" [(set (match_operand:HI 0 "register_operand" "=r") @@ -9724,11 +9344,8 @@ "!AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:HI 22) - (unspec:HI [(reg:QI 24) - (reg:QI 25)] UNSPEC_FMUL)) - (clobber (reg:HI 24)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*fmul.call" [(set (reg:HI 22) @@ -9770,11 +9387,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (unspec:HI [(match_dup 1) - (match_dup 2)] - UNSPEC_FMULS)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*fmuls_insn" [(set (match_operand:HI 0 "register_operand" "=r") @@ -9796,11 +9410,8 @@ "!AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:HI 22) - (unspec:HI [(reg:QI 24) - (reg:QI 25)] UNSPEC_FMULS)) - (clobber (reg:HI 24)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*fmuls.call" [(set (reg:HI 22) @@ -9842,11 +9453,8 @@ "AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (unspec:HI [(match_dup 1) - (match_dup 2)] - UNSPEC_FMULSU)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*fmulsu_insn" [(set (match_operand:HI 0 "register_operand" "=r") @@ -9868,11 +9476,8 @@ "!AVR_HAVE_MUL" "#" "&& reload_completed" - [(parallel [(set (reg:HI 22) - (unspec:HI [(reg:QI 24) - (reg:QI 25)] UNSPEC_FMULSU)) - (clobber (reg:HI 24)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*fmulsu.call" [(set (reg:HI 22) @@ -9993,11 +9598,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (zero_extract:QI (match_dup 0) - (const_int 1) - (match_dup 1)) - (match_dup 2)) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*insv.reg" [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l") @@ -10434,11 +10036,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (zero_extract:QI (not:QI (match_dup 1)) - (const_int 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*extzv.not" [(set (match_operand:QI 0 "register_operand" "=r") @@ -10575,11 +10174,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (and:QISI (any_shift:QISI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*insv.any_shift.<mode>" [(set (match_operand:QISI 0 "register_operand" "=r") @@ -10642,11 +10238,8 @@ "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) - (sign_extract:QISI (match_dup 1) - (const_int 1) - (match_dup 2))) - (clobber (reg:CC REG_CC))])]) + [(scratch)] + { DONE_ADD_CCC }) (define_insn "*sextr.<QISI:mode>.<QISI2:mode>" [(set (match_operand:QISI 0 "register_operand" "=r") @@ -10916,6 +10509,216 @@ DONE; }) +;; Patterns for -muse-nonzero-bits use nonzero_bits() in their condition, +;; which makes possible some more optimizations. +;; Since combine may add clobber of REG_CC, we must make sure that there are +;; no other routes to synthesize such patterns. We use an UNSPEC for that. +;; As insns are not supposed to use stuff like nonzero_bits() in their +;; condition, we split the insns right after reload. For CFG reasons we have +;; to do the splits by hand in avr_pass_split_nzb. All insns that must be +;; split by that pass must have insn attribute "nzb" set to "yes". Moreover, +;; the insns to split must be single_sets and must not touch control flow. + +(define_code_attr nzb_constr_rdr [(and "r") (ior "d") (xor "r")]) +(define_code_attr nzb_use1_nnr [(and "n") (ior "n") (xor "r")]) + +(define_insn_and_split "*nzb=1.<code>.zerox_split" + [(set (match_operand:QI 0 "register_operand") + (bitop:QI (zero_extract:QI (match_operand:QI 1 "register_operand") + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] + "optimize && avropt_use_nonzero_bits + && !reload_completed + && (<CODE> == IOR || <CODE> == XOR + || nonzero_bits (operands[3], QImode) == 1)" + { gcc_unreachable (); } + "optimize && avropt_use_nonzero_bits + && !reload_completed" + [(parallel [(set (match_dup 0) + (bitop:QI (zero_extract:QI (match_dup 1) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) + (use (const_int 1)) + (clobber (reg:CC REG_CC))])] + "" + [(set_attr "nzb" "yes")]) + +(define_insn "*nzb=1.<code>.zerox" + [(set (match_operand:QI 0 "register_operand" "=<nzb_constr_rdr>") + (bitop:QI (zero_extract:QI (match_operand:QI 1 "register_operand" "r") + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand" "n")) + (unspec:QI [(match_operand:QI 3 "register_operand" "0") + ] UNSPEC_NZB))) + (use (match_operand:QI 4 "nonmemory_operand" "<nzb_use1_nnr>")) + (clobber (reg:CC REG_CC))] + "optimize && avropt_use_nonzero_bits" + { + if (<CODE> == AND) + return "sbrs %1,%2\;clr %0"; + else if (<CODE> == IOR) + return "sbrc %1,%2\;ori %0,1"; + else if (<CODE> == XOR) + return "sbrc %1,%2\;eor %0,%4"; + else + gcc_unreachable (); + } + [(set_attr "length" "2")]) + +(define_insn_and_split "*nzb=1.<code>.lsr_split" + [(set (match_operand:QI 0 "register_operand") + (bitop:QI (lshiftrt:QI (match_operand:QI 1 "register_operand") + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] + "optimize && avropt_use_nonzero_bits + && !reload_completed + && avr_nonzero_bits_lsr_operands_p (<CODE>, operands)" + { gcc_unreachable (); } + "optimize && avropt_use_nonzero_bits + && !reload_completed" + [(parallel [(set (match_dup 0) + (bitop:QI (zero_extract:QI (match_dup 1) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) + (use (const_int 1)) + (clobber (reg:CC REG_CC))])] + "" + [(set_attr "nzb" "yes")]) + +(define_insn_and_split "*nzb=1.<code>.zerox.not_split" + [(set (match_operand:QI 0 "register_operand") + (bitop:QI (zero_extract:QI (xor:QI (match_operand:QI 1 "register_operand") + (match_operand:QI 4 "const_int_operand")) + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] + "optimize && avropt_use_nonzero_bits + && !reload_completed + && INTVAL (operands[2]) == exact_log2 (0xff & INTVAL (operands[4])) + && (<CODE> == IOR + || nonzero_bits (operands[3], QImode) == 1)" + { gcc_unreachable (); } + "optimize && avropt_use_nonzero_bits + && !reload_completed" + ; "*nzb=1.<code>.zerox.not" + [(parallel [(set (match_dup 0) + (bitop:QI (zero_extract:QI (not:QI (match_dup 1)) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) + (use (const_int 1)) + (clobber (reg:CC REG_CC))])] + "" + [(set_attr "nzb" "yes")]) + +(define_insn_and_split "*nzb=1.<code>.lsr.not_split" + [(set (match_operand:QI 0 "register_operand") + (bitop:QI (lshiftrt:QI (xor:QI (match_operand:QI 1 "register_operand") + (match_operand:QI 4 "const_int_operand")) + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] + "optimize && avropt_use_nonzero_bits + && !reload_completed + && INTVAL (operands[2]) == exact_log2 (0xff & INTVAL (operands[4])) + && avr_nonzero_bits_lsr_operands_p (<CODE>, operands)" + { gcc_unreachable (); } + "optimize && avropt_use_nonzero_bits + && !reload_completed" + ; "*nzb=1.<code>.zerox.not" + [(parallel [(set (match_dup 0) + (bitop:QI (zero_extract:QI (not:QI (match_dup 1)) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) + (use (const_int 1)) + (clobber (reg:CC REG_CC))])] + "" + [(set_attr "nzb" "yes")]) + +(define_insn_and_split "*nzb=1.<code>.ge0_split" + [(set (match_operand:QI 0 "register_operand") + (bitop:QI (ge:QI (match_operand:QI 1 "register_operand") + (const_int 0)) + (match_operand:QI 2 "register_operand")))] + "optimize && avropt_use_nonzero_bits + && !reload_completed + && (<CODE> == IOR || <CODE> == XOR + || nonzero_bits (operands[2], QImode) == 1)" + { gcc_unreachable (); } + "optimize && avropt_use_nonzero_bits + && !reload_completed" + ; "*nzb=1.<code>.zerox.not" + [(parallel [(set (match_dup 0) + (bitop:QI (zero_extract:QI (not:QI (match_dup 1)) + (const_int 1) + (const_int 7)) + (unspec:QI [(match_dup 2) + ] UNSPEC_NZB))) + (use (const_int 1)) + (clobber (reg:CC REG_CC))])] + "" + [(set_attr "nzb" "yes")]) + +(define_insn "*nzb=1.<code>.zerox.not" + [(set (match_operand:QI 0 "register_operand" "=<nzb_constr_rdr>") + (bitop:QI (zero_extract:QI (not:QI (match_operand:QI 1 "register_operand" "r")) + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand" "n")) + (unspec:QI [(match_operand:QI 3 "register_operand" "0") + ] UNSPEC_NZB))) + (use (match_operand:QI 4 "nonmemory_operand" "<nzb_use1_nnr>")) + (clobber (reg:CC REG_CC))] + "optimize && avropt_use_nonzero_bits" + { + if (<CODE> == AND) + return "sbrc %1,%2\;clr %0"; + else if (<CODE> == IOR) + return "sbrs %1,%2\;ori %0,1"; + else if (<CODE> == XOR) + return "sbrs %1,%2\;eor %0,%4"; + else + gcc_unreachable (); + } + [(set_attr "length" "2")]) + +(define_insn_and_split "*nzb=1.ior.ashift_split" + [(set (match_operand:QI 0 "register_operand" "=d") + (ior:QI (ashift:QI (match_operand:QI 1 "register_operand" "r") + (match_operand:QI 2 "const_0_to_7_operand" "n")) + (match_operand:QI 3 "register_operand" "0")))] + "optimize && avropt_use_nonzero_bits + && !reload_completed + && nonzero_bits (operands[1], QImode) == 1" + { gcc_unreachable (); } + "optimize && avropt_use_nonzero_bits + && !reload_completed" + [(parallel [(set (match_dup 0) + (unspec:QI [(ior:QI (ashift:QI (match_dup 1) + (match_dup 2)) + (match_dup 3)) + ] UNSPEC_NZB)) + (clobber (reg:CC REG_CC))])] + "" + [(set_attr "nzb" "yes")]) + +(define_insn "*nzb=1.ior.ashift" + [(set (match_operand:QI 0 "register_operand" "=d") + (unspec:QI [(ior:QI (ashift:QI (match_operand:QI 1 "register_operand" "r") + (match_operand:QI 2 "const_0_to_7_operand" "n")) + (match_operand:QI 3 "register_operand" "0")) + ] UNSPEC_NZB)) + (clobber (reg:CC REG_CC))] + "optimize && avropt_use_nonzero_bits" + "sbrc %1,0\;ori %0,1<<%2" + [(set_attr "length" "2")]) + ;; Work around PR115307: Early passes expand isinf/f/l to a bloat. ;; These passes do not consider costs, and there is no way to diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index d22a118..2bed8ea 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -18,10 +18,6 @@ ; along with GCC; see the file COPYING3. If not see ; <http://www.gnu.org/licenses/>. -mlra -Target Var(avropt_lra_p) UInteger Init(0) Optimization Undocumented -Usa LRA for reload instead of the old reload framework. This option is experimental, and it may be removed in future versions of the compiler. - mcall-prologues Target Mask(CALL_PROLOGUES) Optimization Optimization. Use subroutines for function prologues and epilogues. @@ -65,6 +61,10 @@ mpr118012 Target Var(avropt_pr118012) UInteger Init(1) Undocumented This option is on per default in order to work around PR118012. +muse-nonzero-bits +Target Var(avropt_use_nonzero_bits) UInteger Init(0) Optimization +Optimization. Allow to use nonzero_bits() in some insn conditions. + mshort-calls Target RejectNegative Mask(SHORT_CALLS) This option is used internally for multilib generation and selection. Assume RJMP / RCALL can target all program memory. @@ -160,6 +160,10 @@ mfuse-move= Target Joined RejectNegative UInteger Var(avropt_fuse_move) Init(0) Optimization IntegerRange(0, 23) -mfuse-move=<0,23> Optimization. Run a post-reload pass that tweaks move instructions. +mfuse-move2 +Target Var(avropt_fuse_move2) Init(0) Optimization +Optimization. Fuse some move insns after insn combine. + mabsdata Target Mask(ABSDATA) Assume that all data in static storage can be accessed by LDS / STS instructions. This option is only useful for reduced Tiny devices like ATtiny40. diff --git a/gcc/config/avr/avr.opt.urls b/gcc/config/avr/avr.opt.urls index 64cf060..fa560bc 100644 --- a/gcc/config/avr/avr.opt.urls +++ b/gcc/config/avr/avr.opt.urls @@ -1,7 +1,5 @@ ; Autogenerated by regenerate-opt-urls.py from gcc/config/avr/avr.opt and generated HTML -; skipping UrlSuffix for 'mlra' due to finding no URLs - mcall-prologues UrlSuffix(gcc/AVR-Options.html#index-mcall-prologues) @@ -26,6 +24,9 @@ UrlSuffix(gcc/AVR-Options.html#index-mskip-bug) mrmw UrlSuffix(gcc/AVR-Options.html#index-mrmw) +muse-nonzero-bits +UrlSuffix(gcc/AVR-Options.html#index-muse-nonzero-bits) + mshort-calls UrlSuffix(gcc/AVR-Options.html#index-mshort-calls) @@ -89,6 +90,9 @@ UrlSuffix(gcc/AVR-Options.html#index-mfuse-move) mfuse-move= UrlSuffix(gcc/AVR-Options.html#index-mfuse-move) +mfuse-move2 +UrlSuffix(gcc/AVR-Options.html#index-mfuse-move2) + mabsdata UrlSuffix(gcc/AVR-Options.html#index-mabsdata) diff --git a/gcc/config/avr/specs.h b/gcc/config/avr/specs.h index ff269bf..c95c758 100644 --- a/gcc/config/avr/specs.h +++ b/gcc/config/avr/specs.h @@ -57,7 +57,7 @@ along with GCC; see the file COPYING3. If not see "%(asm_errata_skip) " #define LINK_RELAX_SPEC \ - "%{mrelax:--relax} " + "%{!r:%{mrelax:--relax}} " #undef LINK_SPEC #define LINK_SPEC \ |