[英]Attempting to use (SSE4) blendvpd with inline assembly in gcc
我想讓編譯器通過在我的C代碼中對我的內聯匯編進行參數化來自動選擇寄存器,但是我遇到了一些麻煩。 誰能告訴我出了什么問題? 如果我使用我已注釋掉的代碼(強制與%xmm0建立聯系),它將編譯並獲得預期的結果。 但如果我把它留在這里寫的注釋,我得到編譯器錯誤:
/tmp/ccJxmSbm.s: Assembler messages:
/tmp/ccJxmSbm.s:81: Error: the first operand of `blendvpd' must be `%xmm0'
此外,如果我除了刪除printf語句之外什么都不做,代碼塊也會成功編譯。 因此它與移動參數以准備printf調用有關。 我已經明確地放入了“Yz”約束,它應該強制使用%xmm0,但看起來它沒有被尊重。
這是有問題的代碼:
#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)
}
我很感激任何想法。
為什么不使用相關的內在?
regVal3 = _mm_blendv_pd (regVal1, regVal2, regVal3);
正如其他人所說, regVal1
, regVal2
和regVal3
都應聲明為__m128d
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.