re PR target/81305 ([avr] avrtiny uses LDS for SREG in ISR routines which is out...
authorGeorg-Johann Lay <avr@gjlay.de>
Wed, 5 Jul 2017 12:28:19 +0000 (12:28 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Wed, 5 Jul 2017 12:28:19 +0000 (12:28 +0000)
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
gcc/config/avr/avr.c
gcc/testsuite/gcc.target/avr/torture/isr-01-simple.c [new file with mode: 0644]
gcc/testsuite/gcc.target/avr/torture/isr-02-call.c [new file with mode: 0644]
gcc/testsuite/gcc.target/avr/torture/isr-03-fixed.c [new file with mode: 0644]

index 2f11b143c962a781f39e05c626ea8d91a876abc3..121f6ab441d7e129c78f303bd88a54602a3c8605 100644 (file)
@@ -1,3 +1,16 @@
+2017-07-05  Georg-Johann Lay  <avr@gjlay.de>
+
+       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  <bin.cheng@arm.com>
 
        * tree-loop-distribution.c: Add general explanantion on the pass.
index 4f385d5682f6d373384630d897b0f76509b4c45b..030a9d9ee97606deb01bead9cd5d289318890b30 100644 (file)
@@ -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 (file)
index 0000000..271d0cf
--- /dev/null
@@ -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 (file)
index 0000000..be4f22e
--- /dev/null
@@ -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 (file)
index 0000000..5606225
--- /dev/null
@@ -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;
+}