ハードウェアを意識したプログラミングの基礎(前編)
● 柔らかいハードウェア
CPUに新しい命令セットが追加されても上位互換性があれば,デバイス・ドライバを書く上ではあまり問題になりません.しかしMicroBlazeのようなソフト・マクロのCPUコアの場合,ユーザが目的に合わせて必要な機能を追加したり外したりすることが可能です.このソフト・マクロのCPUコアの特徴は,FPGAというハードウェア・ロジックの変更が可能なLSIによって実現されています.デザインによってサポートする機能が異なるため,適宜コンパイラ・オプションを変更する必要があります.
ここでは,Xilinx社のMicroBlazeを使って説明します.最新のMicroBlazeのバージョンはv7です.v7では以下の機能の設定変更が可能です注11.
注11;詳しくはMicroBlaze Processor Reference Guideを参照すること.
MMU,FPU,例外,キャッシュ,バレル・シフタ,割り算器,パターン比較命令
多くの機能が選択可能ですが,バレル・シフタを例にとってみましょう.仮に,与えられた値を23ビット右にシフトする関数foo()があったとします(リスト9).
int foo(int x)
{
return x >> 23;
}
リスト9 右に23ビット・シフトする関数foo()
バレル・シフタが無効のとき,MicroBlazeのコンパイラはリスト10のようなコードを生成します.この時の動作は図12のようになります.MicroBlazeは第1引き数をレジスタ5番(r5)で受け取ります.3行目で受け取った引き数を,_shift_temp_locで指定された場所に書き込みます.4行目で,書いた値のMSB側16ビットをレジスタにロードします.MicroBlazeはビッグ・エンディアンなので,16ビット・ロード時はMSB側がロードされます.ストアとロードを行うことで16ビット右にシフトした場合と同じ状態になります.そして右への1ビット・シフトを7回繰り返します.これで16+7=23ビット,シフトできました.
1: foo:
2: .frame r1,0,r15
3: .mask 0x00000000,0
4: swi r5,r0,_shift_temp_loc
5: lhui r18,r0,_shift_temp_loc
6: sext16 r3,r18
7: sra r3,r3
8: sra r3,r3
9: sra r3,r3
10: sra r3,r3
11: sra r3,r3
12: sra r3,r3
13: sra r3,r3
14: rtsd r15, 8
15: nop
リスト10 バレル・シフタが無効の時のコード
図12 バレル・シフタが無効のときの動作
これをバレル・シフタを使うオプション「-mxl-barrel-shift」を指定してコンパイルすると,リスト11のようにたったの2命令に変わってしまいました! rtsdは関数を抜けるときの命令です.rtsdは次の命令を実行したあとに,呼び出し元に戻るようになっています注12.この例では,次のバレル・シフト命令を実行した後に呼び出し元に戻っていきます.
注12;delay slotという機能で,RISCアーキテクチャにおいてよく見られる.
1: foo:
2: .frame r1,0,r15
3: .mask 0x00000000,0
4: rtsd r15, 8
5: bsrai r3,r5,23
リスト11 バレル・シフタが有効の時のコード
ハードウェアを知るのはデバイス・ドライバを書く上で必須です.アプリケーションを書いているときには気にしなかったことも,知っておく必要があります.これらの知識はアプリケーションを書くときにも必ず役に立ちますし,ハードウェアのことを知るとコードを書く楽しみも増えます.
参考・引用*文献 (1)中森 章;TECH I vol.20 マイクロプロセッサ・アーキテクチャ入門,CQ出版,2004年4月.
しょうじ・やすし
(株)アットマークテクノ