【问题标题】:"Immediate out of range errors" when assigning 0.0 to a NEON register将 0.0 分配给 NEON 寄存器时出现“立即超出范围错误”
【发布时间】:2011-10-11 14:28:27
【问题描述】:

如果我理解正确的话,因为 ARM 指令是 32 位长,它们只能保存这么多位立即数。我想要做的是vmov.f32 s0, #0.0,我得到“immediate out of range”编译器错误。奇怪的是,当我使用即时值,比如#0.5#0.25(都非常整齐地以二进制表示)时,我的代码会编译。当我尝试分配 #0.1 的立即值时,我得到“garbage after following instruction”错误,如果它试图用更多可以适合 ARM 指令的位来表示这些值,这是有道理的。 #0.0 案例是唯一一个我得到“immediate out of range”的案例,所以我认为如果没有其他解释,这一定是一个错误。

有谁知道如何将#0.0 的立即值分配给单个字浮点寄存器,而无需从其他地方进行转换?如果有充分的理由它不应该首先工作,请让我知道。我正在使用带有 Android NDK 构建工具的 GNU 汇编器。

更新vmov.f32 d0, #0.0 确实工作。它的意义越来越小。

更新 2: 这也不起作用:vmov.s32 s0, #0

【问题讨论】:

  • 我没有做过任何 ARM 组装。但是只是出于好奇查看了说明以了解您在说什么。所以请原谅我可能天真的问题:s32 的指定不是“有符号整数”类型吗?你确定你不是要使用vmov.f32 #0.0
  • @HostileFork 你是对的。这是一个错字。更正问题。
  • 您缺少第一个操作数的寄存器 - 还是另一个错字?您可以发布导致问题的实际行代码吗?
  • 在“只是阅读文档”中更进一步......它说立即模式下的 VMOV 应该与 Qd or Dd 一起使用,它们是 Neon 寄存器,而 s 寄存器是 VFP。也许您遇到了未定义行为的问题?另外,请注意 [b] cmets:“任何可以表示为 +/- n * 2^(-r) 的数字,其中 n 和 r 是整数,16 infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204h/…

标签: android assembly android-ndk arm neon


【解决方案1】:

0.0 不能表示为 VFP/NEON 浮点立即数。可表示的浮点立即数的大小在 1/8 到 31 之间,而零显然不是。

相应的位模式,然而,可以表示为一个整数 NEON 立即数。您的汇编程序正在为您提供帮助并为您生成此编码,而不是(不可能的)浮点立即数;当您编写 vmov.f32 d0, #0.0 时,它实际上会发出 vmov.s32 d0, #0,这与您似乎正在尝试做的事情具有相同的效果,但实际上是一个合法的指令。

vmov.s32 s0, #0 没有任何意义; NEON 不提供对s 寄存器进行操作的任何指令。

但是,如果您只想将 NEON 寄存器归零,首选的习惯用法通常是 veor d0, d0。你不使用它有什么原因吗?

【讨论】:

  • veor 0o, d0 没有任何问题,我只是从未想过这个解决方案。 = ) 0.0 在 VFP/NEON innediate 中无法表示是否有特殊原因,是否对此有很好的深入阅读?
  • @Phonon:原因很简单:它们只有 8 位用于表示立即数,并且他们不想将它们浪费在您可以通过其他方式产生的值上(整数立即或veor)。至于阅读,我会参考ARM架构参考手册。
【解决方案2】:

如果要将 0 分配给 s 寄存器,可以使用以下指令轻松完成: vsub.f32 s0, s0, s0

【讨论】:

  • 当 s0 中的前一个值不是正常数字(例如 +-Inf,NaN)时,Thid 不起作用,在这种情况下,您将在寄存器中获得 NaN。
【解决方案3】:

要将“0”分配给寄存器(不管是通用寄存器还是 NEON 向量),只需这样做:

"eor s0, s0, s0 \n\t"

【讨论】:

    【解决方案4】:

    你可以简单地使用这个: vmov.u32 d0, #0

    因为 0x00000000 也被解释为 0.0f。

    仅供参考,浮点数中不能有任何“真正的”零。实际上是 1.0 * (2^-128)

    还是 1.0 * (2^-129),具体我记不太清了。

    【讨论】:

    • 没有。 0x00000000 确实是正好 0.0。 (0x80000000 也是如此)。
    • @StephenCanon 阅读 IEEE754 规格表。
    • 杰克,我通常不喜欢诉诸权威,但我会例外:我是 IEEE-754 委员会的成员。因此,当我说 IEEE-754 浮点格式中确实存在精确零时,请相信我。 0x00000000 正好是 0.0。 0x80000000 正好是 -0.0。
    • 不,我宁愿相信官方文件,也不愿相信曾经是某人的人。而且,我一直在说“零”,而你却无缘无故地教我“0.0”和“-0.0”。有什么意义?
    • “0.0”和“-0.0”“零”。如果您坚持引用,请参阅第 3.3 节“在每种格式中,应表示以下浮点数据:有符号零 ...”(强调我的)。如果您更喜欢该标准的先前 (1985) 修订版,那么您将需要第 3.2 条:“如果 e=0f=0 ,则 v=(-1)^s 0 (zero)”
    猜你喜欢
    • 2019-10-27
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 2017-06-28
    相关资源
    最近更新 更多