6
votes

I want to compile a simple program "int main(){return 0;}" to RISC-V processor. LLVM/Clang version is 9.0 and I want to run the compiled program with a RISC-V simulator like this https://github.com/riscv/riscv-tools

My problem is that I can't list the clang supported targets only the LLC-s whith these commands:

llc --version
llc -march=xxARCHTYPExx -mattr=help

And there is no any type of riscv processor listed.

So I tried to look the triple file: llvm-project\llvm\include\llvm\ADT\Triple.h

and try a command like: clang hello.c -target riscv32 -march=rv32imafd

But I get the following error:

error: unable to create target: 'No available targets are compatible with triple "riscv32"'

Can somebody help me to how get a valid RISC-V target? I just simple can't compile the program but I know LLVM has a RISC-V support.

1
The LLVM source code has RISC-V support, but that doesn't mean that your compiled version has that target enabled. cmake -DDLLVM_TARGETS_TO_BUILD=all . gives you a version of LLVM that supports all targets.arnt
I tried this command and get the following error when CMake is finished: CMake Warning: Manually-specified variables were not used by the project: DLLVM_TARGETS_TO_BUILD According to this webpage the default is "all" if I don't specify the target: llvm.org/docs/CMake.htmlZoltán
The problem was with -DDLLVM_TARGETS_TO_BUILD=all The correct is -DLLVM_TARGETS_TO_BUILD=all But the original problem is still on.Zoltán
I'm able to build with these options: cmake -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="RISCV" -DLLVM_USE_LINKER=gold -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON ../llvm But when I want to create a runnable program: clang hello.c --target=riscv64 -march=rv64i -c -o hello.o ld.lld hello.o -o hello It will create a runnable but it seems the instruction are missing inside the file. So it will not work.Zoltán
Maybe I found the answer in here: llvm.org/docs/WritingAnLLVMBackend.html "The document focuses on existing examples found in subdirectories of llvm/lib/Target in a downloaded LLVM release. In particular, this document focuses on the example of creating a static compiler (one that emits text assembly) for a SPARC target, because SPARC has fairly standard characteristics, such as a RISC instruction set and straightforward calling conventions." So it will only generate an assembly not a runnable...Zoltán

1 Answers

6
votes

LLVM 9 release notes explicitly state that RISC-V support was promoted from experimental to official.

And indeed, on my Fedora 31 machine, the LLVM 9 Fedora package does support RISC-V:

$ llvm-objdump --version | grep riscv
    riscv32    - 32-bit RISC-V
    riscv64    - 64-bit RISC-V

Also, I can create RISC-V binary code with the LLVM toolchain:

$ clang --target=riscv64 -march=rv64gc rotate.s -c -o rotate.o
$ file rotate.o
rotate.o: ELF 64-bit LSB relocatable, UCB RISC-V, version 1 (SYSV), not stripped

Although it doesn't include a libc for RISC-V targets:

$ clang --target=riscv64 -march=rv64gc hello-world.c -o hello-world
hello-world.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
         ^~~~~~~~~
1 error generated.

However, you don't really need one - you could directly call syscalls for your hello world, e.g.:

$ clang  --target=riscv64 -march=rv64gc  hello.s -c -o hello.o
$ ld.lld hello.o -o hello
$ spike --isa=RV64gc ~/local/riscv/pk/riscv64-unknown-elf/bin/pk ./hello
bbl loader
Hello World

I don't use clang for linking because it seems that I can't convince clang with -fuse-ld to use another linker besides /usr/bin/ld.