aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2012-01-04 12:39:26 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2012-01-04 12:39:26 +0000
commit299c4b5f8853aa54f17ed38602aced0af0f5b503 (patch)
treec824bcb45c14a6f935a158dd58ff75b45770aba1 /gcc
parent74d1a34e8600c3b8254eb198ef450e761598a18c (diff)
downloadgcc-299c4b5f8853aa54f17ed38602aced0af0f5b503.zip
gcc-299c4b5f8853aa54f17ed38602aced0af0f5b503.tar.gz
gcc-299c4b5f8853aa54f17ed38602aced0af0f5b503.tar.bz2
Fix clearing ZERO_REG
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. From-SVN: r182871
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/avr/avr.c51
-rw-r--r--gcc/config/avr/avr.md4
3 files changed, 48 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f359bd1..e34cfa0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index e2cd135..4830632 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -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);
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 9222f0b..9f3c3f1 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -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"
@@ -584,7 +584,7 @@
}
[(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.