繁体   English   中英

可能要合并r1,r1吗?

[英]Possible to mul r1,r1?

如果我有

movmr x,r1

有可能吗?

mul r1,r1 

(x*x) 我正在尝试有效地执行此操作以节省字节,但这是迄今为止我能想到的最好的解决方案,并且似乎无法找到是否允许这样做。

整个方程为(x+y)(xy) ,因此我将其简化为x^2 - y^2

此外,如果您想知道,f + d / exe是基于每个字节的。

OPC = 8位,x / y = 20位,reg = 3位。 所以movmr x,r1是4f + d和4 exe

编辑:我们正在使用基于Linux的系统

OPC | DST,SRC,XX | <= | 1byte | 1byte |

大多数ISA都没有这种限制,任何有限制的都可以记录下来。

通常,指令在写入任何输出操作数之前先读取其所有输入操作数,因此,如果它们重叠,就可以了。 任何限制都将始终记录在ISA手册/指令集参考中。

通常,您只会发现对写入多个寄存器的指令的限制,在这种情况下,当您为两个输出提供相同的寄存器时,异常行为或非法指令异常是正常的。 例如, AVX512 vpgatherqq

如果目标向量zmm1与索引向量VINDEX相同,则该指令将#UD错误。

AVX2版本在ISA参考手册中没有提及这一点,但我忘记了在其他任何地方是否有反对它的规则。


一种非法的情况是ARM: MUL Rd, Rm, Rs确实Rd := Rm × Rs

在早期的ARM版本(?)中,如果Rd和Rm是同一寄存器,则该行为是不可预测的。 ARM Wiki和一些正式的ARM文档版本)。 也许早期的微体系结构进行了一些多步微编码计算,并将结果累加到目标寄存器中。

MUL     r1,r1,r6    ; incorrect: Rd cannot be the same as Rm
MUL     r1,r6,r1    ; correct:  r1 *= r6

更高版本的ARM文档没有提及此限制,因此我想它不适用于更高的体系结构吗? 否则,谷歌找不到合适的ISA文档。 这些似乎是ARM汇编程序的文档。 以后的ARM体系结构版本肯定没有此限制,但是IDK为什么后来的文档没有提到取消限制的时间。

davespace表示 Rs和Rm(两个源操作数)不能相同。 这与任何其他文档所说的都不匹配,并且从微体系结构的角度讲意义不大,所以我认为这是错误的。


ARM的32x32 => 64位全乘umull Rhi, Rlo, Rm, Rs也有一个限制:Rhi,Rlo和Rm都必须是不同的寄存器。

UMULL  r1, r0, r0, r0     ; unpredictable, Rlo and Rm are the same. 
UMULL  r2, r1, r0, r0     ; r2:r1  =  r0*r0

整个方程为(x+y)(xy) ,因此我将其简化为x^2 - y^2

在没有任何周围代码的情况下,这种转换使它变得更加昂贵,而不是更少。 添加/订阅比乘法便宜:更好的吞吐量和更低的延迟。 在x86上,给定寄存器中的x和y,

; x=eax
; y=edx

lea  ecx, [rax + rdx]     ; x+y
sub  eax, edx             ; x-y
imul ecx, eax             ; (x+y) * (x-y)

Intel SnB系列的4个周期延迟。 (3循环imul ,和LEA /子可以并行运行。 http://agner.org/optimize/ )。

imul  eax, eax
imul  edx, edx
sub   eax, edx

如果eax和edx同时准备就绪,则有5个周期的延迟。 没有现有的x86 CPU具有超过1个标量乘法执行单元,因此存在资源冲突:第二个imul必须等待一个周期才能执行。 取决于周围的代码,端口1可能不是吞吐量瓶颈,也许其中一个输入或另一个输入都可以提前一个周期准备好。

但是,如果xy是不变的,则只需2条指令,您就可以通过这种方式便宜地计算出新的(x+y) * (xy) ,CSE处理不变的平方。

这会破坏两个输入,因此如果之后需要x或y,则需要mov 另一个版本保留y (在edx )并将xy保留在寄存器中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM