-
Notifications
You must be signed in to change notification settings - Fork 31
エミュレーション
Ryota Shioya edited this page Mar 24, 2022
·
2 revisions
- エミュレータ
- 実際の演算やメモリ・アクセス,システムコールなどの動作を実現する
- ここでは投機的/Out-of-orderにエミュレーションを実行するための仕組みについて説明
- 鬼斬では,シミュレータ側ドリブンでエミュレーションを実行する
- シミュレータ側において,エミュレータより命令のOpコードやオペランド番号などの情報を取得し(デコード),
- それらの情報と,演算に使用する値等のコンテキストを合わせてエミュレータに与える事によって,演算結果を得る
- 主な役割
- PCに対応した命令情報の取得
- 演算の実行
- システム・コールの再現
- メモリ・イメージの管理保持
- 命令を,動的な情報と静的な情報にわけて処理する
- 静的な情報(OpInfo)
- Opコード,オペランドの個数など
- 動的な情報(OpStateIF)
- レジスタ値や分岐方向などのコンテキストを格納する
- エミュレータでは,静的な情報を用いてこれの更新を行う
- PCもこっちに入る
- 静的な情報(OpInfo)
鬼斬では,シミュレータ側ドリブンでエミュレーションを実行する
- 命令の静的な情報の取得(デコード)
- 命令アドレスに対応するマイクロ命令群を取得
- Fetcher::Simulate() -> m_emulator->GetOp(pc)
- 命令アドレスに対応するマイクロ命令群を取得
- Out-of-Order実行
- 静的な情報(opInfo)を元にして動的な情報(opState)を更新
- opStateには,ソース・オペランドの値も入っている
- OpExecuteEvent -> Op::Execute() ->Emulator::Execute( opState, opInfo )
- 静的な情報(opInfo)を元にして動的な情報(opState)を更新
- リタイア
- ストアの場合,ストア・バッファからエミュレータ側メモリ・イメージへの反映を行う
- 通常の演算命令(レジスタのみにアクセス)
- レジスタについてはシミュレータ側でリネーミングや回復が行われるため,Out-of-Order に実行しても構わない
- メモリ・アクセスについては,シミュレータ側に実装されたストア・バッファによって投機が実現される
- エミュレータ側が持つメモリ・イメージには確定状態のみが反映される
- システム・コールは不特定かつ複数のメモリ・ロケーションを操作しうるため,シリアライズして実行
- 実装としては,エミュレーションの実現コード内からシミュレーション側に制御を戻すことにより実現
- エミュレーション内からOpStateIF::Write/Read を呼ぶ
- ストアの場合,エミュレーション側のメモリ・イメージに直接反映を行うのではなく,一旦ストア・バッファにいれる
- ロードの場合,投機的に行われたストアの内容を考慮した値をシミュレータ側から戻す
- エミュレーション内からOpStateIF::Write/Read を呼ぶ
- Op::Execute() ->
- (エミュレータ内のLoad実現コード) ->
- OpStateIF::Read() ->
- MemOrderManager::Read() -> # 場合によっては,ここでストアバッファから値を取得
- m_emulator->GetMemImage()->Read()
ストアの動作は命令の実行とリタイアに分けられる
- 実行時
- Op::Execute() ->
- (エミュレータ内のStore実現コード) ->
- OpStateIF::Write() ->
- MemOrderManager::Write() #シミュレータ側のストアバッファに格納
- リタイア時
- MemOrderManager::Commit() ->
- m_emulator->GetMemImage()->Write() # ストアバッファから書き込み
- システム・コール呼び出しの1命令によってシステム・コールによる動作を全て行ったかのように扱う
- 依存元/先のメモリ・アドレスについてはわからないため,投機実行は行わずにシリアライズして実行する
- シリアライズ
- システム・コール命令を実行する場合,常にコア内にシステム・コール命令が1つしかない状態に保つ
- 上流の命令が全てリタイアするまで,システムコール命令をフェッチしない
- コア内にシステム・コール命令があった場合,命令をフェッチしない
- システム・コール命令を実行する場合,常にコア内にシステム・コール命令が1つしかない状態に保つ