ARMv8には「AArch32」という実行モードと「AArch64」という実行モードがあるというのが大きな特徴である。名前から分かるように、AArch32はARMv7との互換性を維持する32ビット実行モードで、今回のアーキテクチャ拡張の目玉は64ビット実行環境であるAArch64である。そして、TrustZone、NEON、VFPなどのARMv6、ARMv7で追加された機能はARMv8のAArch32環境とAArch64の両方の環境で使用できる(ただし、全く同じではない)ようになっている。

64ビットアーキのA64命令セットの特徴

AArch64実行モードで実行されるA64命令セットは、従来の32ビットのA32命令セットとは異なる新しい命令形式で、32ビット固定長となっている。32ビット固定長はA32命令も同じであるが、A64命令では後述のようにレジスタ数が増えており、レジスタ番号の指定に5ビットが必要となり、これに合わせて命令のバイナリ形式は新規となり、従来のややこしい部分をクリーンアップしているようである。

その点ではA64は新規の命令セットであるが、機能的には、A32の命令と同じ機能を実現することを目指しており、どうしてもできない場合だけ異なるものになっている。

そして、大きく変わったのが、汎用レジスタ数が従来の13個(これに3個の固定用途のレジスタがあり、それらを含めると16個)から31個に増え、それぞれのレジスタが32ビット長から64ビット長になった点である。レジスタが64ビットになるのは64ビットアーキテクチャとしては必然であるが、レジスタ数の増加は性能とエネルギー効率の改善に効果があるということで採用されている。また、大部分の命令では31個の汎用レジスタに加えて0固定の値を保持するレジスタを使用することができるようになっている。これで汎用レジスタに関しては、PowerPCやSPARCなどのRISCプロセサと同等となった。

そして、従来は汎用レジスタのR13に割り付けられていたスタックポインタ、R14に割り付けられていたリンクレジスタ、R15に割り付けられていたプログラムカウンタは、AArch64では汎用レジスタでは無く専用のレジスタが設けられることになった。

A64命令セットとA32命令セットとの主要な相違点

64ビットアーキテクチャであるので、A64では64ビットのオペランドを使用することができ、大部分の命令ではオペランドのサイズは32ビットと64ビットを選択して使用できる。また、アドレス(ポインタ)は常に64ビットとして扱われる。つまり、long型のデータとポインタの両方を64ビットとするLP64データモデル、あるいはlong型は32ビットのままで、long long型とポインタは64ビットとするLLP64データモデルをサポートできるようになっている。

その他の違いとしては、条件分岐や条件比較、条件選択などと条件関係の命令が大幅に少なくなっている点と、任意の長さのロード、ストア命令が無くなった点があげられている。これらについては後で考察する。

A64での浮動小数点演算関係の拡張

ARMv7で追加されたAdvanced SIMDやVFP機能に関しては、A32と同等の機能がA64でもサポートされているが、次の3点で大きく拡張されている。まず、第一は128ビット長のレジスタが16個から32個に倍増した点である。第二は、Advanced SIMD命令で倍精度の浮動小数点演算をサポートした点、そして第三はAdvanced SIMDの浮動小数点演算がIEEE 754規格準拠になった点である。レジスタの追加や倍精度演算のサポートは科学技術計算の性能向上に効果があり、IEEE 754準拠は計算精度の改善や他のプロセサと同じ計算結果が得られるので使いやすくなるというメリットがある。

そして、ARMv8で新たに追加されたのがCRYPTOと書かれた暗号化の機能で、AES暗号の暗号化と復号化をサポートするそれぞれ2つの命令をサポートしている。この命令の詳細は不明であるが、IntelのAESサポート命令と同様の機能ではないかと思われる。また、SHA-1、SHA-256という一方向のハッシュ関数の処理も追加されている。

AArch32のレジスタとAArch64のレジスタの対応

詳細は省略するが、AArch32ではR0~R12は原則としてSPSRレジスタの状態に依存せず同じレジスタが使われるが、SPSRレジスタのビットで表される割り込み状態ごとにR13やR14は個別のレジスタが存在する構造である。また、右端から2つ目のfiq割り込みを処理する状態では、R8~R12は別のレジスタが存在するという複雑な作りになっていた。

これに対して、AArch64ではX0~X30というフラットなレジスタになり、割り込みを扱う機構は別途ELレジスタとして設けられるというクリーンな構造となった。

ARMv7ではARM命令と16/32ビット長の短いThumb2命令の実行環境は専用のジャンプ命令で切り替えることもできたが、ARMv8のAArch32とAArch64の切り替えは割り込みの場合だけに切り替えが可能で、切り替えを行うジャンプ命令は存在しない。

そして、AArch32とAarch64を切り替えた場合のレジスタ対応は上の図の右側のようになっている。

ARMv8で、大きく拡張されたのが割り込みハンドリング関係の機能で、4レベルの割り込みレベルをサポートする構造となった。

ARMv8の割り込みモデル

ARMv8ではEL0からEL3の4つの割り込みレベルを持ち、EL0は割り込みのない通常のアプリケーション実行レベルである。そして、アプリケーションの実行時に割り込みが起こるとEL1に移行し、このレベルではゲストOSが走る。そして、ゲストOSの実行中に割り込みが起こるとEL2に移行し、このレベルではVMM(仮想マシンモニタ。ハイパバイザとも呼ばれる)が実行される。VMMの実行中に割り込みが起こるとEL3に移行し、このレベルではTrustZoneのモニタが実行されるという風に、セキュリティの各レベルに割り込みレベルを対応させ、安全性を高めることができるようになっている。しかし、割り込みのレベルの使い方はソフトウェアが決めるので、右側の図のような使い方も可能である。

割り込みレベルに対応するスタックポインタやリンクレジスタ

そして、AArch32ではR13、R14に割り付けられていたスタックポインタやリンクレジスタはELレジスタとしてまとめられて、上の図のようにEL0~3で別個のレジスタが設けられている。また、AArch32ではプログラムカウンタがR15に割り付けられており、汎用の演算命令などでR15に値を書き込むとジャンプを行うことができたが、AArch64ではプログラムカウンタは独立の専用レジスタとなっており、このようなジャンプはできなくなっていると思われる。