【发布时间】:2014-02-26 18:22:09
【问题描述】:
是否存在任何 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 寄存器都被保存) .
顺便说一句,对于我需要完成的事情,自我修改代码不是一种选择。
【问题讨论】:
-
你不能那样做。您可以使用跳台(或只是一大堆分支)并实现它,但它会很糟糕。也许如果你解释这实际上是为了什么(在比“保存一系列 ymm regs”更高的层次上)我/其他人可以想出一些其他的想法
-
@harold:考虑到这是为了什么,我敢肯定,我解释自己会因为提出公然不恰当的问题而受到残酷的打击!去过那里,以前做过。这里的一些人对我的口味的规则过于敏感。但是,是的,如果没有什么绝妙的主意,跳表是必要的。
-
你可以做地址算术(并使用一些填充物来解决它)来跳过表格,但这并没有(如果有的话)更好。
-
@harold:我猜你只是在说“测量每次保存需要多少字节”,然后适当地调整调用地址(而不是有一个地址数组)。如果是这样,我怀疑跳转表效率更高。但我知道你要去哪里......基本上使代码段适合各种代码数组,每个代码块的长度与所有其他代码块相同。这太恶心了,但这肯定是尽可能快的,所以......我也会调查一下。 PS:新的 64 位 ABI 支持 32 * 512 位 zmm 寄存器的“智能功能协议”。忽略这个! :-)
-
@honestann 你是来自 ARM 的变化吗? ARM 上的程序集(以及在此之前的 m68k)一直都知道“多寄存器存储/加载”操作 - 即能够在单个指令中加载/存储通用或向量寄存器的任意子集。唉,这不是英特尔在他们的架构中实现的东西......