`lddqu' 的操作数类型与 __int128 "=r" 目标不匹配

operand type mismatch for `lddqu' with an __int128 "=r" destination

我需要使用指令 lddqu 将 128 位值从地址 [rsi - 0x80] 移动到下面的 dest 变量,我遇到错误“'lddqu' 的操作数类型不匹配”。我知道以前有关于使用较小操作数大小的 Whosebug 的问题,但是我应该在指令中使用什么后缀才能获取变量中该地址的值。

 __int128 dst = 0, src = 0;
asm volatile ("lddqu -0x80(%%rsi), %0\n\t"
        : "=r" (dst)
        : "r" (src));

只是为了概述整个问题,这只是一个更大的图形算法的一部分的指令,该算法用于查找两个顶点之间的最短路径。 src 变量是多余的,如果它增加了歧义,可以将其删除。我正在设计一个硬件预取器(在处理器模拟器中)以根据当前访问的地址预测未来的内存地址。一旦我可以在像 dst 这样的变量中获取地址,我就有了一种技术可以自动预测未来的地址并触发对该地址的内存请求。

该模式的放大版本是一系列加载和存储,如下所示:

  lddqu  xmm0,[rsi-0x80]
  movdqu XMMWORD PTR [rdi-0x80],xmm0
  lddqu  xmm0,[rsi-0x70]
  movdqu XMMWORD PTR [rdi-0x70],xmm0
  lddqu  xmm0,[rsi-0x60]
  movdqu XMMWORD PTR [rdi-0x60],xmm0
  lddqu  xmm0,[rsi-0x50]
  movdqu XMMWORD PTR [rdi-0x50],xmm0

现在,我正在研究如何让内联汇编与 Intel 语法一起工作。

lddqu只能加载到向量寄存器,不能加载到通用寄存器。对于 dst 的约束,使用 =x 代替 =r

此外,您的来源看起来很可疑,因为您忽略了 src 并且只是从您对内容一无所知的寄存器的任意偏移量加载。

查看编译器围绕您的 asm 语句生成的 asm,以了解编译器如何在您强制将其置于 XMM 寄存器中后 __int128 dst 返回内存或整数寄存器,例如 [=17] =],尤其是启用了 -O2 优化。

像这样使用内联 asm 的效率可能比使用像 _mm_loadu_si128 这样的 SSE 内在函数更糟糕 - 另见 https://gcc.gnu.org/wiki/DontUseInlineAsm