CPUのレジスタリネーミングでは、フリーリストと呼ばれる、空いているレジスタ番号を管理するためのFIFOキューが存在する。
フリーリストには、現在使用されていない物理レジスタ番号が格納されており、命令がデコードされ、レジスタ書き込みが必要な命令であるならば、フリーリストからIDを一つ取り出し、書き込み先レジスタとして当該レジスタIDを指定する。 リネームマップを用いて、書き込み物理レジスタ番号(フリーリストから取り出したID)と、アーキテクチャレジスタ番号のマッピングを行う。 アーキテクチャレジスタ番号の最マッピングが行なわれるため、元々マッピングされていた古い物理レジスタ番号は不要になる。 このため、古い物理レジスタ番号はフリーリストに戻され再利用される。
つまり、フリーリストには以下のような機能がある。
- 初期状態では、使用されていない物理レジスタ番号が格納されている。
- 命令がデコードされ、当該命令がレジスタ書き込みを発生する場合、フリーリストから物理レジスタ番号を1つ取り出す。
- 例えばアーキテクチャレジスタ番号R1に書き込みを行う命令で、フリーリストからID10を取り出したとする。もともとアーキテクチャレジスタ番号R1のレジスタには、初期状態として物理レジスタ番号ID1が割り当てられているとする。
- この場合、リネームマップは「R1 --> ID1」から、「R1 --> ID10」へと書き換えを行う。
- この時点でID1は使用されない不要な物理レジスタIDとなる。
- 不要なレジスタID10をフリーリストの最後尾に書き戻す。
フリーリストを実装するにあたり、どのように実装するかを考えたのだが、必要なのは、
- 物理レジスタを書き込むことができるだけのレジスタファイル (通常、アーキテクチャレジスタの数だけ物理レジスタIDは利用されているため、「物理レジスタの総数 - アーキテクチャレジスタの総数」だけ必要だと考えられる)
- 使用される予定の物理レジスタIDの先頭を指すポインタ(HEADポインタ)
- 書き戻される予定の物理レジスタIDの先頭を指すポインタ (TAILポインタ)
まず、命令がデコードされた時点で、HEADポインタが書き込みレジスタ数分だけ進められる。その際(あるいは当該命令がコミットされた後)、既にアーキテクチャレジスタにマップされていた旧物理レジスタIDが解放されるため、解放される分だけフリーリストに書き戻し、その分だけTAILポインタを進める。
途中で命令フラッシュが発生した場合
途中で命令フラッシュが発生した場合、投機的に進めていたHEADポインタを元の位置まで戻さなければならない。 そのため、「コミットポインタ」を用意して、どの位置のIDまで命令実行が確定したかを保持しておかなければならないだろう。 そしてフラッシュが発生した場合、コミットポインタの位置までHEADポインタを戻せば良い。 TAILポインタは、コミットと同時に進めるようにしておけば投機的な状態は無くなるため、フラッシュ時に特別な処理を行う必要はない。
その変わり、リネームと同時に書き戻した場合、その書き戻したIDを再利用しなければならない。これは、フラッシュと同時にデータパス上に存在する命令は一つも存在しなくなると考えれば、 投機的な状態ではなくなるため、現在のHEADポインタに合わせてTAILポインタを調整すれば良いとも考えることができる。