14e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* K=15 r=1/6 Viterbi decoder with optional Intel or PowerPC SIMD
24e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * Copyright Feb 2004, 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_viterbi615(int len){
114e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
124e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  find_cpu_mode();
134e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
144e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  switch(Cpu_mode){
154e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case PORT:
164e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  default:
174e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    return create_viterbi615_port(len);
184e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
194e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case ALTIVEC:
204e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    return create_viterbi615_av(len);
214e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
224e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
234e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case MMX:
244e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    return create_viterbi615_mmx(len);
254e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case SSE:
264e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    return create_viterbi615_sse(len);
274e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case SSE2:
284e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    return create_viterbi615_sse2(len);
294e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
304e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  }
314e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
324e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
334e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid set_viterbi615_polynomial(int polys[6]){
344e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
354e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  switch(Cpu_mode){
364e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case PORT:
374e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  default:
384e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    set_viterbi615_polynomial_port(polys);
394e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    break;
404e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
414e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case ALTIVEC:
424e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    set_viterbi615_polynomial_av(polys);
434e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    break;
444e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
454e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
464e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case MMX:
474e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    set_viterbi615_polynomial_mmx(polys);
484e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    break;
494e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case SSE:
504e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    set_viterbi615_polynomial_sse(polys);
514e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    break;
524e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  case SSE2:
534e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    set_viterbi615_polynomial_sse2(polys);
544e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    break;
554e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
564e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi  }
574e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
584e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
594e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Initialize Viterbi decoder for start of new frame */
604e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint init_viterbi615(void *p,int starting_state){
614e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    switch(Cpu_mode){
624e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case PORT:
634e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    default:
644e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return init_viterbi615_port(p,starting_state);
654e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
664e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case ALTIVEC:
674e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return init_viterbi615_av(p,starting_state);
684e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
694e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
704e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case MMX:
714e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return init_viterbi615_mmx(p,starting_state);
724e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE:
734e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return init_viterbi615_sse(p,starting_state);
744e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE2:
754e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return init_viterbi615_sse2(p,starting_state);
764e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
774e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    }
784e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
794e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
804e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Viterbi chainback */
814e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint chainback_viterbi615(
824e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      void *p,
834e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      unsigned char *data, /* Decoded output data */
844e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      unsigned int nbits, /* Number of data bits */
854e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      unsigned int endstate){ /* Terminal encoder state */
864e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
874e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    switch(Cpu_mode){
884e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case PORT:
894e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    default:
904e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return chainback_viterbi615_port(p,data,nbits,endstate);
914e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
924e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case ALTIVEC:
934e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return chainback_viterbi615_av(p,data,nbits,endstate);
944e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
954e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
964e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case MMX:
974e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return chainback_viterbi615_mmx(p,data,nbits,endstate);
984e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE:
994e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return chainback_viterbi615_sse(p,data,nbits,endstate);
1004e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE2:
1014e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return chainback_viterbi615_sse2(p,data,nbits,endstate);
1024e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
1034e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    }
1044e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
1054e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
1064e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Delete instance of a Viterbi decoder */
1074e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid delete_viterbi615(void *p){
1084e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    switch(Cpu_mode){
1094e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case PORT:
1104e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    default:
1114e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      delete_viterbi615_port(p);
1124e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      break;
1134e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
1144e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case ALTIVEC:
1154e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      delete_viterbi615_av(p);
1164e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      break;
1174e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
1184e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
1194e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case MMX:
1204e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      delete_viterbi615_mmx(p);
1214e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      break;
1224e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE:
1234e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      delete_viterbi615_sse(p);
1244e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      break;
1254e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE2:
1264e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      delete_viterbi615_sse2(p);
1274e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      break;
1284e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
1294e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    }
1304e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
1314e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
1324e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Update decoder with a block of demodulated symbols
1334e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * Note that nbits is the number of decoded data bits, not the number
1344e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * of symbols!
1354e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi */
1364e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint update_viterbi615_blk(void *p,unsigned char syms[],int nbits){
1374e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    switch(Cpu_mode){
1384e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case PORT:
1394e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    default:
1404e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return update_viterbi615_blk_port(p,syms,nbits);
1414e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__
1424e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case ALTIVEC:
1434e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return update_viterbi615_blk_av(p,syms,nbits);
1444e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
1454e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__
1464e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case MMX:
1474e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return update_viterbi615_blk_mmx(p,syms,nbits);
1484e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE:
1494e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return update_viterbi615_blk_sse(p,syms,nbits);
1504e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    case SSE2:
1514e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi      return update_viterbi615_blk_sse2(p,syms,nbits);
1524e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif
1534e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi    }
1544e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi}
1554e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi
156