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 ZigLLVM_ArchType arch_list[] = {
17     ZigLLVM_arm,            // ARM (little endian): arm, armv.*, xscale
18     ZigLLVM_armeb,          // ARM (big endian): armeb
19     ZigLLVM_aarch64,        // AArch64 (little endian): aarch64
20     ZigLLVM_aarch64_be,     // AArch64 (big endian): aarch64_be
21     ZigLLVM_aarch64_32,     // AArch64 (little endian) ILP32: aarch64_32
22     ZigLLVM_arc,            // ARC: Synopsys ARC
23     ZigLLVM_avr,            // AVR: Atmel AVR microcontroller
24     ZigLLVM_bpfel,          // eBPF or extended BPF or 64-bit BPF (little endian)
25     ZigLLVM_bpfeb,          // eBPF or extended BPF or 64-bit BPF (big endian)
26     ZigLLVM_csky,           // CSKY: csky
27     ZigLLVM_hexagon,        // Hexagon: hexagon
28     ZigLLVM_m68k,           // M68k: Motorola 680x0 family
29     ZigLLVM_mips,           // MIPS: mips, mipsallegrex, mipsr6
30     ZigLLVM_mipsel,         // MIPSEL: mipsel, mipsallegrexe, mipsr6el
31     ZigLLVM_mips64,         // MIPS64: mips64, mips64r6, mipsn32, mipsn32r6
32     ZigLLVM_mips64el,       // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el
33     ZigLLVM_msp430,         // MSP430: msp430
34     ZigLLVM_ppc,            // PPC: powerpc
35     ZigLLVM_ppcle,          // PPCLE: powerpc (little endian)
36     ZigLLVM_ppc64,          // PPC64: powerpc64, ppu
37     ZigLLVM_ppc64le,        // PPC64LE: powerpc64le
38     ZigLLVM_r600,           // R600: AMD GPUs HD2XXX - HD6XXX
39     ZigLLVM_amdgcn,         // AMDGCN: AMD GCN GPUs
40     ZigLLVM_riscv32,        // RISC-V (32-bit): riscv32
41     ZigLLVM_riscv64,        // RISC-V (64-bit): riscv64
42     ZigLLVM_sparc,          // Sparc: sparc
43     ZigLLVM_sparcv9,        // Sparcv9: Sparcv9
44     ZigLLVM_sparcel,        // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant
45     ZigLLVM_systemz,        // SystemZ: s390x
46     ZigLLVM_tce,            // TCE (http://tce.cs.tut.fi/): tce
47     ZigLLVM_tcele,          // TCE little endian (http://tce.cs.tut.fi/): tcele
48     ZigLLVM_thumb,          // Thumb (little endian): thumb, thumbv.*
49     ZigLLVM_thumbeb,        // Thumb (big endian): thumbeb
50     ZigLLVM_x86,            // X86: i[3-9]86
51     ZigLLVM_x86_64,         // X86-64: amd64, x86_64
52     ZigLLVM_xcore,          // XCore: xcore
53     ZigLLVM_nvptx,          // NVPTX: 32-bit
54     ZigLLVM_nvptx64,        // NVPTX: 64-bit
55     ZigLLVM_le32,           // le32: generic little-endian 32-bit CPU (PNaCl)
56     ZigLLVM_le64,           // le64: generic little-endian 64-bit CPU (PNaCl)
57     ZigLLVM_amdil,          // AMDIL
58     ZigLLVM_amdil64,        // AMDIL with 64-bit pointers
59     ZigLLVM_hsail,          // AMD HSAIL
60     ZigLLVM_hsail64,        // AMD HSAIL with 64-bit pointers
61     ZigLLVM_spir,           // SPIR: standard portable IR for OpenCL 32-bit version
62     ZigLLVM_spir64,         // SPIR: standard portable IR for OpenCL 64-bit version
63     ZigLLVM_kalimba,        // Kalimba: generic kalimba
64     ZigLLVM_shave,          // SHAVE: Movidius vector VLIW processors
65     ZigLLVM_lanai,          // Lanai: Lanai 32-bit
66     ZigLLVM_wasm32,         // WebAssembly with 32-bit pointers
67     ZigLLVM_wasm64,         // WebAssembly with 64-bit pointers
68     ZigLLVM_renderscript32, // 32-bit RenderScript
69     ZigLLVM_renderscript64, // 64-bit RenderScript
70     ZigLLVM_ve,             // NEC SX-Aurora Vector Engine
71 };
72 
73 static const ZigLLVM_VendorType vendor_list[] = {
74     ZigLLVM_Apple,
75     ZigLLVM_PC,
76     ZigLLVM_SCEI,
77     ZigLLVM_Freescale,
78     ZigLLVM_IBM,
79     ZigLLVM_ImaginationTechnologies,
80     ZigLLVM_MipsTechnologies,
81     ZigLLVM_NVIDIA,
82     ZigLLVM_CSR,
83     ZigLLVM_Myriad,
84     ZigLLVM_AMD,
85     ZigLLVM_Mesa,
86     ZigLLVM_SUSE,
87 };
88 
89 static const Os os_list[] = {
90     OsFreestanding,
91     OsAnanas,
92     OsCloudABI,
93     OsDragonFly,
94     OsFreeBSD,
95     OsFuchsia,
96     OsIOS,
97     OsKFreeBSD,
98     OsLinux,
99     OsLv2,        // PS3
100     OsMacOSX,
101     OsNetBSD,
102     OsOpenBSD,
103     OsSolaris,
104     OsWindows,
105     OsZOS,
106     OsHaiku,
107     OsMinix,
108     OsRTEMS,
109     OsNaCl,       // Native Client
110     OsAIX,
111     OsCUDA,       // NVIDIA CUDA
112     OsNVCL,       // NVIDIA OpenCL
113     OsAMDHSA,     // AMD HSA Runtime
114     OsPS4,
115     OsELFIAMCU,
116     OsTvOS,       // Apple tvOS
117     OsWatchOS,    // Apple watchOS
118     OsMesa3D,
119     OsContiki,
120     OsAMDPAL,
121     OsHermitCore,
122     OsHurd,
123     OsWASI,
124     OsEmscripten,
125     OsUefi,
126     OsOpenCL,
127     OsGLSL450,
128     OsVulkan,
129     OsPlan9,
130     OsOther,
131 };
132 
133 // Coordinate with zig_llvm.h
134 static const ZigLLVM_EnvironmentType abi_list[] = {
135     ZigLLVM_UnknownEnvironment,
136 
137     ZigLLVM_GNU,
138     ZigLLVM_GNUABIN32,
139     ZigLLVM_GNUABI64,
140     ZigLLVM_GNUEABI,
141     ZigLLVM_GNUEABIHF,
142     ZigLLVM_GNUX32,
143     ZigLLVM_GNUILP32,
144     ZigLLVM_CODE16,
145     ZigLLVM_EABI,
146     ZigLLVM_EABIHF,
147     ZigLLVM_Android,
148     ZigLLVM_Musl,
149     ZigLLVM_MuslEABI,
150     ZigLLVM_MuslEABIHF,
151     ZigLLVM_MuslX32,
152 
153     ZigLLVM_MSVC,
154     ZigLLVM_Itanium,
155     ZigLLVM_Cygnus,
156     ZigLLVM_CoreCLR,
157     ZigLLVM_Simulator,
158     ZigLLVM_MacABI,
159 };
160 
161 static const ZigLLVM_ObjectFormatType oformat_list[] = {
162     ZigLLVM_UnknownObjectFormat,
163     ZigLLVM_COFF,
164     ZigLLVM_ELF,
165     ZigLLVM_GOFF,
166     ZigLLVM_MachO,
167     ZigLLVM_Wasm,
168     ZigLLVM_XCOFF,
169 };
170 
target_oformat_count(void)171 size_t target_oformat_count(void) {
172     return array_length(oformat_list);
173 }
174 
target_oformat_enum(size_t index)175 ZigLLVM_ObjectFormatType target_oformat_enum(size_t index) {
176     assert(index < array_length(oformat_list));
177     return oformat_list[index];
178 }
179 
target_oformat_name(ZigLLVM_ObjectFormatType oformat)180 const char *target_oformat_name(ZigLLVM_ObjectFormatType oformat) {
181     switch (oformat) {
182         case ZigLLVM_UnknownObjectFormat: return "unknown";
183         case ZigLLVM_COFF: return "coff";
184         case ZigLLVM_ELF: return "elf";
185         case ZigLLVM_GOFF: return "goff";
186         case ZigLLVM_MachO: return "macho";
187         case ZigLLVM_Wasm: return "wasm";
188         case ZigLLVM_XCOFF: return "xcoff";
189     }
190     zig_unreachable();
191 }
192 
target_arch_count(void)193 size_t target_arch_count(void) {
194     return array_length(arch_list);
195 }
196 
target_arch_enum(size_t index)197 ZigLLVM_ArchType target_arch_enum(size_t index) {
198     assert(index < array_length(arch_list));
199     return arch_list[index];
200 }
201 
target_vendor_count(void)202 size_t target_vendor_count(void) {
203     return array_length(vendor_list);
204 }
205 
target_vendor_enum(size_t index)206 ZigLLVM_VendorType target_vendor_enum(size_t index) {
207     assert(index < array_length(vendor_list));
208     return vendor_list[index];
209 }
210 
target_os_count(void)211 size_t target_os_count(void) {
212     return array_length(os_list);
213 }
target_os_enum(size_t index)214 Os target_os_enum(size_t index) {
215     assert(index < array_length(os_list));
216     return os_list[index];
217 }
218 
get_llvm_os_type(Os os_type)219 ZigLLVM_OSType get_llvm_os_type(Os os_type) {
220     switch (os_type) {
221         case OsFreestanding:
222         case OsOpenCL:
223         case OsGLSL450:
224         case OsVulkan:
225         case OsPlan9:
226         case OsOther:
227             return ZigLLVM_UnknownOS;
228         case OsAnanas:
229             return ZigLLVM_Ananas;
230         case OsCloudABI:
231             return ZigLLVM_CloudABI;
232         case OsDragonFly:
233             return ZigLLVM_DragonFly;
234         case OsFreeBSD:
235             return ZigLLVM_FreeBSD;
236         case OsFuchsia:
237             return ZigLLVM_Fuchsia;
238         case OsIOS:
239             return ZigLLVM_IOS;
240         case OsKFreeBSD:
241             return ZigLLVM_KFreeBSD;
242         case OsLinux:
243             return ZigLLVM_Linux;
244         case OsLv2:
245             return ZigLLVM_Lv2;
246         case OsMacOSX:
247             return ZigLLVM_MacOSX;
248         case OsNetBSD:
249             return ZigLLVM_NetBSD;
250         case OsOpenBSD:
251             return ZigLLVM_OpenBSD;
252         case OsSolaris:
253             return ZigLLVM_Solaris;
254         case OsWindows:
255         case OsUefi:
256             return ZigLLVM_Win32;
257         case OsZOS:
258             return ZigLLVM_ZOS;
259         case OsHaiku:
260             return ZigLLVM_Haiku;
261         case OsMinix:
262             return ZigLLVM_Minix;
263         case OsRTEMS:
264             return ZigLLVM_RTEMS;
265         case OsNaCl:
266             return ZigLLVM_NaCl;
267         case OsAIX:
268             return ZigLLVM_AIX;
269         case OsCUDA:
270             return ZigLLVM_CUDA;
271         case OsNVCL:
272             return ZigLLVM_NVCL;
273         case OsAMDHSA:
274             return ZigLLVM_AMDHSA;
275         case OsPS4:
276             return ZigLLVM_PS4;
277         case OsELFIAMCU:
278             return ZigLLVM_ELFIAMCU;
279         case OsTvOS:
280             return ZigLLVM_TvOS;
281         case OsWatchOS:
282             return ZigLLVM_WatchOS;
283         case OsMesa3D:
284             return ZigLLVM_Mesa3D;
285         case OsContiki:
286             return ZigLLVM_Contiki;
287         case OsAMDPAL:
288             return ZigLLVM_AMDPAL;
289         case OsHermitCore:
290             return ZigLLVM_HermitCore;
291         case OsHurd:
292             return ZigLLVM_Hurd;
293         case OsWASI:
294             return ZigLLVM_WASI;
295         case OsEmscripten:
296             return ZigLLVM_Emscripten;
297     }
298     zig_unreachable();
299 }
300 
target_os_name(Os os_type)301 const char *target_os_name(Os os_type) {
302     switch (os_type) {
303         case OsFreestanding:
304             return "freestanding";
305         case OsPlan9:
306             return "plan9";
307         case OsUefi:
308             return "uefi";
309         case OsOther:
310             return "other";
311         case OsAnanas:
312         case OsCloudABI:
313         case OsDragonFly:
314         case OsFreeBSD:
315         case OsFuchsia:
316         case OsIOS:
317         case OsKFreeBSD:
318         case OsLinux:
319         case OsLv2:        // PS3
320         case OsMacOSX:
321         case OsNetBSD:
322         case OsOpenBSD:
323         case OsSolaris:
324         case OsWindows:
325         case OsZOS:
326         case OsHaiku:
327         case OsMinix:
328         case OsRTEMS:
329         case OsNaCl:       // Native Client
330         case OsAIX:
331         case OsCUDA:       // NVIDIA CUDA
332         case OsNVCL:       // NVIDIA OpenCL
333         case OsAMDHSA:     // AMD HSA Runtime
334         case OsPS4:
335         case OsELFIAMCU:
336         case OsTvOS:       // Apple tvOS
337         case OsWatchOS:    // Apple watchOS
338         case OsMesa3D:
339         case OsContiki:
340         case OsAMDPAL:
341         case OsHermitCore:
342         case OsHurd:
343         case OsWASI:
344         case OsEmscripten:
345         case OsOpenCL:
346         case OsGLSL450:
347         case OsVulkan:
348             return ZigLLVMGetOSTypeName(get_llvm_os_type(os_type));
349     }
350     zig_unreachable();
351 }
352 
target_abi_count(void)353 size_t target_abi_count(void) {
354     return array_length(abi_list);
355 }
target_abi_enum(size_t index)356 ZigLLVM_EnvironmentType target_abi_enum(size_t index) {
357     assert(index < array_length(abi_list));
358     return abi_list[index];
359 }
target_abi_name(ZigLLVM_EnvironmentType abi)360 const char *target_abi_name(ZigLLVM_EnvironmentType abi) {
361     if (abi == ZigLLVM_UnknownEnvironment)
362         return "none";
363     return ZigLLVMGetEnvironmentTypeName(abi);
364 }
365 
target_parse_arch(ZigLLVM_ArchType * out_arch,const char * arch_ptr,size_t arch_len)366 Error target_parse_arch(ZigLLVM_ArchType *out_arch, const char *arch_ptr, size_t arch_len) {
367     *out_arch = ZigLLVM_UnknownArch;
368     for (size_t arch_i = 0; arch_i < array_length(arch_list); arch_i += 1) {
369         ZigLLVM_ArchType arch = arch_list[arch_i];
370         if (mem_eql_str(arch_ptr, arch_len, target_arch_name(arch))) {
371             *out_arch = arch;
372             return ErrorNone;
373         }
374     }
375     return ErrorUnknownArchitecture;
376 }
377 
target_parse_os(Os * out_os,const char * os_ptr,size_t os_len)378 Error target_parse_os(Os *out_os, const char *os_ptr, size_t os_len) {
379     if (mem_eql_str(os_ptr, os_len, "native")) {
380 #if defined(ZIG_OS_DARWIN)
381         *out_os = OsMacOSX;
382         return ErrorNone;
383 #elif defined(ZIG_OS_WINDOWS)
384         *out_os = OsWindows;
385         return ErrorNone;
386 #elif defined(ZIG_OS_LINUX)
387         *out_os = OsLinux;
388         return ErrorNone;
389 #elif defined(ZIG_OS_FREEBSD)
390         *out_os = OsFreeBSD;
391         return ErrorNone;
392 #elif defined(ZIG_OS_NETBSD)
393         *out_os = OsNetBSD;
394         return ErrorNone;
395 #elif defined(ZIG_OS_DRAGONFLY)
396         *out_os = OsDragonFly;
397         return ErrorNone;
398 #elif defined(ZIG_OS_OPENBSD)
399         *out_os = OsOpenBSD;
400         return ErrorNone;
401 #elif defined(ZIG_OS_HAIKU)
402         *out_os = OsHaiku;
403         return ErrorNone;
404 #elif defined(ZIG_OS_SOLARIS)
405         *out_os = OsSolaris;
406         return ErrorNone;
407 #else
408         zig_panic("stage1 is unable to detect native target for this OS");
409 #endif
410     }
411 
412     for (size_t i = 0; i < array_length(os_list); i += 1) {
413         Os os = os_list[i];
414         const char *os_name = target_os_name(os);
415         if (mem_eql_str(os_ptr, os_len, os_name)) {
416             *out_os = os;
417             return ErrorNone;
418         }
419     }
420     return ErrorUnknownOperatingSystem;
421 }
422 
target_parse_abi(ZigLLVM_EnvironmentType * out_abi,const char * abi_ptr,size_t abi_len)423 Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, size_t abi_len) {
424     for (size_t i = 0; i < array_length(abi_list); i += 1) {
425         ZigLLVM_EnvironmentType abi = abi_list[i];
426         const char *abi_name = target_abi_name(abi);
427         if (mem_eql_str(abi_ptr, abi_len, abi_name)) {
428             *out_abi = abi;
429             return ErrorNone;
430         }
431     }
432     return ErrorUnknownABI;
433 }
434 
target_arch_name(ZigLLVM_ArchType arch)435 const char *target_arch_name(ZigLLVM_ArchType arch) {
436     return ZigLLVMGetArchTypeName(arch);
437 }
438 
init_all_targets(void)439 void init_all_targets(void) {
440     LLVMInitializeAllTargets();
441     LLVMInitializeAllTargetInfos();
442     LLVMInitializeAllTargetMCs();
443     LLVMInitializeAllAsmPrinters();
444     LLVMInitializeAllAsmParsers();
445 }
446 
target_triple_zig(Buf * triple,const ZigTarget * target)447 void target_triple_zig(Buf *triple, const ZigTarget *target) {
448     buf_resize(triple, 0);
449     buf_appendf(triple, "%s-%s-%s",
450             target_arch_name(target->arch),
451             target_os_name(target->os),
452             target_abi_name(target->abi));
453 }
454 
target_triple_llvm(Buf * triple,const ZigTarget * target)455 void target_triple_llvm(Buf *triple, const ZigTarget *target) {
456     buf_resize(triple, 0);
457     buf_appendf(triple, "%s-%s-%s-%s",
458             ZigLLVMGetArchTypeName(target->arch),
459             ZigLLVMGetVendorTypeName(ZigLLVM_UnknownVendor),
460             ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),
461             ZigLLVMGetEnvironmentTypeName(target->abi));
462 }
463 
target_os_is_darwin(Os os)464 bool target_os_is_darwin(Os os) {
465     switch (os) {
466         case OsMacOSX:
467         case OsIOS:
468         case OsWatchOS:
469         case OsTvOS:
470             return true;
471         default:
472             return false;
473     }
474 }
475 
target_object_format(const ZigTarget * target)476 ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target) {
477     if (target->os == OsUefi || target->os == OsWindows) {
478         return ZigLLVM_COFF;
479     } else if (target_os_is_darwin(target->os)) {
480         return ZigLLVM_MachO;
481     }
482     if (target->arch == ZigLLVM_wasm32 ||
483         target->arch == ZigLLVM_wasm64)
484     {
485         return ZigLLVM_Wasm;
486     }
487     return ZigLLVM_ELF;
488 }
489 
490 // See lib/Support/Triple.cpp in LLVM for the source of this data.
491 // getArchPointerBitWidth
target_arch_pointer_bit_width(ZigLLVM_ArchType arch)492 uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch) {
493     switch (arch) {
494         case ZigLLVM_UnknownArch:
495             return 0;
496 
497         case ZigLLVM_avr:
498         case ZigLLVM_msp430:
499             return 16;
500 
501         case ZigLLVM_arc:
502         case ZigLLVM_arm:
503         case ZigLLVM_armeb:
504         case ZigLLVM_hexagon:
505         case ZigLLVM_m68k:
506         case ZigLLVM_le32:
507         case ZigLLVM_mips:
508         case ZigLLVM_mipsel:
509         case ZigLLVM_nvptx:
510         case ZigLLVM_ppc:
511         case ZigLLVM_ppcle:
512         case ZigLLVM_r600:
513         case ZigLLVM_riscv32:
514         case ZigLLVM_sparc:
515         case ZigLLVM_sparcel:
516         case ZigLLVM_tce:
517         case ZigLLVM_tcele:
518         case ZigLLVM_thumb:
519         case ZigLLVM_thumbeb:
520         case ZigLLVM_x86:
521         case ZigLLVM_xcore:
522         case ZigLLVM_amdil:
523         case ZigLLVM_hsail:
524         case ZigLLVM_spir:
525         case ZigLLVM_kalimba:
526         case ZigLLVM_lanai:
527         case ZigLLVM_shave:
528         case ZigLLVM_wasm32:
529         case ZigLLVM_renderscript32:
530         case ZigLLVM_aarch64_32:
531         case ZigLLVM_csky:
532             return 32;
533 
534         case ZigLLVM_aarch64:
535         case ZigLLVM_aarch64_be:
536         case ZigLLVM_amdgcn:
537         case ZigLLVM_bpfel:
538         case ZigLLVM_bpfeb:
539         case ZigLLVM_le64:
540         case ZigLLVM_mips64:
541         case ZigLLVM_mips64el:
542         case ZigLLVM_nvptx64:
543         case ZigLLVM_ppc64:
544         case ZigLLVM_ppc64le:
545         case ZigLLVM_riscv64:
546         case ZigLLVM_sparcv9:
547         case ZigLLVM_systemz:
548         case ZigLLVM_x86_64:
549         case ZigLLVM_amdil64:
550         case ZigLLVM_hsail64:
551         case ZigLLVM_spir64:
552         case ZigLLVM_wasm64:
553         case ZigLLVM_renderscript64:
554         case ZigLLVM_ve:
555             return 64;
556     }
557     zig_unreachable();
558 }
559 
target_arch_largest_atomic_bits(ZigLLVM_ArchType arch)560 uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch) {
561     switch (arch) {
562         case ZigLLVM_UnknownArch:
563             zig_unreachable();
564 
565         case ZigLLVM_avr:
566         case ZigLLVM_msp430:
567             return 16;
568 
569         case ZigLLVM_arc:
570         case ZigLLVM_arm:
571         case ZigLLVM_armeb:
572         case ZigLLVM_hexagon:
573         case ZigLLVM_m68k:
574         case ZigLLVM_le32:
575         case ZigLLVM_mips:
576         case ZigLLVM_mipsel:
577         case ZigLLVM_nvptx:
578         case ZigLLVM_ppc:
579         case ZigLLVM_ppcle:
580         case ZigLLVM_r600:
581         case ZigLLVM_riscv32:
582         case ZigLLVM_sparc:
583         case ZigLLVM_sparcel:
584         case ZigLLVM_tce:
585         case ZigLLVM_tcele:
586         case ZigLLVM_thumb:
587         case ZigLLVM_thumbeb:
588         case ZigLLVM_x86:
589         case ZigLLVM_xcore:
590         case ZigLLVM_amdil:
591         case ZigLLVM_hsail:
592         case ZigLLVM_spir:
593         case ZigLLVM_kalimba:
594         case ZigLLVM_lanai:
595         case ZigLLVM_shave:
596         case ZigLLVM_wasm32:
597         case ZigLLVM_renderscript32:
598         case ZigLLVM_csky:
599             return 32;
600 
601         case ZigLLVM_aarch64:
602         case ZigLLVM_aarch64_be:
603         case ZigLLVM_aarch64_32:
604         case ZigLLVM_amdgcn:
605         case ZigLLVM_bpfel:
606         case ZigLLVM_bpfeb:
607         case ZigLLVM_le64:
608         case ZigLLVM_mips64:
609         case ZigLLVM_mips64el:
610         case ZigLLVM_nvptx64:
611         case ZigLLVM_ppc64:
612         case ZigLLVM_ppc64le:
613         case ZigLLVM_riscv64:
614         case ZigLLVM_sparcv9:
615         case ZigLLVM_systemz:
616         case ZigLLVM_amdil64:
617         case ZigLLVM_hsail64:
618         case ZigLLVM_spir64:
619         case ZigLLVM_wasm64:
620         case ZigLLVM_renderscript64:
621         case ZigLLVM_ve:
622             return 64;
623 
624         case ZigLLVM_x86_64:
625             return 128;
626     }
627     zig_unreachable();
628 }
629 
target_c_type_size_in_bits(const ZigTarget * target,CIntType id)630 uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
631     switch (target->os) {
632         case OsFreestanding:
633         case OsOther:
634             switch (target->arch) {
635                 case ZigLLVM_msp430:
636                     switch (id) {
637                         case CIntTypeShort:
638                         case CIntTypeUShort:
639                             return 16;
640                         case CIntTypeInt:
641                         case CIntTypeUInt:
642                             return 16;
643                         case CIntTypeLong:
644                         case CIntTypeULong:
645                             return 32;
646                         case CIntTypeLongLong:
647                         case CIntTypeULongLong:
648                             return 64;
649                         case CIntTypeCount:
650                             zig_unreachable();
651                     }
652                     zig_unreachable();
653                 default:
654                     switch (id) {
655                         case CIntTypeShort:
656                         case CIntTypeUShort:
657                             return 16;
658                         case CIntTypeInt:
659                         case CIntTypeUInt:
660                             return 32;
661                         case CIntTypeLong:
662                         case CIntTypeULong:
663                             return target_arch_pointer_bit_width(target->arch);
664                         case CIntTypeLongLong:
665                         case CIntTypeULongLong:
666                             return 64;
667                         case CIntTypeCount:
668                             zig_unreachable();
669                     }
670             }
671             zig_unreachable();
672         case OsLinux:
673         case OsMacOSX:
674         case OsFreeBSD:
675         case OsNetBSD:
676         case OsDragonFly:
677         case OsOpenBSD:
678         case OsWASI:
679         case OsHaiku:
680         case OsSolaris:
681         case OsEmscripten:
682         case OsPlan9:
683         case OsCUDA:
684         case OsNVCL:
685             switch (id) {
686                 case CIntTypeShort:
687                 case CIntTypeUShort:
688                     return 16;
689                 case CIntTypeInt:
690                 case CIntTypeUInt:
691                     return 32;
692                 case CIntTypeLong:
693                 case CIntTypeULong:
694                     return target_arch_pointer_bit_width(target->arch);
695                 case CIntTypeLongLong:
696                 case CIntTypeULongLong:
697                     return 64;
698                 case CIntTypeCount:
699                     zig_unreachable();
700             }
701             zig_unreachable();
702         case OsUefi:
703         case OsWindows:
704             switch (id) {
705                 case CIntTypeShort:
706                 case CIntTypeUShort:
707                     return 16;
708                 case CIntTypeInt:
709                 case CIntTypeUInt:
710                 case CIntTypeLong:
711                 case CIntTypeULong:
712                     return 32;
713                 case CIntTypeLongLong:
714                 case CIntTypeULongLong:
715                     return 64;
716                 case CIntTypeCount:
717                     zig_unreachable();
718             }
719             zig_unreachable();
720         case OsIOS:
721             switch (id) {
722                 case CIntTypeShort:
723                 case CIntTypeUShort:
724                     return 16;
725                 case CIntTypeInt:
726                 case CIntTypeUInt:
727                     return 32;
728                 case CIntTypeLong:
729                 case CIntTypeULong:
730                 case CIntTypeLongLong:
731                 case CIntTypeULongLong:
732                     return 64;
733                 case CIntTypeCount:
734                     zig_unreachable();
735             }
736             zig_unreachable();
737         case OsAnanas:
738         case OsCloudABI:
739         case OsKFreeBSD:
740         case OsLv2:
741         case OsZOS:
742         case OsMinix:
743         case OsRTEMS:
744         case OsNaCl:
745         case OsAIX:
746         case OsAMDHSA:
747         case OsPS4:
748         case OsELFIAMCU:
749         case OsTvOS:
750         case OsWatchOS:
751         case OsMesa3D:
752         case OsFuchsia:
753         case OsContiki:
754         case OsAMDPAL:
755         case OsHermitCore:
756         case OsHurd:
757         case OsOpenCL:
758         case OsGLSL450:
759         case OsVulkan:
760             zig_panic("TODO c type size in bits for this target");
761     }
762     zig_unreachable();
763 }
764 
target_allows_addr_zero(const ZigTarget * target)765 bool target_allows_addr_zero(const ZigTarget *target) {
766     return target->os == OsFreestanding || target->os == OsUefi;
767 }
768 
target_o_file_ext(const ZigTarget * target)769 const char *target_o_file_ext(const ZigTarget *target) {
770     if (target->abi == ZigLLVM_MSVC ||
771         target->os == OsWindows || target->os == OsUefi)
772     {
773         return ".obj";
774     } else {
775         return ".o";
776     }
777 }
778 
target_asm_file_ext(const ZigTarget * target)779 const char *target_asm_file_ext(const ZigTarget *target) {
780     return ".s";
781 }
782 
target_llvm_ir_file_ext(const ZigTarget * target)783 const char *target_llvm_ir_file_ext(const ZigTarget *target) {
784     return ".ll";
785 }
786 
target_is_android(const ZigTarget * target)787 bool target_is_android(const ZigTarget *target) {
788     return target->abi == ZigLLVM_Android;
789 }
790 
arch_stack_pointer_register_name(ZigLLVM_ArchType arch)791 const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {
792     switch (arch) {
793         case ZigLLVM_UnknownArch:
794             zig_unreachable();
795         case ZigLLVM_x86:
796             return "esp";
797         case ZigLLVM_x86_64:
798             return "rsp";
799         case ZigLLVM_arm:
800         case ZigLLVM_armeb:
801         case ZigLLVM_thumb:
802         case ZigLLVM_thumbeb:
803         case ZigLLVM_aarch64:
804         case ZigLLVM_aarch64_be:
805         case ZigLLVM_aarch64_32:
806         case ZigLLVM_riscv32:
807         case ZigLLVM_riscv64:
808         case ZigLLVM_m68k:
809         case ZigLLVM_mips:
810         case ZigLLVM_mipsel:
811         case ZigLLVM_ppc:
812         case ZigLLVM_ppcle:
813         case ZigLLVM_ppc64:
814         case ZigLLVM_ppc64le:
815             return "sp";
816 
817         case ZigLLVM_wasm32:
818         case ZigLLVM_wasm64:
819             return nullptr; // known to be not available
820 
821         case ZigLLVM_amdgcn:
822         case ZigLLVM_amdil:
823         case ZigLLVM_amdil64:
824         case ZigLLVM_arc:
825         case ZigLLVM_avr:
826         case ZigLLVM_bpfeb:
827         case ZigLLVM_bpfel:
828         case ZigLLVM_csky:
829         case ZigLLVM_hexagon:
830         case ZigLLVM_lanai:
831         case ZigLLVM_hsail:
832         case ZigLLVM_hsail64:
833         case ZigLLVM_kalimba:
834         case ZigLLVM_le32:
835         case ZigLLVM_le64:
836         case ZigLLVM_mips64:
837         case ZigLLVM_mips64el:
838         case ZigLLVM_msp430:
839         case ZigLLVM_nvptx:
840         case ZigLLVM_nvptx64:
841         case ZigLLVM_r600:
842         case ZigLLVM_renderscript32:
843         case ZigLLVM_renderscript64:
844         case ZigLLVM_shave:
845         case ZigLLVM_sparc:
846         case ZigLLVM_sparcel:
847         case ZigLLVM_sparcv9:
848         case ZigLLVM_spir:
849         case ZigLLVM_spir64:
850         case ZigLLVM_systemz:
851         case ZigLLVM_tce:
852         case ZigLLVM_tcele:
853         case ZigLLVM_xcore:
854         case ZigLLVM_ve:
855             zig_panic("TODO populate this table with stack pointer register name for this CPU architecture");
856     }
857     zig_unreachable();
858 }
859 
target_is_arm(const ZigTarget * target)860 bool target_is_arm(const ZigTarget *target) {
861     switch (target->arch) {
862         case ZigLLVM_UnknownArch:
863             zig_unreachable();
864         case ZigLLVM_aarch64:
865         case ZigLLVM_aarch64_be:
866         case ZigLLVM_aarch64_32:
867         case ZigLLVM_arm:
868         case ZigLLVM_armeb:
869         case ZigLLVM_thumb:
870         case ZigLLVM_thumbeb:
871             return true;
872 
873         case ZigLLVM_x86:
874         case ZigLLVM_x86_64:
875         case ZigLLVM_amdgcn:
876         case ZigLLVM_amdil:
877         case ZigLLVM_amdil64:
878         case ZigLLVM_arc:
879         case ZigLLVM_avr:
880         case ZigLLVM_bpfeb:
881         case ZigLLVM_bpfel:
882         case ZigLLVM_csky:
883         case ZigLLVM_hexagon:
884         case ZigLLVM_m68k:
885         case ZigLLVM_lanai:
886         case ZigLLVM_hsail:
887         case ZigLLVM_hsail64:
888         case ZigLLVM_kalimba:
889         case ZigLLVM_le32:
890         case ZigLLVM_le64:
891         case ZigLLVM_mips:
892         case ZigLLVM_mips64:
893         case ZigLLVM_mips64el:
894         case ZigLLVM_mipsel:
895         case ZigLLVM_msp430:
896         case ZigLLVM_nvptx:
897         case ZigLLVM_nvptx64:
898         case ZigLLVM_ppc64le:
899         case ZigLLVM_r600:
900         case ZigLLVM_renderscript32:
901         case ZigLLVM_renderscript64:
902         case ZigLLVM_riscv32:
903         case ZigLLVM_riscv64:
904         case ZigLLVM_shave:
905         case ZigLLVM_sparc:
906         case ZigLLVM_sparcel:
907         case ZigLLVM_sparcv9:
908         case ZigLLVM_spir:
909         case ZigLLVM_spir64:
910         case ZigLLVM_systemz:
911         case ZigLLVM_tce:
912         case ZigLLVM_tcele:
913         case ZigLLVM_wasm32:
914         case ZigLLVM_wasm64:
915         case ZigLLVM_xcore:
916         case ZigLLVM_ppc:
917         case ZigLLVM_ppcle:
918         case ZigLLVM_ppc64:
919         case ZigLLVM_ve:
920             return false;
921     }
922     zig_unreachable();
923 }
924 
925 // Valgrind supports more, but Zig does not support them yet.
target_has_valgrind_support(const ZigTarget * target)926 bool target_has_valgrind_support(const ZigTarget *target) {
927     switch (target->arch) {
928         case ZigLLVM_UnknownArch:
929             zig_unreachable();
930         case ZigLLVM_x86_64:
931             return (target->os == OsLinux || target->os == OsSolaris ||
932                 (target->os == OsWindows && target->abi != ZigLLVM_MSVC));
933         default:
934             return false;
935     }
936     zig_unreachable();
937 }
938 
target_is_wasm(const ZigTarget * target)939 bool target_is_wasm(const ZigTarget *target) {
940     return target->arch == ZigLLVM_wasm32 || target->arch == ZigLLVM_wasm64;
941 }
942 
target_is_bpf(const ZigTarget * target)943 bool target_is_bpf(const ZigTarget *target) {
944     return target->arch == ZigLLVM_bpfel || target->arch == ZigLLVM_bpfeb;
945 }
946 
target_default_abi(ZigLLVM_ArchType arch,Os os)947 ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) {
948     if (arch == ZigLLVM_wasm32 || arch == ZigLLVM_wasm64) {
949         return ZigLLVM_Musl;
950     }
951     switch (os) {
952         case OsFreestanding:
953         case OsAnanas:
954         case OsCloudABI:
955         case OsLv2:
956         case OsSolaris:
957         case OsZOS:
958         case OsMinix:
959         case OsRTEMS:
960         case OsNaCl:
961         case OsAIX:
962         case OsCUDA:
963         case OsNVCL:
964         case OsAMDHSA:
965         case OsPS4:
966         case OsELFIAMCU:
967         case OsMesa3D:
968         case OsContiki:
969         case OsAMDPAL:
970         case OsHermitCore:
971         case OsOther:
972             return ZigLLVM_EABI;
973         case OsOpenBSD:
974         case OsMacOSX:
975         case OsFreeBSD:
976         case OsIOS:
977         case OsTvOS:
978         case OsWatchOS:
979         case OsFuchsia:
980         case OsKFreeBSD:
981         case OsNetBSD:
982         case OsDragonFly:
983         case OsHurd:
984         case OsHaiku:
985             return ZigLLVM_GNU;
986         case OsUefi:
987         case OsWindows:
988             return ZigLLVM_MSVC;
989         case OsLinux:
990         case OsWASI:
991         case OsEmscripten:
992             return ZigLLVM_Musl;
993         case OsOpenCL:
994         case OsGLSL450:
995         case OsVulkan:
996         case OsPlan9:
997             return ZigLLVM_UnknownEnvironment;
998     }
999     zig_unreachable();
1000 }
1001 
target_has_debug_info(const ZigTarget * target)1002 bool target_has_debug_info(const ZigTarget *target) {
1003     return !target_is_wasm(target);
1004 }
1005 
target_long_double_is_f128(const ZigTarget * target)1006 bool target_long_double_is_f128(const ZigTarget *target) {
1007     switch (target->arch) {
1008         case ZigLLVM_riscv64:
1009         case ZigLLVM_aarch64:
1010         case ZigLLVM_aarch64_be:
1011         case ZigLLVM_aarch64_32:
1012         case ZigLLVM_systemz:
1013         case ZigLLVM_mips64:
1014         case ZigLLVM_mips64el:
1015             return true;
1016 
1017         default:
1018             return false;
1019     }
1020 }
1021 
target_is_riscv(const ZigTarget * target)1022 bool target_is_riscv(const ZigTarget *target) {
1023     return target->arch == ZigLLVM_riscv32 || target->arch == ZigLLVM_riscv64;
1024 }
1025 
target_is_sparc(const ZigTarget * target)1026 bool target_is_sparc(const ZigTarget *target) {
1027     return target->arch == ZigLLVM_sparc || target->arch == ZigLLVM_sparcv9;
1028 }
1029 
target_is_mips(const ZigTarget * target)1030 bool target_is_mips(const ZigTarget *target) {
1031     return target->arch == ZigLLVM_mips || target->arch == ZigLLVM_mipsel ||
1032         target->arch == ZigLLVM_mips64 || target->arch == ZigLLVM_mips64el;
1033 }
1034 
target_is_ppc(const ZigTarget * target)1035 bool target_is_ppc(const ZigTarget *target) {
1036     return target->arch == ZigLLVM_ppc || target->arch == ZigLLVM_ppc64 ||
1037         target->arch == ZigLLVM_ppc64le;
1038 }
1039 
1040 // Returns the minimum alignment for every function pointer on the given
1041 // architecture.
target_fn_ptr_align(const ZigTarget * target)1042 unsigned target_fn_ptr_align(const ZigTarget *target) {
1043     // TODO This is a pessimization but is always correct.
1044     return 1;
1045 }
1046 
1047 // Returns the minimum alignment for every function on the given architecture.
target_fn_align(const ZigTarget * target)1048 unsigned target_fn_align(const ZigTarget *target) {
1049     switch (target->arch) {
1050         case ZigLLVM_riscv32:
1051         case ZigLLVM_riscv64:
1052             // TODO If the C extension is not present the value is 4.
1053             return 2;
1054         case ZigLLVM_ppc:
1055         case ZigLLVM_ppcle:
1056         case ZigLLVM_ppc64:
1057         case ZigLLVM_ppc64le:
1058         case ZigLLVM_aarch64:
1059         case ZigLLVM_aarch64_be:
1060         case ZigLLVM_aarch64_32:
1061         case ZigLLVM_sparc:
1062         case ZigLLVM_sparcel:
1063         case ZigLLVM_sparcv9:
1064         case ZigLLVM_mips:
1065         case ZigLLVM_mipsel:
1066         case ZigLLVM_mips64:
1067         case ZigLLVM_mips64el:
1068             return 4;
1069 
1070         default:
1071             return 1;
1072     }
1073 }
1074