aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-08-30 12:43:10 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-08-30 12:50:15 -0700
commit7377dce368090e3c49a15d8996cc812adadd3d43 (patch)
tree6d9714e54fa2223aa6842d8d496d5f3dadd360e8 /src/codegen
parent65d37239682b6418b6dd25f07187ae99088e67f0 (diff)
downloadzig-7377dce368090e3c49a15d8996cc812adadd3d43.tar.gz
zig-7377dce368090e3c49a15d8996cc812adadd3d43.zip
avoid exposing supportsTailCall in the standard library
This is problematic because in practice it depends on whether the compiler backend supports it too, as evidenced by the TODO comment about LLVM not supporting some architectures that in fact do support tail calls. Instead this logic is organized strategically in src/target.zig, part of the internal compiler source code, and the behavior tests in question duplicate some logic for deciding whether to proceed with the test. The proper place to expose this flag is in `@import("builtin")` - the generated source file - so that third party compilers can advertise whether they support tail calls.
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/llvm.zig110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 93d2eaa9df..45426c5ee0 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -177,6 +177,116 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
return llvm_triple.toOwnedSliceSentinel(0);
}
+pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType {
+ return switch (os_tag) {
+ .freestanding, .other, .opencl, .glsl450, .vulkan, .plan9 => .UnknownOS,
+ .windows, .uefi => .Win32,
+ .ananas => .Ananas,
+ .cloudabi => .CloudABI,
+ .dragonfly => .DragonFly,
+ .freebsd => .FreeBSD,
+ .fuchsia => .Fuchsia,
+ .ios => .IOS,
+ .kfreebsd => .KFreeBSD,
+ .linux => .Linux,
+ .lv2 => .Lv2,
+ .macos => .MacOSX,
+ .netbsd => .NetBSD,
+ .openbsd => .OpenBSD,
+ .solaris => .Solaris,
+ .zos => .ZOS,
+ .haiku => .Haiku,
+ .minix => .Minix,
+ .rtems => .RTEMS,
+ .nacl => .NaCl,
+ .aix => .AIX,
+ .cuda => .CUDA,
+ .nvcl => .NVCL,
+ .amdhsa => .AMDHSA,
+ .ps4 => .PS4,
+ .elfiamcu => .ELFIAMCU,
+ .tvos => .TvOS,
+ .watchos => .WatchOS,
+ .mesa3d => .Mesa3D,
+ .contiki => .Contiki,
+ .amdpal => .AMDPAL,
+ .hermit => .HermitCore,
+ .hurd => .Hurd,
+ .wasi => .WASI,
+ .emscripten => .Emscripten,
+ };
+}
+
+pub fn targetArch(arch_tag: std.Target.Cpu.Arch) llvm.ArchType {
+ return switch (arch_tag) {
+ .arm => .arm,
+ .armeb => .armeb,
+ .aarch64 => .aarch64,
+ .aarch64_be => .aarch64_be,
+ .aarch64_32 => .aarch64_32,
+ .arc => .arc,
+ .avr => .avr,
+ .bpfel => .bpfel,
+ .bpfeb => .bpfeb,
+ .csky => .csky,
+ .hexagon => .hexagon,
+ .m68k => .m68k,
+ .mips => .mips,
+ .mipsel => .mipsel,
+ .mips64 => .mips64,
+ .mips64el => .mips64el,
+ .msp430 => .msp430,
+ .powerpc => .ppc,
+ .powerpcle => .ppcle,
+ .powerpc64 => .ppc64,
+ .powerpc64le => .ppc64le,
+ .r600 => .r600,
+ .amdgcn => .amdgcn,
+ .riscv32 => .riscv32,
+ .riscv64 => .riscv64,
+ .sparc => .sparc,
+ .sparc64 => .sparcv9, // In LLVM, sparc64 == sparcv9.
+ .sparcel => .sparcel,
+ .s390x => .systemz,
+ .tce => .tce,
+ .tcele => .tcele,
+ .thumb => .thumb,
+ .thumbeb => .thumbeb,
+ .i386 => .x86,
+ .x86_64 => .x86_64,
+ .xcore => .xcore,
+ .nvptx => .nvptx,
+ .nvptx64 => .nvptx64,
+ .le32 => .le32,
+ .le64 => .le64,
+ .amdil => .amdil,
+ .amdil64 => .amdil64,
+ .hsail => .hsail,
+ .hsail64 => .hsail64,
+ .spir => .spir,
+ .spir64 => .spir64,
+ .kalimba => .kalimba,
+ .shave => .shave,
+ .lanai => .lanai,
+ .wasm32 => .wasm32,
+ .wasm64 => .wasm64,
+ .renderscript32 => .renderscript32,
+ .renderscript64 => .renderscript64,
+ .ve => .ve,
+ .spu_2, .spirv32, .spirv64 => .UnknownArch,
+ };
+}
+
+pub fn supportsTailCall(target: std.Target) bool {
+ switch (target.cpu.arch) {
+ .wasm32, .wasm64 => return std.Target.wasm.featureSetHas(target.cpu.features, .tail_call),
+ // Although these ISAs support tail calls, LLVM does not support tail calls on them.
+ .mips, .mipsel, .mips64, .mips64el => return false,
+ .powerpc, .powerpcle, .powerpc64, .powerpc64le => return false,
+ else => return true,
+ }
+}
+
pub const Object = struct {
gpa: Allocator,
module: *Module,