Skip to content

Draft: RISCV-NCG

Moritz Angermann requested to merge wip/angerman/riscv64-ncg into master

This is my WIP of a RISCV NCG. Based mostly on the AArch64 NCG. The biggest issue I have with his, is that it just screams for some better refactoring, some generic RISC like superclass from which AArch64, and RV64G borrow.

  • Rebased this on ghc-9.6 release branch
  • Brought back the aarch64 test-suite (still needs work)
  • built with
    hadrian/build --build-root=_quick  -j --flavour=quick+no_dynamic_ghc+llvm+native_bignum+no_profiled_libs
  • test with
    EXTRA_HC_OPTS='-fasm' ./hadrian/build --build-root=_quick  -j --flavour=quick+no_dynamic_ghc+llvm+native_bignum+no_profiled_libs  test --test-compiler=$PWD/_quick/stage1/bin/riscv64-unknown-linux-gnu-ghc --docs=none --verbose --test-way=vanilla

quite a bit is still missing, but it can compile Hello World, while linking against the LLVM compiled libraries (e.g.

$ cat <<EOF > Main.hs
main = putStrLn "Hello RiscV NCG!"
EOF
$ _quick/ghc-stage1 -fasm Main.hs 
[1 of 2] Compiling Main             ( Main.hs, Main.o )
[2 of 2] Linking Main
$ qemu-riscv64 Main
Hello RiscV NCG!

So what's missing (from the top of my head):

  • no support for floats at all yet, code is there (aarch64), but that won't work for riscv.
  • lots of misassumptions about riscv carried over from aarch64.
  • Test Suite summary shows a lot of holes
    SUMMARY for test run started at Sun Apr 30 13:44:57 2023 
    3:24:02.808092 spent to go through
      9282 total tests, which gave rise to
     36083 test cases, of which
     27252 were skipped
         7 had missing libraries
    
      5709 expected passes
       767 expected failures
    
        15 caused framework failures
         0 caused framework warnings
        56 unexpected passes
      2267 unexpected failures
         0 unexpected stat failures
        16 fragile tests
    (biggest annoyance, #21292; still can't run test-suite against some EXEC_WRAPPER=qmeu-riscv64). as @TerrorJack has pointed out, this is export CROSS_EMULATOR=qemu-riscv64.
  • Linker/Relocator for riscv64-elf completely missing. The spec isn't so bad, but I think we should try to write the linker in Haskell instead of C. This likely will make it easier/faster/... the C linker is a mess. We could refactor it and try to improve, but I think Haskell would be much better here.
  • Performance is abysmal. There are lots of things we could do (and some that would even benefit AArch64).
  • Compressed (C) instructions might be helpful for performance. So would likely stripping unnecessary stack pointer bumps, and stupid loads. This would ideally be a post-processing phase, and one that AArch64 could also use to transform LDR/LDR into LDP (double register loads to load pair instructions; same for store). It might also allow for some instruction optimisation.
  • We blow on registers, and use way way to much data moving around.
  • The whole atomic situation needs to be rethought, as RISCV requires us to do some looping with acquire and conditional sets.
Edited by Moritz Angermann

Merge request reports