OSDN Git Service

Fix clearing ZERO_REG
authorgjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 4 Jan 2012 12:39:26 +0000 (12:39 +0000)
committergjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 4 Jan 2012 12:39:26 +0000 (12:39 +0000)
* config/avr/avr.md (cc): Add alternative "ldi".
(movqi_insn): Use it in cc attribute.
* config/avr/avr.c (notice_update_cc): Handle CC_LDI.
(output_reload_in_const): Use CLR to move 0 to ZERO_REG.
(output_reload_insisf): Use ZERO_REG to pre-clear register.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182871 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/avr/avr.c
gcc/config/avr/avr.md

index f359bd1..e34cfa0 100644 (file)
@@ -1,3 +1,12 @@
+2012-01-04  Georg-Johann Lay  <avr@gjlay.de>
+
+       Fix clearing ZERO_REG
+       * config/avr/avr.md (cc): Add alternative "ldi".
+       (movqi_insn): Use it in cc attribute.
+       * config/avr/avr.c (notice_update_cc): Handle CC_LDI.
+       (output_reload_in_const): Use CLR to move 0 to ZERO_REG.
+       (output_reload_insisf): Use ZERO_REG to pre-clear register.
+
 2012-01-04  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
        * configure: Regenerate.
index e2cd135..4830632 100644 (file)
@@ -1994,6 +1994,7 @@ notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
 
     case CC_OUT_PLUS:
     case CC_OUT_PLUS_NOCLOBBER:
+    case CC_LDI:
       {
         rtx *op = recog_data.operand;
         int len_dummy, icc;
@@ -2001,16 +2002,36 @@ notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
         /* Extract insn's operands.  */
         extract_constrain_insn_cached (insn);
 
-        if (CC_OUT_PLUS == cc)
-          avr_out_plus (op, &len_dummy, &icc);
-        else
-          avr_out_plus_noclobber (op, &len_dummy, &icc);
-        
-        cc = (enum attr_cc) icc;
-        
+        switch (cc)
+          {
+          default:
+            gcc_unreachable();
+            
+          case CC_OUT_PLUS:
+            avr_out_plus (op, &len_dummy, &icc);
+            cc = (enum attr_cc) icc;
+            break;
+            
+          case CC_OUT_PLUS_NOCLOBBER:
+            avr_out_plus_noclobber (op, &len_dummy, &icc);
+            cc = (enum attr_cc) icc;
+            break;
+
+          case CC_LDI:
+
+            cc = (op[1] == CONST0_RTX (GET_MODE (op[0]))
+                  && reg_overlap_mentioned_p (op[0], zero_reg_rtx))
+              /* Loading zero-reg with 0 uses CLI and thus clobbers cc0.  */
+              ? CC_CLOBBER
+              /* Any other "r,rL" combination does not alter cc0.  */
+              : CC_NONE;
+            
+            break;
+          } /* inner switch */
+
         break;
       }
-    }
+    } /* outer swicth */
 
   switch (cc)
     {
@@ -8945,9 +8966,9 @@ avr_regno_mode_code_ok_for_base_p (int regno,
 
    The effect on cc0 is as follows:
 
-   Load 0 to any register          : NONE
-   Load ld register with any value : NONE
-   Anything else:                  : CLOBBER  */
+   Load 0 to any register except ZERO_REG : NONE
+   Load ld register with any value        : NONE
+   Anything else:                         : CLOBBER  */
 
 static void
 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
@@ -9062,7 +9083,9 @@ output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
       if (ival[n] == 0)
         {
           if (!clear_p)
-            avr_asm_len (ldreg_p ? "ldi %0,0" : "mov %0,__zero_reg__",
+            avr_asm_len (ldreg_p ? "ldi %0,0"
+                         : ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
+                         : "mov %0,__zero_reg__",
                          &xdest[n], len, 1);
           continue;
         }
@@ -9224,8 +9247,8 @@ output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
         {
           /* Default needs 4 CLR instructions: clear register beforehand.  */
           
-          avr_asm_len ("clr %A0" CR_TAB
-                       "clr %B0" CR_TAB
+          avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
+                       "mov %B0,__zero_reg__" CR_TAB
                        "movw %C0,%A0", &op[0], len, 3);
           
           output_reload_in_const (op, clobber_reg, len, true);
index 9222f0b..9f3c3f1 100644 (file)
@@ -95,7 +95,7 @@
   
 ;; Condition code settings.
 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
-                   out_plus, out_plus_noclobber"
+                   out_plus, out_plus_noclobber,ldi"
   (const_string "none"))
 
 (define_attr "type" "branch,branch1,arith,xcall"
   }
   [(set_attr "length" "1,1,5,5,1,1,4")
    (set_attr "adjust_len" "mov8")
-   (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
+   (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
 
 ;; This is used in peephole2 to optimize loading immediate constants
 ;; if a scratch register from LD_REGS happens to be available.