リターンアドレススタック(Return Address Stack: RAS)は、関数呼び出しなどの命令(Call命令)が実行された場合、その関数の戻り先をあらかじめスタックに記憶しておき、Return文が実行された場合にスタックから戻りアドレスを取り出し、 そこからフェッチを行う機構である。
この場合、実際にどのような機構を実装すればよいかという話になるが、RASへの格納はCall命令がコミットされた時点でよかろう。 そうして、フェッチが行われる毎にReturn命令かどうかを判定し、Return命令ならばRASからPopするという方式になる。
ただし、この実装をしていて問題を発見した。 すぐに戻ってくるような関数でテストしていると、どうやらCall命令がコミットする前に(分岐予測のため)Return命令がフェッチされてしまい、RASに積む前にPopが必要となってしまう。 実装は簡単だが、これで背右脳を出すのは難しいのだろうか。
もう一方の実装方法として、Call命令がコミットされる前、つまり命令をフェッチしてきた段階でRASにスタックし、Popと同じステージで制御する。 これも実装としては簡単だが、やはり投機的な命令まで使って判定してしまうため、スタックを汚してしまい、性能に影響が出る。
一般的なRASの実装はどのようになっているのだろう?調査する必要がある。