Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmake: Add option to select micro-arch, use x86-64-v2 by default #548

Merged
merged 3 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,27 @@ set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)

if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
# Setup options for x86_64 micro-architecture levels.
# https://clang.llvm.org/docs/UsersManual.html#x86

set(EVMONE_X86_64_ARCH_LEVEL_INIT 2)
if(APPLE)
# On macos with Apple Silicon CPU (arm64) the x86 is emulated and SSE4.2 is not available.
set(EVMONE_X86_64_ARCH_LEVEL_INIT 1)
endif()

set(EVMONE_X86_64_ARCH_LEVEL ${EVMONE_X86_64_ARCH_LEVEL_INIT} CACHE STRING "The x86_64 micro-architecture level")
if(EVMONE_X86_64_ARCH_LEVEL GREATER_EQUAL 1 AND EVMONE_X86_64_ARCH_LEVEL LESS_EQUAL 4)
message(STATUS "x86_64 micro-architecture level: ${EVMONE_X86_64_ARCH_LEVEL}")
if(EVMONE_X86_64_ARCH_LEVEL GREATER_EQUAL 2)
add_compile_options(-march=x86-64-v${EVMONE_X86_64_ARCH_LEVEL})
endif()
else()
message(FATAL_ERROR "Invalid EVMONE_X86_64_ARCH_LEVEL: ${EVMONE_X86_64_ARCH_LEVEL}")
endif()
endif()

include(GNUInstallDirs)

if(EVMONE_FUZZING)
Expand All @@ -89,7 +110,6 @@ if(EVMONE_FUZZING)
# The coverage builds should be without fuzzing instrumentation to allow
# running fuzzing corpus once and getting code coverage.
set(fuzzing_flags -fsanitize=fuzzer-no-link,address,undefined,shift-exponent,implicit-conversion,nullability)
# set(fuzzing_flags -fsanitize=fuzzer-no-link)
add_compile_options(${fuzzing_flags})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${fuzzing_flags}")
endif()
Expand Down
11 changes: 9 additions & 2 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -586,14 +586,21 @@ jobs:
executor: linux-gcc-latest
environment:
BUILD_TYPE: Release
CMAKE_OPTIONS: -DCMAKE_CROSSCOMPILING_EMULATOR=qemu-x86_64-static
QEMU_CPU: core2duo # The lowest 64-bit CPU I could find, but qemu64 should be good too.
steps:
- run:
name: "Install qemu"
command: sudo apt update -y && sudo apt install -y qemu-user-static
- build
- test
- run:
name: "Check evmone.so"
working_directory: ~/build
command: (! qemu-x86_64-static bin/evmc run --vm ./lib/libevmone.so,trace 6000 2>&1) | grep "CPU does not support"
- run:
name: "Check unittests"
working_directory: ~/build
command: (! qemu-x86_64-static bin/evmone-unittests 2>&1) | grep "CPU does not support"



workflows:
Expand Down
9 changes: 8 additions & 1 deletion lib/evmone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ add_library(evmone
baseline_instruction_table.cpp
baseline_instruction_table.hpp
eof.cpp
eof.hpp
eof.hpp
instructions.hpp
instructions_calls.cpp
instructions_opcodes.hpp
Expand All @@ -37,6 +37,13 @@ target_link_libraries(evmone PUBLIC evmc::evmc intx::intx PRIVATE ethash::keccak
target_include_directories(evmone PUBLIC
$<BUILD_INTERFACE:${include_dir}>$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

if(EVMONE_X86_64_ARCH_LEVEL GREATER_EQUAL 2)
# Add CPU architecture runtime check. The EVMONE_X86_64_ARCH_LEVEL has a valid value.
target_sources(evmone PRIVATE cpu_check.cpp)
set_source_files_properties(cpu_check.cpp PROPERTIES COMPILE_DEFINITIONS EVMONE_X86_64_ARCH_LEVEL=${EVMONE_X86_64_ARCH_LEVEL})
endif()

if(CABLE_COMPILER_GNULIKE)
target_compile_options(
evmone PRIVATE
Expand Down
29 changes: 29 additions & 0 deletions lib/evmone/cpu_check.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)

#if defined(__GNUC__) && __GNUC__ >= 12
#define CPU_FEATURE "x86-64-v" STRINGIFY(EVMONE_X86_64_ARCH_LEVEL)
#else
// Clang 16 and GCC 11 does not support architecture levels in __builtin_cpu_supports().
// Use approximations.
#if EVMONE_X86_64_ARCH_LEVEL == 2
#define CPU_FEATURE "sse4.2"
#endif
#endif

#ifndef CPU_FEATURE
#error "EVMONE_X86_64_ARCH_LEVEL: Unsupported x86-64 architecture level"
#endif

#include <cstdio>
#include <cstdlib>

static bool cpu_check = []() noexcept {
if (!__builtin_cpu_supports(CPU_FEATURE))
{
(void)std::fputs("CPU does not support " CPU_FEATURE "\n", stderr);
std::abort();
}
return false;
}();