RL78コンパイラコーステキスト、2013年5月22日Rev.1.06版の要旨、最後の3回目は、コンパイラ設定です。
コンパイラは、ユーザ記述ソースからロードモジュールを作成します。この時、使用するマイコンに応じて、いろいろなコンパイル・オプションの設定が必要になります。このオプション設定がまずいと、「良いモジュール」ができないからです。もう1つ記述時に重要なことは、ソースプログラムの書き方です。
コンパイラ設定の要旨
本対象マイコンでは、コンパイル・オプションのメモリ・モデルを、「スモール・モデルに設定」することが必要です。デフォルトが、ミディアム。モデルになっているからです。
CubeSuite+は、良いモジュールを作るために9個のコンパイル・オプションを組合せて、標準、サイズ優先、速度優先、詳細設定、いいえの5種類の作成方法(最適化)を予め用意しています。オプションと最適化の関係は、以下になります(テキストの抜粋表に追記)。
コンパイル・オプション設定 |
最適化の種類 |
|||||
標準 | サイズ優先 | 速度優先 | 詳細設定 | いいえ | ||
1 | 演算式の実行順序入替え |
○ |
○ |
○ |
△ |
× |
2 | 自動変数をレジスタまたはsaddr領域に割当 |
○ |
○ |
○ |
△ |
× |
3 | レジスタ変数をレジスタに加えsaddr領域に割当 |
× |
× |
× |
△ |
× |
4 | char演算の符号拡張なし |
○ |
○ |
○ |
△ |
× |
5 | char型をunsigned charとみなす |
× |
× |
× |
△ |
× |
6 | 分岐命令を最適化 |
○ |
○ |
○ |
△ |
× |
7 | 定型コードをライブラリに置換え |
○ |
◎ |
× |
△ |
× |
8 | 相対分岐でswitch分岐テーブル生成 |
× |
× |
× |
△ |
× |
9 | デバックに適した最適化 |
× |
× |
× |
△ |
× |
◎:強力に実施、○:実施、×:実施なし、△:カスタム(自由設定)
最も標準的なオプション設定の組合せが「標準」で、デフォルトになっています。サイズと速度ともに効果がある1、2、4、6オプションなどは、○:実施に設定です。「標準」、「サイズ優先」と「速度優先」の差は、オプション7の定型コードをライブラリに置換えるか否かのみです。つまり、「標準」でかなり最適なモジュール作成ができていて、さらにモジュールサイズを圧縮するなら「サイズ優先」、速度を上げるなら「速度優先」に変更すれば良いことが判ります。
「詳細設定」は、全オプションを自由に設定するモードで、この時のみ9個のコンパイル・オプションが画面表示されます。他の最適化の時は、個々のコンパイル・オプションは表示されません。「詳細設定」ではオプション設定が自由ですので、各オプションの差分評価などの用途と思われますが、サイズ大で速度も遅いモジュールが生成されたりもしますので、使うことはないでしょう。また、「いいえ」は、全オプションを設定しないモードで、これも使わないでしょう。
結局、最適化は、デフォルトの「標準」のままで良く、どうしてもサイズや速度を改善したい時は、「サイズ優先」か「速度優先」を選択します。但し、差分は、定型コードのライブラリ化のみで、記述ソースにもよりますが、効果は期待できないかもしれません。
オプション3のレジスタ変数をレジスタに加えsaddr領域に割当は、何の効果もないので設定不要、オプション8の相対分岐でswitch分岐テーブル生成は、対象マイコン外なので設定不要、オプション9のデバッグ最適化は、内容不明でした。
ソースプログラムの書き方要旨
オプション5のchar型をunsigned charとみなすは、ソースプログラムの書き方に関連します。RL78マイコンで使う整数型変数は、「符号なしの8ビットまたは16ビットが最も効率的」にコンパイルされます。型宣言にcharやint、shortのみを記述すると、デフォルトでは「符号つきのsigned変数」になります。このオプション設定で、char型変数は符号なしにみなされますが、int、shortはそのままです。対策は、「整数型宣言は、必ずsignedかunsigned を付け、符号の有無を明記する」ことです。
RL78マイコンの汎用レジスタは、16ビットです。従って、32ビットのlong変数は避け、「できる限り8ビットまたは16ビット変数を用いると、効率的」な結果が得られます。
#pragma以降のキーワード(例えば、EI、DI、NOP、HALTなど)は、大文字でも小文字でも記述可能ですが、関数内で使う時は、大文字記述時のみ有効なので、「大文字で統一」した方が混乱は避けられます。
呼出される関数にcalltを付けると、通常よりも短いコードで関数呼出しができます。つまり、サイズ優先の書き方です。但し、速度は遅くなります。calltが使える関数は、最大32個です。対象マイコンは、64KBの大容量ROMですので、この「callt記述を使う可能性は低い」と思います。
saddr領域とコンパイラ固定使用領域
第1回のRAMメモリマップで示したように、saddr領域とは、マイコンRAM内:FFE20~FFEB3の148バイトのことです。コンパイル・オプション2の自動変数をレジスタまたはsaddr領域に割当が、○:実施されていることから、最適化に有効な領域であることが判ります。
saddr:ショート・ダイレクト・アドレッシング領域は、8ビットコードでアクセスできるので、サイズ、速度ともに向上します。レジスタとほぼ同じと考えて良いでしょう。「標準」最適化で、コンパイラにより、関数内の自動変数はこのsaddr領域へ割付けられます。また、コンパイル・オプションのデータ制御項目で、static/外部変数をsaddr領域へ自動的に割付けることもできます。この自動割付けが嫌なら、ソース内でユーザが明示的にsregを付けた外部変数、関数内のstatic変数の割付けも可能です。非常に有用な領域で、RL78マイコンを使いこなす技を生むポイントですが、148バイトしかありません。148バイトを超えて使用すると、コンパイルエラーが発生します。
この少ないsaddr領域の対策として、コンパイラ固定使用領域:FFEB4~FFEDEの44バイトのうち、FFEB4~FFED3の32バイトをsaddr領域へ変更することができます。これで、合計148+32=180バイトがsaddrユーザ領域になります。但し、制限として、標準ライブラリのsetjmp、longjmp、sprintf、sscanf、printf、scanf、vprintf、vsprintf、ldiv関数を使わないことと、コンパイル・オプション3のレジスタ変数をレジスタに加えsaddr領域に割当てを、×:実施しないことが条件です。もちろん、「標準」最適化では、このオプションは、×:実施なしですので、printfなどの標準ライブラリ関数を使わなければ、条件を満たします。
CubeSuite+は強力なデバッグ・ツールを持ちますので、printfを使う機会は少ないと思います。ビルド・ツールの変数/配置オプションタグのROM/RAM使用量を、はい:表示へ変更すると、saddr領域の使用量も表示されますので、148バイトよりも大きくなった時は、コンパイラ固定使用領域をsaddr領域へ変更すれば、32バイトの追加ができます。
以上
3回にわたって、RL78コンパイラコーステキスト、2013年5月22日Rev.1.06版の要旨を解説しました。このテキストは、非常に有用な事項を記述していますので、ぜひ、ご自身で精読されることをお勧めします。セミナに参加すれば、記述内容だけでなく、その背景や行間/ページ間の意味、重要度などいろいろなことも把握できるでしょう。残念ながらテキストのみでは、書かれてないことは推測するしかありません。本要旨では、テキストの要旨だけでなく、いろいろ推測を加えた部分もあります。また、解説もコンパイラとリンカに絞り、対象マイコンも絞って説明しました。別側面からテキストを観た結果であり、ご参考になれば幸いです。