R3000特訓講座
第3号
更新日付 1998-02-20
修正日付 1998-06-06
R3000アセンブラの特徴であるマクロ命令を紹介します。
プログラミングでは、遅延スロットの利用に加えて、
マクロではなくネイティブな命令を使うことも考えてみましょう。
・プログラミング
これからはプログラミングから入ります。
とりあえず復習をどうぞ。
問題1.pochi番地から始まる64バイトのデータを、
tama番地からに転送する。
--------------------------------------------------------------------
la a0,pochi #転送元アドレス
la a1,tama #転送先アドレス
la a2,pochi+64 #転送終了時の転送元アドレス
_loop:
lb t0,$0000(a0) #a0+$0000番地から1バイトロード
nop #ロード完了までの時間待ち
sb t0,$0000(a1) #a1+$0000番地へ1バイトストア
addi a0,a0,1 #転送元アドレスを+1
addi a1,a1,1 #転送先アドレスを+1
bne a0,a2,_loop #転送終了アドレスでなければ_loop
nop #遅延スロットを殺す
--------------------------------------------------------------------
ざっと、こんな感じでしょうか。
lbという命令は「ロード・バイト」という意味です。
アドレスの指定方法は前回の講座と同じです。
1バイト読んで、1バイト書いてを繰り返せばいいのですが、
R3000は構造上、読み出してすぐには書けません。
そこでlb直後にnopを追加して、
ロード完了まで時間待ちをしています。
しかし、このままでは賢いコンパイラに負けてしまいます。
このプログラムを高速化してみましょう。
と、その前に・・・。
・マクロ
先ほどのプログラムで登場した
「la a0,pochi」という命令について考えます。
この命令はpochiというアドレスが4バイトであれば、
5バイト以上の命令長になるはずです。
R3000はすべての命令を4バイトであらわすのですが、
これでは「la a0,pochi」が存在しないことになります。
これはどうしたことでしょう。
実はR3000にはlaという命令は存在しないのです。
アセンブラはR3000本来の命令と+マクロ命令で構成されます。
たとえば「la a0,$12345678」という命令は、
アセンブル時に二つの命令に分けられます。
おそらく上位ハーフワードへのロード命令「lui a0,$1234」と、
「addiu a0,a0,$5678」や「ori a0,a0,$5678」に変換されます。
そう、下位ハーフワードへのロード命令も存在しないのです。
このようなマクロ命令は、遅延スロットに入れてはいけません。
勢い余って実行されるのは、最初の1命令だけです。
・プログラミング
laはマクロ命令ですから、最悪の場合6命令に展開されています。
というわけで、「la a2,pochi+64」も、
別の命令に置換した方が高速化できそうです。
では、高速化に挑戦してください。
--------------------------------------------------------------------
la a0,pochi #転送元アドレス
la a1,tama #転送先アドレス
addiu a2,a0,64 #転送終了時の転送元アドレス
_loop:
lb t0,$0000(a0) #a0+$0000番地から1バイトロード
addi a0,a0,1 #転送元アドレスを+1
sb t0,$0000(a1) #a1+$0000番地へ1バイトストア
bne a0,a2,_loop #転送終了アドレスでなければ_loop
addi a1,a1,1 #転送先アドレスを+1
--------------------------------------------------------------------
こんな感じでどうでしょうか。
お仕事ください(笑)...
koh@inetmie.or.jp