authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-04-28 02:18:45+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-04-28 02:18:45+02:00
log78df3c9301891a3333eb5420074c9b0d56d54a54
treef472f17d9afaa3f4d3c5853817628da8e58ccc91
parent5ed8bd5c85e34d200a504418ebd2fc3d902460ac
parent711e055f1852be93dd74dcbbb5777efc30f43506
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #23663 from alexrp/emit-asm-only


5 files changed, 73 insertions(+), 29 deletions(-)

src/link/Elf.zig+12-1
...@@ -1663,7 +1663,18 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s...@@ -1663,7 +1663,18 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
1663 // copy when generating relocatables. Normally, we would expect `lld -r` to work.1663 // copy when generating relocatables. Normally, we would expect `lld -r` to work.
1664 // However, because LLD wants to resolve BPF relocations which it shouldn't, it fails1664 // However, because LLD wants to resolve BPF relocations which it shouldn't, it fails
1665 // before even generating the relocatable.1665 // before even generating the relocatable.
1666 if (output_mode == .Obj and (comp.config.lto != .none or target.cpu.arch.isBpf())) {1666 //
1667 // For m68k, we go through this path because LLD doesn't support it yet, but LLVM can
1668 // produce usable object files.
1669 if (output_mode == .Obj and
1670 (comp.config.lto != .none or
1671 target.cpu.arch.isBpf() or
1672 target.cpu.arch == .lanai or
1673 target.cpu.arch == .m68k or
1674 target.cpu.arch.isSPARC() or
1675 target.cpu.arch == .ve or
1676 target.cpu.arch == .xcore))
1677 {
1667 // In this case we must do a simple file copy1678 // In this case we must do a simple file copy
1668 // here. TODO: think carefully about how we can avoid this redundant operation when doing1679 // here. TODO: think carefully about how we can avoid this redundant operation when doing
1669 // build-obj. See also the corresponding TODO in linkAsArchive.1680 // build-obj. See also the corresponding TODO in linkAsArchive.
src/main.zig+4-2
...@@ -3169,9 +3169,11 @@ fn buildOutputType(...@@ -3169,9 +3169,11 @@ fn buildOutputType(
31693169
3170 const target = main_mod.resolved_target.result;3170 const target = main_mod.resolved_target.result;
31713171
3172 if (target.cpu.arch.isNvptx()) {3172 if (target.cpu.arch == .arc or target.cpu.arch.isNvptx()) {
3173 if (emit_bin != .no and create_module.resolved_options.use_llvm) {3173 if (emit_bin != .no and create_module.resolved_options.use_llvm) {
3174 fatal("cannot emit PTX binary with the LLVM backend; only '-femit-asm' is supported", .{});3174 fatal("cannot emit {s} binary with the LLVM backend; only '-femit-asm' is supported", .{
3175 @tagName(target.cpu.arch),
3176 });
3175 }3177 }
3176 }3178 }
31773179
src/target.zig+5-2
...@@ -153,7 +153,6 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {...@@ -153,7 +153,6 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
153 .avr,153 .avr,
154 .bpfel,154 .bpfel,
155 .bpfeb,155 .bpfeb,
156 .csky,
157 .hexagon,156 .hexagon,
158 .loongarch32,157 .loongarch32,
159 .loongarch64,158 .loongarch64,
...@@ -181,7 +180,6 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {...@@ -181,7 +180,6 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
181 .x86,180 .x86,
182 .x86_64,181 .x86_64,
183 .xcore,182 .xcore,
184 .xtensa,
185 .nvptx,183 .nvptx,
186 .nvptx64,184 .nvptx64,
187 .lanai,185 .lanai,
...@@ -190,6 +188,11 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {...@@ -190,6 +188,11 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
190 .ve,188 .ve,
191 => true,189 => true,
192190
191 // LLVM backend exists but can produce neither assembly nor object files.
192 .csky,
193 .xtensa,
194 => false,
195
193 // No LLVM backend exists.196 // No LLVM backend exists.
194 .kalimba,197 .kalimba,
195 .propeller,198 .propeller,
test/llvm_targets.zig+23-23
...@@ -44,9 +44,9 @@ const targets = [_]std.Target.Query{...@@ -44,9 +44,9 @@ const targets = [_]std.Target.Query{
44 // .{ .cpu_arch = .amdgcn, .os_tag = .amdpal, .abi = .none },44 // .{ .cpu_arch = .amdgcn, .os_tag = .amdpal, .abi = .none },
45 // .{ .cpu_arch = .amdgcn, .os_tag = .mesa3d, .abi = .none },45 // .{ .cpu_arch = .amdgcn, .os_tag = .mesa3d, .abi = .none },
4646
47 // .{ .cpu_arch = .arc, .os_tag = .freestanding, .abi = .none },47 .{ .cpu_arch = .arc, .os_tag = .freestanding, .abi = .none },
48 // .{ .cpu_arch = .arc, .os_tag = .linux, .abi = .gnu },48 .{ .cpu_arch = .arc, .os_tag = .linux, .abi = .gnu },
49 // .{ .cpu_arch = .arc, .os_tag = .linux, .abi = .none },49 .{ .cpu_arch = .arc, .os_tag = .linux, .abi = .none },
5050
51 .{ .cpu_arch = .arm, .os_tag = .freebsd, .abi = .eabi },51 .{ .cpu_arch = .arm, .os_tag = .freebsd, .abi = .eabi },
52 .{ .cpu_arch = .arm, .os_tag = .freebsd, .abi = .eabihf },52 .{ .cpu_arch = .arm, .os_tag = .freebsd, .abi = .eabihf },
...@@ -101,7 +101,7 @@ const targets = [_]std.Target.Query{...@@ -101,7 +101,7 @@ const targets = [_]std.Target.Query{
101 .{ .cpu_arch = .hexagon, .os_tag = .freestanding, .abi = .none },101 .{ .cpu_arch = .hexagon, .os_tag = .freestanding, .abi = .none },
102 .{ .cpu_arch = .hexagon, .os_tag = .linux, .abi = .none },102 .{ .cpu_arch = .hexagon, .os_tag = .linux, .abi = .none },
103103
104 // .{ .cpu_arch = .lanai, .os_tag = .freestanding, .abi = .none },104 .{ .cpu_arch = .lanai, .os_tag = .freestanding, .abi = .none },
105105
106 // .{ .cpu_arch = .loongarch32, .os_tag = .freestanding, .abi = .none },106 // .{ .cpu_arch = .loongarch32, .os_tag = .freestanding, .abi = .none },
107 // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .none },107 // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .none },
...@@ -117,13 +117,13 @@ const targets = [_]std.Target.Query{...@@ -117,13 +117,13 @@ const targets = [_]std.Target.Query{
117 .{ .cpu_arch = .loongarch64, .os_tag = .linux, .abi = .none },117 .{ .cpu_arch = .loongarch64, .os_tag = .linux, .abi = .none },
118 // .{ .cpu_arch = .loongarch64, .os_tag = .uefi, .abi = .none },118 // .{ .cpu_arch = .loongarch64, .os_tag = .uefi, .abi = .none },
119119
120 // .{ .cpu_arch = .m68k, .os_tag = .freestanding, .abi = .none },120 .{ .cpu_arch = .m68k, .os_tag = .freestanding, .abi = .none },
121 // .{ .cpu_arch = .m68k, .os_tag = .haiku, .abi = .none },121 .{ .cpu_arch = .m68k, .os_tag = .haiku, .abi = .none },
122 // .{ .cpu_arch = .m68k, .os_tag = .linux, .abi = .gnu },122 .{ .cpu_arch = .m68k, .os_tag = .linux, .abi = .gnu },
123 // .{ .cpu_arch = .m68k, .os_tag = .linux, .abi = .musl },123 .{ .cpu_arch = .m68k, .os_tag = .linux, .abi = .musl },
124 // .{ .cpu_arch = .m68k, .os_tag = .linux, .abi = .none },124 .{ .cpu_arch = .m68k, .os_tag = .linux, .abi = .none },
125 // .{ .cpu_arch = .m68k, .os_tag = .netbsd, .abi = .none },125 .{ .cpu_arch = .m68k, .os_tag = .netbsd, .abi = .none },
126 // .{ .cpu_arch = .m68k, .os_tag = .rtems, .abi = .none },126 .{ .cpu_arch = .m68k, .os_tag = .rtems, .abi = .none },
127127
128 .{ .cpu_arch = .mips, .os_tag = .freestanding, .abi = .eabi },128 .{ .cpu_arch = .mips, .os_tag = .freestanding, .abi = .eabi },
129 .{ .cpu_arch = .mips, .os_tag = .freestanding, .abi = .eabihf },129 .{ .cpu_arch = .mips, .os_tag = .freestanding, .abi = .eabihf },
...@@ -171,10 +171,10 @@ const targets = [_]std.Target.Query{...@@ -171,10 +171,10 @@ const targets = [_]std.Target.Query{
171171
172 .{ .cpu_arch = .msp430, .os_tag = .freestanding, .abi = .none },172 .{ .cpu_arch = .msp430, .os_tag = .freestanding, .abi = .none },
173173
174 // .{ .cpu_arch = .nvptx, .os_tag = .cuda, .abi = .none },174 .{ .cpu_arch = .nvptx, .os_tag = .cuda, .abi = .none },
175 // .{ .cpu_arch = .nvptx, .os_tag = .nvcl, .abi = .none },175 .{ .cpu_arch = .nvptx, .os_tag = .nvcl, .abi = .none },
176 // .{ .cpu_arch = .nvptx64, .os_tag = .cuda, .abi = .none },176 .{ .cpu_arch = .nvptx64, .os_tag = .cuda, .abi = .none },
177 // .{ .cpu_arch = .nvptx64, .os_tag = .nvcl, .abi = .none },177 .{ .cpu_arch = .nvptx64, .os_tag = .nvcl, .abi = .none },
178178
179 // .{ .cpu_arch = .powerpc, .os_tag = .aix, .abi = .eabihf },179 // .{ .cpu_arch = .powerpc, .os_tag = .aix, .abi = .eabihf },
180 .{ .cpu_arch = .powerpc, .os_tag = .freebsd, .abi = .eabi },180 .{ .cpu_arch = .powerpc, .os_tag = .freebsd, .abi = .eabi },
...@@ -241,11 +241,11 @@ const targets = [_]std.Target.Query{...@@ -241,11 +241,11 @@ const targets = [_]std.Target.Query{
241 .{ .cpu_arch = .s390x, .os_tag = .linux, .abi = .none },241 .{ .cpu_arch = .s390x, .os_tag = .linux, .abi = .none },
242 // .{ .cpu_arch = .s390x, .os_tag = .zos, .abi = .none },242 // .{ .cpu_arch = .s390x, .os_tag = .zos, .abi = .none },
243243
244 // .{ .cpu_arch = .sparc, .os_tag = .freestanding, .abi = .none },244 .{ .cpu_arch = .sparc, .os_tag = .freestanding, .abi = .none },
245 // .{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .gnu },245 .{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .gnu },
246 // .{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .none },246 .{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .none },
247 // .{ .cpu_arch = .sparc, .os_tag = .netbsd, .abi = .none },247 .{ .cpu_arch = .sparc, .os_tag = .netbsd, .abi = .none },
248 // .{ .cpu_arch = .sparc, .os_tag = .rtems, .abi = .none },248 .{ .cpu_arch = .sparc, .os_tag = .rtems, .abi = .none },
249249
250 .{ .cpu_arch = .sparc64, .os_tag = .freestanding, .abi = .none },250 .{ .cpu_arch = .sparc64, .os_tag = .freestanding, .abi = .none },
251 .{ .cpu_arch = .sparc64, .os_tag = .haiku, .abi = .none },251 .{ .cpu_arch = .sparc64, .os_tag = .haiku, .abi = .none },
...@@ -279,8 +279,8 @@ const targets = [_]std.Target.Query{...@@ -279,8 +279,8 @@ const targets = [_]std.Target.Query{
279 .{ .cpu_arch = .thumbeb, .os_tag = .rtems, .abi = .eabi },279 .{ .cpu_arch = .thumbeb, .os_tag = .rtems, .abi = .eabi },
280 .{ .cpu_arch = .thumbeb, .os_tag = .rtems, .abi = .eabihf },280 .{ .cpu_arch = .thumbeb, .os_tag = .rtems, .abi = .eabihf },
281281
282 // .{ .cpu_arch = .ve, .os_tag = .freestanding, .abi = .none },282 .{ .cpu_arch = .ve, .os_tag = .freestanding, .abi = .none },
283 // .{ .cpu_arch = .ve, .os_tag = .linux, .abi = .none },283 .{ .cpu_arch = .ve, .os_tag = .linux, .abi = .none },
284284
285 .{ .cpu_arch = .wasm32, .os_tag = .emscripten, .abi = .none },285 .{ .cpu_arch = .wasm32, .os_tag = .emscripten, .abi = .none },
286 .{ .cpu_arch = .wasm32, .os_tag = .freestanding, .abi = .none },286 .{ .cpu_arch = .wasm32, .os_tag = .freestanding, .abi = .none },
...@@ -350,7 +350,7 @@ const targets = [_]std.Target.Query{...@@ -350,7 +350,7 @@ const targets = [_]std.Target.Query{
350 .{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .itanium },350 .{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .itanium },
351 .{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .msvc },351 .{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .msvc },
352352
353 // .{ .cpu_arch = .xcore, .os_tag = .freestanding, .abi = .none },353 .{ .cpu_arch = .xcore, .os_tag = .freestanding, .abi = .none },
354354
355 // .{ .cpu_arch = .xtensa, .os_tag = .freestanding, .abi = .none },355 // .{ .cpu_arch = .xtensa, .os_tag = .freestanding, .abi = .none },
356 // .{ .cpu_arch = .xtensa, .os_tag = .linux, .abi = .none },356 // .{ .cpu_arch = .xtensa, .os_tag = .linux, .abi = .none },
test/src/Cases.zig+29-1
...@@ -62,6 +62,7 @@ pub const Case = struct {...@@ -62,6 +62,7 @@ pub const Case = struct {
62 Header: []const u8,62 Header: []const u8,
63 },63 },
6464
65 emit_asm: bool = false,
65 emit_bin: bool = true,66 emit_bin: bool = true,
66 emit_h: bool = false,67 emit_h: bool = false,
67 is_test: bool = false,68 is_test: bool = false,
...@@ -173,6 +174,23 @@ pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.Target....@@ -173,6 +174,23 @@ pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.Target.
173}174}
174175
175pub fn addObjLlvm(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {176pub fn addObjLlvm(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
177 const can_emit_asm = switch (target.result.cpu.arch) {
178 .csky,
179 .xtensa,
180 => false,
181 else => true,
182 };
183 const can_emit_bin = switch (target.result.cpu.arch) {
184 .arc,
185 .csky,
186 .nvptx,
187 .nvptx64,
188 .xcore,
189 .xtensa,
190 => false,
191 else => true,
192 };
193
176 ctx.cases.append(.{194 ctx.cases.append(.{
177 .name = name,195 .name = name,
178 .target = target,196 .target = target,
...@@ -181,6 +199,8 @@ pub fn addObjLlvm(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarge...@@ -181,6 +199,8 @@ pub fn addObjLlvm(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarge
181 .output_mode = .Obj,199 .output_mode = .Obj,
182 .deps = std.ArrayList(DepModule).init(ctx.arena),200 .deps = std.ArrayList(DepModule).init(ctx.arena),
183 .backend = .llvm,201 .backend = .llvm,
202 .emit_bin = can_emit_bin,
203 .emit_asm = can_emit_asm,
184 }) catch @panic("out of memory");204 }) catch @panic("out of memory");
185 return &ctx.cases.items[ctx.cases.items.len - 1];205 return &ctx.cases.items[ctx.cases.items.len - 1];
186}206}
...@@ -371,6 +391,7 @@ fn addFromDirInner(...@@ -371,6 +391,7 @@ fn addFromDirInner(
371 const output_mode = try manifest.getConfigForKeyAssertSingle("output_mode", std.builtin.OutputMode);391 const output_mode = try manifest.getConfigForKeyAssertSingle("output_mode", std.builtin.OutputMode);
372 const pic = try manifest.getConfigForKeyAssertSingle("pic", ?bool);392 const pic = try manifest.getConfigForKeyAssertSingle("pic", ?bool);
373 const pie = try manifest.getConfigForKeyAssertSingle("pie", ?bool);393 const pie = try manifest.getConfigForKeyAssertSingle("pie", ?bool);
394 const emit_asm = try manifest.getConfigForKeyAssertSingle("emit_asm", bool);
374 const emit_bin = try manifest.getConfigForKeyAssertSingle("emit_bin", bool);395 const emit_bin = try manifest.getConfigForKeyAssertSingle("emit_bin", bool);
375 const imports = try manifest.getConfigForKeyAlloc(ctx.arena, "imports", []const u8);396 const imports = try manifest.getConfigForKeyAlloc(ctx.arena, "imports", []const u8);
376397
...@@ -438,6 +459,7 @@ fn addFromDirInner(...@@ -438,6 +459,7 @@ fn addFromDirInner(
438 .backend = backend,459 .backend = backend,
439 .files = .init(ctx.arena),460 .files = .init(ctx.arena),
440 .case = null,461 .case = null,
462 .emit_asm = emit_asm,
441 .emit_bin = emit_bin,463 .emit_bin = emit_bin,
442 .is_test = is_test,464 .is_test = is_test,
443 .output_mode = output_mode,465 .output_mode = output_mode,
...@@ -663,7 +685,10 @@ pub fn lowerToBuildSteps(...@@ -663,7 +685,10 @@ pub fn lowerToBuildSteps(
663685
664 switch (case.case.?) {686 switch (case.case.?) {
665 .Compile => {687 .Compile => {
666 // Force the binary to be emitted if requested.688 // Force the assembly/binary to be emitted if requested.
689 if (case.emit_asm) {
690 _ = artifact.getEmittedAsm();
691 }
667 if (case.emit_bin) {692 if (case.emit_bin) {
668 _ = artifact.getEmittedBin();693 _ = artifact.getEmittedBin();
669 }694 }
...@@ -761,6 +786,8 @@ const TestManifestConfigDefaults = struct {...@@ -761,6 +786,8 @@ const TestManifestConfigDefaults = struct {
761 .run_translated_c => "Obj",786 .run_translated_c => "Obj",
762 .cli => @panic("TODO test harness for CLI tests"),787 .cli => @panic("TODO test harness for CLI tests"),
763 };788 };
789 } else if (std.mem.eql(u8, key, "emit_asm")) {
790 return "false";
764 } else if (std.mem.eql(u8, key, "emit_bin")) {791 } else if (std.mem.eql(u8, key, "emit_bin")) {
765 return "true";792 return "true";
766 } else if (std.mem.eql(u8, key, "is_test")) {793 } else if (std.mem.eql(u8, key, "is_test")) {
...@@ -802,6 +829,7 @@ const TestManifest = struct {...@@ -802,6 +829,7 @@ const TestManifest = struct {
802 trailing_bytes: []const u8 = "",829 trailing_bytes: []const u8 = "",
803830
804 const valid_keys = std.StaticStringMap(void).initComptime(.{831 const valid_keys = std.StaticStringMap(void).initComptime(.{
832 .{ "emit_asm", {} },
805 .{ "emit_bin", {} },833 .{ "emit_bin", {} },
806 .{ "is_test", {} },834 .{ "is_test", {} },
807 .{ "output_mode", {} },835 .{ "output_mode", {} },