Skip to content
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
65 changes: 65 additions & 0 deletions .nanvix/dejagnu/baseboards/nanvix-sim.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# DejaGnu board file for Nanvix targets (i686-nanvix, x86_64-nanvix).
#
# This board enables running GCC's testsuite against the Nanvix cross-compiler.
# - Compile-only tests work without a simulator.
# - Execution tests use nanvixd.elf via the nanvix-sim-run wrapper script.
#
# Usage:
# make check-gcc RUNTESTFLAGS="--target_board=nanvix-sim"
#
# Environment variables:
# NANVIX_INSTALL_DIR - Path to the Nanvix toolchain install directory
# (default: /opt/nanvix)

load_generic_config "sim"
load_base_board_description "basic-sim"

process_multilib_options ""

# Compiler is found automatically when testing GCC in-tree.
set_board_info compiler "[find_gcc]"

# Resolve install directory from environment or use default.
if {[info exists ::env(NANVIX_INSTALL_DIR)]} {
set nanvix_install $::env(NANVIX_INSTALL_DIR)
} else {
set nanvix_install "/opt/nanvix"
}

# Use newlib include/link flags from the build tree if available.
set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"

# Link flags for execution tests. Compile-only tests (dg-do compile) never link,
# so these only apply to dg-do run/link tests.
# Note: This board is configured for a single target at a time (i686-nanvix OR
# x86_64-nanvix). The toolchain is built per-target, so the sysroot artifacts in
# ${nanvix_install}/lib/ match the configured target. Multilib is disabled
# (--disable-multilib in the GCC configure step).
set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags] -T ${nanvix_install}/lib/user.ld -Wl,--start-group ${nanvix_install}/lib/libposix.a -lc -Wl,--end-group"
Comment thread
ppenna marked this conversation as resolved.

# Simulator configuration: use the nanvix-sim-run wrapper.
# The wrapper script must be on PATH or specified as an absolute path.
if {[info exists ::env(NANVIX_SIM_RUN)]} {
set_board_info sim $::env(NANVIX_SIM_RUN)
} else {
set_board_info sim "${nanvix_install}/libexec/nanvixd/nanvix-sim-run"
}

# Time limit for program execution (seconds).
set_board_info sim_time_limit 60

# Target capabilities and limitations.
set_board_info is_simulator 1
set_board_info slow_simulator 1
# No command-line argument support.
set_board_info noargs 1
# No signal support.
set_board_info gcc,nosignals 1
set_board_info gcc,signal_suppress 1
# No file I/O support beyond stdout.
set_board_info gcc,no_abs 1
# Compilation timeout (seconds).
set_board_info gcc,timeout 300
# The simulator does not return exit status via the process exit code;
# DejaGnu must link a status wrapper that prints exit status to stdout.
set_board_info needs_status_wrapper 1
65 changes: 65 additions & 0 deletions .nanvix/dejagnu/nanvix-sim-run
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/bin/bash
#
# nanvix-sim-run — DejaGnu simulator wrapper for Nanvix.
#
# This script adapts nanvixd.elf to the interface DejaGnu expects:
# nanvix-sim-run <binary>
#
# It runs the given ELF binary on nanvixd and passes through stdout/stderr.
# Exit code: 0 if nanvixd ran the program successfully, non-zero otherwise.
#
# Environment variables:
# NANVIX_INSTALL_DIR - Path to the Nanvix toolchain install (default: /opt/nanvix)
# NANVIX_SIM_TIMEOUT - Timeout in seconds (default: 30)
# NANVIX_SIM_LOG_DIR - Directory for nanvixd diagnostic logs (default: /tmp)

set -euo pipefail

NANVIX_INSTALL_DIR="${NANVIX_INSTALL_DIR:-/opt/nanvix}"
NANVIX_SIM_TIMEOUT="${NANVIX_SIM_TIMEOUT:-30}"
NANVIX_SIM_LOG_DIR="${NANVIX_SIM_LOG_DIR:-/tmp}"

nanvixd="${NANVIX_INSTALL_DIR}/libexec/nanvixd/nanvixd.elf"
bin_dir="${NANVIX_INSTALL_DIR}/libexec/nanvixd"

if [[ $# -lt 1 ]]; then
echo "Usage: nanvix-sim-run <binary>" >&2
exit 1
fi

binary="$1"
shift

if [[ ! -f "${binary}" ]]; then
echo "ERROR: Binary not found: ${binary}" >&2
exit 1
fi

if [[ ! -x "${nanvixd}" ]]; then
echo "ERROR: nanvixd.elf not found at '${nanvixd}'." >&2
exit 1
fi

if ! command -v timeout >/dev/null 2>&1; then
echo "ERROR: 'timeout' utility not available." >&2
exit 1
fi

# Log nanvixd diagnostics to a separate file rather than discarding them;
# the test program's stderr is passed through so DejaGnu can inspect it.
nanvixd_log="${NANVIX_SIM_LOG_DIR}/nanvix-sim-run.$$.log"

# Run the binary on nanvixd with a kill signal fallback.
# Use --foreground so nanvixd receives signals properly in a pipeline.
timeout --foreground -k 5 "${NANVIX_SIM_TIMEOUT}" \
"${nanvixd}" \
-bin-dir "${bin_dir}" \
-console-file /dev/stdout \
-- "${binary}" </dev/null 2>"${nanvixd_log}"
rc=$?

if [[ $rc -eq 124 ]]; then
echo "NANVIX-SIM-TIMEOUT: Program exceeded ${NANVIX_SIM_TIMEOUT}s time limit." >&2
fi

exit $rc
11 changes: 11 additions & 0 deletions .nanvix/dejagnu/site.exp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# DejaGnu site configuration for Nanvix GCC testing.
#
# This file is sourced by DejaGnu via the DEJAGNU environment variable.
# It sets up the board search path so that the nanvix-sim board file is found.
#
# Usage:
# export DEJAGNU=/path/to/this/site.exp
# make check-gcc RUNTESTFLAGS="--target_board=nanvix-sim compile.exp"

# Add the Nanvix board directory to the search path.
lappend boards_dir "@NANVIX_BOARDS_DIR@"
123 changes: 123 additions & 0 deletions z
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,16 @@ test_steps() {
echo "Skipping integration test: /dev/kvm not available."
fi

# Run GCC compile-only torture tests to validate code generation (opt-in).
if [[ "${Z_RUN_TORTURE:-0}" == "1" ]]; then
check_steps "compile" || {
print_error "GCC testsuite failed."
return 1
}
else
echo "Skipping GCC torture tests (set Z_RUN_TORTURE=1 to enable)."
fi

return 0
}

Expand Down Expand Up @@ -568,6 +578,119 @@ verify_steps() {
return 0
}

#
# Description
#
# Runs GCC's built-in testsuite (compile-only torture tests) against the
# Nanvix cross-compiler to validate code generation.
#
# Parameters
#
# - $1 (optional): Test suite to run. One of:
# "compile" - compile-only torture tests (default)
# "execute" - execution tests via nanvixd (requires /dev/kvm)
# "all" - both compile and execute
#
# Return Value
#
# - On success, this function returns zero.
# - On failure, this function returns non-zero.
#
check_steps() {
local suite="${1:-compile}"
local build_dir="${PROJECT_DIR}/${Z_PROJECT_BUILD_DIR}"
local dejagnu_dir="${PROJECT_DIR}/.nanvix/dejagnu"
local install_location="${Z_INSTALL_LOCATION}"

# Verify build directory exists.
if [[ ! -d "${build_dir}/gcc" ]]; then
print_error "Build directory not found. Run './z build' first."
return 1
fi

# Generate site.exp from template.
local site_exp="${build_dir}/nanvix-site.exp"
sed "s|@NANVIX_BOARDS_DIR@|${dejagnu_dir}/baseboards|g" \
"${dejagnu_dir}/site.exp.in" > "${site_exp}"

# Install the simulator wrapper if the target directory is writable.
local sim_run="${install_location}/libexec/nanvixd/nanvix-sim-run"
if [[ -d "${install_location}/libexec/nanvixd" ]]; then
if [[ -w "${install_location}/libexec/nanvixd" ]]; then
install -m 755 "${dejagnu_dir}/nanvix-sim-run" "${sim_run}"
else
print_warning "Cannot install sim wrapper to '${install_location}/libexec/nanvixd/' (permission denied). Using source copy."
sim_run="${dejagnu_dir}/nanvix-sim-run"
fi
fi

local runtestflags="--target_board=nanvix-sim"
local -a make_targets=()

case "${suite}" in
compile)
echo "Running GCC compile-only torture tests..."
runtestflags="${runtestflags} compile.exp"
make_targets=("check-gcc")
;;
execute)
if [[ ! -w /dev/kvm ]]; then
print_error "/dev/kvm not available; execution tests require KVM."
return 1
fi
echo "Running GCC execution tests via nanvixd..."
runtestflags="${runtestflags} execute.exp"
make_targets=("check-gcc")
;;
all)
echo "Running GCC full testsuite (compile + execute)..."
make_targets=("check-gcc")
if [[ ! -w /dev/kvm ]]; then
print_error "/dev/kvm not available; execute suite cannot run."
return 1
fi
;;
*)
print_error "Unknown test suite '${suite}'. Use: compile, execute, or all."
return 1
;;
esac

# Run from the build directory with scoped environment variables.
pushd "${build_dir}" > /dev/null
DEJAGNU="${site_exp}" NANVIX_INSTALL_DIR="${install_location}" NANVIX_SIM_RUN="${sim_run}" \
make "${make_targets[@]}" RUNTESTFLAGS="${runtestflags}" || {
print_error "GCC testsuite failed."
popd > /dev/null
return 1
}
popd > /dev/null

# Print summary from the .sum file if available.
# Note: make check-gcc returns 0 even on test failures; we must parse
# the summary file for unexpected failures to detect regressions.
local sum_file="${build_dir}/gcc/testsuite/gcc/gcc.sum"
if [[ -f "${sum_file}" ]]; then
echo ""
echo "=== Test Summary ==="
grep -E "^# of (expected|unexpected)" "${sum_file}" || true
Comment thread
ppenna marked this conversation as resolved.

# Fail if there are unexpected failures or errors.
local unexpected
unexpected=$(grep -c "^# of unexpected failures" "${sum_file}" 2>/dev/null || echo "0")
if [[ "$unexpected" -gt 0 ]]; then
local fail_count
fail_count=$(grep "^# of unexpected failures" "${sum_file}" | awk '{print $NF}')
if [[ "${fail_count:-0}" -gt 0 ]]; then
print_error "GCC testsuite reported ${fail_count} unexpected failure(s)."
return 1
fi
fi
fi

return 0
}

#==================================================================================================
# Main Script
#==================================================================================================
Expand Down
Loading