Загрузка данных



    
#include <stdint.h>

/**
 * Конвертация 8 элементов int16_t -> 8 элементов float.
 * Требуется массив из 8 float (32 байта) на выходе.
 */
void s16_to_float_neon(const int16_t* src, float* dst) {
    asm volatile (
        "ld1    {v0.8h}, [%[in]]        \n\t" // Загружаем 8x s16
        "sxtl   v1.4s, v0.4h            \n\t" // Расширяем младшие 4 до s32
        "sxtl2  v2.4s, v0.8h            \n\t" // Расширяем старшие 4 до s32
        "scvtf  v1.4s, v1.4s            \n\t" // Конвертируем младшие s32 -> float
        "scvtf  v2.4s, v2.4s            \n\t" // Конвертируем старшие s32 -> float
        "st1    {v1.4s, v2.4s}, [%[out]] \n\t" // Сохраняем 8 float (2 регистра)
        : 
        : [in] "r" (src), [out] "r" (dst)
        : "v0", "v1", "v2", "memory"
    );
}

/**
 * Конвертация 8 элементов float -> 8 элементов int16_t.
 * Использует округление к ближайшему и насыщение.
 */
void float_to_s16_neon(const float* src, int16_t* dst) {
    asm volatile (
        "ld1    {v1.4s, v2.4s}, [%[in]] \n\t" // Загружаем 8 float
        "fcvtns v1.4s, v1.4s            \n\t" // Округляем float -> s32 (Low)
        "fcvtns v2.4s, v2.4s            \n\t" // Округляем float -> s32 (High)
        "sqxtn  v0.4h, v1.4s            \n\t" // Сужаем s32 -> s16 с насыщением (Low)
        "sqxtn2 v0.8h, v2.4s            \n\t" // Сужаем s32 -> s16 с насыщением (High)
        "st1    {v0.8h}, [%[out]]       \n\t" // Сохраняем 8x s16
        : 
        : [in] "r" (src), [out] "r" (dst)
        : "v0", "v1", "v2", "memory"
    );
}