zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

blob 01e8b90c (31823B) - Raw


      1 /*
      2  * Copyright (c) 2016 Andrew Kelley
      3  *
      4  * This file is part of zig, which is MIT licensed.
      5  * See http://opensource.org/licenses/MIT
      6  */
      7 
      8 #include "buffer.hpp"
      9 #include "error.hpp"
     10 #include "target.hpp"
     11 #include "util.hpp"
     12 #include "os.hpp"
     13 
     14 #include <stdio.h>
     15 
     16 static const ArchType arch_list[] = {
     17     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_3a},
     18     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_2a},
     19     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_1a},
     20     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8},
     21     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8r},
     22     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8m_baseline},
     23     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8m_mainline},
     24     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7},
     25     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7em},
     26     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7m},
     27     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7s},
     28     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7k},
     29     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7ve},
     30     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6},
     31     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6m},
     32     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6k},
     33     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6t2},
     34     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v5},
     35     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v5te},
     36     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v4t},
     37 
     38     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_3a},
     39     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_2a},
     40     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_1a},
     41     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8},
     42     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8r},
     43     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8m_baseline},
     44     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8m_mainline},
     45     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7},
     46     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7em},
     47     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7m},
     48     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7s},
     49     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7k},
     50     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7ve},
     51     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6},
     52     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6m},
     53     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6k},
     54     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6t2},
     55     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v5},
     56     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v5te},
     57     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v4t},
     58 
     59     {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8_3a},
     60     {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8_2a},
     61     {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8_1a},
     62     {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8},
     63     {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8r},
     64     {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8m_baseline},
     65     {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8m_mainline},
     66 
     67     {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8_3a},
     68     {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8_2a},
     69     {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8_1a},
     70     {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8},
     71     {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8r},
     72     {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8m_baseline},
     73     {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8m_mainline},
     74 
     75     {ZigLLVM_arc, ZigLLVM_NoSubArch},
     76     {ZigLLVM_avr, ZigLLVM_NoSubArch},
     77     {ZigLLVM_bpfel, ZigLLVM_NoSubArch},
     78     {ZigLLVM_bpfeb, ZigLLVM_NoSubArch},
     79     {ZigLLVM_hexagon, ZigLLVM_NoSubArch},
     80     {ZigLLVM_mips, ZigLLVM_NoSubArch},
     81     {ZigLLVM_mipsel, ZigLLVM_NoSubArch},
     82     {ZigLLVM_mips64, ZigLLVM_NoSubArch},
     83     {ZigLLVM_mips64el, ZigLLVM_NoSubArch},
     84     {ZigLLVM_msp430, ZigLLVM_NoSubArch},
     85     {ZigLLVM_nios2, ZigLLVM_NoSubArch},
     86     {ZigLLVM_ppc, ZigLLVM_NoSubArch},
     87     {ZigLLVM_ppc64, ZigLLVM_NoSubArch},
     88     {ZigLLVM_ppc64le, ZigLLVM_NoSubArch},
     89     {ZigLLVM_r600, ZigLLVM_NoSubArch},
     90     {ZigLLVM_amdgcn, ZigLLVM_NoSubArch},
     91     {ZigLLVM_riscv32, ZigLLVM_NoSubArch},
     92     {ZigLLVM_riscv64, ZigLLVM_NoSubArch},
     93     {ZigLLVM_sparc, ZigLLVM_NoSubArch},
     94     {ZigLLVM_sparcv9, ZigLLVM_NoSubArch},
     95     {ZigLLVM_sparcel, ZigLLVM_NoSubArch},
     96     {ZigLLVM_systemz, ZigLLVM_NoSubArch},
     97     {ZigLLVM_tce, ZigLLVM_NoSubArch},
     98     {ZigLLVM_tcele, ZigLLVM_NoSubArch},
     99     {ZigLLVM_thumb, ZigLLVM_NoSubArch},
    100     {ZigLLVM_thumbeb, ZigLLVM_NoSubArch},
    101     {ZigLLVM_x86, ZigLLVM_NoSubArch},
    102     {ZigLLVM_x86_64, ZigLLVM_NoSubArch},
    103     {ZigLLVM_xcore, ZigLLVM_NoSubArch},
    104     {ZigLLVM_nvptx, ZigLLVM_NoSubArch},
    105     {ZigLLVM_nvptx64, ZigLLVM_NoSubArch},
    106     {ZigLLVM_le32, ZigLLVM_NoSubArch},
    107     {ZigLLVM_le64, ZigLLVM_NoSubArch},
    108     {ZigLLVM_amdil, ZigLLVM_NoSubArch},
    109     {ZigLLVM_amdil64, ZigLLVM_NoSubArch},
    110     {ZigLLVM_hsail, ZigLLVM_NoSubArch},
    111     {ZigLLVM_hsail64, ZigLLVM_NoSubArch},
    112     {ZigLLVM_spir, ZigLLVM_NoSubArch},
    113     {ZigLLVM_spir64, ZigLLVM_NoSubArch},
    114 
    115     {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v3},
    116     {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v4},
    117     {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v5},
    118 
    119     {ZigLLVM_shave, ZigLLVM_NoSubArch},
    120     {ZigLLVM_lanai, ZigLLVM_NoSubArch},
    121     {ZigLLVM_wasm32, ZigLLVM_NoSubArch},
    122     {ZigLLVM_wasm64, ZigLLVM_NoSubArch},
    123     {ZigLLVM_renderscript32, ZigLLVM_NoSubArch},
    124     {ZigLLVM_renderscript64, ZigLLVM_NoSubArch},
    125 };
    126 
    127 static const ZigLLVM_VendorType vendor_list[] = {
    128     ZigLLVM_Apple,
    129     ZigLLVM_PC,
    130     ZigLLVM_SCEI,
    131     ZigLLVM_BGP,
    132     ZigLLVM_BGQ,
    133     ZigLLVM_Freescale,
    134     ZigLLVM_IBM,
    135     ZigLLVM_ImaginationTechnologies,
    136     ZigLLVM_MipsTechnologies,
    137     ZigLLVM_NVIDIA,
    138     ZigLLVM_CSR,
    139     ZigLLVM_Myriad,
    140     ZigLLVM_AMD,
    141     ZigLLVM_Mesa,
    142     ZigLLVM_SUSE,
    143 };
    144 
    145 static const Os os_list[] = {
    146     OsFreestanding,
    147     OsAnanas,
    148     OsCloudABI,
    149     OsDragonFly,
    150     OsFreeBSD,
    151     OsFuchsia,
    152     OsIOS,
    153     OsKFreeBSD,
    154     OsLinux,
    155     OsLv2,        // PS3
    156     OsMacOSX,
    157     OsNetBSD,
    158     OsOpenBSD,
    159     OsSolaris,
    160     OsWindows,
    161     OsHaiku,
    162     OsMinix,
    163     OsRTEMS,
    164     OsNaCl,       // Native Client
    165     OsCNK,        // BG/P Compute-Node Kernel
    166     OsAIX,
    167     OsCUDA,       // NVIDIA CUDA
    168     OsNVCL,       // NVIDIA OpenCL
    169     OsAMDHSA,     // AMD HSA Runtime
    170     OsPS4,
    171     OsELFIAMCU,
    172     OsTvOS,       // Apple tvOS
    173     OsWatchOS,    // Apple watchOS
    174     OsMesa3D,
    175     OsContiki,
    176     OsAMDPAL,
    177     OsZen,
    178     OsUefi,
    179 };
    180 
    181 // Coordinate with zig_llvm.h
    182 static const ZigLLVM_EnvironmentType environ_list[] = {
    183     ZigLLVM_UnknownEnvironment,
    184 
    185     ZigLLVM_GNU,
    186     ZigLLVM_GNUABIN32,
    187     ZigLLVM_GNUABI64,
    188     ZigLLVM_GNUEABI,
    189     ZigLLVM_GNUEABIHF,
    190     ZigLLVM_GNUX32,
    191     ZigLLVM_CODE16,
    192     ZigLLVM_EABI,
    193     ZigLLVM_EABIHF,
    194     ZigLLVM_Android,
    195     ZigLLVM_Musl,
    196     ZigLLVM_MuslEABI,
    197     ZigLLVM_MuslEABIHF,
    198     ZigLLVM_MSVC,
    199     ZigLLVM_Itanium,
    200     ZigLLVM_Cygnus,
    201     ZigLLVM_CoreCLR,
    202     ZigLLVM_Simulator,
    203 };
    204 
    205 static const ZigLLVM_ObjectFormatType oformat_list[] = {
    206     ZigLLVM_UnknownObjectFormat,
    207     ZigLLVM_COFF,
    208     ZigLLVM_ELF,
    209     ZigLLVM_MachO,
    210     ZigLLVM_Wasm,
    211 };
    212 
    213 size_t target_oformat_count(void) {
    214     return array_length(oformat_list);
    215 }
    216 
    217 ZigLLVM_ObjectFormatType get_target_oformat(size_t index) {
    218     return oformat_list[index];
    219 }
    220 
    221 const char *get_target_oformat_name(ZigLLVM_ObjectFormatType oformat) {
    222     switch (oformat) {
    223         case ZigLLVM_UnknownObjectFormat: return "unknown";
    224         case ZigLLVM_COFF: return "coff";
    225         case ZigLLVM_ELF: return "elf";
    226         case ZigLLVM_MachO: return "macho";
    227         case ZigLLVM_Wasm: return "wasm";
    228     }
    229     zig_unreachable();
    230 }
    231 
    232 size_t target_arch_count(void) {
    233     return array_length(arch_list);
    234 }
    235 
    236 const ArchType *get_target_arch(size_t index) {
    237     return &arch_list[index];
    238 }
    239 
    240 size_t target_vendor_count(void) {
    241     return array_length(vendor_list);
    242 }
    243 
    244 ZigLLVM_VendorType get_target_vendor(size_t index) {
    245     return vendor_list[index];
    246 }
    247 
    248 size_t target_os_count(void) {
    249     return array_length(os_list);
    250 }
    251 Os get_target_os(size_t index) {
    252     return os_list[index];
    253 }
    254 
    255 ZigLLVM_OSType get_llvm_os_type(Os os_type) {
    256     switch (os_type) {
    257         case OsFreestanding:
    258         case OsZen:
    259             return ZigLLVM_UnknownOS;
    260         case OsAnanas:
    261             return ZigLLVM_Ananas;
    262         case OsCloudABI:
    263             return ZigLLVM_CloudABI;
    264         case OsDragonFly:
    265             return ZigLLVM_DragonFly;
    266         case OsFreeBSD:
    267             return ZigLLVM_FreeBSD;
    268         case OsFuchsia:
    269             return ZigLLVM_Fuchsia;
    270         case OsIOS:
    271             return ZigLLVM_IOS;
    272         case OsKFreeBSD:
    273             return ZigLLVM_KFreeBSD;
    274         case OsLinux:
    275             return ZigLLVM_Linux;
    276         case OsLv2:
    277             return ZigLLVM_Lv2;
    278         case OsMacOSX:
    279             return ZigLLVM_MacOSX;
    280         case OsNetBSD:
    281             return ZigLLVM_NetBSD;
    282         case OsOpenBSD:
    283             return ZigLLVM_OpenBSD;
    284         case OsSolaris:
    285             return ZigLLVM_Solaris;
    286         case OsWindows:
    287         case OsUefi:
    288             return ZigLLVM_Win32;
    289         case OsHaiku:
    290             return ZigLLVM_Haiku;
    291         case OsMinix:
    292             return ZigLLVM_Minix;
    293         case OsRTEMS:
    294             return ZigLLVM_RTEMS;
    295         case OsNaCl:
    296             return ZigLLVM_NaCl;
    297         case OsCNK:
    298             return ZigLLVM_CNK;
    299         case OsAIX:
    300             return ZigLLVM_AIX;
    301         case OsCUDA:
    302             return ZigLLVM_CUDA;
    303         case OsNVCL:
    304             return ZigLLVM_NVCL;
    305         case OsAMDHSA:
    306             return ZigLLVM_AMDHSA;
    307         case OsPS4:
    308             return ZigLLVM_PS4;
    309         case OsELFIAMCU:
    310             return ZigLLVM_ELFIAMCU;
    311         case OsTvOS:
    312             return ZigLLVM_TvOS;
    313         case OsWatchOS:
    314             return ZigLLVM_WatchOS;
    315         case OsMesa3D:
    316             return ZigLLVM_Mesa3D;
    317         case OsContiki:
    318             return ZigLLVM_Contiki;
    319         case OsAMDPAL:
    320             return ZigLLVM_AMDPAL;
    321     }
    322     zig_unreachable();
    323 }
    324 
    325 static Os get_zig_os_type(ZigLLVM_OSType os_type) {
    326     switch (os_type) {
    327         case ZigLLVM_UnknownOS:
    328             return OsFreestanding;
    329         case ZigLLVM_Ananas:
    330             return OsAnanas;
    331         case ZigLLVM_CloudABI:
    332             return OsCloudABI;
    333         case ZigLLVM_DragonFly:
    334             return OsDragonFly;
    335         case ZigLLVM_FreeBSD:
    336             return OsFreeBSD;
    337         case ZigLLVM_Fuchsia:
    338             return OsFuchsia;
    339         case ZigLLVM_IOS:
    340             return OsIOS;
    341         case ZigLLVM_KFreeBSD:
    342             return OsKFreeBSD;
    343         case ZigLLVM_Linux:
    344             return OsLinux;
    345         case ZigLLVM_Lv2:
    346             return OsLv2;
    347         case ZigLLVM_Darwin:
    348         case ZigLLVM_MacOSX:
    349             return OsMacOSX;
    350         case ZigLLVM_NetBSD:
    351             return OsNetBSD;
    352         case ZigLLVM_OpenBSD:
    353             return OsOpenBSD;
    354         case ZigLLVM_Solaris:
    355             return OsSolaris;
    356         case ZigLLVM_Win32:
    357             return OsWindows;
    358         case ZigLLVM_Haiku:
    359             return OsHaiku;
    360         case ZigLLVM_Minix:
    361             return OsMinix;
    362         case ZigLLVM_RTEMS:
    363             return OsRTEMS;
    364         case ZigLLVM_NaCl:
    365             return OsNaCl;
    366         case ZigLLVM_CNK:
    367             return OsCNK;
    368         case ZigLLVM_AIX:
    369             return OsAIX;
    370         case ZigLLVM_CUDA:
    371             return OsCUDA;
    372         case ZigLLVM_NVCL:
    373             return OsNVCL;
    374         case ZigLLVM_AMDHSA:
    375             return OsAMDHSA;
    376         case ZigLLVM_PS4:
    377             return OsPS4;
    378         case ZigLLVM_ELFIAMCU:
    379             return OsELFIAMCU;
    380         case ZigLLVM_TvOS:
    381             return OsTvOS;
    382         case ZigLLVM_WatchOS:
    383             return OsWatchOS;
    384         case ZigLLVM_Mesa3D:
    385             return OsMesa3D;
    386         case ZigLLVM_Contiki:
    387             return OsContiki;
    388         case ZigLLVM_AMDPAL:
    389             return OsAMDPAL;
    390     }
    391     zig_unreachable();
    392 }
    393 
    394 const char *get_target_os_name(Os os_type) {
    395     switch (os_type) {
    396         case OsFreestanding:
    397             return "freestanding";
    398         case OsZen:
    399             return "zen";
    400         case OsUefi:
    401             return "uefi";
    402         case OsAnanas:
    403         case OsCloudABI:
    404         case OsDragonFly:
    405         case OsFreeBSD:
    406         case OsFuchsia:
    407         case OsIOS:
    408         case OsKFreeBSD:
    409         case OsLinux:
    410         case OsLv2:        // PS3
    411         case OsMacOSX:
    412         case OsNetBSD:
    413         case OsOpenBSD:
    414         case OsSolaris:
    415         case OsWindows:
    416         case OsHaiku:
    417         case OsMinix:
    418         case OsRTEMS:
    419         case OsNaCl:       // Native Client
    420         case OsCNK:        // BG/P Compute-Node Kernel
    421         case OsAIX:
    422         case OsCUDA:       // NVIDIA CUDA
    423         case OsNVCL:       // NVIDIA OpenCL
    424         case OsAMDHSA:     // AMD HSA Runtime
    425         case OsPS4:
    426         case OsELFIAMCU:
    427         case OsTvOS:       // Apple tvOS
    428         case OsWatchOS:    // Apple watchOS
    429         case OsMesa3D:
    430         case OsContiki:
    431         case OsAMDPAL:
    432             return ZigLLVMGetOSTypeName(get_llvm_os_type(os_type));
    433     }
    434     zig_unreachable();
    435 }
    436 
    437 size_t target_environ_count(void) {
    438     return array_length(environ_list);
    439 }
    440 ZigLLVM_EnvironmentType get_target_environ(size_t index) {
    441     return environ_list[index];
    442 }
    443 
    444 void get_native_target(ZigTarget *target) {
    445     ZigLLVM_OSType os_type;
    446     ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os
    447     ZigLLVMGetNativeTarget(
    448             &target->arch.arch,
    449             &target->arch.sub_arch,
    450             &target->vendor,
    451             &os_type,
    452             &target->env_type,
    453             &oformat);
    454     target->os = get_zig_os_type(os_type);
    455     target->is_native = true;
    456 }
    457 
    458 void get_unknown_target(ZigTarget *target) {
    459     target->arch.arch = ZigLLVM_UnknownArch;
    460     target->arch.sub_arch = ZigLLVM_NoSubArch;
    461     target->vendor = ZigLLVM_UnknownVendor;
    462     target->os = OsFreestanding;
    463     target->env_type = ZigLLVM_UnknownEnvironment;
    464     target->is_native = false;
    465 }
    466 
    467 static void get_arch_name_raw(char *out_str, ZigLLVM_ArchType arch, ZigLLVM_SubArchType sub_arch) {
    468     const char *sub_str = (sub_arch == ZigLLVM_NoSubArch) ? "" : ZigLLVMGetSubArchTypeName(sub_arch);
    469     sprintf(out_str, "%s%s", ZigLLVMGetArchTypeName(arch), sub_str);
    470 }
    471 
    472 void get_arch_name(char *out_str, const ArchType *arch) {
    473     return get_arch_name_raw(out_str, arch->arch, arch->sub_arch);
    474 }
    475 
    476 int parse_target_arch(const char *str, ArchType *out_arch) {
    477     for (size_t i = 0; i < array_length(arch_list); i += 1) {
    478         const ArchType *arch = &arch_list[i];
    479         char arch_name[50];
    480         get_arch_name_raw(arch_name, arch->arch, arch->sub_arch);
    481         if (strcmp(arch_name, str) == 0) {
    482             *out_arch = *arch;
    483             return 0;
    484         }
    485     }
    486     return ErrorFileNotFound;
    487 }
    488 
    489 int parse_target_os(const char *str, Os *out_os) {
    490     for (size_t i = 0; i < array_length(os_list); i += 1) {
    491         Os os = os_list[i];
    492         const char *os_name = get_target_os_name(os);
    493         if (strcmp(os_name, str) == 0) {
    494             *out_os = os;
    495             return 0;
    496         }
    497     }
    498     return ErrorFileNotFound;
    499 }
    500 
    501 int parse_target_environ(const char *str, ZigLLVM_EnvironmentType *out_environ) {
    502     for (size_t i = 0; i < array_length(environ_list); i += 1) {
    503         ZigLLVM_EnvironmentType env_type = environ_list[i];
    504         const char *environ_name = ZigLLVMGetEnvironmentTypeName(env_type);
    505         if (strcmp(environ_name, str) == 0) {
    506             *out_environ = env_type;
    507             return 0;
    508         }
    509     }
    510     return ErrorFileNotFound;
    511 }
    512 
    513 void init_all_targets(void) {
    514     LLVMInitializeAllTargets();
    515     LLVMInitializeAllTargetInfos();
    516     LLVMInitializeAllTargetMCs();
    517     LLVMInitializeAllAsmPrinters();
    518     LLVMInitializeAllAsmParsers();
    519 }
    520 
    521 void get_target_triple(Buf *triple, const ZigTarget *target) {
    522     char arch_name[50];
    523     get_arch_name(arch_name, &target->arch);
    524 
    525     buf_resize(triple, 0);
    526 
    527     // LLVM WebAssembly output support requires the target to be activated at
    528     // build type with -DCMAKE_LLVM_EXPIERMENTAL_TARGETS_TO_BUILD=WebAssembly.
    529     //
    530     // LLVM determines the output format based on the environment suffix,
    531     // defaulting to an object based on the architecture. The default format in
    532     // LLVM 6 sets the wasm arch output incorrectly to ELF. We need to
    533     // explicitly set this ourself in order for it to work.
    534     //
    535     // This is fixed in LLVM 7 and you will be able to get wasm output by
    536     // using the target triple `wasm32-unknown-unknown-unknown`.
    537     if (!strncmp(arch_name, "wasm", 4)) {
    538         buf_appendf(triple, "%s-%s-%s-wasm", arch_name,
    539                 ZigLLVMGetVendorTypeName(target->vendor),
    540                 ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)));
    541     } else {
    542         buf_appendf(triple, "%s-%s-%s-%s", arch_name,
    543                 ZigLLVMGetVendorTypeName(target->vendor),
    544                 ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),
    545                 ZigLLVMGetEnvironmentTypeName(target->env_type));
    546     }
    547 }
    548 
    549 bool target_is_darwin(const ZigTarget *target) {
    550     switch (target->os) {
    551         case OsMacOSX:
    552         case OsIOS:
    553             return true;
    554         default:
    555             return false;
    556     }
    557 }
    558 
    559 ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target) {
    560     if (target->os == OsUefi || target->os == OsWindows) {
    561         return ZigLLVM_COFF;
    562     } else if (target_is_darwin(target)) {
    563         return ZigLLVM_MachO;
    564     }
    565     if (target->arch.arch == ZigLLVM_wasm32 ||
    566         target->arch.arch == ZigLLVM_wasm64)
    567     {
    568         return ZigLLVM_Wasm;
    569     }
    570     return ZigLLVM_ELF;
    571 }
    572 
    573 // See lib/Support/Triple.cpp in LLVM for the source of this data.
    574 // getArchPointerBitWidth
    575 static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) {
    576     switch (arch) {
    577         case ZigLLVM_UnknownArch:
    578             return 0;
    579 
    580         case ZigLLVM_avr:
    581         case ZigLLVM_msp430:
    582             return 16;
    583 
    584         case ZigLLVM_arc:
    585         case ZigLLVM_arm:
    586         case ZigLLVM_armeb:
    587         case ZigLLVM_hexagon:
    588         case ZigLLVM_le32:
    589         case ZigLLVM_mips:
    590         case ZigLLVM_mipsel:
    591         case ZigLLVM_nios2:
    592         case ZigLLVM_nvptx:
    593         case ZigLLVM_ppc:
    594         case ZigLLVM_r600:
    595         case ZigLLVM_riscv32:
    596         case ZigLLVM_sparc:
    597         case ZigLLVM_sparcel:
    598         case ZigLLVM_tce:
    599         case ZigLLVM_tcele:
    600         case ZigLLVM_thumb:
    601         case ZigLLVM_thumbeb:
    602         case ZigLLVM_x86:
    603         case ZigLLVM_xcore:
    604         case ZigLLVM_amdil:
    605         case ZigLLVM_hsail:
    606         case ZigLLVM_spir:
    607         case ZigLLVM_kalimba:
    608         case ZigLLVM_lanai:
    609         case ZigLLVM_shave:
    610         case ZigLLVM_wasm32:
    611         case ZigLLVM_renderscript32:
    612             return 32;
    613 
    614         case ZigLLVM_aarch64:
    615         case ZigLLVM_aarch64_be:
    616         case ZigLLVM_amdgcn:
    617         case ZigLLVM_bpfel:
    618         case ZigLLVM_bpfeb:
    619         case ZigLLVM_le64:
    620         case ZigLLVM_mips64:
    621         case ZigLLVM_mips64el:
    622         case ZigLLVM_nvptx64:
    623         case ZigLLVM_ppc64:
    624         case ZigLLVM_ppc64le:
    625         case ZigLLVM_riscv64:
    626         case ZigLLVM_sparcv9:
    627         case ZigLLVM_systemz:
    628         case ZigLLVM_x86_64:
    629         case ZigLLVM_amdil64:
    630         case ZigLLVM_hsail64:
    631         case ZigLLVM_spir64:
    632         case ZigLLVM_wasm64:
    633         case ZigLLVM_renderscript64:
    634             return 64;
    635     }
    636     zig_unreachable();
    637 }
    638 
    639 uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
    640     switch (target->os) {
    641         case OsFreestanding:
    642             switch (target->arch.arch) {
    643                 case ZigLLVM_msp430:
    644                     switch (id) {
    645                         case CIntTypeShort:
    646                         case CIntTypeUShort:
    647                             return 16;
    648                         case CIntTypeInt:
    649                         case CIntTypeUInt:
    650                             return 16;
    651                         case CIntTypeLong:
    652                         case CIntTypeULong:
    653                             return 32;
    654                         case CIntTypeLongLong:
    655                         case CIntTypeULongLong:
    656                             return 64;
    657                         case CIntTypeCount:
    658                             zig_unreachable();
    659                     }
    660                 default:
    661                     switch (id) {
    662                         case CIntTypeShort:
    663                         case CIntTypeUShort:
    664                             return 16;
    665                         case CIntTypeInt:
    666                         case CIntTypeUInt:
    667                             return 32;
    668                         case CIntTypeLong:
    669                         case CIntTypeULong:
    670                             return get_arch_pointer_bit_width(target->arch.arch);
    671                         case CIntTypeLongLong:
    672                         case CIntTypeULongLong:
    673                             return 64;
    674                         case CIntTypeCount:
    675                             zig_unreachable();
    676                     }
    677             }
    678         case OsLinux:
    679         case OsMacOSX:
    680         case OsZen:
    681         case OsFreeBSD:
    682 	case OsNetBSD:
    683         case OsOpenBSD:
    684             switch (id) {
    685                 case CIntTypeShort:
    686                 case CIntTypeUShort:
    687                     return 16;
    688                 case CIntTypeInt:
    689                 case CIntTypeUInt:
    690                     return 32;
    691                 case CIntTypeLong:
    692                 case CIntTypeULong:
    693                     return get_arch_pointer_bit_width(target->arch.arch);
    694                 case CIntTypeLongLong:
    695                 case CIntTypeULongLong:
    696                     return 64;
    697                 case CIntTypeCount:
    698                     zig_unreachable();
    699             }
    700         case OsUefi:
    701         case OsWindows:
    702             switch (id) {
    703                 case CIntTypeShort:
    704                 case CIntTypeUShort:
    705                     return 16;
    706                 case CIntTypeInt:
    707                 case CIntTypeUInt:
    708                 case CIntTypeLong:
    709                 case CIntTypeULong:
    710                     return 32;
    711                 case CIntTypeLongLong:
    712                 case CIntTypeULongLong:
    713                     return 64;
    714                 case CIntTypeCount:
    715                     zig_unreachable();
    716             }
    717         case OsAnanas:
    718         case OsCloudABI:
    719         case OsDragonFly:
    720         case OsIOS:
    721         case OsKFreeBSD:
    722         case OsLv2:
    723         case OsSolaris:
    724         case OsHaiku:
    725         case OsMinix:
    726         case OsRTEMS:
    727         case OsNaCl:
    728         case OsCNK:
    729         case OsAIX:
    730         case OsCUDA:
    731         case OsNVCL:
    732         case OsAMDHSA:
    733         case OsPS4:
    734         case OsELFIAMCU:
    735         case OsTvOS:
    736         case OsWatchOS:
    737         case OsMesa3D:
    738         case OsFuchsia:
    739         case OsContiki:
    740         case OsAMDPAL:
    741             zig_panic("TODO c type size in bits for this target");
    742     }
    743     zig_unreachable();
    744 }
    745 
    746 bool target_allows_addr_zero(const ZigTarget *target) {
    747     return target->os == OsFreestanding;
    748 }
    749 
    750 const char *target_o_file_ext(const ZigTarget *target) {
    751     if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) {
    752         return ".obj";
    753     } else {
    754         return ".o";
    755     }
    756 }
    757 
    758 const char *target_asm_file_ext(const ZigTarget *target) {
    759     return ".s";
    760 }
    761 
    762 const char *target_llvm_ir_file_ext(const ZigTarget *target) {
    763     return ".ll";
    764 }
    765 
    766 const char *target_exe_file_ext(const ZigTarget *target) {
    767     if (target->os == OsWindows) {
    768         return ".exe";
    769     } else if (target->os == OsUefi) {
    770         return ".efi";
    771     } else {
    772         return "";
    773     }
    774 }
    775 
    776 const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
    777         size_t version_major, size_t version_minor, size_t version_patch)
    778 {
    779     if (target->os == OsWindows || target->os == OsUefi) {
    780         if (is_static) {
    781             return ".lib";
    782         } else {
    783             return ".dll";
    784         }
    785     } else {
    786         if (is_static) {
    787             return ".a";
    788         } else {
    789             return buf_ptr(buf_sprintf(".so.%" ZIG_PRI_usize, version_major));
    790         }
    791     }
    792 }
    793 
    794 enum FloatAbi {
    795     FloatAbiHard,
    796     FloatAbiSoft,
    797     FloatAbiSoftFp,
    798 };
    799 
    800 static FloatAbi get_float_abi(const ZigTarget *target) {
    801     const ZigLLVM_EnvironmentType env = target->env_type;
    802     if (env == ZigLLVM_GNUEABIHF ||
    803         env == ZigLLVM_EABIHF ||
    804         env == ZigLLVM_MuslEABIHF)
    805     {
    806         return FloatAbiHard;
    807     } else {
    808         return FloatAbiSoft;
    809     }
    810 }
    811 
    812 static bool is_64_bit(ZigLLVM_ArchType arch) {
    813     return get_arch_pointer_bit_width(arch) == 64;
    814 }
    815 
    816 Buf *target_dynamic_linker(const ZigTarget *target) {
    817     if (target->os == OsFreeBSD) {
    818         return buf_create_from_str("/libexec/ld-elf.so.1");
    819     }
    820     if (target->os == OsNetBSD) {
    821         return buf_create_from_str("/libexec/ld.elf_so");
    822     }
    823 
    824     const ZigLLVM_ArchType arch = target->arch.arch;
    825     const ZigLLVM_EnvironmentType env = target->env_type;
    826 
    827     if (env == ZigLLVM_Android) {
    828         if (is_64_bit(arch)) {
    829             return buf_create_from_str("/system/bin/linker64");
    830         } else {
    831             return buf_create_from_str("/system/bin/linker");
    832         }
    833     } else if (arch == ZigLLVM_x86 ||
    834             arch == ZigLLVM_sparc ||
    835             arch == ZigLLVM_sparcel)
    836     {
    837         return buf_create_from_str("/lib/ld-linux.so.2");
    838     } else if (arch == ZigLLVM_aarch64) {
    839         return buf_create_from_str("/lib/ld-linux-aarch64.so.1");
    840     } else if (arch == ZigLLVM_aarch64_be) {
    841         return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1");
    842     } else if (arch == ZigLLVM_arm || arch == ZigLLVM_thumb) {
    843         if (get_float_abi(target) == FloatAbiHard) {
    844             return buf_create_from_str("/lib/ld-linux-armhf.so.3");
    845         } else {
    846             return buf_create_from_str("/lib/ld-linux.so.3");
    847         }
    848     } else if (arch == ZigLLVM_armeb || arch == ZigLLVM_thumbeb) {
    849         if (get_float_abi(target) == FloatAbiHard) {
    850             return buf_create_from_str("/lib/ld-linux-armhf.so.3");
    851         } else {
    852             return buf_create_from_str("/lib/ld-linux.so.3");
    853         }
    854     } else if (arch == ZigLLVM_mips || arch == ZigLLVM_mipsel ||
    855             arch == ZigLLVM_mips64 || arch == ZigLLVM_mips64el)
    856     {
    857         // when you want to solve this TODO, grep clang codebase for
    858         // getLinuxDynamicLinker
    859         zig_panic("TODO figure out MIPS dynamic linker name");
    860     } else if (arch == ZigLLVM_ppc) {
    861         return buf_create_from_str("/lib/ld.so.1");
    862     } else if (arch == ZigLLVM_ppc64) {
    863         return buf_create_from_str("/lib64/ld64.so.2");
    864     } else if (arch == ZigLLVM_ppc64le) {
    865         return buf_create_from_str("/lib64/ld64.so.2");
    866     } else if (arch == ZigLLVM_systemz) {
    867         return buf_create_from_str("/lib64/ld64.so.1");
    868     } else if (arch == ZigLLVM_sparcv9) {
    869         return buf_create_from_str("/lib64/ld-linux.so.2");
    870     } else if (arch == ZigLLVM_x86_64 &&
    871             env == ZigLLVM_GNUX32)
    872     {
    873         return buf_create_from_str("/libx32/ld-linux-x32.so.2");
    874     } else if (arch == ZigLLVM_x86_64 &&
    875             (env == ZigLLVM_Musl || env == ZigLLVM_MuslEABI || env == ZigLLVM_MuslEABIHF))
    876     {
    877         return buf_create_from_str("/lib/ld-musl-x86_64.so.1");
    878     } else {
    879         return buf_create_from_str("/lib64/ld-linux-x86-64.so.2");
    880     }
    881 }
    882 
    883 bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target) {
    884     assert(host_target != nullptr);
    885 
    886     if (guest_target == nullptr) {
    887         // null guest target means that the guest target is native
    888         return true;
    889     }
    890 
    891     if (guest_target->os == host_target->os && guest_target->arch.arch == host_target->arch.arch &&
    892         guest_target->arch.sub_arch == host_target->arch.sub_arch)
    893     {
    894         // OS, arch, and sub-arch match
    895         return true;
    896     }
    897 
    898     if (guest_target->os == OsWindows && host_target->os == OsWindows &&
    899         host_target->arch.arch == ZigLLVM_x86_64 && guest_target->arch.arch == ZigLLVM_x86)
    900     {
    901         // 64-bit windows can run 32-bit programs
    902         return true;
    903     }
    904 
    905     return false;
    906 }
    907 
    908 const char *arch_stack_pointer_register_name(const ArchType *arch) {
    909     switch (arch->arch) {
    910         case ZigLLVM_UnknownArch:
    911             zig_unreachable();
    912         case ZigLLVM_x86:
    913             return "esp";
    914         case ZigLLVM_x86_64:
    915             return "rsp";
    916         case ZigLLVM_aarch64:
    917             return "sp";
    918 
    919         case ZigLLVM_arm:
    920         case ZigLLVM_thumb:
    921         case ZigLLVM_aarch64_be:
    922         case ZigLLVM_amdgcn:
    923         case ZigLLVM_amdil:
    924         case ZigLLVM_amdil64:
    925         case ZigLLVM_armeb:
    926         case ZigLLVM_arc:
    927         case ZigLLVM_avr:
    928         case ZigLLVM_bpfeb:
    929         case ZigLLVM_bpfel:
    930         case ZigLLVM_hexagon:
    931         case ZigLLVM_lanai:
    932         case ZigLLVM_hsail:
    933         case ZigLLVM_hsail64:
    934         case ZigLLVM_kalimba:
    935         case ZigLLVM_le32:
    936         case ZigLLVM_le64:
    937         case ZigLLVM_mips:
    938         case ZigLLVM_mips64:
    939         case ZigLLVM_mips64el:
    940         case ZigLLVM_mipsel:
    941         case ZigLLVM_msp430:
    942         case ZigLLVM_nios2:
    943         case ZigLLVM_nvptx:
    944         case ZigLLVM_nvptx64:
    945         case ZigLLVM_ppc64le:
    946         case ZigLLVM_r600:
    947         case ZigLLVM_renderscript32:
    948         case ZigLLVM_renderscript64:
    949         case ZigLLVM_riscv32:
    950         case ZigLLVM_riscv64:
    951         case ZigLLVM_shave:
    952         case ZigLLVM_sparc:
    953         case ZigLLVM_sparcel:
    954         case ZigLLVM_sparcv9:
    955         case ZigLLVM_spir:
    956         case ZigLLVM_spir64:
    957         case ZigLLVM_systemz:
    958         case ZigLLVM_tce:
    959         case ZigLLVM_tcele:
    960         case ZigLLVM_thumbeb:
    961         case ZigLLVM_wasm32:
    962         case ZigLLVM_wasm64:
    963         case ZigLLVM_xcore:
    964         case ZigLLVM_ppc:
    965         case ZigLLVM_ppc64:
    966             zig_panic("TODO populate this table with stack pointer register name for this CPU architecture");
    967     }
    968     zig_unreachable();
    969 }
    970 
    971 bool target_is_arm(const ZigTarget *target) {
    972     switch (target->arch.arch) {
    973         case ZigLLVM_UnknownArch:
    974             zig_unreachable();
    975         case ZigLLVM_aarch64:
    976         case ZigLLVM_arm:
    977         case ZigLLVM_thumb:
    978         case ZigLLVM_aarch64_be:
    979         case ZigLLVM_armeb:
    980         case ZigLLVM_thumbeb:
    981             return true;
    982 
    983         case ZigLLVM_x86:
    984         case ZigLLVM_x86_64:
    985         case ZigLLVM_amdgcn:
    986         case ZigLLVM_amdil:
    987         case ZigLLVM_amdil64:
    988         case ZigLLVM_arc:
    989         case ZigLLVM_avr:
    990         case ZigLLVM_bpfeb:
    991         case ZigLLVM_bpfel:
    992         case ZigLLVM_hexagon:
    993         case ZigLLVM_lanai:
    994         case ZigLLVM_hsail:
    995         case ZigLLVM_hsail64:
    996         case ZigLLVM_kalimba:
    997         case ZigLLVM_le32:
    998         case ZigLLVM_le64:
    999         case ZigLLVM_mips:
   1000         case ZigLLVM_mips64:
   1001         case ZigLLVM_mips64el:
   1002         case ZigLLVM_mipsel:
   1003         case ZigLLVM_msp430:
   1004         case ZigLLVM_nios2:
   1005         case ZigLLVM_nvptx:
   1006         case ZigLLVM_nvptx64:
   1007         case ZigLLVM_ppc64le:
   1008         case ZigLLVM_r600:
   1009         case ZigLLVM_renderscript32:
   1010         case ZigLLVM_renderscript64:
   1011         case ZigLLVM_riscv32:
   1012         case ZigLLVM_riscv64:
   1013         case ZigLLVM_shave:
   1014         case ZigLLVM_sparc:
   1015         case ZigLLVM_sparcel:
   1016         case ZigLLVM_sparcv9:
   1017         case ZigLLVM_spir:
   1018         case ZigLLVM_spir64:
   1019         case ZigLLVM_systemz:
   1020         case ZigLLVM_tce:
   1021         case ZigLLVM_tcele:
   1022         case ZigLLVM_wasm32:
   1023         case ZigLLVM_wasm64:
   1024         case ZigLLVM_xcore:
   1025         case ZigLLVM_ppc:
   1026         case ZigLLVM_ppc64:
   1027             return false;
   1028     }
   1029     zig_unreachable();
   1030 }
   1031 
   1032 // Valgrind supports more, but Zig does not support them yet.
   1033 bool target_has_valgrind_support(const ZigTarget *target) {
   1034     switch (target->arch.arch) {
   1035         case ZigLLVM_UnknownArch:
   1036             zig_unreachable();
   1037         case ZigLLVM_x86_64:
   1038             return (target->os == OsLinux || target_is_darwin(target) || target->os == OsSolaris ||
   1039                 (target->os == OsWindows && target->env_type != ZigLLVM_MSVC));
   1040         default:
   1041             return false;
   1042     }
   1043     zig_unreachable();
   1044 }
   1045 
   1046 bool target_requires_libc(const ZigTarget *target) {
   1047     // On Darwin, we always link libSystem which contains libc.
   1048     // Similarly on FreeBSD and NetBSD we always link system libc
   1049     // since this is the stable syscall interface.
   1050     return (target_is_darwin(target) || target->os == OsFreeBSD || target->os == OsNetBSD);
   1051 }