1 /* Fast Reed-Solomon encoder for (255,223) CCSDS code on PowerPC G4/G5 using Altivec instructions 2 * Copyright 2004, Phil Karn KA9Q 3 * May be used under the terms of the GNU Lesser General Public License (LGPL) 4 */ 5 #include <stdio.h> 6 #include <string.h> 7 #include "fixed.h" 8 9 /* Lookup table for feedback multiplications 10 * These are the low half of the coefficients. Since the generator polynomial is 11 * palindromic, we form it by reversing these on the fly 12 */ 13 static union { vector unsigned char v; unsigned char c[16]; } table[256]; 14 15 static vector unsigned char reverse = (vector unsigned char)(0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1); 16 static vector unsigned char shift_right = (vector unsigned char)(15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30); 17 18 extern data_t CCSDS_alpha_to[]; 19 extern data_t CCSDS_index_of[]; 20 extern data_t CCSDS_poly[]; 21 22 void rs_init_av(){ 23 int i,j; 24 25 /* The PowerPC is big-endian, so the low-order byte of each vector contains the highest order term in the polynomial */ 26 for(j=0;j<16;j++){ 27 table[0].c[j] = 0; 28 for(i=1;i<256;i++){ 29 table[i].c[16-j-1] = CCSDS_alpha_to[MODNN(CCSDS_poly[j+1] + CCSDS_index_of[i])]; 30 } 31 } 32 #if 0 33 for(i=0;i<256;i++){ 34 printf("table[%3d] = %3vu\n",i,table[i].v); 35 } 36 #endif 37 } 38 39 void encode_rs_av(unsigned char *data,unsigned char *parity,int pad){ 40 union { vector unsigned char v[2]; unsigned char c[32]; } shift_register; 41 int i; 42 43 shift_register.v[0] = (vector unsigned char)(0); 44 shift_register.v[1] = (vector unsigned char)(0); 45 46 for(i=0;i<NN-NROOTS-pad;i++){ 47 vector unsigned char feedback0,feedback1; 48 unsigned char f; 49 50 f = data[i] ^ shift_register.c[31]; 51 feedback1 = table[f].v; 52 feedback0 = vec_perm(feedback1,feedback1,reverse); 53 54 /* Shift right one byte */ 55 shift_register.v[1] = vec_perm(shift_register.v[0],shift_register.v[1],shift_right) ^ feedback1; 56 shift_register.v[0] = vec_sro(shift_register.v[0],(vector unsigned char)(8)) ^ feedback0; 57 shift_register.c[0] = f; 58 } 59 for(i=0;i<NROOTS;i++) 60 parity[NROOTS-i-1] = shift_register.c[i]; 61 } 62