QNX-Momentics (eclipse、g++ 4.6.1 ツールチェーンに基づく) と Visual Studio 2010 の両方でコンパイル可能にする必要があるプロジェクトに取り組んでいます。一部のルーチンについては、組み込み関数でさえうまくいかないため、手動でアセンブリを実装することにしました。最適化されました。最初のコンパイラには、-masm=intel フラグを使用して "intelized" できる ATt&T 構文があり、2 番目のコンパイラは intel 方言のみです。
intel-flag を使用して、記法上の側面を上回ることができます。
#ifdef _WIN32
#define _cmd(...) __VA_ARGS__
__asm {
#else
#define _cmd(...) #__VA_ARGS__
asm volatile (
#endif
// constants
// set loop counter
_cmd( xor eax, eax; )
:
:
#ifdef _WIN32
}
#else
);
#endif
さて、問題の 1 つは、インライン AT&T を使用して名前でローカル変数または関数のパラメーターにアクセスできないことです。次のようなものを使用して、別のスレッドで得たヒント
register __m128i x asm("xmm6");
ローカル変数が機能せず、xmm0 に割り当てられました。組み込み関数によって定義されていないローカル変数またはパラメーターは、AT&T で未定義の参照になるため、次のようなベア スタック処理を使用することにしました。
_cmd( movupd xmmword ptr [eax], xmm3; )
新しい問題が発生しました:
関数パラメーターとローカル変数の両方が、両方の方言でまったく異なる方法で処理されます。次の例を検討してください。
template<typename T>
void linearRegression2DAsm(unsigned int p_oNumPoints, T *p_pXcoords, T *p_pYcoords,
double *oX, double *oY, double *oXY,
double p_oAvgX, double p_oAvgY)
{
unsigned int p_rLoopsize = p_oNumPoints - (p_oNumPoints % 2);
double oAvgX[2];
そして、上記の定義ブロックの後のこの単純な計算:
_cmd( xor eax, eax; )
// p_pXccoords
_cmd( mov ecx, dword ptr [ebp+12]; )
// p_pYcoords
_cmd( mov edx, dword ptr [ebp+16]; )
// p_oAvgX
_cmd( movhpd xmm6, qword ptr [ebp+20]; )
// p_oAvgY
_cmd( movhpd xmm7, qword ptr [ebp+28]; )
_cmd( movlpd xmm6, qword ptr [ebp+20]; )
_cmd( movlpd xmm7, qword ptr [ebp+20]; )
_cmd( addpd xmm7, xmm6; )
// result into oAvgX
_cmd( mov eax, [ebp-32]; )
_cmd( movupd xmmword ptr [ebp-32], xmm7; )
結果は oAvgX にあるはずです。これは Intel では問題なく動作しますが、Intel フラグ付きの AT&T asm コンパイラを使用すると成功しません。第二に、追加の O2-Flag が他の変数を最適化する可能性があるため、スタックが異なるコンパイルで同じように構築されることが保証されないことが懸念されます。
とにかくインライン化が必要ですが、二重方言の問題に対処する方法がわかりません。