1

我在一个使用非常旧版本的 gcc 的组织中工作,该版本不支持 sse4 内在函数。

是否可以编写 _mm_blendv_pd 的内联 asm 等效版本?

当然,我使用的 gcc 版本不知道对应的操作码。我想知道是否有一种方法可以直接指定操作码的十六进制代码,而不是使用它的助记符。

任何帮助或参考将不胜感激。谢谢

问候

4

2 回答 2

3

在 GCC 内联汇编中,您可以通过添加操作码

.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,加上%xmm2, %xmm1( 0b11.001.010aka 0xca) 的 Mod R/M 字节,以便本地变量的显式寄存器绑定完成其余工作。

通过将其硬编码到这些寄存器,您会失去优化潜力,因为编译器不再可以自由选择任何 SSE 寄存器。但它会使使用它的代码与一个非常古老的 GCC 一起编译(我试过 3.4.5 并且很好)。

编辑:"x"如果你被一个不知道向量数据类型和 SSE 寄存器(内联汇编的约束)的 gcc 2.x 诅咒,应该说你有我的遗憾。在那种情况下,不可能像这样“模仿”内在的。您仍然可以将内联汇编与“手动编码的操作码”一起使用,但必须通过内存传递参数/返回值。最好别。

于 2013-10-03T11:11:21.413 回答