The case of a CRC == 0 is legal. After discussion with Raymond, it is also possible to have all bits at 0 (and so a CRC==0) if there is no transmission and thus not much energy. So this hotfix may introduce new problems (false decoding). A future work is to handle this case properly by not calling the turbo decoder if there is not enough energy received. The problem might manifest itself more in the UE part, especially when it tries to decode MIB and/or SIB (if I understood correctly).
1661 lines
58 KiB
C
1661 lines
58 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
|
* except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.openairinterface.org/?page_id=698
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
|
|
/* file: 3gpplte_turbo_decoder_sse_16bit.c
|
|
purpose: Routines for implementing max-logmap decoding of Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03
|
|
authors: raymond.knopp@eurecom.fr, Laurent Thomas (Alcatel-Lucent)
|
|
date: 21.10.2009
|
|
|
|
Note: This version of the routine currently requires SSE2,SSSE3 and SSE4.1 equipped computers. It uses 16-bit inputs for
|
|
LLRS and uses 16-bit arithmetic for the internal computations!
|
|
|
|
Changelog: 17.11.2009 FK SSE4.1 not required anymore
|
|
Aug. 2012 new parallelization options for higher speed (8-way parallelization)
|
|
Jan. 2013 8-bit LLR support with 16-way parallelization
|
|
Feb. 2013 New interleaving and hard-decision optimizations (L. Thomas)
|
|
May 2013 Extracted 16bit code
|
|
*/
|
|
|
|
///
|
|
///
|
|
|
|
#undef __AVX2__
|
|
#include "PHY/sse_intrin.h"
|
|
|
|
#ifndef TEST_DEBUG
|
|
#include "PHY/defs.h"
|
|
#include "PHY/CODING/defs.h"
|
|
#include "PHY/CODING/lte_interleaver_inline.h"
|
|
#include "extern_3GPPinterleaver.h"
|
|
#else
|
|
|
|
#include "defs.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#endif
|
|
|
|
#ifdef MEX
|
|
#include "mex.h"
|
|
#endif
|
|
|
|
//#define DEBUG_LOGMAP
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
#define print_shorts(s,x) fprintf(fdsse4,"%s %d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
|
|
#endif
|
|
|
|
#undef __AVX2__
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
FILE *fdsse4;
|
|
#endif
|
|
|
|
typedef int16_t llr_t; // internal decoder LLR data is 16-bit fixed
|
|
typedef int16_t channel_t;
|
|
#define MAX 256
|
|
|
|
void log_map16(llr_t* systematic,channel_t* y_parity, llr_t* m11, llr_t* m10, llr_t *alpha, llr_t *beta, llr_t* ext,unsigned short frame_length,unsigned char term_flag,unsigned char F,
|
|
int offset8_flag,time_stats_t *alpha_stats,time_stats_t *beta_stats,time_stats_t *gamma_stats,time_stats_t *ext_stats);
|
|
void compute_gamma16(llr_t* m11,llr_t* m10,llr_t* systematic, channel_t* y_parity, unsigned short frame_length,unsigned char term_flag);
|
|
void compute_alpha16(llr_t*alpha,llr_t *beta, llr_t* m11,llr_t* m10, unsigned short frame_length,unsigned char F);
|
|
void compute_beta16(llr_t*alpha, llr_t* beta,llr_t* m11,llr_t* m10, unsigned short frame_length,unsigned char F,int offset8_flag);
|
|
void compute_ext16(llr_t* alpha,llr_t* beta,llr_t* m11,llr_t* m10,llr_t* extrinsic, llr_t* ap, unsigned short frame_length);
|
|
|
|
|
|
void log_map16(llr_t* systematic,
|
|
channel_t* y_parity,
|
|
llr_t* m11,
|
|
llr_t* m10,
|
|
llr_t *alpha,
|
|
llr_t *beta,
|
|
llr_t* ext,
|
|
unsigned short frame_length,
|
|
unsigned char term_flag,
|
|
unsigned char F,
|
|
int offset8_flag,
|
|
time_stats_t *alpha_stats,
|
|
time_stats_t *beta_stats,
|
|
time_stats_t *gamma_stats,
|
|
time_stats_t *ext_stats)
|
|
{
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"log_map, frame_length %d\n",frame_length);
|
|
#endif
|
|
|
|
start_meas(gamma_stats) ;
|
|
compute_gamma16(m11,m10,systematic,y_parity,frame_length,term_flag) ;
|
|
stop_meas(gamma_stats);
|
|
start_meas(alpha_stats) ;
|
|
compute_alpha16(alpha,beta,m11,m10,frame_length,F) ;
|
|
stop_meas(alpha_stats);
|
|
start_meas(beta_stats) ;
|
|
compute_beta16(alpha,beta,m11,m10,frame_length,F,offset8_flag) ;
|
|
stop_meas(beta_stats);
|
|
start_meas(ext_stats) ;
|
|
compute_ext16(alpha,beta,m11,m10,ext,systematic,frame_length) ;
|
|
stop_meas(ext_stats);
|
|
|
|
|
|
}
|
|
|
|
void compute_gamma16(llr_t* m11,llr_t* m10,llr_t* systematic,channel_t* y_parity,
|
|
unsigned short frame_length,unsigned char term_flag)
|
|
{
|
|
int k,K1;
|
|
#if defined(__x86_64__)||defined(__i386__)
|
|
__m128i *systematic128 = (__m128i *)systematic;
|
|
__m128i *y_parity128 = (__m128i *)y_parity;
|
|
__m128i *m10_128 = (__m128i *)m10;
|
|
__m128i *m11_128 = (__m128i *)m11;
|
|
#elif defined(__arm__)
|
|
int16x8_t *systematic128 = (int16x8_t *)systematic;
|
|
int16x8_t *y_parity128 = (int16x8_t *)y_parity;
|
|
int16x8_t *m10_128 = (int16x8_t *)m10;
|
|
int16x8_t *m11_128 = (int16x8_t *)m11;
|
|
#endif
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"compute_gamma (sse_16bit), %p,%p,%p,%p,framelength %d\n",m11,m10,systematic,y_parity,frame_length);
|
|
#endif
|
|
|
|
#ifndef __AVX2__
|
|
K1=frame_length>>3;
|
|
#else
|
|
if ((frame_length&15) > 0)
|
|
K1=(frame_length+1)>>4;
|
|
else
|
|
K1=frame_length>>4;
|
|
#endif
|
|
|
|
for (k=0; k<K1; k++) {
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
#ifndef __AVX2__
|
|
m11_128[k] = _mm_srai_epi16(_mm_adds_epi16(systematic128[k],y_parity128[k]),1);
|
|
m10_128[k] = _mm_srai_epi16(_mm_subs_epi16(systematic128[k],y_parity128[k]),1);
|
|
#else
|
|
((__m256i*)m11_128)[k] = _mm256_srai_epi16(_mm256_adds_epi16(((__m256i*)systematic128)[k],((__m256i*)y_parity128)[k]),1);
|
|
// ((__m256i*)m10_128)[k] = _mm256_srai_epi16(_mm256_subs_epi16(((__m256i*)y_parity128)[k],((__m256i*)systematic128)[k]),1);
|
|
((__m256i*)m10_128)[k] = _mm256_srai_epi16(_mm256_subs_epi16(((__m256i*)systematic128)[k],((__m256i*)y_parity128)[k]),1);
|
|
#endif
|
|
#elif defined(__arm__)
|
|
m11_128[k] = vhaddq_s16(systematic128[k],y_parity128[k]);
|
|
m10_128[k] = vhsubq_s16(systematic128[k],y_parity128[k]);
|
|
#endif
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"Loop index k %d\n", k);
|
|
print_shorts("sys",(int16_t*)&systematic128[k]);
|
|
print_shorts("yp",(int16_t*)&y_parity128[k]);
|
|
print_shorts("m11",(int16_t*)&m11_128[k]);
|
|
print_shorts("m10",(int16_t*)&m10_128[k]);
|
|
#endif
|
|
}
|
|
|
|
k=frame_length>>3;
|
|
// Termination
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
m11_128[k] = _mm_srai_epi16(_mm_adds_epi16(systematic128[k+term_flag],y_parity128[k]),1);
|
|
//#ifndef __AVX2__
|
|
#if 1
|
|
m10_128[k] = _mm_srai_epi16(_mm_subs_epi16(systematic128[k+term_flag],y_parity128[k]),1);
|
|
#else
|
|
m10_128[k] = _mm_srai_epi16(_mm_subs_epi16(y_parity128[k],systematic128[k+term_flag]),1);
|
|
#endif
|
|
#elif defined(__arm__)
|
|
m11_128[k] = vhaddq_s16(systematic128[k+term_flag],y_parity128[k]);
|
|
m10_128[k] = vhsubq_s16(systematic128[k+term_flag],y_parity128[k]);
|
|
#endif
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"Loop index k %d (term flag %d)\n", k,term_flag);
|
|
print_shorts("sys",(int16_t*)&systematic128[k]);
|
|
print_shorts("yp",(int16_t*)&y_parity128[k]);
|
|
print_shorts("m11",(int16_t*)&m11_128[k]);
|
|
print_shorts("m10",(int16_t*)&m10_128[k]);
|
|
#endif
|
|
}
|
|
|
|
#define L 40
|
|
|
|
void compute_alpha16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,unsigned short frame_length,unsigned char F)
|
|
{
|
|
int k,l,l2,K1,rerun_flag=0;
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
__m128i *alpha128=(__m128i *)alpha,*alpha_ptr,*m11p,*m10p;
|
|
//#ifndef __AVX2__
|
|
#if 1
|
|
__m128i a0,a1,a2,a3,a4,a5,a6,a7;
|
|
__m128i m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
|
|
__m128i new0,new1,new2,new3,new4,new5,new6,new7;
|
|
__m128i alpha_max;
|
|
#else
|
|
__m256i *alpha256=(__m256i *)alpha,*alpha_ptr256,m11,m10;
|
|
__m256i a01,a23,a45,a67,a02,a13,a64,a75;
|
|
__m256i m_b01,m_b23,m_b45,m_b67,new01,new23,new45,new67;
|
|
__m256i m11m10_256;
|
|
__m256i alpha_max;
|
|
#endif
|
|
|
|
#elif defined(__arm__)
|
|
int16x8_t *alpha128=(int16x8_t *)alpha,*alpha_ptr;
|
|
int16x8_t a0,a1,a2,a3,a4,a5,a6,a7,*m11p,*m10p;
|
|
int16x8_t m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
|
|
int16x8_t new0,new1,new2,new3,new4,new5,new6,new7;
|
|
int16x8_t alpha_max;
|
|
#endif
|
|
l2 = L>>3;
|
|
K1 = (frame_length>>3);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"compute_alpha (sse_16bit)\n");
|
|
#endif
|
|
for (l=K1;; l=l2,rerun_flag=1) {
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
alpha128 = (__m128i *)alpha;
|
|
//#ifdef __AVX2__
|
|
#if 0
|
|
alpha256 = (__m256i *)alpha;
|
|
#endif
|
|
#elif defined(__arm__)
|
|
alpha128 = (int16x8_t *)alpha;
|
|
#endif
|
|
|
|
if (rerun_flag == 0) {
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
alpha128[0] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,0);
|
|
alpha128[1] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
|
|
alpha128[2] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
|
|
alpha128[3] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
|
|
alpha128[4] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
|
|
alpha128[5] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
|
|
alpha128[6] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
|
|
alpha128[7] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
|
|
#elif defined(__arm__)
|
|
alpha128[0] = vdupq_n_s16(-MAX/2);
|
|
alpha128[0] = vsetq_lane_s16(0,alpha128[0],0);
|
|
alpha128[1] = vdupq_n_s16(-MAX/2);
|
|
alpha128[2] = vdupq_n_s16(-MAX/2);
|
|
alpha128[3] = vdupq_n_s16(-MAX/2);
|
|
alpha128[4] = vdupq_n_s16(-MAX/2);
|
|
alpha128[5] = vdupq_n_s16(-MAX/2);
|
|
alpha128[6] = vdupq_n_s16(-MAX/2);
|
|
alpha128[7] = vdupq_n_s16(-MAX/2);
|
|
#endif
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"Initial alpha\n");
|
|
print_shorts("a0",(int16_t*)&alpha128[0]);
|
|
print_shorts("a1",(int16_t*)&alpha128[1]);
|
|
print_shorts("a2",(int16_t*)&alpha128[2]);
|
|
print_shorts("a3",(int16_t*)&alpha128[3]);
|
|
print_shorts("a4",(int16_t*)&alpha128[4]);
|
|
print_shorts("a5",(int16_t*)&alpha128[5]);
|
|
print_shorts("a6",(int16_t*)&alpha128[6]);
|
|
print_shorts("a7",(int16_t*)&alpha128[7]);
|
|
#endif
|
|
} else {
|
|
//set initial alpha in columns 1-7 from final alpha from last run in columns 0-6
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
alpha128[0] = _mm_slli_si128(alpha128[frame_length],2);
|
|
alpha128[1] = _mm_slli_si128(alpha128[1+frame_length],2);
|
|
alpha128[2] = _mm_slli_si128(alpha128[2+frame_length],2);
|
|
alpha128[3] = _mm_slli_si128(alpha128[3+frame_length],2);
|
|
alpha128[4] = _mm_slli_si128(alpha128[4+frame_length],2);
|
|
alpha128[5] = _mm_slli_si128(alpha128[5+frame_length],2);
|
|
alpha128[6] = _mm_slli_si128(alpha128[6+frame_length],2);
|
|
alpha128[7] = _mm_slli_si128(alpha128[7+frame_length],2);
|
|
#elif defined(__arm__)
|
|
alpha128[0] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[frame_length],16); alpha128[0] = vsetq_lane_s16(alpha[8],alpha128[0],3);
|
|
alpha128[1] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[1+frame_length],16); alpha128[1] = vsetq_lane_s16(alpha[24],alpha128[0],3);
|
|
alpha128[2] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[2+frame_length],16); alpha128[2] = vsetq_lane_s16(alpha[40],alpha128[0],3);
|
|
alpha128[3] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[3+frame_length],16); alpha128[3] = vsetq_lane_s16(alpha[56],alpha128[0],3);
|
|
alpha128[4] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[4+frame_length],16); alpha128[4] = vsetq_lane_s16(alpha[72],alpha128[0],3);
|
|
alpha128[5] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[5+frame_length],16); alpha128[5] = vsetq_lane_s16(alpha[88],alpha128[0],3);
|
|
alpha128[6] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[6+frame_length],16); alpha128[6] = vsetq_lane_s16(alpha[104],alpha128[0],3);
|
|
alpha128[7] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[7+frame_length],16); alpha128[7] = vsetq_lane_s16(alpha[120],alpha128[0],3);
|
|
#endif
|
|
// set initial alpha in column 0 to (0,-MAX/2,...,-MAX/2)
|
|
alpha[8] = -MAX/2;
|
|
alpha[16] = -MAX/2;
|
|
alpha[24] = -MAX/2;
|
|
alpha[32] = -MAX/2;
|
|
alpha[40] = -MAX/2;
|
|
alpha[48] = -MAX/2;
|
|
alpha[56] = -MAX/2;
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"Second run\n");
|
|
print_shorts("a0",(int16_t*)&alpha128[0]);
|
|
print_shorts("a1",(int16_t*)&alpha128[1]);
|
|
print_shorts("a2",(int16_t*)&alpha128[2]);
|
|
print_shorts("a3",(int16_t*)&alpha128[3]);
|
|
print_shorts("a4",(int16_t*)&alpha128[4]);
|
|
print_shorts("a5",(int16_t*)&alpha128[5]);
|
|
print_shorts("a6",(int16_t*)&alpha128[6]);
|
|
print_shorts("a7",(int16_t*)&alpha128[7]);
|
|
#endif
|
|
|
|
}
|
|
|
|
alpha_ptr = &alpha128[0];
|
|
//#ifdef __AVX2__
|
|
#if 0
|
|
alpha_ptr256 = &alpha256[0];
|
|
#endif
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
m11p = (__m128i*)m_11;
|
|
m10p = (__m128i*)m_10;
|
|
#elif defined(__arm__)
|
|
m11p = (int16x8_t*)m_11;
|
|
m10p = (int16x8_t*)m_10;
|
|
#endif
|
|
for (k=0;
|
|
k<l;
|
|
k++) {
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
//#ifndef __AVX2__
|
|
#if 1
|
|
a1=_mm_load_si128(&alpha_ptr[1]);
|
|
a3=_mm_load_si128(&alpha_ptr[3]);
|
|
a5=_mm_load_si128(&alpha_ptr[5]);
|
|
a7=_mm_load_si128(&alpha_ptr[7]);
|
|
|
|
m_b0 = _mm_adds_epi16(a1,*m11p); // m11
|
|
m_b4 = _mm_subs_epi16(a1,*m11p); // m00=-m11
|
|
m_b1 = _mm_subs_epi16(a3,*m10p); // m01=-m10
|
|
m_b5 = _mm_adds_epi16(a3,*m10p); // m10
|
|
m_b2 = _mm_adds_epi16(a5,*m10p); // m10
|
|
m_b6 = _mm_subs_epi16(a5,*m10p); // m01=-m10
|
|
m_b3 = _mm_subs_epi16(a7,*m11p); // m00=-m11
|
|
m_b7 = _mm_adds_epi16(a7,*m11p); // m11
|
|
|
|
a0=_mm_load_si128(&alpha_ptr[0]);
|
|
a2=_mm_load_si128(&alpha_ptr[2]);
|
|
a4=_mm_load_si128(&alpha_ptr[4]);
|
|
a6=_mm_load_si128(&alpha_ptr[6]);
|
|
|
|
new0 = _mm_subs_epi16(a0,*m11p); // m00=-m11
|
|
new4 = _mm_adds_epi16(a0,*m11p); // m11
|
|
new1 = _mm_adds_epi16(a2,*m10p); // m10
|
|
new5 = _mm_subs_epi16(a2,*m10p); // m01=-m10
|
|
new2 = _mm_subs_epi16(a4,*m10p); // m01=-m10
|
|
new6 = _mm_adds_epi16(a4,*m10p); // m10
|
|
new3 = _mm_adds_epi16(a6,*m11p); // m11
|
|
new7 = _mm_subs_epi16(a6,*m11p); // m00=-m11
|
|
|
|
a0 = _mm_max_epi16(m_b0,new0);
|
|
a1 = _mm_max_epi16(m_b1,new1);
|
|
a2 = _mm_max_epi16(m_b2,new2);
|
|
a3 = _mm_max_epi16(m_b3,new3);
|
|
a4 = _mm_max_epi16(m_b4,new4);
|
|
a5 = _mm_max_epi16(m_b5,new5);
|
|
a6 = _mm_max_epi16(m_b6,new6);
|
|
a7 = _mm_max_epi16(m_b7,new7);
|
|
|
|
alpha_max = _mm_max_epi16(a0,a1);
|
|
alpha_max = _mm_max_epi16(alpha_max,a2);
|
|
alpha_max = _mm_max_epi16(alpha_max,a3);
|
|
alpha_max = _mm_max_epi16(alpha_max,a4);
|
|
alpha_max = _mm_max_epi16(alpha_max,a5);
|
|
alpha_max = _mm_max_epi16(alpha_max,a6);
|
|
alpha_max = _mm_max_epi16(alpha_max,a7);
|
|
#else
|
|
a02=_mm256_load_si256(&alpha_ptr256[0]);
|
|
a13=_mm256_load_si256(&alpha_ptr256[1]);
|
|
a64=_mm256_load_si256(&alpha_ptr256[2]);
|
|
a75=_mm256_load_si256(&alpha_ptr256[3]);
|
|
m11m10_256 = _mm256_insertf128_si256(m11m10_256,*m11p,0);
|
|
m11m10_256 = _mm256_insertf128_si256(m11m10_256,*m10p,1);
|
|
|
|
|
|
m_b01 = _mm256_adds_epi16(a13,m11m10_256); //negative m10
|
|
m_b23 = _mm256_subs_epi16(a75,m11m10_256); //negative m10
|
|
m_b45 = _mm256_subs_epi16(a13,m11m10_256); //negative m10
|
|
m_b67 = _mm256_adds_epi16(a75,m11m10_256); //negative m10
|
|
|
|
new01 = _mm256_subs_epi16(a02,m11m10_256); //negative m10
|
|
new23 = _mm256_adds_epi16(a64,m11m10_256); //negative m10
|
|
new45 = _mm256_adds_epi16(a02,m11m10_256); //negative m10
|
|
new67 = _mm256_subs_epi16(a64,m11m10_256); //negative m10
|
|
|
|
a01 = _mm256_max_epi16(m_b01,new01);
|
|
a23 = _mm256_max_epi16(m_b23,new23);
|
|
a45 = _mm256_max_epi16(m_b45,new45);
|
|
a67 = _mm256_max_epi16(m_b67,new67);
|
|
|
|
alpha_max = _mm256_max_epi16(a01,a23);
|
|
alpha_max = _mm256_max_epi16(alpha_max,a45);
|
|
alpha_max = _mm256_max_epi16(alpha_max,a67);
|
|
alpha_max = _mm256_max_epi16(alpha_max,_mm256_permutevar8x32_epi32(alpha_max,_mm256_set_epi32(3,2,1,0,7,6,5,4)));
|
|
|
|
|
|
#endif
|
|
#elif defined(__arm__)
|
|
m_b0 = vqaddq_s16(alpha_ptr[1],*m11p); // m11
|
|
m_b4 = vqsubq_s16(alpha_ptr[1],*m11p); // m00=-m11
|
|
m_b1 = vqsubq_s16(alpha_ptr[3],*m10p); // m01=-m10
|
|
m_b5 = vqaddq_s16(alpha_ptr[3],*m10p); // m10
|
|
m_b2 = vqaddq_s16(alpha_ptr[5],*m10p); // m10
|
|
m_b6 = vqsubq_s16(alpha_ptr[5],*m10p); // m01=-m10
|
|
m_b3 = vqsubq_s16(alpha_ptr[7],*m11p); // m00=-m11
|
|
m_b7 = vqaddq_s16(alpha_ptr[7],*m11p); // m11
|
|
|
|
new0 = vqsubq_s16(alpha_ptr[0],*m11p); // m00=-m11
|
|
new4 = vqaddq_s16(alpha_ptr[0],*m11p); // m11
|
|
new1 = vqaddq_s16(alpha_ptr[2],*m10p); // m10
|
|
new5 = vqsubq_s16(alpha_ptr[2],*m10p); // m01=-m10
|
|
new2 = vqsubq_s16(alpha_ptr[4],*m10p); // m01=-m10
|
|
new6 = vqaddq_s16(alpha_ptr[4],*m10p); // m10
|
|
new3 = vqaddq_s16(alpha_ptr[6],*m11p); // m11
|
|
new7 = vqsubq_s16(alpha_ptr[6],*m11p); // m00=-m11
|
|
a0 = vmaxq_s16(m_b0,new0);
|
|
a1 = vmaxq_s16(m_b1,new1);
|
|
a2 = vmaxq_s16(m_b2,new2);
|
|
a3 = vmaxq_s16(m_b3,new3);
|
|
a4 = vmaxq_s16(m_b4,new4);
|
|
a5 = vmaxq_s16(m_b5,new5);
|
|
a6 = vmaxq_s16(m_b6,new6);
|
|
a7 = vmaxq_s16(m_b7,new7);
|
|
|
|
// compute and subtract maxima
|
|
alpha_max = vmaxq_s16(a0,a1);
|
|
alpha_max = vmaxq_s16(alpha_max,a2);
|
|
alpha_max = vmaxq_s16(alpha_max,a3);
|
|
alpha_max = vmaxq_s16(alpha_max,a4);
|
|
alpha_max = vmaxq_s16(alpha_max,a5);
|
|
alpha_max = vmaxq_s16(alpha_max,a6);
|
|
alpha_max = vmaxq_s16(alpha_max,a7);
|
|
|
|
#endif
|
|
|
|
alpha_ptr+=8;
|
|
//#ifdef __AVX2__
|
|
#if 0
|
|
alpha_ptr256+=4;
|
|
#endif
|
|
m11p++;
|
|
m10p++;
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
//#ifndef __AVX2__
|
|
#if 1
|
|
alpha_ptr[0] = _mm_subs_epi16(a0,alpha_max);
|
|
alpha_ptr[1] = _mm_subs_epi16(a1,alpha_max);
|
|
alpha_ptr[2] = _mm_subs_epi16(a2,alpha_max);
|
|
alpha_ptr[3] = _mm_subs_epi16(a3,alpha_max);
|
|
alpha_ptr[4] = _mm_subs_epi16(a4,alpha_max);
|
|
alpha_ptr[5] = _mm_subs_epi16(a5,alpha_max);
|
|
alpha_ptr[6] = _mm_subs_epi16(a6,alpha_max);
|
|
alpha_ptr[7] = _mm_subs_epi16(a7,alpha_max);
|
|
#else
|
|
|
|
a01 = _mm256_subs_epi16(a01,alpha_max);
|
|
a23 = _mm256_subs_epi16(a23,alpha_max);
|
|
a45 = _mm256_subs_epi16(a45,alpha_max);
|
|
a67 = _mm256_subs_epi16(a67,alpha_max);
|
|
|
|
alpha_ptr256[0] = _mm256_permute2x128_si256(a01,a23,0x20); //a02
|
|
alpha_ptr256[1] = _mm256_permute2x128_si256(a01,a23,0x13); //a13
|
|
alpha_ptr256[2] = _mm256_permute2x128_si256(a45,a67,0x02); //a64
|
|
alpha_ptr256[3] = _mm256_permute2x128_si256(a45,a67,0x31); //a75
|
|
#endif
|
|
#elif defined(__arm__)
|
|
alpha_ptr[0] = vqsubq_s16(a0,alpha_max);
|
|
alpha_ptr[1] = vqsubq_s16(a1,alpha_max);
|
|
alpha_ptr[2] = vqsubq_s16(a2,alpha_max);
|
|
alpha_ptr[3] = vqsubq_s16(a3,alpha_max);
|
|
alpha_ptr[4] = vqsubq_s16(a4,alpha_max);
|
|
alpha_ptr[5] = vqsubq_s16(a5,alpha_max);
|
|
alpha_ptr[6] = vqsubq_s16(a6,alpha_max);
|
|
alpha_ptr[7] = vqsubq_s16(a7,alpha_max);
|
|
#endif
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"Loop index %d\n",k);
|
|
print_shorts("mb0",(int16_t*)&m_b0);
|
|
print_shorts("mb1",(int16_t*)&m_b1);
|
|
print_shorts("mb2",(int16_t*)&m_b2);
|
|
print_shorts("mb3",(int16_t*)&m_b3);
|
|
print_shorts("mb4",(int16_t*)&m_b4);
|
|
print_shorts("mb5",(int16_t*)&m_b5);
|
|
print_shorts("mb6",(int16_t*)&m_b6);
|
|
print_shorts("mb7",(int16_t*)&m_b7);
|
|
|
|
fprintf(fdsse4,"Loop index %d, new\n",k);
|
|
print_shorts("new0",(int16_t*)&new0);
|
|
print_shorts("new1",(int16_t*)&new1);
|
|
print_shorts("new2",(int16_t*)&new2);
|
|
print_shorts("new3",(int16_t*)&new3);
|
|
print_shorts("new4",(int16_t*)&new4);
|
|
print_shorts("new5",(int16_t*)&new5);
|
|
print_shorts("new6",(int16_t*)&new6);
|
|
print_shorts("new7",(int16_t*)&new7);
|
|
|
|
fprintf(fdsse4,"Loop index %d, after max\n",k);
|
|
print_shorts("a0",(int16_t*)&a0);
|
|
print_shorts("a1",(int16_t*)&a1);
|
|
print_shorts("a2",(int16_t*)&a2);
|
|
print_shorts("a3",(int16_t*)&a3);
|
|
print_shorts("a4",(int16_t*)&a4);
|
|
print_shorts("a5",(int16_t*)&a5);
|
|
print_shorts("a6",(int16_t*)&a6);
|
|
print_shorts("a7",(int16_t*)&a7);
|
|
|
|
fprintf(fdsse4,"Loop index %d\n",k);
|
|
print_shorts("a0",(int16_t*)&alpha_ptr[0]);
|
|
print_shorts("a1",(int16_t*)&alpha_ptr[1]);
|
|
print_shorts("a2",(int16_t*)&alpha_ptr[2]);
|
|
print_shorts("a3",(int16_t*)&alpha_ptr[3]);
|
|
print_shorts("a4",(int16_t*)&alpha_ptr[4]);
|
|
print_shorts("a5",(int16_t*)&alpha_ptr[5]);
|
|
print_shorts("a6",(int16_t*)&alpha_ptr[6]);
|
|
print_shorts("a7",(int16_t*)&alpha_ptr[7]);
|
|
#endif
|
|
|
|
}
|
|
|
|
if (rerun_flag==1)
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void compute_beta16(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned short frame_length,unsigned char F,int offset8_flag)
|
|
{
|
|
|
|
int k,rerun_flag=0;
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
__m128i m11_128,m10_128;
|
|
__m128i m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
|
|
__m128i new0,new1,new2,new3,new4,new5,new6,new7;
|
|
|
|
__m128i *beta128,*alpha128,*beta_ptr;
|
|
__m128i beta_max;
|
|
#elif defined(__arm__)
|
|
int16x8_t m11_128,m10_128;
|
|
int16x8_t m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
|
|
int16x8_t new0,new1,new2,new3,new4,new5,new6,new7;
|
|
|
|
int16x8_t *beta128,*alpha128,*beta_ptr;
|
|
int16x8_t beta_max;
|
|
#endif
|
|
|
|
int16_t m11,m10,beta0_16,beta1_16,beta2_16,beta3_16,beta4_16,beta5_16,beta6_16,beta7_16,beta0_2,beta1_2,beta2_2,beta3_2,beta_m;
|
|
llr_t beta0,beta1;
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"compute_beta, %p,%p,%p,%p,framelength %d,F %d\n",
|
|
beta,m_11,m_10,alpha,frame_length,F);
|
|
#endif
|
|
|
|
|
|
// termination for beta initialization
|
|
|
|
// fprintf(fdsse4,"beta init: offset8 %d\n",offset8_flag);
|
|
m11=(int16_t)m_11[2+frame_length];
|
|
//#ifndef __AVX2__
|
|
#if 1
|
|
m10=(int16_t)m_10[2+frame_length];
|
|
#else
|
|
m10=-(int16_t)m_10[2+frame_length];
|
|
#endif
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"m11,m10 %d,%d\n",m11,m10);
|
|
#endif
|
|
|
|
beta0 = -m11;//M0T_TERM;
|
|
beta1 = m11;//M1T_TERM;
|
|
m11=(int16_t)m_11[1+frame_length];
|
|
m10=(int16_t)m_10[1+frame_length];
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"m11,m10 %d,%d\n",m11,m10);
|
|
#endif
|
|
|
|
beta0_2 = beta0-m11;//+M0T_TERM;
|
|
beta1_2 = beta0+m11;//+M1T_TERM;
|
|
beta2_2 = beta1+m10;//M2T_TERM;
|
|
beta3_2 = beta1-m10;//+M3T_TERM;
|
|
m11=(int16_t)m_11[frame_length];
|
|
m10=(int16_t)m_10[frame_length];
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"m11,m10 %d,%d\n",m11,m10);
|
|
#endif
|
|
beta0_16 = beta0_2-m11;//+M0T_TERM;
|
|
beta1_16 = beta0_2+m11;//+M1T_TERM;
|
|
beta2_16 = beta1_2+m10;//+M2T_TERM;
|
|
beta3_16 = beta1_2-m10;//+M3T_TERM;
|
|
beta4_16 = beta2_2-m10;//+M4T_TERM;
|
|
beta5_16 = beta2_2+m10;//+M5T_TERM;
|
|
beta6_16 = beta3_2+m11;//+M6T_TERM;
|
|
beta7_16 = beta3_2-m11;//+M7T_TERM;
|
|
|
|
|
|
beta_m = (beta0_16>beta1_16) ? beta0_16 : beta1_16;
|
|
beta_m = (beta_m>beta2_16) ? beta_m : beta2_16;
|
|
beta_m = (beta_m>beta3_16) ? beta_m : beta3_16;
|
|
beta_m = (beta_m>beta4_16) ? beta_m : beta4_16;
|
|
beta_m = (beta_m>beta5_16) ? beta_m : beta5_16;
|
|
beta_m = (beta_m>beta6_16) ? beta_m : beta6_16;
|
|
beta_m = (beta_m>beta7_16) ? beta_m : beta7_16;
|
|
|
|
|
|
beta0_16=beta0_16-beta_m;
|
|
beta1_16=beta1_16-beta_m;
|
|
beta2_16=beta2_16-beta_m;
|
|
beta3_16=beta3_16-beta_m;
|
|
beta4_16=beta4_16-beta_m;
|
|
beta5_16=beta5_16-beta_m;
|
|
beta6_16=beta6_16-beta_m;
|
|
beta7_16=beta7_16-beta_m;
|
|
|
|
for (rerun_flag=0;; rerun_flag=1) {
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
beta_ptr = (__m128i*)&beta[frame_length<<3];
|
|
alpha128 = (__m128i*)&alpha[0];
|
|
#elif defined(__arm__)
|
|
beta_ptr = (int16x8_t*)&beta[frame_length<<3];
|
|
alpha128 = (int16x8_t*)&alpha[0];
|
|
#endif
|
|
if (rerun_flag == 0) {
|
|
beta_ptr[0] = alpha128[(frame_length)];
|
|
beta_ptr[1] = alpha128[1+(frame_length)];
|
|
beta_ptr[2] = alpha128[2+(frame_length)];
|
|
beta_ptr[3] = alpha128[3+(frame_length)];
|
|
beta_ptr[4] = alpha128[4+(frame_length)];
|
|
beta_ptr[5] = alpha128[5+(frame_length)];
|
|
beta_ptr[6] = alpha128[6+(frame_length)];
|
|
beta_ptr[7] = alpha128[7+(frame_length)];
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"beta init \n");
|
|
print_shorts("b0",(int16_t*)&beta_ptr[0]);
|
|
print_shorts("b1",(int16_t*)&beta_ptr[1]);
|
|
print_shorts("b2",(int16_t*)&beta_ptr[2]);
|
|
print_shorts("b3",(int16_t*)&beta_ptr[3]);
|
|
print_shorts("b4",(int16_t*)&beta_ptr[4]);
|
|
print_shorts("b5",(int16_t*)&beta_ptr[5]);
|
|
print_shorts("b6",(int16_t*)&beta_ptr[6]);
|
|
print_shorts("b7",(int16_t*)&beta_ptr[7]);
|
|
#endif
|
|
} else {
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
beta128 = (__m128i*)&beta[0];
|
|
beta_ptr[0] = _mm_srli_si128(beta128[0],2);
|
|
beta_ptr[1] = _mm_srli_si128(beta128[1],2);
|
|
beta_ptr[2] = _mm_srli_si128(beta128[2],2);
|
|
beta_ptr[3] = _mm_srli_si128(beta128[3],2);
|
|
beta_ptr[4] = _mm_srli_si128(beta128[4],2);
|
|
beta_ptr[5] = _mm_srli_si128(beta128[5],2);
|
|
beta_ptr[6] = _mm_srli_si128(beta128[6],2);
|
|
beta_ptr[7] = _mm_srli_si128(beta128[7],2);
|
|
#elif defined(__arm__)
|
|
beta128 = (int16x8_t*)&beta[0];
|
|
beta_ptr = (int16x8_t*)&beta[frame_length<<3];
|
|
beta_ptr[0] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[0],16); beta_ptr[0] = vsetq_lane_s16(beta[3],beta_ptr[0],4);
|
|
beta_ptr[1] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[1],16); beta_ptr[1] = vsetq_lane_s16(beta[11],beta_ptr[1],4);
|
|
beta_ptr[2] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[2],16); beta_ptr[2] = vsetq_lane_s16(beta[19],beta_ptr[2],4);
|
|
beta_ptr[3] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[3],16); beta_ptr[3] = vsetq_lane_s16(beta[27],beta_ptr[3],4);
|
|
beta_ptr[4] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[4],16); beta_ptr[4] = vsetq_lane_s16(beta[35],beta_ptr[4],4);
|
|
beta_ptr[5] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[5],16); beta_ptr[5] = vsetq_lane_s16(beta[43],beta_ptr[5],4);
|
|
beta_ptr[6] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[6],16); beta_ptr[6] = vsetq_lane_s16(beta[51],beta_ptr[6],4);
|
|
beta_ptr[7] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[7],16); beta_ptr[7] = vsetq_lane_s16(beta[59],beta_ptr[7],4);
|
|
#endif
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"beta init (second run) \n");
|
|
print_shorts("b0",(int16_t*)&beta_ptr[0]);
|
|
print_shorts("b1",(int16_t*)&beta_ptr[1]);
|
|
print_shorts("b2",(int16_t*)&beta_ptr[2]);
|
|
print_shorts("b3",(int16_t*)&beta_ptr[3]);
|
|
print_shorts("b4",(int16_t*)&beta_ptr[4]);
|
|
print_shorts("b5",(int16_t*)&beta_ptr[5]);
|
|
print_shorts("b6",(int16_t*)&beta_ptr[6]);
|
|
print_shorts("b7",(int16_t*)&beta_ptr[7]);
|
|
#endif
|
|
}
|
|
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
beta_ptr[0] = _mm_insert_epi16(beta_ptr[0],beta0_16,7);
|
|
beta_ptr[1] = _mm_insert_epi16(beta_ptr[1],beta1_16,7);
|
|
beta_ptr[2] = _mm_insert_epi16(beta_ptr[2],beta2_16,7);
|
|
beta_ptr[3] = _mm_insert_epi16(beta_ptr[3],beta3_16,7);
|
|
beta_ptr[4] = _mm_insert_epi16(beta_ptr[4],beta4_16,7);
|
|
beta_ptr[5] = _mm_insert_epi16(beta_ptr[5],beta5_16,7);
|
|
beta_ptr[6] = _mm_insert_epi16(beta_ptr[6],beta6_16,7);
|
|
beta_ptr[7] = _mm_insert_epi16(beta_ptr[7],beta7_16,7);
|
|
#elif defined(__arm__)
|
|
beta_ptr[0] = vsetq_lane_s16(beta0_16,beta_ptr[0],7);
|
|
beta_ptr[1] = vsetq_lane_s16(beta1_16,beta_ptr[1],7);
|
|
beta_ptr[2] = vsetq_lane_s16(beta2_16,beta_ptr[2],7);
|
|
beta_ptr[3] = vsetq_lane_s16(beta3_16,beta_ptr[3],7);
|
|
beta_ptr[4] = vsetq_lane_s16(beta4_16,beta_ptr[4],7);
|
|
beta_ptr[5] = vsetq_lane_s16(beta5_16,beta_ptr[5],7);
|
|
beta_ptr[6] = vsetq_lane_s16(beta6_16,beta_ptr[6],7);
|
|
beta_ptr[7] = vsetq_lane_s16(beta7_16,beta_ptr[7],7);
|
|
#endif
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"beta init (after insert) \n");
|
|
print_shorts("b0",(int16_t*)&beta_ptr[0]);
|
|
print_shorts("b1",(int16_t*)&beta_ptr[1]);
|
|
print_shorts("b2",(int16_t*)&beta_ptr[2]);
|
|
print_shorts("b3",(int16_t*)&beta_ptr[3]);
|
|
print_shorts("b4",(int16_t*)&beta_ptr[4]);
|
|
print_shorts("b5",(int16_t*)&beta_ptr[5]);
|
|
print_shorts("b6",(int16_t*)&beta_ptr[6]);
|
|
print_shorts("b7",(int16_t*)&beta_ptr[7]);
|
|
#endif
|
|
int loopval=((rerun_flag==0)?0:((frame_length-L)>>3));
|
|
|
|
for (k=(frame_length>>3)-1; k>=loopval; k--) {
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
m11_128=((__m128i*)m_11)[k];
|
|
m10_128=((__m128i*)m_10)[k];
|
|
|
|
|
|
//#ifndef __AVX2__
|
|
#if 1
|
|
m_b0 = _mm_adds_epi16(beta_ptr[4],m11_128); //m11
|
|
m_b1 = _mm_subs_epi16(beta_ptr[4],m11_128); //m00
|
|
m_b2 = _mm_subs_epi16(beta_ptr[5],m10_128); //m01
|
|
m_b3 = _mm_adds_epi16(beta_ptr[5],m10_128); //m10
|
|
m_b4 = _mm_adds_epi16(beta_ptr[6],m10_128); //m10
|
|
m_b5 = _mm_subs_epi16(beta_ptr[6],m10_128); //m01
|
|
m_b6 = _mm_subs_epi16(beta_ptr[7],m11_128); //m00
|
|
m_b7 = _mm_adds_epi16(beta_ptr[7],m11_128); //m11
|
|
|
|
|
|
new0 = _mm_subs_epi16(beta_ptr[0],m11_128); //m00
|
|
new1 = _mm_adds_epi16(beta_ptr[0],m11_128); //m11
|
|
new2 = _mm_adds_epi16(beta_ptr[1],m10_128); //m10
|
|
new3 = _mm_subs_epi16(beta_ptr[1],m10_128); //m01
|
|
new4 = _mm_subs_epi16(beta_ptr[2],m10_128); //m01
|
|
new5 = _mm_adds_epi16(beta_ptr[2],m10_128); //m10
|
|
new6 = _mm_adds_epi16(beta_ptr[3],m11_128); //m11
|
|
new7 = _mm_subs_epi16(beta_ptr[3],m11_128); //m00
|
|
|
|
#else
|
|
b01=_mm256_load_si256(&((_m256i*)beta_ptr)[0]);
|
|
b23=_mm256_load_si256(&((_m256i*)beta_ptr)[1]);
|
|
b45=_mm256_load_si256(&((_m256i*)beta_ptr)[2]);
|
|
b67=_mm256_load_si256(&((_m256i*)beta_ptr)[3]);
|
|
m11m10_256 = _mm256_insertf128_si256(m11m10_256,m11_128,0);
|
|
m11m10_256 = _mm256_insertf128_si256(m11m10_256,m10_128,1);
|
|
|
|
|
|
m_b02 = _mm256_adds_epi16(b45,m11m10_256); //negative m10
|
|
m_b13 = _mm256_subs_epi16(b45,m11m10_256); //negative m10
|
|
m_b64 = _mm256_subs_epi16(b67,m11m10_256); //negative m10
|
|
m_b75 = _mm256_adds_epi16(b67,m11m10_256); //negative m10
|
|
new02 = _mm256_subs_epi16(b01,m11m10_256); //negative m10
|
|
new13 = _mm256_adds_epi16(b01,m11m10_256); //negative m10
|
|
new64 = _mm256_adds_epi16(b23,m11m10_256); //negative m10
|
|
new75 = _mm256_subs_epi16(b24,m11m10_256); //negative m10
|
|
#endif
|
|
|
|
beta_ptr-=8;
|
|
|
|
//#ifndef __AVX2__
|
|
#if 1
|
|
beta_ptr[0] = _mm_max_epi16(m_b0,new0);
|
|
beta_ptr[1] = _mm_max_epi16(m_b1,new1);
|
|
beta_ptr[2] = _mm_max_epi16(m_b2,new2);
|
|
beta_ptr[3] = _mm_max_epi16(m_b3,new3);
|
|
beta_ptr[4] = _mm_max_epi16(m_b4,new4);
|
|
beta_ptr[5] = _mm_max_epi16(m_b5,new5);
|
|
beta_ptr[6] = _mm_max_epi16(m_b6,new6);
|
|
beta_ptr[7] = _mm_max_epi16(m_b7,new7);
|
|
|
|
beta_max = _mm_max_epi16(beta_ptr[0],beta_ptr[1]);
|
|
beta_max = _mm_max_epi16(beta_max ,beta_ptr[2]);
|
|
beta_max = _mm_max_epi16(beta_max ,beta_ptr[3]);
|
|
beta_max = _mm_max_epi16(beta_max ,beta_ptr[4]);
|
|
beta_max = _mm_max_epi16(beta_max ,beta_ptr[5]);
|
|
beta_max = _mm_max_epi16(beta_max ,beta_ptr[6]);
|
|
beta_max = _mm_max_epi16(beta_max ,beta_ptr[7]);
|
|
|
|
beta_ptr[0] = _mm_subs_epi16(beta_ptr[0],beta_max);
|
|
beta_ptr[1] = _mm_subs_epi16(beta_ptr[1],beta_max);
|
|
beta_ptr[2] = _mm_subs_epi16(beta_ptr[2],beta_max);
|
|
beta_ptr[3] = _mm_subs_epi16(beta_ptr[3],beta_max);
|
|
beta_ptr[4] = _mm_subs_epi16(beta_ptr[4],beta_max);
|
|
beta_ptr[5] = _mm_subs_epi16(beta_ptr[5],beta_max);
|
|
beta_ptr[6] = _mm_subs_epi16(beta_ptr[6],beta_max);
|
|
beta_ptr[7] = _mm_subs_epi16(beta_ptr[7],beta_max);
|
|
#else
|
|
b02 = _mm256_max_epi16(m_b02,new02);
|
|
b13 = _mm256_max_epi16(m_b13,new13);
|
|
b64 = _mm256_max_epi16(m_b64,new64);
|
|
b75 = _mm256_max_epi16(m_b75,new75);
|
|
|
|
beta_max = _mm256_max_epi16(b02,b13);
|
|
beta_max = _mm256_max_epi16(beta_max,b64);
|
|
beta_max = _mm256_max_epi16(beta_max,b75);
|
|
beta_max = _mm256_max_epi16(beta_max,_mm256_permutevar8x32_epi32(betaa_max,_mm256_set_epi32(3,2,1,0,7,6,5,4)));
|
|
|
|
b02 = _mm256_subs_epi16(b02,beta_max);
|
|
b13 = _mm256_subs_epi16(b13,beta_max);
|
|
b64 = _mm256_subs_epi16(b64,beta_max);
|
|
b75 = _mm256_subs_epi16(b75,beta_max);
|
|
|
|
((_m256i*)beta_ptr)[0]) = _mm256_permute2x128_si256(b02,b13,0x02); //b01
|
|
((_m256i*)beta_ptr)[1]) = _mm256_permute2x128_si256(b02,b13,0x31); //b23
|
|
((_m256i*)beta_ptr)[2]) = _mm256_permute2x128_si256(b64,b75,0x13); //b45
|
|
((_m256i*)beta_ptr)[3]) = _mm256_permute2x128_si256(b64,b75,0x20); //b67
|
|
#endif
|
|
|
|
#elif defined(__arm__)
|
|
m11_128=((int16x8_t*)m_11)[k];
|
|
m10_128=((int16x8_t*)m_10)[k];
|
|
m_b0 = vqaddq_s16(beta_ptr[4],m11_128); //m11
|
|
m_b1 = vqsubq_s16(beta_ptr[4],m11_128); //m00
|
|
m_b2 = vqsubq_s16(beta_ptr[5],m10_128); //m01
|
|
m_b3 = vqaddq_s16(beta_ptr[5],m10_128); //m10
|
|
m_b4 = vqaddq_s16(beta_ptr[6],m10_128); //m10
|
|
m_b5 = vqsubq_s16(beta_ptr[6],m10_128); //m01
|
|
m_b6 = vqsubq_s16(beta_ptr[7],m11_128); //m00
|
|
m_b7 = vqaddq_s16(beta_ptr[7],m11_128); //m11
|
|
|
|
new0 = vqsubq_s16(beta_ptr[0],m11_128); //m00
|
|
new1 = vqaddq_s16(beta_ptr[0],m11_128); //m11
|
|
new2 = vqaddq_s16(beta_ptr[1],m10_128); //m10
|
|
new3 = vqsubq_s16(beta_ptr[1],m10_128); //m01
|
|
new4 = vqsubq_s16(beta_ptr[2],m10_128); //m01
|
|
new5 = vqaddq_s16(beta_ptr[2],m10_128); //m10
|
|
new6 = vqaddq_s16(beta_ptr[3],m11_128); //m11
|
|
new7 = vqsubq_s16(beta_ptr[3],m11_128); //m00
|
|
|
|
beta_ptr-=8;
|
|
|
|
beta_ptr[0] = vmaxq_s16(m_b0,new0);
|
|
beta_ptr[1] = vmaxq_s16(m_b1,new1);
|
|
beta_ptr[2] = vmaxq_s16(m_b2,new2);
|
|
beta_ptr[3] = vmaxq_s16(m_b3,new3);
|
|
beta_ptr[4] = vmaxq_s16(m_b4,new4);
|
|
beta_ptr[5] = vmaxq_s16(m_b5,new5);
|
|
beta_ptr[6] = vmaxq_s16(m_b6,new6);
|
|
beta_ptr[7] = vmaxq_s16(m_b7,new7);
|
|
|
|
beta_max = vmaxq_s16(beta_ptr[0],beta_ptr[1]);
|
|
beta_max = vmaxq_s16(beta_max ,beta_ptr[2]);
|
|
beta_max = vmaxq_s16(beta_max ,beta_ptr[3]);
|
|
beta_max = vmaxq_s16(beta_max ,beta_ptr[4]);
|
|
beta_max = vmaxq_s16(beta_max ,beta_ptr[5]);
|
|
beta_max = vmaxq_s16(beta_max ,beta_ptr[6]);
|
|
beta_max = vmaxq_s16(beta_max ,beta_ptr[7]);
|
|
|
|
beta_ptr[0] = vqsubq_s16(beta_ptr[0],beta_max);
|
|
beta_ptr[1] = vqsubq_s16(beta_ptr[1],beta_max);
|
|
beta_ptr[2] = vqsubq_s16(beta_ptr[2],beta_max);
|
|
beta_ptr[3] = vqsubq_s16(beta_ptr[3],beta_max);
|
|
beta_ptr[4] = vqsubq_s16(beta_ptr[4],beta_max);
|
|
beta_ptr[5] = vqsubq_s16(beta_ptr[5],beta_max);
|
|
beta_ptr[6] = vqsubq_s16(beta_ptr[6],beta_max);
|
|
beta_ptr[7] = vqsubq_s16(beta_ptr[7],beta_max);
|
|
#endif
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"Loop index %d, mb\n",k);
|
|
fprintf(fdsse4,"beta init (after max)\n");
|
|
print_shorts("b0",(int16_t*)&beta_ptr[0]);
|
|
print_shorts("b1",(int16_t*)&beta_ptr[1]);
|
|
print_shorts("b2",(int16_t*)&beta_ptr[2]);
|
|
print_shorts("b3",(int16_t*)&beta_ptr[3]);
|
|
print_shorts("b4",(int16_t*)&beta_ptr[4]);
|
|
print_shorts("b5",(int16_t*)&beta_ptr[5]);
|
|
print_shorts("b6",(int16_t*)&beta_ptr[6]);
|
|
print_shorts("b7",(int16_t*)&beta_ptr[7]);
|
|
#endif
|
|
|
|
}
|
|
|
|
if (rerun_flag==1)
|
|
break;
|
|
}
|
|
}
|
|
|
|
void compute_ext16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, llr_t* systematic,unsigned short frame_length)
|
|
{
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
__m128i *alpha128=(__m128i *)alpha;
|
|
__m128i *beta128=(__m128i *)beta;
|
|
__m128i *m11_128,*m10_128,*ext_128;
|
|
__m128i *alpha_ptr,*beta_ptr;
|
|
__m128i m00_1,m00_2,m00_3,m00_4;
|
|
__m128i m01_1,m01_2,m01_3,m01_4;
|
|
__m128i m10_1,m10_2,m10_3,m10_4;
|
|
__m128i m11_1,m11_2,m11_3,m11_4;
|
|
#elif defined(__arm__)
|
|
int16x8_t *alpha128=(int16x8_t *)alpha;
|
|
int16x8_t *beta128=(int16x8_t *)beta;
|
|
int16x8_t *m11_128,*m10_128,*ext_128;
|
|
int16x8_t *alpha_ptr,*beta_ptr;
|
|
int16x8_t m00_1,m00_2,m00_3,m00_4;
|
|
int16x8_t m01_1,m01_2,m01_3,m01_4;
|
|
int16x8_t m10_1,m10_2,m10_3,m10_4;
|
|
int16x8_t m11_1,m11_2,m11_3,m11_4;
|
|
#endif
|
|
|
|
int k;
|
|
|
|
//
|
|
// LLR computation, 8 consequtive bits per loop
|
|
//
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"compute_ext (sse_16bit), %p, %p, %p, %p, %p, %p ,framelength %d\n",alpha,beta,m_11,m_10,ext,systematic,frame_length);
|
|
#endif
|
|
|
|
alpha_ptr = alpha128;
|
|
beta_ptr = &beta128[8];
|
|
|
|
|
|
for (k=0; k<(frame_length>>3); k++) {
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
m11_128 = (__m128i*)&m_11[k<<3];
|
|
m10_128 = (__m128i*)&m_10[k<<3];
|
|
ext_128 = (__m128i*)&ext[k<<3];
|
|
|
|
/*
|
|
fprintf(fdsse4,"EXT %03d\n",k);
|
|
print_shorts("a0:",&alpha_ptr[0]);
|
|
print_shorts("a1:",&alpha_ptr[1]);
|
|
print_shorts("a2:",&alpha_ptr[2]);
|
|
print_shorts("a3:",&alpha_ptr[3]);
|
|
print_shorts("a4:",&alpha_ptr[4]);
|
|
print_shorts("a5:",&alpha_ptr[5]);
|
|
print_shorts("a6:",&alpha_ptr[6]);
|
|
print_shorts("a7:",&alpha_ptr[7]);
|
|
print_shorts("b0:",&beta_ptr[0]);
|
|
print_shorts("b1:",&beta_ptr[1]);
|
|
print_shorts("b2:",&beta_ptr[2]);
|
|
print_shorts("b3:",&beta_ptr[3]);
|
|
print_shorts("b4:",&beta_ptr[4]);
|
|
print_shorts("b5:",&beta_ptr[5]);
|
|
print_shorts("b6:",&beta_ptr[6]);
|
|
print_shorts("b7:",&beta_ptr[7]);
|
|
*/
|
|
|
|
//#ifndef __AVX2__
|
|
#if 1
|
|
m00_4 = _mm_adds_epi16(alpha_ptr[7],beta_ptr[3]); //ALPHA_BETA_4m00;
|
|
m11_4 = _mm_adds_epi16(alpha_ptr[7],beta_ptr[7]); //ALPHA_BETA_4m11;
|
|
m00_3 = _mm_adds_epi16(alpha_ptr[6],beta_ptr[7]); //ALPHA_BETA_3m00;
|
|
m11_3 = _mm_adds_epi16(alpha_ptr[6],beta_ptr[3]); //ALPHA_BETA_3m11;
|
|
m00_2 = _mm_adds_epi16(alpha_ptr[1],beta_ptr[4]); //ALPHA_BETA_2m00;
|
|
m11_2 = _mm_adds_epi16(alpha_ptr[1],beta_ptr[0]); //ALPHA_BETA_2m11;
|
|
m11_1 = _mm_adds_epi16(alpha_ptr[0],beta_ptr[4]); //ALPHA_BETA_1m11;
|
|
m00_1 = _mm_adds_epi16(alpha_ptr[0],beta_ptr[0]); //ALPHA_BETA_1m00;
|
|
m01_4 = _mm_adds_epi16(alpha_ptr[5],beta_ptr[6]); //ALPHA_BETA_4m01;
|
|
m10_4 = _mm_adds_epi16(alpha_ptr[5],beta_ptr[2]); //ALPHA_BETA_4m10;
|
|
m01_3 = _mm_adds_epi16(alpha_ptr[4],beta_ptr[2]); //ALPHA_BETA_3m01;
|
|
m10_3 = _mm_adds_epi16(alpha_ptr[4],beta_ptr[6]); //ALPHA_BETA_3m10;
|
|
m01_2 = _mm_adds_epi16(alpha_ptr[3],beta_ptr[1]); //ALPHA_BETA_2m01;
|
|
m10_2 = _mm_adds_epi16(alpha_ptr[3],beta_ptr[5]); //ALPHA_BETA_2m10;
|
|
m10_1 = _mm_adds_epi16(alpha_ptr[2],beta_ptr[1]); //ALPHA_BETA_1m10;
|
|
m01_1 = _mm_adds_epi16(alpha_ptr[2],beta_ptr[5]); //ALPHA_BETA_1m01;
|
|
#else
|
|
|
|
|
|
m00_1 = _mm_adds_epi16(alpha_ptr[0],beta_ptr[0]); //ALPHA_BETA_1m00;
|
|
m10_1 = _mm_adds_epi16(alpha_ptr[2],beta_ptr[1]); //ALPHA_BETA_1m10;
|
|
m11_1 = _mm_adds_epi16(alpha_ptr[0],beta_ptr[4]); //ALPHA_BETA_1m11;
|
|
m01_1 = _mm_adds_epi16(alpha_ptr[2],beta_ptr[5]); //ALPHA_BETA_1m01;
|
|
|
|
m11_2 = _mm_adds_epi16(alpha_ptr[1],beta_ptr[0]); //ALPHA_BETA_2m11;
|
|
m01_2 = _mm_adds_epi16(alpha_ptr[3],beta_ptr[1]); //ALPHA_BETA_2m01;
|
|
m00_2 = _mm_adds_epi16(alpha_ptr[1],beta_ptr[4]); //ALPHA_BETA_2m00;
|
|
m10_2 = _mm_adds_epi16(alpha_ptr[3],beta_ptr[5]); //ALPHA_BETA_2m10;
|
|
|
|
m11_3 = _mm_adds_epi16(alpha_ptr[6],beta_ptr[3]); //ALPHA_BETA_3m11;
|
|
m01_3 = _mm_adds_epi16(alpha_ptr[4],beta_ptr[2]); //ALPHA_BETA_3m01;
|
|
m00_3 = _mm_adds_epi16(alpha_ptr[6],beta_ptr[7]); //ALPHA_BETA_3m00;
|
|
m10_3 = _mm_adds_epi16(alpha_ptr[4],beta_ptr[6]); //ALPHA_BETA_3m10;
|
|
|
|
m00_4 = _mm_adds_epi16(alpha_ptr[7],beta_ptr[3]); //ALPHA_BETA_4m00;
|
|
m10_4 = _mm_adds_epi16(alpha_ptr[5],beta_ptr[2]); //ALPHA_BETA_4m10;
|
|
m11_4 = _mm_adds_epi16(alpha_ptr[7],beta_ptr[7]); //ALPHA_BETA_4m11;
|
|
m01_4 = _mm_adds_epi16(alpha_ptr[5],beta_ptr[6]); //ALPHA_BETA_4m01;
|
|
|
|
|
|
#endif
|
|
|
|
/*
|
|
print_shorts("m11_1:",&m11_1);
|
|
print_shorts("m11_2:",&m11_2);
|
|
print_shorts("m11_3:",&m11_3);
|
|
print_shorts("m11_4:",&m11_4);
|
|
print_shorts("m00_1:",&m00_1);
|
|
print_shorts("m00_2:",&m00_2);
|
|
print_shorts("m00_3:",&m00_3);
|
|
print_shorts("m00_4:",&m00_4);
|
|
print_shorts("m10_1:",&m10_1);
|
|
print_shorts("m10_2:",&m10_2);
|
|
print_shorts("m10_3:",&m10_3);
|
|
print_shorts("m10_4:",&m10_4);
|
|
print_shorts("m01_1:",&m01_1);
|
|
print_shorts("m01_2:",&m01_2);
|
|
print_shorts("m01_3:",&m01_3);
|
|
print_shorts("m01_4:",&m01_4);
|
|
*/
|
|
m01_1 = _mm_max_epi16(m01_1,m01_2);
|
|
m01_1 = _mm_max_epi16(m01_1,m01_3);
|
|
m01_1 = _mm_max_epi16(m01_1,m01_4);
|
|
m00_1 = _mm_max_epi16(m00_1,m00_2);
|
|
m00_1 = _mm_max_epi16(m00_1,m00_3);
|
|
m00_1 = _mm_max_epi16(m00_1,m00_4);
|
|
m10_1 = _mm_max_epi16(m10_1,m10_2);
|
|
m10_1 = _mm_max_epi16(m10_1,m10_3);
|
|
m10_1 = _mm_max_epi16(m10_1,m10_4);
|
|
m11_1 = _mm_max_epi16(m11_1,m11_2);
|
|
m11_1 = _mm_max_epi16(m11_1,m11_3);
|
|
m11_1 = _mm_max_epi16(m11_1,m11_4);
|
|
|
|
// print_shorts("m11_1:",&m11_1);
|
|
|
|
m01_1 = _mm_subs_epi16(m01_1,*m10_128);
|
|
m00_1 = _mm_subs_epi16(m00_1,*m11_128);
|
|
m10_1 = _mm_adds_epi16(m10_1,*m10_128);
|
|
m11_1 = _mm_adds_epi16(m11_1,*m11_128);
|
|
|
|
// print_shorts("m10_1:",&m10_1);
|
|
// print_shorts("m11_1:",&m11_1);
|
|
m01_1 = _mm_max_epi16(m01_1,m00_1);
|
|
m10_1 = _mm_max_epi16(m10_1,m11_1);
|
|
// print_shorts("m01_1:",&m01_1);
|
|
// print_shorts("m10_1:",&m10_1);
|
|
|
|
*ext_128 = _mm_subs_epi16(m10_1,m01_1);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"ext %p\n",ext_128);
|
|
print_shorts("ext:",(int16_t*)ext_128);
|
|
print_shorts("m11:",(int16_t*)m11_128);
|
|
print_shorts("m10:",(int16_t*)m10_128);
|
|
print_shorts("m10_1:",(int16_t*)&m10_1);
|
|
print_shorts("m01_1:",(int16_t*)&m01_1);
|
|
#endif
|
|
|
|
#elif defined(__arm__)
|
|
m11_128 = (int16x8_t*)&m_11[k<<3];
|
|
m10_128 = (int16x8_t*)&m_10[k<<3];
|
|
ext_128 = (int16x8_t*)&ext[k<<3];
|
|
|
|
m00_4 = vqaddq_s16(alpha_ptr[7],beta_ptr[3]); //ALPHA_BETA_4m00;
|
|
m11_4 = vqaddq_s16(alpha_ptr[7],beta_ptr[7]); //ALPHA_BETA_4m11;
|
|
m00_3 = vqaddq_s16(alpha_ptr[6],beta_ptr[7]); //ALPHA_BETA_3m00;
|
|
m11_3 = vqaddq_s16(alpha_ptr[6],beta_ptr[3]); //ALPHA_BETA_3m11;
|
|
m00_2 = vqaddq_s16(alpha_ptr[1],beta_ptr[4]); //ALPHA_BETA_2m00;
|
|
m11_2 = vqaddq_s16(alpha_ptr[1],beta_ptr[0]); //ALPHA_BETA_2m11;
|
|
m11_1 = vqaddq_s16(alpha_ptr[0],beta_ptr[4]); //ALPHA_BETA_1m11;
|
|
m00_1 = vqaddq_s16(alpha_ptr[0],beta_ptr[0]); //ALPHA_BETA_1m00;
|
|
m01_4 = vqaddq_s16(alpha_ptr[5],beta_ptr[6]); //ALPHA_BETA_4m01;
|
|
m10_4 = vqaddq_s16(alpha_ptr[5],beta_ptr[2]); //ALPHA_BETA_4m10;
|
|
m01_3 = vqaddq_s16(alpha_ptr[4],beta_ptr[2]); //ALPHA_BETA_3m01;
|
|
m10_3 = vqaddq_s16(alpha_ptr[4],beta_ptr[6]); //ALPHA_BETA_3m10;
|
|
m01_2 = vqaddq_s16(alpha_ptr[3],beta_ptr[1]); //ALPHA_BETA_2m01;
|
|
m10_2 = vqaddq_s16(alpha_ptr[3],beta_ptr[5]); //ALPHA_BETA_2m10;
|
|
m10_1 = vqaddq_s16(alpha_ptr[2],beta_ptr[1]); //ALPHA_BETA_1m10;
|
|
m01_1 = vqaddq_s16(alpha_ptr[2],beta_ptr[5]); //ALPHA_BETA_1m01;
|
|
|
|
m01_1 = vmaxq_s16(m01_1,m01_2);
|
|
m01_1 = vmaxq_s16(m01_1,m01_3);
|
|
m01_1 = vmaxq_s16(m01_1,m01_4);
|
|
m00_1 = vmaxq_s16(m00_1,m00_2);
|
|
m00_1 = vmaxq_s16(m00_1,m00_3);
|
|
m00_1 = vmaxq_s16(m00_1,m00_4);
|
|
m10_1 = vmaxq_s16(m10_1,m10_2);
|
|
m10_1 = vmaxq_s16(m10_1,m10_3);
|
|
m10_1 = vmaxq_s16(m10_1,m10_4);
|
|
m11_1 = vmaxq_s16(m11_1,m11_2);
|
|
m11_1 = vmaxq_s16(m11_1,m11_3);
|
|
m11_1 = vmaxq_s16(m11_1,m11_4);
|
|
|
|
|
|
m01_1 = vqsubq_s16(m01_1,*m10_128);
|
|
m00_1 = vqsubq_s16(m00_1,*m11_128);
|
|
m10_1 = vqaddq_s16(m10_1,*m10_128);
|
|
m11_1 = vqaddq_s16(m11_1,*m11_128);
|
|
|
|
|
|
m01_1 = vmaxq_s16(m01_1,m00_1);
|
|
m10_1 = vmaxq_s16(m10_1,m11_1);
|
|
|
|
|
|
*ext_128 = vqsubq_s16(m10_1,m01_1);
|
|
#endif
|
|
alpha_ptr+=8;
|
|
beta_ptr+=8;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//int pi2[n],pi3[n+8],pi5[n+8],pi4[n+8],pi6[n+8],
|
|
int *pi2tab16[188],*pi5tab16[188],*pi4tab16[188],*pi6tab16[188];
|
|
|
|
void free_td16(void)
|
|
{
|
|
int ind;
|
|
|
|
for (ind=0; ind<188; ind++) {
|
|
free(pi2tab16[ind]);
|
|
free(pi5tab16[ind]);
|
|
free(pi4tab16[ind]);
|
|
free(pi6tab16[ind]);
|
|
}
|
|
}
|
|
|
|
void init_td16()
|
|
{
|
|
|
|
int ind,i,i2,i3,j,n,pi,pi3;
|
|
short * base_interleaver;
|
|
|
|
for (ind=0; ind<188; ind++) {
|
|
|
|
n = f1f2mat[ind].nb_bits;
|
|
base_interleaver=il_tb+f1f2mat[ind].beg_index;
|
|
#ifdef MEX
|
|
// This is needed for the Mex implementation to make the memory persistent
|
|
pi2tab16[ind] = mxMalloc((n+8)*sizeof(int));
|
|
pi5tab16[ind] = mxMalloc((n+8)*sizeof(int));
|
|
pi4tab16[ind] = mxMalloc((n+8)*sizeof(int));
|
|
pi6tab16[ind] = mxMalloc((n+8)*sizeof(int));
|
|
#else
|
|
pi2tab16[ind] = malloc((n+8)*sizeof(int));
|
|
pi5tab16[ind] = malloc((n+8)*sizeof(int));
|
|
pi4tab16[ind] = malloc((n+8)*sizeof(int));
|
|
pi6tab16[ind] = malloc((n+8)*sizeof(int));
|
|
#endif
|
|
|
|
for (i=i2=0; i2<8; i2++) {
|
|
j=i2;
|
|
|
|
for (i3=0; i3<(n>>3); i3++,i++,j+=8) {
|
|
|
|
// if (j>=n)
|
|
// j-=(n-1);
|
|
|
|
pi2tab16[ind][i] = j;
|
|
// fprintf(fdsse4,"pi2[%d] = %d\n",i,j);
|
|
}
|
|
}
|
|
|
|
for (i=0; i<n; i++) {
|
|
pi = base_interleaver[i];//(unsigned int)threegpplte_interleaver(f1,f2,n);
|
|
pi3 = pi2tab16[ind][pi];
|
|
pi4tab16[ind][pi2tab16[ind][i]] = pi3;
|
|
pi5tab16[ind][pi3] = pi2tab16[ind][i];
|
|
pi6tab16[ind][pi] = pi2tab16[ind][i];
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
unsigned char phy_threegpplte_turbo_decoder16(short *y,
|
|
unsigned char *decoded_bytes,
|
|
unsigned short n,
|
|
unsigned short f1,
|
|
unsigned short f2,
|
|
unsigned char max_iterations,
|
|
unsigned char crc_type,
|
|
unsigned char F,
|
|
time_stats_t *init_stats,
|
|
time_stats_t *alpha_stats,
|
|
time_stats_t *beta_stats,
|
|
time_stats_t *gamma_stats,
|
|
time_stats_t *ext_stats,
|
|
time_stats_t *intl1_stats,
|
|
time_stats_t *intl2_stats)
|
|
{
|
|
|
|
/* y is a pointer to the input
|
|
decoded_bytes is a pointer to the decoded output
|
|
n is the size in bits of the coded block, with the tail */
|
|
|
|
|
|
llr_t systematic0[n+16] __attribute__ ((aligned(32)));
|
|
llr_t systematic1[n+16] __attribute__ ((aligned(32)));
|
|
llr_t systematic2[n+16] __attribute__ ((aligned(32)));
|
|
llr_t yparity1[n+16] __attribute__ ((aligned(32)));
|
|
llr_t yparity2[n+16] __attribute__ ((aligned(32)));
|
|
|
|
llr_t ext[n+128] __attribute__((aligned(32)));
|
|
llr_t ext2[n+128] __attribute__((aligned(32)));
|
|
|
|
llr_t alpha[(n+16)*8] __attribute__ ((aligned(32)));
|
|
llr_t beta[(n+16)*8] __attribute__ ((aligned(32)));
|
|
llr_t m11[n+32] __attribute__ ((aligned(32)));
|
|
llr_t m10[n+32] __attribute__ ((aligned(32)));
|
|
|
|
|
|
int *pi2_p,*pi4_p,*pi5_p,*pi6_p;
|
|
llr_t *s,*s1,*s2,*yp1,*yp2,*yp;
|
|
unsigned int i,j,iind;//,pi;
|
|
unsigned char iteration_cnt=0;
|
|
unsigned int crc,oldcrc,crc_len;
|
|
uint8_t temp;
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
__m128i *yp128;
|
|
__m128i tmp, zeros=_mm_setzero_si128();
|
|
__m128i tmpe;
|
|
#elif defined(__arm__)
|
|
int16x8_t *yp128;
|
|
// int16x8_t tmp128[(n+8)>>3];
|
|
int16x8_t tmp, zeros=vdupq_n_s16(0);
|
|
const uint16_t __attribute__ ((aligned (16))) _Powers[8]=
|
|
{ 1, 2, 4, 8, 16, 32, 64, 128};
|
|
uint16x8_t Powers= vld1q_u16(_Powers);
|
|
#endif
|
|
int offset8_flag=0;
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fdsse4 = fopen("dump_sse4.txt","w");
|
|
|
|
|
|
printf("tc sse4_16 (y) %p\n",y);
|
|
#endif
|
|
|
|
if (crc_type > 3) {
|
|
printf("Illegal crc length!\n");
|
|
return 255;
|
|
}
|
|
|
|
|
|
|
|
start_meas(init_stats);
|
|
|
|
|
|
|
|
for (iind=0; iind < 188 && f1f2mat[iind].nb_bits != n; iind++);
|
|
|
|
if ( iind == 188 ) {
|
|
printf("Illegal frame length!\n");
|
|
return 255;
|
|
}
|
|
|
|
switch (crc_type) {
|
|
case CRC24_A:
|
|
case CRC24_B:
|
|
crc_len=3;
|
|
break;
|
|
|
|
case CRC16:
|
|
crc_len=2;
|
|
break;
|
|
|
|
case CRC8:
|
|
crc_len=1;
|
|
break;
|
|
|
|
default:
|
|
crc_len=3;
|
|
}
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
yp128 = (__m128i*)y;
|
|
#elif defined(__arm__)
|
|
yp128 = (int16x8_t*)y;
|
|
#endif
|
|
|
|
|
|
|
|
|
|
s = systematic0;
|
|
s1 = systematic1;
|
|
s2 = systematic2;
|
|
yp1 = yparity1;
|
|
yp2 = yparity2;
|
|
|
|
|
|
|
|
for (i=0; i<n; i+=8) {
|
|
pi2_p = &pi2tab16[iind][i];
|
|
|
|
j=pi2_p[0];
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
tmpe = _mm_load_si128(yp128);
|
|
// fprintf(fdsse4,"yp128 %p\n",yp128);
|
|
// print_shorts("tmpe",(int16_t *)&tmpe);
|
|
|
|
s[j] = _mm_extract_epi16(tmpe,0);
|
|
yp1[j] = _mm_extract_epi16(tmpe,1);
|
|
yp2[j] = _mm_extract_epi16(tmpe,2);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"init0: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
|
|
#endif
|
|
j=pi2_p[1];
|
|
|
|
s[j] = _mm_extract_epi16(tmpe,3);
|
|
yp1[j] = _mm_extract_epi16(tmpe,4);
|
|
yp2[j] = _mm_extract_epi16(tmpe,5);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"init1: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
|
|
#endif
|
|
j=pi2_p[2];
|
|
|
|
s[j] = _mm_extract_epi16(tmpe,6);
|
|
yp1[j] = _mm_extract_epi16(tmpe,7);
|
|
tmpe = _mm_load_si128(&yp128[1]);
|
|
yp2[j] = _mm_extract_epi16(tmpe,0);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"init2: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
|
|
#endif
|
|
j=pi2_p[3];
|
|
|
|
s[j] = _mm_extract_epi16(tmpe,1);
|
|
yp1[j] = _mm_extract_epi16(tmpe,2);
|
|
yp2[j] = _mm_extract_epi16(tmpe,3);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"init3: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
|
|
#endif
|
|
j=pi2_p[4];
|
|
|
|
s[j] = _mm_extract_epi16(tmpe,4);
|
|
yp1[j] = _mm_extract_epi16(tmpe,5);
|
|
yp2[j] = _mm_extract_epi16(tmpe,6);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"init4: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
|
|
#endif
|
|
j=pi2_p[5];
|
|
|
|
s[j] = _mm_extract_epi16(tmpe,7);
|
|
tmpe = _mm_load_si128(&yp128[2]);
|
|
yp1[j] = _mm_extract_epi16(tmpe,0);
|
|
yp2[j] = _mm_extract_epi16(tmpe,1);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"init5: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
|
|
#endif
|
|
|
|
j=pi2_p[6];
|
|
|
|
s[j] = _mm_extract_epi16(tmpe,2);
|
|
yp1[j] = _mm_extract_epi16(tmpe,3);
|
|
yp2[j] = _mm_extract_epi16(tmpe,4);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"init6: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
|
|
#endif
|
|
j=pi2_p[7];
|
|
|
|
s[j] = _mm_extract_epi16(tmpe,5);
|
|
yp1[j] = _mm_extract_epi16(tmpe,6);
|
|
yp2[j] = _mm_extract_epi16(tmpe,7);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"init7: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
|
|
#endif
|
|
|
|
#elif defined(__arm__)
|
|
s[j] = vgetq_lane_s16(yp128[0],0);
|
|
yp1[j] = vgetq_lane_s16(yp128[0],1);
|
|
yp2[j] = vgetq_lane_s16(yp128[0],2);
|
|
|
|
j=pi2_p[1];
|
|
s[j] = vgetq_lane_s16(yp128[0],3);
|
|
yp1[j] = vgetq_lane_s16(yp128[0],4);
|
|
yp2[j] = vgetq_lane_s16(yp128[0],5);
|
|
|
|
j=pi2_p[2];
|
|
s[j] = vgetq_lane_s16(yp128[0],6);
|
|
yp1[j] = vgetq_lane_s16(yp128[0],7);
|
|
yp2[j] = vgetq_lane_s16(yp128[1],0);
|
|
|
|
j=pi2_p[3];
|
|
s[j] = vgetq_lane_s16(yp128[1],1);
|
|
yp1[j] = vgetq_lane_s16(yp128[1],2);
|
|
yp2[j] = vgetq_lane_s16(yp128[1],3);
|
|
|
|
j=pi2_p[4];
|
|
s[j] = vgetq_lane_s16(yp128[1],4);
|
|
yp1[j] = vgetq_lane_s16(yp128[1],5);
|
|
yp2[j] = vgetq_lane_s16(yp128[1],6);
|
|
|
|
j=pi2_p[5];
|
|
s[j] = vgetq_lane_s16(yp128[1],7);
|
|
yp1[j] = vgetq_lane_s16(yp128[2],0);
|
|
yp2[j] = vgetq_lane_s16(yp128[2],1);
|
|
|
|
j=pi2_p[6];
|
|
s[j] = vgetq_lane_s16(yp128[2],2);
|
|
yp1[j] = vgetq_lane_s16(yp128[2],3);
|
|
yp2[j] = vgetq_lane_s16(yp128[2],4);
|
|
|
|
j=pi2_p[7];
|
|
s[j] = vgetq_lane_s16(yp128[2],5);
|
|
yp1[j] = vgetq_lane_s16(yp128[2],6);
|
|
yp2[j] = vgetq_lane_s16(yp128[2],7);
|
|
#endif
|
|
yp128+=3;
|
|
|
|
}
|
|
|
|
yp=(llr_t*)yp128;
|
|
|
|
|
|
// Termination
|
|
for (i=n; i<n+3; i++) {
|
|
s[i]= *yp;
|
|
s1[i] = s[i] ;
|
|
s2[i] = s[i];
|
|
yp++;
|
|
yp1[i] = *yp;
|
|
yp++;
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"Term 1 (%d): %d %d\n",i,s[i],yp1[i]);
|
|
#endif //DEBUG_LOGMAP
|
|
}
|
|
|
|
for (i=n+8; i<n+11; i++) {
|
|
s[i]= *yp;
|
|
s1[i] = s[i] ;
|
|
s2[i] = s[i];
|
|
yp++;
|
|
yp2[i-8] = *yp;
|
|
yp++;
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"Term 2 (%d): %d %d\n",i-3,s[i],yp2[i-8]);
|
|
#endif //DEBUG_LOGMAP
|
|
}
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"\n");
|
|
#endif //DEBUG_LOGMAP
|
|
|
|
stop_meas(init_stats);
|
|
|
|
// do log_map from first parity bit
|
|
|
|
log_map16(systematic0,yparity1,m11,m10,alpha,beta,ext,n,0,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats);
|
|
|
|
while (iteration_cnt++ < max_iterations) {
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"\n*******************ITERATION %d (n %d), ext %p\n\n",iteration_cnt,n,ext);
|
|
#endif //DEBUG_LOGMAP
|
|
|
|
start_meas(intl1_stats);
|
|
|
|
pi4_p=pi4tab16[iind];
|
|
|
|
for (i=0; i<(n>>3); i++) { // steady-state portion
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],ext[*pi4_p++],0);
|
|
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],ext[*pi4_p++],1);
|
|
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],ext[*pi4_p++],2);
|
|
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],ext[*pi4_p++],3);
|
|
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],ext[*pi4_p++],4);
|
|
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],ext[*pi4_p++],5);
|
|
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],ext[*pi4_p++],6);
|
|
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],ext[*pi4_p++],7);
|
|
|
|
#elif defined(__arm__)
|
|
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(ext[*pi4_p++],((int16x8_t*)systematic2)[i],0);
|
|
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(ext[*pi4_p++],((int16x8_t*)systematic2)[i],1);
|
|
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(ext[*pi4_p++],((int16x8_t*)systematic2)[i],2);
|
|
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(ext[*pi4_p++],((int16x8_t*)systematic2)[i],3);
|
|
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(ext[*pi4_p++],((int16x8_t*)systematic2)[i],4);
|
|
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(ext[*pi4_p++],((int16x8_t*)systematic2)[i],5);
|
|
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(ext[*pi4_p++],((int16x8_t*)systematic2)[i],6);
|
|
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(ext[*pi4_p++],((int16x8_t*)systematic2)[i],7);
|
|
#endif
|
|
#ifdef DEBUG_LOGMAP
|
|
print_shorts("syst2",(int16_t*)&((__m128i *)systematic2)[i]);
|
|
#endif
|
|
}
|
|
|
|
stop_meas(intl1_stats);
|
|
|
|
// do log_map from second parity bit
|
|
|
|
log_map16(systematic2,yparity2,m11,m10,alpha,beta,ext2,n,1,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats);
|
|
|
|
|
|
|
|
pi5_p=pi5tab16[iind];
|
|
|
|
for (i=0; i<(n>>3); i++) {
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],0);
|
|
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],1);
|
|
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],2);
|
|
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],3);
|
|
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],4);
|
|
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],5);
|
|
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],6);
|
|
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],7);
|
|
((__m128i *)systematic1)[i] = _mm_adds_epi16(_mm_subs_epi16(tmp,((__m128i*)ext)[i]),((__m128i *)systematic0)[i]);
|
|
#elif defined(__arm__)
|
|
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,0);
|
|
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,1);
|
|
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,2);
|
|
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,3);
|
|
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,4);
|
|
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,5);
|
|
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,6);
|
|
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,7);
|
|
((int16x8_t *)systematic1)[i] = vqaddq_s16(vqsubq_s16(tmp,((int16x8_t*)ext)[i]),((int16x8_t *)systematic0)[i]);
|
|
#endif
|
|
#ifdef DEBUG_LOGMAP
|
|
print_shorts("syst1",(int16_t*)&((__m128i *)systematic1)[i]);
|
|
#endif
|
|
}
|
|
|
|
if (iteration_cnt>1) {
|
|
start_meas(intl2_stats);
|
|
pi6_p=pi6tab16[iind];
|
|
|
|
for (i=0; i<(n>>3); i++) {
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],7);
|
|
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],6);
|
|
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],5);
|
|
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],4);
|
|
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],3);
|
|
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],2);
|
|
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],1);
|
|
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],0);
|
|
#ifdef DEBUG_LOGMAP
|
|
print_shorts("tmp",(int16_t*)&tmp);
|
|
#endif
|
|
tmp=_mm_cmpgt_epi8(_mm_packs_epi16(tmp,zeros),zeros);
|
|
decoded_bytes[i]=(unsigned char)_mm_movemask_epi8(tmp);
|
|
#elif defined(__arm__)
|
|
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,7);
|
|
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,6);
|
|
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,5);
|
|
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,4);
|
|
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,3);
|
|
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,2);
|
|
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,1);
|
|
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,0);
|
|
// This does:
|
|
// [1 2 4 8 16 32 64 128] .* I(ext_i > 0) = 2.^[b0 b1 b2 b3 b4 b5 b6 b7], where bi =I(ext_i > 0)
|
|
// [2^b0 + 2^b1 2^b2 + 2^b3 2^b4 + 2^b5 2^b6 + 2^b7]
|
|
// [2^b0 + 2^b1 + 2^b2 + 2^b3 2^b4 + 2^b5 + 2^b6 + 2^b7]
|
|
// Mask64 = 2^b0 + 2^b1 + 2^b2 + 2^b3 + 2^b4 + 2^b5 + 2^b6 + 2^b7
|
|
uint64x2_t Mask = vpaddlq_u32(vpaddlq_u16(vandq_u16(vcgtq_s16(tmp,zeros), Powers)));
|
|
uint64x1_t Mask64 = vget_high_u64(Mask)+vget_low_u64(Mask);
|
|
decoded_bytes[i] = (uint8_t)Mask64;
|
|
#endif
|
|
#ifdef DEBUG_LOGMAP
|
|
print_shorts("tmp",(int16_t*)&tmp);
|
|
fprintf(fdsse4,"decoded_bytes[%d] %x\n",i,decoded_bytes[i]);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// check status on output
|
|
if (iteration_cnt>1) {
|
|
oldcrc= *((unsigned int *)(&decoded_bytes[(n>>3)-crc_len]));
|
|
|
|
switch (crc_type) {
|
|
|
|
case CRC24_A:
|
|
oldcrc&=0x00ffffff;
|
|
crc = crc24a(&decoded_bytes[F>>3],
|
|
n-24-F)>>8;
|
|
temp=((uint8_t *)&crc)[2];
|
|
((uint8_t *)&crc)[2] = ((uint8_t *)&crc)[0];
|
|
((uint8_t *)&crc)[0] = temp;
|
|
break;
|
|
|
|
case CRC24_B:
|
|
oldcrc&=0x00ffffff;
|
|
crc = crc24b(decoded_bytes,
|
|
n-24)>>8;
|
|
temp=((uint8_t *)&crc)[2];
|
|
((uint8_t *)&crc)[2] = ((uint8_t *)&crc)[0];
|
|
((uint8_t *)&crc)[0] = temp;
|
|
break;
|
|
|
|
case CRC16:
|
|
oldcrc&=0x0000ffff;
|
|
crc = crc16(decoded_bytes,
|
|
n-16)>>16;
|
|
break;
|
|
|
|
case CRC8:
|
|
oldcrc&=0x000000ff;
|
|
crc = crc8(decoded_bytes,
|
|
n-8)>>24;
|
|
break;
|
|
|
|
default:
|
|
printf("FATAL: 3gpplte_turbo_decoder_sse.c: Unknown CRC\n");
|
|
return(255);
|
|
break;
|
|
}
|
|
|
|
stop_meas(intl2_stats);
|
|
#ifdef DEBUG_LOGMAP
|
|
fprintf(fdsse4,"oldcrc %x, crc %x\n",oldcrc,crc);
|
|
#endif
|
|
|
|
if (crc == oldcrc) {
|
|
return(iteration_cnt);
|
|
}
|
|
}
|
|
|
|
// do log_map from first parity bit
|
|
if (iteration_cnt < max_iterations) {
|
|
log_map16(systematic1,yparity1,m11,m10,alpha,beta,ext,n,0,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats);
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
__m128i* ext_128=(__m128i*) ext;
|
|
__m128i* s1_128=(__m128i*) systematic1;
|
|
__m128i* s0_128=(__m128i*) systematic0;
|
|
#elif defined(__arm__)
|
|
int16x8_t* ext_128=(int16x8_t*) ext;
|
|
int16x8_t* s1_128=(int16x8_t*) systematic1;
|
|
int16x8_t* s0_128=(int16x8_t*) systematic0;
|
|
#endif
|
|
int myloop=n>>3;
|
|
|
|
for (i=0; i<myloop; i++) {
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
*ext_128=_mm_adds_epi16(_mm_subs_epi16(*ext_128,*s1_128++),*s0_128++);
|
|
#elif defined(__arm__)
|
|
*ext_128=vqaddq_s16(vqsubq_s16(*ext_128,*s1_128++),*s0_128++);
|
|
#endif
|
|
ext_128++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// fprintf(fdsse4,"crc %x, oldcrc %x\n",crc,oldcrc);
|
|
|
|
#ifdef DEBUG_LOGMAP
|
|
fclose(fdsse4);
|
|
#endif
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
_mm_empty();
|
|
_m_empty();
|
|
#endif
|
|
return(iteration_cnt);
|
|
}
|
|
|
|
|
|
|
|
|