encode_rs_8.c revision 4e213d510f437769f8a28578dd4f786fb7d16c4
14e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Reed-Solomon encoder 24e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * Copyright 2004, Phil Karn, KA9Q 34e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * May be used under the terms of the GNU Lesser General Public License (LGPL) 44e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi */ 54e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include <string.h> 64e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include "fixed.h" 74e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 84e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include <sys/sysctl.h> 94e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 104e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 114e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 124e213d510f437769f8a28578dd4f786fb7d16c4Bill Yistatic enum {UNKNOWN=0,MMX,SSE,SSE2,ALTIVEC,PORT} cpu_mode; 134e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 144e213d510f437769f8a28578dd4f786fb7d16c4Bill Yistatic void encode_rs_8_c(data_t *data, data_t *parity,int pad); 154e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#if __vec__ 164e213d510f437769f8a28578dd4f786fb7d16c4Bill Yistatic void encode_rs_8_av(data_t *data, data_t *parity,int pad); 174e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 184e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#if __i386__ 194e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint cpu_features(void); 204e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 214e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 224e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid encode_rs_8(data_t *data, data_t *parity,int pad){ 234e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi if(cpu_mode == UNKNOWN){ 244e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 254e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi int f; 264e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi /* Figure out what kind of CPU we have */ 274e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi f = cpu_features(); 284e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi if(f & (1<<26)){ /* SSE2 is present */ 294e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi cpu_mode = SSE2; 304e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } else if(f & (1<<25)){ /* SSE is present */ 314e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi cpu_mode = SSE; 324e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } else if(f & (1<<23)){ /* MMX is present */ 334e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi cpu_mode = MMX; 344e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } else { /* No SIMD at all */ 354e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi cpu_mode = PORT; 364e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 374e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#elif __VEC__ 384e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi /* Ask the OS if we have Altivec support */ 394e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi int selectors[2] = { CTL_HW, HW_VECTORUNIT }; 404e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi int hasVectorUnit = 0; 414e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi size_t length = sizeof(hasVectorUnit); 424e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0); 434e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi if(0 == error && hasVectorUnit) 444e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi cpu_mode = ALTIVEC; 454e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi else 464e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi cpu_mode = PORT; 474e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#else 484e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi cpu_mode = PORT; 494e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 504e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 514e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(cpu_mode){ 524e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#if __vec__ 534e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 544e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi encode_rs_8_av(data,parity,pad); 554e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return; 564e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 574e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#if __i386__ 584e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 594e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 604e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 614e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 624e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 634e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi encode_rs_8_c(data,parity,pad); 644e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return; 654e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 664e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 674e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 684e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#if __vec__ /* PowerPC G4/G5 Altivec instructions are available */ 694e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 704e213d510f437769f8a28578dd4f786fb7d16c4Bill Yistatic vector unsigned char reverse = (vector unsigned char)(0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1); 714e213d510f437769f8a28578dd4f786fb7d16c4Bill Yistatic vector unsigned char shift_right = (vector unsigned char)(15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30); 724e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 734e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Lookup table for feedback multiplications 744e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * These are the low half of the coefficients. Since the generator polynomial is 754e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * palindromic, we form the other half by reversing this one 764e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi */ 774e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiextern static union { vector unsigned char v; unsigned char c[16]; } table[256]; 784e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 794e213d510f437769f8a28578dd4f786fb7d16c4Bill Yistatic void encode_rs_8_av(data_t *data, data_t *parity,int pad){ 804e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi union { vector unsigned char v[2]; unsigned char c[32]; } shift_register; 814e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi int i; 824e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 834e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi shift_register.v[0] = (vector unsigned char)(0); 844e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi shift_register.v[1] = (vector unsigned char)(0); 854e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 864e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi for(i=0;i<NN-NROOTS-pad;i++){ 874e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi vector unsigned char feedback0,feedback1; 884e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi unsigned char f; 894e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 904e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi f = data[i] ^ shift_register.c[31]; 914e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi feedback1 = table[f].v; 924e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi feedback0 = vec_perm(feedback1,feedback1,reverse); 934e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 944e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi /* Shift right one byte */ 954e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi shift_register.v[1] = vec_perm(shift_register.v[0],shift_register.v[1],shift_right) ^ feedback1; 964e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi shift_register.v[0] = vec_sro(shift_register.v[0],(vector unsigned char)(8)) ^ feedback0; 974e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi shift_register.c[0] = f; 984e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 994e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi for(i=0;i<NROOTS;i++) 1004e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi parity[NROOTS-i-1] = shift_register.c[i]; 1014e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 1024e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1034e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 1044e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Portable C version */ 1054e213d510f437769f8a28578dd4f786fb7d16c4Bill Yistatic void encode_rs_8_c(data_t *data, data_t *parity,int pad){ 1064e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 1074e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include "encode_rs.h" 1084e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 1094e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 110