1

私は、sse4 組み込み関数をサポートしていない非常に古いバージョンの gcc を使用している組織で働いています。

_mm_blendv_pd のインライン asm 同等バージョンを作成することは可能ですか?

もちろん、私が使用している gcc バージョンは、対応するオペコードを知りません。ニーモニックを使用する代わりに、オペコードの 16 進数コードを直接指定する方法があるのだろうか。

ヘルプやリファレンスは非常に高く評価されます。ありがとう

よろしく

4

2 に答える 2

3

GCCインラインasmでは、次の方法でオペコードを追加できます

.byte 0xfe, 0x09, 0x12
于 2013-10-02T16:43:08.317 に答える
2

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, %xmm10b11.001.0100xca

これをこれらのレジスターにハードコーディングすると、コンパイラーが SSE レジスターを自由に選択できなくなるため、最適化の可能性が失われます。しかし、それを使用すると、非常に古い GCC でコンパイルされるコードが作成されます (3.4.5 を試してみましたが、問題ありません)。

編集:"x"ベクトル データ型も SSE レジスタ (インライン アセンブリの制約) も知らない gcc 2.x に呪われている場合は、残念です。その場合、組み込みをそのまま「エミュレート」することは不可能です。「ハンドコーディングされたオペコード」でインラインアセンブリを引き続き使用できますが、引数/戻り値をメモリ経由で渡す必要があります。ベター...そうではありません。

于 2013-10-03T11:11:21.413 に答える