From a40fd0b5088544f604d092586eecbc9766ab51e7 Mon Sep 17 00:00:00 2001 From: ChinYikMing Date: Fri, 14 Feb 2025 02:38:35 +0800 Subject: [PATCH 1/6] Enable gcc-14 build rv_histogram on macOS/arm64 Error: Undefined symbols for architecture arm64: "_ebreak_handler", referenced from: lC0 in riscv.o "_ecall_handler", referenced from: lC0 in riscv.o "_log_impl", referenced from: _rv_create in riscv.o _rv_create in riscv.o _rv_create in riscv.o _rv_profile in riscv.o _rv_profile in riscv.o _rv_run in riscv.o "_log_level_string", referenced from: _rv_create in riscv.o "_log_set_level", referenced from: _rv_create in riscv.o "_log_set_stdout_stream", referenced from: _rv_remap_stdstream in riscv.o "_memcpy_handler", referenced from: lC0 in riscv.o "_memory_delete", referenced from: _rv_delete in riscv.o _rv_create in riscv.o "_memory_ifetch", referenced from: _on_mem_ifetch in riscv.o "_memory_new", referenced from: _rv_create in riscv.o "_memory_read_b", referenced from: _on_mem_read_b in riscv.o "_memory_read_s", referenced from: _on_mem_read_s in riscv.o "_memory_read_w", referenced from: _on_mem_read_w in riscv.o "_memory_write_b", referenced from: _on_mem_write_b in riscv.o "_memory_write_s", referenced from: _on_mem_write_s in riscv.o "_memory_write_w", referenced from: _on_mem_write_w in riscv.o "_memset_handler", referenced from: lC0 in riscv.o "_rv", referenced from: _rv_async_block_clear in riscv.o "_rv_step", referenced from: _rv_run in riscv.o _rv_run in riscv.o "_trap_handler", referenced from: lC0 in riscv.o ld: symbol(s) not found for architecture arm64 collect2: error: ld returned 1 exit status make: *** [build/rv_histogram] Error 1 Add emulate.o, syscall.o, syscall_sdl.o, io.o, and log.o objects and conditional build rv_async_block_clear() fixes the error and passes the build. --- mk/tools.mk | 11 ++++++++++- src/riscv.c | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/mk/tools.mk b/mk/tools.mk index aefe0bba6..0d6a2157f 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -1,6 +1,10 @@ HIST_BIN := $(OUT)/rv_histogram -# FIXME: riscv.o and map.o are dependencies of 'elf.o', not 'rv_histogram'. +# On macOS, gcc-14 requires linking symbols from emulate.o, syscall.o, syscall_sdl.o, io.o, and log.o. +# However, these symbols are not actually used in rv_histogram, they are only needed to pass the build. +# +# riscv.o and map.o are dependencies of 'elf.o', not 'rv_histogram'. But, they are also needed to pass +# the build. HIST_OBJS := \ riscv.o \ utils.o \ @@ -9,6 +13,11 @@ HIST_OBJS := \ decode.o \ mpool.o \ utils.o \ + emulate.o \ + syscall.o \ + syscall_sdl.o \ + io.o \ + log.o \ rv_histogram.o HIST_OBJS := $(addprefix $(OUT)/, $(HIST_OBJS)) diff --git a/src/riscv.c b/src/riscv.c index 1ddaf235c..4616f47cd 100644 --- a/src/riscv.c +++ b/src/riscv.c @@ -357,6 +357,7 @@ static void capture_keyboard_input() #endif +#if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER) /* * * atexit() registers void (*)(void) callbacks, so no parameters can be passed. @@ -375,6 +376,7 @@ static void rv_async_block_clear() return; #endif /* !RV32_HAS(JIT) */ } +#endif riscv_t *rv_create(riscv_user_t rv_attr) { @@ -383,8 +385,10 @@ riscv_t *rv_create(riscv_user_t rv_attr) riscv_t *rv = calloc(1, sizeof(riscv_t)); assert(rv); +#if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER) /* register cleaning callback for CTRL+a+x exit */ atexit(rv_async_block_clear); +#endif /* copy over the attr */ rv->data = rv_attr; From 9af41fa34f73d73c0241d87a9bbdf0cb607f39ae Mon Sep 17 00:00:00 2001 From: ChinYikMing Date: Fri, 14 Feb 2025 02:39:26 +0800 Subject: [PATCH 2/6] CI: Integrate macOS/arm64 Specify using gcc-14 instead of gcc (which typically points to the latest version of gcc) due to a macOS limitation in the rlalik/setup-cpp-compiler@master action. According to [1], each gcc must have specified version. Softfloat build warning error using gcc-14 with optimization flag O1: In file included from src/softfloat/source/include/internals.h:42, from src/softfloat/source/s_mulAddF64.c:40: In function 'softfloat_sub128', inlined from 'softfloat_mulAddF64' at src/softfloat/source/s_mulAddF64.c:185:17: src/softfloat/source/include/primitives.h:526:17: error: 'sig128C.v64' may be used uninitialized [-Werror=maybe-uninitialized] 526 | z.v64 = a64 - b64; | ~~~~^~~~~ src/softfloat/source/s_mulAddF64.c: In function 'softfloat_mulAddF64': src/softfloat/source/s_mulAddF64.c:66:20: note: 'sig128C.v64' was declared here 66 | struct uint128 sig128C; | ^~~~~~~ In function 'softfloat_sub128', inlined from 'softfloat_mulAddF64' at src/softfloat/source/s_mulAddF64.c:185:17: src/softfloat/source/include/primitives.h:527:18: error: 'sig128C.v0' may be used uninitialized [-Werror=maybe-uninitialized] 527 | z.v64 -= (a0 < b0); | ~~~~^~~~~ src/softfloat/source/s_mulAddF64.c: In function 'softfloat_mulAddF64': src/softfloat/source/s_mulAddF64.c:66:20: note: 'sig128C.v0' was declared here 66 | struct uint128 sig128C; Add -Wno-initialized to surpress them. Drop the undefined behavior test on macOS/arm64 using gcc-14, as its libsanitizer's configure.txt does not yet support it, check [2]. [1] https://github.com/rlalik/setup-cpp-compiler [2] https://github.com/iains/gcc-darwin-arm64/blob/master-wip-apple-si/ libsanitizer/configure.tgt Close #519 --- .github/workflows/main.yml | 108 +++++++++++++++++++++++++++++++++++++ mk/softfloat.mk | 1 + 2 files changed, 109 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c3e2f2dc1..40e122227 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -317,6 +317,114 @@ jobs: make ENABLE_JIT=1 clean && make ENABLE_EXT_F=0 ENABLE_JIT=1 check -j$(nproc) make ENABLE_JIT=1 clean && make ENABLE_EXT_C=0 ENABLE_JIT=1 check -j$(nproc) + macOS-arm64: + needs: [detect-code-related-file-changes] + if: needs.detect-code-related-file-changes.outputs.has_code_related_changes == 'true' + strategy: + fail-fast: false + matrix: + compiler: [gcc-14, clang] + runs-on: macos-latest # M1 chip + steps: + - uses: actions/checkout@v4 + - name: install-dependencies + run: | + brew install make dtc expect sdl2 sdl2_mixer bc e2fsprogs p7zip llvm@18 dcfldd + .ci/riscv-toolchain-install.sh + echo "${{ github.workspace }}/toolchain/bin" >> $GITHUB_PATH + - name: Install compiler + id: install_cc + uses: rlalik/setup-cpp-compiler@master + with: + compiler: ${{ matrix.compiler }} + - name: Symlink gcc-14 due to the default /usr/local/bin/gcc links to system's clang + run: | + ln -s /opt/homebrew/opt/gcc/bin/gcc-14 /usr/local/bin/gcc-14 + - name: fetch artifact first to reduce HTTP requests + env: + CC: ${{ steps.install_cc.outputs.cc }} + run: | + make artifact + make ENABLE_SYSTEM=1 artifact + make ENABLE_ARCH_TEST=1 artifact + if: ${{ always() }} + - name: check + tests + env: + CC: ${{ steps.install_cc.outputs.cc }} + run: | + make distclean + make check -j$(sysctl -n hw.logicalcpu) + make tests -j$(sysctl -n hw.logicalcpu) + make misalign -j$(sysctl -n hw.logicalcpu) + make tool -j$(sysctl -n hw.logicalcpu) + if: ${{ always() }} + - name: diverse configurations + env: + CC: ${{ steps.install_cc.outputs.cc }} + run: | + make distclean && make ENABLE_EXT_M=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_EXT_A=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_EXT_F=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_EXT_C=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_SDL=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_Zicsr=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_MOP_FUSION=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_BLOCK_CHAINING=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_Zba=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_Zbb=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_Zbc=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_Zbs=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_Zifencei=0 check -j$(sysctl -n hw.logicalcpu) + if: ${{ always() }} + - name: gdbstub test, need RV32 toolchain + env: + CC: ${{ steps.install_cc.outputs.cc }} + run: | + make distclean && make ENABLE_GDBSTUB=1 gdbstub-test -j$(sysctl -n hw.logicalcpu) + if: ${{ always() }} + - name: JIT test + env: + CC: ${{ steps.install_cc.outputs.cc }} + run: | + make ENABLE_JIT=1 clean && make ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_EXT_A=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_EXT_F=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_EXT_C=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_EXT_M=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_Zba=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_Zbb=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_Zbc=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_Zbs=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_Zicsr=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_Zifencei=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_MOP_FUSION=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_BLOCK_CHAINING=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + if: ${{ always() }} + - name: undefined behavior test + env: + CC: ${{ steps.install_cc.outputs.cc }} + if: ${{ env.CC == 'clang' && always() }} # gcc on macOS/arm64 does not support satinizers + run: | + make distclean && make ENABLE_UBSAN=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_JIT=1 ENABLE_UBSAN=1 check -j$(sysctl -n hw.logicalcpu) + - name: boot Linux kernel test + env: + CC: ${{ steps.install_cc.outputs.cc }} + run: | + make distclean && make INITRD_SIZE=32 ENABLE_SYSTEM=1 -j$(sysctl -n hw.logicalcpu) && \ + make ENABLE_SYSTEM=1 artifact -j$(sysctl -n hw.logicalcpu) + .ci/boot-linux.sh + make ENABLE_SYSTEM=1 clean + if: ${{ always() }} + - name: Architecture test + env: + CC: ${{ steps.install_cc.outputs.cc }} + run: | + python3 -m venv venv + . venv/bin/activate + .ci/riscv-tests.sh + if: ${{ always() }} + coding-style: needs: [detect-code-related-file-changes] if: needs.detect-code-related-file-changes.outputs.has_code_related_changes == 'true' diff --git a/mk/softfloat.mk b/mk/softfloat.mk index 77b38b1af..acc9a9e2f 100644 --- a/mk/softfloat.mk +++ b/mk/softfloat.mk @@ -6,6 +6,7 @@ CFLAGS_softfloat := \ -Wno-unused-variable \ -Wno-sign-compare \ -Wno-implicit-fallthrough \ + -Wno-uninitialized \ -I$(SOFTFLOAT_DIR)/RISCV \ -I$(SOFTFLOAT_DIR)/include From 285d210440764633f39da72b24832c325b82e89e Mon Sep 17 00:00:00 2001 From: ChinYikMing Date: Wed, 26 Feb 2025 23:35:23 +0800 Subject: [PATCH 3/6] CI: Add emcc build on macOS/arm64 --- .github/workflows/main.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 40e122227..c50ab5e00 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -337,6 +337,11 @@ jobs: uses: rlalik/setup-cpp-compiler@master with: compiler: ${{ matrix.compiler }} + - name: Setup emsdk + uses: mymindstorm/setup-emsdk@v14 + with: + version: 3.1.51 + actions-cache-folder: 'emsdk-cache' - name: Symlink gcc-14 due to the default /usr/local/bin/gcc links to system's clang run: | ln -s /opt/homebrew/opt/gcc/bin/gcc-14 /usr/local/bin/gcc-14 @@ -347,6 +352,23 @@ jobs: make artifact make ENABLE_SYSTEM=1 artifact make ENABLE_ARCH_TEST=1 artifact + # Hack Cloudflare 403 Forbidden on GitHub Runner for Doom artifact download + wget --header="User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15" \ + --header="Referer: https://www.doomworld.com/" \ + --header="Accept-Language: en-US,en;q=0.9" \ + -O build/shareware_doom_iwad.zip \ + "https://www.doomworld.com/3ddownloads/ports/shareware_doom_iwad.zip" + unzip -d build/ build/shareware_doom_iwad.zip + if: ${{ always() }} + - name: default build using emcc + run: | + make CC=emcc -j$(sysctl -n hw.logicalcpu) + if: ${{ always() }} + - name: default build for system emulation using emcc + run: | + make distclean + make CC=emcc ENABLE_SYSTEM=1 -j$(sysctl -n hw.logicalcpu) + make distclean ENABLE_SYSTEM=1 if: ${{ always() }} - name: check + tests env: From e58bb3064fdda2cf8e891fa26594f33d09d02c8a Mon Sep 17 00:00:00 2001 From: ChinYikMing Date: Wed, 26 Feb 2025 23:36:28 +0800 Subject: [PATCH 4/6] CI: Shorten the statement with PARALLEL variable --- .github/workflows/main.yml | 202 +++++++++++++++++++------------------ 1 file changed, 106 insertions(+), 96 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c50ab5e00..310e0535a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -63,6 +63,9 @@ jobs: with: version: 3.1.51 actions-cache-folder: 'emsdk-cache' + - name: Set parallel jobs variable + run: | + echo "PARALLEL=-j$(nproc)" >> $GITHUB_ENV - name: fetch artifact first to reduce HTTP requests env: CC: ${{ steps.install_cc.outputs.cc }} @@ -80,12 +83,12 @@ jobs: if: ${{ always() }} - name: default build using emcc run: | - make CC=emcc -j$(nproc) + make CC=emcc $PARALLEL if: ${{ always() }} - name: default build for system emulation using emcc run: | make distclean - make CC=emcc ENABLE_SYSTEM=1 -j$(nproc) + make CC=emcc ENABLE_SYSTEM=1 $PARALLEL make distclean ENABLE_SYSTEM=1 if: ${{ always() }} - name: default build with -g @@ -93,175 +96,175 @@ jobs: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-g -j$(nproc) + make OPT_LEVEL=-g $PARALLEL if: ${{ always() }} - name: default build with -Og env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-Og -j$(nproc) + make OPT_LEVEL=-Og $PARALLEL if: ${{ always() }} - name: default build with -O0 env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-O0 -j$(nproc) + make OPT_LEVEL=-O0 $PARALLEL if: ${{ always() }} - name: default build with -O1 env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-O1 -j$(nproc) + make OPT_LEVEL=-O1 $PARALLEL if: ${{ always() }} - name: default build with -O2 env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-O2 -j$(nproc) + make OPT_LEVEL=-O2 $PARALLEL if: ${{ always() }} - name: default build with -O3 env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-O3 -j$(nproc) + make OPT_LEVEL=-O3 $PARALLEL if: ${{ always() }} - name: default build with -Ofast env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-Ofast -j$(nproc) + make OPT_LEVEL=-Ofast $PARALLEL if: ${{ always() }} - name: default build for system emulation with -g env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-g ENABLE_SYSTEM=1 -j$(nproc) + make OPT_LEVEL=-g ENABLE_SYSTEM=1 $PARALLEL if: ${{ always() }} - name: default build for system emulation with -Og env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-Og ENABLE_SYSTEM=1 -j$(nproc) + make OPT_LEVEL=-Og ENABLE_SYSTEM=1 $PARALLEL if: ${{ always() }} - name: default build for system emulation with -O0 env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-O0 ENABLE_SYSTEM=1 -j$(nproc) + make OPT_LEVEL=-O0 ENABLE_SYSTEM=1 $PARALLEL if: ${{ always() }} - name: default build for system emulation with -O1 env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-O1 ENABLE_SYSTEM=1 -j$(nproc) + make OPT_LEVEL=-O1 ENABLE_SYSTEM=1 $PARALLEL if: ${{ always() }} - name: default build for system emulation with -O2 env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-O2 ENABLE_SYSTEM=1 -j$(nproc) + make OPT_LEVEL=-O2 ENABLE_SYSTEM=1 $PARALLEL if: ${{ always() }} - name: default build for system emulation with -O3 env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-O3 ENABLE_SYSTEM=1 -j$(nproc) + make OPT_LEVEL=-O3 ENABLE_SYSTEM=1 $PARALLEL if: ${{ always() }} - name: default build for system emulation with -Ofast env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make OPT_LEVEL=-Ofast ENABLE_SYSTEM=1 -j$(nproc) + make OPT_LEVEL=-Ofast ENABLE_SYSTEM=1 $PARALLEL if: ${{ always() }} - name: check + tests env: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make check -j$(nproc) - make tests -j$(nproc) - make misalign -j$(nproc) - make tool -j$(nproc) + make check $PARALLEL + make tests $PARALLEL + make misalign $PARALLEL + make tool $PARALLEL if: ${{ always() }} - name: diverse configurations env: CC: ${{ steps.install_cc.outputs.cc }} run: | - make distclean && make ENABLE_EXT_M=0 check -j$(nproc) - make distclean && make ENABLE_EXT_A=0 check -j$(nproc) - make distclean && make ENABLE_EXT_F=0 check -j$(nproc) - make distclean && make ENABLE_EXT_C=0 check -j$(nproc) - make distclean && make ENABLE_SDL=0 check -j$(nproc) - make distclean && make ENABLE_Zicsr=0 check -j$(nproc) - make distclean && make ENABLE_MOP_FUSION=0 check -j$(nproc) - make distclean && make ENABLE_BLOCK_CHAINING=0 check -j$(nproc) - make distclean && make ENABLE_Zba=0 check -j$(nproc) - make distclean && make ENABLE_Zbb=0 check -j$(nproc) - make distclean && make ENABLE_Zbc=0 check -j$(nproc) - make distclean && make ENABLE_Zbs=0 check -j$(nproc) - make distclean && make ENABLE_Zifencei=0 check -j$(nproc) + make distclean && make ENABLE_EXT_M=0 check $PARALLEL + make distclean && make ENABLE_EXT_A=0 check $PARALLEL + make distclean && make ENABLE_EXT_F=0 check $PARALLEL + make distclean && make ENABLE_EXT_C=0 check $PARALLEL + make distclean && make ENABLE_SDL=0 check $PARALLEL + make distclean && make ENABLE_Zicsr=0 check $PARALLEL + make distclean && make ENABLE_MOP_FUSION=0 check $PARALLEL + make distclean && make ENABLE_BLOCK_CHAINING=0 check $PARALLEL + make distclean && make ENABLE_Zba=0 check $PARALLEL + make distclean && make ENABLE_Zbb=0 check $PARALLEL + make distclean && make ENABLE_Zbc=0 check $PARALLEL + make distclean && make ENABLE_Zbs=0 check $PARALLEL + make distclean && make ENABLE_Zifencei=0 check $PARALLEL if: ${{ always() }} - name: misalignment test in block emulation env: CC: ${{ steps.install_cc.outputs.cc }} run: | make -C tests/system/alignment/ - make distclean && make ENABLE_ELF_LOADER=1 ENABLE_EXT_C=0 ENABLE_SYSTEM=1 misalign-in-blk-emu -j$(nproc) + make distclean && make ENABLE_ELF_LOADER=1 ENABLE_EXT_C=0 ENABLE_SYSTEM=1 misalign-in-blk-emu $PARALLEL if: ${{ always() }} - name: MMU test env: CC: ${{ steps.install_cc.outputs.cc }} run: | make -C tests/system/mmu/ - make distclean && make ENABLE_ELF_LOADER=1 ENABLE_SYSTEM=1 mmu-test -j$(nproc) + make distclean && make ENABLE_ELF_LOADER=1 ENABLE_SYSTEM=1 mmu-test $PARALLEL if: ${{ always() }} - name: gdbstub test env: CC: ${{ steps.install_cc.outputs.cc }} run: | - make distclean && make ENABLE_GDBSTUB=1 gdbstub-test -j$(nproc) + make distclean && make ENABLE_GDBSTUB=1 gdbstub-test $PARALLEL if: ${{ always() }} - name: JIT test env: CC: ${{ steps.install_cc.outputs.cc }} run: | - make ENABLE_JIT=1 clean && make ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_EXT_A=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_EXT_F=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_EXT_C=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_EXT_M=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_Zba=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_Zbb=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_Zbc=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_Zbs=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_Zicsr=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_Zifencei=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_MOP_FUSION=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_BLOCK_CHAINING=0 ENABLE_JIT=1 check -j$(nproc) + make ENABLE_JIT=1 clean && make ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_A=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_F=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_C=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_M=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zba=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zbb=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zbc=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zbs=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zicsr=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zifencei=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_MOP_FUSION=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_BLOCK_CHAINING=0 ENABLE_JIT=1 check $PARALLEL if: ${{ always() }} - name: undefined behavior test run: | - make distclean && make ENABLE_UBSAN=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_JIT=1 ENABLE_UBSAN=1 check -j$(nproc) + make distclean && make ENABLE_UBSAN=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_JIT=1 ENABLE_UBSAN=1 check $PARALLEL if: ${{ always() }} - name: boot Linux kernel test env: CC: ${{ steps.install_cc.outputs.cc }} run: | - make distclean && make INITRD_SIZE=32 ENABLE_SYSTEM=1 -j$(nproc) && make ENABLE_SYSTEM=1 artifact -j$(nproc) + make distclean && make INITRD_SIZE=32 ENABLE_SYSTEM=1 $PARALLEL && make ENABLE_SYSTEM=1 artifact $PARALLEL .ci/boot-linux.sh make ENABLE_SYSTEM=1 clean if: ${{ always() }} @@ -269,7 +272,7 @@ jobs: env: CC: ${{ steps.install_cc.outputs.cc }} run: | - make distclean && make INITRD_SIZE=32 ENABLE_SYSTEM=1 ENABLE_JIT=1 ENABLE_T2C=0 ENABLE_MOP_FUSION=0 -j$(nproc) && make ENABLE_SYSTEM=1 artifact -j$(nproc) + make distclean && make INITRD_SIZE=32 ENABLE_SYSTEM=1 ENABLE_JIT=1 ENABLE_T2C=0 ENABLE_MOP_FUSION=0 $PARALLEL && make ENABLE_SYSTEM=1 artifact $PARALLEL .ci/boot-linux.sh make ENABLE_SYSTEM=1 ENABLE_JIT=1 ENABLE_T2C=0 ENABLE_MOP_FUSION=0 clean if: ${{ always() }} @@ -287,6 +290,9 @@ jobs: steps: - name: checkout code uses: actions/checkout@v4 + - name: Set parallel jobs variable + run: | + echo "PARALLEL=-j$(nproc)" >> $GITHUB_ENV - name: build artifact # The GitHub Action for non-x86 CPU uses: allinurl/run-on-arch-action@master @@ -307,15 +313,16 @@ jobs: # FIXME: gcc build fails on Aarch64/Linux hosts env: | CC: clang-18 + PARALLEL: ${{ env.PARALLEL }} # Append custom commands here run: | make artifact - make -j$(nproc) - make check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_EXT_A=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_EXT_F=0 ENABLE_JIT=1 check -j$(nproc) - make ENABLE_JIT=1 clean && make ENABLE_EXT_C=0 ENABLE_JIT=1 check -j$(nproc) + make $PARALLEL + make check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_A=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_F=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_C=0 ENABLE_JIT=1 check $PARALLEL macOS-arm64: needs: [detect-code-related-file-changes] @@ -342,6 +349,9 @@ jobs: with: version: 3.1.51 actions-cache-folder: 'emsdk-cache' + - name: Set parallel jobs variable + run: | + echo "PARALLEL=-j$(sysctl -n hw.logicalcpu)" >> $GITHUB_ENV - name: Symlink gcc-14 due to the default /usr/local/bin/gcc links to system's clang run: | ln -s /opt/homebrew/opt/gcc/bin/gcc-14 /usr/local/bin/gcc-14 @@ -362,12 +372,12 @@ jobs: if: ${{ always() }} - name: default build using emcc run: | - make CC=emcc -j$(sysctl -n hw.logicalcpu) + make CC=emcc $PARALLEL if: ${{ always() }} - name: default build for system emulation using emcc run: | make distclean - make CC=emcc ENABLE_SYSTEM=1 -j$(sysctl -n hw.logicalcpu) + make CC=emcc ENABLE_SYSTEM=1 $PARALLEL make distclean ENABLE_SYSTEM=1 if: ${{ always() }} - name: check + tests @@ -375,66 +385,66 @@ jobs: CC: ${{ steps.install_cc.outputs.cc }} run: | make distclean - make check -j$(sysctl -n hw.logicalcpu) - make tests -j$(sysctl -n hw.logicalcpu) - make misalign -j$(sysctl -n hw.logicalcpu) - make tool -j$(sysctl -n hw.logicalcpu) + make check $PARALLEL + make tests $PARALLEL + make misalign $PARALLEL + make tool $PARALLEL if: ${{ always() }} - name: diverse configurations env: CC: ${{ steps.install_cc.outputs.cc }} run: | - make distclean && make ENABLE_EXT_M=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_EXT_A=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_EXT_F=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_EXT_C=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_SDL=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_Zicsr=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_MOP_FUSION=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_BLOCK_CHAINING=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_Zba=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_Zbb=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_Zbc=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_Zbs=0 check -j$(sysctl -n hw.logicalcpu) - make distclean && make ENABLE_Zifencei=0 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_EXT_M=0 check $PARALLEL + make distclean && make ENABLE_EXT_A=0 check $PARALLEL + make distclean && make ENABLE_EXT_F=0 check $PARALLEL + make distclean && make ENABLE_EXT_C=0 check $PARALLEL + make distclean && make ENABLE_SDL=0 check $PARALLEL + make distclean && make ENABLE_Zicsr=0 check $PARALLEL + make distclean && make ENABLE_MOP_FUSION=0 check $PARALLEL + make distclean && make ENABLE_BLOCK_CHAINING=0 check $PARALLEL + make distclean && make ENABLE_Zba=0 check $PARALLEL + make distclean && make ENABLE_Zbb=0 check $PARALLEL + make distclean && make ENABLE_Zbc=0 check $PARALLEL + make distclean && make ENABLE_Zbs=0 check $PARALLEL + make distclean && make ENABLE_Zifencei=0 check $PARALLEL if: ${{ always() }} - name: gdbstub test, need RV32 toolchain env: CC: ${{ steps.install_cc.outputs.cc }} run: | - make distclean && make ENABLE_GDBSTUB=1 gdbstub-test -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_GDBSTUB=1 gdbstub-test $PARALLEL if: ${{ always() }} - name: JIT test env: CC: ${{ steps.install_cc.outputs.cc }} run: | - make ENABLE_JIT=1 clean && make ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_EXT_A=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_EXT_F=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_EXT_C=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_EXT_M=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_Zba=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_Zbb=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_Zbc=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_Zbs=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_Zicsr=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_Zifencei=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_MOP_FUSION=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_BLOCK_CHAINING=0 ENABLE_JIT=1 check -j$(sysctl -n hw.logicalcpu) + make ENABLE_JIT=1 clean && make ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_A=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_F=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_C=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_EXT_M=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zba=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zbb=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zbc=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zbs=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zicsr=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_Zifencei=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_MOP_FUSION=0 ENABLE_JIT=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_BLOCK_CHAINING=0 ENABLE_JIT=1 check $PARALLEL if: ${{ always() }} - name: undefined behavior test env: CC: ${{ steps.install_cc.outputs.cc }} if: ${{ env.CC == 'clang' && always() }} # gcc on macOS/arm64 does not support satinizers run: | - make distclean && make ENABLE_UBSAN=1 check -j$(sysctl -n hw.logicalcpu) - make ENABLE_JIT=1 clean && make ENABLE_JIT=1 ENABLE_UBSAN=1 check -j$(sysctl -n hw.logicalcpu) + make distclean && make ENABLE_UBSAN=1 check $PARALLEL + make ENABLE_JIT=1 clean && make ENABLE_JIT=1 ENABLE_UBSAN=1 check $PARALLEL - name: boot Linux kernel test env: CC: ${{ steps.install_cc.outputs.cc }} run: | - make distclean && make INITRD_SIZE=32 ENABLE_SYSTEM=1 -j$(sysctl -n hw.logicalcpu) && \ - make ENABLE_SYSTEM=1 artifact -j$(sysctl -n hw.logicalcpu) + make distclean && make INITRD_SIZE=32 ENABLE_SYSTEM=1 $PARALLEL && \ + make ENABLE_SYSTEM=1 artifact $PARALLEL .ci/boot-linux.sh make ENABLE_SYSTEM=1 clean if: ${{ always() }} From 878676aff8d1c893b7770ae21a7b68fc8bdf3a98 Mon Sep 17 00:00:00 2001 From: Meng-Hung Chen Date: Fri, 28 Feb 2025 02:37:27 +0800 Subject: [PATCH 5/6] jit: Suppress compiler error on macOS/arm64 unused function 'emit_dataproc_3source' [-Werror,-Wunused-function] --- src/jit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/jit.c b/src/jit.c index 61b7821aa..42ecf59a3 100644 --- a/src/jit.c +++ b/src/jit.c @@ -570,6 +570,7 @@ static void emit_dataproc_2source(struct jit_state *state, } +#if RV32_HAS(EXT_M) /* [ARM-A]: C4.1.67: Data-processing (3 source). */ static void emit_dataproc_3source(struct jit_state *state, bool is64, @@ -582,6 +583,7 @@ static void emit_dataproc_3source(struct jit_state *state, emit_a64(state, sz(is64) | op | (rm << 16) | (ra << 10) | (rn << 5) | rd); set_dirty(rd, true); } +#endif static void update_branch_imm(struct jit_state *state, uint32_t offset, From ad16cd8112c43a2ba23cf32d06300636e1022826 Mon Sep 17 00:00:00 2001 From: ChinYikMing Date: Wed, 26 Feb 2025 23:39:52 +0800 Subject: [PATCH 6/6] CI: Fix failure when fetching latest release tag on macOS/arm64 Refer to [1] and [2], leveraging ${{ secrets.GITHUB_TOKEN }} to be authenticated which increases the Github API request rate limit. [1] https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#primary-rate-limit-for-github_token-in-github-actions [2] https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#getting-a-higher-rate-limit --- .github/workflows/main.yml | 24 +++++++++++++++++++++--- mk/artifact.mk | 27 ++++++++++++++++----------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 310e0535a..7a4fbd528 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -359,9 +359,27 @@ jobs: env: CC: ${{ steps.install_cc.outputs.cc }} run: | - make artifact - make ENABLE_SYSTEM=1 artifact - make ENABLE_ARCH_TEST=1 artifact + LATEST_RELEASE=$(wget --header="Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -q \ + https://api.github.com/repos/sysprog21/rv32emu-prebuilt/releases -O- \ + | grep '"tag_name"' \ + | grep "ELF" \ + | head -n 1 \ + | sed -E 's/.*"tag_name": "([^"]+)".*/\1/') + make LATEST_RELEASE=$LATEST_RELEASE artifact + LATEST_RELEASE=$(wget --header="Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -q \ + https://api.github.com/repos/sysprog21/rv32emu-prebuilt/releases -O- \ + | grep '"tag_name"' \ + | grep "Linux-Image" \ + | head -n 1 \ + | sed -E 's/.*"tag_name": "([^"]+)".*/\1/') + make LATEST_RELEASE=$LATEST_RELEASE ENABLE_SYSTEM=1 artifact + LATEST_RELEASE=$(wget --header="Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -q \ + https://api.github.com/repos/sysprog21/rv32emu-prebuilt/releases -O- \ + | grep '"tag_name"' \ + | grep "sail" \ + | head -n 1 \ + | sed -E 's/.*"tag_name": "([^"]+)".*/\1/') + make LATEST_RELEASE=$LATEST_RELEASE ENABLE_ARCH_TEST=1 artifact # Hack Cloudflare 403 Forbidden on GitHub Runner for Doom artifact download wget --header="User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15" \ --header="Referer: https://www.doomworld.com/" \ diff --git a/mk/artifact.mk b/mk/artifact.mk index 0af8ea83b..db4936e19 100644 --- a/mk/artifact.mk +++ b/mk/artifact.mk @@ -43,25 +43,30 @@ define fetch-releases-tag $(if $(wildcard $(BIN_DIR)/$(2)), \ $(info $(call warnx, $(3) is found. Skipping downloading.)), \ $(eval LATEST_RELEASE := $(shell wget -q https://api.github.com/repos/sysprog21/rv32emu-prebuilt/releases -O- \ - | grep '"tag_name"' \ - | grep "$(1)" \ - | head -n 1 \ - | sed -E 's/.*"tag_name": "([^"]+)".*/\1/')) \ + | grep '"tag_name"' \ + | grep "$(1)" \ + | head -n 1 \ + | sed -E 's/.*"tag_name": "([^"]+)".*/\1/')) \ $(if $(LATEST_RELEASE),, \ $(error Fetching tag of latest releases failed) \ ) \ ) endef +LATEST_RELEASE ?= + ifeq ($(call has, PREBUILT), 1) - ifeq ($(call has, SYSTEM), 1) - $(call fetch-releases-tag,Linux-Image,rv32emu-linux-image-prebuilt.tar.gz,Linux image) - else ifeq ($(call has, ARCH_TEST), 1) - $(call fetch-releases-tag,sail,rv32emu-prebuilt-sail-$(HOST_PLATFORM),Sail model) - else - $(call fetch-releases-tag,ELF,rv32emu-prebuilt.tar.gz,Prebuilt blob) + # On macOS/arm64 Github runner, let's leverage the ${{ secrets.GITHUB_TOKEN }} to prevent 403 rate limit error. + # Thus, the LATEST_RELEASE tag is defined at Github job steps, no need to fetch them here. + ifeq ($(LATEST_RELEASE),) + ifeq ($(call has, SYSTEM), 1) + $(call fetch-releases-tag,Linux-Image,rv32emu-linux-image-prebuilt.tar.gz,Linux image) + else ifeq ($(call has, ARCH_TEST), 1) + $(call fetch-releases-tag,sail,rv32emu-prebuilt-sail-$(HOST_PLATFORM),Sail model) + else + $(call fetch-releases-tag,ELF,rv32emu-prebuilt.tar.gz,Prebuilt benchmark) + endif endif - PREBUILT_BLOB_URL = https://github.com/sysprog21/rv32emu-prebuilt/releases/download/$(LATEST_RELEASE) else # Since rv32emu only supports the dynamic binary translation of integer instruction in tiered compilation currently,