現在の位置
diff プラグインを使用中
- 追加された行はこの色です。
- 削除された行はこの色です。
- 仕様/拡張/ユーザー定義命令の追加 へ行く。
- 仕様/拡張/ユーザー定義命令の追加 の差分を削除
# この機能は現在公開されているバージョンには,まだ実装されていません *はじめに [#ve6508df] -鬼斬では,ユーザー定義の新しい命令をエミュレータに追加する機構を備えてる -具体的な手順は以下の通り ++デコードのフック・ポイントに対し,ユーザー定義のデコード・メソッドを登録 ++ユーザー定義のデコード・メソッドが呼ばれた場合,コードのバイト列から必要に応じて命令を生成し,返す *手順 [#xcf88ec6] +デコードのフック・ポイントに対し,ユーザー定義のデコード・メソッドを登録 --ExtraOpDecoder::s_extraOpDecodeHook に以下のプロトタイプのメソッドを登録 void Decode( HookParameter<ExtraOpDecoder, ExtraOpDecodeArgs>* param ); +デコードに必要な情報の取得 --param->GetParameter() により,ExtraOpDecodeArgs 構造体へのポインタを取得. +Opコードのチェック --ExtraOpDecodeArgs ::codeWord を見て判断 --ユーザー定義命令として扱う必要がなければ,そのままリターン +命令の生成 --ExtraOpDecodeArgs ::decoded をtrueに --ExtraOpDecodeArgs ::decodedOps に,マイクロ命令列へのポインタと命令数を格納 *備考 [#wbf32766] -簡単なテストの際は,gcc のインライン・アセンブラに直接数値を埋め込むと良い __asm__ ( ".int 1<<26 \n\t ".int 1<<26 \n\t" ); *サンプル [#yc98b9cc] -以下は ソースを1つ取り,インクリメントして返す命令の例 -命令のOpコードは1<<26. class TestOp : public ExtraOpInfoIF { OpClass m_opClass; public: TestOp() : m_opClass(OpClassCode::syscall) { } void Execute( OpStateIF* opState ) { opState->SetDst( 0, opState->GetSrc(0) + 1 ); } // 命令の種類 const OpClass& GetOpClass() const { return m_opClass; } // オペランド int GetSrcOperand(const int index) const { return 1; // レジスタ番号1 } int GetDstOperand(const int index) const { return 1; // レジスタ番号1 } // オペランドの数 int GetSrcNum() const { return 1; } int GetDstNum() const { return 1; } // ニーモニック (dump等のため) const char* GetMnemonic() const { return "TestOp"; } }; class TestDecoder { struct MicroOps { ExtraOpInfoIF* ops[SimISAInfo::MAX_OP_INFO_COUNT_PER_PC]; int count; }; vector<MicroOps> m_mops; public: TestDecoder() { ExtraOpDecoder::s_extraOpDecodeHook.Register( this, &TestDecoder::Decode, 0 ); }; ~TestDecoder() { // Release ops for( size_t i = 0; i < m_mops.size(); i++ ){ for( int j = 0; j < m_mops[i].count; j++ ){ delete m_mops[i].ops[j]; } } } void Decode( HookParameter<ExtraOpDecoder, ExtraOpDecodeArgs>* param ) { ExtraOpDecodeArgs* args = param->GetParameter(); args->decoded = false; int opCode = (args->codeWord >> 26) & 63; if( opCode == 1 ){ args->decoded = true; MicroOps mops; mops.count = 1; mops.ops[0] = new TestOp; m_mops.push_back( mops ); args->decodedOps->first = &mops.ops[0]; args->decodedOps->second = mops.count; } }; };