如何对增量指针代码 AVR 进行优化



我有 atmega8 的 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 在 TWO 分支中强制优化,然后生成的 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;

您可以尝试使用如下内容来避免分支:

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

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

最新更新