Сборка: преобразовать значение с плавающей точкой в ​​подписанный байт - PullRequest
1 голос
/ 19 января 2010

В настоящее время я пытаюсь написать программу для VFP-устройства iPhone, используя код сборки ARM. VFP может выполнять вычисления с плавающей запятой, но в AFAIK нет целочисленной арифметики. Однако он может преобразовать число с плавающей запятой в целое число со знаком (4 байта). Кроме того, согласно этой быстрой ссылке: http://www.voti.nl/hvu/arm/ARMquickref.pdf кажется, он не поддерживает какие-либо операции переключения

я хотел бы преобразовать 4 числа с плавающей точкой, из которых, я уверен, каждый больше -127 и меньше 127 в 4 байта со знаком.

Если бы у меня были доступны операции сдвига, я мог бы преобразовать число с плавающей запятой в целое число со знаком, а затем сдвинуть значение на 12 байтов влево (8 и 4 байта для следующих двух значений соответственно) и поразрядно ИЛИ все четыре вместе.

однако, поскольку смещение недоступно, мне нужно найти другой способ сделать это. Кроме того - я не могу использовать целочисленную арифметику (поэтому я не могу умножить уже преобразованное целое число на 2 ^ n для сдвига, но вместо этого мне нужно работать с плавающей точкой).

Кто-нибудь знает, как мне этого добиться?

кстати для тех, кто знаком с архитектурой ARM - я не хочу переключаться на инструкции Thumb, потому что это делается в цикле, работающем на многих элементах, и я не хочу переключаться между инструкциями большого пальца и руки в этом цикле (так как это дорого)

Спасибо!

редактирование:

дополнительный вопрос: как мне нормализовать Вектор с тремя элементами?

1 Ответ

2 голосов
/ 19 января 2010

Требуется инструкция VFP ftosis, которая преобразует значение FP одинарной точности в 4-байтовое целое число. Если у вас есть четыре числа с плавающей точкой в ​​s0-s3, то после выполнения:

ftosis s0, s0
ftosis s1, s1
ftosis s2, s2
ftosis s3, s3

у вас есть четыре 4-байтовых целых числа в s0-s3, которые можно хранить непрерывно в памяти с помощью fstm.

На процессоре ARM, который поддерживает NEON, вы можете использовать vcvt.s32.f32 q0, q0, чтобы выполнить четыре преобразования с одной инструкцией.


Изменить , чтобы ответить на ваш дополнительный вопрос, вот простой пример функции, которая принимает в качестве входных данных указатель на четыре числа в памяти и возвращает преобразованные значения, упакованные в один int32_t:

_floatToPackedInt:
    fldmias   r0,  {s4-s7}
    ftosizs   s0,   s4
    ftosizs   s1,   s5
    ftosizs   s2,   s6
    ftosizs   s3,   s7
    fmrrs r0, r1,  {s0,s1}
    fmrrs r2, r3,  {s2,s3}
    uxtb      r0,   r0
    uxtb      r1,   r1
    uxtb      r2,   r2
    orr       r0,   r0, r1, lsl #8
    orr       r0,   r0, r2, lsl #16
    orr       r0,   r0, r3, lsl #24
    bx        lr

На самом деле я не приложил никаких усилий для настройки этого, потому что вы не хотели бы делать преобразования таким образом, если бы они критиковали производительность; Вы бы предпочли либо работать с большими массивами значений, и передавать этот код так, чтобы несколько преобразований выполнялись одновременно, либо чередовать его с другими операциями, которые также выполняют полезную работу.

Вы также можете вставить ssat с перед uxtb с, чтобы любые значения вне диапазона насыщались вместо переноса.

Также помните, что этот код будет иметь низкую производительность на ядрах ARMv7; Вы определенно захотите использовать векторные операции NEON на этой платформе.

...