是否存在任何SIMD /向量寄存器指令,其中ymm寄存器是在通用寄存器(或SIMD寄存器)中指定的,而不是在指令本身中指定的?
基本上我要做的是编写一个函数,将任何一系列连续的ymm寄存器保存到本地帧上。这是一个想法,除了我发明了我认为我正在寻找的指令的半合理虚构语法。
.text
.align 64
funcname:
orq %rcx, %rcx # is register count <= 0 ???
jle funcdone # # of registers to save is <= 0
xorq %rax, %rax # rax = 0 == vector save element #
funcloop:
vmovapd %ymm(%rsi), (%rdi, %rax) # save ymm?? to address rdi + rax
addq $32, %rax # each ymm vector is 32-bytes
loop funcloop # --rcx; if (rcx > 0) { goto funcloop }
funcdone:
ret
vmovapd
指令是执行我正在寻找的奇怪指令。我确信我从未见过看起来像这样的指令,但这并不意味着没有一些不寻常的指令可以做我需要做的事情。
或许说明看起来像其中之一:
vmovapd %rsi, (%rdi, %rax)
vmovapd (%rsi), (%rdi, %rax)
另一个替代方案是%rsi
中的位0到15对应于向量寄存器ymm00
到ymm15
,并且保存对应于最低设置位的寄存器(或所有“设置位” “ymm寄存器得到保存。”
BTW,对于我需要完成的事情,自修改代码不是一种选择。
答案 0 :(得分:1)
当谈到“SIMD加载/存储”时,可能有两种不同的方法:
ARM和/或m68k总是完成前者 - 这些平台上的“移动多个”操作码(ARM上为[v]ldm
,m68k上为movem
)允许指定枚举寄存器的掩码从给定地址的(连续)数据填充。
英特尔x86在其历史上从来没有这样,除了32位中的PUSHA
/ POPA
,它将无条件地/不可屏蔽地将通用寄存器保存/恢复到堆栈中,并且指令在64位模式下退役。
英特尔与AVX一起创建了同时从多个地址加载的功能,即“分散 - 聚集”。
所以是的,x86取代了ARM上的东西,如:
VLDM.64 r0, {d1, d3, d5, d7} ; load odd-numbered vector regs from mem @r0
将是一个序列:
VMOVAPD YMM1, [ RAX ]
VMOVAPD YMM3, [ RAX + 32 ]
VMOVAPD YMM5, [ RAX + 64 ]
VMOVAPD YMM7, [ RAX + 96 ]
另一方面,x86 VGATHER
指令的ARM等效项(请参阅ARM docs, "indirect addressing"),如:
VGATHERDD YMM0, [ RAX + YMM1 ] ; YMM1[0..8] has 32bit offsets on RAX
需要对向量寄存器的单个元素进行多次加载,最后使用“组合” - 或者子寄存器加载;它变成了一个序列:
VLD1.32 {d0}, [r0] ; r0..r3 have the [32bit] addresses
VLD1.32 {d1}, [r1]
VLD1.32 {d2}, [r2]
VLD1.32 {d3}, [r3]
VTBL d0, { d0 - d3 }, d4 ; d4 is [ 0, .., 7, ..., 15, ..., 31, ... ]
答案 1 :(得分:1)
x86的状态保存说明(xsave
/ xrstor
)执行在edx:eax
中执行掩码以控制要保存/恢复的状态。它真的很复杂,而insn ref手册只是指向另一本手册的一个单独的部分。但是,如果您可以选择单个向量寄存器的级别,则为IDK。更可能的是&#34;所有16个向量寄存器的低位128&#34;但是ymm0-7与其余的分开,以避免在32位代码可以&#39;时保存/恢复ymm8-15。影响他们。
保存的特定状态组件对应于中设置的位 请求特征位图(RFBM),它是EDX:EAX的逻辑AND 和XCR0。
为了在功能序言/尾声中保存/恢复几个ymm regs,它不太可能有用。我没有调查过它。 xsavec
执行&#34;压缩&#34;:CPU跟踪实际修改了哪些状态。
没有其他指令具有寄存器的额外间接级别(寄存器指定哪个寄存器)。对于无序机制来说,这将是一个很大的复杂因素。甚至ARM加载多指令(参见另一个答案)都将寄存器位掩码嵌入到指令中,因此在解码指令时可以使用它(而不是稍后填写)。
你可能会更好地使用你想要使用的任何矢量寄存器的明显存储/重新加载,但是在你正在设计的调用约定中调用保存。
请注意,未来对更宽向量的扩展意味着您最终只会将所选向量reg的低256b保留为调用保留,其中上面的位被破坏。 (归零与否,当被访者不接触他们时,而不是保存/恢复)。