[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