ComProcコンパイラとXC8の出力比較
XC8 は -O2 オプションを有効化した
実験コード
code:for-comproc.c
void led_out(int val) {
char *p = 0x80;
*p = val;
delay_ms(500);
*p = 0;
delay_ms(500);
}
code:for-xc8.c
void led_out(int val) {
LATB = val;
delay_ms(500);
LATB = 0;
delay_ms(500);
}
ComProcはメモリマップトI/O、PICはLATB等のポートを用いるので、そこを変更
結果
ComProcコンパイラの出力は17命令
1命令=16ビットなので、272ビット
code:ComProcコンパイラの出力
led_out:
cpush fp
st cstack+0
add fp,4
push 128
st cstack+2
ld cstack+0
ld cstack+2
std.1
push 500
call delay_ms
push 0
ld cstack+2
std.1
push 500
call delay_ms
cpop fp
ret
XC8コンパイラの出力は19命令
1命令=14ビットなので、266ビット
code:XC8コンパイラの出力
13: void led_out(int val) {
14: LATB = val;
07CF 0875 MOVF val, W
07D0 0140 MOVLB 0x0
07D1 0097 MOVWF LATB
15: delay_ms(500);
07D2 30F4 MOVLW 0xF4
07D3 00F0 MOVWF __pcstackCOMMON
07D4 3001 MOVLW 0x1
07D5 00F1 MOVWF 0x71
07D6 3187 MOVLP 0x7
07D7 27E2 CALL 0x7E2
07D8 3187 MOVLP 0x7
16: LATB = 0;
07D9 0140 MOVLB 0x0
07DA 0197 CLRF LATB
17: delay_ms(500);
07DB 30F4 MOVLW 0xF4
07DC 00F0 MOVWF __pcstackCOMMON
07DD 3001 MOVLW 0x1
07DE 00F1 MOVWF 0x71
07DF 3187 MOVLP 0x7
07E0 27E2 CALL 0x7E2
18: }
07E1 0008 RETURN
考察
命令数換算ではComProcが勝つ
ビット数に換算すると少し負けている
最適化次第でビット数でも勝てる
変数pの値は変更されないので、定数伝播解析ができて無駄な変数読み書きが無くなれば、2命令少なくできる
メモリマップトI/Oをすべて16ビットアクセスにすれば、もっと減らせる
バイトアクセスstd.1などは即値を取れないので、命令が増える原因になっている。
あるいは、バイトアクセス命令も即値を取れるように拡張するか。