From ade10387a583351fe597b58c4c9ceb97d959adf5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 26 Feb 2019 15:51:32 -0500 Subject: [PATCH] breaking changes to the way targets work in zig * CLI: `-target [name]` instead of `--target-*` args. This matches clang's API. * `builtin.Environ` renamed to `builtin.Abi` - likewise `builtin.environ` renamed to `builtin.abi` * stop hiding the concept of sub-arch. closes #1526 * `zig targets` only shows available targets. closes #438 * include all targets in readme, even those that don't print with `zig targets` but note they are Tier 4 * refactor target.cpp and make the naming conventions more consistent * introduce the concept of a "default C ABI" for a given OS/Arch combo. As a rule of thumb, if the system compiler is clang or gcc then the default C ABI is the gnu ABI. --- README.md | 57 ++- doc/docgen.zig | 9 +- src-self-hosted/link.zig | 4 +- src-self-hosted/main.zig | 18 +- src-self-hosted/target.zig | 240 ++------- src/all_types.hpp | 3 +- src/analyze.cpp | 2 +- src/buffer.hpp | 4 +- src/codegen.cpp | 120 +++-- src/error.cpp | 5 + src/error.hpp | 5 + src/libc_installation.cpp | 18 +- src/link.cpp | 34 +- src/main.cpp | 83 ++-- src/target.cpp | 795 ++++++++++++++++++++---------- src/target.hpp | 67 ++- src/util.hpp | 11 +- src/zig_llvm.cpp | 2 +- src/zig_llvm.h | 5 +- std/build.zig | 59 ++- std/fmt/index.zig | 2 +- std/os/linux/index.zig | 2 +- std/special/bootstrap.zig | 2 +- std/special/compiler_rt/index.zig | 58 +-- test/tests.zig | 10 +- 25 files changed, 875 insertions(+), 740 deletions(-) diff --git a/README.md b/README.md index c6d6e8895a..5244b49867 100644 --- a/README.md +++ b/README.md @@ -77,39 +77,54 @@ clarity. - what sizes are the C integer types - C ABI calling convention for this target - bootstrap code and default panic handler + * `zig targets` is guaranteed to include this target. #### Tier 4 Support * Support for these targets is entirely experimental. * LLVM may have the target as an experimental target, which means that you need to use Zig-provided binaries for the target to be available, or - build LLVM from source with special configure flags. + build LLVM from source with special configure flags. `zig targets` will + display the target if it is available. * This target may be considered deprecated by an official party, [such as macosx/i386](https://support.apple.com/en-us/HT208436) in which case this target will remain forever stuck in Tier 4. + * This target may only support `--emit asm` and cannot emit object files. #### Support Table -| | freestanding | linux | macosx | windows | freebsd | netbsd | UEFI | other | -|--------|--------------|--------|--------|---------|---------|------- | -------|--------| -|x86_64 | Tier 2 | Tier 1 | Tier 1 | Tier 1 | Tier 2 | Tier 2 | Tier 2 | Tier 3 | -|i386 | Tier 2 | Tier 2 | Tier 4 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|arm | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|arm64 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|bpf | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|hexagon | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|mips | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|powerpc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|r600 | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|amdgcn | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|sparc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|s390x | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|spir | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|lanai | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|wasm32 | Tier 4 | N/A | N/A | N/A | N/A | N/A | N/A | N/A | -|wasm64 | Tier 4 | N/A | N/A | N/A | N/A | N/A | N/A | N/A | -|riscv32 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | Tier 4 | Tier 4 | -|riscv64 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | Tier 4 | Tier 4 | +| | freestanding | linux | macosx | windows | freebsd | netbsd | UEFI | other | +|-------------|--------------|--------|--------|---------|---------|------- | -------|--------| +|x86_64 | Tier 2 | Tier 1 | Tier 1 | Tier 1 | Tier 2 | Tier 2 | Tier 2 | Tier 3 | +|i386 | Tier 2 | Tier 2 | Tier 4 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | +|arm | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | +|arm64 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | +|avr | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|bpf | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|hexagon | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|mips | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|powerpc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|amdgcn | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|sparc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|s390x | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|lanai | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|wasm32 | Tier 4 | N/A | N/A | N/A | N/A | N/A | N/A | N/A | +|wasm64 | Tier 4 | N/A | N/A | N/A | N/A | N/A | N/A | N/A | +|riscv32 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | Tier 4 | Tier 4 | +|riscv64 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | Tier 4 | Tier 4 | +|xcore | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|nvptx | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|msp430 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|r600 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|arc | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|tce | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|le | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|amdil | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|hsail | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|spir | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|kalimba | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|shave | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | +|renderscript | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 | ## Community diff --git a/doc/docgen.zig b/doc/docgen.zig index 082f308a57..cea456a98d 100644 --- a/doc/docgen.zig +++ b/doc/docgen.zig @@ -1105,14 +1105,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var }, } if (code.target_windows) { - try test_args.appendSlice([][]const u8{ - "--target-os", - "windows", - "--target-arch", - "x86_64", - "--target-environ", - "msvc", - }); + try test_args.appendSlice([][]const u8{ "-target", "x86_64-windows" }); } const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed"); const escaped_stderr = try escapeHtml(allocator, result.stderr); diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index 2d8c0b92c2..5689ee7925 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -326,7 +326,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void { switch (ctx.comp.target.getArch()) { builtin.Arch.i386 => try ctx.args.append(c"-MACHINE:X86"), builtin.Arch.x86_64 => try ctx.args.append(c"-MACHINE:X64"), - builtin.Arch.aarch64v8 => try ctx.args.append(c"-MACHINE:ARM"), + builtin.Arch.aarch64 => try ctx.args.append(c"-MACHINE:ARM"), else => return error.UnsupportedLinkArchitecture, } @@ -552,7 +552,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { } }, DarwinPlatform.Kind.IPhoneOS => { - if (ctx.comp.target.getArch() == builtin.Arch.aarch64v8) { + if (ctx.comp.target.getArch() == builtin.Arch.aarch64) { // iOS does not need any crt1 files for arm64 } else if (platform.versionLessThan(3, 1)) { try ctx.args.append(c"-lcrt1.o"); diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 42556beaed..4c3edf6d5d 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -154,9 +154,7 @@ const usage_build_generic = \\ release-small optimize for small binary, safety off \\ --static Output will be statically linked \\ --strip Exclude debug symbols - \\ --target-arch [name] Specify target architecture - \\ --target-environ [name] Specify target environment - \\ --target-os [name] Specify target operating system + \\ -target [name] -- see the targets command \\ --verbose-tokenize Turn on compiler debug output for tokenization \\ --verbose-ast-tree Turn on compiler debug output for parsing into an AST (tree view) \\ --verbose-ast-fmt Turn on compiler debug output for parsing into an AST (render source) @@ -220,9 +218,7 @@ const args_build_generic = []Flag{ Flag.Bool("--pkg-end"), Flag.Bool("--static"), Flag.Bool("--strip"), - Flag.Arg1("--target-arch"), - Flag.Arg1("--target-environ"), - Flag.Arg1("--target-os"), + Flag.Arg1("-target"), Flag.Bool("--verbose-tokenize"), Flag.Bool("--verbose-ast-tree"), Flag.Bool("--verbose-ast-fmt"), @@ -839,15 +835,15 @@ fn cmdTargets(allocator: *Allocator, args: []const []const u8) !void { } try stdout.write("\n"); - try stdout.write("Environments:\n"); + try stdout.write("C ABIs:\n"); { comptime var i: usize = 0; - inline while (i < @memberCount(builtin.Environ)) : (i += 1) { - comptime const environ_tag = @memberName(builtin.Environ, i); + inline while (i < @memberCount(builtin.Abi)) : (i += 1) { + comptime const abi_tag = @memberName(builtin.Abi, i); // NOTE: Cannot use empty string, see #918. - comptime const native_str = if (comptime mem.eql(u8, environ_tag, @tagName(builtin.environ))) " (native)\n" else "\n"; + comptime const native_str = if (comptime mem.eql(u8, abi_tag, @tagName(builtin.abi))) " (native)\n" else "\n"; - try stdout.print(" {}{}", environ_tag, native_str); + try stdout.print(" {}{}", abi_tag, native_str); } } } diff --git a/src-self-hosted/target.zig b/src-self-hosted/target.zig index 121242b505..5fb7146c40 100644 --- a/src-self-hosted/target.zig +++ b/src-self-hosted/target.zig @@ -16,7 +16,7 @@ pub const Target = union(enum) { pub const Cross = struct { arch: builtin.Arch, os: builtin.Os, - environ: builtin.Environ, + abi: builtin.Abi, object_format: builtin.ObjectFormat, }; @@ -49,16 +49,16 @@ pub const Target = union(enum) { } pub fn getArch(self: Target) builtin.Arch { - return switch (self) { - Target.Native => builtin.arch, - @TagType(Target).Cross => |t| t.arch, - }; + switch (self) { + Target.Native => return builtin.arch, + @TagType(Target).Cross => |t| return t.arch, + } } - pub fn getEnviron(self: Target) builtin.Environ { + pub fn getAbi(self: Target) builtin.Abi { return switch (self) { - Target.Native => builtin.environ, - @TagType(Target).Cross => |t| t.environ, + Target.Native => builtin.abi, + @TagType(Target).Cross => |t| t.abi, }; } @@ -93,46 +93,10 @@ pub const Target = union(enum) { /// TODO expose the arch and subarch separately pub fn isArmOrThumb(self: Target) bool { return switch (self.getArch()) { - builtin.Arch.armv8_3a, - builtin.Arch.armv8_2a, - builtin.Arch.armv8_1a, - builtin.Arch.armv8, - builtin.Arch.armv8r, - builtin.Arch.armv8m_baseline, - builtin.Arch.armv8m_mainline, - builtin.Arch.armv7, - builtin.Arch.armv7em, - builtin.Arch.armv7m, - builtin.Arch.armv7s, - builtin.Arch.armv7k, - builtin.Arch.armv7ve, - builtin.Arch.armv6, - builtin.Arch.armv6m, - builtin.Arch.armv6k, - builtin.Arch.armv6t2, - builtin.Arch.armv5, - builtin.Arch.armv5te, - builtin.Arch.armv4t, - builtin.Arch.armebv8_3a, - builtin.Arch.armebv8_2a, - builtin.Arch.armebv8_1a, - builtin.Arch.armebv8, - builtin.Arch.armebv8r, - builtin.Arch.armebv8m_baseline, - builtin.Arch.armebv8m_mainline, - builtin.Arch.armebv7, - builtin.Arch.armebv7em, - builtin.Arch.armebv7m, - builtin.Arch.armebv7s, - builtin.Arch.armebv7k, - builtin.Arch.armebv7ve, - builtin.Arch.armebv6, - builtin.Arch.armebv6m, - builtin.Arch.armebv6k, - builtin.Arch.armebv6t2, - builtin.Arch.armebv5, - builtin.Arch.armebv5te, - builtin.Arch.armebv4t, + builtin.Arch.arm, + builtin.Arch.armeb, + builtin.Arch.aarch64, + builtin.Arch.aarch64_be, builtin.Arch.thumb, builtin.Arch.thumbeb, => true, @@ -155,14 +119,14 @@ pub const Target = union(enum) { // LLVM WebAssembly output support requires the target to be activated at // build type with -DCMAKE_LLVM_EXPIERMENTAL_TARGETS_TO_BUILD=WebAssembly. // - // LLVM determines the output format based on the environment suffix, + // LLVM determines the output format based on the abi suffix, // defaulting to an object based on the architecture. The default format in // LLVM 6 sets the wasm arch output incorrectly to ELF. We need to // explicitly set this ourself in order for it to work. // // This is fixed in LLVM 7 and you will be able to get wasm output by // using the target triple `wasm32-unknown-unknown-unknown`. - const env_name = if (self.isWasm()) "wasm" else @tagName(self.getEnviron()); + const env_name = if (self.isWasm()) "wasm" else @tagName(self.getAbi()); var out = &std.io.BufferOutStream.init(&result).stream; try out.print("{}-unknown-{}-{}", @tagName(self.getArch()), @tagName(self.getOs()), env_name); @@ -181,46 +145,8 @@ pub const Target = union(enum) { => return 16, builtin.Arch.arc, - builtin.Arch.armv8_3a, - builtin.Arch.armv8_2a, - builtin.Arch.armv8_1a, - builtin.Arch.armv8, - builtin.Arch.armv8r, - builtin.Arch.armv8m_baseline, - builtin.Arch.armv8m_mainline, - builtin.Arch.armv7, - builtin.Arch.armv7em, - builtin.Arch.armv7m, - builtin.Arch.armv7s, - builtin.Arch.armv7k, - builtin.Arch.armv7ve, - builtin.Arch.armv6, - builtin.Arch.armv6m, - builtin.Arch.armv6k, - builtin.Arch.armv6t2, - builtin.Arch.armv5, - builtin.Arch.armv5te, - builtin.Arch.armv4t, - builtin.Arch.armebv8_3a, - builtin.Arch.armebv8_2a, - builtin.Arch.armebv8_1a, - builtin.Arch.armebv8, - builtin.Arch.armebv8r, - builtin.Arch.armebv8m_baseline, - builtin.Arch.armebv8m_mainline, - builtin.Arch.armebv7, - builtin.Arch.armebv7em, - builtin.Arch.armebv7m, - builtin.Arch.armebv7s, - builtin.Arch.armebv7k, - builtin.Arch.armebv7ve, - builtin.Arch.armebv6, - builtin.Arch.armebv6m, - builtin.Arch.armebv6k, - builtin.Arch.armebv6t2, - builtin.Arch.armebv5, - builtin.Arch.armebv5te, - builtin.Arch.armebv4t, + builtin.Arch.arm, + builtin.Arch.armeb, builtin.Arch.hexagon, builtin.Arch.le32, builtin.Arch.mips, @@ -241,29 +167,15 @@ pub const Target = union(enum) { builtin.Arch.amdil, builtin.Arch.hsail, builtin.Arch.spir, - builtin.Arch.kalimbav3, - builtin.Arch.kalimbav4, - builtin.Arch.kalimbav5, + builtin.Arch.kalimba, builtin.Arch.shave, builtin.Arch.lanai, builtin.Arch.wasm32, builtin.Arch.renderscript32, => return 32, - builtin.Arch.aarch64v8_3a, - builtin.Arch.aarch64v8_2a, - builtin.Arch.aarch64v8_1a, - builtin.Arch.aarch64v8, - builtin.Arch.aarch64v8r, - builtin.Arch.aarch64v8m_baseline, - builtin.Arch.aarch64v8m_mainline, - builtin.Arch.aarch64_bev8_3a, - builtin.Arch.aarch64_bev8_2a, - builtin.Arch.aarch64_bev8_1a, - builtin.Arch.aarch64_bev8, - builtin.Arch.aarch64_bev8r, - builtin.Arch.aarch64_bev8m_baseline, - builtin.Arch.aarch64_bev8m_mainline, + builtin.Arch.aarch64, + builtin.Arch.aarch64_be, builtin.Arch.mips64, builtin.Arch.mips64el, builtin.Arch.powerpc64, @@ -287,17 +199,17 @@ pub const Target = union(enum) { } pub fn getFloatAbi(self: Target) FloatAbi { - return switch (self.getEnviron()) { - builtin.Environ.gnueabihf, - builtin.Environ.eabihf, - builtin.Environ.musleabihf, + return switch (self.getAbi()) { + builtin.Abi.gnueabihf, + builtin.Abi.eabihf, + builtin.Abi.musleabihf, => FloatAbi.Hard, else => FloatAbi.Soft, }; } pub fn getDynamicLinkerPath(self: Target) ?[]const u8 { - const env = self.getEnviron(); + const env = self.getAbi(); const arch = self.getArch(); const os = self.getOs(); switch (os) { @@ -306,21 +218,21 @@ pub const Target = union(enum) { }, builtin.Os.linux => { switch (env) { - builtin.Environ.android => { + builtin.Abi.android => { if (self.is64bit()) { return "/system/bin/linker64"; } else { return "/system/bin/linker"; } }, - builtin.Environ.gnux32 => { + builtin.Abi.gnux32 => { if (arch == builtin.Arch.x86_64) { return "/libx32/ld-linux-x32.so.2"; } }, - builtin.Environ.musl, - builtin.Environ.musleabi, - builtin.Environ.musleabihf, + builtin.Abi.musl, + builtin.Abi.musleabi, + builtin.Abi.musleabihf, => { if (arch == builtin.Arch.x86_64) { return "/lib/ld-musl-x86_64.so.1"; @@ -334,70 +246,18 @@ pub const Target = union(enum) { builtin.Arch.sparcel, => return "/lib/ld-linux.so.2", - builtin.Arch.aarch64v8_3a, - builtin.Arch.aarch64v8_2a, - builtin.Arch.aarch64v8_1a, - builtin.Arch.aarch64v8, - builtin.Arch.aarch64v8r, - builtin.Arch.aarch64v8m_baseline, - builtin.Arch.aarch64v8m_mainline, - => return "/lib/ld-linux-aarch64.so.1", + builtin.Arch.aarch64 => return "/lib/ld-linux-aarch64.so.1", - builtin.Arch.aarch64_bev8_3a, - builtin.Arch.aarch64_bev8_2a, - builtin.Arch.aarch64_bev8_1a, - builtin.Arch.aarch64_bev8, - builtin.Arch.aarch64_bev8r, - builtin.Arch.aarch64_bev8m_baseline, - builtin.Arch.aarch64_bev8m_mainline, - => return "/lib/ld-linux-aarch64_be.so.1", + builtin.Arch.aarch64_be => return "/lib/ld-linux-aarch64_be.so.1", - builtin.Arch.armv8_3a, - builtin.Arch.armv8_2a, - builtin.Arch.armv8_1a, - builtin.Arch.armv8, - builtin.Arch.armv8r, - builtin.Arch.armv8m_baseline, - builtin.Arch.armv8m_mainline, - builtin.Arch.armv7, - builtin.Arch.armv7em, - builtin.Arch.armv7m, - builtin.Arch.armv7s, - builtin.Arch.armv7k, - builtin.Arch.armv7ve, - builtin.Arch.armv6, - builtin.Arch.armv6m, - builtin.Arch.armv6k, - builtin.Arch.armv6t2, - builtin.Arch.armv5, - builtin.Arch.armv5te, - builtin.Arch.armv4t, + builtin.Arch.arm, builtin.Arch.thumb, => return switch (self.getFloatAbi()) { FloatAbi.Hard => return "/lib/ld-linux-armhf.so.3", else => return "/lib/ld-linux.so.3", }, - builtin.Arch.armebv8_3a, - builtin.Arch.armebv8_2a, - builtin.Arch.armebv8_1a, - builtin.Arch.armebv8, - builtin.Arch.armebv8r, - builtin.Arch.armebv8m_baseline, - builtin.Arch.armebv8m_mainline, - builtin.Arch.armebv7, - builtin.Arch.armebv7em, - builtin.Arch.armebv7m, - builtin.Arch.armebv7s, - builtin.Arch.armebv7k, - builtin.Arch.armebv7ve, - builtin.Arch.armebv6, - builtin.Arch.armebv6m, - builtin.Arch.armebv6k, - builtin.Arch.armebv6t2, - builtin.Arch.armebv5, - builtin.Arch.armebv5te, - builtin.Arch.armebv4t, + builtin.Arch.armeb, builtin.Arch.thumbeb, => return switch (self.getFloatAbi()) { FloatAbi.Hard => return "/lib/ld-linux-armhf.so.3", @@ -441,9 +301,7 @@ pub const Target = union(enum) { builtin.Arch.hsail64, builtin.Arch.spir, builtin.Arch.spir64, - builtin.Arch.kalimbav3, - builtin.Arch.kalimbav4, - builtin.Arch.kalimbav5, + builtin.Arch.kalimba, builtin.Arch.shave, builtin.Arch.lanai, builtin.Arch.wasm32, @@ -566,35 +424,9 @@ pub const Target = union(enum) { pub fn getDarwinArchString(self: Target) []const u8 { const arch = self.getArch(); switch (arch) { - builtin.Arch.aarch64v8_3a, - builtin.Arch.aarch64v8_2a, - builtin.Arch.aarch64v8_1a, - builtin.Arch.aarch64v8, - builtin.Arch.aarch64v8r, - builtin.Arch.aarch64v8m_baseline, - builtin.Arch.aarch64v8m_mainline, - => return "arm64", + builtin.Arch.aarch64 => return "arm64", builtin.Arch.thumb, - builtin.Arch.armv8_3a, - builtin.Arch.armv8_2a, - builtin.Arch.armv8_1a, - builtin.Arch.armv8, - builtin.Arch.armv8r, - builtin.Arch.armv8m_baseline, - builtin.Arch.armv8m_mainline, - builtin.Arch.armv7, - builtin.Arch.armv7em, - builtin.Arch.armv7m, - builtin.Arch.armv7s, - builtin.Arch.armv7k, - builtin.Arch.armv7ve, - builtin.Arch.armv6, - builtin.Arch.armv6m, - builtin.Arch.armv6k, - builtin.Arch.armv6t2, - builtin.Arch.armv5, - builtin.Arch.armv5te, - builtin.Arch.armv4t, + builtin.Arch.arm, => return "arm", builtin.Arch.powerpc => return "ppc", builtin.Arch.powerpc64 => return "ppc64", diff --git a/src/all_types.hpp b/src/all_types.hpp index fcd4f35b3a..6876aaa3ba 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1784,7 +1784,8 @@ struct CodeGen { unsigned pointer_size_bytes; uint32_t target_os_index; uint32_t target_arch_index; - uint32_t target_environ_index; + uint32_t target_sub_arch_index; + uint32_t target_abi_index; uint32_t target_oformat_index; bool is_big_endian; bool have_pub_main; diff --git a/src/analyze.cpp b/src/analyze.cpp index 5d9b0df8ee..a6c158a780 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1102,7 +1102,7 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) { if (type_is_c_abi_int(g, fn_type_id->return_type)) { return false; } - if (g->zig_target->arch.arch == ZigLLVM_x86_64) { + if (g->zig_target->arch == ZigLLVM_x86_64) { X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type); return abi_class == X64CABIClass_MEMORY; } else if (target_is_arm(g->zig_target)) { diff --git a/src/buffer.hpp b/src/buffer.hpp index afe9fd8a91..e286f7dc63 100644 --- a/src/buffer.hpp +++ b/src/buffer.hpp @@ -132,9 +132,7 @@ void buf_appendf(Buf *buf, const char *format, ...) static inline bool buf_eql_mem(Buf *buf, const char *mem, size_t mem_len) { assert(buf->list.length); - if (buf_len(buf) != mem_len) - return false; - return memcmp(buf_ptr(buf), mem, mem_len) == 0; + return mem_eql_mem(buf_ptr(buf), buf_len(buf), mem, mem_len); } static inline bool buf_eql_str(Buf *buf, const char *str) { diff --git a/src/codegen.cpp b/src/codegen.cpp index b7230328c3..4e8cd070f4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -29,9 +29,9 @@ static void init_darwin_native(CodeGen *g) { // Allow conflicts among OSX and iOS, but choose the default platform. if (osx_target && ios_target) { - if (g->zig_target->arch.arch == ZigLLVM_arm || - g->zig_target->arch.arch == ZigLLVM_aarch64 || - g->zig_target->arch.arch == ZigLLVM_thumb) + if (g->zig_target->arch == ZigLLVM_arm || + g->zig_target->arch == ZigLLVM_aarch64 || + g->zig_target->arch == ZigLLVM_thumb) { osx_target = nullptr; } else { @@ -347,8 +347,8 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { case CallingConventionC: return LLVMCCallConv; case CallingConventionCold: // cold calling convention only works on x86. - if (g->zig_target->arch.arch == ZigLLVM_x86 || - g->zig_target->arch.arch == ZigLLVM_x86_64) + if (g->zig_target->arch == ZigLLVM_x86 || + g->zig_target->arch == ZigLLVM_x86_64) { // cold calling convention is not supported on windows if (g->zig_target->os == OsWindows) { @@ -364,7 +364,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { zig_unreachable(); case CallingConventionStdcall: // stdcall calling convention only works on x86. - if (g->zig_target->arch.arch == ZigLLVM_x86) { + if (g->zig_target->arch == ZigLLVM_x86) { return LLVMX86StdcallCallConv; } else { return LLVMCCallConv; @@ -463,7 +463,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { bool external_linkage = linkage != GlobalLinkageIdInternal; CallingConvention cc = fn_table_entry->type_entry->data.fn.fn_type_id.cc; if (cc == CallingConventionStdcall && external_linkage && - g->zig_target->arch.arch == ZigLLVM_x86) + g->zig_target->arch == ZigLLVM_x86) { // prevent llvm name mangling symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name)); @@ -2095,7 +2095,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ return true; } - if (g->zig_target->arch.arch == ZigLLVM_x86_64) { + if (g->zig_target->arch == ZigLLVM_x86_64) { X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty); size_t ty_size = type_size(g, ty); if (abi_class == X64CABIClass_MEMORY) { @@ -3344,9 +3344,9 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->type_ref; bool asm_has_side_effects = true; bool asm_is_alignstack = false; - if (g->zig_target->arch.arch == ZigLLVM_x86_64) { + if (g->zig_target->arch == ZigLLVM_x86_64) { if (g->zig_target->os == OsLinux || target_is_darwin(g->zig_target) || g->zig_target->os == OsSolaris || - (g->zig_target->os == OsWindows && g->zig_target->env_type != ZigLLVM_MSVC)) + (g->zig_target->os == OsWindows && g->zig_target->abi != ZigLLVM_MSVC)) { if (g->cur_fn->valgrind_client_request_array == nullptr) { LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); @@ -3586,7 +3586,7 @@ static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) { LLVMValueRef write_register_fn_val = get_write_register_fn_val(g); if (g->sp_md_node == nullptr) { - Buf *sp_reg_name = buf_create_from_str(arch_stack_pointer_register_name(&g->zig_target->arch)); + Buf *sp_reg_name = buf_create_from_str(arch_stack_pointer_register_name(g->zig_target->arch)); LLVMValueRef str_node = LLVMMDString(buf_ptr(sp_reg_name), buf_len(sp_reg_name) + 1); g->sp_md_node = LLVMMDNode(&str_node, 1); } @@ -7284,8 +7284,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { buf_appendf(contents, "pub const Os = enum {\n"); uint32_t field_count = (uint32_t)target_os_count(); for (uint32_t i = 0; i < field_count; i += 1) { - Os os_type = get_target_os(i); - const char *name = get_target_os_name(os_type); + Os os_type = target_os_enum(i); + const char *name = target_os_name(os_type); buf_appendf(contents, " %s,\n", name); if (os_type == g->zig_target->os) { @@ -7299,53 +7299,77 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { const char *cur_arch = nullptr; { - buf_appendf(contents, "pub const Arch = enum {\n"); + buf_appendf(contents, "pub const Arch = union(enum) {\n"); uint32_t field_count = (uint32_t)target_arch_count(); - for (uint32_t i = 0; i < field_count; i += 1) { - const ArchType *arch_type = get_target_arch(i); - Buf *arch_name = buf_alloc(); - buf_resize(arch_name, 50); - get_arch_name(buf_ptr(arch_name), arch_type); - buf_resize(arch_name, strlen(buf_ptr(arch_name))); - - buf_appendf(contents, " %s,\n", buf_ptr(arch_name)); - - if (arch_type->arch == g->zig_target->arch.arch && - arch_type->sub_arch == g->zig_target->arch.sub_arch) - { - g->target_arch_index = i; - cur_arch = buf_ptr(arch_name); + for (uint32_t arch_i = 0; arch_i < field_count; arch_i += 1) { + ZigLLVM_ArchType arch = target_arch_enum(arch_i); + const char *arch_name = target_arch_name(arch); + SubArchList sub_arch_list = target_subarch_list(arch); + if (sub_arch_list == SubArchListNone) { + buf_appendf(contents, " %s,\n", arch_name); + if (arch == g->zig_target->arch) { + g->target_arch_index = arch_i; + cur_arch = buf_ptr(buf_sprintf("Arch.%s", arch_name)); + } + } else { + const char *sub_arch_list_name = target_subarch_list_name(sub_arch_list); + buf_appendf(contents, " %s: %s,\n", arch_name, sub_arch_list_name); + if (arch == g->zig_target->arch) { + size_t sub_count = target_subarch_count(sub_arch_list); + for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) { + ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i); + if (sub == g->zig_target->sub_arch) { + g->target_sub_arch_index = sub_i; + cur_arch = buf_ptr(buf_sprintf("Arch{ .%s = Arch.%s.%s }", + arch_name, sub_arch_list_name, target_subarch_name(sub))); + } + } + } } } + + uint32_t list_count = target_subarch_list_count(); + // start at index 1 to skip None + for (uint32_t list_i = 1; list_i < list_count; list_i += 1) { + SubArchList sub_arch_list = target_subarch_list_enum(list_i); + const char *subarch_list_name = target_subarch_list_name(sub_arch_list); + buf_appendf(contents, " pub const %s = enum {\n", subarch_list_name); + size_t sub_count = target_subarch_count(sub_arch_list); + for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) { + ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i); + buf_appendf(contents, " %s,\n", target_subarch_name(sub)); + } + buf_appendf(contents, " };\n"); + } buf_appendf(contents, "};\n\n"); } assert(cur_arch != nullptr); - const char *cur_environ = nullptr; + const char *cur_abi = nullptr; { - buf_appendf(contents, "pub const Environ = enum {\n"); - uint32_t field_count = (uint32_t)target_environ_count(); + buf_appendf(contents, "pub const Abi = enum {\n"); + uint32_t field_count = (uint32_t)target_abi_count(); for (uint32_t i = 0; i < field_count; i += 1) { - ZigLLVM_EnvironmentType environ_type = get_target_environ(i); - const char *name = ZigLLVMGetEnvironmentTypeName(environ_type); + ZigLLVM_EnvironmentType abi = target_abi_enum(i); + const char *name = target_abi_name(abi); buf_appendf(contents, " %s,\n", name); - if (environ_type == g->zig_target->env_type) { - g->target_environ_index = i; - cur_environ = name; + if (abi == g->zig_target->abi) { + g->target_abi_index = i; + cur_abi = name; } } buf_appendf(contents, "};\n\n"); } - assert(cur_environ != nullptr); + assert(cur_abi != nullptr); const char *cur_obj_fmt = nullptr; { buf_appendf(contents, "pub const ObjectFormat = enum {\n"); uint32_t field_count = (uint32_t)target_oformat_count(); for (uint32_t i = 0; i < field_count; i += 1) { - ZigLLVM_ObjectFormatType oformat = get_target_oformat(i); - const char *name = get_target_oformat_name(oformat); + ZigLLVM_ObjectFormatType oformat = target_oformat_enum(i); + const char *name = target_oformat_name(oformat); buf_appendf(contents, " %s,\n", name); ZigLLVM_ObjectFormatType target_oformat = target_object_format(g->zig_target); @@ -7633,8 +7657,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); buf_appendf(contents, "pub const os = Os.%s;\n", cur_os); - buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch); - buf_appendf(contents, "pub const environ = Environ.%s;\n", cur_environ); + buf_appendf(contents, "pub const arch = %s;\n", cur_arch); + buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi); buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->libc_link_lib != nullptr)); @@ -7669,11 +7693,11 @@ static Error define_builtin_compile_vars(CodeGen *g) { cache_bool(&cache_hash, g->is_test_build); cache_bool(&cache_hash, g->is_single_threaded); cache_int(&cache_hash, g->zig_target->is_native); - cache_int(&cache_hash, g->zig_target->arch.arch); - cache_int(&cache_hash, g->zig_target->arch.sub_arch); + cache_int(&cache_hash, g->zig_target->arch); + cache_int(&cache_hash, g->zig_target->sub_arch); cache_int(&cache_hash, g->zig_target->vendor); cache_int(&cache_hash, g->zig_target->os); - cache_int(&cache_hash, g->zig_target->env_type); + cache_int(&cache_hash, g->zig_target->abi); cache_bool(&cache_hash, g->have_err_ret_tracing); cache_bool(&cache_hash, g->libc_link_lib != nullptr); cache_bool(&cache_hash, g->valgrind_support); @@ -7901,7 +7925,7 @@ static void detect_libc(CodeGen *g) { // without a cross compiling libc kit. fprintf(stderr, "Cannot link against libc for non-native OS '%s' without providing a libc installation file.\n" - "See `zig libc --help` for more details.\n", get_target_os_name(g->zig_target->os)); + "See `zig libc --help` for more details.\n", target_os_name(g->zig_target->os)); exit(1); } } @@ -8799,11 +8823,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_int(ch, g->build_mode); cache_int(ch, g->out_type); cache_bool(ch, g->zig_target->is_native); - cache_int(ch, g->zig_target->arch.arch); - cache_int(ch, g->zig_target->arch.sub_arch); + cache_int(ch, g->zig_target->arch); + cache_int(ch, g->zig_target->sub_arch); cache_int(ch, g->zig_target->vendor); cache_int(ch, g->zig_target->os); - cache_int(ch, g->zig_target->env_type); + cache_int(ch, g->zig_target->abi); cache_int(ch, g->subsystem); cache_bool(ch, g->is_static); cache_bool(ch, g->strip_debug_symbols); diff --git a/src/error.cpp b/src/error.cpp index c81cfd1683..80f7963538 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -37,6 +37,11 @@ const char *err_str(Error err) { case ErrorPathTooLong: return "path too long"; case ErrorCCompilerCannotFindFile: return "C compiler cannot find file"; case ErrorReadingDepFile: return "failed to read .d file"; + case ErrorMissingArchitecture: return "missing architecture"; + case ErrorMissingOperatingSystem: return "missing operating system"; + case ErrorUnknownArchitecture: return "unrecognized architecture"; + case ErrorUnknownOperatingSystem: return "unrecognized operating system"; + case ErrorUnknownABI: return "unrecognized C ABI"; } return "(invalid error)"; } diff --git a/src/error.hpp b/src/error.hpp index a580da547f..50dfeecc32 100644 --- a/src/error.hpp +++ b/src/error.hpp @@ -39,6 +39,11 @@ enum Error { ErrorPathTooLong, ErrorCCompilerCannotFindFile, ErrorReadingDepFile, + ErrorMissingArchitecture, + ErrorMissingOperatingSystem, + ErrorUnknownArchitecture, + ErrorUnknownOperatingSystem, + ErrorUnknownABI, }; const char *err_str(Error err); diff --git a/src/libc_installation.cpp b/src/libc_installation.cpp index 04459d78e5..6e410ad5ac 100644 --- a/src/libc_installation.cpp +++ b/src/libc_installation.cpp @@ -103,7 +103,7 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget if (buf_len(&libc->crt_dir) == 0) { if (!target_is_darwin(target)) { if (verbose) { - fprintf(stderr, "crt_dir may not be empty for %s\n", get_target_os_name(target->os)); + fprintf(stderr, "crt_dir may not be empty for %s\n", target_os_name(target->os)); } return ErrorSemanticAnalyzeFail; } @@ -112,7 +112,7 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget if (buf_len(&libc->lib_dir) == 0) { if (!target_is_darwin(target) && target->os != OsWindows) { if (verbose) { - fprintf(stderr, "lib_dir may not be empty for %s\n", get_target_os_name(target->os)); + fprintf(stderr, "lib_dir may not be empty for %s\n", target_os_name(target->os)); } return ErrorSemanticAnalyzeFail; } @@ -121,7 +121,7 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget if (buf_len(&libc->static_lib_dir) == 0) { if (!target_is_darwin(target) && target->os != OsWindows) { if (verbose) { - fprintf(stderr, "static_lib_dir may not be empty for %s\n", get_target_os_name(target->os)); + fprintf(stderr, "static_lib_dir may not be empty for %s\n", target_os_name(target->os)); } return ErrorSemanticAnalyzeFail; } @@ -130,7 +130,7 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget if (buf_len(&libc->msvc_lib_dir) == 0) { if (target->os == OsWindows) { if (verbose) { - fprintf(stderr, "msvc_lib_dir may not be empty for %s\n", get_target_os_name(target->os)); + fprintf(stderr, "msvc_lib_dir may not be empty for %s\n", target_os_name(target->os)); } return ErrorSemanticAnalyzeFail; } @@ -139,7 +139,7 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget if (buf_len(&libc->kernel32_lib_dir) == 0) { if (target->os == OsWindows) { if (verbose) { - fprintf(stderr, "kernel32_lib_dir may not be empty for %s\n", get_target_os_name(target->os)); + fprintf(stderr, "kernel32_lib_dir may not be empty for %s\n", target_os_name(target->os)); } return ErrorSemanticAnalyzeFail; } @@ -148,7 +148,7 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget if (buf_len(&libc->dynamic_linker_path) == 0) { if (!target_is_darwin(target) && target->os != OsWindows) { if (verbose) { - fprintf(stderr, "dynamic_linker_path may not be empty for %s\n", get_target_os_name(target->os)); + fprintf(stderr, "dynamic_linker_path may not be empty for %s\n", target_os_name(target->os)); } return ErrorSemanticAnalyzeFail; } @@ -334,8 +334,10 @@ static Error zig_libc_find_native_dynamic_linker_posix(ZigLibCInstallation *self #endif ZigTarget native_target; get_native_target(&native_target); - Buf *dynamic_linker_path = target_dynamic_linker(&native_target); - buf_init_from_buf(&self->dynamic_linker_path, dynamic_linker_path); + const char *dynamic_linker_path = target_dynamic_linker(&native_target); + if (dynamic_linker_path != nullptr) { + buf_init_from_str(&self->dynamic_linker_path, dynamic_linker_path); + } return ErrorNone; } #endif diff --git a/src/link.cpp b/src/link.cpp index f52eaa1374..df2eb37f0a 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -96,7 +96,7 @@ static Buf *build_compiler_rt(CodeGen *parent_gen) { } static const char *get_darwin_arch_string(const ZigTarget *t) { - switch (t->arch.arch) { + switch (t->arch) { case ZigLLVM_aarch64: return "arm64"; case ZigLLVM_thumb: @@ -109,13 +109,13 @@ static const char *get_darwin_arch_string(const ZigTarget *t) { case ZigLLVM_ppc64le: return "ppc64le"; default: - return ZigLLVMGetArchTypeName(t->arch.arch); + return ZigLLVMGetArchTypeName(t->arch); } } static const char *getLDMOption(const ZigTarget *t) { - switch (t->arch.arch) { + switch (t->arch) { case ZigLLVM_x86: return "elf_i386"; case ZigLLVM_aarch64: @@ -149,7 +149,7 @@ static const char *getLDMOption(const ZigTarget *t) { case ZigLLVM_systemz: return "elf64_s390"; case ZigLLVM_x86_64: - if (t->env_type == ZigLLVM_GNUX32) { + if (t->abi == ZigLLVM_GNUX32) { return "elf32_x86_64"; } // Any target elf will use the freebsd osabi if suffixed with "_fbsd". @@ -191,8 +191,8 @@ static void construct_linker_job_elf(LinkJob *lj) { bool shared = !g->is_static && is_lib; Buf *soname = nullptr; if (g->is_static) { - if (g->zig_target->arch.arch == ZigLLVM_arm || g->zig_target->arch.arch == ZigLLVM_armeb || - g->zig_target->arch.arch == ZigLLVM_thumb || g->zig_target->arch.arch == ZigLLVM_thumbeb) + if (g->zig_target->arch == ZigLLVM_arm || g->zig_target->arch == ZigLLVM_armeb || + g->zig_target->arch == ZigLLVM_thumb || g->zig_target->arch == ZigLLVM_thumbeb) { lj->args.append("-Bstatic"); } else { @@ -375,16 +375,16 @@ static void construct_linker_job_wasm(LinkJob *lj) { } //static bool is_target_cyg_mingw(const ZigTarget *target) { -// return (target->os == ZigLLVM_Win32 && target->env_type == ZigLLVM_Cygnus) || -// (target->os == ZigLLVM_Win32 && target->env_type == ZigLLVM_GNU); +// return (target->os == ZigLLVM_Win32 && target->abi == ZigLLVM_Cygnus) || +// (target->os == ZigLLVM_Win32 && target->abi == ZigLLVM_GNU); //} static void coff_append_machine_arg(CodeGen *g, ZigList *list) { - if (g->zig_target->arch.arch == ZigLLVM_x86) { + if (g->zig_target->arch == ZigLLVM_x86) { list->append("-MACHINE:X86"); - } else if (g->zig_target->arch.arch == ZigLLVM_x86_64) { + } else if (g->zig_target->arch == ZigLLVM_x86_64) { list->append("-MACHINE:X64"); - } else if (g->zig_target->arch.arch == ZigLLVM_arm) { + } else if (g->zig_target->arch == ZigLLVM_arm) { list->append("-MACHINE:ARM"); } } @@ -470,7 +470,7 @@ static void add_nt_link_args(LinkJob *lj, bool is_library) { // lj->args.append("-Bdynamic"); // if (dll || shared) { // lj->args.append("-e"); -// if (g->zig_target.arch.arch == ZigLLVM_x86) { +// if (g->zig_target.arch == ZigLLVM_x86) { // lj->args.append("_DllMainCRTStartup@12"); // } else { // lj->args.append("DllMainCRTStartup"); @@ -496,7 +496,7 @@ static void add_nt_link_args(LinkJob *lj, bool is_library) { //lj->args.append("-lmingw32"); //lj->args.append("-lgcc"); -//bool is_android = (g->zig_target.env_type == ZigLLVM_Android); +//bool is_android = (g->zig_target.abi == ZigLLVM_Android); //bool is_cyg_ming = is_target_cyg_mingw(&g->zig_target); //if (!g->is_static && !is_android) { // if (!is_cyg_ming) { @@ -637,7 +637,7 @@ static void construct_linker_job_coff(LinkJob *lj) { continue; } if (link_lib->provided_explicitly) { - if (lj->codegen->zig_target->env_type == ZigLLVM_GNU) { + if (lj->codegen->zig_target->abi == ZigLLVM_GNU) { Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name)); lj->args.append(buf_ptr(arg)); } @@ -764,8 +764,8 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) { } if (platform->kind == IPhoneOS && - (g->zig_target->arch.arch == ZigLLVM_x86 || - g->zig_target->arch.arch == ZigLLVM_x86_64)) + (g->zig_target->arch == ZigLLVM_x86 || + g->zig_target->arch == ZigLLVM_x86_64)) { platform->kind = IPhoneOSSimulator; } @@ -886,7 +886,7 @@ static void construct_linker_job_macho(LinkJob *lj) { } break; case IPhoneOS: - if (g->zig_target->arch.arch == ZigLLVM_aarch64) { + if (g->zig_target->arch == ZigLLVM_aarch64) { // iOS does not need any crt1 files for arm64 } else if (darwin_version_lt(&platform, 3, 1)) { lj->args.append("-lcrt1.o"); diff --git a/src/main.cpp b/src/main.cpp index 1c154250ff..6af5dc3c37 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,9 +69,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " --single-threaded source may assume it is only used single-threaded\n" " --static output will be statically linked\n" " --strip exclude debug symbols\n" - " --target-arch [name] specify target architecture\n" - " --target-environ [name] specify target environment\n" - " --target-os [name] specify target operating system\n" + " -target [name] -- see the targets command\n" " --verbose-tokenize enable compiler debug output for tokenization\n" " --verbose-ast enable compiler debug output for AST parsing\n" " --verbose-link enable compiler debug output for linking\n" @@ -145,6 +143,14 @@ static const char *ZIG_ZEN = "\n" " * Minimize energy spent on coding style.\n" " * Together we serve end users.\n"; +static bool arch_available_in_llvm(ZigLLVM_ArchType arch) { + LLVMTargetRef target_ref; + char *err_msg = nullptr; + char triple_string[128]; + sprintf(triple_string, "%s-unknown-unknown-unknown", ZigLLVMGetArchTypeName(arch)); + return !LLVMGetTargetFromTriple(triple_string, &target_ref, &err_msg); +} + static int print_target_list(FILE *f) { ZigTarget native; get_native_target(&native); @@ -152,28 +158,36 @@ static int print_target_list(FILE *f) { fprintf(f, "Architectures:\n"); size_t arch_count = target_arch_count(); for (size_t arch_i = 0; arch_i < arch_count; arch_i += 1) { - const ArchType *arch = get_target_arch(arch_i); - char arch_name[50]; - get_arch_name(arch_name, arch); - const char *native_str = (native.arch.arch == arch->arch && native.arch.sub_arch == arch->sub_arch) ? - " (native)" : ""; - fprintf(f, " %s%s\n", arch_name, native_str); + ZigLLVM_ArchType arch = target_arch_enum(arch_i); + if (!arch_available_in_llvm(arch)) + continue; + const char *arch_name = target_arch_name(arch); + SubArchList sub_arch_list = target_subarch_list(arch); + size_t sub_count = target_subarch_count(sub_arch_list); + const char *arch_native_str = (native.arch == arch) ? " (native)" : ""; + fprintf(stderr, " %s%s\n", arch_name, arch_native_str); + for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) { + ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i); + const char *sub_name = target_subarch_name(sub); + const char *sub_native_str = (native.arch == arch && native.sub_arch == sub) ? " (native)" : ""; + fprintf(f, " %s%s\n", sub_name, sub_native_str); + } } fprintf(f, "\nOperating Systems:\n"); size_t os_count = target_os_count(); for (size_t i = 0; i < os_count; i += 1) { - Os os_type = get_target_os(i); + Os os_type = target_os_enum(i); const char *native_str = (native.os == os_type) ? " (native)" : ""; - fprintf(f, " %s%s\n", get_target_os_name(os_type), native_str); + fprintf(f, " %s%s\n", target_os_name(os_type), native_str); } - fprintf(f, "\nEnvironments:\n"); - size_t environ_count = target_environ_count(); - for (size_t i = 0; i < environ_count; i += 1) { - ZigLLVM_EnvironmentType environ_type = get_target_environ(i); - const char *native_str = (native.env_type == environ_type) ? " (native)" : ""; - fprintf(f, " %s%s\n", ZigLLVMGetEnvironmentTypeName(environ_type), native_str); + fprintf(f, "\nC ABIs:\n"); + size_t abi_count = target_abi_count(); + for (size_t i = 0; i < abi_count; i += 1) { + ZigLLVM_EnvironmentType abi = target_abi_enum(i); + const char *native_str = (native.abi == abi) ? " (native)" : ""; + fprintf(f, " %s%s\n", target_abi_name(abi), native_str); } return EXIT_SUCCESS; @@ -397,9 +411,7 @@ int main(int argc, char **argv) { ZigList link_libs = {0}; ZigList forbidden_link_libs = {0}; ZigList frameworks = {0}; - const char *target_arch = nullptr; - const char *target_os = nullptr; - const char *target_environ = nullptr; + const char *target_string = nullptr; bool rdynamic = false; const char *mmacosx_version_min = nullptr; const char *mios_version_min = nullptr; @@ -740,12 +752,8 @@ int main(int argc, char **argv) { asm_files.append(argv[i]); } else if (strcmp(arg, "--cache-dir") == 0) { cache_dir = argv[i]; - } else if (strcmp(arg, "--target-arch") == 0) { - target_arch = argv[i]; - } else if (strcmp(arg, "--target-os") == 0) { - target_os = argv[i]; - } else if (strcmp(arg, "--target-environ") == 0) { - target_environ = argv[i]; + } else if (strcmp(arg, "-target") == 0) { + target_string = argv[i]; } else if (strcmp(arg, "-mmacosx-version-min") == 0) { mmacosx_version_min = argv[i]; } else if (strcmp(arg, "-mios-version-min") == 0) { @@ -874,27 +882,12 @@ int main(int argc, char **argv) { init_all_targets(); ZigTarget target; - if (!target_arch && !target_os && !target_environ) { + if (target_string == nullptr) { get_native_target(&target); } else { - get_unknown_target(&target); - if (target_arch) { - if (parse_target_arch(target_arch, &target.arch)) { - fprintf(stderr, "invalid --target-arch argument\n"); - return print_error_usage(arg0); - } - } - if (target_os) { - if (parse_target_os(target_os, &target.os)) { - fprintf(stderr, "invalid --target-os argument\n"); - return print_error_usage(arg0); - } - } - if (target_environ) { - if (parse_target_environ(target_environ, &target.env_type)) { - fprintf(stderr, "invalid --target-environ argument\n"); - return print_error_usage(arg0); - } + if ((err = target_parse_triple(&target, target_string))) { + fprintf(stderr, "invalid target: %s\n", err_str(err)); + return print_error_usage(arg0); } } diff --git a/src/target.cpp b/src/target.cpp index 49a1742945..74168033a5 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -13,115 +13,105 @@ #include -static const ArchType arch_list[] = { - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_3a}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_2a}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_1a}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8r}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8m_baseline}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8m_mainline}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7em}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7m}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7s}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7k}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7ve}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6m}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6k}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6t2}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v5}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v5te}, - {ZigLLVM_arm, ZigLLVM_ARMSubArch_v4t}, +static const SubArchList subarch_list_list[] = { + SubArchListNone, + SubArchListArm32, + SubArchListArm64, + SubArchListKalimba, +}; - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_3a}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_2a}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_1a}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8r}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8m_baseline}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8m_mainline}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7em}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7m}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7s}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7k}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7ve}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6m}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6k}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6t2}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v5}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v5te}, - {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v4t}, +static const ZigLLVM_SubArchType subarch_list_arm32[] = { + ZigLLVM_ARMSubArch_v8_4a, + ZigLLVM_ARMSubArch_v8_3a, + ZigLLVM_ARMSubArch_v8_2a, + ZigLLVM_ARMSubArch_v8_1a, + ZigLLVM_ARMSubArch_v8, + ZigLLVM_ARMSubArch_v8r, + ZigLLVM_ARMSubArch_v8m_baseline, + ZigLLVM_ARMSubArch_v8m_mainline, + ZigLLVM_ARMSubArch_v7, + ZigLLVM_ARMSubArch_v7em, + ZigLLVM_ARMSubArch_v7m, + ZigLLVM_ARMSubArch_v7s, + ZigLLVM_ARMSubArch_v7k, + ZigLLVM_ARMSubArch_v7ve, + ZigLLVM_ARMSubArch_v6, + ZigLLVM_ARMSubArch_v6m, + ZigLLVM_ARMSubArch_v6k, + ZigLLVM_ARMSubArch_v6t2, + ZigLLVM_ARMSubArch_v5, + ZigLLVM_ARMSubArch_v5te, + ZigLLVM_ARMSubArch_v4t, +}; - {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8_3a}, - {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8_2a}, - {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8_1a}, - {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8}, - {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8r}, - {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8m_baseline}, - {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8m_mainline}, +static const ZigLLVM_SubArchType subarch_list_arm64[] = { + ZigLLVM_ARMSubArch_v8_4a, + ZigLLVM_ARMSubArch_v8_3a, + ZigLLVM_ARMSubArch_v8_2a, + ZigLLVM_ARMSubArch_v8_1a, + ZigLLVM_ARMSubArch_v8, + ZigLLVM_ARMSubArch_v8r, + ZigLLVM_ARMSubArch_v8m_baseline, + ZigLLVM_ARMSubArch_v8m_mainline, +}; - {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8_3a}, - {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8_2a}, - {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8_1a}, - {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8}, - {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8r}, - {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8m_baseline}, - {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8m_mainline}, +static const ZigLLVM_SubArchType subarch_list_kalimba[] = { + ZigLLVM_KalimbaSubArch_v5, + ZigLLVM_KalimbaSubArch_v4, + ZigLLVM_KalimbaSubArch_v3, +}; - {ZigLLVM_arc, ZigLLVM_NoSubArch}, - {ZigLLVM_avr, ZigLLVM_NoSubArch}, - {ZigLLVM_bpfel, ZigLLVM_NoSubArch}, - {ZigLLVM_bpfeb, ZigLLVM_NoSubArch}, - {ZigLLVM_hexagon, ZigLLVM_NoSubArch}, - {ZigLLVM_mips, ZigLLVM_NoSubArch}, - {ZigLLVM_mipsel, ZigLLVM_NoSubArch}, - {ZigLLVM_mips64, ZigLLVM_NoSubArch}, - {ZigLLVM_mips64el, ZigLLVM_NoSubArch}, - {ZigLLVM_msp430, ZigLLVM_NoSubArch}, - {ZigLLVM_nios2, ZigLLVM_NoSubArch}, - {ZigLLVM_ppc, ZigLLVM_NoSubArch}, - {ZigLLVM_ppc64, ZigLLVM_NoSubArch}, - {ZigLLVM_ppc64le, ZigLLVM_NoSubArch}, - {ZigLLVM_r600, ZigLLVM_NoSubArch}, - {ZigLLVM_amdgcn, ZigLLVM_NoSubArch}, - {ZigLLVM_riscv32, ZigLLVM_NoSubArch}, - {ZigLLVM_riscv64, ZigLLVM_NoSubArch}, - {ZigLLVM_sparc, ZigLLVM_NoSubArch}, - {ZigLLVM_sparcv9, ZigLLVM_NoSubArch}, - {ZigLLVM_sparcel, ZigLLVM_NoSubArch}, - {ZigLLVM_systemz, ZigLLVM_NoSubArch}, - {ZigLLVM_tce, ZigLLVM_NoSubArch}, - {ZigLLVM_tcele, ZigLLVM_NoSubArch}, - {ZigLLVM_thumb, ZigLLVM_NoSubArch}, - {ZigLLVM_thumbeb, ZigLLVM_NoSubArch}, - {ZigLLVM_x86, ZigLLVM_NoSubArch}, - {ZigLLVM_x86_64, ZigLLVM_NoSubArch}, - {ZigLLVM_xcore, ZigLLVM_NoSubArch}, - {ZigLLVM_nvptx, ZigLLVM_NoSubArch}, - {ZigLLVM_nvptx64, ZigLLVM_NoSubArch}, - {ZigLLVM_le32, ZigLLVM_NoSubArch}, - {ZigLLVM_le64, ZigLLVM_NoSubArch}, - {ZigLLVM_amdil, ZigLLVM_NoSubArch}, - {ZigLLVM_amdil64, ZigLLVM_NoSubArch}, - {ZigLLVM_hsail, ZigLLVM_NoSubArch}, - {ZigLLVM_hsail64, ZigLLVM_NoSubArch}, - {ZigLLVM_spir, ZigLLVM_NoSubArch}, - {ZigLLVM_spir64, ZigLLVM_NoSubArch}, - - {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v3}, - {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v4}, - {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v5}, - - {ZigLLVM_shave, ZigLLVM_NoSubArch}, - {ZigLLVM_lanai, ZigLLVM_NoSubArch}, - {ZigLLVM_wasm32, ZigLLVM_NoSubArch}, - {ZigLLVM_wasm64, ZigLLVM_NoSubArch}, - {ZigLLVM_renderscript32, ZigLLVM_NoSubArch}, - {ZigLLVM_renderscript64, ZigLLVM_NoSubArch}, +static const ZigLLVM_ArchType arch_list[] = { + ZigLLVM_arm, + ZigLLVM_armeb, + ZigLLVM_aarch64, + ZigLLVM_aarch64_be, + ZigLLVM_arc, + ZigLLVM_avr, + ZigLLVM_bpfel, + ZigLLVM_bpfeb, + ZigLLVM_hexagon, + ZigLLVM_mips, + ZigLLVM_mipsel, + ZigLLVM_mips64, + ZigLLVM_mips64el, + ZigLLVM_msp430, + ZigLLVM_nios2, + ZigLLVM_ppc, + ZigLLVM_ppc64, + ZigLLVM_ppc64le, + ZigLLVM_r600, + ZigLLVM_amdgcn, + ZigLLVM_riscv32, + ZigLLVM_riscv64, + ZigLLVM_sparc, + ZigLLVM_sparcv9, + ZigLLVM_sparcel, + ZigLLVM_systemz, + ZigLLVM_tce, + ZigLLVM_tcele, + ZigLLVM_thumb, + ZigLLVM_thumbeb, + ZigLLVM_x86, + ZigLLVM_x86_64, + ZigLLVM_xcore, + ZigLLVM_nvptx, + ZigLLVM_nvptx64, + ZigLLVM_le32, + ZigLLVM_le64, + ZigLLVM_amdil, + ZigLLVM_amdil64, + ZigLLVM_hsail, + ZigLLVM_hsail64, + ZigLLVM_spir, + ZigLLVM_spir64, + ZigLLVM_kalimba, + ZigLLVM_shave, + ZigLLVM_lanai, + ZigLLVM_wasm32, + ZigLLVM_wasm64, + ZigLLVM_renderscript32, + ZigLLVM_renderscript64, }; static const ZigLLVM_VendorType vendor_list[] = { @@ -179,7 +169,7 @@ static const Os os_list[] = { }; // Coordinate with zig_llvm.h -static const ZigLLVM_EnvironmentType environ_list[] = { +static const ZigLLVM_EnvironmentType abi_list[] = { ZigLLVM_UnknownEnvironment, ZigLLVM_GNU, @@ -214,11 +204,12 @@ size_t target_oformat_count(void) { return array_length(oformat_list); } -ZigLLVM_ObjectFormatType get_target_oformat(size_t index) { +ZigLLVM_ObjectFormatType target_oformat_enum(size_t index) { + assert(index < array_length(oformat_list)); return oformat_list[index]; } -const char *get_target_oformat_name(ZigLLVM_ObjectFormatType oformat) { +const char *target_oformat_name(ZigLLVM_ObjectFormatType oformat) { switch (oformat) { case ZigLLVM_UnknownObjectFormat: return "unknown"; case ZigLLVM_COFF: return "coff"; @@ -233,22 +224,25 @@ size_t target_arch_count(void) { return array_length(arch_list); } -const ArchType *get_target_arch(size_t index) { - return &arch_list[index]; +ZigLLVM_ArchType target_arch_enum(size_t index) { + assert(index < array_length(arch_list)); + return arch_list[index]; } size_t target_vendor_count(void) { return array_length(vendor_list); } -ZigLLVM_VendorType get_target_vendor(size_t index) { +ZigLLVM_VendorType target_vendor_enum(size_t index) { + assert(index < array_length(vendor_list)); return vendor_list[index]; } size_t target_os_count(void) { return array_length(os_list); } -Os get_target_os(size_t index) { +Os target_os_enum(size_t index) { + assert(index < array_length(os_list)); return os_list[index]; } @@ -391,7 +385,7 @@ static Os get_zig_os_type(ZigLLVM_OSType os_type) { zig_unreachable(); } -const char *get_target_os_name(Os os_type) { +const char *target_os_name(Os os_type) { switch (os_type) { case OsFreestanding: return "freestanding"; @@ -434,80 +428,251 @@ const char *get_target_os_name(Os os_type) { zig_unreachable(); } -size_t target_environ_count(void) { - return array_length(environ_list); +size_t target_abi_count(void) { + return array_length(abi_list); } -ZigLLVM_EnvironmentType get_target_environ(size_t index) { - return environ_list[index]; +ZigLLVM_EnvironmentType target_abi_enum(size_t index) { + assert(index < array_length(abi_list)); + return abi_list[index]; +} +const char *target_abi_name(ZigLLVM_EnvironmentType abi) { + if (abi == ZigLLVM_UnknownEnvironment) + return "none"; + return ZigLLVMGetEnvironmentTypeName(abi); } void get_native_target(ZigTarget *target) { ZigLLVM_OSType os_type; ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os ZigLLVMGetNativeTarget( - &target->arch.arch, - &target->arch.sub_arch, + &target->arch, + &target->sub_arch, &target->vendor, &os_type, - &target->env_type, + &target->abi, &oformat); target->os = get_zig_os_type(os_type); target->is_native = true; + if (target->abi == ZigLLVM_UnknownEnvironment) { + target->abi = target_default_abi(target->arch, target->os); + } } -void get_unknown_target(ZigTarget *target) { - target->arch.arch = ZigLLVM_UnknownArch; - target->arch.sub_arch = ZigLLVM_NoSubArch; - target->vendor = ZigLLVM_UnknownVendor; - target->os = OsFreestanding; - target->env_type = ZigLLVM_UnknownEnvironment; - target->is_native = false; -} - -static void get_arch_name_raw(char *out_str, ZigLLVM_ArchType arch, ZigLLVM_SubArchType sub_arch) { - const char *sub_str = (sub_arch == ZigLLVM_NoSubArch) ? "" : ZigLLVMGetSubArchTypeName(sub_arch); - sprintf(out_str, "%s%s", ZigLLVMGetArchTypeName(arch), sub_str); -} - -void get_arch_name(char *out_str, const ArchType *arch) { - return get_arch_name_raw(out_str, arch->arch, arch->sub_arch); -} - -int parse_target_arch(const char *str, ArchType *out_arch) { - for (size_t i = 0; i < array_length(arch_list); i += 1) { - const ArchType *arch = &arch_list[i]; - char arch_name[50]; - get_arch_name_raw(arch_name, arch->arch, arch->sub_arch); - if (strcmp(arch_name, str) == 0) { - *out_arch = *arch; - return 0; +Error target_parse_archsub(ZigLLVM_ArchType *out_arch, ZigLLVM_SubArchType *out_sub, + const char *archsub_ptr, size_t archsub_len) +{ + for (size_t arch_i = 0; arch_i < array_length(arch_list); arch_i += 1) { + ZigLLVM_ArchType arch = arch_list[arch_i]; + SubArchList sub_arch_list = target_subarch_list(arch); + size_t subarch_count = target_subarch_count(sub_arch_list); + if (subarch_count == 0) { + if (mem_eql_str(archsub_ptr, archsub_len, target_arch_name(arch))) { + *out_arch = arch; + *out_sub = ZigLLVM_NoSubArch; + return ErrorNone; + } + continue; + } + for (size_t sub_i = 0; sub_i < subarch_count; sub_i += 1) { + ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i); + char arch_name[64]; + int n = sprintf(arch_name, "%s%s", target_arch_name(arch), target_subarch_name(sub)); + if (mem_eql_mem(arch_name, n, archsub_ptr, archsub_len)) { + *out_arch = arch; + *out_sub = sub; + return ErrorNone; + } } } - return ErrorFileNotFound; + return ErrorUnknownArchitecture; } -int parse_target_os(const char *str, Os *out_os) { +SubArchList target_subarch_list(ZigLLVM_ArchType arch) { + switch (arch) { + case ZigLLVM_UnknownArch: + zig_unreachable(); + case ZigLLVM_arm: + case ZigLLVM_armeb: + case ZigLLVM_thumb: + case ZigLLVM_thumbeb: + return SubArchListArm32; + + case ZigLLVM_aarch64: + case ZigLLVM_aarch64_be: + return SubArchListArm64; + + case ZigLLVM_kalimba: + return SubArchListKalimba; + + case ZigLLVM_arc: + case ZigLLVM_avr: + case ZigLLVM_bpfel: + case ZigLLVM_bpfeb: + case ZigLLVM_hexagon: + case ZigLLVM_mips: + case ZigLLVM_mipsel: + case ZigLLVM_mips64: + case ZigLLVM_mips64el: + case ZigLLVM_msp430: + case ZigLLVM_nios2: + case ZigLLVM_ppc: + case ZigLLVM_ppc64: + case ZigLLVM_ppc64le: + case ZigLLVM_r600: + case ZigLLVM_amdgcn: + case ZigLLVM_riscv32: + case ZigLLVM_riscv64: + case ZigLLVM_sparc: + case ZigLLVM_sparcv9: + case ZigLLVM_sparcel: + case ZigLLVM_systemz: + case ZigLLVM_tce: + case ZigLLVM_tcele: + case ZigLLVM_x86: + case ZigLLVM_x86_64: + case ZigLLVM_xcore: + case ZigLLVM_nvptx: + case ZigLLVM_nvptx64: + case ZigLLVM_le32: + case ZigLLVM_le64: + case ZigLLVM_amdil: + case ZigLLVM_amdil64: + case ZigLLVM_hsail: + case ZigLLVM_hsail64: + case ZigLLVM_spir: + case ZigLLVM_spir64: + case ZigLLVM_shave: + case ZigLLVM_lanai: + case ZigLLVM_wasm32: + case ZigLLVM_wasm64: + case ZigLLVM_renderscript32: + case ZigLLVM_renderscript64: + return SubArchListNone; + } + zig_unreachable(); +} + +size_t target_subarch_count(SubArchList sub_arch_list) { + switch (sub_arch_list) { + case SubArchListNone: + return 0; + case SubArchListArm32: + return array_length(subarch_list_arm32); + case SubArchListArm64: + return array_length(subarch_list_arm64); + case SubArchListKalimba: + return array_length(subarch_list_kalimba); + } + zig_unreachable(); +} + +ZigLLVM_SubArchType target_subarch_enum(SubArchList sub_arch_list, size_t i) { + switch (sub_arch_list) { + case SubArchListNone: + zig_unreachable(); + case SubArchListArm32: + assert(i < array_length(subarch_list_arm32)); + return subarch_list_arm32[i]; + case SubArchListArm64: + assert(i < array_length(subarch_list_arm64)); + return subarch_list_arm64[i]; + case SubArchListKalimba: + assert(i < array_length(subarch_list_kalimba)); + return subarch_list_kalimba[i]; + } + zig_unreachable(); +} + +const char *target_subarch_name(ZigLLVM_SubArchType subarch) { + return ZigLLVMGetSubArchTypeName(subarch); +} + +size_t target_subarch_list_count(void) { + return array_length(subarch_list_list); +} + +SubArchList target_subarch_list_enum(size_t index) { + assert(index < array_length(subarch_list_list)); + return subarch_list_list[index]; +} + +const char *target_subarch_list_name(SubArchList sub_arch_list) { + switch (sub_arch_list) { + case SubArchListNone: + return "None"; + case SubArchListArm32: + return "Arm32"; + case SubArchListArm64: + return "Arm64"; + case SubArchListKalimba: + return "Kalimba"; + } + zig_unreachable(); +} + +Error target_parse_os(Os *out_os, const char *os_ptr, size_t os_len) { for (size_t i = 0; i < array_length(os_list); i += 1) { Os os = os_list[i]; - const char *os_name = get_target_os_name(os); - if (strcmp(os_name, str) == 0) { + const char *os_name = target_os_name(os); + if (mem_eql_str(os_ptr, os_len, os_name)) { *out_os = os; - return 0; + return ErrorNone; } } - return ErrorFileNotFound; + return ErrorUnknownOperatingSystem; } -int parse_target_environ(const char *str, ZigLLVM_EnvironmentType *out_environ) { - for (size_t i = 0; i < array_length(environ_list); i += 1) { - ZigLLVM_EnvironmentType env_type = environ_list[i]; - const char *environ_name = ZigLLVMGetEnvironmentTypeName(env_type); - if (strcmp(environ_name, str) == 0) { - *out_environ = env_type; - return 0; +Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, size_t abi_len) { + for (size_t i = 0; i < array_length(abi_list); i += 1) { + ZigLLVM_EnvironmentType abi = abi_list[i]; + const char *abi_name = target_abi_name(abi); + if (mem_eql_str(abi_ptr, abi_len, abi_name)) { + *out_abi = abi; + return ErrorNone; } } - return ErrorFileNotFound; + return ErrorUnknownABI; +} + +Error target_parse_triple(ZigTarget *target, const char *triple) { + Error err; + SplitIterator it = memSplit(str(triple), str("-")); + + Optional> opt_archsub = SplitIterator_next(&it); + Optional> opt_os = SplitIterator_next(&it); + Optional> opt_abi = SplitIterator_next(&it); + + if (!opt_archsub.is_some) + return ErrorMissingArchitecture; + + if (!opt_os.is_some) + return ErrorMissingOperatingSystem; + + if ((err = target_parse_archsub(&target->arch, &target->sub_arch, + (char*)opt_archsub.value.ptr, opt_archsub.value.len))) + { + return err; + } + + if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) { + return err; + } + + if (opt_abi.is_some) { + if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) { + return err; + } + } else { + target->abi = target_default_abi(target->arch, target->os); + } + + target->vendor = ZigLLVM_UnknownVendor; + target->is_native = false; + return ErrorNone; +} + +const char *target_arch_name(ZigLLVM_ArchType arch) { + return ZigLLVMGetArchTypeName(arch); } void init_all_targets(void) { @@ -519,37 +684,21 @@ void init_all_targets(void) { } void get_target_triple(Buf *triple, const ZigTarget *target) { - char arch_name[50]; - get_arch_name(arch_name, &target->arch); - buf_resize(triple, 0); - - // LLVM WebAssembly output support requires the target to be activated at - // build type with -DCMAKE_LLVM_EXPIERMENTAL_TARGETS_TO_BUILD=WebAssembly. - // - // LLVM determines the output format based on the environment suffix, - // defaulting to an object based on the architecture. The default format in - // LLVM 6 sets the wasm arch output incorrectly to ELF. We need to - // explicitly set this ourself in order for it to work. - // - // This is fixed in LLVM 7 and you will be able to get wasm output by - // using the target triple `wasm32-unknown-unknown-unknown`. - if (!strncmp(arch_name, "wasm", 4)) { - buf_appendf(triple, "%s-%s-%s-wasm", arch_name, - ZigLLVMGetVendorTypeName(target->vendor), - ZigLLVMGetOSTypeName(get_llvm_os_type(target->os))); - } else { - buf_appendf(triple, "%s-%s-%s-%s", arch_name, - ZigLLVMGetVendorTypeName(target->vendor), - ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)), - ZigLLVMGetEnvironmentTypeName(target->env_type)); - } + buf_appendf(triple, "%s%s-%s-%s-%s", + ZigLLVMGetArchTypeName(target->arch), + ZigLLVMGetSubArchTypeName(target->sub_arch), + ZigLLVMGetVendorTypeName(target->vendor), + ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)), + ZigLLVMGetEnvironmentTypeName(target->abi)); } bool target_is_darwin(const ZigTarget *target) { switch (target->os) { case OsMacOSX: case OsIOS: + case OsWatchOS: + case OsTvOS: return true; default: return false; @@ -562,8 +711,8 @@ ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target) { } else if (target_is_darwin(target)) { return ZigLLVM_MachO; } - if (target->arch.arch == ZigLLVM_wasm32 || - target->arch.arch == ZigLLVM_wasm64) + if (target->arch == ZigLLVM_wasm32 || + target->arch == ZigLLVM_wasm64) { return ZigLLVM_Wasm; } @@ -639,7 +788,7 @@ static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) { uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { switch (target->os) { case OsFreestanding: - switch (target->arch.arch) { + switch (target->arch) { case ZigLLVM_msp430: switch (id) { case CIntTypeShort: @@ -667,7 +816,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { return 32; case CIntTypeLong: case CIntTypeULong: - return get_arch_pointer_bit_width(target->arch.arch); + return get_arch_pointer_bit_width(target->arch); case CIntTypeLongLong: case CIntTypeULongLong: return 64; @@ -690,7 +839,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { return 32; case CIntTypeLong: case CIntTypeULong: - return get_arch_pointer_bit_width(target->arch.arch); + return get_arch_pointer_bit_width(target->arch); case CIntTypeLongLong: case CIntTypeULongLong: return 64; @@ -748,7 +897,7 @@ bool target_allows_addr_zero(const ZigTarget *target) { } const char *target_o_file_ext(const ZigTarget *target) { - if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) { + if (target->abi == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) { return ".obj"; } else { return ".o"; @@ -798,7 +947,7 @@ enum FloatAbi { }; static FloatAbi get_float_abi(const ZigTarget *target) { - const ZigLLVM_EnvironmentType env = target->env_type; + const ZigLLVM_EnvironmentType env = target->abi; if (env == ZigLLVM_GNUEABIHF || env == ZigLLVM_EABIHF || env == ZigLLVM_MuslEABIHF) @@ -813,71 +962,154 @@ static bool is_64_bit(ZigLLVM_ArchType arch) { return get_arch_pointer_bit_width(arch) == 64; } -Buf *target_dynamic_linker(const ZigTarget *target) { - if (target->os == OsFreeBSD) { - return buf_create_from_str("/libexec/ld-elf.so.1"); - } - if (target->os == OsNetBSD) { - return buf_create_from_str("/libexec/ld.elf_so"); - } +const char *target_dynamic_linker(const ZigTarget *target) { + switch (target->os) { + case OsFreeBSD: + return "/libexec/ld-elf.so.1"; + case OsNetBSD: + return "/libexec/ld.elf_so"; + case OsLinux: { + const ZigLLVM_EnvironmentType abi = target->abi; + if (abi == ZigLLVM_Android) { + if (is_64_bit(target->arch)) { + return "/system/bin/linker64"; + } else { + return "/system/bin/linker"; + } + } - const ZigLLVM_ArchType arch = target->arch.arch; - const ZigLLVM_EnvironmentType env = target->env_type; + switch (target->arch) { + case ZigLLVM_UnknownArch: + zig_unreachable(); + case ZigLLVM_x86: + case ZigLLVM_sparc: + case ZigLLVM_sparcel: + return "/lib/ld-linux.so.2"; - if (env == ZigLLVM_Android) { - if (is_64_bit(arch)) { - return buf_create_from_str("/system/bin/linker64"); - } else { - return buf_create_from_str("/system/bin/linker"); + case ZigLLVM_aarch64: + return "/lib/ld-linux-aarch64.so.1"; + + case ZigLLVM_aarch64_be: + return "/lib/ld-linux-aarch64_be.so.1"; + + case ZigLLVM_arm: + case ZigLLVM_thumb: + if (get_float_abi(target) == FloatAbiHard) { + return "/lib/ld-linux-armhf.so.3"; + } else { + return "/lib/ld-linux.so.3"; + } + + case ZigLLVM_armeb: + case ZigLLVM_thumbeb: + if (get_float_abi(target) == FloatAbiHard) { + return "/lib/ld-linux-armhf.so.3"; + } else { + return "/lib/ld-linux.so.3"; + } + + case ZigLLVM_mips: + case ZigLLVM_mipsel: + case ZigLLVM_mips64: + case ZigLLVM_mips64el: + zig_panic("TODO implement target_dynamic_linker for mips"); + + case ZigLLVM_ppc: + return "/lib/ld.so.1"; + + case ZigLLVM_ppc64: + return "/lib64/ld64.so.2"; + + case ZigLLVM_ppc64le: + return "/lib64/ld64.so.2"; + + case ZigLLVM_systemz: + return "/lib64/ld64.so.1"; + + case ZigLLVM_sparcv9: + return "/lib64/ld-linux.so.2"; + + case ZigLLVM_x86_64: + if (abi == ZigLLVM_GNUX32) { + return "/libx32/ld-linux-x32.so.2"; + } + if (abi == ZigLLVM_Musl || abi == ZigLLVM_MuslEABI || abi == ZigLLVM_MuslEABIHF) { + return "/lib/ld-musl-x86_64.so.1"; + } + return "/lib64/ld-linux-x86-64.so.2"; + + case ZigLLVM_wasm32: + case ZigLLVM_wasm64: + return nullptr; + + case ZigLLVM_arc: + case ZigLLVM_avr: + case ZigLLVM_bpfel: + case ZigLLVM_bpfeb: + case ZigLLVM_hexagon: + case ZigLLVM_msp430: + case ZigLLVM_nios2: + case ZigLLVM_r600: + case ZigLLVM_amdgcn: + case ZigLLVM_riscv32: + case ZigLLVM_riscv64: + case ZigLLVM_tce: + case ZigLLVM_tcele: + case ZigLLVM_xcore: + case ZigLLVM_nvptx: + case ZigLLVM_nvptx64: + case ZigLLVM_le32: + case ZigLLVM_le64: + case ZigLLVM_amdil: + case ZigLLVM_amdil64: + case ZigLLVM_hsail: + case ZigLLVM_hsail64: + case ZigLLVM_spir: + case ZigLLVM_spir64: + case ZigLLVM_kalimba: + case ZigLLVM_shave: + case ZigLLVM_lanai: + case ZigLLVM_renderscript32: + case ZigLLVM_renderscript64: + zig_panic("TODO implement target_dynamic_linker for this arch"); + } + zig_unreachable(); } - } else if (arch == ZigLLVM_x86 || - arch == ZigLLVM_sparc || - arch == ZigLLVM_sparcel) - { - return buf_create_from_str("/lib/ld-linux.so.2"); - } else if (arch == ZigLLVM_aarch64) { - return buf_create_from_str("/lib/ld-linux-aarch64.so.1"); - } else if (arch == ZigLLVM_aarch64_be) { - return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1"); - } else if (arch == ZigLLVM_arm || arch == ZigLLVM_thumb) { - if (get_float_abi(target) == FloatAbiHard) { - return buf_create_from_str("/lib/ld-linux-armhf.so.3"); - } else { - return buf_create_from_str("/lib/ld-linux.so.3"); - } - } else if (arch == ZigLLVM_armeb || arch == ZigLLVM_thumbeb) { - if (get_float_abi(target) == FloatAbiHard) { - return buf_create_from_str("/lib/ld-linux-armhf.so.3"); - } else { - return buf_create_from_str("/lib/ld-linux.so.3"); - } - } else if (arch == ZigLLVM_mips || arch == ZigLLVM_mipsel || - arch == ZigLLVM_mips64 || arch == ZigLLVM_mips64el) - { - // when you want to solve this TODO, grep clang codebase for - // getLinuxDynamicLinker - zig_panic("TODO figure out MIPS dynamic linker name"); - } else if (arch == ZigLLVM_ppc) { - return buf_create_from_str("/lib/ld.so.1"); - } else if (arch == ZigLLVM_ppc64) { - return buf_create_from_str("/lib64/ld64.so.2"); - } else if (arch == ZigLLVM_ppc64le) { - return buf_create_from_str("/lib64/ld64.so.2"); - } else if (arch == ZigLLVM_systemz) { - return buf_create_from_str("/lib64/ld64.so.1"); - } else if (arch == ZigLLVM_sparcv9) { - return buf_create_from_str("/lib64/ld-linux.so.2"); - } else if (arch == ZigLLVM_x86_64 && - env == ZigLLVM_GNUX32) - { - return buf_create_from_str("/libx32/ld-linux-x32.so.2"); - } else if (arch == ZigLLVM_x86_64 && - (env == ZigLLVM_Musl || env == ZigLLVM_MuslEABI || env == ZigLLVM_MuslEABIHF)) - { - return buf_create_from_str("/lib/ld-musl-x86_64.so.1"); - } else { - return buf_create_from_str("/lib64/ld-linux-x86-64.so.2"); + case OsFreestanding: + case OsIOS: + case OsTvOS: + case OsWatchOS: + case OsMacOSX: + return nullptr; + + case OsAnanas: + case OsCloudABI: + case OsDragonFly: + case OsFuchsia: + case OsKFreeBSD: + case OsLv2: + case OsOpenBSD: + case OsSolaris: + case OsWindows: + case OsHaiku: + case OsMinix: + case OsRTEMS: + case OsNaCl: + case OsCNK: + case OsAIX: + case OsCUDA: + case OsNVCL: + case OsAMDHSA: + case OsPS4: + case OsELFIAMCU: + case OsMesa3D: + case OsContiki: + case OsAMDPAL: + case OsZen: + case OsUefi: + zig_panic("TODO implement target_dynamic_linker for this OS"); } + zig_unreachable(); } bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target) { @@ -888,15 +1120,15 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target return true; } - if (guest_target->os == host_target->os && guest_target->arch.arch == host_target->arch.arch && - guest_target->arch.sub_arch == host_target->arch.sub_arch) + if (guest_target->os == host_target->os && guest_target->arch == host_target->arch && + guest_target->sub_arch == host_target->sub_arch) { // OS, arch, and sub-arch match return true; } if (guest_target->os == OsWindows && host_target->os == OsWindows && - host_target->arch.arch == ZigLLVM_x86_64 && guest_target->arch.arch == ZigLLVM_x86) + host_target->arch == ZigLLVM_x86_64 && guest_target->arch == ZigLLVM_x86) { // 64-bit windows can run 32-bit programs return true; @@ -905,8 +1137,8 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target return false; } -const char *arch_stack_pointer_register_name(const ArchType *arch) { - switch (arch->arch) { +const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) { + switch (arch) { case ZigLLVM_UnknownArch: zig_unreachable(); case ZigLLVM_x86: @@ -969,7 +1201,7 @@ const char *arch_stack_pointer_register_name(const ArchType *arch) { } bool target_is_arm(const ZigTarget *target) { - switch (target->arch.arch) { + switch (target->arch) { case ZigLLVM_UnknownArch: zig_unreachable(); case ZigLLVM_aarch64: @@ -1031,12 +1263,12 @@ bool target_is_arm(const ZigTarget *target) { // Valgrind supports more, but Zig does not support them yet. bool target_has_valgrind_support(const ZigTarget *target) { - switch (target->arch.arch) { + switch (target->arch) { case ZigLLVM_UnknownArch: zig_unreachable(); case ZigLLVM_x86_64: return (target->os == OsLinux || target_is_darwin(target) || target->os == OsSolaris || - (target->os == OsWindows && target->env_type != ZigLLVM_MSVC)); + (target->os == OsWindows && target->abi != ZigLLVM_MSVC)); default: return false; } @@ -1055,3 +1287,46 @@ bool target_supports_fpic(const ZigTarget *target) { // C compiler argument is valid. return target->os != OsWindows; } + +ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) { + switch (os) { + case OsFreestanding: + case OsAnanas: + case OsCloudABI: + case OsDragonFly: + case OsLv2: + case OsSolaris: + case OsHaiku: + case OsMinix: + case OsRTEMS: + case OsNaCl: + case OsCNK: + case OsAIX: + case OsCUDA: + case OsNVCL: + case OsAMDHSA: + case OsPS4: + case OsELFIAMCU: + case OsMesa3D: + case OsContiki: + case OsAMDPAL: + case OsZen: + return ZigLLVM_EABI; + case OsOpenBSD: + case OsMacOSX: + case OsFreeBSD: + case OsIOS: + case OsTvOS: + case OsWatchOS: + case OsFuchsia: + case OsKFreeBSD: + case OsNetBSD: + return ZigLLVM_GNU; + case OsWindows: + case OsUefi: + return ZigLLVM_MSVC; + case OsLinux: + return ZigLLVM_Musl; + } + zig_unreachable(); +} diff --git a/src/target.hpp b/src/target.hpp index dceeee2eca..e3bdc244dc 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -12,11 +12,6 @@ struct Buf; -struct ArchType { - ZigLLVM_ArchType arch; - ZigLLVM_SubArchType sub_arch; -}; - // Synchronize with target.cpp::os_list enum Os { OsFreestanding, @@ -54,6 +49,14 @@ enum Os { OsUefi, }; +// Synchronize with target.cpp::subarch_list_list +enum SubArchList { + SubArchListNone, + SubArchListArm32, + SubArchListArm64, + SubArchListKalimba, +}; + enum TargetSubsystem { TargetSubsystemAuto, // Zig should infer the subsystem TargetSubsystemConsole, @@ -67,10 +70,11 @@ enum TargetSubsystem { }; struct ZigTarget { - ArchType arch; + ZigLLVM_ArchType arch; + ZigLLVM_SubArchType sub_arch; ZigLLVM_VendorType vendor; Os os; - ZigLLVM_EnvironmentType env_type; + ZigLLVM_EnvironmentType abi; bool is_native; }; @@ -87,39 +91,50 @@ enum CIntType { CIntTypeCount, }; -size_t target_arch_count(void); -const ArchType *get_target_arch(size_t index); -void get_arch_name(char *out_str, const ArchType *arch); +Error target_parse_triple(ZigTarget *target, const char *triple); +Error target_parse_archsub(ZigLLVM_ArchType *arch, ZigLLVM_SubArchType *sub, + const char *archsub_ptr, size_t archsub_len); +Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); +Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); -const char *arch_stack_pointer_register_name(const ArchType *arch); +size_t target_arch_count(void); +ZigLLVM_ArchType target_arch_enum(size_t index); +const char *target_arch_name(ZigLLVM_ArchType arch); + +SubArchList target_subarch_list(ZigLLVM_ArchType arch); +size_t target_subarch_count(SubArchList sub_arch_list); +ZigLLVM_SubArchType target_subarch_enum(SubArchList subarch_list, size_t index); +const char *target_subarch_name(ZigLLVM_SubArchType subarch); + +size_t target_subarch_list_count(void); +SubArchList target_subarch_list_enum(size_t index); +const char *target_subarch_list_name(SubArchList sub_arch_list); + +const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch); size_t target_vendor_count(void); -ZigLLVM_VendorType get_target_vendor(size_t index); +ZigLLVM_VendorType target_vendor_enum(size_t index); size_t target_os_count(void); -Os get_target_os(size_t index); -const char *get_target_os_name(Os os_type); +Os target_os_enum(size_t index); +const char *target_os_name(Os os_type); -size_t target_environ_count(void); -ZigLLVM_EnvironmentType get_target_environ(size_t index); +size_t target_abi_count(void); +ZigLLVM_EnvironmentType target_abi_enum(size_t index); +const char *target_abi_name(ZigLLVM_EnvironmentType abi); +ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os); size_t target_oformat_count(void); -ZigLLVM_ObjectFormatType get_target_oformat(size_t index); -const char *get_target_oformat_name(ZigLLVM_ObjectFormatType oformat); +ZigLLVM_ObjectFormatType target_oformat_enum(size_t index); +const char *target_oformat_name(ZigLLVM_ObjectFormatType oformat); ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target); void get_native_target(ZigTarget *target); -void get_unknown_target(ZigTarget *target); - -int parse_target_arch(const char *str, ArchType *arch); -int parse_target_os(const char *str, Os *os); -int parse_target_environ(const char *str, ZigLLVM_EnvironmentType *env_type); +void get_target_triple(Buf *triple, const ZigTarget *target); void init_all_targets(void); -void get_target_triple(Buf *triple, const ZigTarget *target); - void resolve_target_object_format(ZigTarget *target); uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id); @@ -131,7 +146,7 @@ const char *target_exe_file_ext(const ZigTarget *target); const char *target_lib_file_ext(const ZigTarget *target, bool is_static, size_t version_major, size_t version_minor, size_t version_patch); -Buf *target_dynamic_linker(const ZigTarget *target); +const char *target_dynamic_linker(const ZigTarget *target); bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target); ZigLLVM_OSType get_llvm_os_type(Os os_type); diff --git a/src/util.hpp b/src/util.hpp index cc83022328..a0e759567e 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -147,11 +147,14 @@ static inline T clamp(T min_value, T value, T max_value) { return max(min(value, max_value), min_value); } -static inline bool mem_eql_str(const char *mem, size_t mem_len, const char *str) { - size_t str_len = strlen(str); - if (str_len != mem_len) +static inline bool mem_eql_mem(const char *a_ptr, size_t a_len, const char *b_ptr, size_t b_len) { + if (a_len != b_len) return false; - return memcmp(mem, str, mem_len) == 0; + return memcmp(a_ptr, b_ptr, a_len) == 0; +} + +static inline bool mem_eql_str(const char *mem, size_t mem_len, const char *str) { + return mem_eql_mem(mem, mem_len, str, strlen(str)); } static inline bool is_power_of_2(uint64_t x) { diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index e5a4890914..4a7712ca1e 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -730,7 +730,7 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch) { switch (sub_arch) { case ZigLLVM_NoSubArch: - return "(none)"; + return ""; case ZigLLVM_ARMSubArch_v8_4a: return "v8_4a"; case ZigLLVM_ARMSubArch_v8_3a: diff --git a/src/zig_llvm.h b/src/zig_llvm.h index b5b0e97b53..743df123f4 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -215,7 +215,7 @@ ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const // copied from include/llvm/ADT/Triple.h - +// synchronize with target.cpp::arch_list enum ZigLLVM_ArchType { ZigLLVM_UnknownArch, @@ -273,6 +273,7 @@ enum ZigLLVM_ArchType { ZigLLVM_LastArchType = ZigLLVM_renderscript64 }; +// synchronize with lists in target.cpp enum ZigLLVM_SubArchType { ZigLLVM_NoSubArch, @@ -404,7 +405,7 @@ ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch); ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch); ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor); ZIG_EXTERN_C const char *ZigLLVMGetOSTypeName(enum ZigLLVM_OSType os); -ZIG_EXTERN_C const char *ZigLLVMGetEnvironmentTypeName(enum ZigLLVM_EnvironmentType env_type); +ZIG_EXTERN_C const char *ZigLLVMGetEnvironmentTypeName(enum ZigLLVM_EnvironmentType abi); ZIG_EXTERN_C bool ZigLLDLink(enum ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, void (*append_diagnostic)(void *, const char *, size_t), void *context); diff --git a/std/build.zig b/std/build.zig index d88a9b3270..e90d827602 100644 --- a/std/build.zig +++ b/std/build.zig @@ -731,20 +731,40 @@ const Version = struct { const CrossTarget = struct { arch: builtin.Arch, os: builtin.Os, - environ: builtin.Environ, + abi: builtin.Abi, }; pub const Target = union(enum) { Native: void, Cross: CrossTarget, - pub fn oFileExt(self: *const Target) []const u8 { - const environ = switch (self.*) { - Target.Native => builtin.environ, - Target.Cross => |t| t.environ, + fn archSubArchName(arch: builtin.Arch) []const u8 { + return switch (arch) { + builtin.Arch.arm => |sub| @tagName(sub), + builtin.Arch.armeb => |sub| @tagName(sub), + builtin.Arch.thumb => |sub| @tagName(sub), + builtin.Arch.thumbeb => |sub| @tagName(sub), + builtin.Arch.aarch64 => |sub| @tagName(sub), + builtin.Arch.aarch64_be => |sub| @tagName(sub), + builtin.Arch.kalimba => |sub| @tagName(sub), + else => "", }; - return switch (environ) { - builtin.Environ.msvc => ".obj", + } + + pub fn subArchName(self: Target) []const u8 { + switch (self) { + Target.Native => return archSubArchName(builtin.arch), + Target.Cross => |cross| return archSubArchName(cross.arch), + } + } + + pub fn oFileExt(self: *const Target) []const u8 { + const abi = switch (self.*) { + Target.Native => builtin.abi, + Target.Cross => |t| t.abi, + }; + return switch (abi) { + builtin.Abi.msvc => ".obj", else => ".o", }; } @@ -978,12 +998,17 @@ pub const LibExeObjStep = struct { } } - pub fn setTarget(self: *LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os, target_environ: builtin.Environ) void { + pub fn setTarget( + self: *LibExeObjStep, + target_arch: builtin.Arch, + target_os: builtin.Os, + target_abi: builtin.Abi, + ) void { self.target = Target{ .Cross = CrossTarget{ .arch = target_arch, .os = target_os, - .environ = target_environ, + .abi = target_abi, }, }; self.computeOutFileNames(); @@ -1296,14 +1321,16 @@ pub const LibExeObjStep = struct { switch (self.target) { Target.Native => {}, Target.Cross => |cross_target| { - zig_args.append("--target-arch") catch unreachable; - zig_args.append(@tagName(cross_target.arch)) catch unreachable; + const triple = builder.fmt( + "{}{}-{}-{}", + @tagName(cross_target.arch), + Target.archSubArchName(cross_target.arch), + @tagName(cross_target.os), + @tagName(cross_target.abi), + ); - zig_args.append("--target-os") catch unreachable; - zig_args.append(@tagName(cross_target.os)) catch unreachable; - - zig_args.append("--target-environ") catch unreachable; - zig_args.append(@tagName(cross_target.environ)) catch unreachable; + try zig_args.append("-target"); + try zig_args.append(triple); }, } diff --git a/std/fmt/index.zig b/std/fmt/index.zig index f006dfdbdc..4f864b3662 100644 --- a/std/fmt/index.zig +++ b/std/fmt/index.zig @@ -1118,7 +1118,7 @@ test "fmt.format" { const result = try bufPrint(buf1[0..], "f64: {}\n", math.nan_f64); testing.expect(mem.eql(u8, result, "f64: nan\n")); } - if (builtin.arch != builtin.Arch.armv8) { + if (builtin.arch != builtin.Arch.arm) { // negative nan is not defined by IEE 754, // and ARM thus normalizes it to positive nan var buf1: [32]u8 = undefined; diff --git a/std/os/linux/index.zig b/std/os/linux/index.zig index ec90755164..b78c1b3da5 100644 --- a/std/os/linux/index.zig +++ b/std/os/linux/index.zig @@ -6,7 +6,7 @@ const vdso = @import("vdso.zig"); pub use switch (builtin.arch) { builtin.Arch.x86_64 => @import("x86_64.zig"), builtin.Arch.i386 => @import("i386.zig"), - builtin.Arch.aarch64v8 => @import("arm64.zig"), + builtin.Arch.aarch64 => @import("arm64.zig"), else => @compileError("unsupported arch"), }; pub use @import("errno.zig"); diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig index 1192d7e46f..950fd5cbb9 100644 --- a/std/special/bootstrap.zig +++ b/std/special/bootstrap.zig @@ -31,7 +31,7 @@ nakedcc fn _start() noreturn { : [argc] "=r" (-> [*]usize) ); }, - builtin.Arch.aarch64v8 => { + builtin.Arch.aarch64, builtin.Arch.aarch64_be => { argc_ptr = asm ("mov %[argc], sp" : [argc] "=r" (-> [*]usize) ); diff --git a/std/special/compiler_rt/index.zig b/std/special/compiler_rt/index.zig index 6715df1805..7657ce6118 100644 --- a/std/special/compiler_rt/index.zig +++ b/std/special/compiler_rt/index.zig @@ -184,60 +184,10 @@ const is_arm_64 = switch (builtin.arch) { }; const is_arm_arch = switch (builtin.arch) { - builtin.Arch.armv8_3a, - builtin.Arch.armv8_2a, - builtin.Arch.armv8_1a, - builtin.Arch.armv8, - builtin.Arch.armv8r, - builtin.Arch.armv8m_baseline, - builtin.Arch.armv8m_mainline, - builtin.Arch.armv7, - builtin.Arch.armv7em, - builtin.Arch.armv7m, - builtin.Arch.armv7s, - builtin.Arch.armv7k, - builtin.Arch.armv7ve, - builtin.Arch.armv6, - builtin.Arch.armv6m, - builtin.Arch.armv6k, - builtin.Arch.armv6t2, - builtin.Arch.armv5, - builtin.Arch.armv5te, - builtin.Arch.armv4t, - builtin.Arch.armebv8_3a, - builtin.Arch.armebv8_2a, - builtin.Arch.armebv8_1a, - builtin.Arch.armebv8, - builtin.Arch.armebv8r, - builtin.Arch.armebv8m_baseline, - builtin.Arch.armebv8m_mainline, - builtin.Arch.armebv7, - builtin.Arch.armebv7em, - builtin.Arch.armebv7m, - builtin.Arch.armebv7s, - builtin.Arch.armebv7k, - builtin.Arch.armebv7ve, - builtin.Arch.armebv6, - builtin.Arch.armebv6m, - builtin.Arch.armebv6k, - builtin.Arch.armebv6t2, - builtin.Arch.armebv5, - builtin.Arch.armebv5te, - builtin.Arch.armebv4t, - builtin.Arch.aarch64v8_3a, - builtin.Arch.aarch64v8_2a, - builtin.Arch.aarch64v8_1a, - builtin.Arch.aarch64v8, - builtin.Arch.aarch64v8r, - builtin.Arch.aarch64v8m_baseline, - builtin.Arch.aarch64v8m_mainline, - builtin.Arch.aarch64_bev8_3a, - builtin.Arch.aarch64_bev8_2a, - builtin.Arch.aarch64_bev8_1a, - builtin.Arch.aarch64_bev8, - builtin.Arch.aarch64_bev8r, - builtin.Arch.aarch64_bev8m_baseline, - builtin.Arch.aarch64_bev8m_mainline, + builtin.Arch.arm, + builtin.Arch.armeb, + builtin.Arch.aarch64, + builtin.Arch.aarch64_be, builtin.Arch.thumb, builtin.Arch.thumbeb, => true, diff --git a/test/tests.zig b/test/tests.zig index 2591ab4f2a..582736e8d5 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -24,24 +24,24 @@ const gen_h = @import("gen_h.zig"); const TestTarget = struct { os: builtin.Os, arch: builtin.Arch, - environ: builtin.Environ, + abi: builtin.Abi, }; const test_targets = []TestTarget{ TestTarget{ .os = builtin.Os.linux, .arch = builtin.Arch.x86_64, - .environ = builtin.Environ.gnu, + .abi = builtin.Abi.gnu, }, TestTarget{ .os = builtin.Os.macosx, .arch = builtin.Arch.x86_64, - .environ = builtin.Environ.unknown, + .abi = builtin.Abi.gnu, }, TestTarget{ .os = builtin.Os.windows, .arch = builtin.Arch.x86_64, - .environ = builtin.Environ.msvc, + .abi = builtin.Abi.msvc, }, }; @@ -189,7 +189,7 @@ pub fn addPkgTests(b: *build.Builder, test_filter: ?[]const u8, root_src: []cons these_tests.setFilter(test_filter); these_tests.setBuildMode(mode); if (!is_native) { - these_tests.setTarget(test_target.arch, test_target.os, test_target.environ); + these_tests.setTarget(test_target.arch, test_target.os, test_target.abi); } if (link_libc) { these_tests.linkSystemLibrary("c");