如何优化增量指针代码avr

时间:2013-10-06 11:12:53

标签: optimization 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 来强制优化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;

1 个答案:

答案 0 :(得分:0)

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

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

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