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)
INCLUDE(install_macros)
INCLUDE(systemd)
INCLUDE(mysql_add_executable)
INCLUDE(crc32-vpmsum)
# Handle options
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 @@
/* Libraries */
#cmakedefine HAVE_LIBWRAP 1
#cmakedefine HAVE_SYSTEMD 1
#cmakedefine HAVE_CRC32_VPMSUM 1
/* Does "struct timespec" have a "sec" and "nsec" field? */
#cmakedefine HAVE_TIMESPEC_TS_SEC 1
......
......@@ -80,13 +80,6 @@ IF(WITH_INNOBASE_STORAGE_ENGINE OR WITH_XTRADB_STORAGE_ENGINE)
../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})
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})
DTRACE_INSTRUMENT(clientlib)
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
# and link them together into shared library.
......
......@@ -71,7 +71,7 @@ ENDIF()
ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES})
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)
IF(HAVE_BFD_H)
......
......@@ -30,7 +30,13 @@
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);
#endif
DBUG_PRINT("info", ("crc: %lu", (ulong) 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
ut/ut0wqueue.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)
# Legacy option
SET(WITH_INNOBASE_STORAGE_ENGINE TRUE)
......@@ -517,5 +509,5 @@ ENDIF()
MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE
MODULE_ONLY
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;
/********************************************************************//**
Initializes the table that is used to generate the CRC32 if the CPU does
not have support for it. */
#ifndef HAVE_CRC32_VPMSUM
static
void
ut_crc32_slice8_table_init()
......@@ -133,6 +134,7 @@ ut_crc32_slice8_table_init()
ut_crc32_slice8_table_initialized = TRUE;
}
#endif
#if defined(__GNUC__) && defined(__x86_64__)
/********************************************************************//**
......@@ -181,27 +183,22 @@ for RHEL4 support (GCC 3 doesn't support this instruction) */
len -= 8, buf += 8
#endif /* defined(__GNUC__) && defined(__x86_64__) */
#if defined(__powerpc__)
#ifdef HAVE_CRC32_VPMSUM
extern "C" {
unsigned int crc32_vpmsum(unsigned int crc, const unsigned char *p, unsigned long len);
};
#endif /* __powerpc__ */
UNIV_INLINE
ib_uint32_t
ut_crc32_power8(
/*===========*/
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);
#else
ut_error;
/* silence compiler warning about unused parameters */
return((ib_uint32_t) buf[len]);
#endif /* __powerpc__ */
}
#endif
/********************************************************************//**
Calculates CRC32 using CPU instructions.
......@@ -338,18 +335,15 @@ ut_crc32_init()
#endif /* defined(__GNUC__) && defined(__x86_64__) */
#if defined(__linux__) && defined(__powerpc__) && defined(AT_HWCAP2) \
&& !defined(WORDS_BIGENDIAN)
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07)
ut_crc32_power8_enabled = true;
#endif /* defined(__linux__) && defined(__powerpc__) */
#ifdef HAVE_CRC32_VPMSUM
ut_crc32_power8_enabled = true;
ut_crc32 = ut_crc32_power8;
#else
if (ut_crc32_sse2_enabled) {
ut_crc32 = ut_crc32_sse42;
} else if (ut_crc32_power8_enabled) {
ut_crc32 = ut_crc32_power8;
} else {
ut_crc32_slice8_table_init();
ut_crc32 = ut_crc32_slice8;
}
#endif
}
......@@ -496,17 +496,9 @@ SET(INNOBASE_SOURCES
ut/ut0wqueue.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
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)
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;
/********************************************************************//**
Initializes the table that is used to generate the CRC32 if the CPU does
not have support for it. */
#ifndef HAVE_CRC32_VPMSUM
static
void
ut_crc32_slice8_table_init()
......@@ -133,6 +134,7 @@ ut_crc32_slice8_table_init()
ut_crc32_slice8_table_initialized = TRUE;
}
#endif
#if defined(__GNUC__) && defined(__x86_64__)
/********************************************************************//**
......@@ -181,27 +183,22 @@ for RHEL4 support (GCC 3 doesn't support this instruction) */
len -= 8, buf += 8
#endif /* defined(__GNUC__) && defined(__x86_64__) */
#if defined(__powerpc__)
#ifdef HAVE_CRC32_VPMSUM
extern "C" {
unsigned int crc32_vpmsum(unsigned int crc, const unsigned char *p, unsigned long len);
};
#endif /* __powerpc__ */
UNIV_INLINE
ib_uint32_t
ut_crc32_power8(
/*===========*/
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);
#else
ut_error;
/* silence compiler warning about unused parameters */
return((ib_uint32_t) buf[len]);
#endif /* __powerpc__ */
}
#endif
/********************************************************************//**
Calculates CRC32 using CPU instructions.
......@@ -338,18 +335,15 @@ ut_crc32_init()
#endif /* defined(__GNUC__) && defined(__x86_64__) */
#if defined(__linux__) && defined(__powerpc__) && defined(AT_HWCAP2) \
&& !defined(WORDS_BIGENDIAN)
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07)
ut_crc32_power8_enabled = true;
#endif /* defined(__linux__) && defined(__powerpc__) */
#ifdef HAVE_CRC32_VPMSUM
ut_crc32_power8_enabled = true;
ut_crc32 = ut_crc32_power8;
#else
if (ut_crc32_sse2_enabled) {
ut_crc32 = ut_crc32_sse42;
} else if (ut_crc32_power8_enabled) {
ut_crc32 = ut_crc32_power8;
} else {
ut_crc32_slice8_table_init();
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