diff --git a/Algorithms/CRC32.cpp b/Algorithms/CRC32.cpp new file mode 100644 index 000000000..5d1971d18 --- /dev/null +++ b/Algorithms/CRC32.cpp @@ -0,0 +1,89 @@ +/* + 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 crc) { + boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_Processor; + CRC32_Processor.process_bytes( str, 100000000); + 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) { + return &CRC32::SSEBasedCRC32; //crc32 hardware accelarated; + } else { + 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; +} + + +CRC32::~CRC32() { + // TODO Auto-generated destructor stub +} + diff --git a/Algorithms/CRC32.h b/Algorithms/CRC32.h new file mode 100644 index 000000000..32b72f838 --- /dev/null +++ b/Algorithms/CRC32.h @@ -0,0 +1,45 @@ +/* + 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. + */ + +#ifndef CRC32_H_ +#define CRC32_H_ + +#include // for boost::crc_32_type + +class CRC32 { +private: + unsigned crc; + unsigned slowcrc_table[1<<8]; + + typedef boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> my_crc_32_type; + typedef unsigned (CRC32::*CRC32CFunctionPtr)(char *str, unsigned len, unsigned crc); + + unsigned SoftwareBasedCRC32(char *str, unsigned len, unsigned crc); + unsigned SSEBasedCRC32( char *str, unsigned len, unsigned crc); + unsigned cpuid(unsigned functionInput); + CRC32CFunctionPtr detectBestCRC32C(); + CRC32CFunctionPtr crcFunction; +public: + CRC32(); + unsigned operator()(char *str, unsigned len); + virtual ~CRC32(); +}; + +#endif /* CRC32_H_ */