これは些細な質問ではありません。
注: 純粋な asm を使用するための意見やアドバイスは必要ありません。私が話していることを実際に完了する必要があります。結果を短いintに割り当てるときに、この符号/ゼロ拡張オプトコードなしでインラインasmを取得するには。
多くの関数で 16 ビット ショートを悪用するライブラリを扱っており、それを最適化しています。インライン asm を使用して最適化された関数をいくつか追加する必要があります。問題は、多くの場所で関数の結果が short int に割り当てられることです。つまり、コンパイラは ux 番目または sx 番目のアーム オペコードを生成します。
私の目標は、その問題を回避し、この役に立たないオペコードが生成されないようにすることです。まず、short int を返すように最適化された関数を定義する必要があります。このように、int または short int に割り当てられている場合、結果を変換するための余分なオペコードはありません。
問題は、コンパイラが自分の関数内で生成する int->short 変換をスキップする方法がわからないことです。
次のようなダムキャスト:*(short*)(void*)&value
機能しません。コンパイラは、スタック作成の問題をさらにいじり始めるか、同じ sxth を使用して結果を符号拡張します。
複数のコンパイラ用にコンパイルし、arm の armcc コンパイラ用に解決できましたが、GCC では解決できません (4.4.3 または 4.6.3 でコンパイルします)。armcc では、インライン asm ステートメント内で short 型を使用します。gccでは、短いコンパイラを使用しても、何らかの理由で符号拡張が必要であると考えています。
これは、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);
}
armcc -c -O3 で得られる期待される結果は次のとおりです。
test_clz:
CLZ r0,r0
BX lr
GCC -c -O3 が私に与える受け入れられない結果は次のとおりです。
test_clz:
clz r0, r0
sxth r0, r0
bx lr
int ret;
また、ARMCCの代わりに内部変数を使用して CLZ を書き換えるとshort ret;
、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