Skip to content

Define the RISC-V 64 target contract - #334

Merged
LunaStev merged 3 commits into
wavefnd:masterfrom
LunaStev:feat/riscv64-target-contract
Aug 9, 2026
Merged

Define the RISC-V 64 target contract#334
LunaStev merged 3 commits into
wavefnd:masterfrom
LunaStev:feat/riscv64-target-contract

Conversation

@LunaStev

@LunaStev LunaStev commented Aug 9, 2026

Copy link
Copy Markdown
Member

Summary

  • define a validated RISC-V 64 target contract for Linux and freestanding builds
  • split parser and LLVM code generation architecture handling into dedicated modules
  • preserve target ISA and ABI metadata through LLVM IR and bitcode generation
  • harden inline assembly validation, register aliases, clobbers, reserved registers, and noreturn behavior
  • add C ABI wrappers for exported functions using large aggregate parameters or return values
  • isolate cross-target sysroots and runtimes, select the correct dynamic loader and CRT objects, and validate static and shared runtime inputs

Target contract

  • Linux RISC-V 64 defaults to RV64GC with the LP64D ABI
  • freestanding RISC-V 64 defaults to RV64IMAC with the LP64 ABI
  • incompatible target, ISA, ABI, code model, relocation model, and feature combinations are rejected with actionable diagnostics
  • static PIE selects rcrt1.o, while other link modes select the appropriate CRT and loader contract

Audit fixes

  • do not skip CRT objects merely because a static link has no dynamic loader
  • require libc.a and libm.a for static runtime validation
  • validate libc and libm for cross-target shared links as well as executable links
  • exercise aggregate export wrappers through internal calls in the regression suite

CI

  • add a named Build Linux riscv64 job on Ubuntu 24.04
  • cross-compile against an LP64D sysroot
  • execute the RISC-V Hello World artifact under QEMU
  • make Linux amd64, Linux riscv64, macOS arm64, and Windows amd64 job names consistent

Validation

  • cargo fmt --all -- --check
  • cargo test --locked
  • LLVM tests: 7 passed
  • parser tests: 3 passed
  • clippy with all targets and x86_64, AArch64, and RISC-V feature configurations
  • cargo build --locked --release
  • language suite: 96 passed, 12 skipped, 0 failed, 0 timed out
  • workflow YAML and shell syntax validation

Register riscv64-unknown-linux-gnu alongside the freestanding target and resolve effective CPU, ISA extensions, and LP64/LP64F/LP64D ABI settings before code generation. Apply the resolved ABI to LLVM target machines, expose the effective contract through target-spec and dry-run output, and preserve target CPU, features, ABI, and ISA metadata across LLVM IR and bitcode recompilation.

Separate parser and LLVM architecture logic into x86_64, AArch64, and RISC-V modules. Canonicalize architecture aliases for target attributes and centralize per-architecture CPU lists, feature sets, register aliases, inline-assembly dialects, clobbers, register widths, and stack/control-flow analysis.

Harden RISC-V inline assembly by rejecting zero, stack, global, and thread-pointer registers as value operands; supporting integer and floating-point ABI register aliases; accounting for all floating-point clobbers; recognizing non-returning jr, tail, ret, and jalr forms; requiring explicit stack and noreturn contracts; and reporting invalid assembly contracts as E3401 user diagnostics instead of internal compiler failures.

Add C ABI export wrappers so Wave implementations keep native internal signatures while exported RISC-V functions use byval and sret lowering for large aggregates. Marshal direct, split, by-value, and structure-return values between wrapper and implementation paths and verify internal calls through exported aggregate functions.

Make Linux cross-linking target-owned by selecting ABI-specific RISC-V loaders, preventing host CRT and generic library paths from leaking into cross builds, validating CRT ELF machine types, diagnosing incomplete sysroots, retaining CRT files for static links, requiring static archives in static mode, selecting rcrt1.o for static PIE, and avoiding dynamic loaders for static binaries.

Add regression coverage for target option matrices, hosted and freestanding defaults, ELF ABI flags, IR and bitcode target preservation, RISC-V inline assembly contracts, C aggregate export lowering, cross-runtime isolation, static link plans, architecture target attributes, and WaveOS cross-codegen behavior.

Add a Build Linux riscv64 GitHub Actions job that installs the RISC-V GNU sysroot and QEMU, runs the RISC-V contract tests, builds the release compiler, links an LP64D Linux executable, verifies its ELF machine, flags, and loader, and executes Hello World under qemu-riscv64 with a bounded timeout. Give every platform job a consistent OS and architecture name.
@LunaStev
LunaStev marked this pull request as ready for review August 9, 2026 06:38
Detect Debian-style cross-runtime prefixes whose libc or libm linker scripts reference prefix-qualified absolute paths. Keep Wave's target runtime discovery rooted in the requested prefix while passing the filesystem root to ld.lld, preventing the linker from prepending /usr/riscv64-linux-gnu twice to libc.so dependencies.

Add a synthetic RISC-V LP64D cross-prefix regression that provides target CRT objects and GNU linker scripts, verifies the effective linker sysroot, and confirms that target library search paths remain isolated to the cross runtime.

Make CRT path assertions accept both Unix separators and JSON-escaped Windows separators so the Windows amd64 Rust test no longer rejects a valid RISC-V static link plan.

Validated with cargo fmt, all Rust targets, default Clippy, and the RISC-V-only feature configuration with warnings denied.
Normalize path-fragment assertions against both literal paths and JSON-escaped Windows separators. Apply the shared matcher to the RISC-V runtime -L search-path assertion that failed on Windows despite the generated linker plan being correct.

Add a direct regression for a JSON-encoded Windows library search path and retain the existing Unix and Windows CRT path coverage.

Validated with cargo fmt, cargo test --locked --all-targets, and Clippy with warnings denied.
@LunaStev
LunaStev merged commit 6a14f20 into wavefnd:master Aug 9, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant