1 /* K=7 r=1/2 Viterbi decoder for SSE 2 * Feb 2004, Phil Karn, KA9Q 3 */ 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <memory.h> 7 #include <xmmintrin.h> 8 #include "fec.h" 9 10 typedef union { unsigned char c[64]; } metric_t; 11 typedef union { unsigned long w[2]; unsigned char c[8]; __m64 v[1];} decision_t; 12 union branchtab27 { unsigned char c[32]; __m64 v[4];} Branchtab27_sse[2]; 13 static int Init = 0; 14 15 /* State info for instance of Viterbi decoder 16 * Don't change this without also changing references in ssebfly27.s! 17 */ 18 struct v27 { 19 metric_t metrics1; /* path metric buffer 1 */ 20 metric_t metrics2; /* path metric buffer 2 */ 21 decision_t *dp; /* Pointer to current decision */ 22 metric_t *old_metrics,*new_metrics; /* Pointers to path metrics, swapped on every bit */ 23 decision_t *decisions; /* Beginning of decisions for block */ 24 }; 25 26 /* Create a new instance of a Viterbi decoder */ 27 void *create_viterbi27_sse(int len){ 28 struct v27 *vp; 29 30 if(!Init){ 31 int polys[2] = { V27POLYA, V27POLYB }; 32 33 set_viterbi27_polynomial_sse(polys); 34 } 35 if((vp = malloc(sizeof(struct v27))) == NULL) 36 return NULL; 37 if((vp->decisions = malloc((len+6)*sizeof(decision_t))) == NULL){ 38 free(vp); 39 return NULL; 40 } 41 init_viterbi27(vp,0); 42 return vp; 43 } 44 45 void set_viterbi27_polynomial_sse(int polys[2]){ 46 int state; 47 48 for(state=0;state < 32;state++){ 49 Branchtab27_sse[0].c[state] = (polys[0] < 0) ^ parity((2*state) & abs(polys[0])) ? 255 : 0; 50 Branchtab27_sse[1].c[state] = (polys[1] < 0) ^ parity((2*state) & abs(polys[1])) ? 255 : 0; 51 } 52 Init++; 53 } 54 55 /* Initialize Viterbi decoder for start of new frame */ 56 int init_viterbi27_sse(void *p,int starting_state){ 57 struct v27 *vp = p; 58 int i; 59 60 if(p == NULL) 61 return -1; 62 for(i=0;i<64;i++) 63 vp->metrics1.c[i] = 63; 64 65 vp->old_metrics = &vp->metrics1; 66 vp->new_metrics = &vp->metrics2; 67 vp->dp = vp->decisions; 68 vp->old_metrics->c[starting_state & 63] = 0; /* Bias known start state */ 69 return 0; 70 } 71 72 /* Viterbi chainback */ 73 int chainback_viterbi27_sse( 74 void *p, 75 unsigned char *data, /* Decoded output data */ 76 unsigned int nbits, /* Number of data bits */ 77 unsigned int endstate){ /* Terminal encoder state */ 78 struct v27 *vp = p; 79 decision_t *d; 80 81 if(p == NULL) 82 return -1; 83 84 d = vp->decisions; 85 /* Make room beyond the end of the encoder register so we can 86 * accumulate a full byte of decoded data 87 */ 88 endstate %= 64; 89 endstate <<= 2; 90 91 /* The store into data[] only needs to be done every 8 bits. 92 * But this avoids a conditional branch, and the writes will 93 * combine in the cache anyway 94 */ 95 d += 6; /* Look past tail */ 96 while(nbits-- != 0){ 97 int k; 98 99 k = (d[nbits].c[(endstate>>2)/8] >> ((endstate>>2)%8)) & 1; 100 data[nbits>>3] = endstate = (endstate >> 1) | (k << 7); 101 } 102 return 0; 103 } 104 105 /* Delete instance of a Viterbi decoder */ 106 void delete_viterbi27_sse(void *p){ 107 struct v27 *vp = p; 108 109 if(vp != NULL){ 110 free(vp->decisions); 111 free(vp); 112 } 113 } 114