マイコンのわり算事情

とある事情により、あるマイコンで実際に使用されている命令を集計していた。

そしたら乗算・除算命令が使われていなくて、そうなの?

と思ったら、乗算・除算はアセンブラで書かれたコードを呼び出していた。


乗算については32bit×32bitの演算は最大で64bit幅になる可能性があるので、

そのようなケースに対応した処理をアセンブラで書いているようだった。

一方の除算なのだが、1bitずつ除算を進めていく命令を32個並べるというコードになっていた。

除算の途中状況をステータスレジスタに残しながら進めていくらしい。


確かにコンピュータにとってわり算は面倒である。

コンピュータの演算でAND・OR・NOTのような論理演算は論理回路そのままで実現できて、

足し算は全加算器という論理回路の比較的簡単な組み合わせで作ることができる。

引き算は2の補数にして足すという処理に置き換えられるので、全加算器に追加の回路を足せば良い。

これに比べるとかけ算は複雑だが、かけ算を行う乗算器という論理回路は一般的に使われていて、

なので小規模なマイコンを除けば乗算器は積んでいるのが通常である。


一方のわり算だが、筆算のように何ステップかに分けて計算していくのが一般的である。

かけ算に比べるとはるかに複雑な演算なので一発で計算する回路は現実的に積めないと。

高速化する手法はいろいろあるが、回路規模とのトレードオフという側面もある。

それでこのマイコンは直接的にわり算を行う命令はなくて、

そのかわりビットシフトと足し引きをセットにしたような命令を用意していて、

これをビット数分繰り返すことでわり算ができる仕組みになっているよう。

具体的なアセンブラのサンプルコードがいくつか書かれていて、それを実装しているようだった。


こういう処理をコンパイラで自動生成できないのかはよくわからないけど。

ただ、わり算については何命令も積み重ねないといけないので、

そういう関数を1つ作って呼び出すという方がいいのかも。

そこまでコンパイラが自動でやってもよさそうなものだけど。


というわけで、わり算はかなり大変だというのを改めて認識したのだった。

前にRISC-Vの命令セットを見ていたときに、乗算・除算が拡張命令セットに位置づけられていて、

乗算器や除算器を積まないという選択肢を用意しているのかと思うも、

わざわざそういうものを作るのかねとは思う。世の中にはあるかもしれないけど。