Loading...
Searching...
No Matches
volk_8u_conv_k7_r2puppet_8u.h
Go to the documentation of this file.
/* -*- c++ -*- */
/*
* Copyright 2014 Free Software Foundation, Inc.
*
* This file is part of VOLK
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef INCLUDED_volk_8u_conv_k7_r2puppet_8u_H
#define INCLUDED_volk_8u_conv_k7_r2puppet_8u_H
#include <string.h>
#include <volk/volk.h>
#include <volk/volk_8u_x4_conv_k7_r2_8u.h>
typedef union {
// decision_t is a BIT vector
unsigned char* t;
unsigned int* w;
} p_decision_t;
static inline int parity(int x)
{
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return x & 1;
}
static inline int chainback_viterbi(unsigned char* data,
unsigned int nbits,
unsigned int endstate,
unsigned int tailsize,
unsigned char* decisions)
{
unsigned char* d;
int d_ADDSHIFT = 0;
int d_numstates = (1 << 6);
int d_decision_t_size = d_numstates / 8;
unsigned int d_k = 7;
int d_framebits = nbits;
/* ADDSHIFT and SUBSHIFT make sure that the thing returned is a byte. */
d = decisions;
/* Make room beyond the end of the encoder register so we can
* accumulate a full byte of decoded data
*/
endstate = (endstate % d_numstates) << d_ADDSHIFT;
/* The store into data[] only needs to be done every 8 bits.
* But this avoids a conditional branch, and the writes will
* combine in the cache anyway
*/
d += tailsize * d_decision_t_size; /* Look past tail */
int retval;
int dif = tailsize - (d_k - 1);
// printf("break, %d, %d\n", dif, (nbits+dif)%d_framebits);
p_decision_t dec;
while (nbits-- > d_framebits - (d_k - 1)) {
int k;
dec.t = &d[nbits * d_decision_t_size];
k = (dec.w[(endstate >> d_ADDSHIFT) / 32] >> ((endstate >> d_ADDSHIFT) % 32)) & 1;
endstate = (endstate >> 1) | (k << (d_k - 2 + d_ADDSHIFT));
// data[((nbits+dif)%nbits)>>3] = endstate>>d_SUBSHIFT;
// printf("%d, %d\n", k, (nbits+dif)%d_framebits);
data[((nbits + dif) % d_framebits)] = k;
retval = endstate;
}
nbits += 1;
while (nbits-- != 0) {
int k;
dec.t = &d[nbits * d_decision_t_size];
k = (dec.w[(endstate >> d_ADDSHIFT) / 32] >> ((endstate >> d_ADDSHIFT) % 32)) & 1;
endstate = (endstate >> 1) | (k << (d_k - 2 + d_ADDSHIFT));
data[((nbits + dif) % d_framebits)] = k;
}
// printf("%d, %d, %d, %d, %d, %d, %d, %d\n",
// data[4095],data[4094],data[4093],data[4092],data[4091],data[4090],data[4089],data[4088]);
return retval >> d_ADDSHIFT;
}
#if LV_HAVE_SSE3
#include <emmintrin.h>
#include <mmintrin.h>
#include <pmmintrin.h>
#include <stdio.h>
#include <xmmintrin.h>
static inline void volk_8u_conv_k7_r2puppet_8u_spiral(unsigned char* dec,
unsigned char* syms,
unsigned int framebits)
{
if (framebits < 12) {
return;
}
static int once = 1;
int d_numstates = (1 << 6);
int rate = 2;
static unsigned char* D;
static unsigned char* Y;
static unsigned char* X;
static unsigned int excess = 6;
static unsigned char* Branchtab;
int d_polys[2] = { 79, 109 };
if (once) {
X = (unsigned char*)volk_malloc(2 * d_numstates, volk_get_alignment());
Y = X + d_numstates;
Branchtab =
(unsigned char*)volk_malloc(d_numstates / 2 * rate, volk_get_alignment());
D = (unsigned char*)volk_malloc((d_numstates / 8) * (framebits + 6),
volk_get_alignment());
int state, i;
/* Initialize the branch table */
for (state = 0; state < d_numstates / 2; state++) {
for (i = 0; i < rate; i++) {
Branchtab[i * d_numstates / 2 + state] =
parity((2 * state) & d_polys[i]) ? 255 : 0;
}
}
once = 0;
}
// unbias the old_metrics
memset(X, 31, d_numstates);
// initialize decisions
memset(D, 0, (d_numstates / 8) * (framebits + 6));
volk_8u_x4_conv_k7_r2_8u_spiral(
Y, X, syms, D, framebits / 2 - excess, excess, Branchtab);
unsigned int min = X[0];
int i = 0, state = 0;
for (i = 0; i < (d_numstates); ++i) {
if (X[i] < min) {
min = X[i];
state = i;
}
}
chainback_viterbi(dec, framebits / 2 - excess, state, excess, D);
return;
}
#endif /*LV_HAVE_SSE3*/
#if LV_HAVE_NEON
static inline void volk_8u_conv_k7_r2puppet_8u_neonspiral(unsigned char* dec,
unsigned char* syms,
unsigned int framebits)
{
if (framebits < 12) {
return;
}
static int once = 1;
int d_numstates = (1 << 6);
int rate = 2;
static unsigned char* D;
static unsigned char* Y;
static unsigned char* X;
static unsigned int excess = 6;
static unsigned char* Branchtab;
int d_polys[2] = { 79, 109 };
if (once) {
X = (unsigned char*)volk_malloc(2 * d_numstates, volk_get_alignment());
Y = X + d_numstates;
Branchtab =
(unsigned char*)volk_malloc(d_numstates / 2 * rate, volk_get_alignment());
D = (unsigned char*)volk_malloc((d_numstates / 8) * (framebits + 6),
volk_get_alignment());
int state, i;
/* Initialize the branch table */
for (state = 0; state < d_numstates / 2; state++) {
for (i = 0; i < rate; i++) {
Branchtab[i * d_numstates / 2 + state] =
parity((2 * state) & d_polys[i]) ? 255 : 0;
}
}
once = 0;
}
// unbias the old_metrics
memset(X, 31, d_numstates);
// initialize decisions
memset(D, 0, (d_numstates / 8) * (framebits + 6));
volk_8u_x4_conv_k7_r2_8u_neonspiral(
Y, X, syms, D, framebits / 2 - excess, excess, Branchtab);
unsigned int min = X[0];
int i = 0, state = 0;
for (i = 0; i < (d_numstates); ++i) {
if (X[i] < min) {
min = X[i];
state = i;
}
}
chainback_viterbi(dec, framebits / 2 - excess, state, excess, D);
return;
}
#endif /*LV_HAVE_NEON*/
#if LV_HAVE_AVX2
#include <immintrin.h>
#include <stdio.h>
static inline void volk_8u_conv_k7_r2puppet_8u_avx2(unsigned char* dec,
unsigned char* syms,
unsigned int framebits)
{
if (framebits < 12) {
return;
}
static int once = 1;
int d_numstates = (1 << 6);
int rate = 2;
static unsigned char* D;
static unsigned char* Y;
static unsigned char* X;
static unsigned int excess = 6;
static unsigned char* Branchtab;
int d_polys[2] = { 79, 109 };
if (once) {
X = (unsigned char*)volk_malloc(2 * d_numstates, volk_get_alignment());
Y = X + d_numstates;
Branchtab =
(unsigned char*)volk_malloc(d_numstates / 2 * rate, volk_get_alignment());
D = (unsigned char*)volk_malloc((d_numstates / 8) * (framebits + 6),
volk_get_alignment());
int state, i;
/* Initialize the branch table */
for (state = 0; state < d_numstates / 2; state++) {
for (i = 0; i < rate; i++) {
Branchtab[i * d_numstates / 2 + state] =
parity((2 * state) & d_polys[i]) ? 255 : 0;
}
}
once = 0;
}
// unbias the old_metrics
memset(X, 31, d_numstates);
// initialize decisions
memset(D, 0, (d_numstates / 8) * (framebits + 6));
volk_8u_x4_conv_k7_r2_8u_avx2(
Y, X, syms, D, framebits / 2 - excess, excess, Branchtab);
unsigned int min = X[0];
int i = 0, state = 0;
for (i = 0; i < (d_numstates); ++i) {
if (X[i] < min) {
min = X[i];
state = i;
}
}
chainback_viterbi(dec, framebits / 2 - excess, state, excess, D);
return;
}
#endif /*LV_HAVE_AVX2*/
#if LV_HAVE_GENERIC
static inline void volk_8u_conv_k7_r2puppet_8u_generic(unsigned char* dec,
unsigned char* syms,
unsigned int framebits)
{
if (framebits < 12) {
return;
}
static int once = 1;
int d_numstates = (1 << 6);
int rate = 2;
static unsigned char* Y;
static unsigned char* X;
static unsigned char* D;
static unsigned int excess = 6;
static unsigned char* Branchtab;
int d_polys[2] = { 79, 109 };
if (once) {
X = (unsigned char*)volk_malloc(2 * d_numstates, volk_get_alignment());
Y = X + d_numstates;
Branchtab =
(unsigned char*)volk_malloc(d_numstates / 2 * rate, volk_get_alignment());
D = (unsigned char*)volk_malloc((d_numstates / 8) * (framebits + 6),
volk_get_alignment());
int state, i;
/* Initialize the branch table */
for (state = 0; state < d_numstates / 2; state++) {
for (i = 0; i < rate; i++) {
Branchtab[i * d_numstates / 2 + state] =
parity((2 * state) & d_polys[i]) ? 255 : 0;
}
}
once = 0;
}
// unbias the old_metrics
memset(X, 31, d_numstates);
// initialize decisions
memset(D, 0, (d_numstates / 8) * (framebits + 6));
volk_8u_x4_conv_k7_r2_8u_generic(
Y, X, syms, D, framebits / 2 - excess, excess, Branchtab);
unsigned int min = X[0];
int i = 0, state = 0;
for (i = 0; i < (d_numstates); ++i) {
if (X[i] < min) {
min = X[i];
state = i;
}
}
chainback_viterbi(dec, framebits / 2 - excess, state, excess, D);
return;
}
#endif /* LV_HAVE_GENERIC */
#if LV_HAVE_RVV
#include <riscv_vector.h>
static inline void volk_8u_conv_k7_r2puppet_8u_rvv(unsigned char* dec,
unsigned char* syms,
unsigned int framebits)
{
if (framebits < 12)
return;
int d_numstates = (1 << 6);
static unsigned char* D;
static unsigned char* Y;
static unsigned char* X;
static unsigned int excess = 6;
static unsigned char* Branchtab;
static int once = 1;
if (once) {
once = 0;
X = (unsigned char*)volk_malloc(3 * d_numstates, volk_get_alignment());
Y = X + d_numstates;
Branchtab = Y + d_numstates;
D = (unsigned char*)volk_malloc((d_numstates / 8) * (framebits + 6),
volk_get_alignment());
/* Initialize the branch table */
for (size_t state = 0; state < d_numstates / 2; state++) {
Branchtab[state] = parity(state & 39) * 255;
Branchtab[state + d_numstates / 2] = parity(state & 54) * 255;
}
}
memset(X, 31, d_numstates); // unbias the old_metrics
memset(D, 0, (d_numstates / 8) * (framebits + 6)); // initialize decisions
volk_8u_x4_conv_k7_r2_8u_rvv(
Y, X, syms, D, framebits / 2 - excess, excess, Branchtab);
unsigned int min = X[0];
int i = 0, state = 0;
for (i = 0; i < d_numstates; ++i) {
if (X[i] < min) {
min = X[i];
state = i;
}
}
chainback_viterbi(dec, framebits / 2 - excess, state, excess, D);
return;
}
#endif /*LV_HAVE_RVV*/
#endif /*INCLUDED_volk_8u_conv_k7_r2puppet_8u_H*/