1/* K=15 r=1/6 Viterbi decoder with optional Intel or PowerPC SIMD
2 * Copyright Feb 2004, Phil Karn, KA9Q
3 */
4#include <stdio.h>
5#include <stdlib.h>
6#include <memory.h>
7#include "fec.h"
8
9/* Create a new instance of a Viterbi decoder */
10void *create_viterbi615(int len){
11
12  find_cpu_mode();
13
14  switch(Cpu_mode){
15  case PORT:
16  default:
17    return create_viterbi615_port(len);
18#ifdef __VEC__
19  case ALTIVEC:
20    return create_viterbi615_av(len);
21#endif
22#ifdef __i386__
23  case MMX:
24    return create_viterbi615_mmx(len);
25  case SSE:
26    return create_viterbi615_sse(len);
27  case SSE2:
28    return create_viterbi615_sse2(len);
29#endif
30  }
31}
32
33void set_viterbi615_polynomial(int polys[6]){
34
35  switch(Cpu_mode){
36  case PORT:
37  default:
38    set_viterbi615_polynomial_port(polys);
39    break;
40#ifdef __VEC__
41  case ALTIVEC:
42    set_viterbi615_polynomial_av(polys);
43    break;
44#endif
45#ifdef __i386__
46  case MMX:
47    set_viterbi615_polynomial_mmx(polys);
48    break;
49  case SSE:
50    set_viterbi615_polynomial_sse(polys);
51    break;
52  case SSE2:
53    set_viterbi615_polynomial_sse2(polys);
54    break;
55#endif
56  }
57}
58
59/* Initialize Viterbi decoder for start of new frame */
60int init_viterbi615(void *p,int starting_state){
61    switch(Cpu_mode){
62    case PORT:
63    default:
64      return init_viterbi615_port(p,starting_state);
65#ifdef __VEC__
66    case ALTIVEC:
67      return init_viterbi615_av(p,starting_state);
68#endif
69#ifdef __i386__
70    case MMX:
71      return init_viterbi615_mmx(p,starting_state);
72    case SSE:
73      return init_viterbi615_sse(p,starting_state);
74    case SSE2:
75      return init_viterbi615_sse2(p,starting_state);
76#endif
77    }
78}
79
80/* Viterbi chainback */
81int chainback_viterbi615(
82      void *p,
83      unsigned char *data, /* Decoded output data */
84      unsigned int nbits, /* Number of data bits */
85      unsigned int endstate){ /* Terminal encoder state */
86
87    switch(Cpu_mode){
88    case PORT:
89    default:
90      return chainback_viterbi615_port(p,data,nbits,endstate);
91#ifdef __VEC__
92    case ALTIVEC:
93      return chainback_viterbi615_av(p,data,nbits,endstate);
94#endif
95#ifdef __i386__
96    case MMX:
97      return chainback_viterbi615_mmx(p,data,nbits,endstate);
98    case SSE:
99      return chainback_viterbi615_sse(p,data,nbits,endstate);
100    case SSE2:
101      return chainback_viterbi615_sse2(p,data,nbits,endstate);
102#endif
103    }
104}
105
106/* Delete instance of a Viterbi decoder */
107void delete_viterbi615(void *p){
108    switch(Cpu_mode){
109    case PORT:
110    default:
111      delete_viterbi615_port(p);
112      break;
113#ifdef __VEC__
114    case ALTIVEC:
115      delete_viterbi615_av(p);
116      break;
117#endif
118#ifdef __i386__
119    case MMX:
120      delete_viterbi615_mmx(p);
121      break;
122    case SSE:
123      delete_viterbi615_sse(p);
124      break;
125    case SSE2:
126      delete_viterbi615_sse2(p);
127      break;
128#endif
129    }
130}
131
132/* Update decoder with a block of demodulated symbols
133 * Note that nbits is the number of decoded data bits, not the number
134 * of symbols!
135 */
136int update_viterbi615_blk(void *p,unsigned char syms[],int nbits){
137    switch(Cpu_mode){
138    case PORT:
139    default:
140      return update_viterbi615_blk_port(p,syms,nbits);
141#ifdef __VEC__
142    case ALTIVEC:
143      return update_viterbi615_blk_av(p,syms,nbits);
144#endif
145#ifdef __i386__
146    case MMX:
147      return update_viterbi615_blk_mmx(p,syms,nbits);
148    case SSE:
149      return update_viterbi615_blk_sse(p,syms,nbits);
150    case SSE2:
151      return update_viterbi615_blk_sse2(p,syms,nbits);
152#endif
153    }
154}
155
156