|
SASC-NG
DVBSoftCAM
|
00001 /* FFdecsa -- fast decsa algorithm 00002 * 00003 * Copyright (C) 2003-2004 fatih89r 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00020 00021 #include <mmintrin.h> 00022 00023 #define MEMALIGN_VAL 16 00024 00025 struct group_t{ 00026 __m64 s1,s2; 00027 }; 00028 typedef struct group_t group; 00029 00030 #define GROUP_PARALLELISM 128 00031 00032 group static inline FF0(){ 00033 group res; 00034 res.s1=(__m64)0x0ULL; 00035 res.s2=(__m64)0x0ULL; 00036 return res; 00037 } 00038 00039 group static inline FF1(){ 00040 group res; 00041 res.s1=(__m64)0xffffffffffffffffULL; 00042 res.s2=(__m64)0xffffffffffffffffULL; 00043 return res; 00044 } 00045 00046 group static inline FFAND(group a,group b){ 00047 group res; 00048 res.s1=_m_pand(a.s1,b.s1); 00049 res.s2=_m_pand(a.s2,b.s2); 00050 return res; 00051 } 00052 00053 group static inline FFOR(group a,group b){ 00054 group res; 00055 res.s1=_m_por(a.s1,b.s1); 00056 res.s2=_m_por(a.s2,b.s2); 00057 return res; 00058 } 00059 00060 group static inline FFXOR(group a,group b){ 00061 group res; 00062 res.s1=_m_pxor(a.s1,b.s1); 00063 res.s2=_m_pxor(a.s2,b.s2); 00064 return res; 00065 } 00066 00067 group static inline FFNOT(group a){ 00068 group res; 00069 res.s1=_m_pxor(a.s1,FF1().s1); 00070 res.s2=_m_pxor(a.s2,FF1().s2); 00071 return res; 00072 } 00073 00074 00075 /* 64 rows of 128 bits */ 00076 00077 void static inline FFTABLEIN(unsigned char *tab, int g, unsigned char *data){ 00078 *(((int *)tab)+2*g)=*((int *)data); 00079 *(((int *)tab)+2*g+1)=*(((int *)data)+1); 00080 } 00081 00082 void static inline FFTABLEOUT(unsigned char *data, unsigned char *tab, int g){ 00083 *((int *)data)=*(((int *)tab)+2*g); 00084 *(((int *)data)+1)=*(((int *)tab)+2*g+1); 00085 } 00086 00087 void static inline FFTABLEOUTXORNBY(int n, unsigned char *data, unsigned char *tab, int g){ 00088 int j; 00089 for(j=0;j<n;j++){ 00090 *(data+j)^=*(tab+8*g+j); 00091 } 00092 } 00093 00094 00095 struct batch_t{ 00096 __m64 s1,s2; 00097 }; 00098 typedef struct batch_t batch; 00099 00100 #define BYTES_PER_BATCH 16 00101 00102 batch static inline B_FFAND(batch a,batch b){ 00103 batch res; 00104 res.s1=_m_pand(a.s1,b.s1); 00105 res.s2=_m_pand(a.s2,b.s2); 00106 return res; 00107 } 00108 00109 batch static inline B_FFOR(batch a,batch b){ 00110 batch res; 00111 res.s1=_m_por(a.s1,b.s1); 00112 res.s2=_m_por(a.s2,b.s2); 00113 return res; 00114 } 00115 00116 batch static inline B_FFXOR(batch a,batch b){ 00117 batch res; 00118 res.s1=_m_pxor(a.s1,b.s1); 00119 res.s2=_m_pxor(a.s2,b.s2); 00120 return res; 00121 } 00122 00123 batch static inline B_FFN_ALL_29(){ 00124 batch res; 00125 res.s1=(__m64)0x2929292929292929ULL; 00126 res.s2=(__m64)0x2929292929292929ULL; 00127 return res; 00128 } 00129 batch static inline B_FFN_ALL_02(){ 00130 batch res; 00131 res.s1=(__m64)0x0202020202020202ULL; 00132 res.s2=(__m64)0x0202020202020202ULL; 00133 return res; 00134 } 00135 batch static inline B_FFN_ALL_04(){ 00136 batch res; 00137 res.s1=(__m64)0x0404040404040404ULL; 00138 res.s2=(__m64)0x0404040404040404ULL; 00139 return res; 00140 } 00141 batch static inline B_FFN_ALL_10(){ 00142 batch res; 00143 res.s1=(__m64)0x1010101010101010ULL; 00144 res.s2=(__m64)0x1010101010101010ULL; 00145 return res; 00146 } 00147 batch static inline B_FFN_ALL_40(){ 00148 batch res; 00149 res.s1=(__m64)0x4040404040404040ULL; 00150 res.s2=(__m64)0x4040404040404040ULL; 00151 return res; 00152 } 00153 batch static inline B_FFN_ALL_80(){ 00154 batch res; 00155 res.s1=(__m64)0x8080808080808080ULL; 00156 res.s2=(__m64)0x8080808080808080ULL; 00157 return res; 00158 } 00159 00160 batch static inline B_FFSH8L(batch a,int n){ 00161 batch res; 00162 res.s1=_m_psllqi(a.s1,n); 00163 res.s2=_m_psllqi(a.s2,n); 00164 return res; 00165 } 00166 00167 batch static inline B_FFSH8R(batch a,int n){ 00168 batch res; 00169 res.s1=_m_psrlqi(a.s1,n); 00170 res.s2=_m_psrlqi(a.s2,n); 00171 return res; 00172 } 00173 00174 void static inline M_EMPTY(void){ 00175 _m_empty(); 00176 } 00177 00178 00179 #undef XOR_8_BY 00180 #define XOR_8_BY(d,s1,s2) do{ __m64 *pd=(__m64 *)(d), *ps1=(__m64 *)(s1), *ps2=(__m64 *)(s2); \ 00181 *pd = _m_pxor( *ps1 , *ps2 ); }while(0) 00182 00183 #undef XOREQ_8_BY 00184 #define XOREQ_8_BY(d,s) do{ __m64 *pd=(__m64 *)(d), *ps=(__m64 *)(s); \ 00185 *pd = _m_pxor( *ps, *pd ); }while(0) 00186 00187 #undef COPY_8_BY 00188 #define COPY_8_BY(d,s) do{ __m64 *pd=(__m64 *)(d), *ps=(__m64 *)(s); \ 00189 *pd = *ps; }while(0) 00190 00191 #undef BEST_SPAN 00192 #define BEST_SPAN 8 00193 00194 #undef XOR_BEST_BY 00195 #define XOR_BEST_BY(d,s1,s2) do{ XOR_8_BY(d,s1,s2); }while(0); 00196 00197 #undef XOREQ_BEST_BY 00198 #define XOREQ_BEST_BY(d,s) do{ XOREQ_8_BY(d,s); }while(0); 00199 00200 #undef COPY_BEST_BY 00201 #define COPY_BEST_BY(d,s) do{ COPY_8_BY(d,s); }while(0);