大家好,我想执行以下形式的内联程序集指令
BLENDPD xmm1,xmm2/m128, imm8我是新来的内联装配,所以我有一些困难。我的代码是:
#include<iostream>
using namespace std;
int main()
{
long long y;
__asm("blendpd %0,$0xabcd000000001111abcd000000001111,$0x1":
"=r" (y):
);
cout<<y;
return 0;
}我的第一个错误是获得128位操作数,所以我使用了长十六进制数,但是我仍然需要输出128位,因为我希望2能够在屏幕上打印y。而且,最重要的是,我知道我的__asm语法是错误的,但我不知道是错的,而且我也不确定用英特尔或AT&T语法进行编译是否会在使用__asm时产生影响。
欢迎任何帮助。干杯!=)
编辑:--我现在有了这个版本,并且得到了一个未定义的函数错误。
#include<iostream>
#include<emmintrin.h>
using namespace std;
int main()
{
const int mask=5;
__m128d v2 = _mm_set_pd(1.0, 2.0);
__m128d v1;
v1=_mm_blend_pd(v1, v2, mask);
return 0;
}发布于 2011-01-08 20:10:29
作为另一个答案的另一个替代答案,下面是如何使用内联程序集而不是内部程序集来实现这一点。(正如Thomas在我的另一个答案中所指出的,本质通常更好,因为它们更易于移植,但有时你也想要这样的东西。)
首先,我作弊了--我使用一个内置函数获取了版本,并使用-S编译了它,并查看了生成的汇编代码,即:
movsd -64(%rbp), %xmm0
movhpd -56(%rbp), %xmm0
movsd -48(%rbp), %xmm1
movhpd -40(%rbp), %xmm1
blendpd $3, %xmm1, %xmm0
movlpd %xmm0, -64(%rbp)
movhpd %xmm0, -56(%rbp)您可以在这里看到一些与原始代码不同的地方。首先,注意两个128位参数不是直接的--它们是xmm0和xmm1寄存器。另外,您得到的操作数的顺序是错误的--掩码放在第一位,包含输出的寄存器放在最后。修复这些代码,代码就会编译。
这里的第二个问题是,您要将来自普通寄存器的结果存储到y中,而blendpd指令不涉及通用寄存器,所以这只是存储垃圾。您需要xmm0寄存器,这是您在=Yz中获得的(参见GCC的文件)。您不能将其存储到long long中,这是64位;您需要一个128位的向量变量。为了解决所有这些问题,修正的代码是:
#include<iostream>
#include<smmintrin.h>
using namespace std;
int main()
{
__m128d y;
__asm("blendpd $0x3,%%xmm1,%%xmm0":
"=Yz" (y):
);
// cout<<y;
return 0;
}您将注意到,我不得不注释掉cout行,因为它没有处理SSE向量的功能;您需要首先使用_mm_store_pd内在的来从y中获取单个的双值。(也可以添加更多内联程序集来调用movhpd和movhld指令,直接从寄存器中获取双值,而不是使用约束将它们分配给y。)
就在这里--编译和运行都很好。当然,输入值是未定义的(不管这些寄存器中有什么是随机的),所以输出无论如何都是垃圾--如果想要有意义的结果,首先需要添加一些东西来加载值到寄存器中。
发布于 2011-01-07 01:02:08
首先,对于这类事情,很少需要使用内联程序集。GCC通常提供“编译器内在”函数,允许您使用C函数语法而不是程序集语法调用给定的特殊指令。
在本例中,您想要的内部函数是_mm_blend_pd(),它具有以下函数签名
#include <smmintrin.h>
__m128d _mm_blend_pd(__m128d v1, __m128d v2, const int mask);编译器将用单个blendpd指令替换它;这实际上不是一个函数调用。
__m128d数据类型是一个包含两个双精度浮点值的向量;您可以从如下所示的双倍数组中创建一个:
__m128d v = _mm_set_pd(1.0, 2.0);要从向量中检索值以打印它们,可以将向量存储到一个双精度浮点数数组中:
double a[2];
_mm_store_pd(a, v);所有这些都是基于intrinsics.pdf的Intrinsics手册;虽然它引用了Intel C++编译器,但是GCC支持相同的语法。
编辑:将错误的emmintrin.h替换为正确的smmintrin.h。另外,请注意,mask值需要为2位(向量中的每个值为1位);除0、1、2或3以外的值会产生错误。当然,您需要用-msse4 GCC选项编译它。
https://stackoverflow.com/questions/4621342
复制相似问题