我有像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;
答案 0 :(得分:0)
您可以尝试使用以下内容来避免分支:
*timeptr++ = (b != 0)*0xFF + (b == 0)*TNCT0;
对于b = 0;
表达式,很难找到解决方案,因为我们无法看到它在给定代码之外的更新方式。