2013-10-06 33 views
1

优化我有这样的ATmega8的AVR代码:如何使增量指针代码AVR

unsigned char* ledptr = &led[0]; 
unsigned char* anodptr = &anod[0]; 
unsigned char* timeptr = &time[0]; 
//other variable 
loop: 
if (i == 170) goto writeee; 
{ 
    while (((PINC | 0b1110000) & ((PIND | 0b00011111)>>1)) == oc); 
    __asm__("mov r24,r25"); 
    if (b) 
    { 
     *(timeptr++) = 0xFF; //want to optimize 
     b = 0; 
    } 
    else 
     *(timeptr++) = TCNT0; //want to optimize 

    TCNT0 = 0; 
    *(++ledptr) = oc; 
    *(++anodptr) = PINB; 
    i++; 
} 
goto loop; 

我希望它进行优化,以st Z+, r25 (or r19),但它变成这样:

e2: e4 eb   ldi r30, 0xB4 ; 180 
    e4: f1 e0   ldi r31, 0x01 ; 1 
    e6: cb e0   ldi r28, 0x0B ; 11 
    e8: d1 e0   ldi r29, 0x01 ; 1 
    ea: a1 e6   ldi r26, 0x61 ; 97 
    ec: b0 e0   ldi r27, 0x00 ; 0 
    ee: 3f ef   ldi r19, 0xFF ; 255 
    f0: 0a 3a   cpi r16, 0xAA ; 170 
    f2: b9 f0   breq .+46  ; 0x122 <writeee> 
    f4: 23 b3   in r18, 0x13 ; 19 
    f6: 90 b3   in r25, 0x10 ; 16 
    f8: 9f 61   ori r25, 0x1F ; 31 
    fa: 96 95   lsr r25 
    fc: 20 67   ori r18, 0x70 ; 112 
    fe: 92 23   and r25, r18 
100: 98 17   cp r25, r24 
102: c1 f3   breq .-16  ; 0xf4 <loop+0x12> 
104: 89 2f   mov r24, r25 
106: 11 23   and r17, r17 
108: 19 f0   breq .+6   ; 0x110 <loop+0x2e> 
10a: 30 83   st Z, r19   ;******not optimized****** 
10c: 10 e0   ldi r17, 0x00 ; 0 
10e: 02 c0   rjmp .+4   ; 0x114 <loop+0x32> 
110: 92 b7   in r25, 0x32 ; 50 
112: 90 83   st Z, r25   ; ******not optimized****** 
114: 12 be   out 0x32, r1 ; 50 
116: 89 93   st Y+, r24 
118: 96 b3   in r25, 0x16 ; 22 
11a: 9d 93   st X+, r25 
11c: 0f 5f   subi r16, 0xFF ; 255 
11e: 31 96   adiw r30, 0x01 ; ******not optimized****** 
120: e7 cf   rjmp .-50  ; 0xf0 <loop+0xe> 

但ledptr和anodptr优化得很好。这是为什么 ?

//当我发布消息“大多码”继续显示...

编辑: 我解决它。使用asm强制优化一个分支,而其他分支自行优化。我很困难,因为我使用asm在BOTH分支强制优化,然后生成的asm拧紧(错误的寄存器)。

__asm__("ldi r19, 0xff"); 
loop: 
if (i == 170) goto writeee; 
{ 
    while (((PINC | 0b1110000) & ((PIND | 0b00011111)>>1)) == oc); 
    __asm__("mov r24,r25"); 
    if (b) 
    { 
     __asm__ volatile ("st Y+, r19"); 
     b = 0; 
    } 
    else 
     *(timeptr++) = TCNT0; 

    TCNT0 = 0; 
    *(++ledptr) = oc; 
    *(++anodptr) = PINB; 
    i++; 
} 
goto loop; 

回答

0

你可以尽量避免类似的分支:

*timeptr++ = (b != 0)*0xFF + (b == 0)*TNCT0; 

对于b = 0;表达很难找到一个解决方案,因为我们不能看到它是如何给定的代码之外更新。