GCC 内联 ASM,未知的 SSE 操作码

gcc inline asm, unknown sse opcode

本文关键字:SSE 操作码 未知 内联 ASM GCC      更新时间:2023-10-16

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

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

当然,我使用的 gcc 版本不知道相应的操作码。我想知道是否有办法直接指定操作码的十六进制代码而不是使用其助记符。

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

问候

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

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

编辑:应该说你有我的怜悯,如果你被一个不知道矢量数据类型或SSE寄存器(内联程序集的"x"约束)的gcc 2.x诅咒。在这种情况下,就不可能"模仿"内在本身。您仍然可以将内联汇编与"手动编码的操作码"一起使用,但必须通过内存传递参数/返回值。更好。。。不。