/* * 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.1 (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 */ /// /// #ifndef TEST_DEBUG #include "PHY/impl_defs_top.h" #include "PHY/defs_common.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" #include "extern_3GPPinterleaver.h" #else #include "defs.h" #include #include #include #endif #ifdef MEX #include "mex.h" #endif #ifdef __AVX2__ #include "PHY/sse_intrin.h" //#define DEBUG_LOGMAP #ifdef DEBUG_LOGMAP #define print_shorts(s,x) fprintf(fdavx2,"%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]);fprintf(fdavx2b,"%s %d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[8],(x)[9],(x)[10],(x)[11],(x)[12],(x)[13],(x)[14],(x)[15]) FILE *fdavx2,*fdavx2b; #else #endif #define print_bytes(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%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],(x)[8],(x)[9],(x)[10],(x)[11],(x)[12],(x)[13],(x)[14],(x)[15],(x)[16],(x)[17],(x)[18],(x)[19],(x)[20],(x)[21],(x)[22],(x)[23],(x)[24],(x)[25],(x)[26],(x)[27],(x)[28],(x)[29],(x)[30],(x)[31]) typedef int16_t llr_t; // internal decoder LLR data is 16-bit fixed typedef int16_t channel_t; #define MAX 256 void log_map16avx2(llr_t* systematic,channel_t* y_parity, llr_t* m11, llr_t* m10, llr_t *alpha, llr_t *beta, llr_t* ext,uint16_t 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_gamma16avx2(llr_t* m11,llr_t* m10,llr_t* systematic, channel_t* y_parity, uint16_t frame_length,unsigned char term_flag); void compute_alpha16avx2(llr_t*alpha,llr_t *beta, llr_t* m11,llr_t* m10, uint16_t frame_length,unsigned char F); void compute_beta16avx2(llr_t*alpha, llr_t* beta,llr_t* m11,llr_t* m10, uint16_t frame_length,unsigned char F,int offset8_flag); void compute_ext16avx2(llr_t* alpha,llr_t* beta,llr_t* m11,llr_t* m10,llr_t* extrinsic, llr_t* ap, uint16_t frame_length); void log_map16avx2(llr_t* systematic, channel_t* y_parity, llr_t* m11, llr_t* m10, llr_t *alpha, llr_t *beta, llr_t* ext, uint16_t 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(fdavx2,"log_map (avx2_16bit), frame_length %d\n",frame_length); fprintf(fdavx2b,"log_map (avx2_16bit), frame_length %d\n",frame_length); #endif start_meas(gamma_stats) ; compute_gamma16avx2(m11,m10,systematic,y_parity,frame_length,term_flag) ; stop_meas(gamma_stats); start_meas(alpha_stats) ; compute_alpha16avx2(alpha,beta,m11,m10,frame_length,F) ; stop_meas(alpha_stats); start_meas(beta_stats) ; compute_beta16avx2(alpha,beta,m11,m10,frame_length,F,offset8_flag) ; stop_meas(beta_stats); start_meas(ext_stats) ; compute_ext16avx2(alpha,beta,m11,m10,ext,systematic,frame_length) ; stop_meas(ext_stats); } void compute_gamma16avx2(llr_t* m11,llr_t* m10,llr_t* systematic,channel_t* y_parity, uint16_t frame_length,unsigned char term_flag) { int k,K1; __m256i *systematic128 = (__m256i *)systematic; __m256i *y_parity128 = (__m256i *)y_parity; __m256i *m10_128 = (__m256i *)m10; __m256i *m11_128 = (__m256i *)m11; #ifdef DEBUG_LOGMAP fprintf(fdavx2,"compute_gamma (avx2_16bit), %p,%p,%p,%p,framelength %d\n",m11,m10,systematic,y_parity,frame_length); fprintf(fdavx2b,"compute_gamma (avx2_16bit), %p,%p,%p,%p,framelength %d\n",m11,m10,systematic,y_parity,frame_length); #endif K1=frame_length>>3; for (k=0; k>3; K1 = (frame_length>>3); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"Compute alpha (avx2_16bit)\n"); fprintf(fdavx2b,"Compute alpha (avx2_16bit)\n"); #endif timein = rdtsc_oai(); for (l=K1;; l=l2,rerun_flag=1) { alpha128 = (__m256i *)alpha; if (rerun_flag == 0) { alpha128[0] = _mm256_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,0,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,0); alpha128[1] = _mm256_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2); alpha128[2] = _mm256_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2); alpha128[3] = _mm256_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2); alpha128[4] = _mm256_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2); alpha128[5] = _mm256_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2); alpha128[6] = _mm256_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2); alpha128[7] = _mm256_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"Initial alpha\n"); fprintf(fdavx2b,"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 alpha128[0] = _mm256_slli_si256(alpha128[frame_length],2); alpha128[1] = _mm256_slli_si256(alpha128[1+frame_length],2); alpha128[2] = _mm256_slli_si256(alpha128[2+frame_length],2); alpha128[3] = _mm256_slli_si256(alpha128[3+frame_length],2); alpha128[4] = _mm256_slli_si256(alpha128[4+frame_length],2); alpha128[5] = _mm256_slli_si256(alpha128[5+frame_length],2); alpha128[6] = _mm256_slli_si256(alpha128[6+frame_length],2); alpha128[7] = _mm256_slli_si256(alpha128[7+frame_length],2); // set initial alpha in column 0 to (0,-MAX/2,...,-MAX/2) alpha[16] = -MAX/2; alpha[32] = -MAX/2; alpha[48] = -MAX/2; alpha[64] = -MAX/2; alpha[80] = -MAX/2; alpha[96] = -MAX/2; alpha[112] = -MAX/2; alpha[24] = -MAX/2; alpha[40] = -MAX/2; alpha[56] = -MAX/2; alpha[72] = -MAX/2; alpha[88] = -MAX/2; alpha[104] = -MAX/2; alpha[120] = -MAX/2; #ifdef DEBUG_LOGMAP fprintf(fdavx2,"Second run\n"); fprintf(fdavx2b,"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]; m11p = (__m256i*)m_11; m10p = (__m256i*)m_10; for (k=0; kbeta1_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; beta_m_cw2 = (beta0_cw2_16>beta1_cw2_16) ? beta0_cw2_16 : beta1_cw2_16; beta_m_cw2 = (beta_m_cw2>beta2_cw2_16) ? beta_m_cw2 : beta2_cw2_16; beta_m_cw2 = (beta_m_cw2>beta3_cw2_16) ? beta_m_cw2 : beta3_cw2_16; beta_m_cw2 = (beta_m_cw2>beta4_cw2_16) ? beta_m_cw2 : beta4_cw2_16; beta_m_cw2 = (beta_m_cw2>beta5_cw2_16) ? beta_m_cw2 : beta5_cw2_16; beta_m_cw2 = (beta_m_cw2>beta6_cw2_16) ? beta_m_cw2 : beta6_cw2_16; beta_m_cw2 = (beta_m_cw2>beta7_cw2_16) ? beta_m_cw2 : beta7_cw2_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; beta0_cw2_16=beta0_cw2_16-beta_m_cw2; beta1_cw2_16=beta1_cw2_16-beta_m_cw2; beta2_cw2_16=beta2_cw2_16-beta_m_cw2; beta3_cw2_16=beta3_cw2_16-beta_m_cw2; beta4_cw2_16=beta4_cw2_16-beta_m_cw2; beta5_cw2_16=beta5_cw2_16-beta_m_cw2; beta6_cw2_16=beta6_cw2_16-beta_m_cw2; beta7_cw2_16=beta7_cw2_16-beta_m_cw2; for (rerun_flag=0;; rerun_flag=1) { beta_ptr = (__m256i*)&beta[frame_length<<4]; alpha128 = (__m256i*)&alpha[0]; 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(fdavx2,"beta init \n"); fprintf(fdavx2b,"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 { beta128 = (__m256i*)&beta[0]; beta_ptr[0] = _mm256_srli_si256(beta128[0],2); beta_ptr[1] = _mm256_srli_si256(beta128[1],2); beta_ptr[2] = _mm256_srli_si256(beta128[2],2); beta_ptr[3] = _mm256_srli_si256(beta128[3],2); beta_ptr[4] = _mm256_srli_si256(beta128[4],2); beta_ptr[5] = _mm256_srli_si256(beta128[5],2); beta_ptr[6] = _mm256_srli_si256(beta128[6],2); beta_ptr[7] = _mm256_srli_si256(beta128[7],2); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"beta init (second run)\n"); fprintf(fdavx2b,"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 } beta_ptr[0] = _mm256_insert_epi16(beta_ptr[0],beta0_16,7); beta_ptr[1] = _mm256_insert_epi16(beta_ptr[1],beta1_16,7); beta_ptr[2] = _mm256_insert_epi16(beta_ptr[2],beta2_16,7); beta_ptr[3] = _mm256_insert_epi16(beta_ptr[3],beta3_16,7); beta_ptr[4] = _mm256_insert_epi16(beta_ptr[4],beta4_16,7); beta_ptr[5] = _mm256_insert_epi16(beta_ptr[5],beta5_16,7); beta_ptr[6] = _mm256_insert_epi16(beta_ptr[6],beta6_16,7); beta_ptr[7] = _mm256_insert_epi16(beta_ptr[7],beta7_16,7); beta_ptr[0] = _mm256_insert_epi16(beta_ptr[0],beta0_cw2_16,15); beta_ptr[1] = _mm256_insert_epi16(beta_ptr[1],beta1_cw2_16,15); beta_ptr[2] = _mm256_insert_epi16(beta_ptr[2],beta2_cw2_16,15); beta_ptr[3] = _mm256_insert_epi16(beta_ptr[3],beta3_cw2_16,15); beta_ptr[4] = _mm256_insert_epi16(beta_ptr[4],beta4_cw2_16,15); beta_ptr[5] = _mm256_insert_epi16(beta_ptr[5],beta5_cw2_16,15); beta_ptr[6] = _mm256_insert_epi16(beta_ptr[6],beta6_cw2_16,15); beta_ptr[7] = _mm256_insert_epi16(beta_ptr[7],beta7_cw2_16,15); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"beta init (after insert) \n"); fprintf(fdavx2b,"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)); printf("beta: rerun %d => loopval %d\n",rerun_flag,loopval); timein = rdtsc_oai(); m11p = (frame_length>>3)-1+(__m256i*)m_11; m10p = (frame_length>>3)-1+(__m256i*)m_10; for (k=(frame_length>>3)-1; k>=loopval; k--) { b4 = _mm256_load_si256(&beta_ptr[4]); b5 = _mm256_load_si256(&beta_ptr[5]); b6 = _mm256_load_si256(&beta_ptr[6]); b7 = _mm256_load_si256(&beta_ptr[7]); m_b0 = _mm256_adds_epi16(b4,*m11p); //m11 m_b1 = _mm256_subs_epi16(b4,*m11p); //m00 m_b2 = _mm256_subs_epi16(b5,*m10p); //m01 m_b3 = _mm256_adds_epi16(b5,*m10p); //m10 m_b4 = _mm256_adds_epi16(b6,*m10p); //m10 m_b5 = _mm256_subs_epi16(b6,*m10p); //m01 m_b6 = _mm256_subs_epi16(b7,*m11p); //m00 m_b7 = _mm256_adds_epi16(b7,*m11p); //m11 b0 = _mm256_load_si256(&beta_ptr[0]); b1 = _mm256_load_si256(&beta_ptr[1]); b2 = _mm256_load_si256(&beta_ptr[2]); b3 = _mm256_load_si256(&beta_ptr[3]); new0 = _mm256_subs_epi16(b0,*m11p); //m00 new1 = _mm256_adds_epi16(b0,*m11p); //m11 new2 = _mm256_adds_epi16(b1,*m10p); //m10 new3 = _mm256_subs_epi16(b1,*m10p); //m01 new4 = _mm256_subs_epi16(b2,*m10p); //m01 new5 = _mm256_adds_epi16(b2,*m10p); //m10 new6 = _mm256_adds_epi16(b3,*m11p); //m11 new7 = _mm256_subs_epi16(b3,*m11p); //m00 b0 = _mm256_max_epi16(m_b0,new0); b1 = _mm256_max_epi16(m_b1,new1); b2 = _mm256_max_epi16(m_b2,new2); b3 = _mm256_max_epi16(m_b3,new3); b4 = _mm256_max_epi16(m_b4,new4); b5 = _mm256_max_epi16(m_b5,new5); b6 = _mm256_max_epi16(m_b6,new6); b7 = _mm256_max_epi16(m_b7,new7); beta_max = _mm256_max_epi16(b0,b1); beta_max = _mm256_max_epi16(beta_max ,b2); beta_max = _mm256_max_epi16(beta_max ,b3); beta_max = _mm256_max_epi16(beta_max ,b4); beta_max = _mm256_max_epi16(beta_max ,b5); beta_max = _mm256_max_epi16(beta_max ,b6); beta_max = _mm256_max_epi16(beta_max ,b7); beta_ptr-=8; m11p--; m10p--; beta_ptr[0] = _mm256_subs_epi16(b0,beta_max); beta_ptr[1] = _mm256_subs_epi16(b1,beta_max); beta_ptr[2] = _mm256_subs_epi16(b2,beta_max); beta_ptr[3] = _mm256_subs_epi16(b3,beta_max); beta_ptr[4] = _mm256_subs_epi16(b4,beta_max); beta_ptr[5] = _mm256_subs_epi16(b5,beta_max); beta_ptr[6] = _mm256_subs_epi16(b6,beta_max); beta_ptr[7] = _mm256_subs_epi16(b7,beta_max); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"Loop index %d, mb\n",k); fprintf(fdavx2,"beta init (after max)\n"); fprintf(fdavx2b,"Loop index %d, mb\n",k); fprintf(fdavx2b,"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 } timeout = rdtsc_oai(); printf("beta: inner loop time %llu\n",timeout-timein); if (rerun_flag==1) break; } } void compute_ext16avx2(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, llr_t* systematic,uint16_t frame_length) { __m256i *alpha128=(__m256i *)alpha; __m256i *beta128=(__m256i *)beta; __m256i *m11_128,*m10_128,*ext_128; __m256i *alpha_ptr,*beta_ptr; __m256i m00_1,m00_2,m00_3,m00_4; __m256i m01_1,m01_2,m01_3,m01_4; __m256i m10_1,m10_2,m10_3,m10_4; __m256i m11_1,m11_2,m11_3,m11_4; int k; // // LLR computation, 8 consequtive bits per loop // #ifdef DEBUG_LOGMAP fprintf(fdavx2,"compute_ext (avx2_16bit), %p, %p, %p, %p, %p, %p ,framelength %d\n",alpha,beta,m_11,m_10,ext,systematic,frame_length); fprintf(fdavx2b,"compute_ext (avx2_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++) { m11_128 = (__m256i*)&m_11[k<<4]; m10_128 = (__m256i*)&m_10[k<<4]; ext_128 = (__m256i*)&ext[k<<4]; /* fprintf(fdavx2,"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]); */ m00_4 = _mm256_adds_epi16(alpha_ptr[7],beta_ptr[3]); //ALPHA_BETA_4m00; m11_4 = _mm256_adds_epi16(alpha_ptr[7],beta_ptr[7]); //ALPHA_BETA_4m11; m00_3 = _mm256_adds_epi16(alpha_ptr[6],beta_ptr[7]); //ALPHA_BETA_3m00; m11_3 = _mm256_adds_epi16(alpha_ptr[6],beta_ptr[3]); //ALPHA_BETA_3m11; m00_2 = _mm256_adds_epi16(alpha_ptr[1],beta_ptr[4]); //ALPHA_BETA_2m00; m11_2 = _mm256_adds_epi16(alpha_ptr[1],beta_ptr[0]); //ALPHA_BETA_2m11; m11_1 = _mm256_adds_epi16(alpha_ptr[0],beta_ptr[4]); //ALPHA_BETA_1m11; m00_1 = _mm256_adds_epi16(alpha_ptr[0],beta_ptr[0]); //ALPHA_BETA_1m00; m01_4 = _mm256_adds_epi16(alpha_ptr[5],beta_ptr[6]); //ALPHA_BETA_4m01; m10_4 = _mm256_adds_epi16(alpha_ptr[5],beta_ptr[2]); //ALPHA_BETA_4m10; m01_3 = _mm256_adds_epi16(alpha_ptr[4],beta_ptr[2]); //ALPHA_BETA_3m01; m10_3 = _mm256_adds_epi16(alpha_ptr[4],beta_ptr[6]); //ALPHA_BETA_3m10; m01_2 = _mm256_adds_epi16(alpha_ptr[3],beta_ptr[1]); //ALPHA_BETA_2m01; m10_2 = _mm256_adds_epi16(alpha_ptr[3],beta_ptr[5]); //ALPHA_BETA_2m10; m10_1 = _mm256_adds_epi16(alpha_ptr[2],beta_ptr[1]); //ALPHA_BETA_1m10; m01_1 = _mm256_adds_epi16(alpha_ptr[2],beta_ptr[5]); //ALPHA_BETA_1m01; /* 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 = _mm256_max_epi16(m01_1,m01_2); m01_1 = _mm256_max_epi16(m01_1,m01_3); m01_1 = _mm256_max_epi16(m01_1,m01_4); m00_1 = _mm256_max_epi16(m00_1,m00_2); m00_1 = _mm256_max_epi16(m00_1,m00_3); m00_1 = _mm256_max_epi16(m00_1,m00_4); m10_1 = _mm256_max_epi16(m10_1,m10_2); m10_1 = _mm256_max_epi16(m10_1,m10_3); m10_1 = _mm256_max_epi16(m10_1,m10_4); m11_1 = _mm256_max_epi16(m11_1,m11_2); m11_1 = _mm256_max_epi16(m11_1,m11_3); m11_1 = _mm256_max_epi16(m11_1,m11_4); // print_shorts("m11_1:",&m11_1); m01_1 = _mm256_subs_epi16(m01_1,*m10_128); m00_1 = _mm256_subs_epi16(m00_1,*m11_128); m10_1 = _mm256_adds_epi16(m10_1,*m10_128); m11_1 = _mm256_adds_epi16(m11_1,*m11_128); // print_shorts("m10_1:",&m10_1); // print_shorts("m11_1:",&m11_1); m01_1 = _mm256_max_epi16(m01_1,m00_1); m10_1 = _mm256_max_epi16(m10_1,m11_1); // print_shorts("m01_1:",&m01_1); // print_shorts("m10_1:",&m10_1); *ext_128 = _mm256_subs_epi16(m10_1,m01_1); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"ext %p\n",ext_128); fprintf(fdavx2b,"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 alpha_ptr+=8; beta_ptr+=8; } } //int pi2[n],pi3[n+8],pi5[n+8],pi4[n+8],pi6[n+8], int *pi2tab16avx2[188],*pi5tab16avx2[188],*pi4tab16avx2[188],*pi6tab16avx2[188]; void free_td16avx2(void) { int ind; for (ind=0; ind<188; ind++) { free_and_zero(pi2tab16avx2[ind]); free_and_zero(pi5tab16avx2[ind]); free_and_zero(pi4tab16avx2[ind]); free_and_zero(pi6tab16avx2[ind]); } } void init_td16avx2(void) { int ind,i,i2,i3,j,n,pi,pi2_i,pi2_pi; 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 pi2tab16avx2[ind] = malloc((n+8)*sizeof(int)); pi5tab16avx2[ind] = malloc((n+8)*sizeof(int)); pi4tab16avx2[ind] = malloc((n+8)*sizeof(int)); pi6tab16avx2[ind] = malloc((n+8)*sizeof(int)); #endif // fprintf(fdavx2,"Interleaver index %d\n",ind); 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); pi2tab16avx2[ind][i] = ((j>>3)<<4) + (j&7); // 16*floor(j/8) + j mod8, which allows the second codeword to be in pi[i] + 8 // fprintf(fdavx2,"pi2[%d] = %d(%d)\n",i, pi2tab16avx2[ind][i],j); } } for (i=0; i>4)<<3)+(pi2tab16avx2[ind][i]&7); pi2_pi = ((pi2tab16avx2[ind][pi]>>4)<<3)+(pi2tab16avx2[ind][pi]&7); pi4tab16avx2[ind][pi2_i] = pi2tab16avx2[ind][pi]; pi5tab16avx2[ind][pi2_pi] = pi2tab16avx2[ind][i]; pi6tab16avx2[ind][pi] = pi2tab16avx2[ind][i]; } } } unsigned char phy_threegpplte_turbo_decoder16avx2(int16_t *y, int16_t *y2, uint8_t *decoded_bytes, uint8_t *decoded_bytes2, uint16_t n, uint16_t f1, uint16_t f2, uint8_t max_iterations, uint8_t crc_type, uint8_t 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[2*(n+16)] __attribute__ ((aligned(32))); llr_t systematic1[2*(n+16)] __attribute__ ((aligned(32))); llr_t systematic2[2*(n+16)] __attribute__ ((aligned(32))); llr_t yparity1[2*(n+16)] __attribute__ ((aligned(32))); llr_t yparity2[2*(n+16)] __attribute__ ((aligned(32))); llr_t ext[2*(n+128)] __attribute__((aligned(32))); llr_t ext2[2*(n+128)] __attribute__((aligned(32))); llr_t alpha[(n+16)*16] __attribute__ ((aligned(32))); llr_t beta[(n+16)*16] __attribute__ ((aligned(32))); llr_t m11[2*(n+16)] __attribute__ ((aligned(32))); llr_t m10[2*(n+16)] __attribute__ ((aligned(32))); int *pi2_p,*pi4_p,*pi5_p,*pi6_p; llr_t *s,*s1,*s2,*yp1,*yp2,*yp,*yp_cw2; uint32_t i,j,iind;//,pi; uint8_t iteration_cnt=0; uint32_t crc,oldcrc,crc_cw2,oldcrc_cw2,crc_len; uint8_t temp; uint32_t db; __m256i tmp, zeros=_mm256_setzero_si256(); int offset8_flag=0; #ifdef DEBUG_LOGMAP fdavx2 = fopen("dump_avx2.txt","w"); fdavx2b = fopen("dump_avx2b.txt","w"); printf("tc avx2_16 (y,y2) %p,%p\n",y,y2); #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; } s = systematic0; s1 = systematic1; s2 = systematic2; yp1 = yparity1; yp2 = yparity2; #if 0 __m128i *yp128,*yp128_cw2; __m128i tmpe,tmpe_cw2; yp128 = (__m128i*)y; yp128_cw2 = (__m128i*)y2; for (i=0; i>4)<<3)+(j&7),s[j],yp1[j],yp2[j]); fprintf(fdavx2b,"init0: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j+8],yp1[j+8],yp2[j+8]); #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); s[j+8] = _mm_extract_epi16(tmpe_cw2,3); yp1[j+8] = _mm_extract_epi16(tmpe_cw2,4); yp2[j+8] = _mm_extract_epi16(tmpe_cw2,5); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"init1: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j],yp1[j],yp2[j]); fprintf(fdavx2b,"init1: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j+8],yp1[j+8],yp2[j+8]); #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); s[j+8] = _mm_extract_epi16(tmpe_cw2,6); yp1[j+8] = _mm_extract_epi16(tmpe_cw2,7); tmpe_cw2 = _mm_load_si128(&yp128_cw2[1]); yp2[j+8] = _mm_extract_epi16(tmpe_cw2,0); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"init2: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j],yp1[j],yp2[j]); fprintf(fdavx2b,"init2: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j+8],yp1[j+8],yp2[j+8]); #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); s[j+8] = _mm_extract_epi16(tmpe_cw2,1); yp1[j+8] = _mm_extract_epi16(tmpe_cw2,2); yp2[j+8] = _mm_extract_epi16(tmpe_cw2,3); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"init3: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j],yp1[j],yp2[j]); fprintf(fdavx2b,"init3: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j+8],yp1[j+8],yp2[j+8]); #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); s[j+8] = _mm_extract_epi16(tmpe_cw2,4); yp1[j+8] = _mm_extract_epi16(tmpe_cw2,5); yp2[j+8] = _mm_extract_epi16(tmpe_cw2,6); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"init4: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j],yp1[j],yp2[j]); fprintf(fdavx2b,"init4: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j+8],yp1[j+8],yp2[j+8]); #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); s[j+8] = _mm_extract_epi16(tmpe_cw2,7); tmpe_cw2 = _mm_load_si128(&yp128_cw2[2]); yp1[j+8] = _mm_extract_epi16(tmpe_cw2,0); yp2[j+8] = _mm_extract_epi16(tmpe_cw2,1); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"init5: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j],yp1[j],yp2[j]); fprintf(fdavx2b,"init5: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j+8],yp1[j+8],yp2[j+8]); #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); s[j+8] = _mm_extract_epi16(tmpe_cw2,2); yp1[j+8] = _mm_extract_epi16(tmpe_cw2,3); yp2[j+8] = _mm_extract_epi16(tmpe_cw2,4); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"init6: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j],yp1[j],yp2[j]); fprintf(fdavx2b,"init6: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j+8],yp1[j+8],yp2[j+8]); #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); s[j+8] = _mm_extract_epi16(tmpe_cw2,5); yp1[j+8] = _mm_extract_epi16(tmpe_cw2,6); yp2[j+8] = _mm_extract_epi16(tmpe_cw2,7); #ifdef DEBUG_LOGMAP fprintf(fdavx2,"init7: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j],yp1[j],yp2[j]); fprintf(fdavx2b,"init7: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",((j>>4)<<3)+(j&7),s[j+8],yp1[j+8],yp2[j+8]); #endif yp128+=3; yp128_cw2+=3; } yp=(llr_t*)yp128; yp_cw2=(llr_t*)yp128_cw2; #else pi2_p = &pi2tab16avx2[iind][0]; for (i=0,j=0; i>3); i++) { // steady-state portion ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[*pi4_p],0); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[8+*pi4_p++],8); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[*pi4_p],1); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[8+*pi4_p++],9); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[*pi4_p],2); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[8+*pi4_p++],10); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[*pi4_p],3); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[8+*pi4_p++],11); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[*pi4_p],4); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[8+*pi4_p++],12); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[*pi4_p],5); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[8+*pi4_p++],13); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[*pi4_p],6); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[8+*pi4_p++],14); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[*pi4_p],7); ((__m256i *)systematic2)[i]=_mm256_insert_epi16(((__m256i *)systematic2)[i],ext[8+*pi4_p++],15); #ifdef DEBUG_LOGMAP print_shorts("syst2",(int16_t*)&((__m256i *)systematic2)[i]); #endif } stop_meas(intl1_stats); // do log_map from second parity bit log_map16avx2(systematic2,yparity2,m11,m10,alpha,beta,ext2,n,1,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats); pi5_p=pi5tab16avx2[iind]; for (i=0; i<(n>>3); i++) { tmp=_mm256_insert_epi16(tmp,ext2[*pi5_p],0); tmp=_mm256_insert_epi16(tmp,ext2[8+*pi5_p++],8); tmp=_mm256_insert_epi16(tmp,ext2[*pi5_p],1); tmp=_mm256_insert_epi16(tmp,ext2[8+*pi5_p++],9); tmp=_mm256_insert_epi16(tmp,ext2[*pi5_p],2); tmp=_mm256_insert_epi16(tmp,ext2[8+*pi5_p++],10); tmp=_mm256_insert_epi16(tmp,ext2[*pi5_p],3); tmp=_mm256_insert_epi16(tmp,ext2[8+*pi5_p++],11); tmp=_mm256_insert_epi16(tmp,ext2[*pi5_p],4); tmp=_mm256_insert_epi16(tmp,ext2[8+*pi5_p++],12); tmp=_mm256_insert_epi16(tmp,ext2[*pi5_p],5); tmp=_mm256_insert_epi16(tmp,ext2[8+*pi5_p++],13); tmp=_mm256_insert_epi16(tmp,ext2[*pi5_p],6); tmp=_mm256_insert_epi16(tmp,ext2[8+*pi5_p++],14); tmp=_mm256_insert_epi16(tmp,ext2[*pi5_p],7); tmp=_mm256_insert_epi16(tmp,ext2[8+*pi5_p++],15); ((__m256i *)systematic1)[i] = _mm256_adds_epi16(_mm256_subs_epi16(tmp,((__m256i*)ext)[i]),((__m256i *)systematic0)[i]); #ifdef DEBUG_LOGMAP print_shorts("syst1",(int16_t*)&((__m256i *)systematic1)[i]); #endif } if (iteration_cnt>1) { start_meas(intl2_stats); pi6_p=pi6tab16avx2[iind]; for (i=0; i<(n>>3); i++) { tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p],7); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[8+*pi6_p++],15); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p],6); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[8+*pi6_p++],14); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p],5); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[8+*pi6_p++],13); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p],4); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[8+*pi6_p++],12); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p],3); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[8+*pi6_p++],11); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p],2); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[8+*pi6_p++],10); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p],1); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[8+*pi6_p++],9); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p],0); tmp=_mm256_insert_epi16(tmp, ((llr_t*)ext2)[8+*pi6_p++],8); #ifdef DEBUG_LOGMAP print_shorts("tmp",(int16_t*)&tmp); #endif tmp=_mm256_cmpgt_epi8(_mm256_packs_epi16(tmp,zeros),zeros); db=(uint32_t)_mm256_movemask_epi8(tmp); decoded_bytes[i]=db&0xff; decoded_bytes2[i]=(uint8_t)(db>>16)&0xff; #ifdef DEBUG_LOGMAP print_shorts("tmp",(int16_t*)&tmp); fprintf(fdavx2,"decoded_bytes[%d] %x (%x)\n",i,decoded_bytes[i],db); fprintf(fdavx2b,"decoded_bytes[%d] %x (%x)\n",i,decoded_bytes2[i],db); #endif } } // check status on output if (iteration_cnt>1) { oldcrc= *((uint32_t *)(&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; } // second CW oldcrc_cw2= *((uint32_t *)(&decoded_bytes2[(n>>3)-crc_len])); switch (crc_type) { case CRC24_A: oldcrc_cw2&=0x00ffffff; crc_cw2 = crc24a(&decoded_bytes2[F>>3], n-24-F)>>8; temp=((uint8_t *)&crc_cw2)[2]; ((uint8_t *)&crc_cw2)[2] = ((uint8_t *)&crc_cw2)[0]; ((uint8_t *)&crc_cw2)[0] = temp; break; case CRC24_B: oldcrc_cw2&=0x00ffffff; crc_cw2 = crc24b(decoded_bytes2, n-24)>>8; temp=((uint8_t *)&crc_cw2)[2]; ((uint8_t *)&crc_cw2)[2] = ((uint8_t *)&crc_cw2)[0]; ((uint8_t *)&crc_cw2)[0] = temp; break; case CRC16: oldcrc_cw2&=0x0000ffff; crc_cw2 = crc16(decoded_bytes2, n-16)>>16; break; case CRC8: oldcrc_cw2&=0x000000ff; crc_cw2 = crc8(decoded_bytes2, 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(fdavx2,"oldcrc %x, crc %x, oldcrc_cw2 %x, crc_cw2 %x\n",oldcrc,crc,oldcrc_cw2,crc_cw2); fprintf(fdavx2b,"oldcrc %x, crc %x, oldcrc_cw2 %x, crc_cw2 %x\n",oldcrc,crc,oldcrc_cw2,crc_cw2); #endif if (crc == oldcrc && crc_cw2 == oldcrc_cw2) { return(iteration_cnt); } } // do log_map from first parity bit if (iteration_cnt < max_iterations) { log_map16avx2(systematic1,yparity1,m11,m10,alpha,beta,ext,n,0,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats); __m256i* ext_128=(__m256i*) ext; __m256i* s1_128=(__m256i*) systematic1; __m256i* s0_128=(__m256i*) systematic0; int myloop=n>>3; for (i=0; i