set(ARCH_C_FLAGS "${ARCH_C_FLAGS} -march=native -mtune=native")
endif()
- # we don't use these for the lib, but other tools/unit tests
if (NOT CMAKE_CXX_FLAGS MATCHES .*march.*)
set(ARCH_CXX_FLAGS "${ARCH_CXX_FLAGS} -march=native -mtune=native")
endif()
endif()
endif()
-# ensure we are building for the right target arch
+if (CMAKE_SYSTEM_NAME MATCHES "Linux")
+ # This is a Linux-only feature for now - requires platform support
+ # elsewhere
+ option(FAT_RUNTIME "Build a library that supports multiple microarchitecures" RELEASE_BUILD)
+ if (FAT_RUNTIME)
+ include (${CMAKE_MODULE_PATH}/attrib.cmake)
+ if (NOT HAS_C_ATTR_IFUNC)
+ message(FATAL_ERROR "Compiler does not support ifunc attribute, cannot build fat runtime")
+ endif()
+ endif()
+endif ()
+
include (${CMAKE_MODULE_PATH}/arch.cmake)
+if (NOT FAT_RUNTIME AND NOT HAVE_SSSE3)
+ message(FATAL_ERROR "A minimum of SSSE3 compiler support is required")
+endif ()
+
# testing a builtin takes a little more work
CHECK_C_SOURCE_COMPILES("void *aa_test(void *x) { return __builtin_assume_aligned(x, 16);}\nint main(void) { return 0; }" HAVE_CC_BUILTIN_ASSUME_ALIGNED)
CHECK_CXX_SOURCE_COMPILES("void *aa_test(void *x) { return __builtin_assume_aligned(x, 16);}\nint main(void) { return 0; }" HAVE_CXX_BUILTIN_ASSUME_ALIGNED)
endif()
endif()
+if (NOT FAT_RUNTIME)
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_C_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_CXX_FLAGS}")
+else()
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+endif()
+
add_subdirectory(util)
add_subdirectory(unit)
add_subdirectory(doc/dev-reference)
endif()
# only set these after all tests are done
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_C_FLAGS} ${EXTRA_C_FLAGS}")
+if (NOT FAT_RUNTIME)
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}")
+else()
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}")
+endif()
if(NOT WIN32)
)
install(FILES ${hs_HEADERS} DESTINATION include/hs)
+set (hs_exec_common_SRCS
+ src/alloc.c
+ src/scratch.c
+ src/util/multibit.c
+ )
+
set (hs_exec_SRCS
${hs_HEADERS}
src/hs_version.h
src/ue2common.h
- src/alloc.c
src/allocator.h
+ src/crc32.c
+ src/crc32.h
src/report.h
src/runtime.c
src/fdr/fdr.c
src/util/join.h
src/util/masked_move.h
src/util/multibit.h
- src/util/multibit_internal.h
src/util/multibit.c
+ src/util/multibit_internal.h
src/util/pack_bits.h
src/util/popcount.h
src/util/pqueue.h
src/util/state_compress.c
src/util/unaligned.h
src/util/uniform_ops.h
- src/scratch.h
- src/scratch.c
- src/crc32.c
- src/crc32.h
src/database.c
src/database.h
)
-if (HAVE_AVX2)
- set (hs_exec_SRCS
- ${hs_exec_SRCS}
- src/fdr/teddy_avx2.c
- src/util/masked_move.c
- )
-endif ()
+set (hs_exec_avx2_SRCS
+ src/fdr/teddy_avx2.c
+ src/util/masked_move.c
+)
SET (hs_SRCS
set (LIB_VERSION ${HS_VERSION})
set (LIB_SOVERSION ${HS_MAJOR_VERSION})
-add_library(hs_exec OBJECT ${hs_exec_SRCS})
+if (NOT FAT_RUNTIME)
+
+ if (HAVE_AVX2)
+ add_library(hs_exec OBJECT ${hs_exec_common_SRCS} ${hs_exec_SRCS}
+ ${hs_exec_avx2_SRCS})
+ else()
+ add_library(hs_exec OBJECT ${hs_exec_common_SRCS} ${hs_exec_SRCS})
+ endif()
+
+ add_library(hs_runtime STATIC src/hs_version.c $<TARGET_OBJECTS:hs_exec>)
+ set_target_properties(hs_runtime PROPERTIES LINKER_LANGUAGE C)
+
+ if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS)
+ add_library(hs_exec_shared OBJECT ${hs_exec_SRCS})
+ set_target_properties(hs_exec_shared PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
+ endif()
+
+else (FAT_RUNTIME)
+ set(BUILD_WRAPPER "${PROJECT_SOURCE_DIR}/cmake/build_wrapper.sh")
+ add_library(hs_exec_core2 OBJECT ${hs_exec_SRCS})
+ set_target_properties(hs_exec_core2 PROPERTIES
+ COMPILE_FLAGS "-march=core2"
+ RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} core2 ${CMAKE_MODULE_PATH}/keep.syms.in"
+ )
+
+ add_library(hs_exec_corei7 OBJECT ${hs_exec_SRCS})
+ set_target_properties(hs_exec_corei7 PROPERTIES
+ COMPILE_FLAGS "-march=corei7"
+ RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} corei7 ${CMAKE_MODULE_PATH}/keep.syms.in"
+ )
+
+ add_library(hs_exec_avx2 OBJECT ${hs_exec_SRCS} ${hs_exec_avx2_SRCS})
+ set_target_properties(hs_exec_avx2 PROPERTIES
+ COMPILE_FLAGS "-march=core-avx2"
+ RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} avx2 ${CMAKE_MODULE_PATH}/keep.syms.in"
+ )
+
+ add_library(hs_exec_common OBJECT
+ ${hs_exec_common_SRCS}
+ src/dispatcher.c
+ )
+ set_source_files_properties(src/dispatcher.c PROPERTIES
+ COMPILE_FLAGS "-Wno-unused-parameter -Wno-unused-function")
+ set_source_files_properties(${hs_exec_common_SRCS} PROPERTIES
+ COMPILE_FLAGS "-march=core-avx2")
+
+ if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS)
+ add_library(hs_exec_shared_core2 OBJECT ${hs_exec_SRCS})
+ set_target_properties(hs_exec_shared_core2 PROPERTIES
+ COMPILE_FLAGS "-march=core2"
+ POSITION_INDEPENDENT_CODE TRUE
+ RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} core2 ${CMAKE_MODULE_PATH}/keep.syms.in"
+ )
+ add_library(hs_exec_shared_corei7 OBJECT ${hs_exec_SRCS})
+ set_target_properties(hs_exec_shared_corei7 PROPERTIES
+ COMPILE_FLAGS "-march=corei7"
+ POSITION_INDEPENDENT_CODE TRUE
+ RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} corei7 ${CMAKE_MODULE_PATH}/keep.syms.in"
+ )
+ add_library(hs_exec_shared_avx2 OBJECT ${hs_exec_SRCS} ${hs_exec_avx2_SRCS})
+ set_target_properties(hs_exec_shared_avx2 PROPERTIES
+ COMPILE_FLAGS "-march=core-avx2"
+ POSITION_INDEPENDENT_CODE TRUE
+ RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} avx2 ${CMAKE_MODULE_PATH}/keep.syms.in"
+ )
+ add_library(hs_exec_common_shared OBJECT
+ ${hs_exec_common_SRCS}
+ src/dispatcher.c
+ )
+ set_target_properties(hs_exec_common_shared PROPERTIES
+ OUTPUT_NAME hs_exec_common
+ POSITION_INDEPENDENT_CODE TRUE)
+ endif() # SHARED
-if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS)
-add_library(hs_exec_shared OBJECT ${hs_exec_SRCS})
-set_target_properties(hs_exec_shared PROPERTIES
- POSITION_INDEPENDENT_CODE TRUE)
-endif()
# hs_version.c is added explicitly to avoid some build systems that refuse to
# create a lib without any src (I'm looking at you Xcode)
-add_library(hs_runtime STATIC src/hs_version.c $<TARGET_OBJECTS:hs_exec>)
+ add_library(hs_runtime STATIC src/hs_version.c
+ $<TARGET_OBJECTS:hs_exec_common> $<TARGET_OBJECTS:hs_exec_core2>
+ $<TARGET_OBJECTS:hs_exec_corei7> $<TARGET_OBJECTS:hs_exec_avx2>)
+endif (NOT FAT_RUNTIME)
+
-set_target_properties(hs_runtime PROPERTIES
- LINKER_LANGUAGE C)
+set_target_properties(hs_runtime PROPERTIES LINKER_LANGUAGE C)
if (NOT BUILD_SHARED_LIBS)
install(TARGETS hs_runtime DESTINATION lib)
endif()
if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS)
- add_library(hs_runtime_shared SHARED src/hs_version.c $<TARGET_OBJECTS:hs_exec_shared>)
+ if (NOT FAT_RUNTIME)
+ add_library(hs_runtime_shared SHARED src/hs_version.c $<TARGET_OBJECTS:hs_exec_shared>)
+ else()
+ add_library(hs_runtime_shared SHARED src/hs_version.c $<TARGET_OBJECTS:hs_exec_common_shared> $<TARGET_OBJECTS:hs_exec_shared_core2> $<TARGET_OBJECTS:hs_exec_shared_corei7> $<TARGET_OBJECTS:hs_exec_shared_avx2>)
+ endif()
set_target_properties(hs_runtime_shared PROPERTIES
VERSION ${LIB_VERSION}
SOVERSION ${LIB_SOVERSION}
LIBRARY DESTINATION lib)
endif()
+if (NOT FAT_RUNTIME)
+ add_library(hs STATIC ${hs_SRCS} $<TARGET_OBJECTS:hs_exec>)
+else()
# we want the static lib for testing
-add_library(hs STATIC ${hs_SRCS} $<TARGET_OBJECTS:hs_exec>)
+add_library(hs STATIC src/hs_version.c ${hs_SRCS} $<TARGET_OBJECTS:hs_exec_common> $<TARGET_OBJECTS:hs_exec_core2> $<TARGET_OBJECTS:hs_exec_corei7> $<TARGET_OBJECTS:hs_exec_avx2>)
+endif()
add_dependencies(hs ragel_Parser)
endif()
if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS)
- add_library(hs_shared SHARED ${hs_SRCS} $<TARGET_OBJECTS:hs_exec_shared>)
+ if (NOT FAT_RUNTIME)
+ add_library(hs_shared SHARED src/hs_version.c ${hs_SRCS} $<TARGET_OBJECTS:hs_exec_shared>)
+ else()
+ add_library(hs_shared SHARED src/hs_version.c ${hs_SRCS} $<TARGET_OBJECTS:hs_exec_common_shared> $<TARGET_OBJECTS:hs_exec_shared_core2> $<TARGET_OBJECTS:hs_exec_shared_corei7> $<TARGET_OBJECTS:hs_exec_shared_avx2>)
+ endif()
add_dependencies(hs_shared ragel_Parser)
set_target_properties(hs_shared PROPERTIES
OUTPUT_NAME hs
endif ()
-set (CMAKE_REQUIRED_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}")
+set (CMAKE_REQUIRED_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS} ${ARCH_C_FLAGS}")
+
# ensure we have the minimum of SSSE3 - call a SSSE3 intrinsic
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
int main() {
(void)_mm_shuffle_epi8(a, a);
}" HAVE_SSSE3)
-if (NOT HAVE_SSSE3)
- message(FATAL_ERROR "A minimum of SSSE3 compiler support is required")
-endif ()
-
# now look for AVX2
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
#if !defined(__AVX2__)
(void)_mm256_xor_si256(z, z);
}" HAVE_AVX2)
-if (NOT HAVE_AVX2)
- message(STATUS "Building without AVX2 support")
-endif ()
-
unset (CMAKE_REQUIRED_FLAGS)
unset (INTRIN_INC_H)
--- /dev/null
+# tests for compiler properties
+
+CHECK_C_SOURCE_COMPILES("int foo(int) __attribute__ ((ifunc(\"foo_i\"))); int f1(int i) { return i; } void (*foo_i()) { return f1; } int main(void) { return 0; }" HAS_C_ATTR_IFUNC)
--- /dev/null
+#!/bin/sh -e
+# This is used for renaming symbols for the fat runtime, don't call directly
+# TODO: make this a lot less fragile!
+PREFIX=$1
+KEEPSYMS_IN=$2
+shift 2
+BUILD=$@
+OUT=$(echo $BUILD | sed 's/.* -o \(.*\.o\).*/\1/')
+SYMSFILE=/tmp/${PREFIX}_rename.syms.$$
+KEEPSYMS=/tmp/keep.syms.$$
+# grab the command without the target obj or src file flags
+# we don't just call gcc directly as there may be flags modifying the arch
+CC_CMD=$(echo $BUILD | sed 's/ -o .*\.o//;s/ -c //;s/ .[^ ]*\.c//;')
+# find me a libc
+LIBC_SO=$(${CC_CMD} --print-file-name=libc.so.6)
+cp ${KEEPSYMS_IN} ${KEEPSYMS}
+# get all symbols from libc and turn them into patterns
+nm -f p -g -D ${LIBC_SO} | sed -s 's/\([^ ]*\).*/^\1$/' >> ${KEEPSYMS}
+# build the object
+${BUILD}
+# rename the symbols in the object
+nm -f p -g ${OUT} | cut -f1 -d' ' | grep -v -f ${KEEPSYMS} | sed -e "s/\(.*\)/\1\ ${PREFIX}_\1/" >> ${SYMSFILE}
+if test -s ${SYMSFILE}
+then
+ objcopy --redefine-syms=${SYMSFILE} ${OUT}
+fi
+rm -f ${SYMSFILE} ${KEEPSYMS}
/* internal build, switch on dump support. */
#cmakedefine DUMP_SUPPORT
+/* Define if building "fat" runtime. */
+#cmakedefine FAT_RUNTIME
+
/* Define to 1 if `backtrace' works. */
#cmakedefine HAVE_BACKTRACE
--- /dev/null
+# names to exclude
+hs_misc_alloc
+hs_misc_free
+hs_free_scratch
+hs_stream_alloc
+hs_stream_free
+hs_scratch_alloc
+hs_scratch_free
+hs_database_alloc
+hs_database_free
+^_
/** \file
* \brief Compiler front-end interface.
*/
+#include "allocator.h"
#include "asserts.h"
#include "compiler.h"
+#include "crc32.h"
#include "database.h"
#include "grey.h"
#include "hs_internal.h"
return p;
}
+/** \brief Encapsulate the given bytecode (RoseEngine) in a newly-allocated
+ * \ref hs_database, ensuring that it is padded correctly to give cacheline
+ * alignment. */
+static
+hs_database_t *dbCreate(const char *in_bytecode, size_t len, u64a platform) {
+ size_t db_len = sizeof(struct hs_database) + len;
+ DEBUG_PRINTF("db size %zu\n", db_len);
+ DEBUG_PRINTF("db platform %llx\n", platform);
+
+ struct hs_database *db = (struct hs_database *)hs_database_alloc(db_len);
+ if (hs_check_alloc(db) != HS_SUCCESS) {
+ hs_database_free(db);
+ return nullptr;
+ }
+
+ // So that none of our database is uninitialized
+ memset(db, 0, db_len);
+
+ // we need to align things manually
+ size_t shift = (uintptr_t)db->bytes & 0x3f;
+ DEBUG_PRINTF("shift is %zu\n", shift);
+
+ db->bytecode = offsetof(struct hs_database, bytes) - shift;
+ char *bytecode = (char *)db + db->bytecode;
+ assert(ISALIGNED_CL(bytecode));
+
+ db->magic = HS_DB_MAGIC;
+ db->version = HS_DB_VERSION;
+ db->length = len;
+ db->platform = platform;
+
+ // Copy bytecode
+ memcpy(bytecode, in_bytecode, len);
+
+ db->crc32 = Crc32c_ComputeBuf(0, bytecode, db->length);
+ return db;
+}
+
+
struct hs_database *build(NG &ng, unsigned int *length) {
assert(length);
/*
- * Copyright (c) 2015, Intel Corporation
+ * Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
return HS_SUCCESS;
}
-/** \brief Encapsulate the given bytecode (RoseEngine) in a newly-allocated
- * \ref hs_database, ensuring that it is padded correctly to give cacheline
- * alignment. */
-hs_database_t *dbCreate(const char *in_bytecode, size_t len, u64a platform) {
- size_t db_len = sizeof(struct hs_database) + len;
- DEBUG_PRINTF("db size %zu\n", db_len);
- DEBUG_PRINTF("db platform %llx\n", platform);
-
- struct hs_database *db = (struct hs_database *)hs_database_alloc(db_len);
- if (hs_check_alloc(db) != HS_SUCCESS) {
- hs_database_free(db);
- return NULL;
- }
-
- // So that none of our database is uninitialized
- memset(db, 0, db_len);
-
- // we need to align things manually
- size_t shift = (uintptr_t)db->bytes & 0x3f;
- DEBUG_PRINTF("shift is %zu\n", shift);
-
- db->bytecode = offsetof(struct hs_database, bytes) - shift;
- char *bytecode = (char *)db + db->bytecode;
- assert(ISALIGNED_CL(bytecode));
-
- db->magic = HS_DB_MAGIC;
- db->version = HS_DB_VERSION;
- db->length = len;
- db->platform = platform;
-
- // Copy bytecode
- memcpy(bytecode, in_bytecode, len);
-
- db->crc32 = Crc32c_ComputeBuf(0, bytecode, db->length);
- return db;
-}
-
#if defined(_WIN32)
#define SNPRINTF_COMPAT _snprintf
#else
/*
- * Copyright (c) 2015, Intel Corporation
+ * Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
}
hs_error_t dbIsValid(const struct hs_database *db);
-struct hs_database *dbCreate(const char *bytecode, size_t len, u64a platform);
#ifdef __cplusplus
} /* extern "C" */
--- /dev/null
+/*
+ * Copyright (c) 2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "hs_common.h"
+#include "hs_runtime.h"
+#include "ue2common.h"
+#include "util/cpuid_flags.h"
+#include "util/join.h"
+
+#define CREATE_DISPATCH(RTYPE, NAME, ...) \
+ /* create defns */ \
+ RTYPE JOIN(avx2_, NAME)(__VA_ARGS__); \
+ RTYPE JOIN(corei7_, NAME)(__VA_ARGS__); \
+ RTYPE JOIN(core2_, NAME)(__VA_ARGS__); \
+ \
+ /* error func */ \
+ static inline RTYPE JOIN(error_, NAME)(__VA_ARGS__) { \
+ return (RTYPE)HS_ARCH_ERROR; \
+ } \
+ \
+ /* resolver */ \
+ static void(*JOIN(resolve_, NAME)(void)) { \
+ if (check_avx2()) { \
+ return JOIN(avx2_, NAME); \
+ } \
+ if (check_sse42() && check_popcnt()) { \
+ return JOIN(corei7_, NAME); \
+ } \
+ if (check_ssse3()) { \
+ return JOIN(core2_, NAME); \
+ } \
+ /* anything else is fail */ \
+ return JOIN(error_, NAME); \
+ } \
+ \
+ /* function */ \
+ RTYPE NAME(__VA_ARGS__) __attribute__((ifunc("resolve_" #NAME)))
+
+CREATE_DISPATCH(hs_error_t, hs_scan, const hs_database_t *db, const char *data,
+ unsigned length, unsigned flags, hs_scratch_t *scratch,
+ match_event_handler onEvent, void *userCtx);
+
+CREATE_DISPATCH(hs_error_t, hs_stream_size, const hs_database_t *database,
+ size_t *stream_size);
+
+CREATE_DISPATCH(hs_error_t, hs_database_size, const hs_database_t *db,
+ size_t *size);
+CREATE_DISPATCH(hs_error_t, dbIsValid, const hs_database_t *db);
+CREATE_DISPATCH(hs_error_t, hs_free_database, hs_database_t *db);
+
+CREATE_DISPATCH(hs_error_t, hs_open_stream, const hs_database_t *db,
+ unsigned int flags, hs_stream_t **stream);
+
+CREATE_DISPATCH(hs_error_t, hs_scan_stream, hs_stream_t *id, const char *data,
+ unsigned int length, unsigned int flags, hs_scratch_t *scratch,
+ match_event_handler onEvent, void *ctxt);
+
+CREATE_DISPATCH(hs_error_t, hs_close_stream, hs_stream_t *id,
+ hs_scratch_t *scratch, match_event_handler onEvent, void *ctxt);
+
+CREATE_DISPATCH(hs_error_t, hs_scan_vector, const hs_database_t *db,
+ const char *const *data, const unsigned int *length,
+ unsigned int count, unsigned int flags, hs_scratch_t *scratch,
+ match_event_handler onevent, void *context);
+
+CREATE_DISPATCH(hs_error_t, hs_database_info, const hs_database_t *db, char **info);
+
+CREATE_DISPATCH(hs_error_t, hs_copy_stream, hs_stream_t **to_id,
+ const hs_stream_t *from_id);
+
+CREATE_DISPATCH(hs_error_t, hs_reset_stream, hs_stream_t *id,
+ unsigned int flags, hs_scratch_t *scratch,
+ match_event_handler onEvent, void *context);
+
+CREATE_DISPATCH(hs_error_t, hs_reset_and_copy_stream, hs_stream_t *to_id,
+ const hs_stream_t *from_id, hs_scratch_t *scratch,
+ match_event_handler onEvent, void *context);
+
+CREATE_DISPATCH(hs_error_t, hs_serialize_database, const hs_database_t *db,
+ char **bytes, size_t *length);
+
+CREATE_DISPATCH(hs_error_t, hs_deserialize_database, const char *bytes,
+ const size_t length, hs_database_t **db);
+
+CREATE_DISPATCH(hs_error_t, hs_deserialize_database_at, const char *bytes,
+ const size_t length, hs_database_t *db);
+
+CREATE_DISPATCH(hs_error_t, hs_serialized_database_info, const char *bytes,
+ size_t length, char **info);
+
+CREATE_DISPATCH(hs_error_t, hs_serialized_database_size, const char *bytes,
+ const size_t length, size_t *deserialized_size);
+
+/** INTERNALS **/
+
+CREATE_DISPATCH(u32, Crc32c_ComputeBuf, u32 inCrc32, const void *buf, size_t bufLen);
return HS_COMPILER_ERROR;
}
+#if defined(FAT_RUNTIME)
+ if (!check_ssse3()) {
+ *db = nullptr;
+ *comp_error = generateCompileError("Unsupported architecture", -1);
+ return HS_ARCH_ERROR;
+ }
+#endif
+
if (!checkMode(mode, comp_error)) {
*db = nullptr;
assert(*comp_error); // set by checkMode.
return HS_COMPILER_ERROR;
}
+#if defined(FAT_RUNTIME)
+ if (!check_ssse3()) {
+ *error = generateCompileError("Unsupported architecture", -1);
+ return HS_ARCH_ERROR;
+ }
+#endif
+
if (!info) {
*error = generateCompileError("Invalid parameter: info is NULL", -1);
return HS_COMPILER_ERROR;
extern "C" HS_PUBLIC_API
hs_error_t hs_free_compile_error(hs_compile_error_t *error) {
+#if defined(FAT_RUNTIME)
+ if (!check_ssse3()) {
+ return HS_ARCH_ERROR;
+ }
+#endif
freeCompileError(error);
return HS_SUCCESS;
}
*/
#define HS_SCRATCH_IN_USE (-10)
+/**
+ * Unsupported CPU architecture.
+ *
+ * This error is returned when Hyperscan is able to detect that the current
+ * system does not support the required instruction set.
+ *
+ * At a minimum, Hyperscan requires Supplemental Streaming SIMD Extensions 3
+ * (SSSE3).
+ */
+#define HS_ARCH_ERROR (-11)
+
/** @} */
#ifdef __cplusplus
}
for (u32 i = 0; i < N_CHARS; i++) {
assert(info.alpha_remap[i] != info.alpha_remap[TOP]);
- memcpy((u8*)&m->sheng_masks[i], (u8*)masks[info.alpha_remap[i]].data(), sizeof(m128));
+ memcpy((u8 *)&m->sheng_masks[i],
+ (u8 *)masks[info.alpha_remap[i]].data(), sizeof(m128));
}
m->sheng_end = sheng_end;
m->sheng_accel_limit = sheng_end - 1;
#define SSSE3 (1 << 9)
#define SSE4_1 (1 << 19)
#define SSE4_2 (1 << 20)
+#define POPCNT (1 << 23)
#define XSAVE (1 << 27)
#define AVX (1 << 28)
// EDX
+#define FXSAVE (1 << 24)
#define SSE (1 << 25)
-#define SSE2 (1 << 25)
+#define SSE2 (1 << 26)
#define HTT (1 << 28)
// Structured Extended Feature Flags Enumeration Leaf ECX values
#endif
}
-static
int check_avx2(void) {
#if defined(__INTEL_COMPILER)
return _may_i_use_cpu_feature(_FEATURE_AVX2);
return cap;
}
+int check_ssse3(void) {
+ unsigned int eax, ebx, ecx, edx;
+ cpuid(1, 0, &eax, &ebx, &ecx, &edx);
+ return !!(ecx & SSSE3);
+}
+
+int check_sse42(void) {
+ unsigned int eax, ebx, ecx, edx;
+ cpuid(1, 0, &eax, &ebx, &ecx, &edx);
+ return !!(ecx & SSE4_2);
+}
+
+int check_popcnt(void) {
+ unsigned int eax, ebx, ecx, edx;
+ cpuid(1, 0, &eax, &ebx, &ecx, &edx);
+ return !!(ecx & POPCNT);
+}
+
struct family_id {
u32 full_family;
u32 full_model;
u32 cpuid_tune(void);
+int check_avx2(void);
+int check_ssse3(void);
+int check_sse42(void);
+int check_popcnt(void);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
#error no intrinsics!
#endif
+#if defined(__SSE2__)
typedef __m128i m128;
#else
typedef struct ALIGN_DIRECTIVE {u64a hi; u64a lo;} m128;
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_CXX_FLAGS} ${EXTRA_CXX_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}")
set(gtest_SOURCES gtest/gtest-all.cc gtest/gtest.h)
if(NOT XCODE)
add_definitions(-DGTEST_HAS_PTHREAD=0 -DSRCDIR=${PROJECT_SOURCE_DIR})
-if (NOT RELEASE_BUILD)
+if (NOT (RELEASE_BUILD OR FAT_RUNTIME))
set(unit_internal_SOURCES
internal/bitfield.cpp
internal/bitutils.cpp
add_executable(unit-internal ${unit_internal_SOURCES})
target_link_libraries(unit-internal hs gtest corpusomatic)
-endif(NOT RELEASE_BUILD)
+endif(NOT (RELEASE_BUILD OR FAT_RUNTIME))
set(unit_hyperscan_SOURCES
hyperscan/allocators.cpp