Search code examples
assemblyarminline-assemblyneon

immediate out of range in assembly


when I compiled the code

"VMOV.I16    q1, #2730; "

I got an error of

 Error:  immediate out of range

What's may be the reason of this error?I knew that S16 is within [-32768,32767],and what should I do if I what to to store constant 2730 in register Q or D?thanks!


Solution

  • Every ARM instruction is 32bit wide, and only a limited number bits are dedicated to the immediate values - if at all.

    2730 is 0xaaa in hex, and as you can see, you need 11 bits to express the literal, and vmov only accepts 8 bits with a two bits for shift left: 8bit<<(n*8); where n can be 0 to 3

    The best way of loading ANY 16bit value into a NEON register is (2730 in your case):

    movw    %[temp], #2730
    vdup.16 q1, %[temp]
    

    movw is an ARM instruction that accepts 16bit literals, and vdup.n is a NEON instruction that does the same as vmov.in except the source operand is an ARM integer register instead of an immediate value.


    Alternate way:

    You can load any 8bit value into a NEON register; You make an 8bit load with the value 0xaa, then clear the most significant four bits of 16bit values

    vmov.i8     q1, #0xaa
    vbic.i16    q1, q1, #0xf000
    

    Pleas note that however, that this one works only because the bits 16~19 are the same as the bits 0~3 in your case.