[Bug c++/47675] New: [avr] problems with asm when all registers on clobber list
Kicer86 at gmail dot com
gcc-bugzilla@gcc.gnu.org
Thu Feb 10 10:05:00 GMT 2011
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47675
Summary: [avr] problems with asm when all registers on clobber
list
Product: gcc
Version: 4.5.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: Kicer86@gmail.com
I've noticed that, when i use a big asm routine that uses *all* of registers
(r0 to r31) g++ doesn't handle it.
example:
class A
{
int d;
public:
A():d(0){}
void test(void)
{
asm volatile("nop"
:::"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18","r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29","r30","r31");
d++;
}
int getD() const
{
return d;
}
};
int f(A *a, A* b)
{
a->test();
return a->getD();
}
and the interesting part of the output is:
26: cd b7 in r28, 0x3d ; 61
28: de b7 in r29, 0x3e ; 62
2a: 9a 83 std Y+2, r25 ; 0x02
2c: 89 83 std Y+1, r24 ; 0x01
2e: 00 00 nop
30: e9 81 ldd r30, Y+1 ; 0x01
32: fa 81 ldd r31, Y+2 ; 0x02
34: 20 81 ld r18, Z
36: 31 81 ldd r19, Z+1 ; 0x01
as you may see, just after nop execution, Y register is used (to restore Z
register).
The solution is to leave at least 2 register untouched (let's say I remove r20
and r21 from the clobber list) and the output is right:
24: 48 2f mov r20, r24
26: 59 2f mov r21, r25
28: 00 00 nop
2a: e4 2f mov r30, r20
2c: f5 2f mov r31, r21
2e: 20 81 ld r18, Z
30: 31 81 ldd r19, Z+1 ; 0x01
(here Z register is being restored from untouched r21:r20).
For this moment gcc saves (pushes) all the registers at the begining of
function (not the begining of asm routine) and restores them at the end of
function (not asm routine). Maybe the solution is to restore clobbered
registers just after the end of asm routine?
More information about the Gcc-bugs
mailing list