开发者

"Immediate out of range errors" when assigning 0.0 to a NEON register

开发者 https://www.devze.com 2023-04-12 01:07 出处:网络
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 ra

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


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?


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


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"


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号