MIPSにはMOVN/MOVZという条件付き格納命令が存在するが、これの実装は実はなかなか難しい。
if (rt != 0) rd <= rs else <nothing>
これ、HW的に分解すると、
if (rt == 0) rd <= rs else rd <= rd
とせざるを得なくなる。一度「レジスタにWBする」という名目でフリーリストからIDを取得した以上、フォワーディングの論理的にも書き込みをキャンセルするのは難しい。 従って、「同じ値を書き戻す」という処理になる。
では、「フォワーディングをキャンセル」「レジスタ書き込みをキャンセル」という論理を入れれば成立するのではないか?と思うかもしれない。ここもまた難しい。
sub r10,r00,r01 ... movn r10,r11,r12 add r13,r10,r01
さて、add命令はどこからフォワードを受ければ良いか? movnで条件が成立してライトバックが発生する場合、もちろんmovn命令からフォワードを受けとる。 しかし、movnの条件が成立しない場合、フォワードをキャンセルする。すると、addが既にsubの結果を持っていれば良いのだが、subがインフライト中であり、addが既にリネームを完了してしまうと、
- subがレジスタライトバックをおこしても、既にaddはレジスタリードしておりフォワードできない
- フォワードパスを設けたくても、subのr10とaddのr10は「途中にmovnが入っているため」フォワードできない(アーキテクチャレジスタ的には同じr10なのに!)
上記の理由からこのときのフォワーディングは非常に難しい。
このため、現在開発している自作MIPSでは、movn/movz命令は2命令に分割している。 まず比較を実行し、その次のマイクロ命令でcmovを行うという寸法だ。 1番目の命令はex内に比較結果を保持し(こいつはレジスタライトバックをしない)、 2番目の命令は必ずcmovでレジスタライトバックを起こすことで、IDの矛盾が生じないようにしている。