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
This commit is contained in:
parent
74d1a34e86
commit
299c4b5f88
@ -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>
|
2012-01-04 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
|
||||||
|
|
||||||
* configure: Regenerate.
|
* configure: Regenerate.
|
||||||
|
@ -1994,6 +1994,7 @@ notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
|
|||||||
|
|
||||||
case CC_OUT_PLUS:
|
case CC_OUT_PLUS:
|
||||||
case CC_OUT_PLUS_NOCLOBBER:
|
case CC_OUT_PLUS_NOCLOBBER:
|
||||||
|
case CC_LDI:
|
||||||
{
|
{
|
||||||
rtx *op = recog_data.operand;
|
rtx *op = recog_data.operand;
|
||||||
int len_dummy, icc;
|
int len_dummy, icc;
|
||||||
@ -2001,16 +2002,36 @@ notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
|
|||||||
/* Extract insn's operands. */
|
/* Extract insn's operands. */
|
||||||
extract_constrain_insn_cached (insn);
|
extract_constrain_insn_cached (insn);
|
||||||
|
|
||||||
if (CC_OUT_PLUS == cc)
|
switch (cc)
|
||||||
avr_out_plus (op, &len_dummy, &icc);
|
{
|
||||||
else
|
default:
|
||||||
avr_out_plus_noclobber (op, &len_dummy, &icc);
|
gcc_unreachable();
|
||||||
|
|
||||||
cc = (enum attr_cc) icc;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} /* outer swicth */
|
||||||
|
|
||||||
switch (cc)
|
switch (cc)
|
||||||
{
|
{
|
||||||
@ -8945,9 +8966,9 @@ avr_regno_mode_code_ok_for_base_p (int regno,
|
|||||||
|
|
||||||
The effect on cc0 is as follows:
|
The effect on cc0 is as follows:
|
||||||
|
|
||||||
Load 0 to any register : NONE
|
Load 0 to any register except ZERO_REG : NONE
|
||||||
Load ld register with any value : NONE
|
Load ld register with any value : NONE
|
||||||
Anything else: : CLOBBER */
|
Anything else: : CLOBBER */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
|
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 (ival[n] == 0)
|
||||||
{
|
{
|
||||||
if (!clear_p)
|
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);
|
&xdest[n], len, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -9224,8 +9247,8 @@ output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
|
|||||||
{
|
{
|
||||||
/* Default needs 4 CLR instructions: clear register beforehand. */
|
/* Default needs 4 CLR instructions: clear register beforehand. */
|
||||||
|
|
||||||
avr_asm_len ("clr %A0" CR_TAB
|
avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
|
||||||
"clr %B0" CR_TAB
|
"mov %B0,__zero_reg__" CR_TAB
|
||||||
"movw %C0,%A0", &op[0], len, 3);
|
"movw %C0,%A0", &op[0], len, 3);
|
||||||
|
|
||||||
output_reload_in_const (op, clobber_reg, len, true);
|
output_reload_in_const (op, clobber_reg, len, true);
|
||||||
|
@ -95,7 +95,7 @@
|
|||||||
|
|
||||||
;; Condition code settings.
|
;; Condition code settings.
|
||||||
(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
|
(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"))
|
(const_string "none"))
|
||||||
|
|
||||||
(define_attr "type" "branch,branch1,arith,xcall"
|
(define_attr "type" "branch,branch1,arith,xcall"
|
||||||
@ -584,7 +584,7 @@
|
|||||||
}
|
}
|
||||||
[(set_attr "length" "1,1,5,5,1,1,4")
|
[(set_attr "length" "1,1,5,5,1,1,4")
|
||||||
(set_attr "adjust_len" "mov8")
|
(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
|
;; This is used in peephole2 to optimize loading immediate constants
|
||||||
;; if a scratch register from LD_REGS happens to be available.
|
;; if a scratch register from LD_REGS happens to be available.
|
||||||
|
Loading…
Reference in New Issue
Block a user