86 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  open source routing machine
 | |
|  Copyright (C) Dennis Luxen, others 2010
 | |
| 
 | |
|  This program is free software; you can redistribute it and/or modify
 | |
|  it under the terms of the GNU AFFERO General Public License as published by
 | |
|  the Free Software Foundation; either version 3 of the License, or
 | |
|  any later version.
 | |
| 
 | |
|  This program is distributed in the hope that it will be useful,
 | |
|  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  GNU General Public License for more details.
 | |
| 
 | |
|  You should have received a copy of the GNU Affero General Public License
 | |
|  along with this program; if not, write to the Free Software
 | |
|  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
|  or see http://www.gnu.org/licenses/agpl.txt.
 | |
|  */
 | |
| 
 | |
| #include "CRC32.h"
 | |
| 
 | |
| CRC32::CRC32() : crc(0) {
 | |
|     crcFunction = detectBestCRC32C();
 | |
| }
 | |
| 
 | |
| unsigned CRC32::SoftwareBasedCRC32(char *str, unsigned len, unsigned ) {
 | |
|     boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_Processor;
 | |
|     CRC32_Processor.process_bytes( str, len);
 | |
|     return CRC32_Processor.checksum();
 | |
| }
 | |
| 
 | |
| unsigned CRC32::SSEBasedCRC32( char *str, unsigned len, unsigned crc) {
 | |
|     unsigned q=len/sizeof(unsigned),
 | |
|             r=len%sizeof(unsigned),
 | |
|             *p=(unsigned*)str/*, crc*/;
 | |
| 
 | |
|     //crc=0;
 | |
|     while (q--) {
 | |
|         __asm__ __volatile__(
 | |
|                 ".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
 | |
|                 :"=S"(crc)
 | |
|                  :"0"(crc), "c"(*p)
 | |
|         );
 | |
|         ++p;
 | |
|     }
 | |
| 
 | |
|     str=(char*)p;
 | |
|     while (r--) {
 | |
|         __asm__ __volatile__(
 | |
|                 ".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
 | |
|                 :"=S"(crc)
 | |
|                  :"0"(crc), "c"(*str)
 | |
|         );
 | |
|         ++str;
 | |
|     }
 | |
|     return crc;
 | |
| }
 | |
| 
 | |
| CRC32::CRC32CFunctionPtr CRC32::detectBestCRC32C() {
 | |
|     static const int SSE42_BIT = 20;
 | |
|     unsigned ecx = cpuid(1);
 | |
|     bool hasSSE42 = ecx & (1 << SSE42_BIT);
 | |
|     if (hasSSE42) {
 | |
|         SimpleLogger().Write() << "using hardware base sse computation";
 | |
|         return &CRC32::SSEBasedCRC32; //crc32 hardware accelarated;
 | |
|     } else {
 | |
|         SimpleLogger().Write() << "using software base sse computation";
 | |
|         return &CRC32::SoftwareBasedCRC32; //crc32cSlicingBy8;
 | |
|     }
 | |
| }
 | |
| 
 | |
| unsigned CRC32::cpuid(unsigned functionInput) {
 | |
|     unsigned eax;
 | |
|     unsigned ebx;
 | |
|     unsigned ecx;
 | |
|     unsigned edx;
 | |
|     asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (functionInput));
 | |
|     return ecx;
 | |
| }
 | |
| 
 | |
| unsigned CRC32::operator()(char *str, unsigned len){
 | |
|     crc =((*this).*(crcFunction))(str, len, crc);
 | |
|     return crc;
 | |
| }
 |