avr-protos.h (lpm_reg_rtx, [...]): Make global.
authorGeorg-Johann Lay <avr@gjlay.de>
Fri, 27 Jan 2012 18:17:41 +0000 (18:17 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Fri, 27 Jan 2012 18:17:41 +0000 (18:17 +0000)
* config/avr/avr-protos.h (lpm_reg_rtx, lpm_addr_reg_rtx,
tmp_reg_rtx, zero_reg_rtx, all_regs_rtx, rampz_rtx): Make global.
* config/avr/avr.c: Ditto.
(avr_regnames): Remove because unused.
* config/avr/avr.md (*cpse.ne): New peephole.
(*cpse.eq): New peephole from former cpse peepholes.

From-SVN: r183638

gcc/ChangeLog
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.c
gcc/config/avr/avr.md

index 7ce99da..8773d62 100644 (file)
@@ -1,3 +1,12 @@
+2012-01-27  Georg-Johann Lay  <avr@gjlay.de>
+
+       * config/avr/avr-protos.h (lpm_reg_rtx, lpm_addr_reg_rtx,
+       tmp_reg_rtx, zero_reg_rtx, all_regs_rtx, rampz_rtx): Make global.
+       * config/avr/avr.c: Ditto.
+       (avr_regnames): Remove because unused.
+       * config/avr/avr.md (*cpse.ne): New peephole.
+       (*cpse.eq): New peephole from former cpse peepholes.
+
 2012-01-27  Michael Eager  <eager@eagercon.com>
 
        * config/microblaze.c (microblaze_emit_compare): Correct
index f64dbbf..2575fc4 100644 (file)
@@ -124,6 +124,14 @@ extern bool avr_mem_flash_p (rtx);
 extern bool avr_mem_memx_p (rtx);
 extern bool avr_load_libgcc_p (rtx);
 extern bool avr_xload_libgcc_p (enum machine_mode);
+
+extern rtx lpm_reg_rtx;
+extern rtx lpm_addr_reg_rtx;
+extern rtx tmp_reg_rtx;
+extern rtx zero_reg_rtx;
+extern rtx all_regs_rtx[32];
+extern rtx rampz_rtx;
+
 #endif /* RTX_CODE */
 
 #ifdef REAL_VALUE_TYPE
index 6626087..968f450 100644 (file)
@@ -140,30 +140,33 @@ static bool avr_rtx_costs (rtx, int, int, int, int *, bool);
 #define FIRST_CUM_REG 26
 
 /* Implicit target register of LPM instruction (R0) */
-static GTY(()) rtx lpm_reg_rtx;
+extern GTY(()) rtx lpm_reg_rtx;
+rtx lpm_reg_rtx;
 
 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
-static GTY(()) rtx lpm_addr_reg_rtx;
+extern GTY(()) rtx lpm_addr_reg_rtx;
+rtx lpm_addr_reg_rtx;
 
-/* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
-static GTY(()) rtx tmp_reg_rtx;
+/* Temporary register RTX (reg:QI TMP_REGNO) */
+extern GTY(()) rtx tmp_reg_rtx;
+rtx tmp_reg_rtx;
 
-/* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
-static GTY(()) rtx zero_reg_rtx;
+/* Zeroed register RTX (reg:QI ZERO_REGNO) */
+extern GTY(()) rtx zero_reg_rtx;
+rtx zero_reg_rtx;
+
+/* RTXs for all general purpose registers as QImode */
+extern GTY(()) rtx all_regs_rtx[32];
+rtx all_regs_rtx[32];
 
 /* RAMPZ special function register */
-static GTY(()) rtx rampz_rtx;
+extern GTY(()) rtx rampz_rtx;
+rtx rampz_rtx;
 
 /* RTX containing the strings "" and "e", respectively */
 static GTY(()) rtx xstring_empty;
 static GTY(()) rtx xstring_e;
 
-/* RTXs for all general purpose registers as QImode */
-static GTY(()) rtx all_regs_rtx[32];
-
-/* AVR register names {"r0", "r1", ..., "r31"} */
-static const char *const avr_regnames[] = REGISTER_NAMES;
-
 /* Preprocessor macros to define depending on MCU type.  */
 const char *avr_extra_arch_macro;
 
index 0c47794..24044b3 100644 (file)
           AS1 (jmp,%1));
 }")
 
-(define_peephole
+
+(define_peephole ; "*cpse.eq"
   [(set (cc0)
-       (compare (match_operand:QI 0 "register_operand" "")
-                (const_int 0)))
+        (compare (match_operand:QI 1 "register_operand" "r,r")
+                 (match_operand:QI 2 "reg_or_0_operand" "r,L")))
    (set (pc)
-       (if_then_else (eq (cc0) (const_int 0))
-                     (label_ref (match_operand 1 "" ""))
-                     (pc)))]
-  "jump_over_one_insn_p (insn, operands[1])"
-  "cpse %0,__zero_reg__")
+        (if_then_else (eq (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  "jump_over_one_insn_p (insn, operands[0])"
+  "@
+       cpse %1,%2
+       cpse %1,__zero_reg__")
 
-(define_peephole
+;; This peephole avoids code like
+;;
+;;     TST   Rn     ; *cmpqi
+;;     BREQ  .+2    ; branch
+;;     RJMP  .Lm
+;;
+;; Notice that the peephole is always shorter than cmpqi + branch.
+;; The reason to write it as peephole is that sequences like
+;;     
+;;     AND   Rm, Rn
+;;     BRNE  .La
+;;
+;; shall not be superseeded.  With a respective combine pattern
+;; the latter sequence would be 
+;;     
+;;     AND   Rm, Rn
+;;     CPSE  Rm, __zero_reg__
+;;     RJMP  .La
+;;
+;; and thus longer and slower and not easy to be rolled back.
+
+(define_peephole ; "*cpse.ne"
   [(set (cc0)
-        (compare (match_operand:QI 0 "register_operand" "")
-                (match_operand:QI 1 "register_operand" "")))
+        (compare (match_operand:QI 1 "register_operand" "")
+                 (match_operand:QI 2 "reg_or_0_operand" "")))
    (set (pc)
-       (if_then_else (eq (cc0) (const_int 0))
-                     (label_ref (match_operand 2 "" ""))
+        (if_then_else (ne (cc0)
+                          (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
                      (pc)))]
-  "jump_over_one_insn_p (insn, operands[2])"
-  "cpse %0,%1")
+  "!AVR_HAVE_JMP_CALL
+   || !avr_current_device->errata_skip"
+  {
+    if (operands[2] == const0_rtx)
+      operands[2] = zero_reg_rtx;
+
+    return 3 == avr_jump_mode (operands[0], insn)
+      ? "cpse %1,%2\;jmp %0"
+      : "cpse %1,%2\;rjmp %0";
+  })
 
 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
 ;;prologue/epilogue support instructions