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
© Copyright 2024 ExpyDoc