2013-10-06 35 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;表達很難找到一個解決方案,因爲我們不能看到它是如何給定的代碼之外更新。