我是匯編代碼和 SSE/AVX 指令的新手。現在,我想為 256 位 YMM 暫存器中的所有位置分配一個特定的值,但我不知道最終結果是否正確。
- 將0或1分配給
ymm0:
__asm__ __volatile__(
"vpxor %%ymm0, %%ymm0, %%ymm0\n\t" // all are 0
or
"VPCMPEQB %%ymm0, %%ymm0, %%ymm0\n\t" // all are 1
: : :);
GDB 結果表明:
// all are 0
ymm0
{v8_float = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
v4_double = {0x0, 0x0, 0x0, 0x0},
v32_int8 = {0x0 <repeats 32 times>},
v16_int16 = {0x0 <repeats 16 times>},
v8_int32 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
v4_int64 = {0x0, 0x0, 0x0, 0x0},
v2_int128 = {0x0, 0x0}}
// all are 1
ymm0
{v8_float = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
v4_double = {0x7fffffffffffffff, 0x7fffffffffffffff, 0x7fffffffffffffff, 0x7fffffffffffffff},
v32_int8 = {0xff <repeats 32 times>},
v16_int16 = {0xffff <repeats 16 times>},
v8_int32 = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
v4_int64 = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff},
v2_int128 = {0xffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffff}}
- 要將0xA設定為 中的所有位置(高 128 位和低 128 位)
ymm0:
__asm__ __volatile__(
"movq $0xaaaaaaaaaaaaaaaa, %%rcx\n"
"vmovq %%rcx, %%xmm0\n"
"vpbroadcastq %%xmm0, %%ymm0\n": : :);
GDB 結果表明:
ymm0
{v8_float = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
v4_double = {0x0, 0x0, 0x0, 0x0},
v32_int8 = {0xaa <repeats 32 times>},
v16_int16 = {0xaaaa <repeats 16 times>},
v8_int32 = {0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa},
v4_int64 = {0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa},
v2_int128 = {0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}
問題:
- GDB 結果(結構)是什么意思?例如,v8_float、v4_double、v32_int8等。
- 在第二種情況下(0xA),為什么v8_float和v4_double總是0?
- 如何將值(例如,'a')分配給 YMM 中的所有位置(包括高 128 位和低 128 位)?
PS VPBROADCAST — 加載整數和廣播
uj5u.com熱心網友回復:
首先,您的行內匯編已損壞:缺少一個"%ymm0"告訴編譯器您撰寫了該暫存器的內容。您甚至使用asm("" : : :)擴展 asm 語法來明確告訴編譯器沒有破壞者。或者更好的是,https://gcc.gnu.org/wiki/DontUseInlineAsm - 撰寫一個單獨的函式,或者使用內在函式并查看編譯器生成的 asm。
v8_float表示將 256 位解釋為 8x 的向量float。即__m256在英特爾內部。
v32_int8是 32x 的向量int8_t,分別列印每個位元組。p /x $ymm0.v8_int32如果您想查看它,您可以使用它。
(2) 整數0xa是非常小的次正規浮點數或雙精度數的位模式。嘗試將其作為“十六進制表示”放在https://www.h-schmidt.net/FloatConverter/IEEE754.html上。
(3) 您已經對0xa32 位元組 YMM 暫存器中的所有 64 個半位元組進行了廣播,正如您從v2_int128 = {0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}輸出中看到的那樣,顯示兩半都是0xaa位元組。
如果你真的想要
上一篇:鏈接前用匯編語言呼叫函式_mm256_set1_epi8(0x0a)(廣播到每個位元組),你應該寫0x0a0a0a0a而不是0xaaaaaaaa. (無需使用 qword 立即數;vpbroadcastd運行速度一樣快,但mov $0x0a0a0a0a,
