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.0is 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.0it actually emitsvmov.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, #0doesn’t make any sense; NEON does not provide any instructions that operate onsregisters.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?