diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2014-05-09 11:20:43 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2014-05-09 11:20:43 +0000 |
commit | b846980537e3d2f272c461fac6777c6d991aeb67 (patch) | |
tree | 23cd01570b81a57b568a9a032d48643a350cc98f /gcc | |
parent | eac3e079667d0a56f2ba84469a764407f3aee2a9 (diff) | |
download | gcc-b846980537e3d2f272c461fac6777c6d991aeb67.zip gcc-b846980537e3d2f272c461fac6777c6d991aeb67.tar.gz gcc-b846980537e3d2f272c461fac6777c6d991aeb67.tar.bz2 |
re PR target/61055 ([avr] wrong test instruction after increment with -O1)
gcc/config/avr
PR target/61055
* config/avr/avr.md (cc): Add new attribute set_vzn.
(addqi3, addqq3, adduqq3, subqi3, subqq3, subuqq3, negqi2) [cc]:
Set cc insn attribute to set_vzn instead of set_zn for alternatives
with INC, DEC or NEG.
* config/avr/avr.c (avr_notice_update_cc): Handle SET_VZN.
(avr_out_plus_1): ADIW sets cc0 to CC_SET_CZN.
INC, DEC and ADD+ADC set cc0 to CC_CLOBBER.
gcc/testsuite/
PR target/61055
* gcc.target/avr/torture/pr61055.c: New test.
From-SVN: r210267
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 11 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/avr/torture/pr61055.c | 88 |
5 files changed, 117 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 09bbce0..ef75bcb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2014-05-09 Georg-Johann Lay <avr@gjlay.de> + + PR target/61055 + * config/avr/avr.md (cc): Add new attribute set_vzn. + (addqi3, addqq3, adduqq3, subqi3, subqq3, subuqq3, negqi2) [cc]: + Set cc insn attribute to set_vzn instead of set_zn for alternatives + with INC, DEC or NEG. + * config/avr/avr.c (avr_notice_update_cc): Handle SET_VZN. + (avr_out_plus_1): ADIW sets cc0 to CC_SET_CZN. + INC, DEC and ADD+ADC set cc0 to CC_CLOBBER. + 2014-05-09 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> Revert: diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 2edc78a..536fe68 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -2359,6 +2359,12 @@ avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn) } break; + case CC_SET_VZN: + /* Insn like INC, DEC, NEG that set Z,N,V. We currently don't make use + of this combination, cf. also PR61055. */ + CC_STATUS_INIT; + break; + case CC_SET_CZN: /* Insn sets the Z,N,C flags of CC to recog_operand[0]. The V flag may or may not be known but that's ok because @@ -6290,7 +6296,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc, if (REG_P (xop[2])) { - *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N; + *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_CLOBBER; for (i = 0; i < n_bytes; i++) { @@ -6399,7 +6405,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc, op, plen, 1); if (n_bytes == 2 && PLUS == code) - *pcc = CC_SET_ZN; + *pcc = CC_SET_CZN; } i++; @@ -6422,6 +6428,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc, { avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0", op, plen, 1); + *pcc = CC_CLOBBER; break; } diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index d7baa4a..2c59bf3 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -90,7 +90,7 @@ (include "constraints.md") ;; Condition code settings. -(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber, +(define_attr "cc" "none,set_czn,set_zn,set_vzn,set_n,compare,clobber, plus,ldi" (const_string "none")) @@ -1098,7 +1098,7 @@ inc %0\;inc %0 dec %0\;dec %0" [(set_attr "length" "1,1,1,1,2,2") - (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")]) + (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")]) ;; "addhi3" ;; "addhq3" "adduhq3" @@ -1369,7 +1369,7 @@ dec %0\;dec %0 inc %0\;inc %0" [(set_attr "length" "1,1,1,1,2,2") - (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")]) + (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")]) ;; "subhi3" ;; "subhq3" "subuhq3" @@ -3992,7 +3992,7 @@ "" "neg %0" [(set_attr "length" "1") - (set_attr "cc" "set_zn")]) + (set_attr "cc" "set_vzn")]) (define_insn "*negqihi2" [(set (match_operand:HI 0 "register_operand" "=r") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 52639c0..8918976 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-05-09 Georg-Johann Lay <avr@gjlay.de> + + PR target/61055 + * gcc.target/avr/torture/pr61055.c: New test. + 2014-05-09 Marek Polacek <polacek@redhat.com> PR c/50459 diff --git a/gcc/testsuite/gcc.target/avr/torture/pr61055.c b/gcc/testsuite/gcc.target/avr/torture/pr61055.c new file mode 100644 index 0000000..9dd1f42 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr61055.c @@ -0,0 +1,88 @@ +/* { dg-do run } */ +/* { dg-options { -fno-peephole2 } } */ + +#include <stdlib.h> + +typedef __UINT16_TYPE__ uint16_t; +typedef __INT16_TYPE__ int16_t; +typedef __UINT8_TYPE__ uint8_t; + +uint8_t __attribute__((noinline,noclone)) +fun_inc (uint8_t c0) +{ + register uint8_t c asm ("r15") = c0; + + /* Force target value into R15 (lower register) */ + asm ("" : "+l" (c)); + + c++; + if (c >= 0x80) + c = 0; + + asm ("" : "+l" (c)); + + return c; +} + +uint8_t __attribute__((noinline,noclone)) +fun_dec (uint8_t c0) +{ + register uint8_t c asm ("r15") = c0; + + /* Force target value into R15 (lower register) */ + asm ("" : "+l" (c)); + + c--; + if (c < 0x80) + c = 0; + + asm ("" : "+l" (c)); + + return c; +} + + +uint8_t __attribute__((noinline,noclone)) +fun_neg (uint8_t c0) +{ + register uint8_t c asm ("r15") = c0; + + c = -c; + if (c >= 0x80) + c = 0; + + return c; +} + +uint16_t __attribute__((noinline,noclone)) +fun_adiw (uint16_t c0) +{ + register uint16_t c asm ("r24") = c0; + + /* Force target value into R24 (for ADIW) */ + asm ("" : "+r" (c)); + + c += 2; + if (c >= 0x8000) + c = 0; + + asm ("" : "+r" (c)); + + return c; +} + + +int main() +{ + if (fun_inc (0x7f) != 0) + abort(); + + if (fun_neg (0x80) != 0) + abort(); + + if (fun_adiw (0x7ffe) != 0) + abort(); + + exit (0); + return 0; +} |