首页 > 解决方案 > 装配中立即超出范围

问题描述

当我编译代码时

"VMOV.I16    q1, #2730; "

我有一个错误

 Error:  immediate out of range

这个错误的原因可能是什么?我知道 S16 在 [-32768,32767] 内,如果我在寄存器 Q 或 D 中存储常量 2730 该怎么办?谢谢!

标签: assemblyarminline-assemblyneon

解决方案


每条 ARM 指令都是 32 位宽的,并且只有有限数量的位专用于立即值 - 如果有的话。

2730 是十六进制的 0xaaa,如您所见,您需要 11 位来表示文字,并且vmov只接受 8 位和两位左移: 8bit<<(n*8); 其中 n 可以是 0 到 3

将任何 16 位值加载到 NEON 寄存器中的最佳方法是(在您的情况下为 2730):

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

movw是接受 16 位文字的 ARM 指令,并且是 NEON 指令,除了源操作数是 ARM 整数寄存器而不是立即值之外vdup.n,它的作用相同。vmov.in


替代方式:

您可以将任何 8 位值加载到 NEON 寄存器中;您使用值 0xaa 进行 8 位加载,然后清除 16 位值的最高有效四位

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

但是请注意,这仅是因为在您的情况下,位 16~19 与位 0~3 相同。


推荐阅读