| author | |
| committer | |
| log | 11b50e3ad8781fd600961e80aad622c6f5616acc |
| tree | 1fc2c1d26b41b40f4e18a0c5b2e4e3d795e83787 |
| parent | 203d6554b1e54e06aa28cbcfa74596911cd60b4c |
Before, this would cause a link failure when mixing Zig and C code for
RISC-V targets.
Now, the ABIs match and Zig and C code can be mixed successfully.
I will file a follow-up issue for the ability to deal more explicitly
with ABIs.
closes #48634 files changed, 47 insertions(+), 12 deletions(-)
src/codegen.cpp+15-1| ... | ... | @@ -8940,10 +8940,24 @@ static void init(CodeGen *g) { |
| 8940 | 8940 | fprintf(stderr, "name=%s target_specific_cpu_args=%s\n", buf_ptr(g->root_out_name), target_specific_cpu_args); |
| 8941 | 8941 | fprintf(stderr, "name=%s target_specific_features=%s\n", buf_ptr(g->root_out_name), target_specific_features); |
| 8942 | 8942 | } |
| 8943 | ||
| 8944 | // TODO handle float ABI better- it should depend on the ABI portion of std.Target | |
| 8945 | ZigLLVMABIType float_abi = ZigLLVMABITypeDefault; | |
| 8946 | ||
| 8947 | // TODO a way to override this as part of std.Target ABI? | |
| 8948 | const char *abi_name = nullptr; | |
| 8949 | if (target_is_riscv(g->zig_target)) { | |
| 8950 | // RISC-V Linux defaults to ilp32d/lp64d | |
| 8951 | if (g->zig_target->os == OsLinux) { | |
| 8952 | abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32d" : "lp64d"; | |
| 8953 | } else { | |
| 8954 | abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32" : "lp64"; | |
| 8955 | } | |
| 8956 | } | |
| 8943 | 8957 | |
| 8944 | 8958 | g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str), |
| 8945 | 8959 | target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, |
| 8946 | to_llvm_code_model(g), g->function_sections); | |
| 8960 | to_llvm_code_model(g), g->function_sections, float_abi, abi_name); | |
| 8947 | 8961 | |
| 8948 | 8962 | g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine); |
| 8949 | 8963 |
src/zig_llvm.cpp+16-1| ... | ... | @@ -100,7 +100,7 @@ static const bool assertions_on = false; |
| 100 | 100 | |
| 101 | 101 | LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, |
| 102 | 102 | const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, |
| 103 | LLVMCodeModel CodeModel, bool function_sections) | |
| 103 | LLVMCodeModel CodeModel, bool function_sections, ZigLLVMABIType float_abi, const char *abi_name) | |
| 104 | 104 | { |
| 105 | 105 | Optional<Reloc::Model> RM; |
| 106 | 106 | switch (Reloc){ |
| ... | ... | @@ -147,6 +147,21 @@ LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Tri |
| 147 | 147 | |
| 148 | 148 | TargetOptions opt; |
| 149 | 149 | opt.FunctionSections = function_sections; |
| 150 | switch (float_abi) { | |
| 151 | case ZigLLVMABITypeDefault: | |
| 152 | opt.FloatABIType = FloatABI::Default; | |
| 153 | break; | |
| 154 | case ZigLLVMABITypeSoft: | |
| 155 | opt.FloatABIType = FloatABI::Soft; | |
| 156 | break; | |
| 157 | case ZigLLVMABITypeHard: | |
| 158 | opt.FloatABIType = FloatABI::Hard; | |
| 159 | break; | |
| 160 | } | |
| 161 | ||
| 162 | if (abi_name != nullptr) { | |
| 163 | opt.MCOptions.ABIName = abi_name; | |
| 164 | } | |
| 150 | 165 | |
| 151 | 166 | TargetMachine *TM = reinterpret_cast<Target*>(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM, |
| 152 | 167 | OL, JIT); |
src/zig_llvm.h+8-1| ... | ... | @@ -51,9 +51,16 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi |
| 51 | 51 | bool is_small, bool time_report, |
| 52 | 52 | const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename); |
| 53 | 53 | |
| 54 | ||
| 55 | enum ZigLLVMABIType { | |
| 56 | ZigLLVMABITypeDefault, // Target-specific (either soft or hard depending on triple, etc). | |
| 57 | ZigLLVMABITypeSoft, // Soft float. | |
| 58 | ZigLLVMABITypeHard // Hard float. | |
| 59 | }; | |
| 60 | ||
| 54 | 61 | ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, |
| 55 | 62 | const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, |
| 56 | LLVMCodeModel CodeModel, bool function_sections); | |
| 63 | LLVMCodeModel CodeModel, bool function_sections, ZigLLVMABIType float_abi, const char *abi_name); | |
| 57 | 64 | |
| 58 | 65 | ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); |
| 59 | 66 |
test/tests.zig+8-9| ... | ... | @@ -160,15 +160,14 @@ const test_targets = blk: { |
| 160 | 160 | }, |
| 161 | 161 | }, |
| 162 | 162 | |
| 163 | // https://github.com/ziglang/zig/issues/4863 | |
| 164 | //TestTarget{ | |
| 165 | // .target = .{ | |
| 166 | // .cpu_arch = .riscv64, | |
| 167 | // .os_tag = .linux, | |
| 168 | // .abi = .musl, | |
| 169 | // }, | |
| 170 | // .link_libc = true, | |
| 171 | //}, | |
| 163 | TestTarget{ | |
| 164 | .target = .{ | |
| 165 | .cpu_arch = .riscv64, | |
| 166 | .os_tag = .linux, | |
| 167 | .abi = .musl, | |
| 168 | }, | |
| 169 | .link_libc = true, | |
| 170 | }, | |
| 172 | 171 | |
| 173 | 172 | // https://github.com/ziglang/zig/issues/3340 |
| 174 | 173 | //TestTarget{ |