//////////////////////////////////////////////////////////////////////////////// // / // 2012-2020 (c) Baical / // / // This library is free software; you can redistribute it and/or / // modify it under the terms of the GNU Lesser General Public / // License as published by the Free Software Foundation; either / // version 3.0 of the License, or (at your option) any later version. / // / // This library 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 / // Lesser General Public License for more details. / // / // You should have received a copy of the GNU Lesser General Public / // License along with this library. / // / //////////////////////////////////////////////////////////////////////////////// #ifndef PCRC32_H #define PCRC32_H //////////////////////////////////////////////////////////////////////////////// //Get_CRC32 //This function implement 2 calculation kinds: // * AT&T assembler for X86 architecture for GNU C compiler // * standard C function for all other cases like X64 or ARM //Assembler code if faster than generated by GCC (o2) up to 1% it is not a lot //but for big amount of data and often calculation is enough to use it. static UNUSED_FUNC tUINT32 Get_CRC32(tUINT8 *i_pData, size_t i_szCount) { tUINT32 l_dwResult = 0xFFFFFFFF; if ( (NULL == i_pData) || (0 >= i_szCount) ) { return l_dwResult; } #if defined(__i386__) && defined(__GNUC__) && !defined(__PIC__) // Register use: // eax - CRC32 value // ebx - a lot of things // ecx - CRC32 value // edx - address of end of buffer // esi - address of start of buffer // edi - CRC32 table __asm__("push %%esi;" // Save the esi and edi registers "push %%edi;" //"movl l_dwResult, %%ecx;" do it already by constraints //"movl g_ppCRC32_Table, %%edi;" "leal (%%esi,%%ebx),%%edx;" // Calculate the end of the buffer "crc32loop:;" "xorl %%eax, %%eax;" // Clear the eax register" "movb (%%esi), %%bl;" "movb %%cl, %%al;" // Copy crc value into eax "incl %%esi;" // Advance the source pointer "xorb %%bl, %%al;" // Create the index into the CRC32 table "shr $8, %%ecx;" "movl (%%edi, %%eax, 4), %%ebx;" // Get the value out of the table "xorl %%ebx, %%ecx;" // xor with the current byte "cmpl %%edx, %%esi;" // Have we reached the end of the buffer? "jne crc32loop;" "pop %%edi;" "pop %%esi;" //output :"=c"(l_dwResult) //input :"D"(g_ppCRC32_Table), "c"(l_dwResult), "S"(i_pData), "b"(i_szCount) ); #else for (size_t l_szI = 0; l_szI < i_szCount; l_szI ++) { l_dwResult = g_ppCRC32_Table[(l_dwResult ^ i_pData[l_szI]) & 0xFF ] ^ (l_dwResult >> 8); } /* Suppress warning that this is not used */ (void)g_ppCRC32_Table; #endif return l_dwResult; } #endif //PCRC32_H