From d4ca337e6b8d0c268ebce5c4b5fbe9015f3d8ab6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 18 Jul 2019 11:45:37 -0400 Subject: [PATCH] improvements to riscv support --- src/codegen.cpp | 18 +++++++++++++++++- src/link.cpp | 6 ++++-- src/target.cpp | 19 ++++++++++++++++++- src/target.hpp | 2 ++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 188c5ccc8d..7136429615 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8390,13 +8390,13 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa } } + // According to Rich Felker libc headers are supposed to go before C language headers. for (size_t i = 0; i < g->libc_include_dir_len; i += 1) { Buf *include_dir = g->libc_include_dir_list[i]; args.append("-isystem"); args.append(buf_ptr(include_dir)); } - // According to Rich Felker libc headers are supposed to go before C language headers. args.append("-isystem"); args.append(buf_ptr(g->zig_c_headers_dir)); @@ -8405,6 +8405,21 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa } else { args.append("-target"); args.append(buf_ptr(&g->llvm_triple_str)); + + if (target_is_musl(g->zig_target) && target_is_riscv(g->zig_target)) { + // Musl depends on atomic instructions, which are disabled by default in Clang/LLVM's + // cross compilation CPU info for RISCV. + switch (g->zig_target->arch) { + case ZigLLVM_riscv32: + args.append("-march=rv32ia"); + break; + case ZigLLVM_riscv64: + args.append("-march=rv64ia"); + break; + default: + zig_unreachable(); + } + } } if (g->zig_target->os == OsFreestanding) { args.append("-ffreestanding"); @@ -8474,6 +8489,7 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { args.append(g->clang_argv[arg_i]); } + } void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation) { diff --git a/src/link.cpp b/src/link.cpp index 88267f6cac..a7cb9ad26f 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1658,7 +1658,9 @@ static void construct_linker_job_elf(LinkJob *lj) { crt1o = "Scrt1.o"; } lj->args.append(get_libc_crt_file(g, crt1o)); - lj->args.append(get_libc_crt_file(g, "crti.o")); + if (target_libc_needs_crti_crtn(g->zig_target)) { + lj->args.append(get_libc_crt_file(g, "crti.o")); + } } for (size_t i = 0; i < g->rpath_list.length; i += 1) { @@ -1791,7 +1793,7 @@ static void construct_linker_job_elf(LinkJob *lj) { } // crt end - if (lj->link_in_crt) { + if (lj->link_in_crt && target_libc_needs_crti_crtn(g->zig_target)) { lj->args.append(get_libc_crt_file(g, "crtn.o")); } diff --git a/src/target.cpp b/src/target.cpp index fd5deeea29..05eb3c662f 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -1739,8 +1739,25 @@ const char *target_arch_musl_name(ZigLLVM_ArchType arch) { } bool target_supports_libunwind(const ZigTarget *target) { - if (target->arch == ZigLLVM_arm || target->arch == ZigLLVM_armeb) { + switch (target->arch) { + case ZigLLVM_arm: + case ZigLLVM_armeb: + case ZigLLVM_riscv32: + case ZigLLVM_riscv64: + return false; + default: + return true; + } + return true; +} + +bool target_libc_needs_crti_crtn(const ZigTarget *target) { + if (target->arch == ZigLLVM_riscv32 || target->arch == ZigLLVM_riscv64) { return false; } return true; } + +bool target_is_riscv(const ZigTarget *target) { + return target->arch == ZigLLVM_riscv32 || target->arch == ZigLLVM_riscv64; +} diff --git a/src/target.hpp b/src/target.hpp index 85768347a5..a8c0c890eb 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -186,6 +186,7 @@ bool target_abi_is_musl(ZigLLVM_EnvironmentType abi); bool target_is_glibc(const ZigTarget *target); bool target_is_musl(const ZigTarget *target); bool target_is_wasm(const ZigTarget *target); +bool target_is_riscv(const ZigTarget *target); bool target_is_android(const ZigTarget *target); bool target_is_single_threaded(const ZigTarget *target); bool target_supports_stack_probing(const ZigTarget *target); @@ -197,5 +198,6 @@ uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch); size_t target_libc_count(void); void target_libc_enum(size_t index, ZigTarget *out_target); +bool target_libc_needs_crti_crtn(const ZigTarget *target); #endif