您的代码需要 AVX2 ( vperm2i128
),我无法对其进行测试,因为我只有 AVX。无论如何,您的代码对不需要循环的任务使用循环。我的解决方案使用简单的查找表和vpshufb
(需要 SSSE3)指令来重新排序字节。在 YASM 中测试。
这是代码:
[位 64]
部分 .text
全局_start
_开始:
设置示例值:
移动,0x1e ; 字节索引:0...31, 0x00...0x1f
vmovaps ymm0,[example_data] ; 定义数据
code_starts_here:
cmp al,15
jna no_need_to_reorder_octalwords
vperm2f128 ymm0,ymm0,ymm0,0x81 ; 重新排序 ymm0。前 16 个字节为零。
no_need_to_reorder_octalwords:
和 eax,15
shl eax,4
vmovaps xmm1,[rax+shuffle_table] ; 每个字节是一个索引,f0 = 设置为 0。
vpshufb xmm0,xmm1 ; 将右字节复制到 xmm0 的字节 0。
; 将 xmm0 的其余字节归零。
movq rdx,xmm0 ; 复制到rdx。
...
。数据
对齐 32
; 联邦银行 9 8 7 6 5 4 3 2 1 0
example_data 做 0xafaeadacabaaa9a8a7a6a5a4a3a2a1a0
; 1f1e1d1c1b1a19181716151413121110
做 0xbfbebdbcbbbab9b8b7b6b5b4b3b2b1b0
shuffle_table dd 0xf0f0f000, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f001, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f002, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f003, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f004, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f005, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f006, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f007, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f008, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f009, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f00a, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f00b, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f00c, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f00d, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f00e, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0
dd 0xf0f0f00f, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0