From 1ff2edf67ef7a5d434697bb494247b76f34f6c84 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 10 Feb 2016 15:41:50 -0700 Subject: [PATCH] add "targets" command to list architectures, oses, abis --- CMakeLists.txt | 1 + doc/langref.md | 6 +- src/all_types.hpp | 1 - src/codegen.cpp | 3 - src/main.cpp | 40 +++++++++++ src/target.cpp | 169 ++++++++++++++++++++++++++++++++++++++++++++++ src/target.hpp | 51 ++++++++++++++ src/zig_llvm.cpp | 24 +++++++ src/zig_llvm.hpp | 149 +++++++++++++++++++++++++++++++++++++++- 9 files changed, 435 insertions(+), 9 deletions(-) create mode 100644 src/target.cpp create mode 100644 src/target.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a6f3d73ff7..027842c49a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ include_directories( ) set(ZIG_SOURCES + "${CMAKE_SOURCE_DIR}/src/target.cpp" "${CMAKE_SOURCE_DIR}/src/ast_render.cpp" "${CMAKE_SOURCE_DIR}/src/bignum.cpp" "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp" diff --git a/doc/langref.md b/doc/langref.md index a725424104..14b8949614 100644 --- a/doc/langref.md +++ b/doc/langref.md @@ -350,9 +350,9 @@ The functions take an integer (TODO float?) type, two variables of the specified ``` Function Operation -bool add_with_overflow(type, a: type, b: type, x: &type) *x = a + b -bool sub_with_overflow(type, a: type, b: type, x: &type) *x = a - b -bool mul_with_overflow(type, a: type, b: type, x: &type) *x = a * b +bool add_with_overflow(T: type, a: T, b: T, x: &T) *x = a + b +bool sub_with_overflow(T: type, a: T, b: T, x: &T) *x = a - b +bool mul_with_overflow(T: type, a: T, b: T, x: &T) *x = a * b ``` ### Memory Operations diff --git a/src/all_types.hpp b/src/all_types.hpp index 599307cea9..bded9207e9 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1124,7 +1124,6 @@ struct CodeGen { bool is_test_build; LLVMTargetMachineRef target_machine; LLVMZigDIFile *dummy_di_file; - bool is_native_target; Buf *root_source_dir; Buf *root_out_name; diff --git a/src/codegen.cpp b/src/codegen.cpp index 01ef7f2fef..1074d24200 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3498,8 +3498,6 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn_with_arg_count(g, BuiltinFnIdConstEval, "const_eval", 1); } - - static void init(CodeGen *g, Buf *source_path) { g->lib_search_paths.append(g->root_source_dir); g->lib_search_paths.append(buf_create_from_str(ZIG_STD_DIR)); @@ -3510,7 +3508,6 @@ static void init(CodeGen *g, Buf *source_path) { LLVMInitializeAllAsmParsers(); LLVMInitializeNativeTarget(); - g->is_native_target = true; char *native_triple = LLVMGetDefaultTargetTriple(); g->module = LLVMModuleCreateWithName(buf_ptr(source_path)); diff --git a/src/main.cpp b/src/main.cpp index 36aa3497d3..81eea98a4b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include "codegen.hpp" #include "os.hpp" #include "error.hpp" +#include "target.hpp" #include @@ -20,6 +21,7 @@ static int usage(const char *arg0) { " test create and run a test build\n" " version print version number and exit\n" " parseh convert a c header file to zig extern declarations\n" + " targets list available compilation targets\n" "Options:\n" " --release build with optimizations on and debug protection off\n" " --static output will be statically linked\n" @@ -40,12 +42,45 @@ static int usage(const char *arg0) { return EXIT_FAILURE; } +static int print_target_list(FILE *f) { + fprintf(f, "Architectures:\n"); + int arch_count = target_arch_count(); + int sub_arch_count = target_sub_arch_count(); + for (int arch_i = 0; arch_i < arch_count; arch_i += 1) { + const ArchType *arch = get_target_arch(arch_i); + fprintf(f, " %s\n", ZigLLVMGetArchTypeName(arch->llvm_arch)); + for (int sub_arch_i = 0; sub_arch_i < sub_arch_count; sub_arch_i += 1) { + const SubArchType *sub_arch = get_target_sub_arch(sub_arch_i); + if (sub_arch->arch == arch->llvm_arch) { + fprintf(f, " %s\n", sub_arch->name); + } + } + } + + fprintf(f, "\nOperating Systems:\n"); + int os_count = target_os_count(); + for (int i = 0; i < os_count; i += 1) { + const OsType *os_type = get_target_os(i); + fprintf(f, " %s\n", get_target_os_name(os_type)); + } + + fprintf(f, "\nABIs:\n"); + int environ_count = target_environ_count(); + for (int i = 0; i < environ_count; i += 1) { + const EnvironmentType *environ_type = get_target_environ(i); + fprintf(f, " %s\n", ZigLLVMGetEnvironmentTypeName(environ_type->llvm_environment)); + } + + return EXIT_SUCCESS; +} + enum Cmd { CmdInvalid, CmdBuild, CmdTest, CmdVersion, CmdParseH, + CmdTargets, }; int main(int argc, char **argv) { @@ -139,6 +174,8 @@ int main(int argc, char **argv) { cmd = CmdParseH; } else if (strcmp(arg, "test") == 0) { cmd = CmdTest; + } else if (strcmp(arg, "targets") == 0) { + cmd = CmdTargets; } else { fprintf(stderr, "Unrecognized command: %s\n", arg); return usage(arg0); @@ -155,6 +192,7 @@ int main(int argc, char **argv) { } break; case CmdVersion: + case CmdTargets: return usage(arg0); case CmdInvalid: zig_unreachable(); @@ -249,6 +287,8 @@ int main(int argc, char **argv) { case CmdVersion: printf("%s\n", ZIG_VERSION_STRING); return EXIT_SUCCESS; + case CmdTargets: + return print_target_list(stdout); case CmdInvalid: return usage(arg0); } diff --git a/src/target.cpp b/src/target.cpp new file mode 100644 index 0000000000..88ae118d6b --- /dev/null +++ b/src/target.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2016 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#include "target.hpp" +#include "util.hpp" + +static const ArchType arch_list[] = { + {ZigLLVM_arm}, + {ZigLLVM_armeb}, + {ZigLLVM_aarch64}, + {ZigLLVM_aarch64_be}, + {ZigLLVM_bpfel}, + {ZigLLVM_bpfeb}, + {ZigLLVM_hexagon}, + {ZigLLVM_mips}, + {ZigLLVM_mipsel}, + {ZigLLVM_mips64}, + {ZigLLVM_mips64el}, + {ZigLLVM_msp430}, + {ZigLLVM_ppc}, + {ZigLLVM_ppc64}, + {ZigLLVM_ppc64le}, + {ZigLLVM_r600}, + {ZigLLVM_amdgcn}, + {ZigLLVM_sparc}, + {ZigLLVM_sparcv9}, + {ZigLLVM_sparcel}, + {ZigLLVM_systemz}, + {ZigLLVM_tce}, + {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_wasm32}, + {ZigLLVM_wasm64}, +}; + +static const SubArchType sub_arch_list[] = { + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_1a, "v8_1a"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8, "v8"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7, "v7"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7em, "v7em"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7m, "v7m"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7s, "v7s"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6, "v6"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6m, "v6m"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6k, "v6k"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6t2, "v6t2"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v5, "v5"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v5te, "v5te"}, + {ZigLLVM_arm, ZigLLVM_ARMSubArch_v4t, "v4t"}, + + {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v3, "v3"}, + {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v4, "v4"}, + {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v5, "v5"}, +}; + +static const VendorType vendor_list[] = { + {ZigLLVM_Apple}, + {ZigLLVM_PC}, + {ZigLLVM_SCEI}, + {ZigLLVM_BGP}, + {ZigLLVM_BGQ}, + {ZigLLVM_Freescale}, + {ZigLLVM_IBM}, + {ZigLLVM_ImaginationTechnologies}, + {ZigLLVM_MipsTechnologies}, + {ZigLLVM_NVIDIA}, + {ZigLLVM_CSR}, +}; + +static const OsType os_list[] = { + {ZigLLVM_UnknownOS}, + {ZigLLVM_CloudABI}, + {ZigLLVM_Darwin}, + {ZigLLVM_DragonFly}, + {ZigLLVM_FreeBSD}, + {ZigLLVM_IOS}, + {ZigLLVM_KFreeBSD}, + {ZigLLVM_Linux}, + {ZigLLVM_Lv2}, + {ZigLLVM_MacOSX}, + {ZigLLVM_NetBSD}, + {ZigLLVM_OpenBSD}, + {ZigLLVM_Solaris}, + {ZigLLVM_Win32}, + {ZigLLVM_Haiku}, + {ZigLLVM_Minix}, + {ZigLLVM_RTEMS}, + {ZigLLVM_NaCl}, + {ZigLLVM_CNK}, + {ZigLLVM_Bitrig}, + {ZigLLVM_AIX}, + {ZigLLVM_CUDA}, + {ZigLLVM_NVCL}, + {ZigLLVM_AMDHSA}, + {ZigLLVM_PS4}, +}; + +static const EnvironmentType environ_list[] = { + {ZigLLVM_GNU}, + {ZigLLVM_GNUEABI}, + {ZigLLVM_GNUEABIHF}, + {ZigLLVM_GNUX32}, + {ZigLLVM_CODE16}, + {ZigLLVM_EABI}, + {ZigLLVM_EABIHF}, + {ZigLLVM_Android}, + {ZigLLVM_MSVC}, + {ZigLLVM_Itanium}, + {ZigLLVM_Cygnus}, +}; + +int target_arch_count(void) { + return array_length(arch_list); +} + +const ArchType *get_target_arch(int index) { + return &arch_list[index]; +} + +int target_sub_arch_count(void) { + return array_length(sub_arch_list); +} +const SubArchType *get_target_sub_arch(int index) { + return &sub_arch_list[index]; +} + +int target_vendor_count(void) { + return array_length(vendor_list); +} + +const VendorType *get_target_vendor(int index) { + return &vendor_list[index]; +} + +int target_os_count(void) { + return array_length(os_list); +} +const OsType *get_target_os(int index) { + return &os_list[index]; +} +const char *get_target_os_name(const OsType *os_type) { + return (os_type->llvm_os == ZigLLVM_UnknownOS) ? "freestanding" : ZigLLVMGetOSTypeName(os_type->llvm_os); +} + +int target_environ_count(void) { + return array_length(environ_list); +} +const EnvironmentType *get_target_environ(int index) { + return &environ_list[index]; +} diff --git a/src/target.hpp b/src/target.hpp new file mode 100644 index 0000000000..8167bb0da5 --- /dev/null +++ b/src/target.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef ZIG_TARGET_HPP +#define ZIG_TARGET_HPP + +#include + +struct ArchType { + ZigLLVM_ArchType llvm_arch; +}; + +struct SubArchType { + ZigLLVM_ArchType arch; // which arch it applies to + ZigLLVM_SubArchType sub_arch; + const char *name; +}; + +struct VendorType { + ZigLLVM_VendorType llvm_vendor; +}; + +struct OsType { + ZigLLVM_OSType llvm_os; +}; + +struct EnvironmentType { + ZigLLVM_EnvironmentType llvm_environment; +}; + +int target_arch_count(void); +const ArchType *get_target_arch(int index); + +int target_sub_arch_count(void); +const SubArchType *get_target_sub_arch(int index); + +int target_vendor_count(void); +const VendorType *get_target_vendor(int index); + +int target_os_count(void); +const OsType *get_target_os(int index); +const char *get_target_os_name(const OsType *os_type); + +int target_environ_count(void); +const EnvironmentType *get_target_environ(int index); + +#endif diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 5749a996d5..277a155fe0 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -514,8 +514,32 @@ void LLVMZigSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) { } } + +static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, ""); +static_assert((Triple::VendorType)ZigLLVM_LastVendorType == Triple::LastVendorType, ""); +static_assert((Triple::OSType)ZigLLVM_LastOSType == Triple::LastOSType, ""); +static_assert((Triple::EnvironmentType)ZigLLVM_LastEnvironmentType == Triple::LastEnvironmentType, ""); + +const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch) { + return Triple::getArchTypeName((Triple::ArchType)arch); +} + +const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) { + return Triple::getVendorTypeName((Triple::VendorType)vendor); +} + +const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os) { + return Triple::getOSTypeName((Triple::OSType)os); +} + +const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType environ) { + return Triple::getEnvironmentTypeName((Triple::EnvironmentType)environ); +} + //------------------------------------ +#include "buffer.hpp" + enum FloatAbi { FloatAbiHard, FloatAbiSoft, diff --git a/src/zig_llvm.hpp b/src/zig_llvm.hpp index aa50cddaa1..26fdda1840 100644 --- a/src/zig_llvm.hpp +++ b/src/zig_llvm.hpp @@ -143,11 +143,156 @@ LLVMZigDILocation *LLVMZigGetDebugLoc(unsigned line, unsigned col, LLVMZigDIScop void LLVMZigSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state); +// copied from include/llvm/ADT/Triple.h + +enum ZigLLVM_ArchType { + ZigLLVM_UnknownArch, + + ZigLLVM_arm, // ARM (little endian): arm, armv.*, xscale + ZigLLVM_armeb, // ARM (big endian): armeb + ZigLLVM_aarch64, // AArch64 (little endian): aarch64 + ZigLLVM_aarch64_be, // AArch64 (big endian): aarch64_be + ZigLLVM_bpfel, // eBPF or extended BPF or 64-bit BPF (little endian) + ZigLLVM_bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian) + ZigLLVM_hexagon, // Hexagon: hexagon + ZigLLVM_mips, // MIPS: mips, mipsallegrex + ZigLLVM_mipsel, // MIPSEL: mipsel, mipsallegrexel + ZigLLVM_mips64, // MIPS64: mips64 + ZigLLVM_mips64el, // MIPS64EL: mips64el + ZigLLVM_msp430, // MSP430: msp430 + ZigLLVM_ppc, // PPC: powerpc + ZigLLVM_ppc64, // PPC64: powerpc64, ppu + ZigLLVM_ppc64le, // PPC64LE: powerpc64le + ZigLLVM_r600, // R600: AMD GPUs HD2XXX - HD6XXX + ZigLLVM_amdgcn, // AMDGCN: AMD GCN GPUs + ZigLLVM_sparc, // Sparc: sparc + ZigLLVM_sparcv9, // Sparcv9: Sparcv9 + ZigLLVM_sparcel, // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant + ZigLLVM_systemz, // SystemZ: s390x + ZigLLVM_tce, // TCE (http://tce.cs.tut.fi/): tce + ZigLLVM_thumb, // Thumb (little endian): thumb, thumbv.* + ZigLLVM_thumbeb, // Thumb (big endian): thumbeb + ZigLLVM_x86, // X86: i[3-9]86 + ZigLLVM_x86_64, // X86-64: amd64, x86_64 + ZigLLVM_xcore, // XCore: xcore + ZigLLVM_nvptx, // NVPTX: 32-bit + ZigLLVM_nvptx64, // NVPTX: 64-bit + ZigLLVM_le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten) + ZigLLVM_le64, // le64: generic little-endian 64-bit CPU (PNaCl / Emscripten) + ZigLLVM_amdil, // AMDIL + ZigLLVM_amdil64, // AMDIL with 64-bit pointers + ZigLLVM_hsail, // AMD HSAIL + ZigLLVM_hsail64, // AMD HSAIL with 64-bit pointers + ZigLLVM_spir, // SPIR: standard portable IR for OpenCL 32-bit version + ZigLLVM_spir64, // SPIR: standard portable IR for OpenCL 64-bit version + ZigLLVM_kalimba, // Kalimba: generic kalimba + ZigLLVM_shave, // SHAVE: Movidius vector VLIW processors + ZigLLVM_wasm32, // WebAssembly with 32-bit pointers + ZigLLVM_wasm64, // WebAssembly with 64-bit pointers + ZigLLVM_LastArchType = ZigLLVM_wasm64 +}; + +enum ZigLLVM_SubArchType { + ZigLLVM_NoSubArch, + + ZigLLVM_ARMSubArch_v8_1a, + ZigLLVM_ARMSubArch_v8, + ZigLLVM_ARMSubArch_v7, + ZigLLVM_ARMSubArch_v7em, + ZigLLVM_ARMSubArch_v7m, + ZigLLVM_ARMSubArch_v7s, + ZigLLVM_ARMSubArch_v6, + ZigLLVM_ARMSubArch_v6m, + ZigLLVM_ARMSubArch_v6k, + ZigLLVM_ARMSubArch_v6t2, + ZigLLVM_ARMSubArch_v5, + ZigLLVM_ARMSubArch_v5te, + ZigLLVM_ARMSubArch_v4t, + + ZigLLVM_KalimbaSubArch_v3, + ZigLLVM_KalimbaSubArch_v4, + ZigLLVM_KalimbaSubArch_v5 +}; +enum ZigLLVM_VendorType { + ZigLLVM_UnknownVendor, + + ZigLLVM_Apple, + ZigLLVM_PC, + ZigLLVM_SCEI, + ZigLLVM_BGP, + ZigLLVM_BGQ, + ZigLLVM_Freescale, + ZigLLVM_IBM, + ZigLLVM_ImaginationTechnologies, + ZigLLVM_MipsTechnologies, + ZigLLVM_NVIDIA, + ZigLLVM_CSR, + ZigLLVM_LastVendorType = ZigLLVM_CSR +}; +enum ZigLLVM_OSType { + ZigLLVM_UnknownOS, + + ZigLLVM_CloudABI, + ZigLLVM_Darwin, + ZigLLVM_DragonFly, + ZigLLVM_FreeBSD, + ZigLLVM_IOS, + ZigLLVM_KFreeBSD, + ZigLLVM_Linux, + ZigLLVM_Lv2, // PS3 + ZigLLVM_MacOSX, + ZigLLVM_NetBSD, + ZigLLVM_OpenBSD, + ZigLLVM_Solaris, + ZigLLVM_Win32, + ZigLLVM_Haiku, + ZigLLVM_Minix, + ZigLLVM_RTEMS, + ZigLLVM_NaCl, // Native Client + ZigLLVM_CNK, // BG/P Compute-Node Kernel + ZigLLVM_Bitrig, + ZigLLVM_AIX, + ZigLLVM_CUDA, // NVIDIA CUDA + ZigLLVM_NVCL, // NVIDIA OpenCL + ZigLLVM_AMDHSA, // AMD HSA Runtime + ZigLLVM_PS4, + ZigLLVM_LastOSType = ZigLLVM_PS4 +}; +enum ZigLLVM_EnvironmentType { + ZigLLVM_UnknownEnvironment, + + ZigLLVM_GNU, + ZigLLVM_GNUEABI, + ZigLLVM_GNUEABIHF, + ZigLLVM_GNUX32, + ZigLLVM_CODE16, + ZigLLVM_EABI, + ZigLLVM_EABIHF, + ZigLLVM_Android, + + ZigLLVM_MSVC, + ZigLLVM_Itanium, + ZigLLVM_Cygnus, + ZigLLVM_LastEnvironmentType = ZigLLVM_Cygnus +}; +enum ZigLLVM_ObjectFormatType { + ZigLLVM_UnknownObjectFormat, + + ZigLLVM_COFF, + ZigLLVM_ELF, + ZigLLVM_MachO, +}; + +const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch); +const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor); +const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os); +const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType environ); + + /* * This stuff is not LLVM API but it depends on the LLVM C++ API so we put it here. */ -#include "buffer.hpp" - +struct Buf; Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine); #endif