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