Commit 9c2215e0 authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-9872 - Add common optimized CRC32 function interface

Move crc32-vpmsum to extra.
Compile static crc32-vpmsum instead of adding sources directly.
Make use of crc32-vpmsum via my_checksum().

Based on contribution by Daniel Black.
parent 86975e04
...@@ -153,6 +153,7 @@ INCLUDE(plugin) ...@@ -153,6 +153,7 @@ INCLUDE(plugin)
INCLUDE(install_macros) INCLUDE(install_macros)
INCLUDE(systemd) INCLUDE(systemd)
INCLUDE(mysql_add_executable) INCLUDE(mysql_add_executable)
INCLUDE(crc32-vpmsum)
# Handle options # Handle options
OPTION(DISABLE_SHARED OPTION(DISABLE_SHARED
......
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le")
SET(HAVE_CRC32_VPMSUM 1)
SET(CRC32_VPMSUM_LIBRARY crc32-vpmsum)
ADD_SUBDIRECTORY(extra/crc32-vpmsum)
ENDIF()
...@@ -105,6 +105,8 @@ ...@@ -105,6 +105,8 @@
/* Libraries */ /* Libraries */
#cmakedefine HAVE_LIBWRAP 1 #cmakedefine HAVE_LIBWRAP 1
#cmakedefine HAVE_SYSTEMD 1 #cmakedefine HAVE_SYSTEMD 1
#cmakedefine HAVE_CRC32_VPMSUM 1
/* Does "struct timespec" have a "sec" and "nsec" field? */ /* Does "struct timespec" have a "sec" and "nsec" field? */
#cmakedefine HAVE_TIMESPEC_TS_SEC 1 #cmakedefine HAVE_TIMESPEC_TS_SEC 1
......
...@@ -80,13 +80,6 @@ IF(WITH_INNOBASE_STORAGE_ENGINE OR WITH_XTRADB_STORAGE_ENGINE) ...@@ -80,13 +80,6 @@ IF(WITH_INNOBASE_STORAGE_ENGINE OR WITH_XTRADB_STORAGE_ENGINE)
../storage/innobase/page/page0zip.cc ../storage/innobase/page/page0zip.cc
) )
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le")
enable_language(ASM)
LIST(APPEND INNOBASE_SOURCES
../storage/innobase/ut/crc32_power8/crc32.S
../storage/innobase/ut/crc32_power8/crc32_wrapper.c
)
ENDIF()
MYSQL_ADD_EXECUTABLE(innochecksum innochecksum.cc ${INNOBASE_SOURCES}) MYSQL_ADD_EXECUTABLE(innochecksum innochecksum.cc ${INNOBASE_SOURCES})
TARGET_LINK_LIBRARIES(innochecksum mysys mysys_ssl) TARGET_LINK_LIBRARIES(innochecksum mysys mysys_ssl)
......
ENABLE_LANGUAGE(ASM)
ADD_CONVENIENCE_LIBRARY(${CRC32_VPMSUM_LIBRARY} crc32.S crc32_wrapper.c)
...@@ -444,7 +444,7 @@ ADD_CONVENIENCE_LIBRARY(clientlib ${CLIENT_SOURCES}) ...@@ -444,7 +444,7 @@ ADD_CONVENIENCE_LIBRARY(clientlib ${CLIENT_SOURCES})
DTRACE_INSTRUMENT(clientlib) DTRACE_INSTRUMENT(clientlib)
ADD_DEPENDENCIES(clientlib GenError) ADD_DEPENDENCIES(clientlib GenError)
SET(LIBS clientlib dbug strings vio mysys mysys_ssl ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL}) SET(LIBS clientlib dbug strings vio mysys mysys_ssl ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL} ${CRC32_VPMSUM_LIBRARY})
# Merge several convenience libraries into one big mysqlclient # Merge several convenience libraries into one big mysqlclient
# and link them together into shared library. # and link them together into shared library.
......
...@@ -71,7 +71,7 @@ ENDIF() ...@@ -71,7 +71,7 @@ ENDIF()
ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES}) ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES})
TARGET_LINK_LIBRARIES(mysys dbug strings mysys_ssl ${ZLIB_LIBRARY} TARGET_LINK_LIBRARIES(mysys dbug strings mysys_ssl ${ZLIB_LIBRARY}
${LIBNSL} ${LIBM} ${LIBRT} ${LIBDL} ${LIBSOCKET} ${LIBEXECINFO}) ${LIBNSL} ${LIBM} ${LIBRT} ${LIBDL} ${LIBSOCKET} ${LIBEXECINFO} ${CRC32_VPMSUM_LIBRARY})
DTRACE_INSTRUMENT(mysys) DTRACE_INSTRUMENT(mysys)
IF(HAVE_BFD_H) IF(HAVE_BFD_H)
......
...@@ -30,7 +30,13 @@ ...@@ -30,7 +30,13 @@
ha_checksum my_checksum(ha_checksum crc, const uchar *pos, size_t length) ha_checksum my_checksum(ha_checksum crc, const uchar *pos, size_t length)
{ {
#ifdef HAVE_CRC32_VPMSUM
extern unsigned int crc32_vpmsum(unsigned int crc, const unsigned char *p,
unsigned long len);
crc= (ha_checksum) crc32_vpmsum((uint) crc, pos, (uint) length);
#else
crc= (ha_checksum) crc32((uint)crc, pos, (uint) length); crc= (ha_checksum) crc32((uint)crc, pos, (uint) length);
#endif
DBUG_PRINT("info", ("crc: %lu", (ulong) crc)); DBUG_PRINT("info", ("crc: %lu", (ulong) crc));
return crc; return crc;
} }
/* Copyright (c) 2003, 2004 MySQL AB
Use is subject to license terms
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
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 General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
#include "mysys_priv.h"
#ifndef HAVE_COMPRESS
#undef DYNAMIC_CRC_TABLE
#include "../zlib/crc32.c"
#endif
...@@ -491,14 +491,6 @@ SET(INNOBASE_SOURCES ...@@ -491,14 +491,6 @@ SET(INNOBASE_SOURCES
ut/ut0wqueue.cc ut/ut0wqueue.cc
ut/ut0timer.cc) ut/ut0timer.cc)
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le")
enable_language(ASM)
LIST(APPEND INNOBASE_SOURCES
ut/crc32_power8/crc32.S
ut/crc32_power8/crc32_wrapper.c
)
ENDIF()
IF(WITH_INNODB) IF(WITH_INNODB)
# Legacy option # Legacy option
SET(WITH_INNOBASE_STORAGE_ENGINE TRUE) SET(WITH_INNOBASE_STORAGE_ENGINE TRUE)
...@@ -517,5 +509,5 @@ ENDIF() ...@@ -517,5 +509,5 @@ ENDIF()
MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE
MODULE_ONLY MODULE_ONLY
MODULE_OUTPUT_NAME ha_innodb MODULE_OUTPUT_NAME ha_innodb
LINK_LIBRARIES ${ZLIB_LIBRARY} ${LINKER_SCRIPT}) LINK_LIBRARIES ${ZLIB_LIBRARY} ${CRC32_VPMSUM_LIBRARY} ${LINKER_SCRIPT})
...@@ -104,6 +104,7 @@ UNIV_INTERN bool ut_crc32_power8_enabled = false; ...@@ -104,6 +104,7 @@ UNIV_INTERN bool ut_crc32_power8_enabled = false;
/********************************************************************//** /********************************************************************//**
Initializes the table that is used to generate the CRC32 if the CPU does Initializes the table that is used to generate the CRC32 if the CPU does
not have support for it. */ not have support for it. */
#ifndef HAVE_CRC32_VPMSUM
static static
void void
ut_crc32_slice8_table_init() ut_crc32_slice8_table_init()
...@@ -133,6 +134,7 @@ ut_crc32_slice8_table_init() ...@@ -133,6 +134,7 @@ ut_crc32_slice8_table_init()
ut_crc32_slice8_table_initialized = TRUE; ut_crc32_slice8_table_initialized = TRUE;
} }
#endif
#if defined(__GNUC__) && defined(__x86_64__) #if defined(__GNUC__) && defined(__x86_64__)
/********************************************************************//** /********************************************************************//**
...@@ -181,27 +183,22 @@ for RHEL4 support (GCC 3 doesn't support this instruction) */ ...@@ -181,27 +183,22 @@ for RHEL4 support (GCC 3 doesn't support this instruction) */
len -= 8, buf += 8 len -= 8, buf += 8
#endif /* defined(__GNUC__) && defined(__x86_64__) */ #endif /* defined(__GNUC__) && defined(__x86_64__) */
#if defined(__powerpc__)
#ifdef HAVE_CRC32_VPMSUM
extern "C" { extern "C" {
unsigned int crc32_vpmsum(unsigned int crc, const unsigned char *p, unsigned long len); unsigned int crc32_vpmsum(unsigned int crc, const unsigned char *p, unsigned long len);
}; };
#endif /* __powerpc__ */
UNIV_INLINE UNIV_INLINE
ib_uint32_t ib_uint32_t
ut_crc32_power8( ut_crc32_power8(
/*===========*/ /*===========*/
const byte* buf, /*!< in: data over which to calculate CRC32 */ const byte* buf, /*!< in: data over which to calculate CRC32 */
ulint len) /*!< in: data length */ ulint len) /*!< in: data length */
{ {
#if defined(__powerpc__) && !defined(WORDS_BIGENDIAN)
return crc32_vpmsum(0, buf, len); return crc32_vpmsum(0, buf, len);
#else
ut_error;
/* silence compiler warning about unused parameters */
return((ib_uint32_t) buf[len]);
#endif /* __powerpc__ */
} }
#endif
/********************************************************************//** /********************************************************************//**
Calculates CRC32 using CPU instructions. Calculates CRC32 using CPU instructions.
...@@ -338,18 +335,15 @@ ut_crc32_init() ...@@ -338,18 +335,15 @@ ut_crc32_init()
#endif /* defined(__GNUC__) && defined(__x86_64__) */ #endif /* defined(__GNUC__) && defined(__x86_64__) */
#if defined(__linux__) && defined(__powerpc__) && defined(AT_HWCAP2) \ #ifdef HAVE_CRC32_VPMSUM
&& !defined(WORDS_BIGENDIAN) ut_crc32_power8_enabled = true;
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) ut_crc32 = ut_crc32_power8;
ut_crc32_power8_enabled = true; #else
#endif /* defined(__linux__) && defined(__powerpc__) */
if (ut_crc32_sse2_enabled) { if (ut_crc32_sse2_enabled) {
ut_crc32 = ut_crc32_sse42; ut_crc32 = ut_crc32_sse42;
} else if (ut_crc32_power8_enabled) {
ut_crc32 = ut_crc32_power8;
} else { } else {
ut_crc32_slice8_table_init(); ut_crc32_slice8_table_init();
ut_crc32 = ut_crc32_slice8; ut_crc32 = ut_crc32_slice8;
} }
#endif
} }
...@@ -496,17 +496,9 @@ SET(INNOBASE_SOURCES ...@@ -496,17 +496,9 @@ SET(INNOBASE_SOURCES
ut/ut0wqueue.cc ut/ut0wqueue.cc
ut/ut0timer.cc) ut/ut0timer.cc)
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le")
enable_language(ASM)
LIST(APPEND INNOBASE_SOURCES
ut/crc32_power8/crc32.S
ut/crc32_power8/crc32_wrapper.c
)
ENDIF()
MYSQL_ADD_PLUGIN(xtradb ${INNOBASE_SOURCES} STORAGE_ENGINE MYSQL_ADD_PLUGIN(xtradb ${INNOBASE_SOURCES} STORAGE_ENGINE
DEFAULT RECOMPILE_FOR_EMBEDDED DEFAULT RECOMPILE_FOR_EMBEDDED
LINK_LIBRARIES ${ZLIB_LIBRARY} ${LINKER_SCRIPT}) LINK_LIBRARIES ${ZLIB_LIBRARY} ${CRC32_VPMSUM_LIBRARY} ${LINKER_SCRIPT})
IF(TARGET xtradb AND NOT XTRADB_OK) IF(TARGET xtradb AND NOT XTRADB_OK)
MESSAGE(FATAL_ERROR "Percona XtraDB is not supported on this platform") MESSAGE(FATAL_ERROR "Percona XtraDB is not supported on this platform")
......
This diff is collapsed.
This diff is collapsed.
#ifdef __powerpc__
#define CRC_TABLE
#include "crc32_constants.h"
#define VMX_ALIGN 16
#define VMX_ALIGN_MASK (VMX_ALIGN-1)
#ifdef REFLECT
static unsigned int crc32_align(unsigned int crc, unsigned char *p,
unsigned long len)
{
while (len--)
crc = crc_table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
return crc;
}
#else
static unsigned int crc32_align(unsigned int crc, unsigned char *p,
unsigned long len)
{
while (len--)
crc = crc_table[((crc >> 24) ^ *p++) & 0xff] ^ (crc << 8);
return crc;
}
#endif
unsigned int __crc32_vpmsum(unsigned int crc, unsigned char *p,
unsigned long len);
unsigned int crc32_vpmsum(unsigned int crc, unsigned char *p,
unsigned long len)
{
unsigned int prealign;
unsigned int tail;
#ifdef CRC_XOR
crc ^= 0xffffffff;
#endif
if (len < VMX_ALIGN + VMX_ALIGN_MASK) {
crc = crc32_align(crc, p, len);
goto out;
}
if ((unsigned long)p & VMX_ALIGN_MASK) {
prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK);
crc = crc32_align(crc, p, prealign);
len -= prealign;
p += prealign;
}
crc = __crc32_vpmsum(crc, p, len & ~VMX_ALIGN_MASK);
tail = len & VMX_ALIGN_MASK;
if (tail) {
p += len & ~VMX_ALIGN_MASK;
crc = crc32_align(crc, p, tail);
}
out:
#ifdef CRC_XOR
crc ^= 0xffffffff;
#endif
return crc;
}
#endif /* __powerpc__ */
#ifndef __OPCODES_H
#define __OPCODES_H
#define __PPC_RA(a) (((a) & 0x1f) << 16)
#define __PPC_RB(b) (((b) & 0x1f) << 11)
#define __PPC_XA(a) ((((a) & 0x1f) << 16) | (((a) & 0x20) >> 3))
#define __PPC_XB(b) ((((b) & 0x1f) << 11) | (((b) & 0x20) >> 4))
#define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5))
#define __PPC_XT(s) __PPC_XS(s)
#define VSX_XX3(t, a, b) (__PPC_XT(t) | __PPC_XA(a) | __PPC_XB(b))
#define VSX_XX1(s, a, b) (__PPC_XS(s) | __PPC_RA(a) | __PPC_RB(b))
#define PPC_INST_VPMSUMW 0x10000488
#define PPC_INST_VPMSUMD 0x100004c8
#define PPC_INST_MFVSRD 0x7c000066
#define PPC_INST_MTVSRD 0x7c000166
#define VPMSUMW(t, a, b) .long PPC_INST_VPMSUMW | VSX_XX3((t), a, b)
#define VPMSUMD(t, a, b) .long PPC_INST_VPMSUMD | VSX_XX3((t), a, b)
#define MFVRD(a, t) .long PPC_INST_MFVSRD | VSX_XX1((t)+32, a, 0)
#define MTVRD(t, a) .long PPC_INST_MTVSRD | VSX_XX1((t)+32, a, 0)
#endif
...@@ -104,6 +104,7 @@ UNIV_INTERN bool ut_crc32_power8_enabled = false; ...@@ -104,6 +104,7 @@ UNIV_INTERN bool ut_crc32_power8_enabled = false;
/********************************************************************//** /********************************************************************//**
Initializes the table that is used to generate the CRC32 if the CPU does Initializes the table that is used to generate the CRC32 if the CPU does
not have support for it. */ not have support for it. */
#ifndef HAVE_CRC32_VPMSUM
static static
void void
ut_crc32_slice8_table_init() ut_crc32_slice8_table_init()
...@@ -133,6 +134,7 @@ ut_crc32_slice8_table_init() ...@@ -133,6 +134,7 @@ ut_crc32_slice8_table_init()
ut_crc32_slice8_table_initialized = TRUE; ut_crc32_slice8_table_initialized = TRUE;
} }
#endif
#if defined(__GNUC__) && defined(__x86_64__) #if defined(__GNUC__) && defined(__x86_64__)
/********************************************************************//** /********************************************************************//**
...@@ -181,27 +183,22 @@ for RHEL4 support (GCC 3 doesn't support this instruction) */ ...@@ -181,27 +183,22 @@ for RHEL4 support (GCC 3 doesn't support this instruction) */
len -= 8, buf += 8 len -= 8, buf += 8
#endif /* defined(__GNUC__) && defined(__x86_64__) */ #endif /* defined(__GNUC__) && defined(__x86_64__) */
#if defined(__powerpc__)
#ifdef HAVE_CRC32_VPMSUM
extern "C" { extern "C" {
unsigned int crc32_vpmsum(unsigned int crc, const unsigned char *p, unsigned long len); unsigned int crc32_vpmsum(unsigned int crc, const unsigned char *p, unsigned long len);
}; };
#endif /* __powerpc__ */
UNIV_INLINE UNIV_INLINE
ib_uint32_t ib_uint32_t
ut_crc32_power8( ut_crc32_power8(
/*===========*/ /*===========*/
const byte* buf, /*!< in: data over which to calculate CRC32 */ const byte* buf, /*!< in: data over which to calculate CRC32 */
ulint len) /*!< in: data length */ ulint len) /*!< in: data length */
{ {
#if defined(__powerpc__) && !defined(WORDS_BIGENDIAN)
return crc32_vpmsum(0, buf, len); return crc32_vpmsum(0, buf, len);
#else
ut_error;
/* silence compiler warning about unused parameters */
return((ib_uint32_t) buf[len]);
#endif /* __powerpc__ */
} }
#endif
/********************************************************************//** /********************************************************************//**
Calculates CRC32 using CPU instructions. Calculates CRC32 using CPU instructions.
...@@ -338,18 +335,15 @@ ut_crc32_init() ...@@ -338,18 +335,15 @@ ut_crc32_init()
#endif /* defined(__GNUC__) && defined(__x86_64__) */ #endif /* defined(__GNUC__) && defined(__x86_64__) */
#if defined(__linux__) && defined(__powerpc__) && defined(AT_HWCAP2) \ #ifdef HAVE_CRC32_VPMSUM
&& !defined(WORDS_BIGENDIAN) ut_crc32_power8_enabled = true;
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) ut_crc32 = ut_crc32_power8;
ut_crc32_power8_enabled = true; #else
#endif /* defined(__linux__) && defined(__powerpc__) */
if (ut_crc32_sse2_enabled) { if (ut_crc32_sse2_enabled) {
ut_crc32 = ut_crc32_sse42; ut_crc32 = ut_crc32_sse42;
} else if (ut_crc32_power8_enabled) {
ut_crc32 = ut_crc32_power8;
} else { } else {
ut_crc32_slice8_table_init(); ut_crc32_slice8_table_init();
ut_crc32 = ut_crc32_slice8; ut_crc32 = ut_crc32_slice8;
} }
#endif
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment