DSP SIMD для Flipper Zero
В этом версии нет никакой защиты цикла от чтения за границей буфера, мне показалось, что во «Флиппере» это неважно, но возможно это не так.
Ну что ж, разобрался я что за зверь такой этот DSP SIMD и запрограммировал на нём векторизированную версию функции для измерения длины строки.
Сегодня описывать и замерять уже не буду, и так времени много ушло, но по крайней мере всё работает на настоящем «Флиппере».
Сразу можно заметить, что вектора тут вдвое короче — всего четыре байта, да и функций для работы с ними гораздо меньше, но этого набора оказалось достаточно, чтобы всё векторизовать.
#include <arm_acle.h>
size_t strlen_arm_utf8(char * str) {
uint32_t len = 0;
int8x4_t zero = 0x00000000;
int8x4_t one = 0x01010101;
int8x4_t threshold = -1077952577; // -65, -65, -65, -65
for (;;) {
uint8x4_t result;
int8x4_t vec = *(int8x4_t *) str;
__uadd8(0xFFFFFFFF, vec); result = __sel(zero, one);
if (result > 0) {
if (result == 0x01000000) {
__ssub8(threshold, vec); result = __sel(zero, one);
return __usada8(result, 1, len);
}
break;
}
__ssub8(threshold, vec); result = __sel(zero, one);
len = __usada8(result, zero, len);
str += sizeof(uint8x4_t);
}
for (signed char c; (c = *str); str++) {
if (c >= -64) {
len++;
}
}
return len;
}