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

时间:2011-10-11 14:28:27

标签: android assembly android-ndk arm neon

如果我理解正确,因为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的立即值分配给单个字浮点寄存器而无需从其他地方转换它?如果有一个很好的理由它不应该首先工作,请告诉我。我正在使用GNU汇编程序和Android NDK构建工具。

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

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

4 个答案:

答案 0 :(得分:3)

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。你是不是有理由不使用它?

答案 1 :(得分:1)

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

答案 2 :(得分:1)

用于分配" 0"到寄存器(如果它的通用寄存器或NEON向量不重要)就这样做:

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

答案 3 :(得分:0)

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

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

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

或1.0 *(2 ^ -129),我不记得确切。