#include <stdint.h>
#include <stdio.h>
void process_signal(int16_t* input, int16_t* output) {
// Входные данные: 8 элементов int16
// Мы используем inline asm для конвертации туда-обратно
asm volatile (
// 1. Загружаем 8 значений int16 в V0
"ld1 {v0.8h}, [%[in]] \n\t"
// --- КОНВЕРТАЦИЯ int16 -> float ---
"sxtl v1.4s, v0.4h \n\t" // Младшие 4: s16 -> s32
"sxtl2 v2.4s, v0.8h \n\t" // Старшие 4: s16 -> s32
"scvtf v1.4s, v1.4s \n\t" // s32 -> float (Low)
"scvtf v2.4s, v2.4s \n\t" // s32 -> float (High)
// --- ЗДЕСЬ МОЖЕТ БЫТЬ ОБРАБОТКА (напр. умножение на 0.5) ---
"fmov v3.4s, #0.5 \n\t" // Константа 0.5
"fmul v1.4s, v1.4s, v3.4s \n\t"
"fmul v2.4s, v2.4s, v3.4s \n\t"
// --- КОНВЕРТАЦИЯ float -> int16 ---
"fcvtns v1.4s, v1.4s \n\t" // float -> s32 (округление)
"fcvtns v2.4s, v2.4s \n\t" // float -> s32
"sqxtn v0.4h, v1.4s \n\t" // s32 -> s16 (насыщение, Low)
"sqxtn2 v0.8h, v2.4s \n\t" // s32 -> s16 (насыщение, High)
// 2. Сохраняем результат
"st1 {v0.8h}, [%[out]] \n\t"
: // Нет выходных переменных в C-коде (пишем напрямую в память)
: [in] "r" (input), [out] "r" (output) // Входные параметры
: "v0", "v1", "v2", "v3", "memory" // Список испорченных регистров
);
}
int main() {
int16_t src[8] = {1000, -2000, 3000, -4000, 10000, -20000, 30000, -32000};
int16_t dst[8];
process_signal(src, dst);
for(int i=0; i<8; i++) printf("%d -> %d\n", src[i], dst[i]);
return 0;
}