Thumb-2命令

主なThumb-2命令

ビット・フィールド命令

パックデータ構造の処理を改善するため、ビットフィールドを挿入、抽出する命令がThumb 16ビット命令とARM 32ビット命令の両方に追加されました。これにより、多数のビットを挿入したり、レジスタから多数のビットを抽出したりするのに必要な命令数が減るため、パックデータ構造を使用するメリットが増え、必要なデータメモリの削減にもつながります。

ビット・リバーサル命令

この命令は、ソースレジスタの各ビットをディスティネーションレジスタのビット[n]からビット[31-n]へ転送します。ビットリバーサル命令を使わずにこれを行うには、命令15本のシーケンスで全ビットをリバースするまで少しずつスワップを続けるなど、様々な方法がありますが、これにはワーキングレジスタが必要となります。ビットリバーサル命令は、このような面倒な作業が必要なくなり、命令数を大幅に節約します。ビットリバーサルは、FFTなどのDSPアルゴリズムに使用されます。

ゼロ比較&分岐 - CZB -

この命令は、ゼロ比較の後に分岐命令が続く一般的なシーケンスの代用となります。目的は通常、アドレスポインタのテストです。新しい命令には、プログラムフロー制御、データ処理、ロード/ストア命令のほか、コプロセッサアクセス命令が含まれます。

コプロセッサアクセス命令によって、コプロセッサの中でも、初めてベクタ浮動小数点(VFP)ユニットに対応するThumbコードの記述が可能となりました。システムレジスタにアクセスする命令に加え、この命令によって、ARMステートに切替えて特殊機能にアクセスする必要がなくなり、アプリケーション全体をThumbステートで記述することが可能となります。

16ビット定数

プログラム定数の処理を柔軟に行うため、2本の新しい命令がARM 32ビット命令セットおよびThumb 16ビット命令セットに追加されました。1つはMOVW命令で、レジスタに16ビット定数をロードし、結果をゼロ拡張するものです。もう1つはMOVT命令で、16ビット定数をレジスタの上半分にロードします。32ビット定数をレジスタにロードするには、この2つの組み合わせを使います。

これがよく使用されるのは、ペリフェラルの1本以上のレジスタにアクセスする前にペリフェラルのアドレスをロードするときで、現在はリテラルプールが使用されています。リテラルプールとは、命令ストリームに組み込まれた32ビット定数群で、プログラムカウンタを基準にアクセスされます。

リテラルプールは、定数をストアし、それにアクセスするために必要なコードサイズを抑えるのに有効です。しかし、ハーバードアーキテクチャを実装するコアではオーバヘッドが発生します。このオーバヘッドとは、命令ストリームに含まれる定数をコアのデータポートで使用可能にするために必要なサイクル数です。つまり、定数をデータキャッシュにロードするか、プロセッサのデータポートからプログラムメモリにアクセスできることを指します。

定数を半分に分け、2本の命令に組み込めば、定数が既に命令ストリームにあることになり、データアクセスは不要となります。これは、小型のリテラルプールに有効です。定数にアクセスするためのサイクル数が減ることで性能が改善され、事実上、定数にアクセスする際の消費電力が削減されるからです。

ビットフィールド命令の例
ARM(v6以前) Thumb-2
AND r2, r1, #bitmask BFI r0, r1, #bitpos, #bitwidth
BIC r0, r0, #bitmask « bitpos
ORR r0, r0, r2, LSL #bitpos

上記は、マスクとシフトマスクがARM命令内でフィールドの限界を超えない単純な場合に、3本の命令が必要なことを示しています。フィールド幅が大きければ、さらに多くの命令が必要です。Thumb-2コア技術では、この限界がありません。またARMコードでは、中間値のためのレジスタが1本余計に必要です。

付録