我想让编译器在C代码中通过参数化我的内联程序集来自动选择寄存器,但是我遇到了一些问题。有人能告诉我出了什么问题吗?如果我使用我注释掉的代码(强制加入%xmm0 0),它将编译并获得预期的结果。但是,如果我把它注释掉在这里,我就会得到编译器错误:
/tmp/ccJxmSbm.s: Assembler messages:
/tmp/ccJxmSbm.s:81: Error: the first operand of `blendvpd' must be `%xmm0'另外,如果我只删除printf语句,代码块也会成功编译。因此,它与移动参数有关,以便为printf调用做准备。我已经显式地添加了"Yz“约束,该约束应该强制使用%xmm0 0,但是它看起来没有得到遵守。
下面是所讨论的代码:
#include <stdio.h>
const unsigned long long myConst[2] = {0x0000000000000000,0xffffffffffffffff};
const unsigned long long myConst2[2] = {0x0000000000000000,0x1111111111111111};
const unsigned long long myConst3[2] = {0x0123456789abcdef,0x0000000000000000};
#define ASSIGN_CONST128( val, const ) \
val = *((__uint128_t *)const);
int main( void )
{
register __uint128_t regVal1 /* asm("%xmm0") */ ;
register __uint128_t regVal2;
register __uint128_t regVal3;
ASSIGN_CONST128( regVal1, myConst );
ASSIGN_CONST128( regVal2, myConst2 );
ASSIGN_CONST128( regVal3, myConst3 );
asm( "blendvpd %[mask], %[val1], %[val2]" :
[val2] "+x" (regVal3) :
[mask] "Yz" (regVal1),
[val1] "x" (regVal2) );
printf( "REGVAL1: %016llx%016llx (original=%016llx%016llx)\n"
"REGVAL2: %016llx%016llx (original=%016llx%016llx)\n"
"REGVAL3: %016llx%016llx (original=%016llx%016llx)\n",
(unsigned long long)(regVal1>>64), (unsigned long long)regVal1,
myConst[1], myConst[0],
(unsigned long long)(regVal2>>64), (unsigned long long)regVal2,
myConst2[1], myConst2[0],
(unsigned long long)(regVal3>>64), (unsigned long long)regVal3,
myConst3[1], myConst3[0] );
// Expected result:
// REGVAL1: ffffffffffffffff0000000000000000 (original=ffffffffffffffff0000000000000000)
// REGVAL2: 11111111111111110000000000000000 (original=11111111111111110000000000000000)
// REGVAL3: 11111111111111110123456789abcdef (original=00000000000000000123456789abcdef)
}我很感激你的想法。
发布于 2014-04-10 06:54:29
为什么不直接使用相关的内在呢?
regVal3 = _mm_blendv_pd (regVal1, regVal2, regVal3);正如其他人所指出的,regVal1、regVal2和regVal3都应该声明为__m128d。
https://stackoverflow.com/questions/22978983
复制相似问题