演算命令 ()

演算命令とは四則演算、論理演算、比較などを行う命令群です。 ARM64 では演算命令に3つのレジスタを指定することができます。 3番目の位置には、レジスタ以外に定数やレジスタの内容をシフトした値を指定することもできます。

    add  x1, x2, x3           // x1 = x2 + x3

上の例では、x1 はデスティネーションレジスタ (Rd) で演算結果が最終的に代入されます。 x2 は第1ソースオペランドレジスタ (Rn) 、x3 の部分は第2オペランドと呼んで、 レジスタ、メモリアドレス、定数値を指定できます。

    // すべてを同じレジスタにすることも可能
    add  x1, x1, x1           // x1 = x1 + x1 = x1 * 2

演算命令の場合、第2オペランドは「そのオペランドレジスタの内容をシフトしたもの」 という指定が可能で、次のように1命令でシフト演算まで実行することができます。

    add  x1, x2, x3 LSL #20   // x1 = x2 + (x3 << 20)

シフト演算 には LSL、LSR 、ASR を指定することができます。

アドレッシングモード

以下の加減算の命令のアドレッシングモードには、単純なレジスタ指定、シフトレジスタ、イミディエート(定数指定)、 拡張レジスタの4種類がありますが、命令によって使えるアドレッシングモードが 異なっているため、注意が必要です。

ニーモニックの末尾が S の命令は、演算結果にしたがって条件フラグが更新されます。

アドレッシング
演算レジスタ シフトレジスタイミディエート拡張レジスタ
加算ADD ADD ADD
加算ADDS / CMN ADDS / CMN ADDS / CMN
減算SUB / NEG SUB / NEGS SUB
減算SUBS / CMP SUBS / CMP SUBS / CMP
論理積AND AND
論理積ANDS / TST ANDS / TST
ビットクリアBIC
ビットクリアBICS
否定論理和ORN
論理和ORR ORR
否定排他的論理和EON
排他的論理和EOR EOR
キャリー込み加算ADC
キャリー込み加算SBC

イミディエート(定数指定)

加減算命令の定数指定は以下の形式です。論理演算のイミディエートアドレッシングは後述します。

    ADD   Xd, Xn, #uimm12 {, LSL #12}
    ADD   Wd, Wn, #uimm12 {, LSL #12}

この命令はレジスタ(Rn)が格納している値に定数を加算または減算して、指定したレジスタ (Rd) に書き込みます。 定数は12ビットの左シフト(4096倍)を指定することもできます。定数値は 0 から 4095 の範囲です。定数のシフトを指定する場合は LSL #12 を加えます。

シフトレジスタ(シフト済みレジスタ指定)

    ADD   Xd, Xn, Xm {, shift #amount}
    ADD   Wd, Wn, Wm {, shift #amount}

Rn と Rm を加えて、Rd に設定します。 Rm の内容は演算前にシフト演算(LSL、LSR 、ASR)を指定することができます。シフト量は64bitレジスタでは 0 - 63、32bitレジスタでは 0 - 31 の範囲となります。

拡張レジスタ

レジスタのデータを 8 ビットから 64 ビットへ符号付拡張する等が可能なアドレッシングモードです。

    ADD   Xd, Xn, Wm {,extend {#amount}}
    ADD   Xd, Xn, Xm {,extend {#amount}}

この命令はレジスタ(Rn)が格納している値に符号拡張またはゼロ拡張したレジスタ(Rm)の値を加算または減算して、指定したレジスタ (Rd) に書き込みます。データ拡張後に左シフトする量を 0 から 4 の範囲で指定できます。 拡張するデータは byte、halfword、word、doubleword が可能です。

option extend意味
32 bit 64 bit
000 UXTBUXTB 8bitから無符号拡張
001 UXTHUXTH16bitから無符号拡張
010 LSL/UXTWUXTW32bitから無符号拡張
011 UXTXLSL/UXTX 64bitから無符号拡張
100 SXTBSXTB 8bitから符号付拡張
101 SXTHSXTH16bitから符号付拡張
110 SXTWSXTW32bitから符号付拡張
111 SXTXSXTX64bitから符号付拡張

拡張後に適用する左シフト量を 0 - 4 の範囲で指定できます。LSLの場合は必須です。



加減算

単純な加減算はアドレッシングとしてシフトレジスタ、イミディエート、拡張レジスタの3種類を使うことができます。

ADD

レジスタとレジスタ、またはレジスタと定数の加算を行います。演算結果で条件フラグ (NZCV レジスタ) は変化しません。

    ADD    Xd, Xn, Xm {,shift #amount}
    ADD    Wd, Wn, Wm {,shift #amount}

    ADD    Xd|SP,  Xn|SP,  #uimm12 {, LSL #12}
    ADD    Wd|WSP, Wn|WSP, #uimm12 {, LSL #12}

    ADD    Xd|SP,  Xn|SP,  Rm {,extend {#amount}}
    ADD    Wd|WSP, Wn|WSP, Rm {,extend {#amount}}

ADDS

レジスタとレジスタ、またはレジスタと定数の加算を行います。演算結果に応じて条件フラグ (NZCV レジスタ) のビットを更新します。

    ADDS   Xd, Xn, Xm {,shift #amount}
    ADDS   Wd, Wn, Wm {,shift #amount}

    ADDS   Xd|SP,  Xn|SP,  #uimm12 {,LSL #12}
    ADDS   Wd|WSP, Wn|WSP, #uimm12 {,LSL #12}

    ADDS   Xd|SP,  Xn|SP,  Rm {,extend {#amount}}
    ADDS   Wd|WSP, Wn|WSP, Rm {,extend {#amount}}

SUB

レジスタからレジスタ、またはレジスタから定数を減算します (Rd = Rn - Rm|imm)。 演算結果で条件フラグ (NZCV レジスタ) は変化しません。

    SUB    Xd, Xn, Xm {,shift #amount}
    SUB    Wd, Wn, Wm {,shift #amount}

    SUB    Xd|SP,  Xn|SP,  #uimm12 {,LSL #12}
    SUB    Wd|WSP, Wn|WSP, #uimm12 {,LSL #12}

    SUB    Xd|SP,  Xn|SP,  Rm {,extend {#amount}}
    SUB    Wd|WSP, Wn|WSP, Rm {,extend {#amount}}

NEG

レジスタの値を正負反転します(Rd = - Rm)。演算結果で条件フラグ (NZCV レジスタ) は変化しません。 この命令はアセンブラで SUB に翻訳されます。

    NEG    Xd, Xm {,shift #amount}      // SUB   Xd, XZR, Xm {,shift #amount} と同じ
    NEG    Wd, Wm {,shift #amount}      // SUB   Xd, WZR, Xm {,shift #amount} と同じ

SUBS

レジスタからレジスタ、またはレジスタから定数を減算します(Rd = Rn - Rm|imm)。演算結果に応じて条件フラグ (NZCV レジスタ) のビットを更新します。キャリーフラグはボローが発生しない (Rn ≧ Rm) 場合に 1、ボローが発生する (Rn < Rm) 場合は 0 となります。

内部的には、減数の1の補数を求め、キャリーフラグを 1 にした後、キャリー込み加算(ADCS) を行っているようです。 減数の 1 の補数にキャリーフラグの 1 を加えると 2 の補数(減数 * -1)を求めたことになり、被減数と加算することで結果的に「被減数 - 減数」という減算となります。「被減数 ≧ 減数」のとき、「被減数 + (減数 * -1)」の符号付き加算ではキャリーセットされ、「被減数 < 減数」のとき、「被減数 + (減数 * -1)」の符号付き加算ではキャリークリアされます。 分かり難いですが、以上がボローが発生するとキャリーフラグが 0 になる理由です。

    SUBS   Xd, Xn, Xm {,shift #amount}
    SUBS   Wd, Wn, Wm {,shift #amount}

    SUBS   Xd|SP,  Xn|SP,  #uimm12 {, LSL #12}
    SUBS   Wd|WSP, Wn|WSP, #uimm12 {, LSL #12}

    SUBS   Xd|SP,  Xn|SP,  Rm {,extend {#amount}}
    SUBS   Wd|WSP, Wn|WSP, Rm {,extend {#amount}}

NEGS

レジスタの値を正負反転します(Rd = - Rm)。演算結果に応じて条件フラグ(NZCV レジスタ) のビットを更新します。 この命令はアセンブラで SUBS に翻訳されます。

    NEGS   Xd, Xm {,shift #amount}      // SUBS Xd, XZR, Xm {,shift #amount} と同じ 
    NEGS   Wd, Wm {,shift #amount}      // SUBS Wd, WZR, Wm {,shift #amount} と同じ 

CMP

レジスタからレジスタ、またはレジスタから定数の減算を行って、演算結果に対応した条件フラグを設定します。 減算算結果自身は使用しません。 この命令はアセンブラで SUBS に翻訳されます。

    CMP  Wn|WSP, #imm {,shift}           // SUBS WZR, Wn|WSP, #imm {,shift} と同じ
    CMP  Xn|SP, #imm {,shift}            // SUBS XZR, Xn|SP, #imm {,shift} と同じ

    CMP  Wn|WSP, Wm {,extend {#amount}}  // SUBS WZR, Wn|WSP, Wm {,extend {#amount}} と同じ
    CMP  Xn|SP, R m {,extend {#amount}}  // SUBS XZR, Xn|SP, R m {,extend {#amount}} と同じ

    CMP  Wn, Wm {,shift #amount}         // SUBS WZR, Wn, Wm {,shift #amount} と同じ
    CMP  Xn, Xm {,shift #amount}         // SUBS XZR, Xn, Xm {,shift #amount} と同じ

CMN

レジスタ Rm または定数に -1 を乗じたものとレジスタ Rn またはスタックポインタ(SP)を比較します。 この命令はアセンブラで ADDS に翻訳されます。

  CMN   Wn|WSP, #imm {,shift}            // ADDS WZR, Wn|WSP, #imm {,shift}と同じ
  CMN   Xn|SP, #imm {,shift}             // ADDS XZR, Xn|SP, #imm {,shift}と同じ

  CMN   Wn|WSP, Wm {,extend {#amount}}   // ADDS WZR, Wn|WSP, Wm {,extend {#amount}}と同じ
  CMN   Xn|SP,  Rm {,extend {#amount}}   // ADDS XZR, Xn|SP, Rm {,extend {#amount}}と同じ

  CMN   Wn, Wm {,shift #amount}          // ADDS WZR, Wn, Wm {,shift #amount}と同じ
  CMN   Xn, Xm {,shift #amount}          // ADDS XZR, Xn, Xm {,shift #amount}と同じ

命令エンコード

命令 313029 282726 252423 222120 191817 161514 131211 100908 070605 040302 0100
ADD (shifted) z 0 0 0 1 0 1 1 shift 0 Rm imm6 (0-63) Rn Rt
ADD (imm12) z 0 0 1 0 0 0 1 shift imm12 (0-4095) Rn Rt
ADD (extended) z 0 0 0 1 0 1 1 0 0 1 Rm option imm3 Rn Rt
SUB (shifted) z 1 0 0 1 0 1 1 shift 0 Rm imm6 (0-63) Rn Rt
SUB (imm12) z 1 0 1 0 0 0 1 shift imm12 (0-4095) Rn Rt
SUB (extended) z 1 0 0 1 0 1 1 0 0 1 Rm option imm3 Rn Rt
ADDS (shifted) z 0 1 0 1 0 1 1 shift 0 Rm imm6 (0-63) Rn Rt
ADDS (imm12) z 0 1 1 0 0 0 1 shift imm12 (0-4095) Rn Rt
ADDS (extended) z 0 1 0 1 0 1 1 0 0 1 Rm option imm3 Rn Rt
SUBS (shifted) z 1 1 0 1 0 1 1 shift 0 Rm imm6 (0-63) Rn Rt
SUBS (imm12) z 1 1 1 0 0 0 1 shift imm12 (0-4095) Rn Rt
SUBS (extended) z 1 1 0 1 0 1 1 0 0 1 Rm option imm3 Rn Rt


キャリー込の加減算

加減算でオーバーフロー (キャリー、桁あふれ) やアンダーフロー (ボロー、桁借り) のために NZCV レジスタの C ビットがキャリーとして使用されます。

アドレッシングモード

キャリー込の加減算のアドレッシングは、単純なレジスタ指定のみです。

アドレッシング
演算レジスタ シフトレジスタイミディエート拡張レジスタ
キャリー込み加算ADC
キャリー込み加算SBC

キャリー込の加算

キャリーを含めて加算します。 キャリーフラグが 1 のときに 1 が余分に加算されます。 複数のレジスタにわたる(多倍長)加算に使います。

    ADC     Rd, Rn, Rm
    ADCS    Rd, Rn, Rm

キャリーフラグとキャリー込の減算を試してみます。stdio.sdebug.sを置いたディレクトリに、次のコードを adc.s というファイル名で作成します。 64ビットの大きな数値(0x8000000000000000) を 2 つ加算して、フラグを表示、0 と 0 をキャリー込み加算して結果を表示するプログラムです。 加算でキャリー (桁あふれ) が発生、「0 + 0 + キャリー」の結果は 1 になると予想されます。

.include        "debug.s"
.text
.global _start
_start:
         mov    x1, #0x8000000000000000
         adds   x0, x1, x1        // x0 = x1 + x1
         PRINTFLAGS               // print flags
         adc    x0, xzr, xzr      // x0 = 0 + 0

         bl     PrintLeft         // print x0
         bl     NewLine
         bl     Exit

アセンブル、リンク、実行してみます。

as -o adc.o adc.s
ld -o adc adc.o
./adc

nZCV
1

予想通り、結果は 1 になりました。debug.s の PRINTFLAGS マクロはキャリーフラグが c の場合は 0、C の場合は 1 を表示します。 結果は「C」となっているため キャリーで 「Carry = 1」となることが確認できます。

キャリー込の減算

キャリー(ボロー)を含めて減算します。 キャリーフラグが 0 のときに 1 が余分に引かれます(参考)。複数のレジスタにわたる(多倍長)減算に使います。

    SBC     Rd, Rn, Rm
    SBCS    Rd, Rn, Rm

キャリーフラグとキャリー込の減算を試してみます。stdio.sdebug.sを置いたディレクトリに、次のコードを sbc.s というファイル名で作成します。 0 から 1 を引いて、フラグを表示、0 から 0 をキャリー込み減算して結果を表示するプログラムです。 「0 - 1」でボロー (桁借り) が発生、「0 - 0 - ボロー」の結果は -1 になると予想されます。

.include        "debug.s"
.text
.global _start

_start:  mov    x1, #1
         subs   x0, xzr, x1       // x0 = 0 - 1
         PRINTFLAGS               // print flags
         sbc    x0, xzr, xzr      // x0 = 0 - 0

         bl     PrintLeft         // print x0
         bl     NewLine
         bl     Exit

アセンブル、リンク、実行してみます。

as -o sbc.o sbc.s
ld -o sbc sbc.o
./sbc

Nzcv
-1

予想通り、結果は -1 です。 debug.s の PRINTFLAGS マクロはキャリーフラグが c の場合は 0、C の場合は 1 を表示します。 結果は「c」となっているため ボローの場合に 「Carry=0」となることが分かります。

命令エンコード

命令 313029 282726 252423 222120 191817 161514 131211 100908 070605 040302 0100
ADC z 0 0 1 1 0 1 0 0 0 0 Rm 0 0 0 0 0 0 Rn Rt
ADCS z 0 1 1 1 0 1 0 0 0 0 Rm 0 0 0 0 0 0 Rn Rt
SBC z 1 0 1 1 0 1 0 0 0 0 Rm 0 0 0 0 0 0 Rn Rt
SBCS z 1 1 1 1 0 1 0 0 0 0 Rm 0 0 0 0 0 0 Rn Rt



乗算命令

乗算命令は32ビットまたは64ビットの乗算を行います。積和命令 (MADD) は乗算と加算を同時に行う命令で、積差命令(MSUB)は乗算と減算を同時に行う命令です。32ビット同士の乗算でも結果は 32 ビットで返り、64ビット同士の乗算でも結果は 64 ビットで返ります。乗算結果の上位ビットを取得するための命令として、SMULH(符号付)、UMULH(符号なし)という 専用命令が用意されています。下位ビットは符号付き(2の補数)、符号無しのどちらの場合も同じになります。

倍精度積算(multiply long)命令は、32ビットの整数積算を行い、64ビットの結果を返します。積算と積和(64ビット整数の加算も行う)、符号付きと符合無し演算があり、計4種類の命令(UMULL,UMULAL,SMULL,SMULAL)があります。

MADD/MUL

積和(Multiply-Add)演算は演算は2つのレジスタの積 (Rn * Rm) をレジスタ Ra に加算して、結果をレジスタ Rd に格納します。 MUL命令は加算するレジスタを ゼロレジスタにしたMADD命令です。

    MADD   Wd, Wn, Wm, Wa  // Wd = Wa + (Wn * Wm)
    MADD   Xd, Xn, Xm, Xa  // Xd = Xa + (Xn * Xm)

    MUL    Wd, Wn, Wm      // MADD Wd, Wn, Wm, WZR の別名
    MUL    Xd, Xn, Xm      // MADD Xd, Xn, Xm, XZR の別名

MSUB/MNEG

積差(Multiply-Subtract)演算は2つのレジスタの積 (Rn * Rm) をレジスタ Ra から減算して、結果をレジスタ Rd に格納します。MNEG命令は減算する対象の レジスタをゼロレジスタにしたMSUB命令です。

    MSUB   Wd, Wn, Wm, Wa  // Wd = Wa - (Wn * Wm)
    MSUB   Xd, Xn, Xm, Xa  // Xd = Xa - (Xn * Xm)

    MNEG   Wd, Wn, Wm      // MSUB Wd, Wn, Wm, WZR の別名
    MNEG   Xd, Xn, Xm      // MSUB Xd, Xn, Xm, XZR の別名

SMULH

符号付上位乗算 (Signed Multiply High) は 2 つの 64 ビットレジスタ Xn と Xm を乗算し、その 128 ビットの乗算結果の上位 64 ビットをレジスタ (Xd) に書き込みます。

    SMULH  Xd, Xn, Xm

UMULH

符号なし上位乗算 (Unsigned Multiply High) は 2 つの 64 ビットレジスタを乗算し、その 128 ビットの乗算結果の上位 64 ビットをレジスタに書き込みます。

    UMULH  Xd, Xn, Xm

SMADDL/SMUL

2 つの 32 ビットのレジスタ Wn とWm の積を 64 ビットのレジスタ Xa と加算し、その結果を 64 ビットのレジスタ Xd に書き込みます。

    SMADDL Xd, Wn, Wm, Xa
    SMULL  Xd, Wn, Wm      // SMADDL Xd, Wn, Wm, XZR の別名

UMADDL/UMULL

2 つの 32 ビットのレジスタ Wn とWm の積を 64 ビットのレジスタ Xa と加算し、その結果を 64 ビットのレジスタ Xd に書き込みます。

    UMADDL Xd, Wn, Wm, Xa
    UMULL  Xd, Wn, Wm      // UMADDL Xd, Wn, Wm, XZR の別名

SMSUBL/SMNEGL

64 ビットのレジスタ Xa から 32ビットレジスタWn とWm の積を減算し、その結果を 64 ビットのレジスタ Xd に書き込みます。

    SMSUBL Xd, Wn, Wm, Xa  // Xd = Xa - (Wn * Wm)
    SMNEGL Xd, Wn, Wm      // SMSUBL Xd, Wn, Wm, XZR の別名

UMSUBL/UMNEGL

64 ビットのレジスタ Xa から 32ビットレジスタWn とWm の積を減算し、その結果を 64 ビットのレジスタ Xd に書き込みます。

    UMSUBL Xd, Wn, Wm, Xa
    UMNEGL Xd, Wn, Wm      // UMSUBL Xd, Wn, Wm, XZR の別名

命令エンコード

命令 313029 282726 252423 222120 191817 161514 131211 100908 070605 040302 0100
MADD z 0 0 1 1 0 1 1 0 0 0 Rm 0 Ra Rn Rd
MUL z 0 0 1 1 0 1 1 0 0 0 Rm 1 1 1 1 1 1 Rn Rt
MSUB z 0 0 1 1 0 1 1 0 0 0 Rm 1 Ra Rn Rd
MNEG z 0 0 1 1 0 1 1 0 0 0 Rm 1 1 1 1 1 1 Rn Rd
xMADDL 1 0 0 1 1 0 1 1 U 0 1 Rm 0 Ra Rn Rd
xMSUBL 1 0 0 1 1 0 1 1 U 0 1 Rm 1 Ra Rn Rd
xMULH 1 0 0 1 1 0 1 1 U 1 0 Rm 0 (1 1 1 1 1) Rn Rd



除算命令

除算命令は32ビットまたは64ビットの整数の除算を行います。商はゼロに向かって丸められます。SDIV(符号付整数) と UDIV(符号なし整数)の2つの命令があります。 0 で除算した場合は、エラーとはならず除算結果が 0 となります。

    Rd = Rn / Rm

剰余は除算命令では計算されないため、MSUB命令を使って求めます。

    mov     x2, #37
    mov     x3, #10
    sdiv    x0, x2, x3     // x0 = 37 / 10     --> 3
    msub    x4, x0, x3, x2 // x4 = 37 - 3 * 10 --> 7

SDIV

SDIV は32ビットまたは64ビットの符号付整数の除算を行います。

    SDIV  Wd, Wn, Wm
    SDIV  Xd, Xn, Xm

最も小さい負の整数を -1 で除算すると符号付整数の範囲を超えますが、オーバーフローは発生せず、最も小さい負の整数がそのまま結果に入ります。 下の例は 64ビットの最も小さい整数 -9223372036854775808 を -1 で割った 場合に 9223372036854775808 にならず、-9223372036854775808 になることを 確認できます。 64 ビットで表現できるもっとも大きい整数 9223372036854775807 より大きくなるためです。

    mov     x5, #0x8000000000000000  // -9223372036854775808
    mov     x6, #-1                  // -1
    sdiv    x0, x5, x6               // x0 = -9223372036854775808

32ビットでも同様に -2147483648 を -1 で割ると -2147483648 が返ります。


UDIV

UDIV は32ビットまたは64ビットの符号なし整数の除算を行います。

    UDIV  Wd, Wn, Wm
    UDIV  Xd, Xn, Xm

命令エンコード

命令 313029 282726 252423 222120 191817 161514 131211 100908 070605 040302 0100
SDIV z 0 0 1 1 0 1 0 1 1 0 Rm 0 0 0 0 1 1 Rn Rd
UDIV z 0 0 1 1 0 1 0 1 1 0 Rm 0 0 0 0 1 0 Rn Rd



論理演算

アドレッシングモード

論理演算命令のアドレッシングモードには、シフトレジスタ、イミディエート(定数指定)、 拡張レジスタの3種類がありますが、命令によって使えるアドレッシングモードが 異なっているため、注意が必要です。

アドレッシング
演算 シフトレジスタイミディエート拡張レジスタ
論理積AND AND
論理積ANDS / TST ANDS / TST
ビットクリアBIC
ビットクリアBICS
否定論理和ORN
論理和ORR ORR
否定排他的論理和EON
排他的論理和EOR EOR
イミディエート

汎用レジスタと即値を論理演算して、結果を汎用レジスタまたはスタックポインタに設定します。 即値は、ビットマスク用の32ビットまたは64ビットのパターンを指定できます。 2、4、8、16、32、64ビットを単位として、連続した 0 または 1 のパターンを繰り返した値を指定できます。例えば 0x000000001ffffc00、0xfffffffffc0fffff、0x007f007f007f007f、0x7070707070707070、0x5555555555555555といった即値です。 不可能なパターンを指定するとアセンブラで「Error: immediate out of range at operand 3」というエラーを起こします。

    AND Wd|WSP, Wn, #imm
    AND Xd|SP,  Xn, #imm
シフトレジスタ

汎用レジスタ Rn と汎用レジスタ Rm 間の演算を行い、結果を汎用レジスタに格納します。オプションで Rm レジスタの値に対してシフト演算を指定することができます。デフォルトは LSL になり、LSR、ASR、または ROR も指定できます。

    AND    Wd, Wn, Wm {,shift #amount}
    AND    Xd, Xn, Xm {,shift #amount}

AND

レジスタとレジスタ、またはレジスタと定数のビット単位の論理積を実行して、結果をレジスタに書き込みます。演算結果で条件フラグ (NZCV レジスタ) は変化しません。

    AND    Wd|WSP, Wn, #imm
    AND    Wd, Wn, Wm {,shift #amount}

    AND    Xd|SP, Xn, #imm
    AND    Xd, Xn, Xm {,shift #amount}

ANDS

レジスタとレジスタ、またはレジスタと定数のビット単位の論理積を実行して、結果をレジスタに書き込みます。演算結果に応じて条件フラグ (NZCV レジスタ) のビットを更新します。

    ANDS  Wd|WSP, Wn, #imm
    ANDS  Wd, Wn, Wm {,shift #amount}

    ANDS  Xd|SP, Xn, #imm
    ANDS  Xd, Xn, Xm {,shift #amount}

TST

レジスタとレジスタ、またはレジスタと定数のビット単位の論理積を実行して、演算結果に応じて条件フラグ (NZCV レジスタ) のビットを更新します。 この命令はアセンブラで ANDS に翻訳されます。

    TST    Wn, #imm                 // ANDS   WZR, Xn, #imm と同じ
    TST    Wn, Wm {,shift #amount}  // ANDS  WZR, Wn, Wm {,shift #amount} と同じ

    TST    Xn, #imm                 // ANDS   XZR, Xn, #imm と同じ
    TST    Xn, Xm {,shift #amount}  // ANDS  XZR, Xn, Xm {,shift #amount} と同じ

ORR

レジスタとレジスタ、またはレジスタと定数のビット単位の論理和を実行して、結果をレジスタに書き込みます。 演算結果で条件フラグ (NZCV レジスタ) は変化しません。

    ORR  Wd|WSP, Wn, #imm
    ORR  Wd, Wn, Wm {,shift #amount}

    ORR  Xd|SP, Xn, #imm
    ORR  Xd, Xn, Xm {,shift #amount}

ORN

Rn レジスタの値と、 Rm レジスタを反転した値との間で論理和を求め、 結果を Rd レジスタに書き込みます。オプションで Rm レジスタの値に対して シフト演算を指定することができます。デフォルトは LSL になり、LSR、ASR、 または ROR も指定できます。 演算結果で条件フラグ (NZCV レジスタ) は変化しません。

    ORN  Xd, Xn, Xm {,shift #amount}
    ORN  Wd, Wn, Wm {,shift #amount}

EOR

レジスタとレジスタ、またはレジスタと定数のビット単位の排他的論理和を実行して、結果をレジスタに書き込みます。 演算結果で条件フラグ (NZCV レジスタ) は変化しません。

    EOR  Wd|WSP, Wn, #imm
    EOR  Wd, Wn, Wm {,shift #amount}

    EOR  Xd|SP, Xn, #imm
    EOR  Xd, Xn, Xm {,shift #amount}

EON

Rn レジスタの値と、 Rm レジスタを反転した値との間で論理和を求め、 結果を Rd レジスタに書き込みます。オプションで Rm レジスタの値に対して シフト演算を指定することができます。デフォルトは LSL になり、LSR、ASR、 または ROR も指定できます。

    EON  Xd, Xn, Xm {,shift #amount}
    EON  Wd, Wn, Wm {,shift #amount}

BIC

BIC命令は、ビット単位で指定したビットをクリアします。 Rn レジスタの値と、 Rm レジスタを反転した値との間で論理積を求め、結果を Rd レジスタに書き込みます。演算結果で条件フラグ (NZCV レジスタ) は変化しません。

    BIC  Wd, Wn, Wm {,shift #amount}
    BIC  Xd, Xn, Xm {,shift #amount}

BICS

BIC命令は、ビット単位で指定したビットをクリアします。 Rn レジスタの値と、 Rm レジスタを反転した値との間で論理積を求め、結果を Rd レジスタに書き込みます。演算結果に応じて条件フラグ (NZCV レジスタ) のビットを更新します。

    BICS Wd, Wn, Wm {,shift #amount}
    BICS Xd, Xn, Xm {,shift #amount}

命令エンコード

命令 313029 282726 252423 222120 191817 161514 131211 100908 070605 040302 0100
AND (shifted) z 0 0 0 1 0 1 0 shift 0 Rm imm6 Rn Rd
AND (imm) z 0 0 1 0 0 1 0 0 N immr imms Rn Rd
ANDS (shifted) z 1 1 0 1 0 1 0 shift 0 Rm imm6 Rn Rd
ANDS (imm) z 1 1 1 0 0 1 0 0 N immr imms Rn Rd
ORR (shifted) z 0 1 0 1 0 1 0 shift 0 Rm imm6 Rn Rd
ORR (imm) z 0 1 1 0 0 1 0 0 N immr imms Rn Rd
ORN (shifted) z 0 1 0 1 0 1 0 shift 1 Rm imm6 Rn Rd
EOR (shifted) z 1 0 0 1 0 1 0 shift 0 Rm imm6 Rn Rd
EOR (imm) z 1 0 1 0 0 1 0 0 N immr imms Rn Rd
EON (shifted) z 1 0 0 1 0 1 0 shift 1 Rm imm6 Rn Rd
BIC (shifted) z 0 0 0 1 0 1 0 shift 1 Rm imm6 Rn Rd
BICS (shifted) z 1 1 0 1 0 1 0 shift 1 Rm imm6 Rn Rd
shift
function bit
LSL 00
LSR 01
ASR 10
ROR 11


次はシフト命令




このページの目次