authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-12-03 16:37:56-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-12-03 16:37:56-08:00
log3311ef3262c6d650d7ef23ad62ae0483835f79c4
tree922d865e78b10012f773c292795b9d7479894bdd
parent84704ef43e5414860aa9d3dc0f94f9737404f6e5
parent4c1a62326b5090fad67c004a6e58a6e4265a77ad
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10006 from akovaski/riscv-default-abi

Default target-abi based on RISC-V extensions and user selectable -mabi/target-abi

6 files changed, 69 insertions(+), 33 deletions(-)

src/Compilation.zig+28-16
...@@ -992,6 +992,12 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -992,6 +992,12 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
992 } else if (options.target.os.tag == .windows and link_libcpp) {992 } else if (options.target.os.tag == .windows and link_libcpp) {
993 // https://github.com/ziglang/zig/issues/8531993 // https://github.com/ziglang/zig/issues/8531
994 break :blk false;994 break :blk false;
995 } else if (options.target.cpu.arch.isRISCV()) {
996 // Clang and LLVM currently don't support RISC-V target-abi for LTO.
997 // Compiling with LTO may fail or produce undesired results.
998 // See https://reviews.llvm.org/D71387
999 // See https://reviews.llvm.org/D102582
1000 break :blk false;
995 } else switch (options.output_mode) {1001 } else switch (options.output_mode) {
996 .Lib, .Obj => break :blk false,1002 .Lib, .Obj => break :blk false,
997 .Exe => switch (options.optimize_mode) {1003 .Exe => switch (options.optimize_mode) {
...@@ -1780,8 +1786,8 @@ pub fn getTarget(self: Compilation) Target {...@@ -1780,8 +1786,8 @@ pub fn getTarget(self: Compilation) Target {
17801786
1781/// Detect changes to source files, perform semantic analysis, and update the output files.1787/// Detect changes to source files, perform semantic analysis, and update the output files.
1782pub fn update(self: *Compilation) !void {1788pub fn update(self: *Compilation) !void {
1783 const t = trace(@src());1789 const tracy_trace = trace(@src());
1784 defer t.end();1790 defer tracy_trace.end();
17851791
1786 self.clearMiscFailures();1792 self.clearMiscFailures();
17871793
...@@ -2822,8 +2828,8 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {...@@ -2822,8 +2828,8 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
2822 if (!build_options.have_llvm)2828 if (!build_options.have_llvm)
2823 return error.ZigCompilerNotBuiltWithLLVMExtensions;2829 return error.ZigCompilerNotBuiltWithLLVMExtensions;
28242830
2825 const t = trace(@src());2831 const tracy_trace = trace(@src());
2826 defer t.end();2832 defer tracy_trace.end();
28272833
2828 const cimport_zig_basename = "cimport.zig";2834 const cimport_zig_basename = "cimport.zig";
28292835
...@@ -3077,8 +3083,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P...@@ -3077,8 +3083,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
3077 const self_exe_path = comp.self_exe_path orelse3083 const self_exe_path = comp.self_exe_path orelse
3078 return comp.failCObj(c_object, "clang compilation disabled", .{});3084 return comp.failCObj(c_object, "clang compilation disabled", .{});
30793085
3080 const t = trace(@src());3086 const tracy_trace = trace(@src());
3081 defer t.end();3087 defer tracy_trace.end();
30823088
3083 log.debug("updating C object: {s}", .{c_object.src.src_path});3089 log.debug("updating C object: {s}", .{c_object.src.src_path});
30843090
...@@ -3590,6 +3596,11 @@ pub fn addCCArgs(...@@ -3590,6 +3596,11 @@ pub fn addCCArgs(
3590 }3596 }
3591 },3597 },
3592 }3598 }
3599
3600 if (target_util.llvmMachineAbi(target)) |mabi| {
3601 try argv.append(try std.fmt.allocPrint(arena, "-mabi={s}", .{mabi}));
3602 }
3603
3593 if (out_dep_path) |p| {3604 if (out_dep_path) |p| {
3594 try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p });3605 try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p });
3595 }3606 }
...@@ -4036,8 +4047,8 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {...@@ -4036,8 +4047,8 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
4036}4047}
40374048
4038fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) Allocator.Error!void {4049fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) Allocator.Error!void {
4039 const t = trace(@src());4050 const tracy_trace = trace(@src());
4040 defer t.end();4051 defer tracy_trace.end();
40414052
4042 const source = try comp.generateBuiltinZigSource(comp.gpa);4053 const source = try comp.generateBuiltinZigSource(comp.gpa);
4043 defer comp.gpa.free(source);4054 defer comp.gpa.free(source);
...@@ -4074,8 +4085,8 @@ pub fn dump_argv(argv: []const []const u8) void {...@@ -4074,8 +4085,8 @@ pub fn dump_argv(argv: []const []const u8) void {
4074}4085}
40754086
4076pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Allocator.Error![]u8 {4087pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Allocator.Error![]u8 {
4077 const t = trace(@src());4088 const tracy_trace = trace(@src());
4078 defer t.end();4089 defer tracy_trace.end();
40794090
4080 var buffer = std.ArrayList(u8).init(allocator);4091 var buffer = std.ArrayList(u8).init(allocator);
4081 defer buffer.deinit();4092 defer buffer.deinit();
...@@ -4320,8 +4331,8 @@ fn buildOutputFromZig(...@@ -4320,8 +4331,8 @@ fn buildOutputFromZig(
4320 out: *?CRTFile,4331 out: *?CRTFile,
4321 misc_task_tag: MiscTask,4332 misc_task_tag: MiscTask,
4322) !void {4333) !void {
4323 const t = trace(@src());4334 const tracy_trace = trace(@src());
4324 defer t.end();4335 defer tracy_trace.end();
43254336
4326 std.debug.assert(output_mode != .Exe);4337 std.debug.assert(output_mode != .Exe);
4327 const special_sub = "std" ++ std.fs.path.sep_str ++ "special";4338 const special_sub = "std" ++ std.fs.path.sep_str ++ "special";
...@@ -4419,8 +4430,8 @@ fn buildOutputFromZig(...@@ -4419,8 +4430,8 @@ fn buildOutputFromZig(
4419}4430}
44204431
4421fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node) !void {4432fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node) !void {
4422 const t = trace(@src());4433 const tracy_trace = trace(@src());
4423 defer t.end();4434 defer tracy_trace.end();
44244435
4425 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);4436 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
4426 defer arena_allocator.deinit();4437 defer arena_allocator.deinit();
...@@ -4566,6 +4577,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node...@@ -4566,6 +4577,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
4566 .is_native_cpu = false, // Only true when bootstrapping the compiler.4577 .is_native_cpu = false, // Only true when bootstrapping the compiler.
4567 .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null,4578 .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null,
4568 .llvm_cpu_features = comp.bin_file.options.llvm_cpu_features.?,4579 .llvm_cpu_features = comp.bin_file.options.llvm_cpu_features.?,
4580 .llvm_target_abi = if (target_util.llvmMachineAbi(target)) |s| s.ptr else null,
4569 };4581 };
45704582
4571 comp.stage1_cache_manifest = &man;4583 comp.stage1_cache_manifest = &man;
...@@ -4773,8 +4785,8 @@ pub fn build_crt_file(...@@ -4773,8 +4785,8 @@ pub fn build_crt_file(
4773 output_mode: std.builtin.OutputMode,4785 output_mode: std.builtin.OutputMode,
4774 c_source_files: []const Compilation.CSourceFile,4786 c_source_files: []const Compilation.CSourceFile,
4775) !void {4787) !void {
4776 const t = trace(@src());4788 const tracy_trace = trace(@src());
4777 defer t.end();4789 defer tracy_trace.end();
47784790
4779 const target = comp.getTarget();4791 const target = comp.getTarget();
4780 const basename = try std.zig.binNameAlloc(comp.gpa, .{4792 const basename = try std.zig.binNameAlloc(comp.gpa, .{
src/codegen/llvm.zig+2-14
...@@ -15,6 +15,7 @@ const TypedValue = @import("../TypedValue.zig");...@@ -15,6 +15,7 @@ const TypedValue = @import("../TypedValue.zig");
15const Zir = @import("../Zir.zig");15const Zir = @import("../Zir.zig");
16const Air = @import("../Air.zig");16const Air = @import("../Air.zig");
17const Liveness = @import("../Liveness.zig");17const Liveness = @import("../Liveness.zig");
18const target_util = @import("../target.zig");
1819
19const Value = @import("../value.zig").Value;20const Value = @import("../value.zig").Value;
20const Type = @import("../type.zig").Type;21const Type = @import("../type.zig").Type;
...@@ -244,19 +245,6 @@ pub const Object = struct {...@@ -244,19 +245,6 @@ pub const Object = struct {
244 // TODO handle float ABI better- it should depend on the ABI portion of std.Target245 // TODO handle float ABI better- it should depend on the ABI portion of std.Target
245 const float_abi: llvm.ABIType = .Default;246 const float_abi: llvm.ABIType = .Default;
246247
247 // TODO a way to override this as part of std.Target ABI?
248 const abi_name: ?[*:0]const u8 = switch (options.target.cpu.arch) {
249 .riscv32 => switch (options.target.os.tag) {
250 .linux => "ilp32d",
251 else => "ilp32",
252 },
253 .riscv64 => switch (options.target.os.tag) {
254 .linux => "lp64d",
255 else => "lp64",
256 },
257 else => null,
258 };
259
260 const target_machine = llvm.TargetMachine.create(248 const target_machine = llvm.TargetMachine.create(
261 target,249 target,
262 llvm_target_triple.ptr,250 llvm_target_triple.ptr,
...@@ -267,7 +255,7 @@ pub const Object = struct {...@@ -267,7 +255,7 @@ pub const Object = struct {
267 code_model,255 code_model,
268 options.function_sections,256 options.function_sections,
269 float_abi,257 float_abi,
270 abi_name,258 if (target_util.llvmMachineAbi(options.target)) |s| s.ptr else null,
271 );259 );
272 errdefer target_machine.dispose();260 errdefer target_machine.dispose();
273261
src/stage1.zig+1
...@@ -364,6 +364,7 @@ pub const Stage2Target = extern struct {...@@ -364,6 +364,7 @@ pub const Stage2Target = extern struct {
364364
365 llvm_cpu_name: ?[*:0]const u8,365 llvm_cpu_name: ?[*:0]const u8,
366 llvm_cpu_features: ?[*:0]const u8,366 llvm_cpu_features: ?[*:0]const u8,
367 llvm_target_abi: ?[*:0]const u8,
367};368};
368369
369// ABI warning370// ABI warning
src/stage1/codegen.cpp+2-3
...@@ -9487,9 +9487,8 @@ static void init(CodeGen *g) {...@@ -9487,9 +9487,8 @@ static void init(CodeGen *g) {
9487 // TODO handle float ABI better- it should depend on the ABI portion of std.Target9487 // TODO handle float ABI better- it should depend on the ABI portion of std.Target
9488 ZigLLVMABIType float_abi = ZigLLVMABITypeDefault;9488 ZigLLVMABIType float_abi = ZigLLVMABITypeDefault;
94899489
9490 // TODO a way to override this as part of std.Target ABI?9490 const char *abi_name = g->zig_target->llvm_target_abi;
9491 const char *abi_name = nullptr;9491 if (abi_name == nullptr && target_is_riscv(g->zig_target)) {
9492 if (target_is_riscv(g->zig_target)) {
9493 // RISC-V Linux defaults to ilp32d/lp64d9492 // RISC-V Linux defaults to ilp32d/lp64d
9494 if (g->zig_target->os == OsLinux) {9493 if (g->zig_target->os == OsLinux) {
9495 abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32d" : "lp64d";9494 abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32d" : "lp64d";
src/stage1/stage1.h+1
...@@ -112,6 +112,7 @@ struct ZigTarget {...@@ -112,6 +112,7 @@ struct ZigTarget {
112112
113 const char *llvm_cpu_name;113 const char *llvm_cpu_name;
114 const char *llvm_cpu_features;114 const char *llvm_cpu_features;
115 const char *llvm_target_abi;
115};116};
116117
117// ABI warning118// ABI warning
src/target.zig+35
...@@ -599,3 +599,38 @@ pub fn defaultAddressSpace(...@@ -599,3 +599,38 @@ pub fn defaultAddressSpace(
599 _ = context;599 _ = context;
600 return .generic;600 return .generic;
601}601}
602
603pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
604 const have_float = switch (target.abi) {
605 .gnuilp32 => return "ilp32",
606 .gnueabihf, .musleabihf, .eabihf => true,
607 else => false,
608 };
609
610 switch (target.cpu.arch) {
611 .riscv64 => {
612 const featureSetHas = std.Target.riscv.featureSetHas;
613 if (featureSetHas(target.cpu.features, .d)) {
614 return "lp64d";
615 } else if (have_float) {
616 return "lp64f";
617 } else {
618 return "lp64";
619 }
620 },
621 .riscv32 => {
622 const featureSetHas = std.Target.riscv.featureSetHas;
623 if (featureSetHas(target.cpu.features, .d)) {
624 return "ilp32d";
625 } else if (have_float) {
626 return "ilp32f";
627 } else if (featureSetHas(target.cpu.features, .e)) {
628 return "ilp32e";
629 } else {
630 return "ilp32";
631 }
632 },
633 //TODO add ARM, Mips, and PowerPC
634 else => return null,
635 }
636}