zig

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

blob d760f230 (21096B) - 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 
     13 #include <stdio.h>
     14 
     15 static const ArchType arch_list[] = {
     16     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_3a},
     17     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_2a},
     18     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_1a},
     19     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8},
     20     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8r},
     21     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8m_baseline},
     22     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8m_mainline},
     23     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7},
     24     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7em},
     25     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7m},
     26     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7s},
     27     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7k},
     28     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7ve},
     29     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6},
     30     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6m},
     31     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6k},
     32     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6t2},
     33     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v5},
     34     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v5te},
     35     {ZigLLVM_arm, ZigLLVM_ARMSubArch_v4t},
     36 
     37     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_3a},
     38     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_2a},
     39     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_1a},
     40     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8},
     41     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8r},
     42     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8m_baseline},
     43     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8m_mainline},
     44     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7},
     45     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7em},
     46     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7m},
     47     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7s},
     48     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7k},
     49     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7ve},
     50     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6},
     51     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6m},
     52     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6k},
     53     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6t2},
     54     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v5},
     55     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v5te},
     56     {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v4t},
     57 
     58     {ZigLLVM_aarch64, ZigLLVM_NoSubArch},
     59     {ZigLLVM_aarch64_be, ZigLLVM_NoSubArch},
     60     {ZigLLVM_arc, ZigLLVM_NoSubArch},
     61     {ZigLLVM_avr, ZigLLVM_NoSubArch},
     62     {ZigLLVM_bpfel, ZigLLVM_NoSubArch},
     63     {ZigLLVM_bpfeb, ZigLLVM_NoSubArch},
     64     {ZigLLVM_hexagon, ZigLLVM_NoSubArch},
     65     {ZigLLVM_mips, ZigLLVM_NoSubArch},
     66     {ZigLLVM_mipsel, ZigLLVM_NoSubArch},
     67     {ZigLLVM_mips64, ZigLLVM_NoSubArch},
     68     {ZigLLVM_mips64el, ZigLLVM_NoSubArch},
     69     {ZigLLVM_msp430, ZigLLVM_NoSubArch},
     70     {ZigLLVM_nios2, ZigLLVM_NoSubArch},
     71     {ZigLLVM_ppc, ZigLLVM_NoSubArch},
     72     {ZigLLVM_ppc64, ZigLLVM_NoSubArch},
     73     {ZigLLVM_ppc64le, ZigLLVM_NoSubArch},
     74     {ZigLLVM_r600, ZigLLVM_NoSubArch},
     75     {ZigLLVM_amdgcn, ZigLLVM_NoSubArch},
     76     {ZigLLVM_riscv32, ZigLLVM_NoSubArch},
     77     {ZigLLVM_riscv64, ZigLLVM_NoSubArch},
     78     {ZigLLVM_sparc, ZigLLVM_NoSubArch},
     79     {ZigLLVM_sparcv9, ZigLLVM_NoSubArch},
     80     {ZigLLVM_sparcel, ZigLLVM_NoSubArch},
     81     {ZigLLVM_systemz, ZigLLVM_NoSubArch},
     82     {ZigLLVM_tce, ZigLLVM_NoSubArch},
     83     {ZigLLVM_tcele, ZigLLVM_NoSubArch},
     84     {ZigLLVM_thumb, ZigLLVM_NoSubArch},
     85     {ZigLLVM_thumbeb, ZigLLVM_NoSubArch},
     86     {ZigLLVM_x86, ZigLLVM_NoSubArch},
     87     {ZigLLVM_x86_64, ZigLLVM_NoSubArch},
     88     {ZigLLVM_xcore, ZigLLVM_NoSubArch},
     89     {ZigLLVM_nvptx, ZigLLVM_NoSubArch},
     90     {ZigLLVM_nvptx64, ZigLLVM_NoSubArch},
     91     {ZigLLVM_le32, ZigLLVM_NoSubArch},
     92     {ZigLLVM_le64, ZigLLVM_NoSubArch},
     93     {ZigLLVM_amdil, ZigLLVM_NoSubArch},
     94     {ZigLLVM_amdil64, ZigLLVM_NoSubArch},
     95     {ZigLLVM_hsail, ZigLLVM_NoSubArch},
     96     {ZigLLVM_hsail64, ZigLLVM_NoSubArch},
     97     {ZigLLVM_spir, ZigLLVM_NoSubArch},
     98     {ZigLLVM_spir64, ZigLLVM_NoSubArch},
     99 
    100     {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v3},
    101     {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v4},
    102     {ZigLLVM_kalimba, ZigLLVM_KalimbaSubArch_v5},
    103 
    104     {ZigLLVM_shave, ZigLLVM_NoSubArch},
    105     {ZigLLVM_lanai, ZigLLVM_NoSubArch},
    106     {ZigLLVM_wasm32, ZigLLVM_NoSubArch},
    107     {ZigLLVM_wasm64, ZigLLVM_NoSubArch},
    108     {ZigLLVM_renderscript32, ZigLLVM_NoSubArch},
    109     {ZigLLVM_renderscript64, ZigLLVM_NoSubArch},
    110 };
    111 
    112 static const ZigLLVM_VendorType vendor_list[] = {
    113     ZigLLVM_Apple,
    114     ZigLLVM_PC,
    115     ZigLLVM_SCEI,
    116     ZigLLVM_BGP,
    117     ZigLLVM_BGQ,
    118     ZigLLVM_Freescale,
    119     ZigLLVM_IBM,
    120     ZigLLVM_ImaginationTechnologies,
    121     ZigLLVM_MipsTechnologies,
    122     ZigLLVM_NVIDIA,
    123     ZigLLVM_CSR,
    124     ZigLLVM_Myriad,
    125     ZigLLVM_AMD,
    126     ZigLLVM_Mesa,
    127     ZigLLVM_SUSE,
    128 };
    129 
    130 static const ZigLLVM_OSType os_list[] = {
    131     ZigLLVM_UnknownOS,
    132     ZigLLVM_Ananas,
    133     ZigLLVM_CloudABI,
    134     ZigLLVM_Darwin,
    135     ZigLLVM_DragonFly,
    136     ZigLLVM_FreeBSD,
    137     ZigLLVM_Fuchsia,
    138     ZigLLVM_IOS,
    139     ZigLLVM_KFreeBSD,
    140     ZigLLVM_Linux,
    141     ZigLLVM_Lv2,
    142     ZigLLVM_MacOSX,
    143     ZigLLVM_NetBSD,
    144     ZigLLVM_OpenBSD,
    145     ZigLLVM_Solaris,
    146     ZigLLVM_Win32,
    147     ZigLLVM_Haiku,
    148     ZigLLVM_Minix,
    149     ZigLLVM_RTEMS,
    150     ZigLLVM_NaCl,
    151     ZigLLVM_CNK,
    152     ZigLLVM_Bitrig,
    153     ZigLLVM_AIX,
    154     ZigLLVM_CUDA,
    155     ZigLLVM_NVCL,
    156     ZigLLVM_AMDHSA,
    157     ZigLLVM_PS4,
    158     ZigLLVM_ELFIAMCU,
    159     ZigLLVM_TvOS,
    160     ZigLLVM_WatchOS,
    161     ZigLLVM_Mesa3D,
    162     ZigLLVM_Contiki,
    163 };
    164 
    165 static const ZigLLVM_EnvironmentType environ_list[] = {
    166     ZigLLVM_UnknownEnvironment,
    167 
    168     ZigLLVM_GNU,
    169     ZigLLVM_GNUABIN32,
    170     ZigLLVM_GNUABI64,
    171     ZigLLVM_GNUEABI,
    172     ZigLLVM_GNUEABIHF,
    173     ZigLLVM_GNUX32,
    174     ZigLLVM_CODE16,
    175     ZigLLVM_EABI,
    176     ZigLLVM_EABIHF,
    177     ZigLLVM_Android,
    178     ZigLLVM_Musl,
    179     ZigLLVM_MuslEABI,
    180     ZigLLVM_MuslEABIHF,
    181     ZigLLVM_MSVC,
    182     ZigLLVM_Itanium,
    183     ZigLLVM_Cygnus,
    184     ZigLLVM_AMDOpenCL,
    185     ZigLLVM_CoreCLR,
    186     ZigLLVM_OpenCL,
    187     ZigLLVM_Simulator,
    188 };
    189 
    190 static const ZigLLVM_ObjectFormatType oformat_list[] = {
    191     ZigLLVM_UnknownObjectFormat,
    192     ZigLLVM_COFF,
    193     ZigLLVM_ELF,
    194     ZigLLVM_MachO,
    195     ZigLLVM_Wasm,
    196 };
    197 
    198 size_t target_oformat_count(void) {
    199     return array_length(oformat_list);
    200 }
    201 
    202 const ZigLLVM_ObjectFormatType get_target_oformat(size_t index) {
    203     return oformat_list[index];
    204 }
    205 
    206 const char *get_target_oformat_name(ZigLLVM_ObjectFormatType oformat) {
    207     switch (oformat) {
    208         case ZigLLVM_UnknownObjectFormat: return "unknown";
    209         case ZigLLVM_COFF: return "coff";
    210         case ZigLLVM_ELF: return "elf";
    211         case ZigLLVM_MachO: return "macho";
    212         case ZigLLVM_Wasm: return "wasm";
    213     }
    214     zig_unreachable();
    215 }
    216 
    217 size_t target_arch_count(void) {
    218     return array_length(arch_list);
    219 }
    220 
    221 const ArchType *get_target_arch(size_t index) {
    222     return &arch_list[index];
    223 }
    224 
    225 size_t target_vendor_count(void) {
    226     return array_length(vendor_list);
    227 }
    228 
    229 ZigLLVM_VendorType get_target_vendor(size_t index) {
    230     return vendor_list[index];
    231 }
    232 
    233 size_t target_os_count(void) {
    234     return array_length(os_list);
    235 }
    236 ZigLLVM_OSType get_target_os(size_t index) {
    237     return os_list[index];
    238 }
    239 
    240 const char *get_target_os_name(ZigLLVM_OSType os_type) {
    241     return (os_type == ZigLLVM_UnknownOS) ? "freestanding" : ZigLLVMGetOSTypeName(os_type);
    242 }
    243 
    244 size_t target_environ_count(void) {
    245     return array_length(environ_list);
    246 }
    247 ZigLLVM_EnvironmentType get_target_environ(size_t index) {
    248     return environ_list[index];
    249 }
    250 
    251 void get_native_target(ZigTarget *target) {
    252     ZigLLVMGetNativeTarget(
    253             &target->arch.arch,
    254             &target->arch.sub_arch,
    255             &target->vendor,
    256             &target->os,
    257             &target->env_type,
    258             &target->oformat);
    259 }
    260 
    261 void get_unknown_target(ZigTarget *target) {
    262     target->arch.arch = ZigLLVM_UnknownArch;
    263     target->arch.sub_arch = ZigLLVM_NoSubArch;
    264     target->vendor = ZigLLVM_UnknownVendor;
    265     target->os = ZigLLVM_UnknownOS;
    266     target->env_type = ZigLLVM_UnknownEnvironment;
    267     target->oformat = ZigLLVM_UnknownObjectFormat;
    268 }
    269 
    270 static void get_arch_name_raw(char *out_str, ZigLLVM_ArchType arch, ZigLLVM_SubArchType sub_arch) {
    271     const char *sub_str = (sub_arch == ZigLLVM_NoSubArch) ? "" : ZigLLVMGetSubArchTypeName(sub_arch);
    272     sprintf(out_str, "%s%s", ZigLLVMGetArchTypeName(arch), sub_str);
    273 }
    274 
    275 void get_arch_name(char *out_str, const ArchType *arch) {
    276     return get_arch_name_raw(out_str, arch->arch, arch->sub_arch);
    277 }
    278 
    279 int parse_target_arch(const char *str, ArchType *out_arch) {
    280     for (size_t i = 0; i < array_length(arch_list); i += 1) {
    281         const ArchType *arch = &arch_list[i];
    282         char arch_name[50];
    283         get_arch_name_raw(arch_name, arch->arch, arch->sub_arch);
    284         if (strcmp(arch_name, str) == 0) {
    285             *out_arch = *arch;
    286             return 0;
    287         }
    288     }
    289     return ErrorFileNotFound;
    290 }
    291 
    292 int parse_target_os(const char *str, ZigLLVM_OSType *out_os) {
    293     for (size_t i = 0; i < array_length(os_list); i += 1) {
    294         ZigLLVM_OSType os = os_list[i];
    295         const char *os_name = get_target_os_name(os);
    296         if (strcmp(os_name, str) == 0) {
    297             *out_os = os;
    298             return 0;
    299         }
    300     }
    301     return ErrorFileNotFound;
    302 }
    303 
    304 int parse_target_environ(const char *str, ZigLLVM_EnvironmentType *out_environ) {
    305     for (size_t i = 0; i < array_length(environ_list); i += 1) {
    306         ZigLLVM_EnvironmentType env_type = environ_list[i];
    307         const char *environ_name = ZigLLVMGetEnvironmentTypeName(env_type);
    308         if (strcmp(environ_name, str) == 0) {
    309             *out_environ = env_type;
    310             return 0;
    311         }
    312     }
    313     return ErrorFileNotFound;
    314 }
    315 
    316 void init_all_targets(void) {
    317     LLVMInitializeAllTargets();
    318     LLVMInitializeAllTargetInfos();
    319     LLVMInitializeAllTargetMCs();
    320     LLVMInitializeAllAsmPrinters();
    321     LLVMInitializeAllAsmParsers();
    322 }
    323 
    324 void get_target_triple(Buf *triple, const ZigTarget *target) {
    325     char arch_name[50];
    326     get_arch_name(arch_name, &target->arch);
    327 
    328     buf_resize(triple, 0);
    329     buf_appendf(triple, "%s-%s-%s-%s", arch_name,
    330             ZigLLVMGetVendorTypeName(target->vendor),
    331             ZigLLVMGetOSTypeName(target->os),
    332             ZigLLVMGetEnvironmentTypeName(target->env_type));
    333 }
    334 
    335 static bool is_os_darwin(ZigTarget *target) {
    336     switch (target->os) {
    337         case ZigLLVM_Darwin:
    338         case ZigLLVM_IOS:
    339         case ZigLLVM_MacOSX:
    340             return true;
    341         default:
    342             return false;
    343     }
    344 }
    345 
    346 void resolve_target_object_format(ZigTarget *target) {
    347     if (target->oformat != ZigLLVM_UnknownObjectFormat) {
    348         return;
    349     }
    350 
    351     switch (target->arch.arch) {
    352         case ZigLLVM_UnknownArch:
    353         case ZigLLVM_aarch64:
    354         case ZigLLVM_arm:
    355         case ZigLLVM_thumb:
    356         case ZigLLVM_x86:
    357         case ZigLLVM_x86_64:
    358             if (is_os_darwin(target)) {
    359                 target->oformat = ZigLLVM_MachO;
    360             } else if (target->os == ZigLLVM_Win32) {
    361                 target->oformat = ZigLLVM_COFF;
    362             } else {
    363                 target->oformat = ZigLLVM_ELF;
    364             }
    365             return;
    366 
    367         case ZigLLVM_aarch64_be:
    368         case ZigLLVM_amdgcn:
    369         case ZigLLVM_amdil:
    370         case ZigLLVM_amdil64:
    371         case ZigLLVM_armeb:
    372         case ZigLLVM_arc:
    373         case ZigLLVM_avr:
    374         case ZigLLVM_bpfeb:
    375         case ZigLLVM_bpfel:
    376         case ZigLLVM_hexagon:
    377         case ZigLLVM_lanai:
    378         case ZigLLVM_hsail:
    379         case ZigLLVM_hsail64:
    380         case ZigLLVM_kalimba:
    381         case ZigLLVM_le32:
    382         case ZigLLVM_le64:
    383         case ZigLLVM_mips:
    384         case ZigLLVM_mips64:
    385         case ZigLLVM_mips64el:
    386         case ZigLLVM_mipsel:
    387         case ZigLLVM_msp430:
    388         case ZigLLVM_nios2:
    389         case ZigLLVM_nvptx:
    390         case ZigLLVM_nvptx64:
    391         case ZigLLVM_ppc64le:
    392         case ZigLLVM_r600:
    393         case ZigLLVM_renderscript32:
    394         case ZigLLVM_renderscript64:
    395         case ZigLLVM_riscv32:
    396         case ZigLLVM_riscv64:
    397         case ZigLLVM_shave:
    398         case ZigLLVM_sparc:
    399         case ZigLLVM_sparcel:
    400         case ZigLLVM_sparcv9:
    401         case ZigLLVM_spir:
    402         case ZigLLVM_spir64:
    403         case ZigLLVM_systemz:
    404         case ZigLLVM_tce:
    405         case ZigLLVM_tcele:
    406         case ZigLLVM_thumbeb:
    407         case ZigLLVM_wasm32:
    408         case ZigLLVM_wasm64:
    409         case ZigLLVM_xcore:
    410             target->oformat= ZigLLVM_ELF;
    411             return;
    412 
    413         case ZigLLVM_ppc:
    414         case ZigLLVM_ppc64:
    415             if (is_os_darwin(target)) {
    416                 target->oformat = ZigLLVM_MachO;
    417             } else {
    418                 target->oformat= ZigLLVM_ELF;
    419             }
    420             return;
    421     }
    422 }
    423 
    424 // See lib/Support/Triple.cpp in LLVM for the source of this data.
    425 // getArchPointerBitWidth
    426 static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) {
    427     switch (arch) {
    428         case ZigLLVM_UnknownArch:
    429             return 0;
    430 
    431         case ZigLLVM_avr:
    432         case ZigLLVM_msp430:
    433             return 16;
    434 
    435         case ZigLLVM_arc:
    436         case ZigLLVM_arm:
    437         case ZigLLVM_armeb:
    438         case ZigLLVM_hexagon:
    439         case ZigLLVM_le32:
    440         case ZigLLVM_mips:
    441         case ZigLLVM_mipsel:
    442         case ZigLLVM_nios2:
    443         case ZigLLVM_nvptx:
    444         case ZigLLVM_ppc:
    445         case ZigLLVM_r600:
    446         case ZigLLVM_riscv32:
    447         case ZigLLVM_sparc:
    448         case ZigLLVM_sparcel:
    449         case ZigLLVM_tce:
    450         case ZigLLVM_tcele:
    451         case ZigLLVM_thumb:
    452         case ZigLLVM_thumbeb:
    453         case ZigLLVM_x86:
    454         case ZigLLVM_xcore:
    455         case ZigLLVM_amdil:
    456         case ZigLLVM_hsail:
    457         case ZigLLVM_spir:
    458         case ZigLLVM_kalimba:
    459         case ZigLLVM_lanai:
    460         case ZigLLVM_shave:
    461         case ZigLLVM_wasm32:
    462         case ZigLLVM_renderscript32:
    463             return 32;
    464 
    465         case ZigLLVM_aarch64:
    466         case ZigLLVM_aarch64_be:
    467         case ZigLLVM_amdgcn:
    468         case ZigLLVM_bpfel:
    469         case ZigLLVM_bpfeb:
    470         case ZigLLVM_le64:
    471         case ZigLLVM_mips64:
    472         case ZigLLVM_mips64el:
    473         case ZigLLVM_nvptx64:
    474         case ZigLLVM_ppc64:
    475         case ZigLLVM_ppc64le:
    476         case ZigLLVM_riscv64:
    477         case ZigLLVM_sparcv9:
    478         case ZigLLVM_systemz:
    479         case ZigLLVM_x86_64:
    480         case ZigLLVM_amdil64:
    481         case ZigLLVM_hsail64:
    482         case ZigLLVM_spir64:
    483         case ZigLLVM_wasm64:
    484         case ZigLLVM_renderscript64:
    485             return 64;
    486     }
    487     zig_unreachable();
    488 }
    489 
    490 uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
    491     switch (target->os) {
    492         case ZigLLVM_UnknownOS:
    493             switch (id) {
    494                 case CIntTypeShort:
    495                 case CIntTypeUShort:
    496                     return 16;
    497                 case CIntTypeInt:
    498                 case CIntTypeUInt:
    499                     return 32;
    500                 case CIntTypeLong:
    501                 case CIntTypeULong:
    502                     return get_arch_pointer_bit_width(target->arch.arch);
    503                 case CIntTypeLongLong:
    504                 case CIntTypeULongLong:
    505                     return 64;
    506                 case CIntTypeCount:
    507                     zig_unreachable();
    508             }
    509         case ZigLLVM_Linux:
    510         case ZigLLVM_Darwin:
    511         case ZigLLVM_MacOSX:
    512             switch (id) {
    513                 case CIntTypeShort:
    514                 case CIntTypeUShort:
    515                     return 16;
    516                 case CIntTypeInt:
    517                 case CIntTypeUInt:
    518                     return 32;
    519                 case CIntTypeLong:
    520                 case CIntTypeULong:
    521                     return get_arch_pointer_bit_width(target->arch.arch);
    522                 case CIntTypeLongLong:
    523                 case CIntTypeULongLong:
    524                     return 64;
    525                 case CIntTypeCount:
    526                     zig_unreachable();
    527             }
    528         case ZigLLVM_Win32:
    529             switch (id) {
    530                 case CIntTypeShort:
    531                 case CIntTypeUShort:
    532                     return 16;
    533                 case CIntTypeInt:
    534                 case CIntTypeUInt:
    535                 case CIntTypeLong:
    536                 case CIntTypeULong:
    537                     return 32;
    538                 case CIntTypeLongLong:
    539                 case CIntTypeULongLong:
    540                     return 64;
    541                 case CIntTypeCount:
    542                     zig_unreachable();
    543             }
    544         case ZigLLVM_Ananas:
    545         case ZigLLVM_CloudABI:
    546         case ZigLLVM_DragonFly:
    547         case ZigLLVM_FreeBSD:
    548         case ZigLLVM_IOS:
    549         case ZigLLVM_KFreeBSD:
    550         case ZigLLVM_Lv2:
    551         case ZigLLVM_NetBSD:
    552         case ZigLLVM_OpenBSD:
    553         case ZigLLVM_Solaris:
    554         case ZigLLVM_Haiku:
    555         case ZigLLVM_Minix:
    556         case ZigLLVM_RTEMS:
    557         case ZigLLVM_NaCl:
    558         case ZigLLVM_CNK:
    559         case ZigLLVM_Bitrig:
    560         case ZigLLVM_AIX:
    561         case ZigLLVM_CUDA:
    562         case ZigLLVM_NVCL:
    563         case ZigLLVM_AMDHSA:
    564         case ZigLLVM_PS4:
    565         case ZigLLVM_ELFIAMCU:
    566         case ZigLLVM_TvOS:
    567         case ZigLLVM_WatchOS:
    568         case ZigLLVM_Mesa3D:
    569         case ZigLLVM_Fuchsia:
    570         case ZigLLVM_Contiki:
    571             zig_panic("TODO c type size in bits for this target");
    572     }
    573     zig_unreachable();
    574 }
    575 
    576 const char *target_o_file_ext(ZigTarget *target) {
    577     if (target->env_type == ZigLLVM_MSVC || target->os == ZigLLVM_Win32) {
    578         return ".obj";
    579     } else {
    580         return ".o";
    581     }
    582 }
    583 
    584 const char *target_asm_file_ext(ZigTarget *target) {
    585     return ".s";
    586 }
    587 
    588 const char *target_llvm_ir_file_ext(ZigTarget *target) {
    589     return ".ll";
    590 }
    591 
    592 const char *target_exe_file_ext(ZigTarget *target) {
    593     if (target->os == ZigLLVM_Win32) {
    594         return ".exe";
    595     } else {
    596         return "";
    597     }
    598 }
    599 
    600 enum FloatAbi {
    601     FloatAbiHard,
    602     FloatAbiSoft,
    603     FloatAbiSoftFp,
    604 };
    605 
    606 static FloatAbi get_float_abi(ZigTarget *target) {
    607     const ZigLLVM_EnvironmentType env = target->env_type;
    608     if (env == ZigLLVM_GNUEABIHF ||
    609         env == ZigLLVM_EABIHF ||
    610         env == ZigLLVM_MuslEABIHF)
    611     {
    612         return FloatAbiHard;
    613     } else {
    614         zig_panic("TODO: user needs to input if they want hard or soft floating point");
    615     }
    616 }
    617 
    618 static bool is_64_bit(ZigLLVM_ArchType arch) {
    619     return get_arch_pointer_bit_width(arch) == 64;
    620 }
    621 
    622 Buf *target_dynamic_linker(ZigTarget *target) {
    623     const ZigLLVM_ArchType arch = target->arch.arch;
    624     const ZigLLVM_EnvironmentType env = target->env_type;
    625 
    626     if (env == ZigLLVM_Android) {
    627         if (is_64_bit(arch)) {
    628             return buf_create_from_str("/system/bin/linker64");
    629         } else {
    630             return buf_create_from_str("/system/bin/linker");
    631         }
    632     } else if (arch == ZigLLVM_x86 ||
    633             arch == ZigLLVM_sparc ||
    634             arch == ZigLLVM_sparcel)
    635     {
    636         return buf_create_from_str("/lib/ld-linux.so.2");
    637     } else if (arch == ZigLLVM_aarch64) {
    638         return buf_create_from_str("/lib/ld-linux-aarch64.so.1");
    639     } else if (arch == ZigLLVM_aarch64_be) {
    640         return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1");
    641     } else if (arch == ZigLLVM_arm || arch == ZigLLVM_thumb) {
    642         if (get_float_abi(target) == FloatAbiHard) {
    643             return buf_create_from_str("/lib/ld-linux-armhf.so.3");
    644         } else {
    645             return buf_create_from_str("/lib/ld-linux.so.3");
    646         }
    647     } else if (arch == ZigLLVM_armeb || arch == ZigLLVM_thumbeb) {
    648         if (get_float_abi(target) == FloatAbiHard) {
    649             return buf_create_from_str("/lib/ld-linux-armhf.so.3");
    650         } else {
    651             return buf_create_from_str("/lib/ld-linux.so.3");
    652         }
    653     } else if (arch == ZigLLVM_mips || arch == ZigLLVM_mipsel ||
    654             arch == ZigLLVM_mips64 || arch == ZigLLVM_mips64el)
    655     {
    656         // when you want to solve this TODO, grep clang codebase for
    657         // getLinuxDynamicLinker
    658         zig_panic("TODO figure out MIPS dynamic linker name");
    659     } else if (arch == ZigLLVM_ppc) {
    660         return buf_create_from_str("/lib/ld.so.1");
    661     } else if (arch == ZigLLVM_ppc64) {
    662         return buf_create_from_str("/lib64/ld64.so.2");
    663     } else if (arch == ZigLLVM_ppc64le) {
    664         return buf_create_from_str("/lib64/ld64.so.2");
    665     } else if (arch == ZigLLVM_systemz) {
    666         return buf_create_from_str("/lib64/ld64.so.1");
    667     } else if (arch == ZigLLVM_sparcv9) {
    668         return buf_create_from_str("/lib64/ld-linux.so.2");
    669     } else if (arch == ZigLLVM_x86_64 &&
    670             env == ZigLLVM_GNUX32)
    671     {
    672         return buf_create_from_str("/libx32/ld-linux-x32.so.2");
    673     } else {
    674         return buf_create_from_str("/lib64/ld-linux-x86-64.so.2");
    675     }
    676 }
    677 
    678 bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target) {
    679     assert(host_target != nullptr);
    680 
    681     if (guest_target == nullptr) {
    682         // null guest target means that the guest target is native
    683         return true;
    684     }
    685 
    686     if (guest_target->os == host_target->os && guest_target->arch.arch == host_target->arch.arch &&
    687         guest_target->arch.sub_arch == host_target->arch.sub_arch)
    688     {
    689         // OS, arch, and sub-arch match
    690         return true;
    691     }
    692 
    693     if (guest_target->os == ZigLLVM_Win32 && host_target->os == ZigLLVM_Win32 &&
    694         host_target->arch.arch == ZigLLVM_x86_64 && guest_target->arch.arch == ZigLLVM_x86)
    695     {
    696         // 64-bit windows can run 32-bit programs
    697         return true;
    698     }
    699     
    700     return false;
    701 }