14e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Switch to K=9 r=1/3 Viterbi decoder with optional Intel or PowerPC SIMD
24e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * Copyright Aug 2006, Phil Karn, KA9Q
34e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi */
44e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include <stdio.h>
54e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include <stdlib.h>
64e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include <memory.h>
74e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include "fec.h"
84e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
94e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Create a new instance of a Viterbi decoder */
104e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid *create_viterbi39(int len){
114e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  find_cpu_mode();
124e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
134e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  switch(Cpu_mode){
144e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case PORT:
154e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  default:
164e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    return create_viterbi39_port(len);
174e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
184e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case ALTIVEC:
194e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    return create_viterbi39_av(len);
204e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
214e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
224e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case MMX:
234e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    return create_viterbi39_mmx(len);
244e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case SSE:
254e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    return create_viterbi39_sse(len);
264e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case SSE2:
274e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    return create_viterbi39_sse2(len);
284e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
294e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  }
304e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
314e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
324e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid set_viterbi39_polynomial(int polys[3]){
334e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  switch(Cpu_mode){
344e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case PORT:
354e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  default:
364e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    set_viterbi39_polynomial_port(polys);
374e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    break;
384e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
394e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case ALTIVEC:
404e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    set_viterbi39_polynomial_av(polys);
414e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    break;
424e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
434e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
444e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case MMX:
454e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    set_viterbi39_polynomial_mmx(polys);
464e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    break;
474e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case SSE:
484e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    set_viterbi39_polynomial_sse(polys);
494e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    break;
504e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case SSE2:
514e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    set_viterbi39_polynomial_sse2(polys);
524e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    break;
534e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
544e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  }
554e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
564e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
574e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
584e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Initialize Viterbi decoder for start of new frame */
594e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint init_viterbi39(void *p,int starting_state){
604e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    switch(Cpu_mode){
614e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case PORT:
624e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    default:
634e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return init_viterbi39_port(p,starting_state);
644e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
654e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case ALTIVEC:
664e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return init_viterbi39_av(p,starting_state);
674e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
684e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
694e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case MMX:
704e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return init_viterbi39_mmx(p,starting_state);
714e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE:
724e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return init_viterbi39_sse(p,starting_state);
734e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE2:
744e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return init_viterbi39_sse2(p,starting_state);
754e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
764e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    }
774e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
784e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
794e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Viterbi chainback */
804e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint chainback_viterbi39(
814e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      void *p,
824e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      unsigned char *data, /* Decoded output data */
834e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      unsigned int nbits, /* Number of data bits */
844e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      unsigned int endstate){ /* Terminal encoder state */
854e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
864e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    switch(Cpu_mode){
874e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case PORT:
884e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    default:
894e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return chainback_viterbi39_port(p,data,nbits,endstate);
904e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
914e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case ALTIVEC:
924e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return chainback_viterbi39_av(p,data,nbits,endstate);
934e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
944e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
954e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case MMX:
964e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return chainback_viterbi39_mmx(p,data,nbits,endstate);
974e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE:
984e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return chainback_viterbi39_sse(p,data,nbits,endstate);
994e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE2:
1004e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return chainback_viterbi39_sse2(p,data,nbits,endstate);
1014e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
1024e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    }
1034e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
1044e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
1054e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Delete instance of a Viterbi decoder */
1064e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid delete_viterbi39(void *p){
1074e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    switch(Cpu_mode){
1084e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case PORT:
1094e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    default:
1104e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      delete_viterbi39_port(p);
1114e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      break;
1124e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
1134e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case ALTIVEC:
1144e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      delete_viterbi39_av(p);
1154e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      break;
1164e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
1174e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
1184e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case MMX:
1194e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      delete_viterbi39_mmx(p);
1204e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      break;
1214e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE:
1224e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      delete_viterbi39_sse(p);
1234e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      break;
1244e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE2:
1254e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      delete_viterbi39_sse2(p);
1264e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      break;
1274e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
1284e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    }
1294e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
1304e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
1314e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Update decoder with a block of demodulated symbols
1324e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * Note that nbits is the number of decoded data bits, not the number
1334e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * of symbols!
1344e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi */
1354e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint update_viterbi39_blk(void *p,unsigned char syms[],int nbits){
1364e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    switch(Cpu_mode){
1374e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case PORT:
1384e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    default:
1394e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return update_viterbi39_blk_port(p,syms,nbits);
1404e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
1414e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case ALTIVEC:
1424e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return update_viterbi39_blk_av(p,syms,nbits);
1434e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
1444e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
1454e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case MMX:
1464e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return update_viterbi39_blk_mmx(p,syms,nbits);
1474e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE:
1484e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return update_viterbi39_blk_sse(p,syms,nbits);
1494e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE2:
1504e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return update_viterbi39_blk_sse2(p,syms,nbits);
1514e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
1524e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    }
1534e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
154