私は、sse4 組み込み関数をサポートしていない非常に古いバージョンの gcc を使用している組織で働いています。
_mm_blendv_pd のインライン asm 同等バージョンを作成することは可能ですか?
もちろん、私が使用している gcc バージョンは、対応するオペコードを知りません。ニーモニックを使用する代わりに、オペコードの 16 進数コードを直接指定する方法があるのだろうか。
ヘルプやリファレンスは非常に高く評価されます。ありがとう
よろしく
私は、sse4 組み込み関数をサポートしていない非常に古いバージョンの gcc を使用している組織で働いています。
_mm_blendv_pd のインライン asm 同等バージョンを作成することは可能ですか?
もちろん、私が使用している gcc バージョンは、対応するオペコードを知りません。ニーモニックを使用する代わりに、オペコードの 16 進数コードを直接指定する方法があるのだろうか。
ヘルプやリファレンスは非常に高く評価されます。ありがとう
よろしく
GCCインラインasmでは、次の方法でオペコードを追加できます
.byte 0xfe, 0x09, 0x12
GCC<smmintrin.h>
は次のことを行います。
extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_blendv_pd (__m128d __X, __m128d __Y, __m128d __M)
{
return (__m128d) __builtin_ia32_blendvpd ((__v2df)__X,
(__v2df)__Y,
(__v2df)__M);
}
そのため、コンパイラ組み込みサポートが必要です。
ただし、古い gcc バージョンでは、次のように再定義できます。
typedef double __m128d __attribute__ ((vector_size(16)));
__inline__ __m128d _mm_blendv_pd(__m128d __X, __m128d __Y, __m128d __M)
{
register __m128d m asm("%xmm0") = __M;
register __m128d x asm("%xmm1") = __X;
register __m128d y asm("%xmm2") = __Y;
__asm__ __volatile__ (".byte 0x66, 0xf, 0x38, 0x15, 0xca" : "+x"(x) : "x"(m), "x"(y));
return x;
}
ローカル変数の明示的なレジスタバインディングが残りを行うように、バイトシーケンスは(別名)BLENDVPD %xmm0,
の Mod R/M バイトに加えられます。%xmm2, %xmm1
0b11.001.010
0xca
これをこれらのレジスターにハードコーディングすると、コンパイラーが SSE レジスターを自由に選択できなくなるため、最適化の可能性が失われます。しかし、それを使用すると、非常に古い GCC でコンパイルされるコードが作成されます (3.4.5 を試してみましたが、問題ありません)。
編集:"x"
ベクトル データ型も SSE レジスタ (インライン アセンブリの制約) も知らない gcc 2.x に呪われている場合は、残念です。その場合、組み込みをそのまま「エミュレート」することは不可能です。「ハンドコーディングされたオペコード」でインラインアセンブリを引き続き使用できますが、引数/戻り値をメモリ経由で渡す必要があります。ベター...そうではありません。