我正在尝试汇编以使用 vector 运算,这是我以前从未真正使用过的,而且我承认在掌握一些语法方面遇到了一些麻烦。
相关代码如下。
unit16_t asdf[4];
asdf[0] = 1;
asdf[1] = 2;
asdf[2] = 3;
asdf[3] = 4;
uint16_t other = 3;
__asm__("movq %0, %%mm0"
:
: "m" (asdf));
__asm__("pcmpeqw %0, %%mm0"
:
: "r" (other));
__asm__("movq %%mm0, %0" : "=m" (asdf));
printf("%u %u %u %u\n", asdf[0], asdf[1], asdf[2], asdf[3]);
在这个简单的示例中,我试图对数组中的每个元素进行“3”的 16 位比较。我希望输出是“0 0 65535 0”。但它甚至不会组装。
第一个汇编指令给我以下错误:
错误:内存输入 0 不可直接寻址
第二条指令给了我一个不同的错误:
错误:“pcmpeqw”的后缀或操作数无效
如有任何帮助,我们将不胜感激。
最佳答案
您不能在 gcc asm 语句中直接使用寄存器并期望它们与其他 asm 语句中的任何内容相匹配——优化器会四处移动。相反,您需要声明适当类型的变量并使用约束将这些变量强制放入您正在使用的指令的正确类型的寄存器中。
MMX/SSE 的相关约束是 xmm 寄存器的 x
和 mmx 寄存器的 y
。对于您的示例,您可以执行以下操作:
#include <stdint.h>
#include <stdio.h>
typedef union xmmreg {
uint8_t b[16];
uint16_t w[8];
uint32_t d[4];
uint64_t q[2];
} xmmreg;
int main() {
xmmreg v1, v2;
v1.w[0] = 1;
v1.w[1] = 2;
v1.w[2] = 3;
v1.w[3] = 4;
v2.w[0] = v2.w[1] = v2.w[2] = v2.w[3] = 3;
asm("pcmpeqw %1,%0" : "+x"(v1) : "x"(v2));
printf("%u %u %u %u\n", v1.w[0], v1.w[1], v1.w[2], v1.w[3]);
}
请注意,您需要在第二个 vector 的所有相关元素中显式复制 3
。
关于c - 在 C 中使用内联汇编的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21995904/