【问题标题】:Possible to mul r1,r1?可以 mul r1,r1 吗?
【发布时间】:2017-11-03 18:43:43
【问题描述】:

如果我有

movmr x,r1

可以吗?

mul r1,r1 

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

整个方程是(x+y)(x-y),所以我把它简化为x^2 - y^2

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

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

编辑:我们使用的是基于 linux 的系统

OPC|夏令时,SRC,xx|

【问题讨论】:

  • 确定是“mips”还是“x86-64”或其他。但一般来说,是的,通常是允许它自己相乘的。
  • 只选择一个指令集或告诉我执行 MIPS 和 x86-64 指令的 CPU。
  • 我们为赋值进行的编码是 x86-64,但除了学习它的格式和字节用法之外,我们还没有真正在代码中做过任何类似的事情。基于 x86-64 逻辑,这应该是可能的,但我真的找不到任何例子。所以这就是我问的原因,再次感谢 Jester。
  • 请注意,x86-64 没有r1 寄存器,除非您将其别名为某物。它也没有采用 2 个操作数的 mul 指令。
  • 你写的问题是毫无意义的废话。 x86-86 和 MIPS 指令集都没有 MOVMR 指令。这对参加你的课程的人来说可能是有意义的,但否则我认为没有人会帮助你。您应该尝试向您的老师寻求帮助。

标签: assembly mips x86-64 instruction-set


【解决方案1】:

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

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

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

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

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


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

在早期的 ARM 版本中(?),如果 Rd 和 Rm 是同一个寄存器,则行为是不可预测的。 (ARM wiki,以及某些版本的official ARM docs)。也许早期的微架构做了某种多步微编码计算,并将结果累积到目标寄存器中。

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

A later version of ARM documentation 没有提到这个限制,所以我想不适用于以后的架构?或者谷歌没有找到好的 ISA 文档。这些似乎是 ARM 汇编程序的文档。以后的 ARM 架构版本肯定很可能没有限制,但是 IDK 为什么后来的文档没有提及限制何时被删除。

davespace says 是 Rs 和 Rm(两个源操作数)不能相同。这与任何其他文档所说的不符,并且在微架构上也没有多大意义,所以我认为这是错误的。


ARM 的32x32 => 64 bit full-multiply 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)(x-y),所以我将其简化为x^2 - y^2

在没有任何周围代码的情况下,这种转换使其成本更高,而不是更少。 add/sub 比乘法便宜:更好的吞吐量和更低的延迟。在 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)

英特尔 SnB 系列上的 4 个周期延迟。 (3 周期 imul,并且 lea/sub 可以并行运行。http://agner.org/optimize/)。对比

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

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

但是,如果 xy 是不变的,您可以用这种方式更便宜地计算一个新的 (x+y) * (x-y),只需 2 条指令,CSEing 不会改变的正方形。

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

【讨论】:

  • 微架构是什么意思?手臂没有微编码,这通常是 CISC 的事情。因此 RISC 的意义...
  • @old_timer:en.wikipedia.org/wiki/Microarchitecture。外部可见 ISA 的内部实现。两个 CPU 可以完全兼容软件(实现相同的架构),但具有不同的内部结构(不同的微架构)。感谢您确认它是早期 ARM 中的一个东西,现在已经消失了。我不知道该用 google 找到比 ARM 的大量相同文档副本更权威的东西。
  • @old_timer:完全不相关,但some ARM instructions are micro-coded。一个典型的例子是 LDMIA(最多弹出 16 个寄存器)。 As David Kanter points out,在执行过程中处理中断或故障基本上需要对其进行 ucoded 实现,这就是为什么 AArch64 仅将其删除为加载/存储对。要真正避免微代码,您需要像 MIPS 那样非常积极地简化。这不一定是好事。
  • 我们已经讨论过了,它绝不要求状态机工作得很好,如果不是更好的话,因为开销要少得多。该指令没有太多意义,因此没有理由在重做时保留它。在发明它时没有预期的价值。很酷的指令,但副作用很糟糕。
  • 说虽然很明显有两个指令集被解码到同一个管道中,一个正在翻译到另一个,原来的拇指很明显,在手册中打印了翻译,他们今天是怎么做到的?不知道,但很明显它就在那里。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-19
  • 1970-01-01
  • 2020-10-10
  • 1970-01-01
  • 2023-02-01
  • 2014-06-12
相关资源
最近更新 更多