diff --git a/src/codegen.cpp b/src/codegen.cpp index c9e67dcac5..ed8fcf54d7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8940,10 +8940,24 @@ static void init(CodeGen *g) { fprintf(stderr, "name=%s target_specific_cpu_args=%s\n", buf_ptr(g->root_out_name), target_specific_cpu_args); fprintf(stderr, "name=%s target_specific_features=%s\n", buf_ptr(g->root_out_name), target_specific_features); } + + // TODO handle float ABI better- it should depend on the ABI portion of std.Target + ZigLLVMABIType float_abi = ZigLLVMABITypeDefault; + + // TODO a way to override this as part of std.Target ABI? + const char *abi_name = nullptr; + if (target_is_riscv(g->zig_target)) { + // RISC-V Linux defaults to ilp32d/lp64d + if (g->zig_target->os == OsLinux) { + abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32d" : "lp64d"; + } else { + abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32" : "lp64"; + } + } g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str), target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, - to_llvm_code_model(g), g->function_sections); + to_llvm_code_model(g), g->function_sections, float_abi, abi_name); g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine); diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 5569f90cdc..e5b9df625c 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -100,7 +100,7 @@ static const bool assertions_on = false; LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, - LLVMCodeModel CodeModel, bool function_sections) + LLVMCodeModel CodeModel, bool function_sections, ZigLLVMABIType float_abi, const char *abi_name) { Optional RM; switch (Reloc){ @@ -147,6 +147,21 @@ LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Tri TargetOptions opt; opt.FunctionSections = function_sections; + switch (float_abi) { + case ZigLLVMABITypeDefault: + opt.FloatABIType = FloatABI::Default; + break; + case ZigLLVMABITypeSoft: + opt.FloatABIType = FloatABI::Soft; + break; + case ZigLLVMABITypeHard: + opt.FloatABIType = FloatABI::Hard; + break; + } + + if (abi_name != nullptr) { + opt.MCOptions.ABIName = abi_name; + } TargetMachine *TM = reinterpret_cast(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM, OL, JIT); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index c2c4b4dd77..f07684f2a4 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -51,9 +51,16 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi bool is_small, bool time_report, const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename); + +enum ZigLLVMABIType { + ZigLLVMABITypeDefault, // Target-specific (either soft or hard depending on triple, etc). + ZigLLVMABITypeSoft, // Soft float. + ZigLLVMABITypeHard // Hard float. +}; + ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, - LLVMCodeModel CodeModel, bool function_sections); + LLVMCodeModel CodeModel, bool function_sections, ZigLLVMABIType float_abi, const char *abi_name); ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); diff --git a/test/tests.zig b/test/tests.zig index 9ada899b1b..6861270792 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -160,15 +160,14 @@ const test_targets = blk: { }, }, - // https://github.com/ziglang/zig/issues/4863 - //TestTarget{ - // .target = .{ - // .cpu_arch = .riscv64, - // .os_tag = .linux, - // .abi = .musl, - // }, - // .link_libc = true, - //}, + TestTarget{ + .target = .{ + .cpu_arch = .riscv64, + .os_tag = .linux, + .abi = .musl, + }, + .link_libc = true, + }, // https://github.com/ziglang/zig/issues/3340 //TestTarget{