«Немедленные ошибки вне диапазона» при назначении 0.0 в регистр NEON - PullRequest
1 голос
/ 11 октября 2011

Если я правильно понимаю, поскольку инструкции 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 ]

3 голосов
/ 12 октября 2011

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 голос
/ 02 марта 2016

Для присвоения «0» регистру (не имеет значения, является ли он общим регистром или вектором NEON), просто сделайте это:

"eor s0, s0, s0 \n\t"
1 голос
/ 16 декабря 2011

Если вы хотите присвоить 0 регистру s, вы можете легко сделать это, используя инструкцию: vsub.f32 s0, s0, s0

0 голосов
/ 01 ноября 2011

Вы можете просто использовать это: vmov.u32 d0, # 0

, потому что 0x00000000 также интерпретируется как 0.0f.

К вашему сведению, не может быть никакого «истинного» нуляв поплавке.На самом деле это 1,0 * (2 ^ -128)

или 1,0 * (2 ^ -129), точно не помню.

...