Free EditionではRegister変数が使えない?
(2015.11.17)
=====================
記事の途中、SkypePhoneへのリンクが生成されていますが無視して下さい
=====================
PIC32用のCコンパイラXC32のマニュアルの9.6項にRegister変数に関する記述があります。
9.6 VARIABLES IN REGISTERS
”最適化レベル1以上で有効”と記されていて、5.9.7項によるとFree Edition(無償版)でも最適化レベル1は設定可能です。
5.9.7 Options for Controlling Optimization
TABLE 5-11: GENERAL OPTIMIZATION OPTIONS
オシロジは、ソフトウェアによるトリガ判定処理がサンプリング・レートを制限する要因となっていて、Register変数を上手く利用すれば処理時間を短縮出来るかもしれないのです。
で早速、こんなプログラムを試して見たのですが・・・
672: register unsigned int *ifs0 __asm__("$4"); // a0 reg.
673: ifs0 = (unsigned int *)(&IFS0);
674:
675: if( *ifs0&ifs0_adif_bit )
9D002900 8F828060 LW V0, -32672(GP)
9D002904 3C03BF88 LUI V1, -16504
9D002908 8C631030 LW V1, 4144(V1)
9D00290C 00431824 AND V1, V0, V1
9D002910 10600002 BEQ V1, ZERO, 0x9D00291C
9D002914 3C03BF88 LUI V1, -16504
676: {
677: *(ifs0+1) = ifs0_adif_bit;
9D002918 AC621034 SW V0, 4148(V1) <== ここと
678: }
こちらはIFS0レジスタを直接読む従来の方法です
641: if( IFS0&ifs0_adif_bit )
9D003120 3C02BF88 LUI V0, -16504
9D003124 8C431030 LW V1, 4144(V0)
9D003128 8F828060 LW V0, -32672(GP)
9D00312C 00431824 AND V1, V0, V1
9D003130 5060001E BEQL V1, ZERO, 0x9D0031AC
9D003134 3C02BF88 LUI V0, -16504
642: {
643: IFS0CLR = ifs0_adif_bit;
9D003138 3C03BF88 LUI V1, -16504 <==ここが
9D00313C AC621034 SW V0, 4148(V1) <==ちょっと違う
8ステップから7ステップに変わりましたが、Register変数の指定は無視されているように思われます。
使い方が悪いのでしょうか?
それともRegister変数を使った最適化は(Free Editionには)許されないのでしょうか?
orz
マニュアルの11.3項には、”関数パラメータはA0~A3レジスタを介して引き渡される”と記されています。
11.3 REGISTER CONVENTIONS
そこで、さらにもう一つ試して見ました。
662: void dummy_log(uint32_t *ifs0)
663: {
664: if( *(ifs0)&ifs0_adif_bit )
9D004CA4 8F828060 LW V0, -32672(GP)
9D004CA8 8C830000 LW V1, 0(A0)
<== A0(IFS0へのポインタ)を介してアクセスしている
9D004CAC 00431824 AND V1, V0, V1
9D004CB0 54600001 BNEL V1, ZERO, 0x9D004CB8
9D004CB4 AC820004 SW V0, 4(A0)
<== A0+4(IFSCLRへのポインタ)を介してアクセスしている
9D004CB8 03E00008 JR RA
9D004CBC 00000000 NOP
665: {
666: *(ifs0+1) = ifs0_adif_bit;
667: }
668: }
684: dummy_log( (uint32_t *)(&IFS0) );
9D002934 3C04BF88 LUI A0, -16504
9D002938 0F401329 JAL dummy_log
9D00293C 24841030 ADDIU A0, A0, 4144 <== IFS0へのポインタがセットされる
成功です。A0レジスタを介して引き渡されたIFS0へのポインタを使ってIFS0にアクセスしています。
僅かな違い(7ステップから5ステップ)ですが、一歩前進しました!