スライド 1

B10 CPUを作る
3日目 SPIMの改造
TA 高田正法
[email protected]
1
はじめに

このスライドは以下の場所にあります
 http://www.mtl.t.u-tokyo.ac.jp/~mtakada/jikken_b10/
2
注意!!

PCSpimディレクトリの下にあるファイルは、
Windows用インターフェースに関するものなので、
今回書き換える必要はありません
 srcディレクトリの下を見ましょう

以下のファイルは自動生成されるものなので、書き
換えない方が無難です
 y.tab.c
 y.tab.h
 lex.yy.c
3
SPIMのソースを書き
換える前に
命令の仕様を決めましょう
4
命令の仕様を決める前に

MIPSの命令セット



全ての命令の長さは32bitです
命令の形式も数種類しかありません
以下ではこの単語を使います

ニーモニック形式


014b4820 といった、命令がメモリに格納されるときの形式
アセンブル


$t1, $t2, $t3 といった表記
バイナリ形式


add
ニーモニック形式→バイナリ形式の変換
逆アセンブル

バイナリ形式→ニーモニック形式の変換
5
固定部分
命令のバイナリ形式

I型(Immediate型 lw, bne, addiなど)
31
26 25
21 20
命令コード Reg(src)

16 15
0
即値(アドレス含)
Reg(tgt)
J型(Jump型 jaなど)
31
26 25
0
命令コード

パラメータ部分
ジャンプ先アドレス
R型(Register型 add, mulなど)
31
26 25
21 20
命令コード Reg(src)
16 15
Reg(tgt)
11 10
Reg(dst)
6 5
0
命令コード
新命令もどれかの形式に合わせるとラク
6
ニーモニック-バイナリ対応の例
コンピュータの設計下巻Appendix参照

I型
 bne
SPIMマニュアル10ページ参照
$t1, $t2, LABEL ($t1!=$t2→LABELへ)
000101

01001
01010
分岐先相対アドレス(16bit)
固定部分
R型
 add
000000
$t1, $t2, $t3 ($t1 = $t2 + $t3)
01010
01011
01001
00000
パラメータ部分
100000
2進->16進変換
014b4820
7
新命令の仕様 (例)

名前


命令形式


sub
$t2, $t0, $t1
機能


レジスタ3つ
表記例


R型
オペランド


sub
2つ目のレジスタの値から3つ目のレジスタの値を減算し、結果を1つ
目のレジスタへ格納する
書式
31
26 25
000000
21 20
reg番号2
16 15
reg番号3
11 10
reg番号1
6 5
00000
0
100010
8
新命令の仕様決定の流れ

命令の名前を決める
 他の命令と被らないように
 SPIMマニュアルまたはコンピュータの構成と設計下巻
Appendix参照

命令の形式を決める
 I型、R型、J型のどれか?

命令のバイナリ表記を決める
 7ページの”固定部分”について、他の命令と被らないよう
に適当な値を決める

コンピュータの構成と設計下巻 Appendix参照
9
SPIMのソースを書き
換える前に
SPIMに関する予備知識
10
書いたプログラムが動くまで

C言語の場合
実行ファイル(バイナリ)
Cのソースファイル
コンパイル

実行
アセンブリ言語の場合
アセンブラソースファイル
実行ファイル(バイナリ)
アセンブル
実行
ニーモニック形式の命
令が並んだもの
11
プログラムを動作させるための道具

ソースファイル
 C言語/アセンブリ言語その他

ソースファイルをバイナリに変換するための
プログラム
 コンパイラ/アセンブラ

実行する環境
 PC実機
SPIMは両方の機能を持っている
(アセンブラ+シミュレータ)
 シミュレータ
12
新命令の追加

命令の追加をするには以下の2つの作業が
必要です
 アセンブラ部分への、新命令翻訳機能の追加

正しくバイナリへ変換できるようにする正確には、バイ
ナリ→ニーモニック変換部分の対応も必要(画面に表
示するため)
 シミュレータ部分への、新命令実行機能の追加

新命令が正しく解釈され実行されるように
13
ソースファイルの中身
srcディレクトリの中にある、”README”に簡
単な説明があります
 以下では、わかりにくいと思われる次のファイ
ルについて、簡単に解説してみます

 op.h
 parser.y
14
SPIMのソースを書き換えま
しょう
まずは共通部分
15
op.h

op.hは、SPIMがサポートする命令のテーブルになっ
ています
 ここに新命令を追加しましょう
 他のファイル内でincludeして使われています
OP ("sub",
Y_SUB_OP,
R3_TYPE_INST,
命令のタイプ。他の命令の
命令の名前
定義を見て、似たようなもの
にしましょう。inst.cの、
SPIMソース内での
print_inst_internal関数、
識別名。Y_命令名_OP
inst_encode関数、
にするのが無難
inst_decode関数で
使われてます。
0x00000022)
命令のバイナリ表記。
ただし、レジスタ番号や即値、
アドレスなどの部分は全て
0で置き換えたもの。
16
SPIMのソースを書き換えま
しょう
アセンブラ部分
17
SPIMのアセンブラ部分
spim_utils.c 及び、inst.cが中心
 ファイルを開くと、spim_utils.c の
read_assembly_file関数が呼ばれます

 while
(!yyparse ()) ;
が、アセンブラ部分のメインループです
 内部では、各命令に対し、命令の形式に応じて
r_type_inst関数や、i_type_inst関数など(inst.c
内)が読み込んだソースファイルに書いてある順
に呼ばれます
18
parser.yの書き換え(1) – parser.yとは
parser.yに書かれている内容に従って、ソー
スファイルを読み込みます
 謎のスクリプト言語だと思ってください

 命令解釈は、450行目付近から始まる
ASM_CODE:部分で行っています
19
parser.yの書き換え(2) – 簡単な説明

例
| BINARY_OP_I
DEST_REG
{
r_type_inst ($1.i, $2.i, $3.i, $4.i);
}

SRC1
SRC2
意味: BINARY_OP_I DEST_REG SRC1 SRC2
というパターンを見つけたら、r_type_inst関数を呼
び出しなさい
 BINARY_OP_Iは、1360行目付近からはじまる
BINARY_OP_I の右側に書いてある命令のいずれか
20
parser.yの書き換え(3) – 作業内容(1)
命令を追加するには
 前半の %token~部分に、新命令の記述を
追加してください

 op.hと同じ識別名に
(前略)
%token Y_DIV_S_OP
%token Y_HOGE_OP
%token Y_HOGE2_OP
%token Y_JALR_OP

次のページへ続く
(後略)
21
parser.yの書き換え(4) – 作業内容(2)

ASM_CODE: で
始まる部分(450
行目付近)に、右
のような記述を追
加
 R型は上のように
 I型の場合は、下
のように
/* R型の例 */
| Y_HOGE_OP DEST_REG SRC1 SRC2
{
r_type_inst ($1.i, $2.i, $3.i, $4.i);
}
/* I型の例 */
| Y_HOGE2_OP SRC1 SRC2 LABEL
{
i_type_inst_free ($1.i, $3.i, $2.i,
(imm_expr *)$4.p);
}
22
parser.yの書き換え(5) – 書き換え例

例
ASM_CODE: Y_HOGE_OP DEST_REG SRC1 SRC2
{
r_type_inst ($1.i, $2.i, $3.i, $4.i);
}
| Y_HOGE2_OP SRC1 SRC2 LABEL
{
i_type_inst_free ($1.i, $3.i, $2.i, (imm_expr *)$4.p);
}
| LOAD_OP DEST_REG
ADDRESS
{
i_type_inst ($1.i == Y_LD_POP ? Y_LW_OP : $1.i,
(以下略)
23
他にも…
inst.c内に、アセンブラに相当する部分が存
在します
 数点書き換えなければならない点があります

24
SPIMのソースを書き換えま
しょう
シミュレータ部分
25
シミュレータ部分の書き換え
実はほとんど書き換える必要はありません
 run.cや、mem.h、reg.hなどが中心になって
います
 いかにも各命令について何かやってそうなと
ころを探し出して、書き換えてやりましょう

26