mirror of
https://github.com/GerbilSoft/zlib-ng.git
synced 2025-06-18 11:35:35 -04:00
Add supporting RISC-V cross compilation workflows
Add RISC-V cross-compilation test Enable RVV support at compile time
This commit is contained in:
parent
9087c75f8d
commit
c3cdf434f3
14
.github/workflows/cmake.yml
vendored
14
.github/workflows/cmake.yml
vendored
@ -378,6 +378,12 @@ jobs:
|
|||||||
# https://github.com/llvm/llvm-project/issues/55785
|
# https://github.com/llvm/llvm-project/issues/55785
|
||||||
msan-options: use_sigaltstack=0
|
msan-options: use_sigaltstack=0
|
||||||
|
|
||||||
|
- name: Ubuntu Clang RISC-V
|
||||||
|
os: ubuntu-latest
|
||||||
|
cmake-args: -GNinja -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain-riscv.cmake -DTOOLCHAIN_PATH=${PWD}/prebuilt-riscv-toolchain-qemu/riscv-clang -DQEMU_PATH=${PWD}/prebuilt-riscv-toolchain-qemu/riscv-qemu/bin/qemu-riscv64
|
||||||
|
packages: build-essential cmake ninja-build
|
||||||
|
codecov: ubuntu_clang_toolchain_riscv
|
||||||
|
|
||||||
- name: Ubuntu Emscripten WASM32
|
- name: Ubuntu Emscripten WASM32
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
chost: wasm32
|
chost: wasm32
|
||||||
@ -502,6 +508,14 @@ jobs:
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y --allow-downgrades --no-install-recommends ${{ matrix.packages }}
|
sudo apt-get install -y --allow-downgrades --no-install-recommends ${{ matrix.packages }}
|
||||||
|
|
||||||
|
- name: Download prebuilt RISC-V Clang toolchain & QEMU emulator
|
||||||
|
if: runner.os == 'Linux' && contains(matrix.name, 'RISC-V')
|
||||||
|
run: |
|
||||||
|
gh release download ubuntu20.04_llvm16.0.0_qemu7.0.0 --repo sifive/prepare-riscv-toolchain-qemu
|
||||||
|
tar zxvf prebuilt-riscv-toolchain-qemu.tar.gz
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Install packages (Windows)
|
- name: Install packages (Windows)
|
||||||
if: runner.os == 'Windows'
|
if: runner.os == 'Windows'
|
||||||
run: |
|
run: |
|
||||||
|
@ -105,6 +105,8 @@ elseif(BASEARCH_PPC_FOUND)
|
|||||||
option(WITH_ALTIVEC "Build with AltiVec (VMX) optimisations for PowerPC" ON)
|
option(WITH_ALTIVEC "Build with AltiVec (VMX) optimisations for PowerPC" ON)
|
||||||
option(WITH_POWER8 "Build with optimisations for POWER8" ON)
|
option(WITH_POWER8 "Build with optimisations for POWER8" ON)
|
||||||
option(WITH_POWER9 "Build with optimisations for POWER9" ON)
|
option(WITH_POWER9 "Build with optimisations for POWER9" ON)
|
||||||
|
elseif(BASEARCH_RISCV_FOUND)
|
||||||
|
option(WITH_RVV "Build with RVV intrinsics" ON)
|
||||||
elseif(BASEARCH_S360_FOUND)
|
elseif(BASEARCH_S360_FOUND)
|
||||||
option(WITH_DFLTCC_DEFLATE "Build with DFLTCC intrinsics for compression on IBM Z" OFF)
|
option(WITH_DFLTCC_DEFLATE "Build with DFLTCC intrinsics for compression on IBM Z" OFF)
|
||||||
option(WITH_DFLTCC_INFLATE "Build with DFLTCC intrinsics for decompression on IBM Z" OFF)
|
option(WITH_DFLTCC_INFLATE "Build with DFLTCC intrinsics for decompression on IBM Z" OFF)
|
||||||
@ -135,6 +137,7 @@ mark_as_advanced(FORCE
|
|||||||
WITH_ALTIVEC
|
WITH_ALTIVEC
|
||||||
WITH_POWER8
|
WITH_POWER8
|
||||||
WITH_POWER9
|
WITH_POWER9
|
||||||
|
WITH_RVV
|
||||||
WITH_INFLATE_STRICT
|
WITH_INFLATE_STRICT
|
||||||
WITH_INFLATE_ALLOW_INVALID_DIST
|
WITH_INFLATE_ALLOW_INVALID_DIST
|
||||||
WITH_UNALIGNED
|
WITH_UNALIGNED
|
||||||
@ -544,6 +547,8 @@ if(BASEARCH_ARM_FOUND)
|
|||||||
set(ARCHDIR "arch/arm")
|
set(ARCHDIR "arch/arm")
|
||||||
elseif(BASEARCH_PPC_FOUND)
|
elseif(BASEARCH_PPC_FOUND)
|
||||||
set(ARCHDIR "arch/power")
|
set(ARCHDIR "arch/power")
|
||||||
|
elseif(BASEARCH_RISCV_FOUND)
|
||||||
|
set(ARCHDIR "arch/riscv")
|
||||||
elseif(BASEARCH_S360_FOUND)
|
elseif(BASEARCH_S360_FOUND)
|
||||||
set(ARCHDIR "arch/s390")
|
set(ARCHDIR "arch/s390")
|
||||||
elseif(BASEARCH_X86_FOUND)
|
elseif(BASEARCH_X86_FOUND)
|
||||||
@ -718,6 +723,18 @@ if(WITH_OPTIM)
|
|||||||
set(WITH_POWER9 OFF)
|
set(WITH_POWER9 OFF)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
elseif(BASEARCH_RISCV_FOUND)
|
||||||
|
if(WITH_RVV)
|
||||||
|
check_rvv_intrinsics()
|
||||||
|
if(HAVE_RVV_INTRIN)
|
||||||
|
add_definitions(-DRISCV_FEATURES)
|
||||||
|
add_definitions(-DRISCV_RVV)
|
||||||
|
list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/riscv_features.h)
|
||||||
|
list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/riscv_features.c)
|
||||||
|
else()
|
||||||
|
set(WITH_RVV OFF)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
elseif(BASEARCH_S360_FOUND)
|
elseif(BASEARCH_S360_FOUND)
|
||||||
check_s390_intrinsics()
|
check_s390_intrinsics()
|
||||||
if(HAVE_S390_INTRIN)
|
if(HAVE_S390_INTRIN)
|
||||||
@ -1228,6 +1245,8 @@ elseif(BASEARCH_PPC_FOUND)
|
|||||||
add_feature_info(WITH_ALTIVEC WITH_ALTIVEC "Build with AltiVec optimisations")
|
add_feature_info(WITH_ALTIVEC WITH_ALTIVEC "Build with AltiVec optimisations")
|
||||||
add_feature_info(WITH_POWER8 WITH_POWER8 "Build with optimisations for POWER8")
|
add_feature_info(WITH_POWER8 WITH_POWER8 "Build with optimisations for POWER8")
|
||||||
add_feature_info(WITH_POWER9 WITH_POWER9 "Build with optimisations for POWER9")
|
add_feature_info(WITH_POWER9 WITH_POWER9 "Build with optimisations for POWER9")
|
||||||
|
elseif(BASEARCH_RISCV_FOUND)
|
||||||
|
add_feature_info(WITH_RVV WITH_RVV "Build with RVV intrinsics")
|
||||||
elseif(BASEARCH_S360_FOUND)
|
elseif(BASEARCH_S360_FOUND)
|
||||||
add_feature_info(WITH_DFLTCC_DEFLATE WITH_DFLTCC_DEFLATE "Build with DFLTCC intrinsics for compression on IBM Z")
|
add_feature_info(WITH_DFLTCC_DEFLATE WITH_DFLTCC_DEFLATE "Build with DFLTCC intrinsics for compression on IBM Z")
|
||||||
add_feature_info(WITH_DFLTCC_INFLATE WITH_DFLTCC_INFLATE "Build with DFLTCC intrinsics for decompression on IBM Z")
|
add_feature_info(WITH_DFLTCC_INFLATE WITH_DFLTCC_INFLATE "Build with DFLTCC intrinsics for decompression on IBM Z")
|
||||||
|
@ -34,7 +34,7 @@ Features
|
|||||||
* Comprehensive set of CMake unit tests
|
* Comprehensive set of CMake unit tests
|
||||||
* Code sanitizers, fuzzing, and coverage
|
* Code sanitizers, fuzzing, and coverage
|
||||||
* GitHub Actions continuous integration on Windows, macOS, and Linux
|
* GitHub Actions continuous integration on Windows, macOS, and Linux
|
||||||
* Emulated CI for ARM, AARCH64, PPC, PPC64, SPARC64, S390x using qemu
|
* Emulated CI for ARM, AARCH64, PPC, PPC64, RISCV, SPARC64, S390x using qemu
|
||||||
|
|
||||||
|
|
||||||
History
|
History
|
||||||
@ -221,6 +221,7 @@ Advanced Build Options
|
|||||||
| WITH_NEON | --without-neon | Build with NEON intrinsics | ON |
|
| WITH_NEON | --without-neon | Build with NEON intrinsics | ON |
|
||||||
| WITH_ALTIVEC | --without-altivec | Build with AltiVec (VMX) intrinsics | ON |
|
| WITH_ALTIVEC | --without-altivec | Build with AltiVec (VMX) intrinsics | ON |
|
||||||
| WITH_POWER8 | --without-power8 | Build with POWER8 optimisations | ON |
|
| WITH_POWER8 | --without-power8 | Build with POWER8 optimisations | ON |
|
||||||
|
| WITH_RVV | | Build with RVV intrinsics | ON |
|
||||||
| WITH_CRC32_VX | --without-crc32-vx | Build with vectorized CRC32 on IBM Z | ON |
|
| WITH_CRC32_VX | --without-crc32-vx | Build with vectorized CRC32 on IBM Z | ON |
|
||||||
| WITH_DFLTCC_DEFLATE | --with-dfltcc-deflate | Build with DFLTCC intrinsics for compression on IBM Z | OFF |
|
| WITH_DFLTCC_DEFLATE | --with-dfltcc-deflate | Build with DFLTCC intrinsics for compression on IBM Z | OFF |
|
||||||
| WITH_DFLTCC_INFLATE | --with-dfltcc-inflate | Build with DFLTCC intrinsics for decompression on IBM Z | OFF |
|
| WITH_DFLTCC_INFLATE | --with-dfltcc-inflate | Build with DFLTCC intrinsics for decompression on IBM Z | OFF |
|
||||||
|
45
arch/riscv/README.md
Normal file
45
arch/riscv/README.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Building RISC-V Target with Cmake #
|
||||||
|
|
||||||
|
> **Warning**
|
||||||
|
> We cannot detect rvv support at runtime, running the rvv code on a no-rvv target is a risk. Users should disable the rvv when the target does not support it.
|
||||||
|
>
|
||||||
|
> We will have a better solution when the kernels update `hwcap` or `hwprobe` for risc-v.
|
||||||
|
|
||||||
|
## Prerequisite: Build RISC-V Clang Toolchain and QEMU ##
|
||||||
|
|
||||||
|
If you don't have prebuilt clang and riscv64 qemu, you can refer to the [script](https://github.com/sifive/prepare-riscv-toolchain-qemu/blob/main/prepare_riscv_toolchain_qemu.sh) to get the source. Copy the script to the zlib-ng root directory, and run it to download the source and build them. Modify the content according to your conditions (e.g., toolchain version).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./prepare_riscv_toolchain_qemu.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
After running script, clang & qemu are built in `build-toolchain-qemu/riscv-clang/` & `build-toolchain-qemu/riscv-qemu/`.
|
||||||
|
|
||||||
|
`build-toolchain-qemu/riscv-clang/` is your `TOOLCHAIN_PATH`.
|
||||||
|
`build-toolchain-qemu/riscv-qemu/bin/qemu-riscv64` is your `QEMU_PATH`.
|
||||||
|
|
||||||
|
You can also download the prebuilt toolchain & qemu from [the release page](https://github.com/sifive/prepare-riscv-toolchain-qemu/releases), and enjoy using them.
|
||||||
|
|
||||||
|
## Cross-Compile for RISC-V Target ##
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake -G Ninja -B ./build-riscv \
|
||||||
|
-D CMAKE_TOOLCHAIN_FILE=./cmake/toolchain-riscv.cmake \
|
||||||
|
-D CMAKE_INSTALL_PREFIX=./build-riscv/install \
|
||||||
|
-D TOOLCHAIN_PATH={TOOLCHAIN_PATH} \
|
||||||
|
-D QEMU_PATH={QEMU_PATH} \
|
||||||
|
.
|
||||||
|
|
||||||
|
cmake --build ./build-riscv
|
||||||
|
```
|
||||||
|
|
||||||
|
Disable the option if there is no RVV support:
|
||||||
|
```
|
||||||
|
-D WITH_RVV=OFF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run Unittests on User Mode QEMU ##
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ./build-riscv && ctest --verbose
|
||||||
|
```
|
15
arch/riscv/riscv_features.c
Normal file
15
arch/riscv/riscv_features.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../../zbuild.h"
|
||||||
|
#include "riscv_features.h"
|
||||||
|
|
||||||
|
/* TODO: detect risc-v cpu info at runtime when the kernel updates hwcap or hwprobe for risc-v */
|
||||||
|
void Z_INTERNAL riscv_check_features(struct riscv_cpu_features *features) {
|
||||||
|
#if defined(__riscv_v) && defined(__linux__)
|
||||||
|
features->has_rvv = 1;
|
||||||
|
#else
|
||||||
|
features->has_rvv = 0;
|
||||||
|
#endif
|
||||||
|
}
|
18
arch/riscv/riscv_features.h
Normal file
18
arch/riscv/riscv_features.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/* riscv_features.h -- check for riscv features.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SiFive, Inc. All rights reserved.
|
||||||
|
* Contributed by Alex Chiang <alex.chiang@sifive.com>
|
||||||
|
*
|
||||||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RISCV_H_
|
||||||
|
#define RISCV_H_
|
||||||
|
|
||||||
|
struct riscv_cpu_features {
|
||||||
|
int has_rvv;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Z_INTERNAL riscv_check_features(struct riscv_cpu_features *features);
|
||||||
|
|
||||||
|
#endif /* RISCV_H_ */
|
@ -347,6 +347,24 @@ macro(check_power8_intrinsics)
|
|||||||
set(CMAKE_REQUIRED_FLAGS)
|
set(CMAKE_REQUIRED_FLAGS)
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
|
macro(check_rvv_intrinsics)
|
||||||
|
if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||||
|
if(NOT NATIVEFLAG)
|
||||||
|
set(RISCVFLAG "-march=rv64gcv")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
# Check whether compiler supports RVV
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "${RISCVFLAG} ${NATIVEFLAG}")
|
||||||
|
check_c_source_compiles(
|
||||||
|
"#include <riscv_vector.h>
|
||||||
|
int main() {
|
||||||
|
return 0;
|
||||||
|
}"
|
||||||
|
HAVE_RVV_INTRIN
|
||||||
|
)
|
||||||
|
set(CMAKE_REQUIRED_FLAGS)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
macro(check_s390_intrinsics)
|
macro(check_s390_intrinsics)
|
||||||
check_c_source_compiles(
|
check_c_source_compiles(
|
||||||
"#include <sys/auxv.h>
|
"#include <sys/auxv.h>
|
||||||
|
28
cmake/toolchain-riscv.cmake
Normal file
28
cmake/toolchain-riscv.cmake
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
set(CMAKE_CROSSCOMPILING TRUE)
|
||||||
|
set(CMAKE_SYSTEM_NAME "Linux")
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR "riscv64")
|
||||||
|
|
||||||
|
# Avoid to use system path for cross-compile
|
||||||
|
set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH FALSE)
|
||||||
|
|
||||||
|
set(TOOLCHAIN_PATH "" CACHE STRING "The toolchain path.")
|
||||||
|
if(NOT TOOLCHAIN_PATH)
|
||||||
|
set(TOOLCHAIN_PATH ${CMAKE_SOURCE_DIR}/prebuilt-riscv-toolchain-qemu/riscv-clang)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(TOOLCHAIN_PREFIX "riscv64-unknown-linux-gnu-" CACHE STRING "The toolchain prefix.")
|
||||||
|
set(QEMU_PATH "" CACHE STRING "The qemu path.")
|
||||||
|
if(NOT QEMU_PATH)
|
||||||
|
set(QEMU_PATH ${CMAKE_SOURCE_DIR}/prebuilt-riscv-toolchain-qemu/riscv-qemu/bin/qemu-riscv64)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# toolchain setting
|
||||||
|
set(CMAKE_C_COMPILER "${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX}clang")
|
||||||
|
set(CMAKE_CXX_COMPILER "${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX}clang++")
|
||||||
|
|
||||||
|
# disable auto-vectorizer
|
||||||
|
add_compile_options(-fno-vectorize -fno-slp-vectorize)
|
||||||
|
|
||||||
|
# emulator setting
|
||||||
|
set(QEMU_CPU_OPTION "rv64,zba=true,zbb=true,zbc=true,zbs=true,v=true,vlen=512,elen=64,vext_spec=v1.0")
|
||||||
|
set(CMAKE_CROSSCOMPILING_EMULATOR ${QEMU_PATH} -cpu ${QEMU_CPU_OPTION} -L ${TOOLCHAIN_PATH}/sysroot/)
|
@ -17,5 +17,7 @@ Z_INTERNAL void cpu_check_features(struct cpu_features *features) {
|
|||||||
power_check_features(&features->power);
|
power_check_features(&features->power);
|
||||||
#elif defined(S390_FEATURES)
|
#elif defined(S390_FEATURES)
|
||||||
s390_check_features(&features->s390);
|
s390_check_features(&features->s390);
|
||||||
|
#elif defined(RISCV_FEATURES)
|
||||||
|
riscv_check_features(&features->riscv);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
# include "arch/power/power_features.h"
|
# include "arch/power/power_features.h"
|
||||||
#elif defined(S390_FEATURES)
|
#elif defined(S390_FEATURES)
|
||||||
# include "arch/s390/s390_features.h"
|
# include "arch/s390/s390_features.h"
|
||||||
|
#elif defined(RISCV_FEATURES)
|
||||||
|
# include "arch/riscv/riscv_features.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct cpu_features {
|
struct cpu_features {
|
||||||
@ -29,6 +31,8 @@ struct cpu_features {
|
|||||||
struct power_cpu_features power;
|
struct power_cpu_features power;
|
||||||
#elif defined(S390_FEATURES)
|
#elif defined(S390_FEATURES)
|
||||||
struct s390_cpu_features s390;
|
struct s390_cpu_features s390;
|
||||||
|
#elif defined(RISCV_FEATURES)
|
||||||
|
struct riscv_cpu_features riscv;
|
||||||
#else
|
#else
|
||||||
char empty;
|
char empty;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user