“立即超出范围错误”将 0.0 分配给 NEON 寄存器时

发布于 2024-12-09 03:43:23 字数 622 浏览 0 评论 0原文

如果我理解正确的话,因为 ARM 指令是 32 位长,所以它们只能保存这么多位的立即值。我想要做的是 vmov.f32 s0, #0.0,但出现“立即超出范围”编译器错误。奇怪的是,当我使用立即值时,比如 #0.5#0.25 (都非常整齐地以二进制表示),我的代码会编译。当我尝试分配立即值 #0.1 时,出现“遵循指令后出现垃圾”错误,如果它尝试用更多位表示这些值,则这是有意义的可以适合 ARM 指令。 #0.0 情况是我得到“立即超出范围”的唯一情况,因此我认为如果没有其他解释,这一定是一个错误。

有谁知道如何将 #0.0 的立即值分配给单字浮点寄存器,而无需从其他地方转换它?如果有充分的理由它一开始就不起作用,也请告诉我。我正在使用 GNU 汇编器和 Android NDK 构建工具。

更新vmov.f32 d0, #0.0 确实工作。它变得越来越没有意义。

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

If I understand it correctly, because ARM instructions are 32 bits long they can only hold so many bits of immediate value. What I'm trying to do is vmov.f32 s0, #0.0, and I get "immediate out of range" compiler error. Strange thing is that when I use an immediate value of, say #0.5 or #0.25 (all very neatly represented in binary), my code compiles. When I try to assign an immediate value of #0.1, I get the "garbage after following instruction" error, which makes sense if it's trying to represent those values with more bits that can fit into an ARM instruction. The #0.0 case is the only one where I get "immediate out of range", so I'm thinking it's got to be a bug if there's no other explanation.

Does anyone know how to assign an immediate value of #0.0 to a single word floating point register without having to convert it from somewhere else? If there's a good reason it shouldn't work in the first place, please let me know as well. I'm using GNU assembler with Android NDK build tool.

Update:
vmov.f32 d0, #0.0 does work. It keeps making less and less sense.

Update 2:
This doesn't work either: vmov.s32 s0, #0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

猫瑾少女 2024-12-16 03:43:23

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

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

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

然而,如果您只想将 NEON 寄存器清零,首选习惯用法通常是veor d0, d0。您有什么理由不使用它吗?

0.0 is not representable as a VFP/NEON floating-point immediate. Representable floating-point immediates are between 1/8 and 31 in magnitude, which zero clearly isn't.

The corresponding bit pattern, however, is representable as an integer NEON immediate. Your assembler is being helpful and generating this encoding for you instead of an (impossible) floating-point immediate; when you write vmov.f32 d0, #0.0 it actually emits vmov.s32 d0, #0, which has the same effect as what you appear to be trying to do, but is actually a legal instruction.

vmov.s32 s0, #0 doesn't make any sense; NEON does not provide any instructions that operate on s registers.

If you just want to zero a NEON register, however, the preferred idiom is usually veor d0, d0. Is there a reason that you aren't using that?

苹果你个爱泡泡 2024-12-16 03:43:23

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

If you want to assign 0 to an s register, you can easily do by using the instruction:
vsub.f32 s0, s0, s0

空名 2024-12-16 03:43:23

要将“0”分配给寄存器(不管它是通用寄存器还是 NEON 向量)只需执行以下操作:

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

For assigning "0" to a register(doesn't matter if it's general register or NEON vector) just do this:

"eor s0, s0, s0 \n\t"
身边 2024-12-16 03:43:23

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

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

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

或 1.0 * (2^-129),我不太记得了。

You could simply use this :
vmov.u32 d0, #0

because 0x00000000 is interpreted as 0.0f as well.

FYI, there can't be any "true" zero in float. It's actually 1.0 * (2^-128)

or 1.0 * (2^-129), I don't remember exactly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文