これは簡単な質問ではありません。
注:純粋なasmを使用するための意見やアドバイスは必要ありません。私は実際に私が話していることをやり遂げる必要があります:この記号なしでインラインasmを得るには/ゼロは短いintに結果を割り当てるときにオプコードを拡張します。
私は多くの機能のために16ビットの短絡を悪用するライブラリを扱っており、私はそれを最適化しています。インラインasmでいくつかの最適化された関数を追加する必要があります。問題は、多くの場所で、関数の結果が短いintに割り当てられていることです。つまり、コンパイラはuxまたはsx番目のアームオペコードを生成します。
私の目標は、この問題を回避し、この無駄なオペコードが生成されないようにすることです。 まず、intを返すように私の最適化された関数を定義する必要があります。このようにintまたはshort intに代入された場合、結果を変換するための余分なオペコードはありません。
問題は、自分の関数内でコンパイラが生成するint - > short変換をスキップする方法がないということです。
ダムキャスト:*(short*)(void*)&value
は機能しません。コンパイラは、スタックを問題にして混乱を招きかねません。あるいは、同じsxthを使用して結果を符号拡張します。
私は複数のコンパイラでコンパイルしましたが、アームのarmccコンパイラで解決できましたが、GCCでコンパイルできません(4.4.3または4.6.3でコンパイルできます)。 armccでは、短いタイプのインラインasm文を使用します。短いコンパイラを使用していても何らかの理由でgccで拡張子が必要だと考えています。
C/C++ intをshortとinlineに変換するasm(ARM固有)
私はGCCで作業することができない簡単なコードスニペットがあります。どのように動作するのかアドバイスはありますか?この単純な例のために私は、CLZ命令を使用します:
サンプルファイルtest.cのファイル:
:static __inline short CLZ(int n)
{
short ret;
#ifdef __GNUC__
__asm__("clz %0, %1" : "=r"(ret) : "r"(n));
#else
__asm { clz ret, n; }
#endif
return ret;
}
//test function
short test_clz(int n)
{
return CLZ(n);
}
は、ここで私は-O3 -cのarmccで得た結果予想です
test_clz:
CLZ r0,r0
BX lr
ここでGCC -c -O3が私を与えることを容認できない結果だ:
は、test_clz:
clz r0, r0
sxth r0, r0
bx lr
short ret;
ではなく、内部変数int ret;
でCLZを書き換えると、armccはGCCと同じ結果を生成することにも注意してください。
GCCまたはのarmccでのasm出力を得るためにクイックライン:
gcc -O3 -c test.c -o test.o && objdump -d test.o > test.s
armcc -O3 --arm --asm -c test.c
インラインアセンブリをスキップして、最適化されたビットをアセンブリで記述された関数全体として書くのはなぜですか?あなたの問題は、C関数とインラインasmの混在から来ているようです。しかし、なぜ内部にたくさんのasmが入っているC関数を書くのですか? – TJD
はオプションではありません。私は本当に完全にasmで書かれている必要がある関数を書き換えました。それを正しく行うには、おそらくコード全体を調べて短所に代わってintを使用する必要がありますが、その作業だけでは、更新するために必要なコード量と一緒にテストすることができます。 – Pavel