#include "streamvbyte.h"
#if defined(_MSC_VER)
#include <intrin.h>
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
#include <x86intrin.h>
#elif defined(__GNUC__) && defined(__ARM_NEON__)
#include <arm_neon.h>
#elif defined(__GNUC__) && defined(__IWMMXT__)
#include <mmintrin.h>
#elif (defined(__GNUC__) || defined(__xlC__)) && \
(defined(__VEC__) || defined(__ALTIVEC__))
#include <altivec.h>
#elif defined(__GNUC__) && defined(__SPE__)
#include <spe.h>
#endif
#include <string.h>
#include "streamvbyte_shuffle_tables_encode.h"
#ifdef STREAMVBYTE_SSSE3
#include "streamvbyte_x64_encode.c"
#else
static uint8_t _encode_data(uint32_t val, uint8_t *__restrict__ *dataPtrPtr) {
uint8_t *dataPtr = *dataPtrPtr;
uint8_t code;
if (val < (1 << 8)) { *dataPtr = (uint8_t)(val);
*dataPtrPtr += 1;
code = 0;
} else if (val < (1 << 16)) { memcpy(dataPtr, &val, 2); *dataPtrPtr += 2;
code = 1;
} else if (val < (1 << 24)) { memcpy(dataPtr, &val, 3); *dataPtrPtr += 3;
code = 2;
} else { memcpy(dataPtr, &val, sizeof(uint32_t));
*dataPtrPtr += sizeof(uint32_t);
code = 3;
}
return code;
}
static uint8_t *svb_encode_scalar(const uint32_t *in,
uint8_t *__restrict__ keyPtr,
uint8_t *__restrict__ dataPtr,
uint32_t count) {
if (count == 0)
return dataPtr;
uint8_t shift = 0; uint8_t key = 0;
for (uint32_t c = 0; c < count; c++) {
if (shift == 8) {
shift = 0;
*keyPtr++ = key;
key = 0;
}
uint32_t val = in[c];
uint8_t code = _encode_data(val, &dataPtr);
key |= code << shift;
shift += 2;
}
*keyPtr = key; return dataPtr; }
#endif
#ifdef __ARM_NEON__
#include "streamvbyte_arm_encode.c"
#endif
size_t __slow5_streamvbyte_encode(const uint32_t *in, uint32_t count, uint8_t *out) {
#ifdef STREAMVBYTE_SSSE3
return streamvbyte_encode_SSSE3(in,count,out);
#else
uint8_t *keyPtr = out;
uint32_t keyLen = (count + 3) / 4; uint8_t *dataPtr = keyPtr + keyLen;
#if defined(__ARM_NEON__)
uint32_t count_quads = count / 4;
count -= 4 * count_quads;
for (uint32_t c = 0; c < count_quads; c++) {
dataPtr += streamvbyte_encode_quad(in, dataPtr, keyPtr);
keyPtr++;
in += 4;
}
#endif
return svb_encode_scalar(in, keyPtr, dataPtr, count) - out;
#endif}