denshikobo’s blog

PICプログラミングやPCの操作で感じた日々の由無し事を綴ります

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ステップ)ですが、一歩前進しました!