命令セット

命令セットはプロセッサ命令の集まりである。すなわちコンピュータのハードウェアに対して命令を伝えるための言葉の語彙である。

1. 概要
-----

プロセッサは命令を実行することで処理をおこなう。プロセッサが受け入れ可能な命令はプロセッサごとに異なり、あるプロセッサが受け入れ可能な命令の集合を命令セットという。

命令はバイナリ形式であるため、命令セットは受け入れ可能なバイナリの単なる一覧である。しかし実際に命令セットを利用するには各命令の意味を理解する必要がある。命令セットはこのセマンティクスをバイナリ列で表現したものとも言えるため、「命令セット」という語はレジスタ種別やアドレッシングモードなどを含む「プロセッサモデルとその命令群」という意味で用いられる。

プロセッサ間で共通化された、インターフェースとしての論理的な命令セットは命令セットアーキテクチャと呼ばれる。ISAに対してプログラミングをおこない、ISAに対してプロセッサ実装をおこなうことで、単一のISAに対して書かれたプログラムが様々なプロセッサで動作する。

2. 要素
-----

命令セットは複数の要素を組み合わせて設計されている。

計算モデル: レジスタマシンかスタックマシンか
演算: CISC型かRISC型か。対応するオペコードの設定
レジスタ: 用途、bit幅、本数
アドレッシングモードこれらの要素は最終的に「利用可能な命令の一覧」という形でインターフェースとなる。

2.1. レジスタ
---------

ISAにおけるレジスタはオペランドとして利用できる記憶領域である。論理レジスタとも呼ばれる。レジスタの構成はISAによって異なる。例えばIA-32は8本のGPレジスタを持つがX64は16本のGPレジスタを持つ。

論理レジスタという名称はマイクロアーキテクチャ上で定義されるレジスタとの区別を意図した名称である。ソフトウェアはインターフェースとしての論理レジスタに対してプログラミングされ、処理系であるCPUは論理レジスタを物理レジスタへマッピングして実処理をおこなう。この抽象化により並行計算などの最適化が可能になっている。

3. 命令セットの設計
-----------

マイクロアーキテクチャを設計するとき、技術者はRegister Transfer Languageを使って ISAの各命令の処理を定義する。

ISAをプロセッサとして実装する方法が歴史的に大きく2つ存在している。この記事は実装についての記事ではないので深くは扱わない。詳細はCPU設計などの記事を参照のこと。

ワイヤードロジック
マイクロプログラム方式この他、エミュレータや仮想機械などインタプリタ型のソフトウェアによる実装や、ハードウェア記述言語などでFPGAなどのプログラマブルロジックデバイスのコンフィギュレーションとして記述されたソフトプロセッサがある。

今日、新たなISAを開発しようとするベンダーはソフトウェアエミュレータを作って、ハードウェアが完成する前にソフトウェア開発者が開発に取り掛かることができるようにするのが一般的である。

命令セットの設計では、一部のオペコードをソフトウェア割り込みに利用する。例えば、6502では0x00、Z80では0xFFなど、68000では0xA000から0xAFFFがソフトウェア割り込みに使われた。

PopekとGoldbergの仮想化要件に適合した命令セットでは、高速な仮想機械の実装が容易になる。

複数プロセッサを搭載するシステムでは、命令セットでフェッチ・アンド・アッド、LL/SC、コンペア・アンド・スワップなどの機能をサポートすることで排他制御の実装が容易になる。

3.1. コード密度
----------

初期のコンピュータでは、メモリは高価で容量が少なかったため、メモリ上のプログラムのサイズを削減することが重要な課題であった。そのため、ある作業をするのに要する命令列のサイズを「コード密度; code density」と呼び、命令セットの重要な特性の1つとしていた。コード密度の高い命令セットでは、1つの命令で一度にいくつもの機能を実行できるようになっている。そのような複雑な命令セットを持つコンピュータ  では、基本的な操作に加えて、メモリアクセス、レジスタのインクリメントといった操作を同時に行う。ソフトウェア実装の命令セットではさらに複雑な命令も存在する。

RISCは、メモリの低価格化に伴って登場した考え方であり、命令セットを単純化することでコード密度は低下する。RISCでは、各命令はレジスタ同士の加算などといった単純な操作しか行わない。

MISC  はスタックマシンの一種であり、命令数は非常に少なく、1ワードに複数の命令を格納可能となっている。MISCの実装にはチップ面積はごく小さくて済み、FPGA やマルチコアでの実装に適している。コード密度はRISCと同程度である。例えば、FORTH言語を実装したチップがある[1]。

命令セットの分類方法として、最も複雑な命令のオペランド数で分類する方法がある。

0オペランド - スタックマシンとも呼ばれ、全てのオペランドをスタックから取り出して使用する。2つの数を加算する処理は4命令  で行われる。
1オペランド - 初期のコンピュータでよく使われたモデルで、1つのオペランドを使って処理をし、結果をアキュムレータに格納する。2つの数を加算する処理は3命令  で行われる。
2オペランド - RISCマシンのほとんどはここに分類される。CISCマシンもここに分類されるものが多い。RISCの場合、2つの数を加算する処理は4命令  で行われる。
3オペランド - 一部のCISCと、RISC の中ではごく一部に過ぎないがRISCの特徴を最も良く表すとされる、RISC I、MIPS、RISC-Vがここに分類される。CISCの場合、2つの数を加算する処理は1命令  で行われるか、より一般的には2命令  で行われる。RISCの場合、オペランドが3つであってもメモリアクセスと加算は別命令となるため、さらにロード命令とストア命令が必要になる。レジスタが32本なら、3つのオペランドを指定するのに15ビット必要となり、必然的に命令サイズは32ビットかそれ以上でなければならない。
4以上 - 一部のCISCでは3つ以上のレジスタを指定してメモリアクセスを行う命令が存在する。コード密度を改善する機構として実行ファイル圧縮が研究されてきた。関連する数学上の概念としてコルモゴロフ複雑性がある。

3.2. 機械語
--------

機械語は個々の命令から構成される。アーキテクチャにもよるが、命令は通常、以下のいずれかを指定する。

算術演算、アドレス指定、制御用途にレジスタを指定する。
メモリ位置やオフセットを指定する。
オペランドを解釈するためのアドレッシングモードを指定する。このような単純な命令を組み合わせてより複雑な操作を構築し、これを逐次的に実行したり、制御フロー命令で順序を変えたりする。

多くの命令セットに共通な操作として、以下のものがある。

移動
レジスタに固定の定数値を格納する。
あるメモリ位置からレジスタにデータを移動する。そのデータに対して後から何らかの計算を行い、結果をメモリに格納する。
ハードウェア機器からデータを読み込んだり、逆にデータを書き込んだりする。 計算
加算、減算、乗算、除算。2つのレジスタの内容についてそれら演算を行い、結果をレジスタに格納する。
ビット演算。2つのレジスタのビット位置毎の論理和や論理積を計算したり、1つのレジスタのビット毎の否定を計算する。
2つのレジスタの値の比較 制御フローの変更
プログラム内の別の位置にジャンプし、そこの命令を実行する。
ある条件が成り立つときだけ別の位置にジャンプする。
別の位置にジャンプするが、その際にジャンプ元の次の命令の位置を記憶しておき、後でそこに戻るコンピュータによっては命令セット内に複雑な命令を持っている。通常ならいくつもの命令を使わなければならないような操作を1つの命令で実現している。一般にそのような命令は内部で複数のステップに分解され、複数の実行ユニットを使って実現される。さもなくば、プロセッサの回路規模が大きくなりすぎることになる。そのような複雑な命令として以下のようなものがある。

複数のレジスタを一度にスタック上にセーブする。
メモリを大きなブロックで移動する。
複雑な浮動小数点演算
テスト・アンド・セット命令などの不可分操作を実行する。
ALUへの入力にレジスタではなく、メモリ位置を指定する命令。つまり、メモリからの移動と計算が1つの命令で行われる。最近普通に実装されるようになった複雑な命令として、SIMD  命令またはベクター命令がある。これは、同じ演算操作を複数のデータに同時に行うものである。SIMD によって大きなベクトルや行列の操作を短時間で行うことが可能となる。また、音声、画像、動画などの並列化されたアルゴリズムを高速に実行できる。SIMD の実装には様々なマーケティング上の名称がつけられている。

命令セットの設計は複雑な問題である。マイクロプロセッサの歴史は命令セットの設計で2つの段階に分けられる。当初、CISC すなわち複雑な命令セットが実装されていた。1970年代、IBMなどで研究が行われ、多くの命令が省略可能であることが判明した。その結果 RISC すなわち縮小された命令セットが登場した。命令セットが縮小されることで、クロックを高速化でき、プロセッサのサイズを小さくでき、電力消費を低減させることが可能となった。極端なRISCでなくとも、典型的な操作を最適化し、メモリやキャッシュの効率を向上させ、プログラミングを単純化させることができる。

4. 命令セットアーキテクチャ
---------------

命令セットアーキテクチャはプロセッサの論理的動作を定義づける、ハードウェアとソフトウェアのインタフェースである。すなわち、インターフェースとして定義される論理的な命令セットである。

ISA登場前、各プロセッサは自身の動作を表現する独自の命令セットを有していた。ゆえにソフトウェア開発者は各プロセッサの命令セットを理解し、各プロセッサ向けに異なるプログラムを用意する必要があった。プロセッサ種が増えるにつれこの形は非効率になっていき、インタフェースの必要性が認識された。すなわち、論理的/仮想的なプロセッサの命令セットを先行して定義する方式である。この方式では、ハードウェア開発者は良いインタフェース実装を作れれば幅広いユーザを獲得でき、同時にソフトウェア開発者は単一の命令セットに対してプログラミングするだけで幅広いプロセッサで動作するプログラムを作成できる。こうして考案された、プロセッサの論理的動作を定義づける、ハードウェアとソフトウェアのインタフェースが命令セットアーキテクチャである。

ISAはコンピュータ・アーキテクチャの一部であり、レジスタの構成、命令、アドレッシングモードなどから構成される。ISAでは命令を二進数のコードのセットで表現する。これは機械語とも呼ばれる。

ISAの実装様式をマイクロアーキテクチャという。マイクロアーキテクチャはマイクロコード、パイプライン、キャッシュシステムなどを含む。ISAに対する異なるマイクロアーキテクチャの例として、x86 ISA に対するインテルのPentiumとAMDのAthlonが挙げられる。

この概念を拡大したユニークなISAとしてTIMI  があり、これはシステム/38とAS/400で使われている。TIMIは最近では仮想機械として知られるソフトウェアで実現されている。これはプラットフォームとそこで動作するアプリケーションの寿命を延ばすために設計されたもので、プラットフォーム全体を全く異なるハードウェアに移行してもTIMI自身だけを移植すれば、その上のオペレーティングシステムもアプリケーションもそのまま動作する。このためIBMはAS/400のハードウェアを古いCISCからPOWERに移行させたが、オペレーティングシステム  を含めたソフトウェアは全く変更せずに済んだ。

論理スイッチアーキテクチャの基本的な構成要素はフローテーブルである。スイッチに入る各パケットは、1つまたは複数のフローテーブルを通過する。各フローテーブルは、エントリと呼ばれるいくつかの行で構成され、7つのコンポーネントで構成される。

4.1. ISA一覧
----------

この一覧は完全ではない。古いものは省かれていて、新しいものはこれからも出てくるだろう。 商用のマイクロプロセッサやマイクロコントローラは様々なISAを実装している。 ISAのカスタマイズも非常によく見られる。

4.1.1. ハードウェアで実装されたISA
----------------------

DEC Alpha
ARMアーキテクチャ
ARM64 
IA-64
MIPSアーキテクチャ
68000
PA-RISC
POWER
PowerPC
SPARC
SuperH
System/360
z/Architecture
Tricore 
トランスピュータ 
VAX 
x86
IA-32
x64
バロース B5000
PDP-11 

4.1.2. ハードウェアでも実装されたが一般にはソフトウェアで実装されているISA
------------------------------------------

p-Code 
Java仮想マシン 
FORTH
RISC-V

4.1.3. ハードウェアに実装されていないISA
-------------------------

SECDマシン
ALGOL Object Code
MMIX - ドナルド・クヌースの //The Art of Computer Programming// で使われている教育用途のマシン

5. 関連項目
-------

5.1. ISAのカテゴリー
--------------

CISC
RISC
ベクタープロセッサ
VLIW
EPIC
SIMD
Explicit Data Graph Execution

5.2. 特殊な命令セットの利用例
-----------------

デジタルシグナルプロセッサ
GPU
再構成可能コンピューティング

5.3. 何らかのISAを実装しているハードウェア
-------------------------

CPU
マイクロコントローラ
マイクロプロセッサ

5.4. その他
--------

コンピュータ・アーキテクチャ
CPU設計
エミュレータ
仮想機械
Atmel AVR
アプリケーションバイナリインタフェース 
Hardware Abstract Layer 
ストリーミングSIMD拡張命令  命令セット

6. 脚注
-----

7. 参考文献
-------

8. 外部リンク
--------

[2]
[3]
[4] by Jonathan Bowen
[5]