FPGA開発日記

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

RISC-Vが32ビットと64ビットの仕様を明確に分離するのは何故なのか

f:id:msyksphinz:20210325001324p:plain

RISC-V ISAマニュアルの最初の方を読んでいて、小噺的に書いてあったのを読んでちょっと面白そうと思った、というか自分でもまだイメージが上手くできていない部分があるのでメモしてみる。

github.com

RISC-Vでは32ビットと64ビットのモードを明確に分離し別々のISAとして定義している。なぜRV32はRV64の厳密なサブセットにしなかったのか、という理由が説明されている。 MIPS32とMIPS64は完全にスーパーセットであるように設計されているという説明を見たのだが、ググってみると確かに以下の文章で似たような記述があるのでそれは間違いないのだろう(中森章さんの文章)。

  • 『はじめて読む MIPS(リローデッド)』 by 中森章

https://www.cqpub.co.jp/interface/TechI/Vol39/app/mips_asm.pdf

ここでいう互換性がないというのがあまりイメージできていなかったのだが、詳細に調べるとMIPSの場合はMIPS32とMIPS64において同一命令の動作は完全に同一らしい。 例えばADD命令は、MIPS32とMIPS64ではどちらでも「32ビット加算」として定義されている(64ビット加算はMIPS64においてDADDとして定義されている)。

f:id:msyksphinz:20210324235809p:plain

f:id:msyksphinz:20210324235853p:plain

一方でRISC-Vの場合はADD命令はRV32では32ビット加算、RV64では64ビット加算となる。なるほど、これが「RV32とRV64で互換性がない」という説明の意味するところか。 MIPSの方式ではMIPS64のハードウェアでMIPS32のバイナリを厳密に実行できる可能性があるが、RISC-Vの場合はそうはならない。これが「命令セットを分離する」というところの意味合いとなっているのだろう。

まあとりあえずこの辺の前置きはすっ飛ばすとして、RV32とRV64を明確に分離した理由として一つは、各ISAのベースコンフィグレーションに実装を最適化できるという点が挙げられている。 さらに、どちらにしろRV32IをRV64Iでエミュレートするような状況でも、微妙な仕様の違いにより不正命令例外などの制御の違いによりどちらにしろハードウェアの支援なしに完全なエミュレーションは出来ないという結論に至ったらしい(結局MIPSもそうだったのだろうか、最後にそれっぽいメモが入っている)。

We note that newer SPARC and MIPS ISA revisions have deprecated support for running 32-bit code unchanged on 64-bit systems.

さらに、RV32とRV64でのABIの仕様の違いもあり完全に互換性をもって設計することは出来ない、という所からもRV32IとRV64Iを分離して設計した、という理由になっている。

このような議論により、「RV32/RV64にはADD命令を定義し、RV64には追加的にADDW」という命令を定義する、という設計方針に繋がっている。 これは命令の互換性というよりも「RV64で32ビット演算をしたい」という目的から作られた命令であり、現にRV32ではADDWはサポートされていない。


こうして改めてMIPSの仕様を見てみると、MIPS64でも「AND」命令の仕様は「do a bitwise logical AND」となっておりビット幅の定義が載っていない。加算命令ではADDとDADDを厳密に分離したのに、ANDの場合は胡麻化しているように見えないこともない。これを良しとするかは別問題として、RISC-Vはこの辺の命名統一性まで考慮して命令をデザインしたということなんだろうか。