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.
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.