再定義された64bit命令

ARM社によれば、64bitアーキテクチャについては2007年から作業を開始したという。2007年は、現在のCortex-A9マイクロアーキテクチャが発表され、GoogleがOHA(Open Handset Aliance)を設立してAndroidを正式発表した年。これ以前から、スマートフォンなどの動向を見て、開発を決断したのだと考えられる。

ARM社によれば、64bit動作が必要な理由として「大きな仮想アドレス空間が必要」としている。また、将来のマーケットで必要になる予想され、さらに64bit動作を可能にすることでARMのマーケットを拡大可能とできることも理由だとしている。ある意味、スマートフォン、タブレットといった、モバイル機器だけでなく、サーバー、デスクトップなど広い分野への進出を決めたのだと思われる。

64bitモードアーキテクチャAArch64では、新たな命令セットであるA64を使う。AArch64では、汎用レジスタはすべて64bitとなり、X0~X30の31個が利用できる。さらに数値0を表すゼロレジスタも用意され、大半の命令で利用できる。浮動小数点レジスタは、128bitとなり、32個用意される。なお、ARMv7までは、R13がスタックポインタ、R14がリンクレジスタ(戻りアドレスを記憶するレジスタ)、R15がプログラムカウンタとされていたが、プログラムカウンタとスタックポインタは、汎用レジスタとは別になった。また、ステータスレジスタ、リンクレジスタ、スタックポインタは、例外レベル(後述)によりバンク切り替えとなる。

オペコードは32bitで、レジスタ指定ビットは5bitとなる。命令によってはこれに32bitまたは64bitのオペランドが続く。アドレスは、64bitであり、LP64(int型は32bit、long型とポインタが64bit)またはLLP64(int型、long型は32bitのままlong long型とポインタが64bit)モデルに向くという。

基本的な命令の意味は、A32とA64で共通だが、いくつかの変更がある。まず、ARM命令セットの特徴であった条件付き実行は、Branch、Compare、Selectの命令のみとなったようだ。

新たに追加される暗号化支援命令は、AES(米国の標準暗号化アルゴリズム)およびSHA-1/SHA-256(ハッシュアルゴリズム)に対応する。AES用にはエンコード用、デコード用の命令がそれぞれ2つで計4つの命令が追加される。AESは、128bitブロックに対する演算(ラウンド)をくりかえし、最終ラウンドのみ別処理となることから、通常と最終ラウンド用の命令に分かれているのだと推測される。なお、演算には、SIMD用の128bitレジスタを利用する。

NEON/VFPでは、前述のように128bitのレジスタを32個利用できる。SIMD演算では、倍精度浮動小数点がサポートされる。IEEE754のフルサポートが行われ、IEEE754-2008で定義された浮動小数点命令(MaxNum/MinNumなど)が追加された。

ARMv7では、8つの動作モードがあり、そのうち1つがユーザーアプリケーションの動作するモードで、これにスーパーバイザモード(カーネルモード)やハイパーバイザー(仮想マシン管理プログラム)、割り込み、例外の処理モードがあった。ARMアーキテクチャでは、汎用レジスタの一部をスタックポインタなどとして利用しているため、これらのモードでは、一部のレジスタがバンク切り替えにより、各モード専用のレジスタとなっていた。これにより、ユーザーモードとカーネルモードのスタックポインタを分離していたわけだ。なお、オペレーティングシステムのAPI呼びだしなどは、SVC(SuperVisor Call)命令で行う。

AArch64では、これらを4段階の「Exception Level(EL)」として定義し、EL0がユーザーモード、EL1がゲストOS、EL2にハイパーバイザー、EL3にセキュア実行環境(TrustZone)モニターなどを配置する。このとき、ステータスレジスタ、リンクレジスタ(AArch64ではELR=Exception Link Register)、スタックポインタのみバンク切り替えが行われ、各ELの環境を分離する。

AArch 64では、ポインタは64bitだが、仮想メモリアドレスはこのうち48bitを使う。ただし、システム用とユーザー用は分離されており、それぞれで48bitの仮想アドレスを利用できる。これに対して、物理メモリアドレスも48bitとなっており、最大256TBytesを搭載できる。また、仮想記憶のページは4KBytesまたは64KBytesが選択できる。

AArch 64では、メモリモデルとしてWeak Memory Modelを採用し、メモリアクセス順序を保証しない。ただし、同期命令を使い、ロードとストアの依存関係のある順番を保証する。簡単にいうと、書き換えられる前に読み、読み出しが終わってから書くようにする「同期」という処理を使うことで、特定処理の読み書きの順番を保証する。このためにA64には、Load-Acquire、Store-Release命令が追加され、すべての汎用レジスタ1つのロードセーブは、この形で行うことができる(汎用レジスタ1つと限定されているのは複数レジスタ読み書きの命令もあるため)。Load-Acquireが終了するまでは他のアクセスを止め、Store-Releaseが実行される前に、それ以前に発行されたメモリアクセスを完了させる。このようにすることで、必要な読み書きの順番を保証することが可能になる。なお、この同期命令同士は、RCsc(Release Consistency sequential consistency)に従い、実行順が保存される。

なお、AArch 32とAArch 64の関係だが、stateの切替は、エクセプションレベル(EL)が切り替わるとき(および戻るとき)にしか切り替わらず、同一EL内でAArch32とAArch64を切り替えることもできないし、お互いに呼び出すためのブランチやリンク方法もない。

しかし、64bitオペレーティングシステム(EL1で動作)の中で32bitアプリケーションをEL0で動作させることはできる。また、64bitハイパーバイザーのゲストOSとして32bit OSを動かすことも可能。

AArch64には、31個の64bit汎用レジスタと32個の128bitメディアレジスタがある。

AArch64では、64bitアドレス空間の中でシステム、ユーザー用にそれぞれ48bitの仮想アドレス空間を振り分けている。物理アドレスも48bitで最大256TBytesのメモリを実装できる。

AArch64では4つの「例外レベル」(Exception Level)により、動作モードを分けている。従来のARMv7までは8つの動作モードがあった。なお、AArch32では、EL1とEL2は同じ権限となる。

AArch32とAArch64の関係。64bit OSカーネル以下で32bitアプリケーションが動作可能、64bit ハイパーバイザーなら、32bit OSをゲストOSとして実行可能。