用于读/写 XMM 和 YMM 寄存器的内联汇编代码?

aqu*_*019 6 assembly gcc sse inline-assembly

我有 2 个变量来模拟 X86 XMM 和 YMM,如下所示:

uint64_t xmm_value[2];
uint64_t ymm_value[4];
Run Code Online (Sandbox Code Playgroud)

现在我想使用内联汇编来读取和写入 XMM/YMM 寄存器。

  • 如何编写GCC内联汇编来复制xmm_value到寄存器XMM0
  • 如何编写 GCC 内联汇编将寄存器复制YMM0ymm_value

我已经尝试搜索示例内联汇编来执行此操作,但找不到任何好的答案。谢谢!


因此,在一些帮助下,我编写了这段代码,并且编译正常。我用于movupsXMM 和vmovupsYMM,如下所示。这是正确的吗?我还可以优化我的代码吗?

__m128 xmm0;
__m256 ymm0;

// write to XMM0, and read from YMM0
__asm__("movups %1, %%xmm0\n\t"
        "vmovups %%ymm0, %0"
        : "=m"(ymm0)
        : "m"(xmm0)
        : "xmm0", "ymm0");
Run Code Online (Sandbox Code Playgroud)

更新 2:这是我的完整代码(添加了 vpbroadcastb)

__m128 xmm0;
__m256 ymm0;

// write to XMM0, and read from YMM0
__asm__("movups %1, %%xmm0\n\t"
        "vpbroadcastb %%xmm0, %%ymm0\n\t"
        "vmovups %%ymm0, %0"
        : "=m"(ymm0)
        : "m"(xmm0)
        : "xmm0", "ymm0");
Run Code Online (Sandbox Code Playgroud)

我的想法是,我想将 xmm0 (变量)复制到 XMM0,然后运行vpbroadcastb​​,然后将 YMM0 中的结果复制到 ymm0 (变量)。现在我意识到XMM0是YMM0的下半部分,那么这段代码还可以改进吗?

Chr*_*odd 3

第一步是#include <immintrin.h>,其中包括所需类型的所有定义以及用于访问所有 MMX/SSE/AVX 指令的所有英特尔内部函数。对于大多数目的,您希望使用这些内在函数而不是内联汇编,因为它们更清晰且更可移植,但如果您确实想使用内联汇编,则可以使用内在类型( 、__m64__m128__m128d__m256)以及x约束绑定到正确类型的 xmm/ymm 寄存器。

  • @aq2019:您可以使用 `register __m128 foo asm("xmm0")` 强制使用 `"x"` 约束来选择 XMM0。与遵循标准调用约定的 JITing 函数相比,这听起来是一个非常糟糕的想法,因此您可以编写 C 原型,但如果您想编写难以维护且容易出错的汇编语言,那就是这样。不要忘记,您无法安全地破坏内联汇编中的红色区域,因此您需要在“call”之前添加“add $-128, %rsp”。 (2认同)