Инструкция NEON SSUBL имеет неверный результат? 127-220 = 0x00a3 (должно быть 0xffa3)

#arm #neon #arm64 #armasm

#arm #neon #arm64 #armasm

Вопрос:

У меня проблема при использовании ssubl инструкции в наборе команд A64.

Я просто хочу вычесть постоянное значение из 8-байтового SIMD-вектора. Поскольку результат может включать отрицательное число, я использую ssubl для расширения диапазона данных и выполнения вычитания со знаком.

Вот мой код:

 mov w4, #127    // set a const
mov w5, #220    // set another const

dup v1.16b, w4  // move the const to a vector
dup v2.16b, w5  // move the const to a vector

ssubl v3.8h, v1.8b, v2.8b // long type vector subtraction, 127-220
  

Я проверил результат в векторном регистре v1, v2 и v3:

  • v1: все 0x7f (десятичное число 127)
  • v2: все 0xdc (десятичное число 220)
  • v3: все 0x00a3 (163 после запятой), НЕВЕРНО

[127-220 = -93 (0xffa3), ПРАВИЛЬНО]

Я думаю, что значение в v3 должно быть 0xff5d, поскольку это отрицательное число. Но почему это не так?


На самом деле, после нескольких тестов я обнаружил, что эта проблема не связана со значением в w5 , независимо от того, 220 или 230 или другое значение. Пока значение в w4 меньше или равно 127, результат вычитания неверен.

Итак, если мы используем тот же код, но изменим значение w4 на 128 или больше:

 mov w4, #128    // set a const
mov w5, #220    // set another const

dup v1.16b, w4  // move the const to a vector
dup v2.16b, w5  // move the const to a vector

ssubl v3.8h, v1.8b, v2.8b // long type vector subtraction, 128-220
  

Результаты теперь таковы:

  • v1: все 0x80 (десятичное число 128)
  • v2: все 0xdc (десятичное число 220)
  • v3: все 0xffa4 (десятичное число -92), ПРАВИЛЬНЫЕ

[128 — 220 = -92 (0xffa4), ПРАВИЛЬНО]

Теперь результаты верны, и я также пробовал использовать 150, 250 в w5 , все результаты верны. Проблема связана только со значением в w4 .

Кто-нибудь может это объяснить?

Спасибо!

Комментарии:

1. Возможно, вы захотите рассмотреть, что будет представлять восьмибитовое целое число, которому вы присваиваете 220 , при интерпретации как подписанное ssubl .

2. @EOF: речь идет не о 220. Я пробовал 150, 250 для w5 . Результат связан только со значением в w4

3. Вероятно, вы хотите, usubl чтобы входные операнды были без знака. Результат вычитания является как подписанным, так и беззнаковым, и вам решать, как его интерпретировать, но поскольку входные операнды должны быть либо с расширением до нуля, либо со знаком, важно указать это.

4. 127 - (-36) == 163 — кажется законным. Помните, что вы выполняете вычитание операндов со знаком в байтах (что дает результат в виде полуслова со знаком) ssubl . Каким вы ожидали быть знаковое байтовое представление 220?

5. @sh1: Да, я пробовал usubl , который дает правильный результат. Я думаю, да, usubl и ssubl заботятся только о том, являются ли операнды подписанными / неподписанными

Ответ №1:

(Опубликовал решение от имени OP).

Используйте usubl вместо ssubl для выполнения вычитания.

Похоже, что usubl и ssubl заботятся только о том, являются ли операнды подписанными / неподписанными.