ARMアーキテクチャ

概要

ARMアーキテクチャは消費電力を抑える特徴を持ち、低消費電力を目標に設計されるモバイル機器において支配的となっている。本アーキテクチャの命令セットは「（基本的に）固定長の命令」「簡素な命令セット」というRISC風の特徴を有しつつ、「条件実行、定数シフト/ローテート付きオペランド、比較的豊富なアドレッシングモード」といったCISC風の特徴を併せ持つのが特徴的だが、これは初期のARMがパソコン向けに設計された際、当時の同程度の性能のチップとしてはかなり少ないゲート数（約25,000トランジスタ）で実装されたチップの多くの部分を常に活用する設計として工夫されたもので、回路の複雑さを増さないという方向性だというように見れば、CISC風の特徴というよりむしろRISC風の特徴とも言える。ともあれ以上のような設計が、初期の世代の実装において、（性能の割に）低消費電力、小さなコア、（RISCとしては）高いコード密度といった優れた特性に結びつき、広く普及する原動力となった。
2005年の時点で、ARMファミリーは32ビット組込みマイクロプロセッサ（乃至、特にマイクロコントローラ）のおよそ75%を占め、全世界で最も使用されている32ビットCPUアーキテクチャである。ARMアーキテクチャに基づくCPUコアは、PDA・携帯電話・メディアプレーヤー・携帯型ゲーム・電卓などの携帯機器から、ハードディスク・ルータなどのPC周辺機器まで、あらゆる電子機器に使用される。2013年現在、NECのEMMA MobileはCortex-A9をや日立系のSuperH系のSH Mobile GシリーズはARMを内蔵するなど、携帯電話では100%近いシェアがある。
携帯機器や電子機器の高性能化に伴いARMコアの出荷数は加速度的に伸びており、2008年1月の時点で100億個以上、2010年9月の時点で200億個以上が出荷されている。ARMアーキテクチャを使用したプロセッサの例としては、テキサス・インスツルメンツのOMAPシリーズやマーベル・テクノロジー・グループのXScale、NVIDIAのTegra、クアルコムのSnapdragon、フリースケールのi.MXシリーズ、ルネサス エレクトロニクスのRZファミリ、Synergyなどがある。
既存のARMプロセッサは組み込みとクライアントシステムに特化していたため全て32ビットであるが、顧客からは電力効率に優れるARMアーキテクチャのサーバへの応用を望む声が高まり、ARM社は2011年10月27日、ARMの64ビット拡張であるARMv8アーキテクチャを発表した。

歴史

ARMの設計は、1983年にエイコーン・コンピュータ（イギリス）によって開始された。当時エイコーンはモステクノロジーのMOS 6502を搭載したコンピューターを製造・販売しており、小さなハードウェア規模でシンプルな命令セットを持つ、より高速なプロセッサを開発することによって、6502を置き換えることが目的であった。
開発チームは1985年までにARM1と呼ばれる開発サンプルを完成させ、最初の製品となるARM2は次の年に完成した。ARM2は32ビットのデータバス、26ビットのアドレス空間と16個の32ビットレジスタを備えていた。レジスタの1つは、上位6ビットが状態フラグを保持するプログラムカウンタである。ARM2のトランジスタ数は30000個しかなく、おそらく世界で最もシンプルな実用32ビットマイクロプロセッサであった。これは、マイクロコードを持たないこと（モトローラのMC68000の場合は1/4から1/3がマイクロコードであった）と、現在のほとんどのCPUと違ってキャッシュを含まないことによるものである。このシンプルさのために消費電力は極めて低いが、それにもかかわらず80286よりも性能は高かった。後継となるARM3は、4KBのキャッシュを含みさらに性能を高めた。
1980年代後半、アップルコンピュータはエイコーンと共同で新しいARMコアの開発に取り組んだ。この作業は非常に重要視されていたため、エイコーンは1990年に開発チームをスピンオフしてAdvanced RISC Machinesという新会社を設立した。このため、ARMは本来のAcorn RISC MachineではなくAdvanced RISC Machineの略であるという説明をよく見かけることになる。Advanced RISC Machinesは、1998年にロンドン証券取引所とNASDAQに上場した際、ARM Limitedとなった。
この作業の結果、ARM6が開発された。1991年に最初のモデルがリリースされ、アップルはARM6ベースのARM610をアップル・ニュートンに採用した。
これらの変化を経てもコアは大体同じサイズに収まっている。ARM2は30000個のトランジスタを使用していたが、ARM6は35000個にしか増えていない。そこにあるアイデアは、エンドユーザーがARMコアと多くのオプションのパーツを組み合わせて完全なCPUとし、それによって古い設備でも製造でき、かつ安価に高性能を得られる、というものである。
このARM6の改良版であるARM7も、ARM6を採用した製品群に引き続き採用されたほか、普及期に入りつつあった携帯電話にも広く採用されたことから、今日のARMの礎ともなった。
さらに、新世代のARMv4アーキテクチャに基いてARM7を再設計したものがARM7TDMIである。ARM7TDMIはThumb命令（後述）を実装し、低消費電力と高いコード効率を両立する利点を備えていたことから、ライセンスを受けた多くの企業によって製品化され、特に携帯電話やゲームボーイアドバンスといった民生機器に採用されたことから、莫大な数の製品に搭載された。なお、TDMIとはThumb命令、デバッグ (Debug) 回路、乗算器 (Multiplier)、ICE機能を搭載していることを意味している。しかし、これより後のコアには全てこれらの機能が標準的に搭載されるようになったため、この名称は省かれている。
DECはARMv4アーキテクチャの設計のライセンスを得てStrongARMを製造した。233MHzでStrongARMはほんの1Wの電力しか消費しない（最近のバージョンはさらに少ない）。この業績は後に訴訟の解決の一環としてインテルに移管され、インテルはこの機会を利用して古くなりつつあったi960をStrongARMで補強することにし、それ以降XScaleという名で知られる高性能の実装を開発した。
以後も、StrongARMの技術のフィードバックを受けたARM9やARM10を経て、NECとの提携などによって携帯電話向けプロセッサとしての地位を確固たるものにしたARM11をリリースする。
2005年には製品ラインナップを一新し、高機能携帯電話などのアプリケーションプロセッサ向けであるCortex-A、リアルタイム制御向けであるCortex-R、組み込みシステム向けであるCortex-Mと、ターゲットごとにシリーズを分類した。なお、Cortexの末尾に付く文字は、社名であるARMの一文字ずつをそれぞれ割り当てたものである。また、2012年11月にはARM初となる64ビットアーキテクチャによるプロセッサコアであるCortex-A50シリーズを発表した。
ARMからIPコアのライセンス供与を受けている主な企業には、モトローラ、IBM、テキサス・インスツルメンツ、任天堂、フィリップス、Atmel、シャープ、サムスン電子、STマイクロエレクトロニクス、アナログ・デバイセズ、パナソニック、クアルコム、マーベル・テクノロジー・グループなどがある。ARMチップは世界で最もよく使われているCPUデザインの一つとなっており、ハードディスク、携帯電話、ルータ、電卓から玩具に至るまであらゆる製品の中に見ることができる。32ビット組み込みCPUで圧倒的なシェアを占め、2004年の世界シェアは61%であった。

条件実行

ARMの命令セットにおいてユニークなのは、マシン語の最上位4ビットを占める条件コードを使用した条件実行命令であり、これによってほぼ全ての命令を分岐命令無しに条件付きで実行することができる。
これにより、マシン語中の即値フィールドに割けるビット数が減ってしまう等の欠点もあるものの、小さなif文に対応するコードの生成時に分岐命令を避けることが可能になる。例として、ユークリッドの互除法を挙げる。
（この例はC言語による）
int gcd(int i, int j){
    while (i != j) {
        if (i > j)
            i -= j;
        else
            j -= i;
    }
    return i;}
ARMのアセンブリ言語では、whileループの部分は以下のようになる。
 
 loop
        CMP    Ri, Rj       ; i と j を比較
        SUBGT  Ri, Ri, Rj   ; もし "GT" ならば i = i - j;  
        SUBLT  Rj, Rj, Ri   ; もし "LT" ならば j = j - i; 
        BNE    loop         ; もし "NE" ならば loop に戻る
通常分岐命令を使用しなければならないthenやelse節のところで分岐が省かれていることが分かる。
命令セットのもう一つのユニークな機能が、シフト演算を「データ処理」（算術演算、論理演算、レジスタ間の代入）命令の中に織り込むことができることである。例えば、C言語の
a += (j << 2);
のような文を1つのARM命令
        ADD     Ra, Ra, Rj, LSL #2
として表すことができる。（なお、Intel 80386などでも1個の命令でできる。LEA EAX,[EAX+EBX*4] とすればよい。）
これにより、多くのARMプログラムは通常RISCプロセッサに期待されるようなプログラムよりも密度の高いものになる。このため、命令フェッチに伴うメモリへのアクセス頻度が少なくなり、分岐に伴うストールも回避しやすく、パイプライン処理を効率的に使うことができる。このことが、ARMがARMより複雑なCPUデザインと競合することを可能にした特徴的な一因のひとつである。

Thumb

ARMプロセッサはThumbと呼ばれるコード効率の向上を意図した16ビット長の命令モードを持っている(SuperHの命令16ビット/データ32ビットに倣い追加された)。条件実行のための4ビットプレディケートが削除されている。メモリポートやバスが32ビットよりも狭い状況において32ビットコードよりも性能が向上する。多くの場合、組み込みアプリケーションでは32ビットのデータパスを持っているのは一部のアドレス範囲のみであり（例: ゲームボーイアドバンス）、残りは16ビットかそれよりも狭くなっている。このような状況では、Thumbコードをコンパイルし、CPUに最も負荷のかかる部分だけを32ビット長の命令セットを使用して手作業で最適化するのが、通常は理にかなっている。Thumb命令とARM命令は単一の実行ファイル内で混在が可能であるが、Thumb命令を実行できるモードとARM命令を実行できるモードは独立しており、両者を使うにはその都度プロセッサの状態を切り替える必要がある。状態の切り替えは分岐命令 (BX, BLX) で行うことができるため、通常は関数単位でThumb命令とARM命令を使い分け、関数呼び出しの際に切り替えを行うのが一般的である。
Thumbテクノロジを搭載した最初のプロセッサはARM7TDMIである。ARM9とそれ以降のファミリは、XScaleも含めて全てThumbテクノロジを搭載している。

Thumb-2

Thumb-2テクノロジは2003年に発表されたARM1156コアで登場した。Thumb-2はThumbの制限された16ビット長の命令セットを追加の32ビット長命令で拡張し、命令セットの幅を広げるものである。公称されているThumb-2の目的は、Thumbと同様のコード密度と32ビットメモリ上でのARM命令セットと同様の性能を得ることであり、Thumb-2はビットフィールド操作、テーブル分岐や条件付き実行などを含んでいる。従来はThumbモードにおいて使用可能な汎用レジスタは8本のみであり自由度が低かったが、Thumb-2で導入された32ビット長命令では16本全てのレジスタが使用可能である。16ビット長命令と32ビット長命令はモードの切り替えなしで混在可能であるため、ThumbモードにおいてもARMモードに近い自由度が得られるようになった。

Jazelle

ARMは、Javaバイトコードをハードウェアでネイティブに実行できる技術を実装した。これはARMやThumbモードと並ぶもう一つの実行モードであり、ARM/Thumbの切り替えと同様にしてアクセスすることができる。後述のJazelle RCTに対してJazelle DBX (Direct Bytecode eXecution) とも言う。
Jazelleテクノロジを搭載した最初のプロセッサはARM926EJ-Sである。CPU名の'J'がJazelleを表している。

Thumb Execution Environment (ThumbEE)

ThumbEEはJazelle RCT (Runtime Compilation Target)とも呼ばれる第4のモードである。2005年にアナウンスされ、Cortex-A8プロセッサで最初に実装された。Thumb-2命令セットに小規模な変更を加えたもので、JITコンパイラのように実行時にコードを生成する場合に向いている。主な対象はJava、.NET MSIL（C#など）、Python、Perlなどの言語である。

DSP 拡張命令

デジタル信号処理とマルチメディアアプリケーション向けに ARMアーキテクチャを拡張するため、いくつかの命令が追加された。ARMv5TE と ARMv5TEJ というアーキテクチャ名の "E" がこれを表していると思われる。
追加された命令は、デジタルシグナルプロセッサアーキテクチャで一般的なものである。例えば、符号付積和演算、飽和加算と飽和減算、「先行する0のカウント」のバリエーションである。

SIMD

ARMv6で導入された。32ビット幅。

Advanced SIMD (NEON)

Advanced SIMD拡張はNEONとも呼ばれ、メディアおよびデジタル信号の処理に向いた64ビットと128ビットのSIMD命令セットである。8/16/32/64ビットの整数演算と、32ビット (単精度) 浮動小数点演算のためのSIMD命令が定義されており、ARMv7から利用可能。32ビットCPUでは倍精度浮動小数点数は利用不可で、倍精度にはVFPを使用。
ほとんどの ARMv7 SoC で NEON に対応しているが、NVIDIA Tegra 2 シリーズ、SPEAr1310、SPEAr1340 などで対応していない。
レジスタはVFPレジスタとして用意されている32本の64ビットレジスタを用いて、32本の64ビットSIMDレジスタ (D0-D31) 、もしくは16本の128ビットSIMDレジスタ (Q0-Q15) としてアクセスできる。例えば128ビットレジスタQ0はD0とD1の2つの64ビットレジスタの領域にマッピングされている。
Cortex-A15 などより、NEONv2 (version 2) が搭載され、Fused Multiply-Add ができる。これにより、単精度浮動小数点数で 8 FLOPS/cycle となった。

Wireless MMX

Wireless MMX (WMMX) はインテルがXScaleプロセッサ向けに開発したSIMD命令セットである。64ビット幅のレジスタが16本用意されており、8/16/32/64ビットのSIMD整数演算が可能。XScaleとその売却先であるマーベル・テクノロジー・グループ製のARM SoCに採用されている。命令セット自体はx86プロセッサのMMXとは全く異なるものの、GCCやVisual C++等のコンパイラで利用できる組み込み関数はMMXとの互換性がある程度確保されており、これを利用すればMMX向けに記述されたコードを比較的容易に移植することができる。

SIMD and Floating-point (NEON) 命令

A64命令セットにおいては従来のVFPとAdvanced SIMD (NEON) は統合され、一つの命令体系となった。これに伴い、名称については単にSIMD and Floating-point命令と呼ばれるようになった。
主な変更点は倍精度浮動小数点演算への対応、IEEE754への準拠、レジスタ本数の増加の3点である。レジスタについては128ビットのレジスタが32本に増加している。依然として64ビットレジスタとしてアクセスすることも可能であるが、32ビットモードとは異なり、64ビットレジスタは128ビットレジスタの下位64ビットにマッピングされている。
VFPとAdvanced SIMDの統合に伴い、従来はVFPが担っていたスカラの浮動小数点演算命令は、SIMDレジスタのうち下位の32/64ビットにのみ作用する命令として再定義されている。例えば浮動小数点加算命令については
 fadd  s2, s1, s0             ; s2 <= s0 + s1（単精度スカラ）
 fadd  d2, d1, d0             ; d2 <= d0 + d1（倍精度スカラ）
 fadd  v2.4s, v1.4s, v0.4s    ; [v2] <= [v0] + [v1]（単精度x4 SIMD）
 fadd  v2.2d, v1.2d, v0.2d    ; [v2] <= [v0] + [v1]（倍精度x2 SIMD）
のようなバリエーションが命令のニーモニックを保ちつつ、オペランドのプレフィックス (s, d, v) とサフィックスを変更することによって記述可能になっている（サフィックスについては、一部の環境向けのアセンブラではニーモニック側に付加する省略記法も許されるようである）。これはx86プロセッサのSSE命令セットがスカラ命令とSIMD命令の双方を備えているのとよく似ている。