diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2011-10-12 09:59:30 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2011-10-12 09:59:30 +0000 |
commit | 9bc9ee679959ee61d93ee0d39b7df2235bf0f38a (patch) | |
tree | cbf58215876ec07f4e01477bde81061f8a1df931 /gcc | |
parent | 2ba87a294f618e93699867f50f924758c60dab45 (diff) | |
download | gcc-9bc9ee679959ee61d93ee0d39b7df2235bf0f38a.zip gcc-9bc9ee679959ee61d93ee0d39b7df2235bf0f38a.tar.gz gcc-9bc9ee679959ee61d93ee0d39b7df2235bf0f38a.tar.bz2 |
re PR target/49939 ([avr] Skip 2-word instructions if applicable)
PR target/49939
* config/avr/avr.md (*movqi): Rename to movqi_insn.
(*call_insn): Rename to call_insn.
(*call_value_insn): Rename to call_value_insn.
* config/avr/avr.c (avr_2word_insn_p): New static function.
(jump_over_one_insn_p): Use it.
From-SVN: r179843
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 53 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 6 |
3 files changed, 64 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 96d79e6..7b66633 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-10-12 Georg-Johann Lay <avr@gjlay.de> + + PR target/49939 + * config/avr/avr.md (*movqi): Rename to movqi_insn. + (*call_insn): Rename to call_insn. + (*call_value_insn): Rename to call_value_insn. + * config/avr/avr.c (avr_2word_insn_p): New static function. + (jump_over_one_insn_p): Use it. + 2011-10-12 Richard Sandiford <richard.sandiford@linaro.org> * expr.h (copy_blkmode_to_reg): Declare. diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 751f27a..4a93c0a 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -7202,6 +7202,53 @@ test_hard_reg_class (enum reg_class rclass, rtx x) } +/* Helper for jump_over_one_insn_p: Test if INSN is a 2-word instruction + and thus is suitable to be skipped by CPSE, SBRC, etc. */ + +static bool +avr_2word_insn_p (rtx insn) +{ + if (avr_current_device->errata_skip + || !insn + || 2 != get_attr_length (insn)) + { + return false; + } + + switch (INSN_CODE (insn)) + { + default: + return false; + + case CODE_FOR_movqi_insn: + { + rtx set = single_set (insn); + rtx src = SET_SRC (set); + rtx dest = SET_DEST (set); + + /* Factor out LDS and STS from movqi_insn. */ + + if (MEM_P (dest) + && (REG_P (src) || src == const0_rtx)) + { + return CONSTANT_ADDRESS_P (XEXP (dest, 0)); + } + else if (REG_P (dest) + && MEM_P (src)) + { + return CONSTANT_ADDRESS_P (XEXP (src, 0)); + } + + return false; + } + + case CODE_FOR_call_insn: + case CODE_FOR_call_value_insn: + return true; + } +} + + int jump_over_one_insn_p (rtx insn, rtx dest) { @@ -7210,7 +7257,11 @@ jump_over_one_insn_p (rtx insn, rtx dest) : dest); int jump_addr = INSN_ADDRESSES (INSN_UID (insn)); int dest_addr = INSN_ADDRESSES (uid); - return dest_addr - jump_addr == get_attr_length (insn) + 1; + int jump_offset = dest_addr - jump_addr - get_attr_length (insn); + + return (jump_offset == 1 + || (jump_offset == 2 + && avr_2word_insn_p (next_active_insn (insn)))); } /* Returns 1 if a value of mode MODE can be stored starting with hard diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index b7fe770..1052378 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -296,7 +296,7 @@ operands[1] = copy_to_mode_reg(QImode, operand1); ") -(define_insn "*movqi" +(define_insn "movqi_insn" [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r") (match_operand:QI 1 "general_operand" "rL,i,rL,Qm,r,q,i"))] "(register_operand (operands[0],QImode) @@ -3627,7 +3627,7 @@ "" "") -(define_insn "*call_insn" +(define_insn "call_insn" [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s")) (match_operand:HI 1 "general_operand" "X,X,X,X")) (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])] @@ -3650,7 +3650,7 @@ (const_int 2) (const_int 1))])]) -(define_insn "*call_value_insn" +(define_insn "call_value_insn" [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r") (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s")) (match_operand:HI 2 "general_operand" "X,X,X,X"))) |