Commit 5c4feb2d by Georg-Johann Lay Committed by Georg-Johann Lay

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
parent a8745cc2
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.
......
......@@ -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
......
/* { 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;
}
/* { 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;
}
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment