割り算器の話しは終わりであるが、整数演算の締めくくりとして、シフト回路について考察しておこう。
マイクロプロセサの整数の演算には、加減算、乗除算の四則演算の他に、シフトや論理演算などがある。論理演算はビットごとにANDやORなどの必要な回路を作って並べれば良いので、簡単であるが、左右にシフトを行うシフターは、多少、工夫が必要である。シフト命令を見ると、
- シフト方向の左右
- シフトして溢れたビットを捨ててしまうタイプの命令と最上位ビットと最下位ビットをリング状につないでシフトを行うサーキュラーシフト
- 右シフトの場合、符号ビットを保存するか否か
のようなバラエティーがあるが、基本は、指定された数に従ってレジスタの各ビットを左右に動かすという操作である。
次の図19は、0~7ポジションの右シフトを行うシフターの回路図である。第一段のスイッチは、自分の位置の入力と左隣からの入力が入っており、スイッチを切り替えるS0信号が"0"の場合には、自分の位置の入力、"1"の場合には左隣からの入力を選択して出力する。つまり、第一段のスイッチ群の出力は、S0が"0"の場合には入力と同じであるが、"1"の場合には全て左隣の入力となり、結果として入力が1ポジション右側にシフトされたことになる。
そして、第二段のスイッチは真上の第一段スイッチの出力と、二つ左側の第一段スイッチの出力が入力されており、選択信号S1が"0"の場合には真上のスイッチ、"1"の場合には2つ左のスイッチの出力を選択して出力するので、結果として、S1が"1"の場合には第一段のスイッチの出力を2ポジション右シフトする。第三段のスイッチは真上と4つ左のスイッチの出力に接続されており、結果としてS3が"1"の場合は、第二段のスイッチの出力を4ポジション右シフトする。
このように、S0が"1"であると1ポジション、S1が"1"であると2ポジション、S2が"1"であると4ポジションの右シフトが順に行われるので、(S2、S1、S0)をバイナリの数とした値だけのポジションの右シフトを行うことが出来る。
紙面の都合で7ビット分のシフターしか書けないが、第四段は8箇所、第五段は16箇所、第六段は32箇所 左側の前段のスイッチの出力に接続するスイッチ構成を付け加えることにより、最大63ビットの右シフタが構成できる。
この図の左上にA/Lと書いた入力があるが、これはシフトで空いた箇所に"0"を詰めるロジカルシフトの場合は"0"を入力し、符号ビットを詰めるアリスメティック(算術)シフトの場合は最上位ビットであるIn N-1を入力する。
また、この図の構成では右シフトだけの機能であるが、左右両方向のシフトを行う場合は3入力のスイッチを使い、第一段は左右の隣、第二段は左右2箇所、第三段は左右4箇所離れた出力のように接続すれば良い。そして、最下位ビットと最上位ビットをリング状に繋いでサーキュラーシフトを行う場合は、上記の図でA/L信号を接続した各入力に、右シフトで溢れる下位ビットの対応する出力を接続すれば良い。
このようにシフターは、論理的には非常に単純な構成であるが、64ビットレジスタの場合の第六段では32箇所離れたビットから信号を持ってくる必要があり、長い配線が多数必要となる。このため、どうしても遅延時間が長くなる。シフターを高速化するため、伝説的な高速プロセサであるDEC Alphaではトランスミッションゲートを使ったマルチプレクサを使っており、また、各段のマルチプレクサの入力を増やして2ビット分のシフトを担当させ、スイッチ段数を半減するというような構成も用いられるが、画期的な遅延時間改善を行う方式は知られていない。
そのため、例えば、IntelのCore 2プロセサのデータシートでは、ADD/SUBは1サイクル(短い場合は0.5サイクルの命令もある)で終わるのであるが、シフト命令は4サイクルを必要としている。