From 5c4feb2d1a0b504f24bb340b2406983955248abd Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Wed, 5 Jul 2017 12:28:19 +0000 Subject: [PATCH] re PR target/81305 ([avr] avrtiny uses LDS for SREG in ISR routines which is out of range of LDS.) gcc/ PR target/81305 * config/avr/avr.c (avr_out_movhi_mr_r_xmega) [CONSTANT_ADDRESS_P]: Don't depend on "optimize > 0". (out_movhi_r_mr, out_movqi_mr_r): Same. (out_movhi_mr_r, out_movqi_r_mr): Same. (avr_address_cost) [CONSTANT_ADDRESS_P]: Don't depend cost for io_address_operand on "optimize > 0". * testsuite/gcc.target/avr/torture/isr-01-simple.c: New test. * testsuite/gcc.target/avr/torture/isr-02-call.c: New test. * testsuite/gcc.target/avr/torture/isr-03-fixed.c: New test. From-SVN: r249995 --- gcc/ChangeLog | 13 ++ gcc/config/avr/avr.c | 16 +- .../gcc.target/avr/torture/isr-01-simple.c | 98 ++++++++++++ .../gcc.target/avr/torture/isr-02-call.c | 60 +++++++ .../gcc.target/avr/torture/isr-03-fixed.c | 146 ++++++++++++++++++ 5 files changed, 324 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/avr/torture/isr-01-simple.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/isr-02-call.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/isr-03-fixed.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2f11b143c96..121f6ab441d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2017-07-05 Georg-Johann Lay + + PR target/81305 + * config/avr/avr.c (avr_out_movhi_mr_r_xmega) [CONSTANT_ADDRESS_P]: + Don't depend on "optimize > 0". + (out_movhi_r_mr, out_movqi_mr_r): Same. + (out_movhi_mr_r, out_movqi_r_mr): Same. + (avr_address_cost) [CONSTANT_ADDRESS_P]: Don't depend cost for + io_address_operand on "optimize > 0". + * testsuite/gcc.target/avr/torture/isr-01-simple.c: New test. + * testsuite/gcc.target/avr/torture/isr-02-call.c: New test. + * testsuite/gcc.target/avr/torture/isr-03-fixed.c: New test. + 2017-07-05 Bin Cheng * tree-loop-distribution.c: Add general explanantion on the pass. diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 4f385d5682f..030a9d9ee97 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -3820,7 +3820,7 @@ out_movqi_r_mr (rtx_insn *insn, rtx op[], int *plen) if (CONSTANT_ADDRESS_P (x)) { int n_words = AVR_TINY ? 1 : 2; - return optimize > 0 && io_address_operand (x, QImode) + return io_address_operand (x, QImode) ? avr_asm_len ("in %0,%i1", op, plen, -1) : avr_asm_len ("lds %0,%m1", op, plen, -n_words); } @@ -4088,7 +4088,7 @@ out_movhi_r_mr (rtx_insn *insn, rtx op[], int *plen) else if (CONSTANT_ADDRESS_P (base)) { int n_words = AVR_TINY ? 2 : 4; - return optimize > 0 && io_address_operand (base, HImode) + return io_address_operand (base, HImode) ? avr_asm_len ("in %A0,%i1" CR_TAB "in %B0,%i1+1", op, plen, -2) @@ -5215,7 +5215,7 @@ out_movqi_mr_r (rtx_insn *insn, rtx op[], int *plen) if (CONSTANT_ADDRESS_P (x)) { int n_words = AVR_TINY ? 1 : 2; - return optimize > 0 && io_address_operand (x, QImode) + return io_address_operand (x, QImode) ? avr_asm_len ("out %i0,%1", op, plen, -1) : avr_asm_len ("sts %m0,%1", op, plen, -n_words); } @@ -5291,13 +5291,12 @@ avr_out_movhi_mr_r_xmega (rtx_insn *insn, rtx op[], int *plen) if (CONSTANT_ADDRESS_P (base)) { - int n_words = AVR_TINY ? 2 : 4; - return optimize > 0 && io_address_operand (base, HImode) + return io_address_operand (base, HImode) ? avr_asm_len ("out %i0,%A1" CR_TAB "out %i0+1,%B1", op, plen, -2) : avr_asm_len ("sts %m0,%A1" CR_TAB - "sts %m0+1,%B1", op, plen, -n_words); + "sts %m0+1,%B1", op, plen, -4); } if (reg_base > 0) @@ -5477,7 +5476,7 @@ out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen) if (CONSTANT_ADDRESS_P (base)) { int n_words = AVR_TINY ? 2 : 4; - return optimize > 0 && io_address_operand (base, HImode) + return io_address_operand (base, HImode) ? avr_asm_len ("out %i0+1,%B1" CR_TAB "out %i0,%A1", op, plen, -2) @@ -11367,8 +11366,7 @@ avr_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED, } else if (CONSTANT_ADDRESS_P (x)) { - if (optimize > 0 - && io_address_operand (x, QImode)) + if (io_address_operand (x, QImode)) cost = 2; if (AVR_TINY diff --git a/gcc/testsuite/gcc.target/avr/torture/isr-01-simple.c b/gcc/testsuite/gcc.target/avr/torture/isr-01-simple.c new file mode 100644 index 00000000000..271d0cf47e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/isr-01-simple.c @@ -0,0 +1,98 @@ +/* { dg-do run } */ +/* { dg-options "-std=c99" } */ + +#include "../isr-test.h" + +int volatile v; + +/**********************************************************************/ + +ISR (1, signal) +{ +} + +MK_RUN_ISR (1, 0) + +void test1 (void) +{ + run_isr_1(); +} + +/**********************************************************************/ + +ISR (2, signal) +{ + v++; +} + +MK_RUN_ISR (2, 0) + +void test2 (void) +{ + v = 0; + run_isr_2(); + if (v != 1) + __builtin_abort(); +} + + +/**********************************************************************/ + +ISR (3, signal) +{ + __asm __volatile__ ("$ lds r27, v" + "$ swap r27" + "$ sts v, r27" + ::: "memory", "r27"); +} + +MK_RUN_ISR (3, 0) + +void test3 (void) +{ + run_isr_3(); + if (v != 0x10) + __builtin_abort(); +} + +/**********************************************************************/ + +ISR (4, signal) +{ + __asm __volatile__ ("sts v,__zero_reg__" ::: "memory"); +} + +MK_RUN_ISR (4, 0) + +void test4 (void) +{ + run_isr_4(); + if (v != 0) + __builtin_abort(); +} + +/**********************************************************************/ + +ISR (5, signal) +{ + __asm __volatile__ ("clt"); +} + +MK_RUN_ISR (5, 0) + +void test5 (void) +{ + run_isr_5(); +} + +/**********************************************************************/ + +int main (void) +{ + test1(); + test2(); + test3(); + test4(); + test5(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/avr/torture/isr-02-call.c b/gcc/testsuite/gcc.target/avr/torture/isr-02-call.c new file mode 100644 index 00000000000..be4f22ebb35 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/isr-02-call.c @@ -0,0 +1,60 @@ +/* { dg-do run } */ +/* { dg-options "-std=c99" } */ + +#include "../isr-test.h" + +int volatile v; + +__attribute__((noinline,noclone)) +void inc_v (void) +{ + v++; +} + +/**********************************************************************/ + +ISR (1, signal) +{ + inc_v(); +} + +MK_RUN_ISR (1, 0) + +void test1 (void) +{ + run_isr_1(); + if (v != 1) + __builtin_abort(); +} + +/**********************************************************************/ + +ISR (2, signal) +{ + if (v == 1) + inc_v(); + else + v += 2; +} + +MK_RUN_ISR (2, 0) + +void test2 (void) +{ + run_isr_2(); + if (v != 2) + __builtin_abort(); + run_isr_2(); + if (v != 4) + __builtin_abort(); +} + + +/**********************************************************************/ + +int main (void) +{ + test1(); + test2(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/avr/torture/isr-03-fixed.c b/gcc/testsuite/gcc.target/avr/torture/isr-03-fixed.c new file mode 100644 index 00000000000..5606225aebc --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/isr-03-fixed.c @@ -0,0 +1,146 @@ +/* { dg-do run } */ +/* { dg-options "-std=gnu99 -fno-lto -fno-toplevel-reorder" } */ + +// No LTO for now due to PR lto/68384. + +#ifdef __AVR_TINY__ +unsigned char reg2; +#else +register unsigned char reg2 __asm("r2"); +#endif + +#include "../isr-test.h" + +#define SET_REG(reg,val) \ + do { \ + reg = (val); \ + __asm __volatile__("" : "+r" (reg)); \ + } while (0) \ + +#define GET_REG(reg) \ + ({ \ + __asm __volatile__("" : "+r" (reg)); \ + reg; \ + }) + +/**********************************************************************/ + +ISR (1, signal) +{ + reg2++; +} + +MK_RUN_ISR (1, 1ul << 2) + +void test1 (void) +{ + SET_REG (reg2, 0); + run_isr_1(); + if (GET_REG (reg2) != 1) + __builtin_abort(); +} + +/**********************************************************************/ + +__attribute__((noinline,noclone)) +void inc_r2 (void) +{ + reg2++; +} + +ISR (2, signal) +{ + inc_r2 (); +} + +MK_RUN_ISR (2, 1ul << 2) + +void test2 (void) +{ + run_isr_2(); + if (GET_REG (reg2) != 2) + __builtin_abort(); +} + + +/**********************************************************************/ + +ISR (3, signal) +{ +#ifndef __AVR_TINY__ + register char r4 __asm ("r4"); + __asm __volatile ("inc %0" : "+r" (r4)); + __asm __volatile ("inc r5" ::: "r5"); +#endif +} + +MK_RUN_ISR (3, 0) + +void test3 (void) +{ + run_isr_3(); +} + + +/**********************************************************************/ + +#define CLOBB(reg) \ + do { \ + __asm __volatile__ ("inc " #reg ::: #reg); \ + } while (0) + +ISR (4, signal) +{ + char volatile v; + v = 1; + +#ifndef __AVR_TINY__ + CLOBB (r3); + CLOBB (r4); + CLOBB (r5); + CLOBB (r6); + CLOBB (r7); + CLOBB (r8); + CLOBB (r9); + CLOBB (r10); + CLOBB (r11); + CLOBB (r12); + CLOBB (r13); + CLOBB (r14); + CLOBB (r15); + CLOBB (r16); + CLOBB (r17); +#endif + + CLOBB (r18); + CLOBB (r19); + CLOBB (r20); + CLOBB (r21); + CLOBB (r22); + CLOBB (r23); + CLOBB (r24); + CLOBB (r25); + CLOBB (r26); + CLOBB (r27); + CLOBB (r30); + CLOBB (r31); +} + +MK_RUN_ISR (4, 0) + +void test4 (void) +{ + run_isr_4(); +} + + +/**********************************************************************/ + +int main (void) +{ + test1(); + test2(); + test3(); + test4(); + return 0; +} -- 2.30.2