FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Conditional Moveがスーパスカラで難しい理由

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が既にリネームを完了してしまうと、

上記の理由からこのときのフォワーディングは非常に難しい。

このため、現在開発している自作MIPSでは、movn/movz命令は2命令に分割している。 まず比較を実行し、その次のマイクロ命令でcmovを行うという寸法だ。 1番目の命令はex内に比較結果を保持し(こいつはレジスタライトバックをしない)、 2番目の命令は必ずcmovでレジスタライトバックを起こすことで、IDの矛盾が生じないようにしている。