Сборка:преобразовать значение с плавающей запятой в байт со знаком

StackOverflow https://stackoverflow.com/questions/2089884

Вопрос

В настоящее время я пытаюсь написать программу для блока 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, потому что это делается в цикле, работающем со многими элементами, и я не хочу переключаться между инструкциями большого пальца и руки внутри этого цикла (поскольку это дорогой)

Спасибо!

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

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

Это было полезно?

Решение

Вы хотите 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перед uxtbs, чтобы любые значения, выходящие за пределы диапазона, насыщались вместо переноса.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top