AVR: target/98762 - Handle partial clobber in movqi output.
PR target/98762 gcc/ * config/avr/avr.cc (avr_out_movqi_r_mr_reg_disp_tiny): Properly restore the base register when it is partially clobbered. gcc/testsuite/ * gcc.target/avr/torture/pr98762.c: New test. (cherry picked from commit e9fb6efa1cf542353fd44ddcbb5136344c463fd0)
This commit is contained in:
parent
052f78d010
commit
55744507ab
2 changed files with 41 additions and 5 deletions
|
@ -4838,13 +4838,30 @@ avr_out_movqi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
|
|||
rtx dest = op[0];
|
||||
rtx src = op[1];
|
||||
rtx x = XEXP (src, 0);
|
||||
rtx base = XEXP (x, 0);
|
||||
|
||||
avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
|
||||
"ld %0,%b1" , op, plen, -3);
|
||||
if (plen)
|
||||
*plen = 0;
|
||||
|
||||
if (!reg_overlap_mentioned_p (dest, XEXP (x, 0))
|
||||
&& !reg_unused_after (insn, XEXP (x, 0)))
|
||||
avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
|
||||
if (!reg_overlap_mentioned_p (dest, base))
|
||||
{
|
||||
avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
|
||||
"ld %0,%b1", op, plen, 3);
|
||||
if (!reg_unused_after (insn, base))
|
||||
avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// PR98762: The base register overlaps dest and is only partly clobbered.
|
||||
rtx base2 = all_regs_rtx[1 ^ REGNO (dest)];
|
||||
|
||||
if (!reg_unused_after (insn, base2))
|
||||
avr_asm_len ("mov __tmp_reg__,%0" , &base2, plen, 1);
|
||||
avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
|
||||
"ld %0,%b1", op, plen, 3);
|
||||
if (!reg_unused_after (insn, base2))
|
||||
avr_asm_len ("mov %0,__tmp_reg__" , &base2, plen, 1);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
|
19
gcc/testsuite/gcc.target/avr/torture/pr98762.c
Normal file
19
gcc/testsuite/gcc.target/avr/torture/pr98762.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-additional-options "-std=c99" } */
|
||||
|
||||
long long acc = 0x1122334455667788;
|
||||
|
||||
__attribute__((noinline,noclone))
|
||||
void addhi (short a)
|
||||
{
|
||||
acc += (long long) a << 32;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
addhi (0x0304);
|
||||
if (acc != 0x1122364855667788)
|
||||
__builtin_abort();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue