authorgravatar for gwenzek@users.noreply.github.comgwenzek <gwenzek@users.noreply.github.com> 2022-02-05 15:33:00+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-02-05 16:33:00+02:00
log0e1afb4d986c3316c6f024be50612b0a6c66777b
tree7b2bc69ae80604165ce4d11bf72ef104d4b51f86
parentfbc06f9c9151205896fb167b087506d6580946c4
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

stage2: add support for Nvptx target

sample command: /home/guw/github/zig/stage2/bin/zig build-obj cuda_kernel.zig -target nvptx64-cuda -O ReleaseSafe this will create a kernel.ptx expose PtxKernel call convention from LLVM kernels are `export fn f() callconv(.PtxKernel)`

12 files changed, 185 insertions(+), 8 deletions(-)

lib/std/builtin.zig+1
...@@ -147,6 +147,7 @@ pub const CallingConvention = enum {...@@ -147,6 +147,7 @@ pub const CallingConvention = enum {
147 AAPCS,147 AAPCS,
148 AAPCSVFP,148 AAPCSVFP,
149 SysV,149 SysV,
150 PtxKernel,
150};151};
151152
152/// This data structure is used by the Zig language code generation and153/// This data structure is used by the Zig language code generation and
lib/std/target.zig+4
...@@ -579,6 +579,8 @@ pub const Target = struct {...@@ -579,6 +579,8 @@ pub const Target = struct {
579 raw,579 raw,
580 /// Plan 9 from Bell Labs580 /// Plan 9 from Bell Labs
581 plan9,581 plan9,
582 /// Nvidia PTX format
583 nvptx,
582584
583 pub fn fileExt(of: ObjectFormat, cpu_arch: Cpu.Arch) [:0]const u8 {585 pub fn fileExt(of: ObjectFormat, cpu_arch: Cpu.Arch) [:0]const u8 {
584 return switch (of) {586 return switch (of) {
...@@ -589,6 +591,7 @@ pub const Target = struct {...@@ -589,6 +591,7 @@ pub const Target = struct {
589 .hex => ".ihex",591 .hex => ".ihex",
590 .raw => ".bin",592 .raw => ".bin",
591 .plan9 => plan9Ext(cpu_arch),593 .plan9 => plan9Ext(cpu_arch),
594 .nvptx => ".ptx",
592 };595 };
593 }596 }
594 };597 };
...@@ -1388,6 +1391,7 @@ pub const Target = struct {...@@ -1388,6 +1391,7 @@ pub const Target = struct {
1388 else => return switch (cpu_arch) {1391 else => return switch (cpu_arch) {
1389 .wasm32, .wasm64 => .wasm,1392 .wasm32, .wasm64 => .wasm,
1390 .spirv32, .spirv64 => .spirv,1393 .spirv32, .spirv64 => .spirv,
1394 .nvptx, .nvptx64 => .nvptx,
1391 else => .elf,1395 else => .elf,
1392 },1396 },
1393 };1397 };
lib/std/zig.zig+1
...@@ -181,6 +181,7 @@ pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error...@@ -181,6 +181,7 @@ pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error
181 .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, ofmt.fileExt(target.cpu.arch) }),181 .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, ofmt.fileExt(target.cpu.arch) }),
182 .Lib => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{ target.libPrefix(), root_name }),182 .Lib => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{ target.libPrefix(), root_name }),
183 },183 },
184 .nvptx => return std.fmt.allocPrint(allocator, "{s}", .{root_name}),
184 }185 }
185}186}
186187
src/Module.zig+5-1
...@@ -4242,7 +4242,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -4242,7 +4242,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4242 // in `Decl` to notice that the line number did not change.4242 // in `Decl` to notice that the line number did not change.
4243 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });4243 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });
4244 },4244 },
4245 .c, .wasm, .spirv => {},4245 .c, .wasm, .spirv, .nvptx => {},
4246 }4246 }
4247 }4247 }
4248}4248}
...@@ -4316,6 +4316,7 @@ pub fn clearDecl(...@@ -4316,6 +4316,7 @@ pub fn clearDecl(
4316 .c => .{ .c = {} },4316 .c => .{ .c = {} },
4317 .wasm => .{ .wasm = link.File.Wasm.DeclBlock.empty },4317 .wasm => .{ .wasm = link.File.Wasm.DeclBlock.empty },
4318 .spirv => .{ .spirv = {} },4318 .spirv => .{ .spirv = {} },
4319 .nvptx => .{ .nvptx = {} },
4319 };4320 };
4320 decl.fn_link = switch (mod.comp.bin_file.tag) {4321 decl.fn_link = switch (mod.comp.bin_file.tag) {
4321 .coff => .{ .coff = {} },4322 .coff => .{ .coff = {} },
...@@ -4325,6 +4326,7 @@ pub fn clearDecl(...@@ -4325,6 +4326,7 @@ pub fn clearDecl(
4325 .c => .{ .c = {} },4326 .c => .{ .c = {} },
4326 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },4327 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },
4327 .spirv => .{ .spirv = .{} },4328 .spirv => .{ .spirv = .{} },
4329 .nvptx => .{ .nvptx = .{} },
4328 };4330 };
4329 }4331 }
4330 if (decl.getInnerNamespace()) |namespace| {4332 if (decl.getInnerNamespace()) |namespace| {
...@@ -4652,6 +4654,7 @@ pub fn allocateNewDecl(...@@ -4652,6 +4654,7 @@ pub fn allocateNewDecl(
4652 .c => .{ .c = {} },4654 .c => .{ .c = {} },
4653 .wasm => .{ .wasm = link.File.Wasm.DeclBlock.empty },4655 .wasm => .{ .wasm = link.File.Wasm.DeclBlock.empty },
4654 .spirv => .{ .spirv = {} },4656 .spirv => .{ .spirv = {} },
4657 .nvptx => .{ .nvptx = {} },
4655 },4658 },
4656 .fn_link = switch (mod.comp.bin_file.tag) {4659 .fn_link = switch (mod.comp.bin_file.tag) {
4657 .coff => .{ .coff = {} },4660 .coff => .{ .coff = {} },
...@@ -4661,6 +4664,7 @@ pub fn allocateNewDecl(...@@ -4661,6 +4664,7 @@ pub fn allocateNewDecl(
4661 .c => .{ .c = {} },4664 .c => .{ .c = {} },
4662 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },4665 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },
4663 .spirv => .{ .spirv = .{} },4666 .spirv => .{ .spirv = .{} },
4667 .nvptx => .{ .nvptx = .{} },
4664 },4668 },
4665 .generation = 0,4669 .generation = 0,
4666 .is_pub = false,4670 .is_pub = false,
src/Sema.zig+1
...@@ -3724,6 +3724,7 @@ pub fn analyzeExport(...@@ -3724,6 +3724,7 @@ pub fn analyzeExport(
3724 .c => .{ .c = {} },3724 .c => .{ .c = {} },
3725 .wasm => .{ .wasm = {} },3725 .wasm => .{ .wasm = {} },
3726 .spirv => .{ .spirv = {} },3726 .spirv => .{ .spirv = {} },
3727 .nvptx => .{ .nvptx = {} },
3727 },3728 },
3728 .owner_decl = owner_decl,3729 .owner_decl = owner_decl,
3729 .src_decl = src_decl,3730 .src_decl = src_decl,
src/codegen/llvm.zig+5-1
...@@ -378,7 +378,7 @@ pub const Object = struct {...@@ -378,7 +378,7 @@ pub const Object = struct {
378 const mod = comp.bin_file.options.module.?;378 const mod = comp.bin_file.options.module.?;
379 const cache_dir = mod.zig_cache_artifact_directory;379 const cache_dir = mod.zig_cache_artifact_directory;
380380
381 const emit_bin_path: ?[*:0]const u8 = if (comp.bin_file.options.emit) |emit|381 var emit_bin_path: ?[*:0]const u8 = if (comp.bin_file.options.emit) |emit|
382 try emit.basenamePath(arena, try arena.dupeZ(u8, comp.bin_file.intermediary_basename.?))382 try emit.basenamePath(arena, try arena.dupeZ(u8, comp.bin_file.intermediary_basename.?))
383 else383 else
384 null;384 null;
...@@ -5078,6 +5078,10 @@ fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) llvm.Ca...@@ -5078,6 +5078,10 @@ fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) llvm.Ca
5078 },5078 },
5079 .Signal => .AVR_SIGNAL,5079 .Signal => .AVR_SIGNAL,
5080 .SysV => .X86_64_SysV,5080 .SysV => .X86_64_SysV,
5081 .PtxKernel => return switch (target.cpu.arch) {
5082 .nvptx, .nvptx64 => .PTX_Kernel,
5083 else => unreachable,
5084 },
5081 };5085 };
5082}5086}
50835087
src/link.zig+25-5
...@@ -215,6 +215,7 @@ pub const File = struct {...@@ -215,6 +215,7 @@ pub const File = struct {
215 c: void,215 c: void,
216 wasm: Wasm.DeclBlock,216 wasm: Wasm.DeclBlock,
217 spirv: void,217 spirv: void,
218 nvptx: void,
218 };219 };
219220
220 pub const LinkFn = union {221 pub const LinkFn = union {
...@@ -225,6 +226,7 @@ pub const File = struct {...@@ -225,6 +226,7 @@ pub const File = struct {
225 c: void,226 c: void,
226 wasm: Wasm.FnData,227 wasm: Wasm.FnData,
227 spirv: SpirV.FnData,228 spirv: SpirV.FnData,
229 nvptx: void,
228 };230 };
229231
230 pub const Export = union {232 pub const Export = union {
...@@ -235,6 +237,7 @@ pub const File = struct {...@@ -235,6 +237,7 @@ pub const File = struct {
235 c: void,237 c: void,
236 wasm: void,238 wasm: void,
237 spirv: void,239 spirv: void,
240 nvptx: void,
238 };241 };
239242
240 /// For DWARF .debug_info.243 /// For DWARF .debug_info.
...@@ -274,6 +277,7 @@ pub const File = struct {...@@ -274,6 +277,7 @@ pub const File = struct {
274 .plan9 => return &(try Plan9.createEmpty(allocator, options)).base,277 .plan9 => return &(try Plan9.createEmpty(allocator, options)).base,
275 .c => unreachable, // Reported error earlier.278 .c => unreachable, // Reported error earlier.
276 .spirv => &(try SpirV.createEmpty(allocator, options)).base,279 .spirv => &(try SpirV.createEmpty(allocator, options)).base,
280 .nvptx => &(try NvPtx.createEmpty(allocator, options)).base,
277 .hex => return error.HexObjectFormatUnimplemented,281 .hex => return error.HexObjectFormatUnimplemented,
278 .raw => return error.RawObjectFormatUnimplemented,282 .raw => return error.RawObjectFormatUnimplemented,
279 };283 };
...@@ -292,6 +296,7 @@ pub const File = struct {...@@ -292,6 +296,7 @@ pub const File = struct {
292 .wasm => &(try Wasm.createEmpty(allocator, options)).base,296 .wasm => &(try Wasm.createEmpty(allocator, options)).base,
293 .c => unreachable, // Reported error earlier.297 .c => unreachable, // Reported error earlier.
294 .spirv => &(try SpirV.createEmpty(allocator, options)).base,298 .spirv => &(try SpirV.createEmpty(allocator, options)).base,
299 .nvptx => &(try NvPtx.createEmpty(allocator, options)).base,
295 .hex => return error.HexObjectFormatUnimplemented,300 .hex => return error.HexObjectFormatUnimplemented,
296 .raw => return error.RawObjectFormatUnimplemented,301 .raw => return error.RawObjectFormatUnimplemented,
297 };302 };
...@@ -312,6 +317,7 @@ pub const File = struct {...@@ -312,6 +317,7 @@ pub const File = struct {
312 .wasm => &(try Wasm.openPath(allocator, sub_path, options)).base,317 .wasm => &(try Wasm.openPath(allocator, sub_path, options)).base,
313 .c => &(try C.openPath(allocator, sub_path, options)).base,318 .c => &(try C.openPath(allocator, sub_path, options)).base,
314 .spirv => &(try SpirV.openPath(allocator, sub_path, options)).base,319 .spirv => &(try SpirV.openPath(allocator, sub_path, options)).base,
320 .nvptx => &(try NvPtx.openPath(allocator, sub_path, options)).base,
315 .hex => return error.HexObjectFormatUnimplemented,321 .hex => return error.HexObjectFormatUnimplemented,
316 .raw => return error.RawObjectFormatUnimplemented,322 .raw => return error.RawObjectFormatUnimplemented,
317 };323 };
...@@ -344,7 +350,7 @@ pub const File = struct {...@@ -344,7 +350,7 @@ pub const File = struct {
344 .mode = determineMode(base.options),350 .mode = determineMode(base.options),
345 });351 });
346 },352 },
347 .c, .wasm, .spirv => {},353 .c, .wasm, .spirv, .nvptx => {},
348 }354 }
349 }355 }
350356
...@@ -389,7 +395,7 @@ pub const File = struct {...@@ -389,7 +395,7 @@ pub const File = struct {
389 f.close();395 f.close();
390 base.file = null;396 base.file = null;
391 },397 },
392 .c, .wasm, .spirv => {},398 .c, .wasm, .spirv, .nvptx => {},
393 }399 }
394 }400 }
395401
...@@ -437,6 +443,7 @@ pub const File = struct {...@@ -437,6 +443,7 @@ pub const File = struct {
437 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDecl(module, decl),443 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDecl(module, decl),
438 .spirv => return @fieldParentPtr(SpirV, "base", base).updateDecl(module, decl),444 .spirv => return @fieldParentPtr(SpirV, "base", base).updateDecl(module, decl),
439 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDecl(module, decl),445 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDecl(module, decl),
446 .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateDecl(module, decl),
440 // zig fmt: on447 // zig fmt: on
441 }448 }
442 }449 }
...@@ -456,6 +463,7 @@ pub const File = struct {...@@ -456,6 +463,7 @@ pub const File = struct {
456 .wasm => return @fieldParentPtr(Wasm, "base", base).updateFunc(module, func, air, liveness),463 .wasm => return @fieldParentPtr(Wasm, "base", base).updateFunc(module, func, air, liveness),
457 .spirv => return @fieldParentPtr(SpirV, "base", base).updateFunc(module, func, air, liveness),464 .spirv => return @fieldParentPtr(SpirV, "base", base).updateFunc(module, func, air, liveness),
458 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateFunc(module, func, air, liveness),465 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateFunc(module, func, air, liveness),
466 .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateFunc(module, func, air, liveness),
459 // zig fmt: on467 // zig fmt: on
460 }468 }
461 }469 }
...@@ -471,7 +479,7 @@ pub const File = struct {...@@ -471,7 +479,7 @@ pub const File = struct {
471 .macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl),479 .macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl),
472 .c => return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl),480 .c => return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl),
473 .plan9 => @panic("TODO: implement updateDeclLineNumber for plan9"),481 .plan9 => @panic("TODO: implement updateDeclLineNumber for plan9"),
474 .wasm, .spirv => {},482 .wasm, .spirv, .nvptx => {},
475 }483 }
476 }484 }
477485
...@@ -493,7 +501,7 @@ pub const File = struct {...@@ -493,7 +501,7 @@ pub const File = struct {
493 },501 },
494 .wasm => return @fieldParentPtr(Wasm, "base", base).allocateDeclIndexes(decl),502 .wasm => return @fieldParentPtr(Wasm, "base", base).allocateDeclIndexes(decl),
495 .plan9 => return @fieldParentPtr(Plan9, "base", base).allocateDeclIndexes(decl),503 .plan9 => return @fieldParentPtr(Plan9, "base", base).allocateDeclIndexes(decl),
496 .c, .spirv => {},504 .c, .spirv, .nvptx => {},
497 }505 }
498 }506 }
499507
...@@ -551,6 +559,11 @@ pub const File = struct {...@@ -551,6 +559,11 @@ pub const File = struct {
551 parent.deinit();559 parent.deinit();
552 base.allocator.destroy(parent);560 base.allocator.destroy(parent);
553 },561 },
562 .nvptx => {
563 const parent = @fieldParentPtr(NvPtx, "base", base);
564 parent.deinit();
565 base.allocator.destroy(parent);
566 },
554 }567 }
555 }568 }
556569
...@@ -584,6 +597,7 @@ pub const File = struct {...@@ -584,6 +597,7 @@ pub const File = struct {
584 .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp),597 .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp),
585 .spirv => return @fieldParentPtr(SpirV, "base", base).flush(comp),598 .spirv => return @fieldParentPtr(SpirV, "base", base).flush(comp),
586 .plan9 => return @fieldParentPtr(Plan9, "base", base).flush(comp),599 .plan9 => return @fieldParentPtr(Plan9, "base", base).flush(comp),
600 .nvptx => return @fieldParentPtr(NvPtx, "base", base).flush(comp),
587 }601 }
588 }602 }
589603
...@@ -598,6 +612,7 @@ pub const File = struct {...@@ -598,6 +612,7 @@ pub const File = struct {
598 .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp),612 .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp),
599 .spirv => return @fieldParentPtr(SpirV, "base", base).flushModule(comp),613 .spirv => return @fieldParentPtr(SpirV, "base", base).flushModule(comp),
600 .plan9 => return @fieldParentPtr(Plan9, "base", base).flushModule(comp),614 .plan9 => return @fieldParentPtr(Plan9, "base", base).flushModule(comp),
615 .nvptx => return @fieldParentPtr(NvPtx, "base", base).flushModule(comp),
601 }616 }
602 }617 }
603618
...@@ -612,6 +627,7 @@ pub const File = struct {...@@ -612,6 +627,7 @@ pub const File = struct {
612 .wasm => @fieldParentPtr(Wasm, "base", base).freeDecl(decl),627 .wasm => @fieldParentPtr(Wasm, "base", base).freeDecl(decl),
613 .spirv => @fieldParentPtr(SpirV, "base", base).freeDecl(decl),628 .spirv => @fieldParentPtr(SpirV, "base", base).freeDecl(decl),
614 .plan9 => @fieldParentPtr(Plan9, "base", base).freeDecl(decl),629 .plan9 => @fieldParentPtr(Plan9, "base", base).freeDecl(decl),
630 .nvptx => @fieldParentPtr(NvPtx, "base", base).freeDecl(decl),
615 }631 }
616 }632 }
617633
...@@ -622,7 +638,7 @@ pub const File = struct {...@@ -622,7 +638,7 @@ pub const File = struct {
622 .macho => return @fieldParentPtr(MachO, "base", base).error_flags,638 .macho => return @fieldParentPtr(MachO, "base", base).error_flags,
623 .plan9 => return @fieldParentPtr(Plan9, "base", base).error_flags,639 .plan9 => return @fieldParentPtr(Plan9, "base", base).error_flags,
624 .c => return .{ .no_entry_point_found = false },640 .c => return .{ .no_entry_point_found = false },
625 .wasm, .spirv => return ErrorFlags{},641 .wasm, .spirv, .nvptx => return ErrorFlags{},
626 }642 }
627 }643 }
628644
...@@ -644,6 +660,7 @@ pub const File = struct {...@@ -644,6 +660,7 @@ pub const File = struct {
644 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDeclExports(module, decl, exports),660 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDeclExports(module, decl, exports),
645 .spirv => return @fieldParentPtr(SpirV, "base", base).updateDeclExports(module, decl, exports),661 .spirv => return @fieldParentPtr(SpirV, "base", base).updateDeclExports(module, decl, exports),
646 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDeclExports(module, decl, exports),662 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDeclExports(module, decl, exports),
663 .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateDeclExports(module, decl, exports),
647 }664 }
648 }665 }
649666
...@@ -656,6 +673,7 @@ pub const File = struct {...@@ -656,6 +673,7 @@ pub const File = struct {
656 .c => unreachable,673 .c => unreachable,
657 .wasm => unreachable,674 .wasm => unreachable,
658 .spirv => unreachable,675 .spirv => unreachable,
676 .nvptx => unreachable,
659 }677 }
660 }678 }
661679
...@@ -851,6 +869,7 @@ pub const File = struct {...@@ -851,6 +869,7 @@ pub const File = struct {
851 wasm,869 wasm,
852 spirv,870 spirv,
853 plan9,871 plan9,
872 nvptx,
854 };873 };
855874
856 pub const ErrorFlags = struct {875 pub const ErrorFlags = struct {
...@@ -864,6 +883,7 @@ pub const File = struct {...@@ -864,6 +883,7 @@ pub const File = struct {
864 pub const MachO = @import("link/MachO.zig");883 pub const MachO = @import("link/MachO.zig");
865 pub const SpirV = @import("link/SpirV.zig");884 pub const SpirV = @import("link/SpirV.zig");
866 pub const Wasm = @import("link/Wasm.zig");885 pub const Wasm = @import("link/Wasm.zig");
886 pub const NvPtx = @import("link/NvPtx.zig");
867};887};
868888
869pub fn determineMode(options: Options) fs.File.Mode {889pub fn determineMode(options: Options) fs.File.Mode {
src/link/NvPtx.zig created+122
...@@ -0,0 +1,122 @@
1//! NVidia PTX (Paralle Thread Execution)
2//! https://docs.nvidia.com/cuda/parallel-thread-execution/index.html
3//! For this we rely on the nvptx backend of LLVM
4//! Kernel functions need to be marked both as "export" and "callconv(.PtxKernel)"
5
6const NvPtx = @This();
7
8const std = @import("std");
9const builtin = @import("builtin");
10
11const Allocator = std.mem.Allocator;
12const assert = std.debug.assert;
13const log = std.log.scoped(.link);
14
15const Module = @import("../Module.zig");
16const Compilation = @import("../Compilation.zig");
17const link = @import("../link.zig");
18const trace = @import("../tracy.zig").trace;
19const build_options = @import("build_options");
20const Air = @import("../Air.zig");
21const Liveness = @import("../Liveness.zig");
22const LlvmObject = @import("../codegen/llvm.zig").Object;
23
24base: link.File,
25llvm_object: *LlvmObject,
26
27pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx {
28 if (!build_options.have_llvm) return error.TODOArchNotSupported;
29
30 const nvptx = try gpa.create(NvPtx);
31 nvptx.* = .{
32 .base = .{
33 .tag = .nvptx,
34 .options = options,
35 .file = null,
36 .allocator = gpa,
37 },
38 .llvm_object = undefined,
39 };
40
41 switch (options.target.cpu.arch) {
42 .nvptx, .nvptx64 => {},
43 else => return error.TODOArchNotSupported,
44 }
45
46 switch (options.target.os.tag) {
47 // TODO: does it also work with nvcl ?
48 .cuda => {},
49 else => return error.TODOOsNotSupported,
50 }
51
52 return nvptx;
53}
54
55pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*NvPtx {
56 if (!build_options.have_llvm) @panic("nvptx target requires a zig compiler with llvm enabled.");
57 if (!options.use_llvm) return error.TODOArchNotSupported;
58 assert(options.object_format == .nvptx);
59
60 const nvptx = try createEmpty(allocator, options);
61 errdefer nvptx.base.destroy();
62 log.info("Opening .ptx target file {s}", .{sub_path});
63 nvptx.llvm_object = try LlvmObject.create(allocator, options);
64 return nvptx;
65}
66
67pub fn deinit(self: *NvPtx) void {
68 if (!build_options.have_llvm) return;
69 self.llvm_object.destroy(self.base.allocator);
70}
71
72pub fn updateFunc(self: *NvPtx, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
73 if (!build_options.have_llvm) return;
74 try self.llvm_object.updateFunc(module, func, air, liveness);
75}
76
77pub fn updateDecl(self: *NvPtx, module: *Module, decl: *Module.Decl) !void {
78 if (!build_options.have_llvm) return;
79 return self.llvm_object.updateDecl(module, decl);
80}
81
82pub fn updateDeclExports(
83 self: *NvPtx,
84 module: *Module,
85 decl: *const Module.Decl,
86 exports: []const *Module.Export,
87) !void {
88 if (!build_options.have_llvm) return;
89 if (build_options.skip_non_native and builtin.object_format != .nvptx) {
90 @panic("Attempted to compile for object format that was disabled by build configuration");
91 }
92 return self.llvm_object.updateDeclExports(module, decl, exports);
93}
94
95pub fn freeDecl(self: *NvPtx, decl: *Module.Decl) void {
96 if (!build_options.have_llvm) return;
97 return self.llvm_object.freeDecl(decl);
98}
99
100pub fn flush(self: *NvPtx, comp: *Compilation) !void {
101 return self.flushModule(comp);
102}
103
104pub fn flushModule(self: *NvPtx, comp: *Compilation) !void {
105 if (!build_options.have_llvm) return;
106 if (build_options.skip_non_native) {
107 @panic("Attempted to compile for architecture that was disabled by build configuration");
108 }
109 const tracy = trace(@src());
110 defer tracy.end();
111
112 var hack_comp = comp;
113 if (comp.bin_file.options.emit) |emit| {
114 hack_comp.emit_asm = .{
115 .directory = emit.directory,
116 .basename = comp.bin_file.intermediary_basename.?,
117 };
118 hack_comp.bin_file.options.emit = null;
119 }
120
121 return try self.llvm_object.flushModule(hack_comp);
122}
src/stage1/all_types.hpp+2-1
...@@ -83,7 +83,8 @@ enum CallingConvention {...@@ -83,7 +83,8 @@ enum CallingConvention {
83 CallingConventionAPCS,83 CallingConventionAPCS,
84 CallingConventionAAPCS,84 CallingConventionAAPCS,
85 CallingConventionAAPCSVFP,85 CallingConventionAAPCSVFP,
86 CallingConventionSysV86 CallingConventionSysV,
87 CallingConventionPtxKernel
87};88};
8889
89// Stage 1 supports only the generic address space90// Stage 1 supports only the generic address space
src/stage1/analyze.cpp+12
...@@ -991,6 +991,7 @@ const char *calling_convention_name(CallingConvention cc) {...@@ -991,6 +991,7 @@ const char *calling_convention_name(CallingConvention cc) {
991 case CallingConventionAAPCSVFP: return "AAPCSVFP";991 case CallingConventionAAPCSVFP: return "AAPCSVFP";
992 case CallingConventionInline: return "Inline";992 case CallingConventionInline: return "Inline";
993 case CallingConventionSysV: return "SysV";993 case CallingConventionSysV: return "SysV";
994 case CallingConventionPtxKernel: return "PtxKernel";
994 }995 }
995 zig_unreachable();996 zig_unreachable();
996}997}
...@@ -1000,6 +1001,7 @@ bool calling_convention_allows_zig_types(CallingConvention cc) {...@@ -1000,6 +1001,7 @@ bool calling_convention_allows_zig_types(CallingConvention cc) {
1000 case CallingConventionUnspecified:1001 case CallingConventionUnspecified:
1001 case CallingConventionAsync:1002 case CallingConventionAsync:
1002 case CallingConventionInline:1003 case CallingConventionInline:
1004 case CallingConventionPtxKernel:
1003 return true;1005 return true;
1004 case CallingConventionC:1006 case CallingConventionC:
1005 case CallingConventionNaked:1007 case CallingConventionNaked:
...@@ -2006,6 +2008,15 @@ Error emit_error_unless_callconv_allowed_for_target(CodeGen *g, AstNode *source_...@@ -2006,6 +2008,15 @@ Error emit_error_unless_callconv_allowed_for_target(CodeGen *g, AstNode *source_
2006 case CallingConventionSysV:2008 case CallingConventionSysV:
2007 if (g->zig_target->arch != ZigLLVM_x86_64)2009 if (g->zig_target->arch != ZigLLVM_x86_64)
2008 allowed_platforms = "x86_64";2010 allowed_platforms = "x86_64";
2011 break;
2012 case CallingConventionPtxKernel:
2013 if (g->zig_target->arch != ZigLLVM_nvptx
2014 && g->zig_target->arch != ZigLLVM_nvptx64)
2015 {
2016 allowed_platforms = "nvptx and nvptx64";
2017 }
2018 break;
2019
2009 }2020 }
2010 if (allowed_platforms != nullptr) {2021 if (allowed_platforms != nullptr) {
2011 add_node_error(g, source_node, buf_sprintf(2022 add_node_error(g, source_node, buf_sprintf(
...@@ -3827,6 +3838,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3827,6 +3838,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3827 case CallingConventionAAPCS:3838 case CallingConventionAAPCS:
3828 case CallingConventionAAPCSVFP:3839 case CallingConventionAAPCSVFP:
3829 case CallingConventionSysV:3840 case CallingConventionSysV:
3841 case CallingConventionPtxKernel:
3830 add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name),3842 add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name),
3831 GlobalLinkageIdStrong, fn_cc);3843 GlobalLinkageIdStrong, fn_cc);
3832 break;3844 break;
src/stage1/codegen.cpp+6
...@@ -209,6 +209,11 @@ static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) {...@@ -209,6 +209,11 @@ static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
209 case CallingConventionSysV:209 case CallingConventionSysV:
210 assert(g->zig_target->arch == ZigLLVM_x86_64);210 assert(g->zig_target->arch == ZigLLVM_x86_64);
211 return ZigLLVM_X86_64_SysV;211 return ZigLLVM_X86_64_SysV;
212 case CallingConventionPtxKernel:
213 assert(g->zig_target->arch == ZigLLVM_nvptx ||
214 g->zig_target->arch == ZigLLVM_nvptx64);
215 return ZigLLVM_PTX_Kernel;
216
212 }217 }
213 zig_unreachable();218 zig_unreachable();
214}219}
...@@ -354,6 +359,7 @@ static bool cc_want_sret_attr(CallingConvention cc) {...@@ -354,6 +359,7 @@ static bool cc_want_sret_attr(CallingConvention cc) {
354 case CallingConventionAAPCS:359 case CallingConventionAAPCS:
355 case CallingConventionAAPCSVFP:360 case CallingConventionAAPCSVFP:
356 case CallingConventionSysV:361 case CallingConventionSysV:
362 case CallingConventionPtxKernel:
357 return true;363 return true;
358 case CallingConventionAsync:364 case CallingConventionAsync:
359 case CallingConventionUnspecified:365 case CallingConventionUnspecified:
src/stage1/ir.cpp+1
...@@ -11666,6 +11666,7 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns...@@ -11666,6 +11666,7 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns
11666 case CallingConventionAAPCS:11666 case CallingConventionAAPCS:
11667 case CallingConventionAAPCSVFP:11667 case CallingConventionAAPCSVFP:
11668 case CallingConventionSysV:11668 case CallingConventionSysV:
11669 case CallingConventionPtxKernel:
11669 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc);11670 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc);
11670 fn_entry->section_name = section_name;11671 fn_entry->section_name = section_name;
11671 break;11672 break;