Commit 1ff2edf67e

Andrew Kelley <superjoe30@gmail.com>
2016-02-10 23:41:50
add "targets" command to list architectures, oses, abis
1 parent b988017
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
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;
 
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));
src/main.cpp
@@ -10,6 +10,7 @@
 #include "codegen.hpp"
 #include "os.hpp"
 #include "error.hpp"
+#include "target.hpp"
 
 #include <stdio.h>
 
@@ -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);
     }
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];
+}
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 <zig_llvm.hpp>
+
+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
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,
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
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"