注意事項必読。
Raspberry Pi Pico 2 などの RP2350 系向け (他のマイコンに関しては確認していません)。Main Extension も含めすべて使えます。
- 0. 注意事項
- 1. データ処理命令 (Data Processing Instructions)
- 2. メモリアクセス命令 (Memory Access Instructions)
- 3. 分岐命令 (Branch Instructions)
- 4. システム・その他命令
- 5. DSP拡張命令
- 6. FPU拡張命令
0. 注意事項
- AI を使ってリファレンスから整理させています。
- 私が確認した上で公開していますが、間違いや不足する情報などがある可能性があります。
- 表にあるサイクル数は Cortex-M33 のものであり、Cortex-M23 ではありません。また、サイクル数に関しては ARM Cortex-M33 Devices Generic User Guide を参照していますが、間違っているケースがあるかもしれません。
1. データ処理命令 (Data Processing Instructions)
1.1 基本算術演算
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
ADD, ADDS |
2つのオペランドを加算します | 1 | S付きはAPSRフラグを更新します。 |
SUB, SUBS |
2つのオペランドを減算します | 1 | S付きはAPSRフラグを更新します。 |
ADC, ADCS |
キャリーフラグを含めて加算します | 1 | 多倍長演算に使用します。S付きはフラグを更新。 |
SBC, SBCS |
キャリーフラグをボローとして減算します | 1 | 多倍長演算に使用します。S付きはフラグを更新。 |
RSB, RSBS |
オペランドを逆にして減算します | 1 | S付きはフラグを更新します。 |
CMP |
2つのオペランドを比較(減算)し、フラグを更新します | 1 | 結果は破棄されます。 |
CMN |
2つのオペランドを比較(加算)し、フラグを更新します | 1 | 結果は破棄されます。 |
NEG, NEGS |
オペランドの符号を反転します (0 - value) | 1 | RSB Rd, Rn, #0 のエイリアスです。 |
1.2 乗算・除算
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
MUL, MULS |
32bit x 32bit乗算を行い、結果の下位32bitを返します | 1 | S付きはフラグを更新します |
MLA |
乗算後、第3オペランドを加算します (a * b + c) | 1 | |
MLS |
乗算後、第3オペランドを減算します (c - a * b) | 1 | |
UMULL |
符号なし32bit x 32bit乗算を行い、64bitの結果を返します | 3 | 結果は2つのレジスタに格納されます |
SMULL |
符号付き32bit x 32bit乗算を行い、64bitの結果を返します | 3 | 結果は2つのレジスタに格納されます |
UDIV |
符号なし32bit除算を行います | 2-11 | オペランドの値によってサイクル数が変動します |
SDIV |
符号付き32bit除算を行います | 2-11 | オペランドの値によってサイクル数が変動します |
1.3 論理・シフト演算
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
AND, ANDS |
ビット単位の論理積を計算します | 1 | S付きはフラグを更新 |
ORR, ORRS |
ビット単位の論理和を計算します | 1 | S付きはフラグを更新 |
EOR, EORS |
ビット単位の排他的論理和を計算します | 1 | S付きはフラグを更新 |
BIC, BICS |
ビットクリア(第2オペランドの反転と論理積)を行います | 1 | S付きはフラグを更新 |
TST |
論理積を計算し、フラグのみ更新します | 1 | 結果は破棄されます |
MOV, MOVS |
レジスタまたは即値をコピーします | 1 | S付きはフラグを更新 |
MVN, MVNS |
レジスタまたは即値をビット反転してコピーします | 1 | S付きはフラグを更新 |
LSL, LSLS |
論理左シフト | 1 | S付きはフラグを更新 |
LSR, LSRS |
論理右シフト | 1 | S付きはフラグを更新 |
ASR, ASRS |
算術右シフト(符号ビットを維持) | 1 | S付きはフラグを更新 |
ROR, RORS |
右ローテート | 1 | S付きはフラグを更新 |
1.4 ビットフィールド・バイト操作
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
BFC |
ビットフィールドをクリアします | 1 | Main Extension |
BFI |
ビットフィールドに値を挿入します | 1 | Main Extension |
SBFX |
符号付きビットフィールドを抽出します | 1 | Main Extension |
UBFX |
符号なしビットフィールドを抽出します | 1 | Main Extension |
REV |
32bitワード内のバイト順序を反転します | 1 | |
REV16 |
32bitワード内の各16bitハーフワードのバイト順序を反転します | 1 | |
REVSH |
16bitハーフワードのバイト順序を反転し、符号拡張します | 1 | |
RBIT |
32bitワード内のビット順序を反転します | 1 | Main Extension |
CLZ |
先行するゼロの数(最上位ビットからの連続した0の数)をカウントします | 1 |
2. メモリアクセス命令 (Memory Access Instructions)
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
LDR |
メモリから32bitワードをロードします | 2+ | |
LDRH |
メモリから16bitハーフワードを符号なしでロードします | 2+ | |
LDRSH |
メモリから16bitハーフワードを符号付きでロードします | 2+ | |
LDRB |
メモリから8bitバイトを符号なしでロードします | 2+ | |
LDRSB |
メモリから8bitバイトを符号付きでロードします | 2+ | |
STR |
メモリへ32bitワードをストアします | 2+ | |
STRH |
メモリへ16bitハーフワードをストアします | 2+ | |
STRB |
メモリへ8bitバイトをストアします | 2+ | |
LDM, LDMIA, LDMDB |
複数のレジスタをメモリからロードします | (n+1)+ | nはレジスタ数。POPのエイリアスとしても使用 |
STM, STMIA, STMDB |
複数のレジスタをメモリへストアします | (n+1)+ | nはレジスタ数。PUSHのエイリアスとしても使用 |
LDREX, LDREXH, LDREXB |
排他アクセス用のロード | 2+ | セマフォなどの排他制御に使用 |
STREX, STREXH, STREXB |
排他アクセス用のストア。成功/失敗を返します | 2+ | |
CLREX |
排他アクセスモニタをクリアします | 1 |
3. 分岐命令 (Branch Instructions)
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
B |
指定ラベルへ分岐します | 1-3 | |
B<cond> |
条件付きで分岐します (e.g., BEQ, BNE) | 1-3 | |
BL |
戻りアドレスをLRに格納して分岐(サブルーチンコール) | 1-3 | |
BLX |
レジスタ指定アドレスへ分岐し、LRにリターンアドレスを格納 | 1-3 | |
BX |
レジスタ指定アドレスへ分岐します | 1-3 | MOV PC, Rmのエイリアス |
CBZ |
レジスタが0なら分岐します | 1-3 | フラグに影響しません |
CBNZ |
レジスタが0でないなら分岐します | 1-3 | フラグに影響しません |
IT |
If-Then命令ブロック。最大4つの後続命令を条件付きで実行 | 1 | 非推奨: ARMv8-Aでは廃止。v8-Mでは互換性のために残存 |
TBB, TBH |
テーブル分岐。ジャンプテーブルを用いて分岐します | 3+ | Main Extension |
4. システム・その他命令
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
SVC |
スーパーバイザコール例外を発生させます | 3+ | OSのサービス呼び出しに使用。 |
MRS |
特殊レジスタから汎用レジスタへ値を移動します | 1-2 | |
MSR |
汎用レジスタから特殊レジスタへ値を移動します | 1-2 | |
CPSIE i, CPSID i |
PRIMASKレジスタを操作し、割り込みを有効/無効化します | 2 | |
CPSIE f, CPSID f |
FAULTMASKレジスタを操作し、フォールトを有効/無効化します | 2 | |
WFI |
割り込みを待機して低電力モードに入ります | 実装依存 | |
WFE |
イベントを待機して低電力モードに入ります | 実装依存 | |
SEV |
マルチコアシステムでイベントを送信します | 1 | |
ISB |
命令同期バリア。パイプラインをフラッシュします | 3 | |
DSB |
データ同期バリア。メモリ操作の完了を待ちます | 実装依存 | |
DMB |
データメモリバリア。メモリアクセスの順序を保証します | 実装依存 | |
NOP |
何も行いません(No Operation) | 1 | |
BKPT |
ブレークポイント例外を発生させます | 3+ | デバッグ用。 |
5. DSP拡張命令
5.1 SIMD (Single Instruction, Multiple Data) 演算命令
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
SADD8, UADD8 |
4組の8bitデータに対して並列に符号付き/符号なし加算を行います | 1 | APSRのGE[3:0]フラグに各レーンのキャリー/ボローがセットされます |
SSUB8, USUB8 |
4組の8bitデータに対して並列に符号付き/符号なし減算を行います | 1 | APSRのGE[3:0]フラグに各レーンのキャリー/ボローがセットされます |
SADD16, UADD16 |
2組の16bitデータに対して並列に符号付き/符号なし加算を行います | 1 | APSRのGE[1:0]フラグに各レーンのキャリー/ボローがセットされます |
SSUB16, USUB16 |
2組の16bitデータに対して並列に符号付き/符号なし減算を行います | 1 | APSRのGE[1:0]フラグに各レーンのキャリー/ボローがセットされます |
SASX, UASX |
2組の16bitデータをクロスして加算/減算します (e.g., Rd.H0=Rn.H0+Rm.H1) | 1 | GEフラグが更新されます。ASX = Add and Subtract with Exchange. |
SSAX, USAX |
2組の16bitデータをクロスして減算/加算します (e.g., Rd.H0=Rn.H0-Rm.H1) | 1 | GEフラグが更新されます。SAX = Subtract and Add with Exchange. |
SHADD8, UHADD8 |
4組の8bitデータを並列加算し、結果を1/2にします(右シフト) | 1 | 平均化処理に利用します |
SHADD16, UHADD16 |
2組の16bitデータを並列加算し、結果を1/2にします(右シフト) | 1 | 平均化処理に利用します |
SHSUB8, UHSUB8 |
4組の8bitデータを並列減算し、結果を1/2にします(右シフト) | 1 | |
SHSUB16, UHSUB16 |
2組の16bitデータを並列減算し、結果を1/2にします(右シフト) | 1 | |
SEL |
APSRのGEフラグに基づき、2つのソースレジスタのバイトを選択して結合します | 1 | SIMD演算後のバイト選択に利用します |
5.2 サチュレーション(飽和)演算命令
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
QADD |
符号付き飽和加算を行います | 1 | |
QSUB |
符号付き飽和減算を行います | 1 | |
QADD8, UADD8 |
4組の8bitデータに対して並列に符号付き/符号なし飽和加算を行います | 1 | |
QSUB8, USUB8 |
4組の8bitデータに対して並列に符号付き/符号なし飽和減算を行います | 1 | |
QADD16, UADD16 |
2組の16bitデータに対して並列に符号付き/符号なし飽和加算を行います | 1 | |
QSUB16, USUB16 |
2組の16bitデータに対して並列に符号付き/符号なし飽和減算を行います | 1 | |
QASX, UQASX |
2組の16bitデータをクロスして符号付き/符号なし飽和加算/減算を行います | 1 | |
QSAX, UQSAX |
2組の16bitデータをクロスして符号付き/符号なし飽和減算/加算を行います | 1 | |
SSAT |
符号付き値を指定したビット幅に飽和させます | 1 | |
USAT |
符号なし値を指定したビット幅に飽和させます | 1 |
5.3 乗算・積和演算 (MAC) 命令
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
SMLAD |
2組の16bit乗算を並列で行い、その2つの結果と第3オペランド(アキュムレータ)を加算します | 1 | Rd = Ra + (Rn.H0*Rm.H0) + (Rn.H1*Rm.H1) |
SMLADX |
SMLADの片方のオペランドを交換したバージョンです |
1 | Rd = Ra + (Rn.H0*Rm.H1) + (Rn.H1*Rm.H0) |
SMLSD |
2組の16bit乗算を並列で行い、片方を加算、もう片方を減算します | 1 | Rd = Ra + (Rn.H0*Rm.H0) - (Rn.H1*Rm.H1) |
SMLSDX |
SMLSDの片方のオペランドを交換したバージョンです |
1 | Rd = Ra + (Rn.H0*Rm.H1) - (Rn.H1*Rm.H0) |
SMLALD |
SMLADの64bitアキュムレータ版です |
3 | 結果は2つのレジスタに格納されます |
SMLALDX |
SMLADXの64bitアキュムレータ版です |
3 | |
SMLSLD |
SMLSDの64bitアキュムレータ版です |
3 | |
SMLSLDX |
SMLSDXの64bitアキュムレータ版です |
3 | |
SMULBB, SMULBT, SMULTB,SMULTT` |
2つのレジスタの下位/上位16bitを選択して符号付き16x16乗算を行います | 1 | |
SMUAD |
2組の16bit乗算を並列で行い、その2つの結果を加算します | 1 | アキュムレーションなし |
SMUADX |
SMUADのオペランド交換版です |
1 | |
SMUSD |
2組の16bit乗算を並列で行い、片方からもう片方を減算します | 1 | |
SMUSDX |
SMUSDのオペランド交換版です |
1 | |
SMMUL |
32x32bit乗算を行い、結果の上位32bitを返します(丸め付き) | 1 | Q1.31形式などの小数演算に利用 |
5.4 パッキング・アンパッキング・拡張命令
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
PKHBT |
2つのレジスタから、片方の下位16bitと、もう片方の上位16bitを結合します | 1 | |
PKHTB |
2つのレジスタから、片方の上位16bitと、もう片方の下位16bitを結合します | 1 | |
SXTAB |
8bit値を符号拡張して32bitにし、別の値に加算します | 1 | |
SXTAH |
16bit値を符号拡張して32bitにし、別の値に加算します | 1 | |
SXTB16 |
2組の8bit値をそれぞれ16bitに符号拡張します | 1 | |
UXTAB |
8bit値をゼロ拡張して32bitにし、別の値に加算します | 1 | |
UXTAH |
16bit値をゼロ拡張して32bitにし、別の値に加算します | 1 | |
UXTB16 |
2組の8bit値をそれぞれ16bitにゼロ拡張します | 1 |
6. FPU拡張命令
6.1 データ転送命令 (Load/Store/Move)
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
VLDR |
メモリからFPUレジスタ(S0-S31)に単精度データをロードします | 2+ | メモリのウェイト数に応じて増加します |
VSTR |
FPUレジスタの単精度データをメモリにストアします | 2+ | メモリのウェイト数に応じて増加します |
VLDM |
メモリから複数のFPUレジスタをロードします | (n+1)+ | nはレジスタ数 |
VSTM |
複数のFPUレジスタをメモリにストアします | (n+1)+ | nはレジスタ数 |
VMOV |
FPUレジスタ間、または汎用レジスタとFPUレジスタ間でデータを移動します | 1 | VMOV.F32 Sd, Sm や VMOV Rd, Sn など |
6.2 算術演算命令 (Arithmetic Instructions)
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
VADD.F32 |
2つの単精度浮動小数点数を加算します | 1 | |
VSUB.F32 |
2つの単精度浮動小数点数を減算します | 1 | |
VMUL.F32 |
2つの単精度浮動小数点数を乗算します | 1 | |
VNMUL.F32 |
2つの単精度浮動小数点数を乗算し、結果の符号を反転します | 1 | VNEG(VMUL) と同等 |
VDIV.F32 |
2つの単精度浮動小数点数を除算します | 14 | FPU命令の中で最も時間のかかる処理の一つです |
VSQRT.F32 |
単精度浮動小数点数の平方根を計算します | 14 | VDIV と同様に、完了まで多くのサイクルを要します |
VMLA.F32 |
乗算と加算を結合した演算を行います (a + (b * c)) | 1 | Fused MAC。VADD と VMUL を個別に行うより高精度・高速です。レイテンシは3サイクル |
VMLS.F32 |
乗算と減算を結合した演算を行います (a - (b * c)) | 1 | Fused MAC。レイテンシは3サイクル |
VNMLA.F32 |
VMLA の結果の符号を反転します | 1 | |
VNMLS.F32 |
VMLS の結果の符号を反転します | 1 | |
VABS.F32 |
単精度浮動小数点数の絶対値を取得します | 1 | |
VNEG.F32 |
単精度浮動小数点数の符号を反転します | 1 |
6.3 変換命令 (Conversion Instructions)
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
VCVT.S32.F32 |
単精度浮動小数点数を符号付き32bit整数に変換します | 1 | 丸めモードはFPSCRで設定できます |
VCVT.U32.F32 |
単精度浮動小数点数を符号なし32bit整数に変換します | 1 | |
VCVT.F32.S32 |
符号付き32bit整数を単精度浮動小数点数に変換します | 1 | |
VCVT.F32.U32 |
符号なし32bit整数を単精度浮動小数点数に変換します | 1 |
(注: Cortex-M33はFPv5-SPのため、半精度 (F16) や倍精度 (F64) へのハードウェア変換命令は通常サポートされません)
6.4 比較命令 (Comparison Instructions)
| 命令 | 説明 | サイクル数 (Cortex-M33) |
補足 |
|---|---|---|---|
VCMP.F32 |
2つの単精度浮動小数点数を比較します | 1 | 結果はAPSRではなく、FPSCRの条件フラグにセットされます |
VCMPE.F32 |
VCMP と同様ですが、NaNをオペランドに持つ場合に例外を発生させます | 1 |
VCMP命令実行後の注意点:
VCMP命令の結果を使って条件分岐を行うには、VCMP の直後に必ず VMRS APSR_nzcv, FPSCR 命令を実行し、FPUのステータスを汎用レジスタのフラグ(APSR)にコピーする必要があります。その後で B<cond> 命令を使用します。
VCMP.F32 S0, S1 @ S0とS1を比較 -> 結果はFPSCRへ VMRS APSR_nzcv, FPSCR @ FPSCRのフラグをAPSRにコピー BEQ equal_label @ APSRを読んで条件分岐