やまものブログ

メモ書きブログです (^_^;A

ARM アセンブラ 積算命令

もっとも基本的な積算命令は MUL ですが、これに加算や減算が合わせて実行される命令(MLA, MLS)とか演算結果が64-bit対応の命令(SMAL,SMULL, UMLAL, UMULL)があります。

Cで簡単な関数を書いてコンパイル結果に MLA, MLS, SMULL, UMULL が使われることを確認してみました。

● Cソースコード
int mla_func(register int n, register int m, register int a){
        return a + (n * m);
}

int mls_func(register int n, register int m, register int a){
        return a - (n * m);
}

long long smull_func(register int n, register int m){
        long long n64 = n;
        long long m64 = m;
        return n64 * m64;
}

unsigned long long umull_func(register unsigned n, register unsigned m){
        unsigned long long n64 = n;
        unsigned long long m64 = m;
        return n64 * m64;
}



アセンブラコンパイル結果)
00000000 <mla_func>:
   0:   e0202091        mla     r0, r1, r0, r2
   4:   e12fff1e        bx      lr

00000008 <mls_func>:
   8:   e0602091        mls     r0, r1, r0, r2
   c:   e12fff1e        bx      lr

00000010 <smull_func>:
  10:   e0c32190        smull   r2, r3, r0, r1
  14:   e1a00002        mov     r0, r2
  18:   e1a01003        mov     r1, r3
  1c:   e12fff1e        bx      lr

00000020 <umull_func>:
  20:   e0832091        umull   r2, r3, r1, r0
  24:   e1a00002        mov     r0, r2
  28:   e1a01003        mov     r1, r3
  2c:   e12fff1e        bx      lr



最初、アセンブラが MUL しか使ってくれなくて悩みました。
これには最適化オプション
-O2
が必要でした。

なお、このオプションで O は大文字です。
実は当初誤って小文字の o を使っていました。
  -o <file>                Place the output into <file>
小文字の -o は上記のとおり、出力ファイル名を指定するオプションです。なので、-o2 と指定すると '2' というファイルが出力されていました。これは最後まで気がつきませんでした

最適化オプションとそのコンパイル結果は、コンパイラ、および、そのバージョンにも依存するかと思います。今回、使ったのは下記のものになります。

$ arm-xilinx-linux-gnueabi-gcc --version
arm-xilinx-linux-gnueabi-gcc (Sourcery CodeBench Lite 2013.05-40) 4.7.3
Copyright (C) 2012 Free Software Foundation, Inc.