Skip to content

Commit

Permalink
Implement CMake build system
Browse files Browse the repository at this point in the history
This is a draft of a CMake build system. It doesn't yet include RVFI, JSON docs, formal stuff, etc.
  • Loading branch information
Timmmm committed Jan 2, 2025
1 parent 1c591ba commit bad1feb
Show file tree
Hide file tree
Showing 13 changed files with 577 additions and 267 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ _build/
_sbuild/
*.o
*.a
/z3_problems
z3_problems

# Typical CMake build directory.
/build
76 changes: 76 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
cmake_minimum_required(VERSION 3.22)

project(sail_riscv)

# Enable CTest
enable_testing()

# We technically require C++20 since the C generated by Sail - which we compile
# as C++ - uses designated initialisers, a C++20 feature. However in practice
# much older compilers support this feature so everything does work with C++17,
# but you get lots of warnings on compilers that support C++20 if you use
# this feature without -std=c++20.
if (cxx_std_20 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
set(CMAKE_CXX_STANDARD 20)
else()
set(CMAKE_CXX_STANDARD 17)
endif()
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

# Export compile_commands.json for IDE support.
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)

# Always use Position Independent Code. By default it is only used for
# shared libraries (which require it), but you also need it for static
# libraries if you link them into shared libraries.
# Generally it just simplifies everything for a negligable performance cost.
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)

# Don't allow undefined symbols in shared libraries. This is generally a pain.
if (UNIX)
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined")
endif()

# Optional faster binary. Increases compilation time a lot though due to LTO.
option(EXTRA_FAST "Enable aggressive optimisation flags (-march=native, -flto, etc)" FALSE)

if (EXTRA_FAST)
include("cmake/extra_fast.cmake")
endif()

# Extra CMake files.
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")

# These are the main requirements.
# Don't use `REQUIRED` so that we can print custom help messages.
find_package(ZLIB)
if (NOT ZLIB_FOUND)
message(FATAL_ERROR "Zlib not found. Try 'sudo apt install zlib1g-dev' or 'sudo dnf install zlib-devel'.")
endif()

find_package(GMP)
if (NOT GMP_FOUND)
message(FATAL_ERROR "GMP not found. Try 'sudo apt install libgmp3-dev' or 'sudo dnf install gmp-devel'.")
endif()

find_program(SAIL_BIN "sail")
if (NOT SAIL_BIN)
message(FATAL_ERROR "Sail not found. See README.md for installation instructions.")
endif()

set(ENABLED_ARCHITECTURES "rv32;rv64" CACHE STRING "Enabled architectures to build (rv32, rv64, rv32d, rv64f)" )

# Softfloat support.
add_subdirectory("dependencies/softfloat")

# Sail C runtime.
add_subdirectory("sail_runtime")

# Sail model generated C code.
add_subdirectory("model")

# Emulator binary.
add_subdirectory("emulator")

# Old pre-compiled riscv-tests.
add_subdirectory("test/riscv-tests")
28 changes: 28 additions & 0 deletions cmake/extra_fast.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
include(CheckCXXCompilerFlag)

# Enable agressive optimisation flags.

# Try to use -march=x86-64-v3, but fall back to -march=native if we are
# using an old compiler that doesn't support that flag.
check_cxx_compiler_flag("-march=x86-64-v3" COMPILER_SUPPORTS_MARCH_X86_V3)
if (COMPILER_SUPPORTS_MARCH_X86_V3)
message(STATUS "Enabling -march=x86-64-v3")
add_compile_options("-march=x86-64-v3")
else()
# Must be quite old so try -march=native.
check_cxx_compiler_flag("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE)
if (COMPILER_SUPPORTS_MARCH_NATIVE)
message(STATUS "Enabling -march=native")
add_compile_options("-march=native")
endif()
endif()

# This makes a measurable difference.
check_cxx_compiler_flag("-fomit-frame-pointer" COMPILER_SUPPORTS_FOMIT_FRAME_POINTER)
if (COMPILER_SUPPORTS_FOMIT_FRAME_POINTER)
message(STATUS "Enabling -fomit-frame-pointer")
add_compile_options("-fomit-frame-pointer")
endif()

# LTO
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
46 changes: 46 additions & 0 deletions cmake/modules/FindGMP.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# From https://github.com/Z3Prover/z3/blob/7f8e2a9f75f6c8b4b8ab05b87ea6a343d9a0b88d/cmake/modules/FindGMP.cmake
# with minor simplication to remove gmp++ and try pkg-config.

# Tries to find an install of the GNU multiple precision library
#
# Once done this will define
# GMP_FOUND - BOOL: System has the GMP library installed
# GMP_C_LIBRARIES - LIST: The libraries needed to use GMP via it's C interface
# GMP_C_INCLUDES - LIST: The GMP include directories

include(FindPackageHandleStandardArgs)

find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_GMP QUIET gmp)
endif()

# Try to find libraries
find_library(GMP_C_LIBRARIES
NAMES gmp
PATHS ${PC_GMP_LIBRARY_DIRS}
DOC "GMP C libraries"
)

# Try to find headers
find_path(GMP_C_INCLUDES
NAMES gmp.h
PATHS ${PC_GMP_INCLUDE_DIRS}
DOC "GMP C header"
)

# TODO: We should check we can link some simple code against libgmp

# Handle QUIET and REQUIRED and check the necessary variables were set and if so
# set ``GMP_FOUND``
find_package_handle_standard_args(GMP
REQUIRED_VARS GMP_C_LIBRARIES GMP_C_INCLUDES)

if (GMP_FOUND)
if (NOT TARGET GMP::GMP)
add_library(GMP::GMP UNKNOWN IMPORTED)
set_target_properties(GMP::GMP PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${GMP_C_INCLUDES}"
IMPORTED_LOCATION "${GMP_C_LIBRARIES}")
endif()
endif()
44 changes: 44 additions & 0 deletions dependencies/softfloat/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
SET(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/berkeley-softfloat-3")

# Generic source plus RISC-V specific source.
file(GLOB riscv_source
"${source_dir}/source/*.c"
"${source_dir}/source/include/*.h"
"${source_dir}/source/RISCV/*.c"
"${source_dir}/source/RISCV/*.h"
"${source_dir}/build/Linux-RISCV-GCC/platform.h"
)

# Some files do not work with SOFTFLOAT_FAST_INT64
list(REMOVE_ITEM riscv_source
"${source_dir}/source/s_addExtF80M.c"
"${source_dir}/source/s_addF128M.c"
"${source_dir}/source/s_compareNonnormExtF80M.c"
"${source_dir}/source/s_invalidF128M.c"
"${source_dir}/source/s_mulAddF128M.c"
"${source_dir}/source/s_normRoundPackMToExtF80M.c"
"${source_dir}/source/s_normRoundPackMToF128M.c"
"${source_dir}/source/s_normSubnormalF128SigM.c"
"${source_dir}/source/s_roundPackMToExtF80M.c"
"${source_dir}/source/s_roundPackMToF128M.c"
"${source_dir}/source/s_shiftLeftM.c"
"${source_dir}/source/s_shiftNormSigF128M.c"
"${source_dir}/source/s_shiftRightJamM.c"
"${source_dir}/source/s_shiftRightM.c"
"${source_dir}/source/s_tryPropagateNaNExtF80M.c"
"${source_dir}/source/s_tryPropagateNaNF128M.c"
"${source_dir}/source/RISCV/s_propagateNaNF128M.c"
"${source_dir}/source/RISCV/s_commonNaNToF128M.c"
)

add_library(softfloat
${riscv_source}
)

target_include_directories(softfloat PUBLIC
"${source_dir}/source/include"
"${source_dir}/source/RISCV"
"${source_dir}/build/Linux-RISCV-GCC"
)

target_compile_options(softfloat PRIVATE "-Werror=implicit-function-declaration" "-DSOFTFLOAT_ROUND_ODD")
44 changes: 44 additions & 0 deletions emulator/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
set(EMULATOR_COMMON_SRCS
riscv_config.h
riscv_platform.c
riscv_platform.h
riscv_platform_impl.c
riscv_platform_impl.h
riscv_prelude.c
riscv_prelude.h
riscv_sail.h
riscv_sim.c
riscv_softfloat.c
riscv_softfloat.h
)

foreach (arch IN LISTS ENABLED_ARCHITECTURES)
add_executable(emulator_${arch}
"${CMAKE_BINARY_DIR}/riscv_model_${arch}.c"
${EMULATOR_COMMON_SRCS}
)

add_dependencies(emulator_${arch} generated_model_${arch})

target_link_libraries(emulator_${arch}
PRIVATE softfloat sail_runtime GMP::GMP ZLIB::ZLIB
)

target_include_directories(emulator_${arch}
# So the generated C can find riscv_platform/prelude.h"
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}"
)

# TODO: Enable warnings when we use the #include trick
# to include the generated Sail code. Currently it
# generates too many warnings to turn these on globally.

# target_compile_options(emulator_${arch} PRIVATE
# -Wall -Wextra
# # Too annoying at the moment.
# -Wno-unused-parameter
# )

install(TARGETS emulator_${arch})

endforeach()
Loading

0 comments on commit bad1feb

Please sign in to comment.